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 */ 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