VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.1f/crypto/kdf/tls1_prf.c@ 83531

Last change on this file since 83531 was 83531, checked in by vboxsync, 5 years ago

setting svn:sync-process=export for openssl-1.1.1f, all files except tests

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette