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 "crypto/evp.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 
pkey_hkdf_init(EVP_PKEY_CTX * ctx)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 
pkey_hkdf_cleanup(EVP_PKEY_CTX * ctx)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 
pkey_hkdf_ctrl(EVP_PKEY_CTX * ctx,int type,int p1,void * p2)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 
pkey_hkdf_ctrl_str(EVP_PKEY_CTX * ctx,const char * type,const char * value)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 
pkey_hkdf_derive_init(EVP_PKEY_CTX * ctx)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 
pkey_hkdf_derive(EVP_PKEY_CTX * ctx,unsigned char * key,size_t * keylen)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 
HKDF(const EVP_MD * evp_md,const unsigned char * salt,size_t salt_len,const unsigned char * key,size_t key_len,const unsigned char * info,size_t info_len,unsigned char * okm,size_t okm_len)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 
HKDF_Extract(const EVP_MD * evp_md,const unsigned char * salt,size_t salt_len,const unsigned char * key,size_t key_len,unsigned char * prk,size_t * prk_len)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 
HKDF_Expand(const EVP_MD * evp_md,const unsigned char * prk,size_t prk_len,const unsigned char * info,size_t info_len,unsigned char * okm,size_t okm_len)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 }
353