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