1f8374f6274ecc0e66aa2d150b083882343d2fc4
[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 <stdarg.h>
12 #include <string.h>
13 #include "internal/cryptlib.h"
14 #include <openssl/evp.h>
15 #include <openssl/kdf.h>
16 #include "internal/evp_int.h"
17 #include "kdf_local.h"
18
19 static void kdf_tls1_prf_reset(EVP_KDF_IMPL *impl);
20 static int tls1_prf_alg(const EVP_MD *md,
21                         const unsigned char *sec, size_t slen,
22                         const unsigned char *seed, size_t seed_len,
23                         unsigned char *out, size_t olen);
24
25 #define TLS1_PRF_MAXBUF 1024
26
27 /* TLS KDF kdf context structure */
28
29 struct evp_kdf_impl_st {
30     /* Digest to use for PRF */
31     const EVP_MD *md;
32     /* Secret value to use for PRF */
33     unsigned char *sec;
34     size_t seclen;
35     /* Buffer of concatenated seed data */
36     unsigned char seed[TLS1_PRF_MAXBUF];
37     size_t seedlen;
38 };
39
40 static EVP_KDF_IMPL *kdf_tls1_prf_new(void)
41 {
42     EVP_KDF_IMPL *impl;
43
44     if ((impl = OPENSSL_zalloc(sizeof(*impl))) == NULL)
45         KDFerr(KDF_F_KDF_TLS1_PRF_NEW, ERR_R_MALLOC_FAILURE);
46     return impl;
47 }
48
49 static void kdf_tls1_prf_free(EVP_KDF_IMPL *impl)
50 {
51     kdf_tls1_prf_reset(impl);
52     OPENSSL_free(impl);
53 }
54
55 static void kdf_tls1_prf_reset(EVP_KDF_IMPL *impl)
56 {
57     OPENSSL_clear_free(impl->sec, impl->seclen);
58     OPENSSL_cleanse(impl->seed, impl->seedlen);
59     memset(impl, 0, sizeof(*impl));
60 }
61
62 static int kdf_tls1_prf_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args)
63 {
64     const unsigned char *p;
65     size_t len;
66     const EVP_MD *md;
67
68     switch (cmd) {
69     case EVP_KDF_CTRL_SET_MD:
70         md = va_arg(args, const EVP_MD *);
71         if (md == NULL)
72             return 0;
73
74         impl->md = md;
75         return 1;
76
77     case EVP_KDF_CTRL_SET_TLS_SECRET:
78         p = va_arg(args, const unsigned char *);
79         len = va_arg(args, size_t);
80         OPENSSL_clear_free(impl->sec, impl->seclen);
81         impl->sec = OPENSSL_memdup(p, len);
82         if (impl->sec == NULL)
83             return 0;
84
85         impl->seclen  = len;
86         return 1;
87
88     case EVP_KDF_CTRL_RESET_TLS_SEED:
89         OPENSSL_cleanse(impl->seed, impl->seedlen);
90         impl->seedlen = 0;
91         return 1;
92
93     case EVP_KDF_CTRL_ADD_TLS_SEED:
94         p = va_arg(args, const unsigned char *);
95         len = va_arg(args, size_t);
96         if (len == 0 || p == NULL)
97             return 1;
98
99         if (len > (TLS1_PRF_MAXBUF - impl->seedlen))
100             return 0;
101
102         memcpy(impl->seed + impl->seedlen, p, len);
103         impl->seedlen += len;
104         return 1;
105
106     default:
107         return -2;
108     }
109 }
110
111 static int kdf_tls1_prf_ctrl_str(EVP_KDF_IMPL *impl,
112                                  const char *type, const char *value)
113 {
114     if (value == NULL) {
115         KDFerr(KDF_F_KDF_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING);
116         return 0;
117     }
118     if (strcmp(type, "digest") == 0)
119         return kdf_md2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_SET_MD, value);
120
121     if (strcmp(type, "secret") == 0)
122         return kdf_str2ctrl(impl, kdf_tls1_prf_ctrl,
123                             EVP_KDF_CTRL_SET_TLS_SECRET, value);
124
125     if (strcmp(type, "hexsecret") == 0)
126         return kdf_hex2ctrl(impl, kdf_tls1_prf_ctrl,
127                             EVP_KDF_CTRL_SET_TLS_SECRET, value);
128
129     if (strcmp(type, "seed") == 0)
130         return kdf_str2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_ADD_TLS_SEED,
131                             value);
132
133     if (strcmp(type, "hexseed") == 0)
134         return kdf_hex2ctrl(impl, kdf_tls1_prf_ctrl, EVP_KDF_CTRL_ADD_TLS_SEED,
135                             value);
136
137     return -2;
138 }
139
140 static int kdf_tls1_prf_derive(EVP_KDF_IMPL *impl, unsigned char *key,
141                                size_t keylen)
142 {
143     if (impl->md == NULL) {
144         KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
145         return 0;
146     }
147     if (impl->sec == NULL) {
148         KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_SECRET);
149         return 0;
150     }
151     if (impl->seedlen == 0) {
152         KDFerr(KDF_F_KDF_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED);
153         return 0;
154     }
155     return tls1_prf_alg(impl->md, impl->sec, impl->seclen,
156                         impl->seed, impl->seedlen,
157                         key, keylen);
158 }
159
160 const EVP_KDF_METHOD tls1_prf_kdf_meth = {
161     EVP_KDF_TLS1_PRF,
162     kdf_tls1_prf_new,
163     kdf_tls1_prf_free,
164     kdf_tls1_prf_reset,
165     kdf_tls1_prf_ctrl,
166     kdf_tls1_prf_ctrl_str,
167     NULL,
168     kdf_tls1_prf_derive
169 };
170
171 static int tls1_prf_P_hash(const EVP_MD *md,
172                            const unsigned char *sec, size_t sec_len,
173                            const unsigned char *seed, size_t seed_len,
174                            unsigned char *out, size_t olen)
175 {
176     int chunk;
177     EVP_MAC_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL;
178     unsigned char A1[EVP_MAX_MD_SIZE];
179     size_t A1_len;
180     int ret = 0;
181
182     chunk = EVP_MD_size(md);
183     if (!ossl_assert(chunk > 0))
184         goto err;
185
186     ctx = EVP_MAC_CTX_new_id(EVP_MAC_HMAC);
187     ctx_tmp = EVP_MAC_CTX_new_id(EVP_MAC_HMAC);
188     ctx_init = EVP_MAC_CTX_new_id(EVP_MAC_HMAC);
189     if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL)
190         goto err;
191     if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_FLAGS, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) != 1)
192         goto err;
193     if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_MD, md) != 1)
194         goto err;
195     if (EVP_MAC_ctrl(ctx_init, EVP_MAC_CTRL_SET_KEY, sec, sec_len) != 1)
196         goto err;
197     if (!EVP_MAC_init(ctx_init))
198         goto err;
199     if (!EVP_MAC_CTX_copy(ctx, ctx_init))
200         goto err;
201     if (seed != NULL && !EVP_MAC_update(ctx, seed, seed_len))
202         goto err;
203     if (!EVP_MAC_final(ctx, A1, &A1_len))
204         goto err;
205
206     for (;;) {
207         /* Reinit mac contexts */
208         if (!EVP_MAC_CTX_copy(ctx, ctx_init))
209             goto err;
210         if (!EVP_MAC_update(ctx, A1, A1_len))
211             goto err;
212         if (olen > (size_t)chunk && !EVP_MAC_CTX_copy(ctx_tmp, ctx))
213             goto err;
214         if (seed != NULL && !EVP_MAC_update(ctx, seed, seed_len))
215             goto err;
216
217         if (olen > (size_t)chunk) {
218             size_t mac_len;
219             if (!EVP_MAC_final(ctx, out, &mac_len))
220                 goto err;
221             out += mac_len;
222             olen -= mac_len;
223             /* calc the next A1 value */
224             if (!EVP_MAC_final(ctx_tmp, A1, &A1_len))
225                 goto err;
226         } else {                /* last one */
227
228             if (!EVP_MAC_final(ctx, A1, &A1_len))
229                 goto err;
230             memcpy(out, A1, olen);
231             break;
232         }
233     }
234     ret = 1;
235  err:
236     EVP_MAC_CTX_free(ctx);
237     EVP_MAC_CTX_free(ctx_tmp);
238     EVP_MAC_CTX_free(ctx_init);
239     OPENSSL_cleanse(A1, sizeof(A1));
240     return ret;
241 }
242
243 static int tls1_prf_alg(const EVP_MD *md,
244                         const unsigned char *sec, size_t slen,
245                         const unsigned char *seed, size_t seed_len,
246                         unsigned char *out, size_t olen)
247 {
248     if (EVP_MD_type(md) == NID_md5_sha1) {
249         size_t i;
250         unsigned char *tmp;
251         if (!tls1_prf_P_hash(EVP_md5(), sec, slen/2 + (slen & 1),
252                              seed, seed_len, out, olen))
253             return 0;
254
255         if ((tmp = OPENSSL_malloc(olen)) == NULL) {
256             KDFerr(KDF_F_TLS1_PRF_ALG, ERR_R_MALLOC_FAILURE);
257             return 0;
258         }
259         if (!tls1_prf_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1),
260                              seed, seed_len, tmp, olen)) {
261             OPENSSL_clear_free(tmp, olen);
262             return 0;
263         }
264         for (i = 0; i < olen; i++)
265             out[i] ^= tmp[i];
266         OPENSSL_clear_free(tmp, olen);
267         return 1;
268     }
269     if (!tls1_prf_P_hash(md, sec, slen, seed, seed_len, out, olen))
270         return 0;
271
272     return 1;
273 }