]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/kdf/tls1_prf.c
24ad59b92736f14124951ea3b349dd5ebeb68542
[thirdparty/openssl.git] / crypto / kdf / tls1_prf.c
1 /*
2 * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (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
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_MAC_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL;
182 unsigned char A1[EVP_MAX_MD_SIZE];
183 size_t A1_len;
184 int ret = 0;
185
186 chunk = EVP_MD_size(md);
187 if (!ossl_assert(chunk > 0))
188 goto err;
189
190 ctx = EVP_MAC_CTX_new_id(EVP_MAC_HMAC);
191 ctx_tmp = EVP_MAC_CTX_new_id(EVP_MAC_HMAC);
192 ctx_init = EVP_MAC_CTX_new_id(EVP_MAC_HMAC);
193 if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL)
194 goto err;
195 if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_FLAGS, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) != 1)
196 goto err;
197 if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_MD, md) != 1)
198 goto err;
199 if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_KEY, sec, sec_len) != 1)
200 goto err;
201 if (!EVP_MAC_init(ctx_init))
202 goto err;
203 if (!EVP_MAC_CTX_copy(ctx, ctx_init))
204 goto err;
205 if (seed != NULL && !EVP_MAC_update(ctx, seed, seed_len))
206 goto err;
207 if (!EVP_MAC_final(ctx, A1, &A1_len))
208 goto err;
209
210 for (;;) {
211 /* Reinit mac contexts */
212 if (!EVP_MAC_CTX_copy(ctx, ctx_init))
213 goto err;
214 if (!EVP_MAC_update(ctx, A1, A1_len))
215 goto err;
216 if (olen > (size_t)chunk && !EVP_MAC_CTX_copy(ctx_tmp, ctx))
217 goto err;
218 if (seed != NULL && !EVP_MAC_update(ctx, seed, seed_len))
219 goto err;
220
221 if (olen > (size_t)chunk) {
222 size_t mac_len;
223 if (!EVP_MAC_final(ctx, out, &mac_len))
224 goto err;
225 out += mac_len;
226 olen -= mac_len;
227 /* calc the next A1 value */
228 if (!EVP_MAC_final(ctx_tmp, A1, &A1_len))
229 goto err;
230 } else { /* last one */
231
232 if (!EVP_MAC_final(ctx, A1, &A1_len))
233 goto err;
234 memcpy(out, A1, olen);
235 break;
236 }
237 }
238 ret = 1;
239 err:
240 EVP_MAC_CTX_free(ctx);
241 EVP_MAC_CTX_free(ctx_tmp);
242 EVP_MAC_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 }