Single step kdf implementation
[openssl.git] / test / evp_kdf_test.c
1 /*
2  * Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright (c) 2018-2019, Oracle and/or its affiliates.  All rights reserved.
4  *
5  * Licensed under the Apache License 2.0 (the "License").  You may not use
6  * this file except in compliance with the License.  You can obtain a copy
7  * in the file LICENSE in the source distribution or at
8  * https://www.openssl.org/source/license.html
9  */
10
11 /* Tests of the EVP_KDF_CTX APIs */
12
13 #include <stdio.h>
14 #include <string.h>
15
16 #include <openssl/evp.h>
17 #include <openssl/kdf.h>
18 #include "testutil.h"
19
20 static int test_kdf_tls1_prf(void)
21 {
22     int ret = 0;
23     EVP_KDF_CTX *kctx;
24     unsigned char out[16];
25
26     if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_TLS1_PRF)) == NULL) {
27         TEST_error("EVP_KDF_TLS1_PRF");
28         goto err;
29     }
30     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) {
31         TEST_error("EVP_KDF_CTRL_SET_MD");
32         goto err;
33     }
34     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_TLS_SECRET,
35                      "secret", (size_t)6) <= 0) {
36         TEST_error("EVP_KDF_CTRL_SET_TLS_SECRET");
37         goto err;
38     }
39     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_TLS_SEED, "seed", (size_t)4) <= 0) {
40         TEST_error("EVP_KDF_CTRL_ADD_TLS_SEED");
41         goto err;
42     }
43     if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
44         TEST_error("EVP_KDF_derive");
45         goto err;
46     }
47
48     {
49         const unsigned char expected[sizeof(out)] = {
50             0x8e, 0x4d, 0x93, 0x25, 0x30, 0xd7, 0x65, 0xa0,
51             0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc
52         };
53         if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) {
54             goto err;
55         }
56     }
57     ret = 1;
58 err:
59     EVP_KDF_CTX_free(kctx);
60     return ret;
61 }
62
63 static int test_kdf_hkdf(void)
64 {
65     int ret = 0;
66     EVP_KDF_CTX *kctx;
67     unsigned char out[10];
68
69     if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_HKDF)) == NULL) {
70         TEST_error("EVP_KDF_HKDF");
71         goto err;
72     }
73     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) {
74         TEST_error("EVP_KDF_CTRL_SET_MD");
75         goto err;
76     }
77     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) {
78         TEST_error("EVP_KDF_CTRL_SET_SALT");
79         goto err;
80     }
81     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) {
82         TEST_error("EVP_KDF_CTRL_SET_KEY");
83         goto err;
84     }
85     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_HKDF_INFO,
86                      "label", (size_t)5) <= 0) {
87         TEST_error("EVP_KDF_CTRL_ADD_HKDF_INFO");
88         goto err;
89     }
90     if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
91         TEST_error("EVP_KDF_derive");
92         goto err;
93     }
94
95     {
96         const unsigned char expected[sizeof(out)] = {
97             0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8, 0xde, 0x13
98         };
99         if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) {
100             goto err;
101         }
102     }
103     ret = 1;
104 err:
105     EVP_KDF_CTX_free(kctx);
106     return ret;
107 }
108
109 static int test_kdf_pbkdf2(void)
110 {
111     int ret = 0;
112     EVP_KDF_CTX *kctx;
113     unsigned char out[32];
114
115     if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2)) == NULL) {
116         TEST_error("EVP_KDF_PBKDF2");
117         goto err;
118     }
119     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, "password", (size_t)8) <= 0) {
120         TEST_error("EVP_KDF_CTRL_SET_PASS");
121         goto err;
122     }
123     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) {
124         TEST_error("EVP_KDF_CTRL_SET_SALT");
125         goto err;
126     }
127     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, 2) <= 0) {
128         TEST_error("EVP_KDF_CTRL_SET_ITER");
129         goto err;
130     }
131     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) {
132         TEST_error("EVP_KDF_CTRL_SET_MD");
133         goto err;
134     }
135     if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
136         TEST_error("EVP_KDF_derive");
137         goto err;
138     }
139
140     {
141         const unsigned char expected[sizeof(out)] = {
142             0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3,
143             0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0,
144             0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf,
145             0xd6, 0xe2, 0xd8, 0x5a, 0x95, 0x47, 0x4c, 0x43
146         };
147         if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) {
148             goto err;
149         }
150     }
151     ret = 1;
152 err:
153     EVP_KDF_CTX_free(kctx);
154     return ret;
155 }
156
157 #ifndef OPENSSL_NO_SCRYPT
158 static int test_kdf_scrypt(void)
159 {
160     int ret = 0;
161     EVP_KDF_CTX *kctx;
162     unsigned char out[64];
163
164     if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT)) == NULL) {
165         TEST_error("EVP_KDF_SCRYPT");
166         goto err;
167     }
168     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, "password", (size_t)8) <= 0) {
169         TEST_error("EVP_KDF_CTRL_SET_PASS");
170         goto err;
171     }
172     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "NaCl", (size_t)4) <= 0) {
173         TEST_error("EVP_KDF_CTRL_SET_SALT");
174         goto err;
175     }
176     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, (uint64_t)1024) <= 0) {
177         TEST_error("EVP_KDF_CTRL_SET_SCRYPT_N");
178         goto err;
179     }
180     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)8) <= 0) {
181         TEST_error("EVP_KDF_CTRL_SET_SCRYPT_R");
182         goto err;
183     }
184     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)16) <= 0) {
185         TEST_error("EVP_KDF_CTRL_SET_SCRYPT_P");
186         goto err;
187     }
188     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, (uint64_t)16) <= 0) {
189         TEST_error("EVP_KDF_CTRL_SET_MAXMEM_BYTES");
190         goto err;
191     }
192     if (EVP_KDF_derive(kctx, out, sizeof(out)) > 0) {
193         TEST_error("EVP_KDF_derive should have failed");
194         goto err;
195     }
196     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES,
197                      (uint64_t)(10 * 1024 * 1024)) <= 0) {
198         TEST_error("EVP_KDF_CTRL_SET_MAXMEM_BYTES");
199         goto err;
200     }
201     if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
202         TEST_error("EVP_KDF_derive");
203         goto err;
204     }
205
206     {
207         const unsigned char expected[sizeof(out)] = {
208             0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00,
209             0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe,
210             0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30,
211             0xe7, 0x73, 0x76, 0x63, 0x4b, 0x37, 0x31, 0x62,
212             0x2e, 0xaf, 0x30, 0xd9, 0x2e, 0x22, 0xa3, 0x88,
213             0x6f, 0xf1, 0x09, 0x27, 0x9d, 0x98, 0x30, 0xda,
214             0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, 0xee, 0x6d,
215             0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40
216         };
217         if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) {
218             goto err;
219         }
220     }
221     ret = 1;
222 err:
223     EVP_KDF_CTX_free(kctx);
224     return ret;
225 }
226 #endif
227
228 static int test_kdf_ss_hash(void)
229 {
230     EVP_KDF_CTX *kctx;
231     const unsigned char z[] = {
232         0x6d,0xbd,0xc2,0x3f,0x04,0x54,0x88,0xe4,0x06,0x27,0x57,0xb0,0x6b,0x9e,
233         0xba,0xe1,0x83,0xfc,0x5a,0x59,0x46,0xd8,0x0d,0xb9,0x3f,0xec,0x6f,0x62,
234         0xec,0x07,0xe3,0x72,0x7f,0x01,0x26,0xae,0xd1,0x2c,0xe4,0xb2,0x62,0xf4,
235         0x7d,0x48,0xd5,0x42,0x87,0xf8,0x1d,0x47,0x4c,0x7c,0x3b,0x18,0x50,0xe9
236     };
237     const unsigned char other[] = {
238         0xa1,0xb2,0xc3,0xd4,0xe5,0x43,0x41,0x56,0x53,0x69,0x64,0x3c,0x83,0x2e,
239         0x98,0x49,0xdc,0xdb,0xa7,0x1e,0x9a,0x31,0x39,0xe6,0x06,0xe0,0x95,0xde,
240         0x3c,0x26,0x4a,0x66,0xe9,0x8a,0x16,0x58,0x54,0xcd,0x07,0x98,0x9b,0x1e,
241         0xe0,0xec,0x3f,0x8d,0xbe
242     };
243     const unsigned char expected[] = {
244         0xa4,0x62,0xde,0x16,0xa8,0x9d,0xe8,0x46,0x6e,0xf5,0x46,0x0b,0x47,0xb8
245     };
246     unsigned char out[14];
247
248     kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS);
249
250     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha224()) <= 0) {
251         TEST_error("EVP_KDF_CTRL_SET_MD");
252         return 0;
253     }
254     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, z, sizeof(z)) <= 0) {
255         TEST_error("EVP_KDF_CTRL_SET_KEY");
256         return 0;
257     }
258     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSKDF_INFO, other,
259                      sizeof(other)) <= 0) {
260         TEST_error("EVP_KDF_CTRL_SET_OTHER");
261         return 0;
262     }
263     if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
264         TEST_error("EVP_KDF_derive");
265         return 0;
266     }
267
268     if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)))
269         return 0;
270
271     EVP_KDF_CTX_free(kctx);
272     return 1;
273 }
274
275 static int test_kdf_ss_hmac(void)
276 {
277     EVP_KDF_CTX *kctx;
278     const EVP_MAC *mac;
279
280     const unsigned char z[] = {
281         0xb7,0x4a,0x14,0x9a,0x16,0x15,0x46,0xf8,0xc2,0x0b,0x06,0xac,0x4e,0xd4
282     };
283     const unsigned char other[] = {
284         0x34,0x8a,0x37,0xa2,0x7e,0xf1,0x28,0x2f,0x5f,0x02,0x0d,0xcc
285     };
286     const unsigned char salt[] = {
287         0x36,0x38,0x27,0x1c,0xcd,0x68,0xa2,0x5d,0xc2,0x4e,0xcd,0xdd,0x39,0xef,
288         0x3f,0x89
289     };
290     const unsigned char expected[] = {
291         0x44,0xf6,0x76,0xe8,0x5c,0x1b,0x1a,0x8b,0xbc,0x3d,0x31,0x92,0x18,0x63,
292         0x1c,0xa3
293     };
294     unsigned char out[16];
295
296     kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS);
297     mac = EVP_get_macbyname("HMAC");
298
299     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAC, mac) <= 0) {
300         TEST_error("EVP_KDF_CTRL_SET_MAC");
301         return 0;
302     }
303     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) {
304         TEST_error("EVP_KDF_CTRL_SET_MD");
305         return 0;
306     }
307     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, z, sizeof(z)) <= 0) {
308         TEST_error("EVP_KDF_CTRL_SET_KEY");
309         return 0;
310     }
311     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSKDF_INFO, other,
312                      sizeof(other)) <= 0) {
313         TEST_error("EVP_KDF_CTRL_SET_OTHER");
314         return 0;
315     }
316     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, salt, sizeof(salt)) <= 0) {
317         TEST_error("EVP_KDF_CTRL_SET_SALT");
318         return 0;
319     }
320     if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
321         TEST_error("EVP_KDF_derive");
322         return 0;
323     }
324
325     if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)))
326         return 0;
327
328     EVP_KDF_CTX_free(kctx);
329     return 1;
330 }
331
332 static int test_kdf_ss_kmac(void)
333 {
334     EVP_KDF_CTX *kctx;
335     unsigned char out[64];
336     const EVP_MAC *mac;
337
338     const unsigned char z[] = {
339         0xb7,0x4a,0x14,0x9a,0x16,0x15,0x46,0xf8,0xc2,0x0b,0x06,0xac,0x4e,0xd4
340     };
341     const unsigned char other[] = {
342         0x34,0x8a,0x37,0xa2,0x7e,0xf1,0x28,0x2f,0x5f,0x02,0x0d,0xcc
343     };
344     const unsigned char salt[] = {
345         0x36,0x38,0x27,0x1c,0xcd,0x68,0xa2,0x5d,0xc2,0x4e,0xcd,0xdd,0x39,0xef,
346         0x3f,0x89
347     };
348     const unsigned char expected[] = {
349         0xe9,0xc1,0x84,0x53,0xa0,0x62,0xb5,0x3b,0xdb,0xfc,0xbb,0x5a,0x34,0xbd,
350         0xb8,0xe5,0xe7,0x07,0xee,0xbb,0x5d,0xd1,0x34,0x42,0x43,0xd8,0xcf,0xc2,
351         0xc2,0xe6,0x33,0x2f,0x91,0xbd,0xa5,0x86,0xf3,0x7d,0xe4,0x8a,0x65,0xd4,
352         0xc5,0x14,0xfd,0xef,0xaa,0x1e,0x67,0x54,0xf3,0x73,0xd2,0x38,0xe1,0x95,
353         0xae,0x15,0x7e,0x1d,0xe8,0x14,0x98,0x03
354     };
355
356     kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS);
357     mac = EVP_get_macbyname("KMAC128");
358
359     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAC, mac) <= 0) {
360         TEST_error("EVP_KDF_CTRL_SET_MAC");
361         return 0;
362     }
363     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, z, sizeof(z)) <= 0) {
364         TEST_error("EVP_KDF_CTRL_SET_KEY");
365         return 0;
366     }
367     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSKDF_INFO, other,
368                      sizeof(other)) <= 0) {
369         TEST_error("EVP_KDF_CTRL_SET_OTHER");
370         return 0;
371     }
372     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, salt, sizeof(salt)) <= 0) {
373         TEST_error("EVP_KDF_CTRL_SET_SALT");
374         return 0;
375     }
376     if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAC_SIZE, (size_t)20) <= 0) {
377         TEST_error("EVP_KDF_CTRL_SET_MACSIZE");
378         return 0;
379     }
380     if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
381         TEST_error("EVP_KDF_derive");
382         return 0;
383     }
384
385     if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)))
386         return 0;
387
388     EVP_KDF_CTX_free(kctx);
389     return 1;
390 }
391
392 int setup_tests(void)
393 {
394     ADD_TEST(test_kdf_tls1_prf);
395     ADD_TEST(test_kdf_hkdf);
396     ADD_TEST(test_kdf_pbkdf2);
397 #ifndef OPENSSL_NO_SCRYPT
398     ADD_TEST(test_kdf_scrypt);
399 #endif
400     ADD_TEST(test_kdf_ss_hash);
401     ADD_TEST(test_kdf_ss_hmac);
402     ADD_TEST(test_kdf_ss_kmac);
403     return 1;
404 }