Unix build: for mingw and cygwin, create the right location for DLLs
[openssl.git] / crypto / kdf / hkdf.c
1 /*
2  * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
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
8  */
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <openssl/hmac.h>
13 #include <openssl/kdf.h>
14 #include <openssl/evp.h>
15 #include "internal/cryptlib.h"
16 #include "internal/evp_int.h"
17
18 #define HKDF_MAXBUF 1024
19
20 static unsigned char *HKDF(const EVP_MD *evp_md,
21                            const unsigned char *salt, size_t salt_len,
22                            const unsigned char *key, size_t key_len,
23                            const unsigned char *info, size_t info_len,
24                            unsigned char *okm, size_t okm_len);
25
26 static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
27                                    const unsigned char *salt, size_t salt_len,
28                                    const unsigned char *key, size_t key_len,
29                                    unsigned char *prk, size_t *prk_len);
30
31 static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
32                                   const unsigned char *prk, size_t prk_len,
33                                   const unsigned char *info, size_t info_len,
34                                   unsigned char *okm, size_t okm_len);
35
36 typedef struct {
37     int mode;
38     const EVP_MD *md;
39     unsigned char *salt;
40     size_t salt_len;
41     unsigned char *key;
42     size_t key_len;
43     unsigned char info[HKDF_MAXBUF];
44     size_t info_len;
45 } HKDF_PKEY_CTX;
46
47 static int pkey_hkdf_init(EVP_PKEY_CTX *ctx)
48 {
49     HKDF_PKEY_CTX *kctx;
50
51     if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) {
52         KDFerr(KDF_F_PKEY_HKDF_INIT, ERR_R_MALLOC_FAILURE);
53         return 0;
54     }
55
56     ctx->data = kctx;
57
58     return 1;
59 }
60
61 static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx)
62 {
63     HKDF_PKEY_CTX *kctx = ctx->data;
64     OPENSSL_clear_free(kctx->salt, kctx->salt_len);
65     OPENSSL_clear_free(kctx->key, kctx->key_len);
66     OPENSSL_cleanse(kctx->info, kctx->info_len);
67     OPENSSL_free(kctx);
68 }
69
70 static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
71 {
72     HKDF_PKEY_CTX *kctx = ctx->data;
73
74     switch (type) {
75     case EVP_PKEY_CTRL_HKDF_MD:
76         if (p2 == NULL)
77             return 0;
78
79         kctx->md = p2;
80         return 1;
81
82     case EVP_PKEY_CTRL_HKDF_MODE:
83         kctx->mode = p1;
84         return 1;
85
86     case EVP_PKEY_CTRL_HKDF_SALT:
87         if (p1 == 0 || p2 == NULL)
88             return 1;
89
90         if (p1 < 0)
91             return 0;
92
93         if (kctx->salt != NULL)
94             OPENSSL_clear_free(kctx->salt, kctx->salt_len);
95
96         kctx->salt = OPENSSL_memdup(p2, p1);
97         if (kctx->salt == NULL)
98             return 0;
99
100         kctx->salt_len = p1;
101         return 1;
102
103     case EVP_PKEY_CTRL_HKDF_KEY:
104         if (p1 < 0)
105             return 0;
106
107         if (kctx->key != NULL)
108             OPENSSL_clear_free(kctx->key, kctx->key_len);
109
110         kctx->key = OPENSSL_memdup(p2, p1);
111         if (kctx->key == NULL)
112             return 0;
113
114         kctx->key_len  = p1;
115         return 1;
116
117     case EVP_PKEY_CTRL_HKDF_INFO:
118         if (p1 == 0 || p2 == NULL)
119             return 1;
120
121         if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len))
122             return 0;
123
124         memcpy(kctx->info + kctx->info_len, p2, p1);
125         kctx->info_len += p1;
126         return 1;
127
128     default:
129         return -2;
130
131     }
132 }
133
134 static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
135                               const char *value)
136 {
137     if (strcmp(type, "mode") == 0) {
138         int mode;
139
140         if (strcmp(value, "EXTRACT_AND_EXPAND") == 0)
141             mode = EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND;
142         else if (strcmp(value, "EXTRACT_ONLY") == 0)
143             mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY;
144         else if (strcmp(value, "EXPAND_ONLY") == 0)
145             mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
146         else
147             return 0;
148
149         return EVP_PKEY_CTX_hkdf_mode(ctx, mode);
150     }
151
152     if (strcmp(type, "md") == 0)
153         return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_DERIVE,
154                                EVP_PKEY_CTRL_HKDF_MD, value);
155
156     if (strcmp(type, "salt") == 0)
157         return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
158
159     if (strcmp(type, "hexsalt") == 0)
160         return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
161
162     if (strcmp(type, "key") == 0)
163         return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
164
165     if (strcmp(type, "hexkey") == 0)
166         return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
167
168     if (strcmp(type, "info") == 0)
169         return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
170
171     if (strcmp(type, "hexinfo") == 0)
172         return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
173
174     KDFerr(KDF_F_PKEY_HKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE);
175     return -2;
176 }
177
178 static int pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx)
179 {
180     HKDF_PKEY_CTX *kctx = ctx->data;
181
182     OPENSSL_clear_free(kctx->key, kctx->key_len);
183     OPENSSL_clear_free(kctx->salt, kctx->salt_len);
184     OPENSSL_cleanse(kctx->info, kctx->info_len);
185     memset(kctx, 0, sizeof(*kctx));
186
187     return 1;
188 }
189
190 static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
191                             size_t *keylen)
192 {
193     HKDF_PKEY_CTX *kctx = ctx->data;
194
195     if (kctx->md == NULL) {
196         KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
197         return 0;
198     }
199     if (kctx->key == NULL) {
200         KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_KEY);
201         return 0;
202     }
203
204     switch (kctx->mode) {
205     case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND:
206         return HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
207                     kctx->key_len, kctx->info, kctx->info_len, key,
208                     *keylen) != NULL;
209
210     case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY:
211         if (key == NULL) {
212             *keylen = EVP_MD_size(kctx->md);
213             return 1;
214         }
215         return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
216                             kctx->key_len, key, keylen) != NULL;
217
218     case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY:
219         return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info,
220                            kctx->info_len, key, *keylen) != NULL;
221
222     default:
223         return 0;
224     }
225 }
226
227 const EVP_PKEY_METHOD hkdf_pkey_meth = {
228     EVP_PKEY_HKDF,
229     0,
230     pkey_hkdf_init,
231     0,
232     pkey_hkdf_cleanup,
233
234     0, 0,
235     0, 0,
236
237     0,
238     0,
239
240     0,
241     0,
242
243     0, 0,
244
245     0, 0, 0, 0,
246
247     0, 0,
248
249     0, 0,
250
251     pkey_hkdf_derive_init,
252     pkey_hkdf_derive,
253     pkey_hkdf_ctrl,
254     pkey_hkdf_ctrl_str
255 };
256
257 static unsigned char *HKDF(const EVP_MD *evp_md,
258                            const unsigned char *salt, size_t salt_len,
259                            const unsigned char *key, size_t key_len,
260                            const unsigned char *info, size_t info_len,
261                            unsigned char *okm, size_t okm_len)
262 {
263     unsigned char prk[EVP_MAX_MD_SIZE];
264     unsigned char *ret;
265     size_t prk_len;
266
267     if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len))
268         return NULL;
269
270     ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
271     OPENSSL_cleanse(prk, sizeof(prk));
272
273     return ret;
274 }
275
276 static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
277                                    const unsigned char *salt, size_t salt_len,
278                                    const unsigned char *key, size_t key_len,
279                                    unsigned char *prk, size_t *prk_len)
280 {
281     unsigned int tmp_len;
282
283     if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len))
284         return NULL;
285
286     *prk_len = tmp_len;
287     return prk;
288 }
289
290 static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
291                                   const unsigned char *prk, size_t prk_len,
292                                   const unsigned char *info, size_t info_len,
293                                   unsigned char *okm, size_t okm_len)
294 {
295     HMAC_CTX *hmac;
296     unsigned char *ret = NULL;
297
298     unsigned int i;
299
300     unsigned char prev[EVP_MAX_MD_SIZE];
301
302     size_t done_len = 0, dig_len = EVP_MD_size(evp_md);
303
304     size_t n = okm_len / dig_len;
305     if (okm_len % dig_len)
306         n++;
307
308     if (n > 255 || okm == NULL)
309         return NULL;
310
311     if ((hmac = HMAC_CTX_new()) == NULL)
312         return NULL;
313
314     if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
315         goto err;
316
317     for (i = 1; i <= n; i++) {
318         size_t copy_len;
319         const unsigned char ctr = i;
320
321         if (i > 1) {
322             if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))
323                 goto err;
324
325             if (!HMAC_Update(hmac, prev, dig_len))
326                 goto err;
327         }
328
329         if (!HMAC_Update(hmac, info, info_len))
330             goto err;
331
332         if (!HMAC_Update(hmac, &ctr, 1))
333             goto err;
334
335         if (!HMAC_Final(hmac, prev, NULL))
336             goto err;
337
338         copy_len = (done_len + dig_len > okm_len) ?
339                        okm_len - done_len :
340                        dig_len;
341
342         memcpy(okm + done_len, prev, copy_len);
343
344         done_len += copy_len;
345     }
346     ret = okm;
347
348  err:
349     OPENSSL_cleanse(prev, sizeof(prev));
350     HMAC_CTX_free(hmac);
351     return ret;
352 }