xref: /optee_os/core/tee/tee_cryp_concat_kdf.c (revision 3f4b5250f820ec567422230370fa94e3d6277265)
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 <tee/tee_cryp_concat_kdf.h>
29 #include <tee/tee_cryp_provider.h>
30 #include <tee/tee_cryp_utl.h>
31 #include <utee_defines.h>
32 #include <stdlib.h>
33 #include <string.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 	const struct hash_ops *hash = &crypto_ops.hash;
49 
50 	if (!hash->get_ctx_size || !hash->init || !hash->update ||
51 	    !hash->final) {
52 		res = TEE_ERROR_NOT_IMPLEMENTED;
53 		goto out;
54 	}
55 
56 	res = hash->get_ctx_size(hash_algo, &ctx_size);
57 	if (res != TEE_SUCCESS)
58 		goto out;
59 
60 	ctx = malloc(ctx_size);
61 	if (!ctx) {
62 		res = TEE_ERROR_OUT_OF_MEMORY;
63 		goto out;
64 	}
65 
66 	res = tee_hash_get_digest_size(hash_algo, &hash_len);
67 	if (res != TEE_SUCCESS)
68 		goto out;
69 
70 	n = derived_key_len / hash_len;
71 	sz = hash_len;
72 	for (i = 1; i <= n + 1; i++) {
73 		be_count = TEE_U32_TO_BIG_ENDIAN(i);
74 
75 		res = hash->init(ctx, hash_algo);
76 		if (res != TEE_SUCCESS)
77 			goto out;
78 		res = hash->update(ctx, hash_algo, (uint8_t *)&be_count,
79 				   sizeof(be_count));
80 		if (res != TEE_SUCCESS)
81 			goto out;
82 		res = hash->update(ctx, hash_algo, shared_secret,
83 				   shared_secret_len);
84 		if (res != TEE_SUCCESS)
85 			goto out;
86 		if (other_info && other_info_len) {
87 			res = hash->update(ctx, hash_algo, other_info,
88 					   other_info_len);
89 			if (res != TEE_SUCCESS)
90 				goto out;
91 		}
92 		res = hash->final(ctx, hash_algo, tmp, sizeof(tmp));
93 		if (res != TEE_SUCCESS)
94 			goto out;
95 
96 		if (i == n + 1)
97 			sz = derived_key_len % hash_len;
98 		memcpy(out, tmp, sz);
99 		out += sz;
100 	}
101 	res = TEE_SUCCESS;
102 out:
103 	free(ctx);
104 	return res;
105 }
106