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