xref: /optee_os/core/tee/tee_cryp_hkdf.c (revision b1469ba0bfd0371eb52bd50f5c52eeda7a8f5f1e)
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_hkdf.h>
32 #include <tee/tee_cryp_utl.h>
33 #include <utee_defines.h>
34 
35 
36 static const uint8_t zero_salt[TEE_MAX_HASH_SIZE];
37 
38 static TEE_Result hkdf_extract(uint32_t hash_id, const uint8_t *ikm,
39 			       size_t ikm_len, const uint8_t *salt,
40 			       size_t salt_len, uint8_t *prk, size_t *prk_len)
41 {
42 	TEE_Result res;
43 	size_t ctx_size;
44 	void *ctx = NULL;
45 	uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id);
46 	uint32_t hmac_algo = (TEE_OPERATION_MAC << 28) | hash_id;
47 
48 	if (!salt || !salt_len) {
49 		/*
50 		 * RFC 5869 section 2.2:
51 		 * If not provided, [the salt] is set to a string of HashLen
52 		 * zeros
53 		 */
54 		salt = zero_salt;
55 		res = tee_hash_get_digest_size(hash_algo, &salt_len);
56 		if (res != TEE_SUCCESS)
57 			goto out;
58 	}
59 
60 	res = crypto_mac_get_ctx_size(hmac_algo, &ctx_size);
61 	if (res != TEE_SUCCESS)
62 		goto out;
63 
64 	ctx = malloc(ctx_size);
65 	if (!ctx) {
66 		res = TEE_ERROR_OUT_OF_MEMORY;
67 		goto out;
68 	}
69 
70 	/*
71 	 * RFC 5869 section 2.1: "Note that in the extract step, 'IKM' is used
72 	 * as the HMAC input, not as the HMAC key."
73 	 * Therefore, salt is the HMAC key in the formula from section 2.2:
74 	 * "PRK = HMAC-Hash(salt, IKM)"
75 	 */
76 	res = crypto_mac_init(ctx, hmac_algo, salt, salt_len);
77 	if (res != TEE_SUCCESS)
78 		goto out;
79 
80 	res = crypto_mac_update(ctx, hmac_algo, ikm, ikm_len);
81 	if (res != TEE_SUCCESS)
82 		goto out;
83 
84 	res = crypto_mac_final(ctx, hmac_algo, prk, *prk_len);
85 	if (res != TEE_SUCCESS)
86 		goto out;
87 
88 	res = tee_hash_get_digest_size(hash_algo, prk_len);
89 out:
90 	free(ctx);
91 	return res;
92 }
93 
94 static TEE_Result hkdf_expand(uint32_t hash_id, const uint8_t *prk,
95 			      size_t prk_len, const uint8_t *info,
96 			      size_t info_len, uint8_t *okm, size_t okm_len)
97 {
98 	uint8_t tn[TEE_MAX_HASH_SIZE];
99 	size_t tn_len, hash_len, i, n, where, ctx_size;
100 	TEE_Result res = TEE_SUCCESS;
101 	void *ctx = NULL;
102 	uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id);
103 	uint32_t hmac_algo = TEE_ALG_HMAC_ALGO(hash_id);
104 
105 	res = tee_hash_get_digest_size(hash_algo, &hash_len);
106 	if (res != TEE_SUCCESS)
107 		goto out;
108 
109 	if (!okm || prk_len < hash_len) {
110 		res = TEE_ERROR_BAD_STATE;
111 		goto out;
112 	}
113 
114 	if (!info)
115 		info_len = 0;
116 
117 	res = crypto_mac_get_ctx_size(hmac_algo, &ctx_size);
118 	if (res != TEE_SUCCESS)
119 		goto out;
120 
121 	ctx = malloc(ctx_size);
122 	if (!ctx) {
123 		res = TEE_ERROR_OUT_OF_MEMORY;
124 		goto out;
125 	}
126 
127 	/* N = ceil(L/HashLen) */
128 	n = okm_len / hash_len;
129 	if ((okm_len % hash_len) != 0)
130 		n++;
131 
132 	if (n > 255) {
133 		res = TEE_ERROR_BAD_PARAMETERS;
134 		goto out;
135 	}
136 
137 
138 	/*
139 	 * RFC 5869 section 2.3
140 	 *   T = T(1) | T(2) | T(3) | ... | T(N)
141 	 *   OKM = first L octets of T
142 	 *   T(0) = empty string (zero length)
143 	 *   T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
144 	 *   T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
145 	 *   T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
146 	 *   ...
147 	 */
148 	tn_len = 0;
149 	where = 0;
150 	for (i = 1; i <= n; i++) {
151 		uint8_t c = i;
152 
153 		res = crypto_mac_init(ctx, hmac_algo, prk, prk_len);
154 		if (res != TEE_SUCCESS)
155 			goto out;
156 		res = crypto_mac_update(ctx, hmac_algo, tn, tn_len);
157 		if (res != TEE_SUCCESS)
158 			goto out;
159 		res = crypto_mac_update(ctx, hmac_algo, info, info_len);
160 		if (res != TEE_SUCCESS)
161 			goto out;
162 		res = crypto_mac_update(ctx, hmac_algo, &c, 1);
163 		if (res != TEE_SUCCESS)
164 			goto out;
165 		res = crypto_mac_final(ctx, hmac_algo, tn, sizeof(tn));
166 		if (res != TEE_SUCCESS)
167 			goto out;
168 
169 		memcpy(okm + where, tn, (i < n) ? hash_len : (okm_len - where));
170 		where += hash_len;
171 		tn_len = hash_len;
172 	}
173 
174 out:
175 	free(ctx);
176 	return res;
177 }
178 
179 TEE_Result tee_cryp_hkdf(uint32_t hash_id, const uint8_t *ikm, size_t ikm_len,
180 			 const uint8_t *salt, size_t salt_len,
181 			 const uint8_t *info, size_t info_len, uint8_t *okm,
182 			 size_t okm_len)
183 {
184 	TEE_Result res;
185 	uint8_t prk[TEE_MAX_HASH_SIZE];
186 	size_t prk_len = sizeof(prk);
187 
188 	res = hkdf_extract(hash_id, ikm, ikm_len, salt, salt_len, prk,
189 			   &prk_len);
190 	if (res != TEE_SUCCESS)
191 		return res;
192 	res = hkdf_expand(hash_id, prk, prk_len, info, info_len, okm,
193 			  okm_len);
194 
195 	return res;
196 }
197