0bcb1c2f056af111087aa2482169fb2a4ffe2476
[openssl.git] / crypto / kdf / hkdf.c
1 /*
2  * Copyright 2016 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     kctx = OPENSSL_zalloc(sizeof(*kctx));
52     if (kctx == NULL)
53         return 0;
54
55     ctx->data = kctx;
56
57     return 1;
58 }
59
60 static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx)
61 {
62     HKDF_PKEY_CTX *kctx = ctx->data;
63     OPENSSL_clear_free(kctx->salt, kctx->salt_len);
64     OPENSSL_clear_free(kctx->key, kctx->key_len);
65     OPENSSL_cleanse(kctx->info, kctx->info_len);
66     OPENSSL_free(kctx);
67 }
68
69 static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
70 {
71     HKDF_PKEY_CTX *kctx = ctx->data;
72
73     switch (type) {
74     case EVP_PKEY_CTRL_HKDF_MD:
75         if (p2 == NULL)
76             return 0;
77
78         kctx->md = p2;
79         return 1;
80
81     case EVP_PKEY_CTRL_HKDF_MODE:
82         kctx->mode = p1;
83         return 1;
84
85     case EVP_PKEY_CTRL_HKDF_SALT:
86         if (p1 == 0 || p2 == NULL)
87             return 1;
88
89         if (p1 < 0)
90             return 0;
91
92         if (kctx->salt != NULL)
93             OPENSSL_clear_free(kctx->salt, kctx->salt_len);
94
95         kctx->salt = OPENSSL_memdup(p2, p1);
96         if (kctx->salt == NULL)
97             return 0;
98
99         kctx->salt_len = p1;
100         return 1;
101
102     case EVP_PKEY_CTRL_HKDF_KEY:
103         if (p1 < 0)
104             return 0;
105
106         if (kctx->key != NULL)
107             OPENSSL_clear_free(kctx->key, kctx->key_len);
108
109         kctx->key = OPENSSL_memdup(p2, p1);
110         if (kctx->key == NULL)
111             return 0;
112
113         kctx->key_len  = p1;
114         return 1;
115
116     case EVP_PKEY_CTRL_HKDF_INFO:
117         if (p1 == 0 || p2 == NULL)
118             return 1;
119
120         if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len))
121             return 0;
122
123         memcpy(kctx->info + kctx->info_len, p2, p1);
124         kctx->info_len += p1;
125         return 1;
126
127     default:
128         return -2;
129
130     }
131 }
132
133 static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
134                               const char *value)
135 {
136     if (strcmp(type, "md") == 0)
137         return EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_get_digestbyname(value));
138
139     if (strcmp(type, "salt") == 0)
140         return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
141
142     if (strcmp(type, "hexsalt") == 0)
143         return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
144
145     if (strcmp(type, "key") == 0)
146         return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
147
148     if (strcmp(type, "hexkey") == 0)
149         return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
150
151     if (strcmp(type, "info") == 0)
152         return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
153
154     if (strcmp(type, "hexinfo") == 0)
155         return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
156
157     return -2;
158 }
159
160 static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
161                             size_t *keylen)
162 {
163     HKDF_PKEY_CTX *kctx = ctx->data;
164
165     if (kctx->md == NULL || kctx->key == NULL)
166         return 0;
167
168     switch (kctx->mode) {
169     case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND:
170         return HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
171                     kctx->key_len, kctx->info, kctx->info_len, key,
172                     *keylen) != NULL;
173
174     case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY:
175         if (key == NULL) {
176             *keylen = EVP_MD_size(kctx->md);
177             return 1;
178         }
179         return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
180                             kctx->key_len, key, keylen) != NULL;
181
182     case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY:
183         return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info,
184                            kctx->info_len, key, *keylen) != NULL;
185
186     default:
187         return 0;
188     }
189 }
190
191 const EVP_PKEY_METHOD hkdf_pkey_meth = {
192     EVP_PKEY_HKDF,
193     0,
194     pkey_hkdf_init,
195     0,
196     pkey_hkdf_cleanup,
197
198     0, 0,
199     0, 0,
200
201     0,
202     0,
203
204     0,
205     0,
206
207     0, 0,
208
209     0, 0, 0, 0,
210
211     0, 0,
212
213     0, 0,
214
215     0,
216     pkey_hkdf_derive,
217     pkey_hkdf_ctrl,
218     pkey_hkdf_ctrl_str
219 };
220
221 static unsigned char *HKDF(const EVP_MD *evp_md,
222                            const unsigned char *salt, size_t salt_len,
223                            const unsigned char *key, size_t key_len,
224                            const unsigned char *info, size_t info_len,
225                            unsigned char *okm, size_t okm_len)
226 {
227     unsigned char prk[EVP_MAX_MD_SIZE];
228     unsigned char *ret;
229     size_t prk_len;
230
231     if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len))
232         return NULL;
233
234     ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
235     OPENSSL_cleanse(prk, sizeof(prk));
236
237     return ret;
238 }
239
240 static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
241                                    const unsigned char *salt, size_t salt_len,
242                                    const unsigned char *key, size_t key_len,
243                                    unsigned char *prk, size_t *prk_len)
244 {
245     unsigned int tmp_len;
246
247     if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len))
248         return NULL;
249
250     *prk_len = tmp_len;
251     return prk;
252 }
253
254 static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
255                                   const unsigned char *prk, size_t prk_len,
256                                   const unsigned char *info, size_t info_len,
257                                   unsigned char *okm, size_t okm_len)
258 {
259     HMAC_CTX *hmac;
260
261     unsigned int i;
262
263     unsigned char prev[EVP_MAX_MD_SIZE];
264
265     size_t done_len = 0, dig_len = EVP_MD_size(evp_md);
266
267     size_t n = okm_len / dig_len;
268     if (okm_len % dig_len)
269         n++;
270
271     if (n > 255 || okm == NULL)
272         return NULL;
273
274     if ((hmac = HMAC_CTX_new()) == NULL)
275         return NULL;
276
277     if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
278         goto err;
279
280     for (i = 1; i <= n; i++) {
281         size_t copy_len;
282         const unsigned char ctr = i;
283
284         if (i > 1) {
285             if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))
286                 goto err;
287
288             if (!HMAC_Update(hmac, prev, dig_len))
289                 goto err;
290         }
291
292         if (!HMAC_Update(hmac, info, info_len))
293             goto err;
294
295         if (!HMAC_Update(hmac, &ctr, 1))
296             goto err;
297
298         if (!HMAC_Final(hmac, prev, NULL))
299             goto err;
300
301         copy_len = (done_len + dig_len > okm_len) ?
302                        okm_len - done_len :
303                        dig_len;
304
305         memcpy(okm + done_len, prev, copy_len);
306
307         done_len += copy_len;
308     }
309
310     HMAC_CTX_free(hmac);
311     return okm;
312
313  err:
314     HMAC_CTX_free(hmac);
315     return NULL;
316 }