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 ctx_size, 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_get_ctx_size(hash_algo, &ctx_size); 28 if (res != TEE_SUCCESS) 29 goto out; 30 31 ctx = malloc(ctx_size); 32 if (!ctx) { 33 res = TEE_ERROR_OUT_OF_MEMORY; 34 goto out; 35 } 36 37 res = tee_hash_get_digest_size(hash_algo, &hash_len); 38 if (res != TEE_SUCCESS) 39 goto out; 40 41 n = derived_key_len / hash_len; 42 sz = hash_len; 43 for (i = 1; i <= n + 1; i++) { 44 be_count = TEE_U32_TO_BIG_ENDIAN(i); 45 46 res = crypto_hash_init(ctx, hash_algo); 47 if (res != TEE_SUCCESS) 48 goto out; 49 res = crypto_hash_update(ctx, hash_algo, (uint8_t *)&be_count, 50 sizeof(be_count)); 51 if (res != TEE_SUCCESS) 52 goto out; 53 res = crypto_hash_update(ctx, hash_algo, shared_secret, 54 shared_secret_len); 55 if (res != TEE_SUCCESS) 56 goto out; 57 if (other_info && other_info_len) { 58 res = crypto_hash_update(ctx, hash_algo, other_info, 59 other_info_len); 60 if (res != TEE_SUCCESS) 61 goto out; 62 } 63 res = crypto_hash_final(ctx, hash_algo, tmp, sizeof(tmp)); 64 if (res != TEE_SUCCESS) 65 goto out; 66 67 if (i == n + 1) 68 sz = derived_key_len % hash_len; 69 memcpy(out, tmp, sz); 70 out += sz; 71 } 72 res = TEE_SUCCESS; 73 out: 74 free(ctx); 75 return res; 76 } 77