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