source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/hkdf.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

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