xref: /optee_os/core/tee/tee_cryp_concat_kdf.c (revision 1bb929836182ecb96d2d9d268daa807c67596396)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, Linaro Limited
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <crypto/crypto.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <tee/tee_cryp_concat_kdf.h>
33 #include <tee/tee_cryp_utl.h>
34 #include <utee_defines.h>
35 
36 TEE_Result tee_cryp_concat_kdf(uint32_t hash_id, const uint8_t *shared_secret,
37 			       size_t shared_secret_len,
38 			       const uint8_t *other_info,
39 			       size_t other_info_len, uint8_t *derived_key,
40 			       size_t derived_key_len)
41 {
42 	TEE_Result res;
43 	size_t ctx_size, hash_len, i, n, sz;
44 	void *ctx = NULL;
45 	uint8_t tmp[TEE_MAX_HASH_SIZE];
46 	uint32_t be_count;
47 	uint8_t *out = derived_key;
48 	uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id);
49 
50 	res = crypto_hash_get_ctx_size(hash_algo, &ctx_size);
51 	if (res != TEE_SUCCESS)
52 		goto out;
53 
54 	ctx = malloc(ctx_size);
55 	if (!ctx) {
56 		res = TEE_ERROR_OUT_OF_MEMORY;
57 		goto out;
58 	}
59 
60 	res = tee_hash_get_digest_size(hash_algo, &hash_len);
61 	if (res != TEE_SUCCESS)
62 		goto out;
63 
64 	n = derived_key_len / hash_len;
65 	sz = hash_len;
66 	for (i = 1; i <= n + 1; i++) {
67 		be_count = TEE_U32_TO_BIG_ENDIAN(i);
68 
69 		res = crypto_hash_init(ctx, hash_algo);
70 		if (res != TEE_SUCCESS)
71 			goto out;
72 		res = crypto_hash_update(ctx, hash_algo, (uint8_t *)&be_count,
73 				   sizeof(be_count));
74 		if (res != TEE_SUCCESS)
75 			goto out;
76 		res = crypto_hash_update(ctx, hash_algo, shared_secret,
77 				   shared_secret_len);
78 		if (res != TEE_SUCCESS)
79 			goto out;
80 		if (other_info && other_info_len) {
81 			res = crypto_hash_update(ctx, hash_algo, other_info,
82 					   other_info_len);
83 			if (res != TEE_SUCCESS)
84 				goto out;
85 		}
86 		res = crypto_hash_final(ctx, hash_algo, tmp, sizeof(tmp));
87 		if (res != TEE_SUCCESS)
88 			goto out;
89 
90 		if (i == n + 1)
91 			sz = derived_key_len % hash_len;
92 		memcpy(out, tmp, sz);
93 		out += sz;
94 	}
95 	res = TEE_SUCCESS;
96 out:
97 	free(ctx);
98 	return res;
99 }
100