49f7ecced90615be1928273661089e63622301f2
[openssl.git] / crypto / kdf / tls1_prf.c
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 "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_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 }