11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
28854d3c6SJerome Forissier /*
38854d3c6SJerome Forissier * Copyright (c) 2014, Linaro Limited
48854d3c6SJerome Forissier */
58854d3c6SJerome Forissier
6e1770e71SJens Wiklander #include <crypto/crypto.h>
78854d3c6SJerome Forissier #include <stdlib.h>
88854d3c6SJerome Forissier #include <string.h>
9e1770e71SJens Wiklander #include <tee/tee_cryp_concat_kdf.h>
10e1770e71SJens Wiklander #include <tee/tee_cryp_utl.h>
11e1770e71SJens Wiklander #include <utee_defines.h>
128854d3c6SJerome Forissier
tee_cryp_concat_kdf(uint32_t hash_id,const uint8_t * shared_secret,size_t shared_secret_len,const uint8_t * other_info,size_t other_info_len,uint8_t * derived_key,size_t derived_key_len)138854d3c6SJerome Forissier TEE_Result tee_cryp_concat_kdf(uint32_t hash_id, const uint8_t *shared_secret,
148854d3c6SJerome Forissier size_t shared_secret_len,
158854d3c6SJerome Forissier const uint8_t *other_info,
168854d3c6SJerome Forissier size_t other_info_len, uint8_t *derived_key,
178854d3c6SJerome Forissier size_t derived_key_len)
188854d3c6SJerome Forissier {
198854d3c6SJerome Forissier TEE_Result res;
20ecf2e014SJens Wiklander size_t hash_len, i, n, sz;
218854d3c6SJerome Forissier void *ctx = NULL;
228854d3c6SJerome Forissier uint8_t tmp[TEE_MAX_HASH_SIZE];
238854d3c6SJerome Forissier uint32_t be_count;
248854d3c6SJerome Forissier uint8_t *out = derived_key;
258854d3c6SJerome Forissier uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id);
268854d3c6SJerome Forissier
27ecf2e014SJens Wiklander res = crypto_hash_alloc_ctx(&ctx, hash_algo);
288854d3c6SJerome Forissier if (res != TEE_SUCCESS)
29ecf2e014SJens Wiklander return res;
308854d3c6SJerome Forissier
31*7c767434SAlbert Schwarzkopf res = tee_alg_get_digest_size(hash_algo, &hash_len);
328854d3c6SJerome Forissier if (res != TEE_SUCCESS)
338854d3c6SJerome Forissier goto out;
348854d3c6SJerome Forissier
358854d3c6SJerome Forissier n = derived_key_len / hash_len;
368854d3c6SJerome Forissier sz = hash_len;
378854d3c6SJerome Forissier for (i = 1; i <= n + 1; i++) {
388854d3c6SJerome Forissier be_count = TEE_U32_TO_BIG_ENDIAN(i);
398854d3c6SJerome Forissier
406b3a371cSJens Wiklander res = crypto_hash_init(ctx);
418854d3c6SJerome Forissier if (res != TEE_SUCCESS)
428854d3c6SJerome Forissier goto out;
436b3a371cSJens Wiklander res = crypto_hash_update(ctx, (uint8_t *)&be_count,
448854d3c6SJerome Forissier sizeof(be_count));
458854d3c6SJerome Forissier if (res != TEE_SUCCESS)
468854d3c6SJerome Forissier goto out;
476b3a371cSJens Wiklander res = crypto_hash_update(ctx, shared_secret, shared_secret_len);
488854d3c6SJerome Forissier if (res != TEE_SUCCESS)
498854d3c6SJerome Forissier goto out;
508854d3c6SJerome Forissier if (other_info && other_info_len) {
516b3a371cSJens Wiklander res = crypto_hash_update(ctx, other_info,
528854d3c6SJerome Forissier other_info_len);
538854d3c6SJerome Forissier if (res != TEE_SUCCESS)
548854d3c6SJerome Forissier goto out;
558854d3c6SJerome Forissier }
566b3a371cSJens Wiklander res = crypto_hash_final(ctx, tmp, sizeof(tmp));
578854d3c6SJerome Forissier if (res != TEE_SUCCESS)
588854d3c6SJerome Forissier goto out;
598854d3c6SJerome Forissier
608854d3c6SJerome Forissier if (i == n + 1)
618854d3c6SJerome Forissier sz = derived_key_len % hash_len;
628854d3c6SJerome Forissier memcpy(out, tmp, sz);
638854d3c6SJerome Forissier out += sz;
648854d3c6SJerome Forissier }
658854d3c6SJerome Forissier res = TEE_SUCCESS;
668854d3c6SJerome Forissier out:
676b3a371cSJens Wiklander crypto_hash_free_ctx(ctx);
688854d3c6SJerome Forissier return res;
698854d3c6SJerome Forissier }
70