]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/kdf/tls1_prf.c
Update copyright year
[thirdparty/openssl.git] / crypto / kdf / tls1_prf.c
CommitLineData
1eff3485 1/*
b0edda11 2 * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
1eff3485 3 *
d2e9e320
RS
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
1eff3485
DSH
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
cdb10bae
RS
40 if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) {
41 KDFerr(KDF_F_PKEY_TLS1_PRF_INIT, ERR_R_MALLOC_FAILURE);
1eff3485 42 return 0;
cdb10bae 43 }
1eff3485
DSH
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
4e8cb45c
DSH
93static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx,
94 const char *type, const char *value)
95{
3e30fa0a
DSH
96 if (value == NULL) {
97 KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING);
4e8cb45c 98 return 0;
3e30fa0a 99 }
4e8cb45c
DSH
100 if (strcmp(type, "md") == 0) {
101 TLS1_PRF_PKEY_CTX *kctx = ctx->data;
102
103 const EVP_MD *md = EVP_get_digestbyname(value);
3e30fa0a
DSH
104 if (md == NULL) {
105 KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_INVALID_DIGEST);
4e8cb45c 106 return 0;
3e30fa0a 107 }
4e8cb45c
DSH
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);
a24a5b8c
JB
119
120 KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE);
4e8cb45c
DSH
121 return -2;
122}
123
1eff3485
DSH
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;
f55129c7
JB
128 if (kctx->md == NULL) {
129 KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
130 return 0;
131 }
5b277519
JB
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) {
f55129c7 137 KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED);
1eff3485 138 return 0;
3e30fa0a 139 }
1eff3485
DSH
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,
4e8cb45c 172 pkey_tls1_prf_ctrl_str
1eff3485
DSH
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);
88809830 188 if (!ossl_assert(chunk > 0))
7d248ee0 189 goto err;
1eff3485
DSH
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);
f929439f 197 mac_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
1eff3485
DSH
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
cdb10bae
RS
260 if ((tmp = OPENSSL_malloc(olen)) == NULL) {
261 KDFerr(KDF_F_TLS1_PRF_ALG, ERR_R_MALLOC_FAILURE);
1eff3485 262 return 0;
cdb10bae 263 }
1eff3485
DSH
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}