]>
Commit | Line | Data |
---|---|---|
d2e9e320 | 1 | /* |
33388b44 | 2 | * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. |
aacfb134 | 3 | * |
7bb803e8 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
d2e9e320 RS |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
aacfb134 AG |
8 | */ |
9 | ||
dbde4726 P |
10 | /* |
11 | * HMAC low level APIs are deprecated for public use, but still ok for internal | |
12 | * use. | |
13 | */ | |
14 | #include "internal/deprecated.h" | |
15 | ||
aacfb134 | 16 | #include <stdlib.h> |
5a285add | 17 | #include <stdarg.h> |
aacfb134 AG |
18 | #include <string.h> |
19 | #include <openssl/hmac.h> | |
aacfb134 | 20 | #include <openssl/evp.h> |
5a285add | 21 | #include <openssl/kdf.h> |
e3405a4a | 22 | #include <openssl/core_names.h> |
aacfb134 | 23 | #include "internal/cryptlib.h" |
cee719c2 | 24 | #include "internal/numbers.h" |
25f2138b | 25 | #include "crypto/evp.h" |
ddd21319 | 26 | #include "prov/provider_ctx.h" |
2b9e4e95 | 27 | #include "prov/providercommon.h" |
ddd21319 | 28 | #include "prov/providercommonerr.h" |
af3e7e1b | 29 | #include "prov/implementations.h" |
ddd21319 | 30 | #include "prov/provider_util.h" |
e3405a4a | 31 | #include "e_os.h" |
aacfb134 AG |
32 | |
33 | #define HKDF_MAXBUF 1024 | |
34 | ||
363b1e5d DMSP |
35 | static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_new; |
36 | static OSSL_FUNC_kdf_freectx_fn kdf_hkdf_free; | |
37 | static OSSL_FUNC_kdf_reset_fn kdf_hkdf_reset; | |
38 | static OSSL_FUNC_kdf_derive_fn kdf_hkdf_derive; | |
39 | static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_hkdf_settable_ctx_params; | |
40 | static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params; | |
41 | static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params; | |
42 | static OSSL_FUNC_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params; | |
e3405a4a | 43 | |
5a285add DM |
44 | static int HKDF(const EVP_MD *evp_md, |
45 | const unsigned char *salt, size_t salt_len, | |
46 | const unsigned char *key, size_t key_len, | |
47 | const unsigned char *info, size_t info_len, | |
48 | unsigned char *okm, size_t okm_len); | |
49 | static int HKDF_Extract(const EVP_MD *evp_md, | |
50 | const unsigned char *salt, size_t salt_len, | |
e7018588 | 51 | const unsigned char *ikm, size_t ikm_len, |
5a285add DM |
52 | unsigned char *prk, size_t prk_len); |
53 | static int HKDF_Expand(const EVP_MD *evp_md, | |
54 | const unsigned char *prk, size_t prk_len, | |
55 | const unsigned char *info, size_t info_len, | |
56 | unsigned char *okm, size_t okm_len); | |
57 | ||
e3405a4a P |
58 | typedef struct { |
59 | void *provctx; | |
d2139cf8 | 60 | int mode; |
86f17ed6 | 61 | PROV_DIGEST digest; |
aacfb134 AG |
62 | unsigned char *salt; |
63 | size_t salt_len; | |
64 | unsigned char *key; | |
65 | size_t key_len; | |
66 | unsigned char info[HKDF_MAXBUF]; | |
67 | size_t info_len; | |
e3405a4a | 68 | } KDF_HKDF; |
aacfb134 | 69 | |
e3405a4a | 70 | static void *kdf_hkdf_new(void *provctx) |
aacfb134 | 71 | { |
e3405a4a | 72 | KDF_HKDF *ctx; |
aacfb134 | 73 | |
2b9e4e95 P |
74 | if (!ossl_prov_is_running()) |
75 | return NULL; | |
76 | ||
e3405a4a P |
77 | if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) |
78 | ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); | |
79 | else | |
80 | ctx->provctx = provctx; | |
81 | return ctx; | |
5a285add | 82 | } |
aacfb134 | 83 | |
e3405a4a | 84 | static void kdf_hkdf_free(void *vctx) |
5a285add | 85 | { |
e3405a4a | 86 | KDF_HKDF *ctx = (KDF_HKDF *)vctx; |
aacfb134 | 87 | |
3c659415 P |
88 | if (ctx != NULL) { |
89 | kdf_hkdf_reset(ctx); | |
90 | OPENSSL_free(ctx); | |
91 | } | |
aacfb134 AG |
92 | } |
93 | ||
e3405a4a | 94 | static void kdf_hkdf_reset(void *vctx) |
aacfb134 | 95 | { |
e3405a4a | 96 | KDF_HKDF *ctx = (KDF_HKDF *)vctx; |
0577959c | 97 | void *provctx = ctx->provctx; |
aacfb134 | 98 | |
86f17ed6 | 99 | ossl_prov_digest_reset(&ctx->digest); |
e3405a4a P |
100 | OPENSSL_free(ctx->salt); |
101 | OPENSSL_clear_free(ctx->key, ctx->key_len); | |
102 | OPENSSL_cleanse(ctx->info, ctx->info_len); | |
103 | memset(ctx, 0, sizeof(*ctx)); | |
0577959c | 104 | ctx->provctx = provctx; |
aacfb134 AG |
105 | } |
106 | ||
e3405a4a | 107 | static size_t kdf_hkdf_size(KDF_HKDF *ctx) |
ca55d70b | 108 | { |
97cc9c9b | 109 | int sz; |
86f17ed6 | 110 | const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); |
97cc9c9b | 111 | |
e3405a4a | 112 | if (ctx->mode != EVP_KDF_HKDF_MODE_EXTRACT_ONLY) |
5a285add | 113 | return SIZE_MAX; |
ca55d70b | 114 | |
86f17ed6 | 115 | if (md == NULL) { |
e3405a4a | 116 | ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); |
5a285add DM |
117 | return 0; |
118 | } | |
86f17ed6 | 119 | sz = EVP_MD_size(md); |
97cc9c9b SL |
120 | if (sz < 0) |
121 | return 0; | |
122 | ||
123 | return sz; | |
ca55d70b MC |
124 | } |
125 | ||
e3405a4a | 126 | static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen) |
aacfb134 | 127 | { |
e3405a4a | 128 | KDF_HKDF *ctx = (KDF_HKDF *)vctx; |
2b9e4e95 P |
129 | const EVP_MD *md; |
130 | ||
131 | if (!ossl_prov_is_running()) | |
132 | return 0; | |
e3405a4a | 133 | |
2b9e4e95 | 134 | md = ossl_prov_digest_md(&ctx->digest); |
86f17ed6 | 135 | if (md == NULL) { |
e3405a4a | 136 | ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); |
f55129c7 JB |
137 | return 0; |
138 | } | |
e3405a4a P |
139 | if (ctx->key == NULL) { |
140 | ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); | |
aacfb134 | 141 | return 0; |
e65f6509 | 142 | } |
1cae59d1 JS |
143 | if (keylen == 0) { |
144 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); | |
145 | return 0; | |
146 | } | |
aacfb134 | 147 | |
e3405a4a | 148 | switch (ctx->mode) { |
5a285add | 149 | case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND: |
86f17ed6 | 150 | return HKDF(md, ctx->salt, ctx->salt_len, ctx->key, |
e3405a4a | 151 | ctx->key_len, ctx->info, ctx->info_len, key, |
5a285add | 152 | keylen); |
d2139cf8 | 153 | |
5a285add | 154 | case EVP_KDF_HKDF_MODE_EXTRACT_ONLY: |
86f17ed6 | 155 | return HKDF_Extract(md, ctx->salt, ctx->salt_len, ctx->key, |
e3405a4a | 156 | ctx->key_len, key, keylen); |
d2139cf8 | 157 | |
5a285add | 158 | case EVP_KDF_HKDF_MODE_EXPAND_ONLY: |
86f17ed6 | 159 | return HKDF_Expand(md, ctx->key, ctx->key_len, ctx->info, |
e3405a4a | 160 | ctx->info_len, key, keylen); |
d2139cf8 MC |
161 | |
162 | default: | |
aacfb134 AG |
163 | return 0; |
164 | } | |
aacfb134 AG |
165 | } |
166 | ||
e3405a4a P |
167 | static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) |
168 | { | |
169 | const OSSL_PARAM *p; | |
170 | KDF_HKDF *ctx = vctx; | |
86f17ed6 | 171 | OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); |
e3405a4a | 172 | int n; |
86f17ed6 P |
173 | |
174 | if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx)) | |
175 | return 0; | |
e3405a4a P |
176 | |
177 | if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE)) != NULL) { | |
178 | if (p->data_type == OSSL_PARAM_UTF8_STRING) { | |
179 | if (strcasecmp(p->data, "EXTRACT_AND_EXPAND") == 0) { | |
180 | ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND; | |
181 | } else if (strcasecmp(p->data, "EXTRACT_ONLY") == 0) { | |
182 | ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY; | |
183 | } else if (strcasecmp(p->data, "EXPAND_ONLY") == 0) { | |
184 | ctx->mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY; | |
185 | } else { | |
186 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); | |
187 | return 0; | |
188 | } | |
189 | } else if (OSSL_PARAM_get_int(p, &n)) { | |
190 | if (n != EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND | |
191 | && n != EVP_KDF_HKDF_MODE_EXTRACT_ONLY | |
192 | && n != EVP_KDF_HKDF_MODE_EXPAND_ONLY) { | |
193 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); | |
194 | return 0; | |
195 | } | |
196 | ctx->mode = n; | |
197 | } else { | |
198 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); | |
199 | return 0; | |
200 | } | |
201 | } | |
202 | ||
203 | if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL) { | |
204 | OPENSSL_clear_free(ctx->key, ctx->key_len); | |
205 | ctx->key = NULL; | |
206 | if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->key, 0, | |
207 | &ctx->key_len)) | |
208 | return 0; | |
209 | } | |
210 | ||
211 | if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) { | |
212 | if (p->data_size != 0 && p->data != NULL) { | |
213 | OPENSSL_free(ctx->salt); | |
214 | ctx->salt = NULL; | |
215 | if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0, | |
216 | &ctx->salt_len)) | |
217 | return 0; | |
218 | } | |
219 | } | |
220 | /* The info fields concatenate, so process them all */ | |
221 | if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL) { | |
222 | ctx->info_len = 0; | |
223 | for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, | |
224 | OSSL_KDF_PARAM_INFO)) { | |
225 | const void *q = ctx->info + ctx->info_len; | |
226 | size_t sz = 0; | |
227 | ||
228 | if (p->data_size != 0 | |
229 | && p->data != NULL | |
230 | && !OSSL_PARAM_get_octet_string(p, (void **)&q, | |
231 | HKDF_MAXBUF - ctx->info_len, | |
232 | &sz)) | |
233 | return 0; | |
234 | ctx->info_len += sz; | |
235 | } | |
236 | } | |
237 | return 1; | |
238 | } | |
239 | ||
1017ab21 | 240 | static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(ossl_unused void *provctx) |
e3405a4a P |
241 | { |
242 | static const OSSL_PARAM known_settable_ctx_params[] = { | |
243 | OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), | |
244 | OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL), | |
245 | OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), | |
246 | OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), | |
247 | OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0), | |
248 | OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), | |
249 | OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0), | |
250 | OSSL_PARAM_END | |
251 | }; | |
252 | return known_settable_ctx_params; | |
253 | } | |
254 | ||
255 | static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) | |
256 | { | |
257 | KDF_HKDF *ctx = (KDF_HKDF *)vctx; | |
258 | OSSL_PARAM *p; | |
259 | ||
260 | if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) | |
261 | return OSSL_PARAM_set_size_t(p, kdf_hkdf_size(ctx)); | |
262 | return -2; | |
263 | } | |
264 | ||
1017ab21 | 265 | static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *provctx) |
e3405a4a P |
266 | { |
267 | static const OSSL_PARAM known_gettable_ctx_params[] = { | |
268 | OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), | |
269 | OSSL_PARAM_END | |
270 | }; | |
271 | return known_gettable_ctx_params; | |
272 | } | |
273 | ||
1be63951 | 274 | const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = { |
e3405a4a P |
275 | { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new }, |
276 | { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free }, | |
277 | { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset }, | |
278 | { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_hkdf_derive }, | |
279 | { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, | |
280 | (void(*)(void))kdf_hkdf_settable_ctx_params }, | |
281 | { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_hkdf_set_ctx_params }, | |
282 | { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, | |
283 | (void(*)(void))kdf_hkdf_gettable_ctx_params }, | |
284 | { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params }, | |
285 | { 0, NULL } | |
aacfb134 AG |
286 | }; |
287 | ||
e7018588 DM |
288 | /* |
289 | * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)" | |
290 | * Section 2 (https://tools.ietf.org/html/rfc5869#section-2) and | |
291 | * "Cryptographic Extraction and Key Derivation: The HKDF Scheme" | |
292 | * Section 4.2 (https://eprint.iacr.org/2010/264.pdf). | |
293 | * | |
294 | * From the paper: | |
295 | * The scheme HKDF is specified as: | |
296 | * HKDF(XTS, SKM, CTXinfo, L) = K(1) | K(2) | ... | K(t) | |
297 | * | |
298 | * where: | |
299 | * SKM is source key material | |
300 | * XTS is extractor salt (which may be null or constant) | |
301 | * CTXinfo is context information (may be null) | |
302 | * L is the number of key bits to be produced by KDF | |
303 | * k is the output length in bits of the hash function used with HMAC | |
304 | * t = ceil(L/k) | |
305 | * the value K(t) is truncated to its first d = L mod k bits. | |
306 | * | |
307 | * From RFC 5869: | |
308 | * 2.2. Step 1: Extract | |
309 | * HKDF-Extract(salt, IKM) -> PRK | |
310 | * 2.3. Step 2: Expand | |
311 | * HKDF-Expand(PRK, info, L) -> OKM | |
312 | */ | |
5a285add DM |
313 | static int HKDF(const EVP_MD *evp_md, |
314 | const unsigned char *salt, size_t salt_len, | |
e7018588 | 315 | const unsigned char *ikm, size_t ikm_len, |
5a285add DM |
316 | const unsigned char *info, size_t info_len, |
317 | unsigned char *okm, size_t okm_len) | |
aacfb134 AG |
318 | { |
319 | unsigned char prk[EVP_MAX_MD_SIZE]; | |
97cc9c9b SL |
320 | int ret, sz; |
321 | size_t prk_len; | |
322 | ||
323 | sz = EVP_MD_size(evp_md); | |
324 | if (sz < 0) | |
325 | return 0; | |
326 | prk_len = (size_t)sz; | |
aacfb134 | 327 | |
e7018588 DM |
328 | /* Step 1: HKDF-Extract(salt, IKM) -> PRK */ |
329 | if (!HKDF_Extract(evp_md, salt, salt_len, ikm, ikm_len, prk, prk_len)) | |
5a285add | 330 | return 0; |
aacfb134 | 331 | |
e7018588 | 332 | /* Step 2: HKDF-Expand(PRK, info, L) -> OKM */ |
d2139cf8 MC |
333 | ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len); |
334 | OPENSSL_cleanse(prk, sizeof(prk)); | |
335 | ||
336 | return ret; | |
aacfb134 AG |
337 | } |
338 | ||
e7018588 DM |
339 | /* |
340 | * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)" | |
341 | * Section 2.2 (https://tools.ietf.org/html/rfc5869#section-2.2). | |
342 | * | |
343 | * 2.2. Step 1: Extract | |
344 | * | |
345 | * HKDF-Extract(salt, IKM) -> PRK | |
346 | * | |
347 | * Options: | |
348 | * Hash a hash function; HashLen denotes the length of the | |
349 | * hash function output in octets | |
350 | * | |
351 | * Inputs: | |
352 | * salt optional salt value (a non-secret random value); | |
353 | * if not provided, it is set to a string of HashLen zeros. | |
354 | * IKM input keying material | |
355 | * | |
356 | * Output: | |
357 | * PRK a pseudorandom key (of HashLen octets) | |
358 | * | |
359 | * The output PRK is calculated as follows: | |
360 | * | |
361 | * PRK = HMAC-Hash(salt, IKM) | |
362 | */ | |
5a285add DM |
363 | static int HKDF_Extract(const EVP_MD *evp_md, |
364 | const unsigned char *salt, size_t salt_len, | |
e7018588 | 365 | const unsigned char *ikm, size_t ikm_len, |
5a285add | 366 | unsigned char *prk, size_t prk_len) |
aacfb134 | 367 | { |
97cc9c9b SL |
368 | int sz = EVP_MD_size(evp_md); |
369 | ||
370 | if (sz < 0) | |
371 | return 0; | |
372 | if (prk_len != (size_t)sz) { | |
e3405a4a | 373 | ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_OUTPUT_BUFFER_SIZE); |
5a285add DM |
374 | return 0; |
375 | } | |
e7018588 DM |
376 | /* calc: PRK = HMAC-Hash(salt, IKM) */ |
377 | return HMAC(evp_md, salt, salt_len, ikm, ikm_len, prk, NULL) != NULL; | |
aacfb134 AG |
378 | } |
379 | ||
e7018588 DM |
380 | /* |
381 | * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)" | |
382 | * Section 2.3 (https://tools.ietf.org/html/rfc5869#section-2.3). | |
383 | * | |
384 | * 2.3. Step 2: Expand | |
385 | * | |
386 | * HKDF-Expand(PRK, info, L) -> OKM | |
387 | * | |
388 | * Options: | |
389 | * Hash a hash function; HashLen denotes the length of the | |
390 | * hash function output in octets | |
391 | * | |
392 | * Inputs: | |
393 | * PRK a pseudorandom key of at least HashLen octets | |
394 | * (usually, the output from the extract step) | |
395 | * info optional context and application specific information | |
396 | * (can be a zero-length string) | |
397 | * L length of output keying material in octets | |
398 | * (<= 255*HashLen) | |
399 | * | |
400 | * Output: | |
401 | * OKM output keying material (of L octets) | |
402 | * | |
403 | * The output OKM is calculated as follows: | |
404 | * | |
405 | * N = ceil(L/HashLen) | |
406 | * T = T(1) | T(2) | T(3) | ... | T(N) | |
407 | * OKM = first L octets of T | |
408 | * | |
409 | * where: | |
410 | * T(0) = empty string (zero length) | |
411 | * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01) | |
412 | * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02) | |
413 | * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03) | |
414 | * ... | |
415 | * | |
416 | * (where the constant concatenated to the end of each T(n) is a | |
417 | * single octet.) | |
418 | */ | |
5a285add DM |
419 | static int HKDF_Expand(const EVP_MD *evp_md, |
420 | const unsigned char *prk, size_t prk_len, | |
421 | const unsigned char *info, size_t info_len, | |
422 | unsigned char *okm, size_t okm_len) | |
aacfb134 AG |
423 | { |
424 | HMAC_CTX *hmac; | |
97cc9c9b | 425 | int ret = 0, sz; |
aacfb134 | 426 | unsigned int i; |
aacfb134 | 427 | unsigned char prev[EVP_MAX_MD_SIZE]; |
97cc9c9b SL |
428 | size_t done_len = 0, dig_len, n; |
429 | ||
430 | sz = EVP_MD_size(evp_md); | |
431 | if (sz <= 0) | |
432 | return 0; | |
433 | dig_len = (size_t)sz; | |
5a285add | 434 | |
e7018588 DM |
435 | /* calc: N = ceil(L/HashLen) */ |
436 | n = okm_len / dig_len; | |
aacfb134 AG |
437 | if (okm_len % dig_len) |
438 | n++; | |
439 | ||
d2139cf8 | 440 | if (n > 255 || okm == NULL) |
5a285add | 441 | return 0; |
aacfb134 AG |
442 | |
443 | if ((hmac = HMAC_CTX_new()) == NULL) | |
5a285add | 444 | return 0; |
aacfb134 AG |
445 | |
446 | if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL)) | |
447 | goto err; | |
448 | ||
449 | for (i = 1; i <= n; i++) { | |
450 | size_t copy_len; | |
451 | const unsigned char ctr = i; | |
452 | ||
e7018588 | 453 | /* calc: T(i) = HMAC-Hash(PRK, T(i - 1) | info | i) */ |
aacfb134 AG |
454 | if (i > 1) { |
455 | if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL)) | |
456 | goto err; | |
457 | ||
458 | if (!HMAC_Update(hmac, prev, dig_len)) | |
459 | goto err; | |
460 | } | |
461 | ||
462 | if (!HMAC_Update(hmac, info, info_len)) | |
463 | goto err; | |
464 | ||
465 | if (!HMAC_Update(hmac, &ctr, 1)) | |
466 | goto err; | |
467 | ||
468 | if (!HMAC_Final(hmac, prev, NULL)) | |
469 | goto err; | |
470 | ||
471 | copy_len = (done_len + dig_len > okm_len) ? | |
472 | okm_len - done_len : | |
473 | dig_len; | |
474 | ||
475 | memcpy(okm + done_len, prev, copy_len); | |
476 | ||
477 | done_len += copy_len; | |
478 | } | |
5a285add | 479 | ret = 1; |
aacfb134 AG |
480 | |
481 | err: | |
64ed55ab | 482 | OPENSSL_cleanse(prev, sizeof(prev)); |
aacfb134 | 483 | HMAC_CTX_free(hmac); |
64ed55ab | 484 | return ret; |
aacfb134 | 485 | } |