source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/tls1_prf.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 <stdio.h>
11#include "internal/cryptlib.h"
12#include <openssl/kdf.h>
13#include <openssl/evp.h>
14#include "internal/evp_int.h"
15
16static int tls1_prf_alg(const EVP_MD *md,
17 const unsigned char *sec, size_t slen,
18 const unsigned char *seed, size_t seed_len,
19 unsigned char *out, size_t olen);
20
21#define TLS1_PRF_MAXBUF 1024
22
23/* TLS KDF pkey context structure */
24
25typedef struct {
26 /* Digest to use for PRF */
27 const EVP_MD *md;
28 /* Secret value to use for PRF */
29 unsigned char *sec;
30 size_t seclen;
31 /* Buffer of concatenated seed data */
32 unsigned char seed[TLS1_PRF_MAXBUF];
33 size_t seedlen;
34} TLS1_PRF_PKEY_CTX;
35
36static int pkey_tls1_prf_init(EVP_PKEY_CTX *ctx)
37{
38 TLS1_PRF_PKEY_CTX *kctx;
39
40 kctx = OPENSSL_zalloc(sizeof(*kctx));
41 if (kctx == NULL)
42 return 0;
43 ctx->data = kctx;
44
45 return 1;
46}
47
48static void pkey_tls1_prf_cleanup(EVP_PKEY_CTX *ctx)
49{
50 TLS1_PRF_PKEY_CTX *kctx = ctx->data;
51 OPENSSL_clear_free(kctx->sec, kctx->seclen);
52 OPENSSL_cleanse(kctx->seed, kctx->seedlen);
53 OPENSSL_free(kctx);
54}
55
56static int pkey_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
57{
58 TLS1_PRF_PKEY_CTX *kctx = ctx->data;
59 switch (type) {
60 case EVP_PKEY_CTRL_TLS_MD:
61 kctx->md = p2;
62 return 1;
63
64 case EVP_PKEY_CTRL_TLS_SECRET:
65 if (p1 < 0)
66 return 0;
67 if (kctx->sec != NULL)
68 OPENSSL_clear_free(kctx->sec, kctx->seclen);
69 OPENSSL_cleanse(kctx->seed, kctx->seedlen);
70 kctx->seedlen = 0;
71 kctx->sec = OPENSSL_memdup(p2, p1);
72 if (kctx->sec == NULL)
73 return 0;
74 kctx->seclen = p1;
75 return 1;
76
77 case EVP_PKEY_CTRL_TLS_SEED:
78 if (p1 == 0 || p2 == NULL)
79 return 1;
80 if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - kctx->seedlen))
81 return 0;
82 memcpy(kctx->seed + kctx->seedlen, p2, p1);
83 kctx->seedlen += p1;
84 return 1;
85
86 default:
87 return -2;
88
89 }
90}
91
92static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx,
93 const char *type, const char *value)
94{
95 if (value == NULL) {
96 KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING);
97 return 0;
98 }
99 if (strcmp(type, "md") == 0) {
100 TLS1_PRF_PKEY_CTX *kctx = ctx->data;
101
102 const EVP_MD *md = EVP_get_digestbyname(value);
103 if (md == NULL) {
104 KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_INVALID_DIGEST);
105 return 0;
106 }
107 kctx->md = md;
108 return 1;
109 }
110 if (strcmp(type, "secret") == 0)
111 return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
112 if (strcmp(type, "hexsecret") == 0)
113 return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
114 if (strcmp(type, "seed") == 0)
115 return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
116 if (strcmp(type, "hexseed") == 0)
117 return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
118 return -2;
119}
120
121static int pkey_tls1_prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
122 size_t *keylen)
123{
124 TLS1_PRF_PKEY_CTX *kctx = ctx->data;
125 if (kctx->md == NULL || kctx->sec == NULL || kctx->seedlen == 0) {
126 KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_PARAMETER);
127 return 0;
128 }
129 return tls1_prf_alg(kctx->md, kctx->sec, kctx->seclen,
130 kctx->seed, kctx->seedlen,
131 key, *keylen);
132}
133
134const EVP_PKEY_METHOD tls1_prf_pkey_meth = {
135 EVP_PKEY_TLS1_PRF,
136 0,
137 pkey_tls1_prf_init,
138 0,
139 pkey_tls1_prf_cleanup,
140
141 0, 0,
142 0, 0,
143
144 0,
145 0,
146
147 0,
148 0,
149
150 0, 0,
151
152 0, 0, 0, 0,
153
154 0, 0,
155
156 0, 0,
157
158 0,
159 pkey_tls1_prf_derive,
160 pkey_tls1_prf_ctrl,
161 pkey_tls1_prf_ctrl_str
162};
163
164static int tls1_prf_P_hash(const EVP_MD *md,
165 const unsigned char *sec, size_t sec_len,
166 const unsigned char *seed, size_t seed_len,
167 unsigned char *out, size_t olen)
168{
169 int chunk;
170 EVP_MD_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL;
171 EVP_PKEY *mac_key = NULL;
172 unsigned char A1[EVP_MAX_MD_SIZE];
173 size_t A1_len;
174 int ret = 0;
175
176 chunk = EVP_MD_size(md);
177 OPENSSL_assert(chunk >= 0);
178
179 ctx = EVP_MD_CTX_new();
180 ctx_tmp = EVP_MD_CTX_new();
181 ctx_init = EVP_MD_CTX_new();
182 if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL)
183 goto err;
184 EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
185 mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
186 if (mac_key == NULL)
187 goto err;
188 if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key))
189 goto err;
190 if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
191 goto err;
192 if (seed != NULL && !EVP_DigestSignUpdate(ctx, seed, seed_len))
193 goto err;
194 if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
195 goto err;
196
197 for (;;) {
198 /* Reinit mac contexts */
199 if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
200 goto err;
201 if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
202 goto err;
203 if (olen > (size_t)chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx))
204 goto err;
205 if (seed && !EVP_DigestSignUpdate(ctx, seed, seed_len))
206 goto err;
207
208 if (olen > (size_t)chunk) {
209 size_t mac_len;
210 if (!EVP_DigestSignFinal(ctx, out, &mac_len))
211 goto err;
212 out += mac_len;
213 olen -= mac_len;
214 /* calc the next A1 value */
215 if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len))
216 goto err;
217 } else { /* last one */
218
219 if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
220 goto err;
221 memcpy(out, A1, olen);
222 break;
223 }
224 }
225 ret = 1;
226 err:
227 EVP_PKEY_free(mac_key);
228 EVP_MD_CTX_free(ctx);
229 EVP_MD_CTX_free(ctx_tmp);
230 EVP_MD_CTX_free(ctx_init);
231 OPENSSL_cleanse(A1, sizeof(A1));
232 return ret;
233}
234
235static int tls1_prf_alg(const EVP_MD *md,
236 const unsigned char *sec, size_t slen,
237 const unsigned char *seed, size_t seed_len,
238 unsigned char *out, size_t olen)
239{
240
241 if (EVP_MD_type(md) == NID_md5_sha1) {
242 size_t i;
243 unsigned char *tmp;
244 if (!tls1_prf_P_hash(EVP_md5(), sec, slen/2 + (slen & 1),
245 seed, seed_len, out, olen))
246 return 0;
247
248 tmp = OPENSSL_malloc(olen);
249 if (tmp == NULL)
250 return 0;
251 if (!tls1_prf_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1),
252 seed, seed_len, tmp, olen)) {
253 OPENSSL_clear_free(tmp, olen);
254 return 0;
255 }
256 for (i = 0; i < olen; i++)
257 out[i] ^= tmp[i];
258 OPENSSL_clear_free(tmp, olen);
259 return 1;
260 }
261 if (!tls1_prf_P_hash(md, sec, slen, seed, seed_len, out, olen))
262 return 0;
263
264 return 1;
265}
Note: See TracBrowser for help on using the repository browser.