Fix indentation
[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, "mode") == 0) {
137         int mode;
138
139         if (strcmp(value, "EXTRACT_AND_EXPAND") == 0)
140             mode = EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND;
141         else if (strcmp(value, "EXTRACT_ONLY") == 0)
142             mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY;
143         else if (strcmp(value, "EXPAND_ONLY") == 0)
144             mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
145         else
146             return 0;
147
148         return EVP_PKEY_CTX_hkdf_mode(ctx, mode);
149     }
150
151     if (strcmp(type, "md") == 0)
152         return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_DERIVE,
153                                EVP_PKEY_CTRL_HKDF_MD, value);
154
155     if (strcmp(type, "salt") == 0)
156         return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
157
158     if (strcmp(type, "hexsalt") == 0)
159         return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
160
161     if (strcmp(type, "key") == 0)
162         return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
163
164     if (strcmp(type, "hexkey") == 0)
165         return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
166
167     if (strcmp(type, "info") == 0)
168         return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
169
170     if (strcmp(type, "hexinfo") == 0)
171         return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
172
173     KDFerr(KDF_F_PKEY_HKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE);
174     return -2;
175 }
176
177 static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
178                             size_t *keylen)
179 {
180     HKDF_PKEY_CTX *kctx = ctx->data;
181
182     if (kctx->md == NULL) {
183         KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
184         return 0;
185     }
186     if (kctx->key == NULL) {
187         KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_KEY);
188         return 0;
189     }
190
191     switch (kctx->mode) {
192     case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND:
193         return HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
194                     kctx->key_len, kctx->info, kctx->info_len, key,
195                     *keylen) != NULL;
196
197     case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY:
198         if (key == NULL) {
199             *keylen = EVP_MD_size(kctx->md);
200             return 1;
201         }
202         return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
203                             kctx->key_len, key, keylen) != NULL;
204
205     case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY:
206         return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info,
207                            kctx->info_len, key, *keylen) != NULL;
208
209     default:
210         return 0;
211     }
212 }
213
214 const EVP_PKEY_METHOD hkdf_pkey_meth = {
215     EVP_PKEY_HKDF,
216     0,
217     pkey_hkdf_init,
218     0,
219     pkey_hkdf_cleanup,
220
221     0, 0,
222     0, 0,
223
224     0,
225     0,
226
227     0,
228     0,
229
230     0, 0,
231
232     0, 0, 0, 0,
233
234     0, 0,
235
236     0, 0,
237
238     0,
239     pkey_hkdf_derive,
240     pkey_hkdf_ctrl,
241     pkey_hkdf_ctrl_str
242 };
243
244 static unsigned char *HKDF(const EVP_MD *evp_md,
245                            const unsigned char *salt, size_t salt_len,
246                            const unsigned char *key, size_t key_len,
247                            const unsigned char *info, size_t info_len,
248                            unsigned char *okm, size_t okm_len)
249 {
250     unsigned char prk[EVP_MAX_MD_SIZE];
251     unsigned char *ret;
252     size_t prk_len;
253
254     if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len))
255         return NULL;
256
257     ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
258     OPENSSL_cleanse(prk, sizeof(prk));
259
260     return ret;
261 }
262
263 static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
264                                    const unsigned char *salt, size_t salt_len,
265                                    const unsigned char *key, size_t key_len,
266                                    unsigned char *prk, size_t *prk_len)
267 {
268     unsigned int tmp_len;
269
270     if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len))
271         return NULL;
272
273     *prk_len = tmp_len;
274     return prk;
275 }
276
277 static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
278                                   const unsigned char *prk, size_t prk_len,
279                                   const unsigned char *info, size_t info_len,
280                                   unsigned char *okm, size_t okm_len)
281 {
282     HMAC_CTX *hmac;
283
284     unsigned int i;
285
286     unsigned char prev[EVP_MAX_MD_SIZE];
287
288     size_t done_len = 0, dig_len = EVP_MD_size(evp_md);
289
290     size_t n = okm_len / dig_len;
291     if (okm_len % dig_len)
292         n++;
293
294     if (n > 255 || okm == NULL)
295         return NULL;
296
297     if ((hmac = HMAC_CTX_new()) == NULL)
298         return NULL;
299
300     if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
301         goto err;
302
303     for (i = 1; i <= n; i++) {
304         size_t copy_len;
305         const unsigned char ctr = i;
306
307         if (i > 1) {
308             if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))
309                 goto err;
310
311             if (!HMAC_Update(hmac, prev, dig_len))
312                 goto err;
313         }
314
315         if (!HMAC_Update(hmac, info, info_len))
316             goto err;
317
318         if (!HMAC_Update(hmac, &ctr, 1))
319             goto err;
320
321         if (!HMAC_Final(hmac, prev, NULL))
322             goto err;
323
324         copy_len = (done_len + dig_len > okm_len) ?
325                        okm_len - done_len :
326                        dig_len;
327
328         memcpy(okm + done_len, prev, copy_len);
329
330         done_len += copy_len;
331     }
332
333     HMAC_CTX_free(hmac);
334     return okm;
335
336  err:
337     HMAC_CTX_free(hmac);
338     return NULL;
339 }