Convert tls1_prf_P_hash to use the EVP_MAC interface
[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 }