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