diff options
author | tb <> | 2024-07-09 16:24:47 +0000 |
---|---|---|
committer | tb <> | 2024-07-09 16:24:47 +0000 |
commit | 50946a304fc1a23a184733df7cfa4380a8b25160 (patch) | |
tree | 9df22fdb25677ee3fe3b38fc4114e04570020171 /src/lib | |
parent | 10b1fa6f30a06c3faf9686a97b5ee5a9712b4069 (diff) | |
download | openbsd-50946a304fc1a23a184733df7cfa4380a8b25160.tar.gz openbsd-50946a304fc1a23a184733df7cfa4380a8b25160.tar.bz2 openbsd-50946a304fc1a23a184733df7cfa4380a8b25160.zip |
Add a verbatim copy of tls1_prf.c from OpenSSL 1.1.1
From the last public commit b372b1f76450acdfed1e2301a39810146e28b02c
of the OpenSSL_1_1_1-stable branch
SHA256 (kdf/tls1_prf.c) = a519d3ff721d4ec59befac8586e24624fa87d9d8f6479327f7af58d652b6e4e5
Will be beat (a little bit) into shape in tree before linking it to the
build.
ok jsing
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/kdf/tls1_prf.c | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/src/lib/libcrypto/kdf/tls1_prf.c b/src/lib/libcrypto/kdf/tls1_prf.c new file mode 100644 index 0000000000..e9ca8e1278 --- /dev/null +++ b/src/lib/libcrypto/kdf/tls1_prf.c | |||
@@ -0,0 +1,278 @@ | |||
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 | |||
16 | static 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 | |||
25 | typedef 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 | |||
36 | static 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 | |||
49 | static 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 | |||
57 | static 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 | |||
93 | static 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 | |||
124 | static 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 | |||
145 | const 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 | |||
175 | static 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 | |||
247 | static 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 | } | ||