xref: /optee_os/core/crypto/sm2-kdf.c (revision 1e149c24535c9f02cca39901afaa33088e295d34)
1*1e149c24SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2*1e149c24SJerome Forissier /*
3*1e149c24SJerome Forissier  * Copyright (c) 2020 Huawei Technologies Co., Ltd
4*1e149c24SJerome Forissier  */
5*1e149c24SJerome Forissier 
6*1e149c24SJerome Forissier #include <crypto/crypto.h>
7*1e149c24SJerome Forissier #include <crypto/sm2-kdf.h>
8*1e149c24SJerome Forissier #include <io.h>
9*1e149c24SJerome Forissier #include <stdint.h>
10*1e149c24SJerome Forissier #include <string.h>
11*1e149c24SJerome Forissier #include <tee_api_types.h>
12*1e149c24SJerome Forissier #include <unistd.h>
13*1e149c24SJerome Forissier #include <utee_defines.h>
14*1e149c24SJerome Forissier 
15*1e149c24SJerome Forissier /*
16*1e149c24SJerome Forissier  * GM/T 0003.1‒2012 Part 4 Sections 5.4.2 and 5.4.3
17*1e149c24SJerome Forissier  * GM/T 0003.1‒2012 Part 5 Sections 5.4.2 and 5.4.3
18*1e149c24SJerome Forissier  * Key derivation function based on the SM3 hash function
19*1e149c24SJerome Forissier  */
sm2_kdf(const uint8_t * Z,size_t Z_len,uint8_t * t,size_t tlen)20*1e149c24SJerome Forissier TEE_Result sm2_kdf(const uint8_t *Z, size_t Z_len, uint8_t *t, size_t tlen)
21*1e149c24SJerome Forissier {
22*1e149c24SJerome Forissier 	TEE_Result res = TEE_SUCCESS;
23*1e149c24SJerome Forissier 	size_t remain = tlen;
24*1e149c24SJerome Forissier 	uint32_t count = 1;
25*1e149c24SJerome Forissier 	uint32_t be_count = 0;
26*1e149c24SJerome Forissier 	void *ctx = NULL;
27*1e149c24SJerome Forissier 	uint8_t *out = t;
28*1e149c24SJerome Forissier 
29*1e149c24SJerome Forissier 	res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SM3);
30*1e149c24SJerome Forissier 	if (res)
31*1e149c24SJerome Forissier 		return res;
32*1e149c24SJerome Forissier 
33*1e149c24SJerome Forissier 	while (remain) {
34*1e149c24SJerome Forissier 		uint8_t tmp[TEE_SM3_HASH_SIZE] = { };
35*1e149c24SJerome Forissier 		uint8_t *buf = NULL;
36*1e149c24SJerome Forissier 
37*1e149c24SJerome Forissier 		if (remain >= TEE_SM3_HASH_SIZE)
38*1e149c24SJerome Forissier 			buf = out;
39*1e149c24SJerome Forissier 		else
40*1e149c24SJerome Forissier 			buf = tmp;
41*1e149c24SJerome Forissier 
42*1e149c24SJerome Forissier 		put_be32(&be_count, count);
43*1e149c24SJerome Forissier 		res = crypto_hash_init(ctx);
44*1e149c24SJerome Forissier 		if (res)
45*1e149c24SJerome Forissier 			goto out;
46*1e149c24SJerome Forissier 		res = crypto_hash_update(ctx, Z, Z_len);
47*1e149c24SJerome Forissier 		if (res)
48*1e149c24SJerome Forissier 			goto out;
49*1e149c24SJerome Forissier 		res = crypto_hash_update(ctx, (const uint8_t *)&be_count,
50*1e149c24SJerome Forissier 					 sizeof(be_count));
51*1e149c24SJerome Forissier 		if (res)
52*1e149c24SJerome Forissier 			goto out;
53*1e149c24SJerome Forissier 		res = crypto_hash_final(ctx, buf, TEE_SM3_HASH_SIZE);
54*1e149c24SJerome Forissier 		if (res)
55*1e149c24SJerome Forissier 			goto out;
56*1e149c24SJerome Forissier 
57*1e149c24SJerome Forissier 		if (remain < TEE_SM3_HASH_SIZE) {
58*1e149c24SJerome Forissier 			memcpy(out, tmp, remain);
59*1e149c24SJerome Forissier 			break;
60*1e149c24SJerome Forissier 		}
61*1e149c24SJerome Forissier 
62*1e149c24SJerome Forissier 		out += TEE_SM3_HASH_SIZE;
63*1e149c24SJerome Forissier 		remain -= TEE_SM3_HASH_SIZE;
64*1e149c24SJerome Forissier 		count++;
65*1e149c24SJerome Forissier 	}
66*1e149c24SJerome Forissier out:
67*1e149c24SJerome Forissier 	crypto_hash_free_ctx(ctx);
68*1e149c24SJerome Forissier 	return res;
69*1e149c24SJerome Forissier }
70*1e149c24SJerome Forissier 
71