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_alg_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); 41 if (res != TEE_SUCCESS) 42 goto out; 43 res = crypto_hash_update(ctx, (uint8_t *)&be_count, 44 sizeof(be_count)); 45 if (res != TEE_SUCCESS) 46 goto out; 47 res = crypto_hash_update(ctx, shared_secret, shared_secret_len); 48 if (res != TEE_SUCCESS) 49 goto out; 50 if (other_info && other_info_len) { 51 res = crypto_hash_update(ctx, other_info, 52 other_info_len); 53 if (res != TEE_SUCCESS) 54 goto out; 55 } 56 res = crypto_hash_final(ctx, tmp, sizeof(tmp)); 57 if (res != TEE_SUCCESS) 58 goto out; 59 60 if (i == n + 1) 61 sz = derived_key_len % hash_len; 62 memcpy(out, tmp, sz); 63 out += sz; 64 } 65 res = TEE_SUCCESS; 66 out: 67 crypto_hash_free_ctx(ctx); 68 return res; 69 } 70