1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, Linaro Limited 4 */ 5 6 #include <crypto/crypto.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <tee/tee_cryp_concat_kdf.h> 10 #include <tee/tee_cryp_utl.h> 11 #include <utee_defines.h> 12 13 TEE_Result tee_cryp_concat_kdf(uint32_t hash_id, const uint8_t *shared_secret, 14 size_t shared_secret_len, 15 const uint8_t *other_info, 16 size_t other_info_len, uint8_t *derived_key, 17 size_t derived_key_len) 18 { 19 TEE_Result res; 20 size_t hash_len, i, n, sz; 21 void *ctx = NULL; 22 uint8_t tmp[TEE_MAX_HASH_SIZE]; 23 uint32_t be_count; 24 uint8_t *out = derived_key; 25 uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id); 26 27 res = crypto_hash_alloc_ctx(&ctx, hash_algo); 28 if (res != TEE_SUCCESS) 29 return res; 30 31 res = tee_hash_get_digest_size(hash_algo, &hash_len); 32 if (res != TEE_SUCCESS) 33 goto out; 34 35 n = derived_key_len / hash_len; 36 sz = hash_len; 37 for (i = 1; i <= n + 1; i++) { 38 be_count = TEE_U32_TO_BIG_ENDIAN(i); 39 40 res = crypto_hash_init(ctx, hash_algo); 41 if (res != TEE_SUCCESS) 42 goto out; 43 res = crypto_hash_update(ctx, hash_algo, (uint8_t *)&be_count, 44 sizeof(be_count)); 45 if (res != TEE_SUCCESS) 46 goto out; 47 res = crypto_hash_update(ctx, hash_algo, shared_secret, 48 shared_secret_len); 49 if (res != TEE_SUCCESS) 50 goto out; 51 if (other_info && other_info_len) { 52 res = crypto_hash_update(ctx, hash_algo, other_info, 53 other_info_len); 54 if (res != TEE_SUCCESS) 55 goto out; 56 } 57 res = crypto_hash_final(ctx, hash_algo, tmp, sizeof(tmp)); 58 if (res != TEE_SUCCESS) 59 goto out; 60 61 if (i == n + 1) 62 sz = derived_key_len % hash_len; 63 memcpy(out, tmp, sz); 64 out += sz; 65 } 66 res = TEE_SUCCESS; 67 out: 68 crypto_hash_free_ctx(ctx, hash_algo); 69 return res; 70 } 71