xref: /freebsd/crypto/openssl/test/evp_kdf_test.c (revision 0d0c8621fd181e507f0fb50ffcca606faf66a8c2)
1e0c4386eSCy Schubert /*
2*0d0c8621SEnji Cooper  * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.
3e0c4386eSCy Schubert  * Copyright (c) 2018-2020, Oracle and/or its affiliates.  All rights reserved.
4e0c4386eSCy Schubert  *
5e0c4386eSCy Schubert  * Licensed under the Apache License 2.0 (the "License").  You may not use
6e0c4386eSCy Schubert  * this file except in compliance with the License.  You can obtain a copy
7e0c4386eSCy Schubert  * in the file LICENSE in the source distribution or at
8e0c4386eSCy Schubert  * https://www.openssl.org/source/license.html
9e0c4386eSCy Schubert  */
10e0c4386eSCy Schubert 
11e0c4386eSCy Schubert /* Tests of the EVP_KDF_CTX APIs */
12e0c4386eSCy Schubert 
13e0c4386eSCy Schubert #include <stdio.h>
14e0c4386eSCy Schubert #include <string.h>
15e0c4386eSCy Schubert 
16e0c4386eSCy Schubert #include <openssl/evp.h>
17e0c4386eSCy Schubert #include <openssl/kdf.h>
18e0c4386eSCy Schubert #include <openssl/core_names.h>
19e0c4386eSCy Schubert #include "internal/numbers.h"
20e0c4386eSCy Schubert #include "testutil.h"
21e0c4386eSCy Schubert 
22e0c4386eSCy Schubert 
get_kdfbyname_libctx(OSSL_LIB_CTX * libctx,const char * name)23e0c4386eSCy Schubert static EVP_KDF_CTX *get_kdfbyname_libctx(OSSL_LIB_CTX *libctx, const char *name)
24e0c4386eSCy Schubert {
25e0c4386eSCy Schubert     EVP_KDF *kdf = EVP_KDF_fetch(libctx, name, NULL);
26e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);
27e0c4386eSCy Schubert 
28e0c4386eSCy Schubert     EVP_KDF_free(kdf);
29e0c4386eSCy Schubert     return kctx;
30e0c4386eSCy Schubert }
31e0c4386eSCy Schubert 
get_kdfbyname(const char * name)32e0c4386eSCy Schubert static EVP_KDF_CTX *get_kdfbyname(const char *name)
33e0c4386eSCy Schubert {
34e0c4386eSCy Schubert     return get_kdfbyname_libctx(NULL, name);
35e0c4386eSCy Schubert }
36e0c4386eSCy Schubert 
construct_tls1_prf_params(const char * digest,const char * secret,const char * seed)37e0c4386eSCy Schubert static OSSL_PARAM *construct_tls1_prf_params(const char *digest, const char *secret,
38e0c4386eSCy Schubert     const char *seed)
39e0c4386eSCy Schubert {
40e0c4386eSCy Schubert     OSSL_PARAM *params = OPENSSL_malloc(sizeof(OSSL_PARAM) * 4);
41e0c4386eSCy Schubert     OSSL_PARAM *p = params;
42e0c4386eSCy Schubert 
43e0c4386eSCy Schubert     if (params == NULL)
44e0c4386eSCy Schubert         return NULL;
45e0c4386eSCy Schubert 
46e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
47e0c4386eSCy Schubert                                             (char *)digest, 0);
48e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET,
49e0c4386eSCy Schubert                                              (unsigned char *)secret,
50e0c4386eSCy Schubert                                              strlen(secret));
51e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
52e0c4386eSCy Schubert                                              (unsigned char *)seed,
53e0c4386eSCy Schubert                                              strlen(seed));
54e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
55e0c4386eSCy Schubert 
56e0c4386eSCy Schubert     return params;
57e0c4386eSCy Schubert }
58e0c4386eSCy Schubert 
test_kdf_tls1_prf(void)59e0c4386eSCy Schubert static int test_kdf_tls1_prf(void)
60e0c4386eSCy Schubert {
61e0c4386eSCy Schubert     int ret;
62e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
63e0c4386eSCy Schubert     unsigned char out[16];
64e0c4386eSCy Schubert     OSSL_PARAM *params;
65e0c4386eSCy Schubert     static const unsigned char expected[sizeof(out)] = {
66e0c4386eSCy Schubert         0x8e, 0x4d, 0x93, 0x25, 0x30, 0xd7, 0x65, 0xa0,
67e0c4386eSCy Schubert         0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc
68e0c4386eSCy Schubert     };
69e0c4386eSCy Schubert 
70e0c4386eSCy Schubert     params = construct_tls1_prf_params("sha256", "secret", "seed");
71e0c4386eSCy Schubert 
72e0c4386eSCy Schubert     ret = TEST_ptr(params)
73e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_TLS1_PRF))
74e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0)
75e0c4386eSCy Schubert         && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
76e0c4386eSCy Schubert 
77e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
78e0c4386eSCy Schubert     OPENSSL_free(params);
79e0c4386eSCy Schubert     return ret;
80e0c4386eSCy Schubert }
81e0c4386eSCy Schubert 
test_kdf_tls1_prf_invalid_digest(void)82e0c4386eSCy Schubert static int test_kdf_tls1_prf_invalid_digest(void)
83e0c4386eSCy Schubert {
84e0c4386eSCy Schubert     int ret;
85e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
86e0c4386eSCy Schubert     OSSL_PARAM *params;
87e0c4386eSCy Schubert 
88e0c4386eSCy Schubert     params = construct_tls1_prf_params("blah", "secret", "seed");
89e0c4386eSCy Schubert 
90e0c4386eSCy Schubert     ret = TEST_ptr(params)
91e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_TLS1_PRF))
92e0c4386eSCy Schubert         && TEST_false(EVP_KDF_CTX_set_params(kctx, params));
93e0c4386eSCy Schubert 
94e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
95e0c4386eSCy Schubert     OPENSSL_free(params);
96e0c4386eSCy Schubert     return ret;
97e0c4386eSCy Schubert }
98e0c4386eSCy Schubert 
test_kdf_tls1_prf_zero_output_size(void)99e0c4386eSCy Schubert static int test_kdf_tls1_prf_zero_output_size(void)
100e0c4386eSCy Schubert {
101e0c4386eSCy Schubert     int ret;
102e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
103e0c4386eSCy Schubert     unsigned char out[16];
104e0c4386eSCy Schubert     OSSL_PARAM *params;
105e0c4386eSCy Schubert 
106e0c4386eSCy Schubert     params = construct_tls1_prf_params("sha256", "secret", "seed");
107e0c4386eSCy Schubert 
108e0c4386eSCy Schubert     /* Negative test - derive should fail */
109e0c4386eSCy Schubert     ret = TEST_ptr(params)
110e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_TLS1_PRF))
111e0c4386eSCy Schubert         && TEST_true(EVP_KDF_CTX_set_params(kctx, params))
112e0c4386eSCy Schubert         && TEST_int_eq(EVP_KDF_derive(kctx, out, 0, NULL), 0);
113e0c4386eSCy Schubert 
114e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
115e0c4386eSCy Schubert     OPENSSL_free(params);
116e0c4386eSCy Schubert     return ret;
117e0c4386eSCy Schubert }
118e0c4386eSCy Schubert 
test_kdf_tls1_prf_empty_secret(void)119e0c4386eSCy Schubert static int test_kdf_tls1_prf_empty_secret(void)
120e0c4386eSCy Schubert {
121e0c4386eSCy Schubert     int ret;
122e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
123e0c4386eSCy Schubert     unsigned char out[16];
124e0c4386eSCy Schubert     OSSL_PARAM *params;
125e0c4386eSCy Schubert 
126e0c4386eSCy Schubert     params = construct_tls1_prf_params("sha256", "", "seed");
127e0c4386eSCy Schubert 
128e0c4386eSCy Schubert     ret = TEST_ptr(params)
129e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_TLS1_PRF))
130e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0);
131e0c4386eSCy Schubert 
132e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
133e0c4386eSCy Schubert     OPENSSL_free(params);
134e0c4386eSCy Schubert     return ret;
135e0c4386eSCy Schubert }
136e0c4386eSCy Schubert 
test_kdf_tls1_prf_1byte_secret(void)137e0c4386eSCy Schubert static int test_kdf_tls1_prf_1byte_secret(void)
138e0c4386eSCy Schubert {
139e0c4386eSCy Schubert     int ret;
140e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
141e0c4386eSCy Schubert     unsigned char out[16];
142e0c4386eSCy Schubert     OSSL_PARAM *params;
143e0c4386eSCy Schubert 
144e0c4386eSCy Schubert     params = construct_tls1_prf_params("sha256", "1", "seed");
145e0c4386eSCy Schubert 
146e0c4386eSCy Schubert     ret = TEST_ptr(params)
147e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_TLS1_PRF))
148e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0);
149e0c4386eSCy Schubert 
150e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
151e0c4386eSCy Schubert     OPENSSL_free(params);
152e0c4386eSCy Schubert     return ret;
153e0c4386eSCy Schubert }
154e0c4386eSCy Schubert 
test_kdf_tls1_prf_empty_seed(void)155e0c4386eSCy Schubert static int test_kdf_tls1_prf_empty_seed(void)
156e0c4386eSCy Schubert {
157e0c4386eSCy Schubert     int ret;
158e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
159e0c4386eSCy Schubert     unsigned char out[16];
160e0c4386eSCy Schubert     OSSL_PARAM *params;
161e0c4386eSCy Schubert 
162e0c4386eSCy Schubert     params = construct_tls1_prf_params("sha256", "secret", "");
163e0c4386eSCy Schubert 
164e0c4386eSCy Schubert     /* Negative test - derive should fail */
165e0c4386eSCy Schubert     ret = TEST_ptr(params)
166e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_TLS1_PRF))
167e0c4386eSCy Schubert         && TEST_true(EVP_KDF_CTX_set_params(kctx, params))
168e0c4386eSCy Schubert         && TEST_int_eq(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0);
169e0c4386eSCy Schubert 
170e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
171e0c4386eSCy Schubert     OPENSSL_free(params);
172e0c4386eSCy Schubert     return ret;
173e0c4386eSCy Schubert }
174e0c4386eSCy Schubert 
test_kdf_tls1_prf_1byte_seed(void)175e0c4386eSCy Schubert static int test_kdf_tls1_prf_1byte_seed(void)
176e0c4386eSCy Schubert {
177e0c4386eSCy Schubert     int ret;
178e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
179e0c4386eSCy Schubert     unsigned char out[16];
180e0c4386eSCy Schubert     OSSL_PARAM *params;
181e0c4386eSCy Schubert 
182e0c4386eSCy Schubert     params = construct_tls1_prf_params("sha256", "secret", "1");
183e0c4386eSCy Schubert 
184e0c4386eSCy Schubert     ret = TEST_ptr(params)
185e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_TLS1_PRF))
186e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0);
187e0c4386eSCy Schubert 
188e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
189e0c4386eSCy Schubert     OPENSSL_free(params);
190e0c4386eSCy Schubert     return ret;
191e0c4386eSCy Schubert }
192e0c4386eSCy Schubert 
construct_hkdf_params(char * digest,char * key,size_t keylen,char * salt,char * info)193e0c4386eSCy Schubert static OSSL_PARAM *construct_hkdf_params(char *digest, char *key,
194e0c4386eSCy Schubert     size_t keylen, char *salt, char *info)
195e0c4386eSCy Schubert {
196e0c4386eSCy Schubert     OSSL_PARAM *params = OPENSSL_malloc(sizeof(OSSL_PARAM) * 5);
197e0c4386eSCy Schubert     OSSL_PARAM *p = params;
198e0c4386eSCy Schubert 
199e0c4386eSCy Schubert     if (params == NULL)
200e0c4386eSCy Schubert         return NULL;
201e0c4386eSCy Schubert 
202e0c4386eSCy Schubert     if (digest != NULL)
203e0c4386eSCy Schubert         *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
204e0c4386eSCy Schubert                                                 digest, 0);
205e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
206e0c4386eSCy Schubert                                              salt, strlen(salt));
207e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
208e0c4386eSCy Schubert                                              (unsigned char *)key, keylen);
209e0c4386eSCy Schubert     if (info != NULL)
210e0c4386eSCy Schubert         *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
211e0c4386eSCy Schubert                                                  info, strlen(info));
212e0c4386eSCy Schubert     else
213e0c4386eSCy Schubert         *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE,
214e0c4386eSCy Schubert                                                 "EXTRACT_ONLY", 0);
215e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
216e0c4386eSCy Schubert 
217e0c4386eSCy Schubert     return params;
218e0c4386eSCy Schubert }
219e0c4386eSCy Schubert 
test_kdf_hkdf(void)220e0c4386eSCy Schubert static int test_kdf_hkdf(void)
221e0c4386eSCy Schubert {
222e0c4386eSCy Schubert     int ret;
223e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
224e0c4386eSCy Schubert     unsigned char out[10];
225e0c4386eSCy Schubert     OSSL_PARAM *params;
226e0c4386eSCy Schubert     static const unsigned char expected[sizeof(out)] = {
227e0c4386eSCy Schubert         0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8, 0xde, 0x13
228e0c4386eSCy Schubert     };
229e0c4386eSCy Schubert 
230e0c4386eSCy Schubert     params = construct_hkdf_params("sha256", "secret", 6, "salt", "label");
231e0c4386eSCy Schubert 
232e0c4386eSCy Schubert     ret = TEST_ptr(params)
233e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF))
234e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0)
235e0c4386eSCy Schubert         && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
236e0c4386eSCy Schubert 
237e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
238e0c4386eSCy Schubert     OPENSSL_free(params);
239e0c4386eSCy Schubert     return ret;
240e0c4386eSCy Schubert }
241e0c4386eSCy Schubert 
do_kdf_hkdf_gettables(int expand_only,int has_digest)242e0c4386eSCy Schubert static int do_kdf_hkdf_gettables(int expand_only, int has_digest)
243e0c4386eSCy Schubert {
244e0c4386eSCy Schubert     int ret = 0;
245e0c4386eSCy Schubert     size_t sz = 0;
246e0c4386eSCy Schubert     OSSL_PARAM *params;
247e0c4386eSCy Schubert     OSSL_PARAM params_get[2];
248e0c4386eSCy Schubert     const OSSL_PARAM *gettables, *p;
249e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
250e0c4386eSCy Schubert 
251e0c4386eSCy Schubert     if (!TEST_ptr(params = construct_hkdf_params(
252e0c4386eSCy Schubert                                                  has_digest ? "sha256" : NULL,
253e0c4386eSCy Schubert                                                  "secret", 6, "salt",
254e0c4386eSCy Schubert                                                  expand_only ? NULL : "label"))
255e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF))
256e0c4386eSCy Schubert         || !TEST_true(EVP_KDF_CTX_set_params(kctx, params)))
257e0c4386eSCy Schubert         goto err;
258e0c4386eSCy Schubert 
259e0c4386eSCy Schubert     /* Check OSSL_KDF_PARAM_SIZE is gettable */
260e0c4386eSCy Schubert     if (!TEST_ptr(gettables = EVP_KDF_CTX_gettable_params(kctx))
261e0c4386eSCy Schubert         || !TEST_ptr(p = OSSL_PARAM_locate_const(gettables, OSSL_KDF_PARAM_SIZE)))
262e0c4386eSCy Schubert         goto err;
263e0c4386eSCy Schubert 
264e0c4386eSCy Schubert     /* Get OSSL_KDF_PARAM_SIZE as a size_t */
265e0c4386eSCy Schubert     params_get[0] = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_SIZE, &sz);
266e0c4386eSCy Schubert     params_get[1] = OSSL_PARAM_construct_end();
267e0c4386eSCy Schubert     if (has_digest) {
268e0c4386eSCy Schubert         if (!TEST_int_eq(EVP_KDF_CTX_get_params(kctx, params_get), 1)
269e0c4386eSCy Schubert             || !TEST_size_t_eq(sz, expand_only ? SHA256_DIGEST_LENGTH : SIZE_MAX))
270e0c4386eSCy Schubert             goto err;
271e0c4386eSCy Schubert     } else {
272e0c4386eSCy Schubert         if (!TEST_int_eq(EVP_KDF_CTX_get_params(kctx, params_get), 0))
273e0c4386eSCy Schubert             goto err;
274e0c4386eSCy Schubert     }
275e0c4386eSCy Schubert 
276e0c4386eSCy Schubert     /* Get params returns -2 if an unsupported parameter is requested */
277e0c4386eSCy Schubert     params_get[0] = OSSL_PARAM_construct_end();
278e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_KDF_CTX_get_params(kctx, params_get), -2))
279e0c4386eSCy Schubert         goto err;
280e0c4386eSCy Schubert     ret = 1;
281e0c4386eSCy Schubert err:
282e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
283e0c4386eSCy Schubert     OPENSSL_free(params);
284e0c4386eSCy Schubert     return ret;
285e0c4386eSCy Schubert }
286e0c4386eSCy Schubert 
test_kdf_hkdf_gettables(void)287e0c4386eSCy Schubert static int test_kdf_hkdf_gettables(void)
288e0c4386eSCy Schubert {
289e0c4386eSCy Schubert     return do_kdf_hkdf_gettables(0, 1);
290e0c4386eSCy Schubert }
291e0c4386eSCy Schubert 
test_kdf_hkdf_gettables_expandonly(void)292e0c4386eSCy Schubert static int test_kdf_hkdf_gettables_expandonly(void)
293e0c4386eSCy Schubert {
294e0c4386eSCy Schubert     return do_kdf_hkdf_gettables(1, 1);
295e0c4386eSCy Schubert }
296e0c4386eSCy Schubert 
test_kdf_hkdf_gettables_no_digest(void)297e0c4386eSCy Schubert static int test_kdf_hkdf_gettables_no_digest(void)
298e0c4386eSCy Schubert {
299e0c4386eSCy Schubert     return do_kdf_hkdf_gettables(1, 0);
300e0c4386eSCy Schubert }
301e0c4386eSCy Schubert 
test_kdf_hkdf_invalid_digest(void)302e0c4386eSCy Schubert static int test_kdf_hkdf_invalid_digest(void)
303e0c4386eSCy Schubert {
304e0c4386eSCy Schubert     int ret;
305e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
306e0c4386eSCy Schubert     OSSL_PARAM *params;
307e0c4386eSCy Schubert 
308e0c4386eSCy Schubert     params = construct_hkdf_params("blah", "secret", 6, "salt", "label");
309e0c4386eSCy Schubert 
310e0c4386eSCy Schubert     ret = TEST_ptr(params)
311e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF))
312e0c4386eSCy Schubert         && TEST_false(EVP_KDF_CTX_set_params(kctx, params));
313e0c4386eSCy Schubert 
314e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
315e0c4386eSCy Schubert     OPENSSL_free(params);
316e0c4386eSCy Schubert     return ret;
317e0c4386eSCy Schubert }
318e0c4386eSCy Schubert 
test_kdf_hkdf_derive_set_params_fail(void)319e0c4386eSCy Schubert static int test_kdf_hkdf_derive_set_params_fail(void)
320e0c4386eSCy Schubert {
321e0c4386eSCy Schubert     int ret = 0, i = 0;
322e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
323e0c4386eSCy Schubert     OSSL_PARAM params[2];
324e0c4386eSCy Schubert     unsigned char out[10];
325e0c4386eSCy Schubert 
326e0c4386eSCy Schubert     if (!TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF)))
327e0c4386eSCy Schubert         goto end;
328e0c4386eSCy Schubert     /*
329e0c4386eSCy Schubert      * Set the wrong type for the digest so that it causes a failure
330e0c4386eSCy Schubert      * inside kdf_hkdf_derive() when kdf_hkdf_set_ctx_params() is called
331e0c4386eSCy Schubert      */
332e0c4386eSCy Schubert     params[0] = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_DIGEST, &i);
333e0c4386eSCy Schubert     params[1] = OSSL_PARAM_construct_end();
334e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_KDF_derive(kctx, out, sizeof(out), params), 0))
335e0c4386eSCy Schubert         goto end;
336e0c4386eSCy Schubert     ret = 1;
337e0c4386eSCy Schubert end:
338e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
339e0c4386eSCy Schubert     return ret;
340e0c4386eSCy Schubert }
341e0c4386eSCy Schubert 
test_kdf_hkdf_set_invalid_mode(void)342e0c4386eSCy Schubert static int test_kdf_hkdf_set_invalid_mode(void)
343e0c4386eSCy Schubert {
344e0c4386eSCy Schubert     int ret = 0, bad_mode = 100;
345e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
346e0c4386eSCy Schubert     OSSL_PARAM params[2];
347e0c4386eSCy Schubert 
348e0c4386eSCy Schubert     if (!TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF)))
349e0c4386eSCy Schubert         goto end;
350e0c4386eSCy Schubert     params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE,
351e0c4386eSCy Schubert                                                  "BADMODE", 0);
352e0c4386eSCy Schubert     params[1] = OSSL_PARAM_construct_end();
353e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_KDF_CTX_set_params(kctx, params), 0))
354e0c4386eSCy Schubert         goto end;
355e0c4386eSCy Schubert 
356e0c4386eSCy Schubert     params[0] = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &bad_mode);
357e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_KDF_CTX_set_params(kctx, params), 0))
358e0c4386eSCy Schubert         goto end;
359e0c4386eSCy Schubert 
360e0c4386eSCy Schubert     ret = 1;
361e0c4386eSCy Schubert end:
362e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
363e0c4386eSCy Schubert     return ret;
364e0c4386eSCy Schubert }
365e0c4386eSCy Schubert 
do_kdf_hkdf_set_invalid_param(const char * key,int type)366e0c4386eSCy Schubert static int do_kdf_hkdf_set_invalid_param(const char *key, int type)
367e0c4386eSCy Schubert {
368e0c4386eSCy Schubert     int ret = 0;
369e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
370e0c4386eSCy Schubert     OSSL_PARAM params[2];
371e0c4386eSCy Schubert     unsigned char buf[2];
372e0c4386eSCy Schubert 
373e0c4386eSCy Schubert     if (!TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF)))
374e0c4386eSCy Schubert         goto end;
375e0c4386eSCy Schubert     /* Set the wrong type for the key so that it causes a failure */
376e0c4386eSCy Schubert     if (type == OSSL_PARAM_UTF8_STRING)
377e0c4386eSCy Schubert         params[0] = OSSL_PARAM_construct_utf8_string(key, "BAD", 0);
378e0c4386eSCy Schubert     else
379e0c4386eSCy Schubert         params[0] = OSSL_PARAM_construct_octet_string(key, buf, sizeof(buf));
380e0c4386eSCy Schubert     params[1] = OSSL_PARAM_construct_end();
381e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_KDF_CTX_set_params(kctx, params), 0))
382e0c4386eSCy Schubert         goto end;
383e0c4386eSCy Schubert 
384e0c4386eSCy Schubert     ret = 1;
385e0c4386eSCy Schubert end:
386e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
387e0c4386eSCy Schubert     return ret;
388e0c4386eSCy Schubert }
389e0c4386eSCy Schubert 
test_kdf_hkdf_set_ctx_param_fail(void)390e0c4386eSCy Schubert static int test_kdf_hkdf_set_ctx_param_fail(void)
391e0c4386eSCy Schubert {
392e0c4386eSCy Schubert     return do_kdf_hkdf_set_invalid_param(OSSL_KDF_PARAM_MODE,
393e0c4386eSCy Schubert                                          OSSL_PARAM_OCTET_STRING)
394e0c4386eSCy Schubert            && do_kdf_hkdf_set_invalid_param(OSSL_KDF_PARAM_KEY,
395e0c4386eSCy Schubert                                             OSSL_PARAM_UTF8_STRING)
396e0c4386eSCy Schubert            && do_kdf_hkdf_set_invalid_param(OSSL_KDF_PARAM_SALT,
397e0c4386eSCy Schubert                                             OSSL_PARAM_UTF8_STRING)
398e0c4386eSCy Schubert            && do_kdf_hkdf_set_invalid_param(OSSL_KDF_PARAM_INFO,
399e0c4386eSCy Schubert                                             OSSL_PARAM_UTF8_STRING);
400e0c4386eSCy Schubert }
401e0c4386eSCy Schubert 
test_kdf_hkdf_zero_output_size(void)402e0c4386eSCy Schubert static int test_kdf_hkdf_zero_output_size(void)
403e0c4386eSCy Schubert {
404e0c4386eSCy Schubert     int ret;
405e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
406e0c4386eSCy Schubert     unsigned char out[10];
407e0c4386eSCy Schubert     OSSL_PARAM *params;
408e0c4386eSCy Schubert 
409e0c4386eSCy Schubert     params = construct_hkdf_params("sha256", "secret", 6, "salt", "label");
410e0c4386eSCy Schubert 
411e0c4386eSCy Schubert     /* Negative test - derive should fail */
412e0c4386eSCy Schubert     ret = TEST_ptr(params)
413e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF))
414e0c4386eSCy Schubert         && TEST_true(EVP_KDF_CTX_set_params(kctx, params))
415e0c4386eSCy Schubert         && TEST_int_eq(EVP_KDF_derive(kctx, out, 0, NULL), 0);
416e0c4386eSCy Schubert 
417e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
418e0c4386eSCy Schubert     OPENSSL_free(params);
419e0c4386eSCy Schubert     return ret;
420e0c4386eSCy Schubert }
421e0c4386eSCy Schubert 
test_kdf_hkdf_empty_key(void)422e0c4386eSCy Schubert static int test_kdf_hkdf_empty_key(void)
423e0c4386eSCy Schubert {
424e0c4386eSCy Schubert     int ret;
425e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
426e0c4386eSCy Schubert     unsigned char out[10];
427e0c4386eSCy Schubert     OSSL_PARAM *params;
428e0c4386eSCy Schubert 
429e0c4386eSCy Schubert     params = construct_hkdf_params("sha256", "", 0, "salt", "label");
430e0c4386eSCy Schubert 
431e0c4386eSCy Schubert     ret = TEST_ptr(params)
432e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF))
433e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0);
434e0c4386eSCy Schubert 
435e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
436e0c4386eSCy Schubert     OPENSSL_free(params);
437e0c4386eSCy Schubert     return ret;
438e0c4386eSCy Schubert }
439e0c4386eSCy Schubert 
test_kdf_hkdf_1byte_key(void)440e0c4386eSCy Schubert static int test_kdf_hkdf_1byte_key(void)
441e0c4386eSCy Schubert {
442e0c4386eSCy Schubert     int ret;
443e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
444e0c4386eSCy Schubert     unsigned char out[10];
445e0c4386eSCy Schubert     OSSL_PARAM *params;
446e0c4386eSCy Schubert 
447e0c4386eSCy Schubert     params = construct_hkdf_params("sha256", "1", 1, "salt", "label");
448e0c4386eSCy Schubert 
449e0c4386eSCy Schubert     ret = TEST_ptr(params)
450e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF))
451e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0);
452e0c4386eSCy Schubert 
453e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
454e0c4386eSCy Schubert     OPENSSL_free(params);
455e0c4386eSCy Schubert     return ret;
456e0c4386eSCy Schubert }
457e0c4386eSCy Schubert 
test_kdf_hkdf_empty_salt(void)458e0c4386eSCy Schubert static int test_kdf_hkdf_empty_salt(void)
459e0c4386eSCy Schubert {
460e0c4386eSCy Schubert     int ret;
461e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
462e0c4386eSCy Schubert     unsigned char out[10];
463e0c4386eSCy Schubert     OSSL_PARAM *params;
464e0c4386eSCy Schubert 
465e0c4386eSCy Schubert     params = construct_hkdf_params("sha256", "secret", 6, "", "label");
466e0c4386eSCy Schubert 
467e0c4386eSCy Schubert     ret = TEST_ptr(params)
468e0c4386eSCy Schubert         && TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF))
469e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0);
470e0c4386eSCy Schubert 
471e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
472e0c4386eSCy Schubert     OPENSSL_free(params);
473e0c4386eSCy Schubert     return ret;
474e0c4386eSCy Schubert }
475e0c4386eSCy Schubert 
construct_pbkdf1_params(char * pass,char * digest,char * salt,unsigned int * iter)476e0c4386eSCy Schubert static OSSL_PARAM *construct_pbkdf1_params(char *pass, char *digest, char *salt,
477e0c4386eSCy Schubert     unsigned int *iter)
478e0c4386eSCy Schubert {
479e0c4386eSCy Schubert     OSSL_PARAM *params = OPENSSL_malloc(sizeof(OSSL_PARAM) * 5);
480e0c4386eSCy Schubert     OSSL_PARAM *p = params;
481e0c4386eSCy Schubert 
482e0c4386eSCy Schubert     if (params == NULL)
483e0c4386eSCy Schubert         return NULL;
484e0c4386eSCy Schubert 
485e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
486e0c4386eSCy Schubert                                              (unsigned char *)pass, strlen(pass));
487e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
488e0c4386eSCy Schubert                                              (unsigned char *)salt, strlen(salt));
489e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_ITER, iter);
490e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
491e0c4386eSCy Schubert                                              digest, 0);
492e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
493e0c4386eSCy Schubert 
494e0c4386eSCy Schubert     return params;
495e0c4386eSCy Schubert }
496e0c4386eSCy Schubert 
test_kdf_pbkdf1(void)497e0c4386eSCy Schubert static int test_kdf_pbkdf1(void)
498e0c4386eSCy Schubert {
499e0c4386eSCy Schubert     int ret = 0;
500e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
501e0c4386eSCy Schubert     unsigned char out[25];
502e0c4386eSCy Schubert     unsigned int iterations = 4096;
503e0c4386eSCy Schubert     OSSL_LIB_CTX *libctx = NULL;
504e0c4386eSCy Schubert     OSSL_PARAM *params = NULL;
505e0c4386eSCy Schubert     OSSL_PROVIDER *legacyprov = NULL;
506e0c4386eSCy Schubert     OSSL_PROVIDER *defprov = NULL;
507e0c4386eSCy Schubert     const unsigned char expected[sizeof(out)] = {
508e0c4386eSCy Schubert         0xfb, 0x83, 0x4d, 0x36, 0x6d, 0xbc, 0x53, 0x87, 0x35, 0x1b, 0x34, 0x75,
509e0c4386eSCy Schubert         0x95, 0x88, 0x32, 0x4f, 0x3e, 0x82, 0x81, 0x01, 0x21, 0x93, 0x64, 0x00,
510e0c4386eSCy Schubert         0xcc
511e0c4386eSCy Schubert     };
512e0c4386eSCy Schubert 
513e0c4386eSCy Schubert     if (!TEST_ptr(libctx = OSSL_LIB_CTX_new()))
514e0c4386eSCy Schubert         goto err;
515e0c4386eSCy Schubert 
516e0c4386eSCy Schubert     /* PBKDF1 only available in the legacy provider */
517e0c4386eSCy Schubert     legacyprov = OSSL_PROVIDER_load(libctx, "legacy");
518e0c4386eSCy Schubert     if (legacyprov == NULL) {
519e0c4386eSCy Schubert         OSSL_LIB_CTX_free(libctx);
520e0c4386eSCy Schubert         return TEST_skip("PBKDF1 only available in legacy provider");
521e0c4386eSCy Schubert     }
522e0c4386eSCy Schubert 
523e0c4386eSCy Schubert     if (!TEST_ptr(defprov = OSSL_PROVIDER_load(libctx, "default")))
524e0c4386eSCy Schubert         goto err;
525e0c4386eSCy Schubert 
526e0c4386eSCy Schubert     params = construct_pbkdf1_params("passwordPASSWORDpassword", "sha256",
527e0c4386eSCy Schubert                                      "saltSALTsaltSALTsaltSALTsaltSALTsalt",
528e0c4386eSCy Schubert                                      &iterations);
529e0c4386eSCy Schubert 
530e0c4386eSCy Schubert     if (!TEST_ptr(params)
531e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname_libctx(libctx, OSSL_KDF_NAME_PBKDF1))
532e0c4386eSCy Schubert         || !TEST_true(EVP_KDF_CTX_set_params(kctx, params))
533e0c4386eSCy Schubert         || !TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0)
534e0c4386eSCy Schubert         || !TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)))
535e0c4386eSCy Schubert         goto err;
536e0c4386eSCy Schubert 
537e0c4386eSCy Schubert     ret = 1;
538e0c4386eSCy Schubert err:
539e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
540e0c4386eSCy Schubert     OPENSSL_free(params);
541e0c4386eSCy Schubert     OSSL_PROVIDER_unload(defprov);
542e0c4386eSCy Schubert     OSSL_PROVIDER_unload(legacyprov);
543e0c4386eSCy Schubert     OSSL_LIB_CTX_free(libctx);
544e0c4386eSCy Schubert     return ret;
545e0c4386eSCy Schubert }
546e0c4386eSCy Schubert 
test_kdf_pbkdf1_key_too_long(void)547e0c4386eSCy Schubert static int test_kdf_pbkdf1_key_too_long(void)
548e0c4386eSCy Schubert {
549e0c4386eSCy Schubert     int ret = 0;
550e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
551e0c4386eSCy Schubert     unsigned char out[EVP_MAX_MD_SIZE + 1];
552e0c4386eSCy Schubert     unsigned int iterations = 4096;
553e0c4386eSCy Schubert     OSSL_LIB_CTX *libctx = NULL;
554e0c4386eSCy Schubert     OSSL_PARAM *params = NULL;
555e0c4386eSCy Schubert     OSSL_PROVIDER *legacyprov = NULL;
556e0c4386eSCy Schubert     OSSL_PROVIDER *defprov = NULL;
557e0c4386eSCy Schubert 
558e0c4386eSCy Schubert     if (!TEST_ptr(libctx = OSSL_LIB_CTX_new()))
559e0c4386eSCy Schubert         goto err;
560e0c4386eSCy Schubert 
561e0c4386eSCy Schubert     /* PBKDF1 only available in the legacy provider */
562e0c4386eSCy Schubert     legacyprov = OSSL_PROVIDER_load(libctx, "legacy");
563e0c4386eSCy Schubert     if (legacyprov == NULL) {
564e0c4386eSCy Schubert         OSSL_LIB_CTX_free(libctx);
565e0c4386eSCy Schubert         return TEST_skip("PBKDF1 only available in legacy provider");
566e0c4386eSCy Schubert     }
567e0c4386eSCy Schubert 
568e0c4386eSCy Schubert     if (!TEST_ptr(defprov = OSSL_PROVIDER_load(libctx, "default")))
569e0c4386eSCy Schubert         goto err;
570e0c4386eSCy Schubert 
571e0c4386eSCy Schubert     params = construct_pbkdf1_params("passwordPASSWORDpassword", "sha256",
572e0c4386eSCy Schubert                                      "saltSALTsaltSALTsaltSALTsaltSALTsalt",
573e0c4386eSCy Schubert                                      &iterations);
574e0c4386eSCy Schubert 
575e0c4386eSCy Schubert     /*
576e0c4386eSCy Schubert      * This is the same test sequence as test_kdf_pbkdf1, but we expect
577e0c4386eSCy Schubert      * failure here as the requested key size is longer than the digest
578e0c4386eSCy Schubert      * can provide
579e0c4386eSCy Schubert      */
580e0c4386eSCy Schubert     if (!TEST_ptr(params)
581e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname_libctx(libctx, OSSL_KDF_NAME_PBKDF1))
582e0c4386eSCy Schubert         || !TEST_true(EVP_KDF_CTX_set_params(kctx, params))
583e0c4386eSCy Schubert         || !TEST_int_eq(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0))
584e0c4386eSCy Schubert         goto err;
585e0c4386eSCy Schubert 
586e0c4386eSCy Schubert     ret = 1;
587e0c4386eSCy Schubert err:
588e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
589e0c4386eSCy Schubert     OPENSSL_free(params);
590e0c4386eSCy Schubert     OSSL_PROVIDER_unload(defprov);
591e0c4386eSCy Schubert     OSSL_PROVIDER_unload(legacyprov);
592e0c4386eSCy Schubert     OSSL_LIB_CTX_free(libctx);
593e0c4386eSCy Schubert     return ret;
594e0c4386eSCy Schubert }
595e0c4386eSCy Schubert 
construct_pbkdf2_params(char * pass,char * digest,char * salt,unsigned int * iter,int * mode)596e0c4386eSCy Schubert static OSSL_PARAM *construct_pbkdf2_params(char *pass, char *digest, char *salt,
597e0c4386eSCy Schubert     unsigned int *iter, int *mode)
598e0c4386eSCy Schubert {
599e0c4386eSCy Schubert     OSSL_PARAM *params = OPENSSL_malloc(sizeof(OSSL_PARAM) * 6);
600e0c4386eSCy Schubert     OSSL_PARAM *p = params;
601e0c4386eSCy Schubert 
602e0c4386eSCy Schubert     if (params == NULL)
603e0c4386eSCy Schubert         return NULL;
604e0c4386eSCy Schubert 
605e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
606e0c4386eSCy Schubert                                              (unsigned char *)pass, strlen(pass));
607e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
608e0c4386eSCy Schubert                                              (unsigned char *)salt, strlen(salt));
609e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_ITER, iter);
610e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
611e0c4386eSCy Schubert                                              digest, 0);
612e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS5, mode);
613e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
614e0c4386eSCy Schubert 
615e0c4386eSCy Schubert     return params;
616e0c4386eSCy Schubert }
617e0c4386eSCy Schubert 
test_kdf_pbkdf2(void)618e0c4386eSCy Schubert static int test_kdf_pbkdf2(void)
619e0c4386eSCy Schubert {
620e0c4386eSCy Schubert     int ret = 0;
621e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
622e0c4386eSCy Schubert     unsigned char out[25];
623e0c4386eSCy Schubert     unsigned int iterations = 4096;
624e0c4386eSCy Schubert     int mode = 0;
625e0c4386eSCy Schubert     OSSL_PARAM *params;
626e0c4386eSCy Schubert     const unsigned char expected[sizeof(out)] = {
627e0c4386eSCy Schubert         0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f,
628e0c4386eSCy Schubert         0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf,
629e0c4386eSCy Schubert         0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18,
630e0c4386eSCy Schubert         0x1c
631e0c4386eSCy Schubert     };
632e0c4386eSCy Schubert 
633e0c4386eSCy Schubert     params = construct_pbkdf2_params("passwordPASSWORDpassword", "sha256",
634e0c4386eSCy Schubert                                      "saltSALTsaltSALTsaltSALTsaltSALTsalt",
635e0c4386eSCy Schubert                                      &iterations, &mode);
636e0c4386eSCy Schubert 
637e0c4386eSCy Schubert     if (!TEST_ptr(params)
638e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_PBKDF2))
639e0c4386eSCy Schubert         || !TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0)
640e0c4386eSCy Schubert         || !TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)))
641e0c4386eSCy Schubert         goto err;
642e0c4386eSCy Schubert 
643e0c4386eSCy Schubert     ret = 1;
644e0c4386eSCy Schubert err:
645e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
646e0c4386eSCy Schubert     OPENSSL_free(params);
647e0c4386eSCy Schubert     return ret;
648e0c4386eSCy Schubert }
649e0c4386eSCy Schubert 
test_kdf_pbkdf2_small_output(void)650e0c4386eSCy Schubert static int test_kdf_pbkdf2_small_output(void)
651e0c4386eSCy Schubert {
652e0c4386eSCy Schubert     int ret = 0;
653e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
654e0c4386eSCy Schubert     unsigned char out[25];
655e0c4386eSCy Schubert     unsigned int iterations = 4096;
656e0c4386eSCy Schubert     int mode = 0;
657e0c4386eSCy Schubert     OSSL_PARAM *params;
658e0c4386eSCy Schubert 
659e0c4386eSCy Schubert     params = construct_pbkdf2_params("passwordPASSWORDpassword", "sha256",
660e0c4386eSCy Schubert                                      "saltSALTsaltSALTsaltSALTsaltSALTsalt",
661e0c4386eSCy Schubert                                      &iterations, &mode);
662e0c4386eSCy Schubert 
663e0c4386eSCy Schubert     if (!TEST_ptr(params)
664e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_PBKDF2))
665e0c4386eSCy Schubert         || !TEST_true(EVP_KDF_CTX_set_params(kctx, params))
666e0c4386eSCy Schubert         /* A key length that is too small should fail */
667e0c4386eSCy Schubert         || !TEST_int_eq(EVP_KDF_derive(kctx, out, 112 / 8 - 1, NULL), 0))
668e0c4386eSCy Schubert         goto err;
669e0c4386eSCy Schubert 
670e0c4386eSCy Schubert     ret = 1;
671e0c4386eSCy Schubert err:
672e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
673e0c4386eSCy Schubert     OPENSSL_free(params);
674e0c4386eSCy Schubert     return ret;
675e0c4386eSCy Schubert }
676e0c4386eSCy Schubert 
test_kdf_pbkdf2_large_output(void)677e0c4386eSCy Schubert static int test_kdf_pbkdf2_large_output(void)
678e0c4386eSCy Schubert {
679e0c4386eSCy Schubert     int ret = 0;
680e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
681e0c4386eSCy Schubert     unsigned char out[25];
682e0c4386eSCy Schubert     size_t len = 0;
683e0c4386eSCy Schubert     unsigned int iterations = 4096;
684e0c4386eSCy Schubert     int mode = 0;
685e0c4386eSCy Schubert     OSSL_PARAM *params;
686e0c4386eSCy Schubert 
687e0c4386eSCy Schubert     if (sizeof(len) > 32)
688e0c4386eSCy Schubert         len = SIZE_MAX;
689e0c4386eSCy Schubert 
690e0c4386eSCy Schubert     params = construct_pbkdf2_params("passwordPASSWORDpassword", "sha256",
691e0c4386eSCy Schubert                                      "saltSALTsaltSALTsaltSALTsaltSALTsalt",
692e0c4386eSCy Schubert                                      &iterations, &mode);
693e0c4386eSCy Schubert 
694e0c4386eSCy Schubert     if (!TEST_ptr(params)
695e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_PBKDF2))
696e0c4386eSCy Schubert         /* A key length that is too large should fail */
697e0c4386eSCy Schubert         || !TEST_true(EVP_KDF_CTX_set_params(kctx, params))
698e0c4386eSCy Schubert         || (len != 0 && !TEST_int_eq(EVP_KDF_derive(kctx, out, len, NULL), 0)))
699e0c4386eSCy Schubert         goto err;
700e0c4386eSCy Schubert 
701e0c4386eSCy Schubert     ret = 1;
702e0c4386eSCy Schubert err:
703e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
704e0c4386eSCy Schubert     OPENSSL_free(params);
705e0c4386eSCy Schubert     return ret;
706e0c4386eSCy Schubert }
707e0c4386eSCy Schubert 
test_kdf_pbkdf2_small_salt(void)708e0c4386eSCy Schubert static int test_kdf_pbkdf2_small_salt(void)
709e0c4386eSCy Schubert {
710e0c4386eSCy Schubert     int ret = 0;
711e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
712e0c4386eSCy Schubert     unsigned int iterations = 4096;
713e0c4386eSCy Schubert     int mode = 0;
714e0c4386eSCy Schubert     OSSL_PARAM *params;
715e0c4386eSCy Schubert 
716e0c4386eSCy Schubert     params = construct_pbkdf2_params("passwordPASSWORDpassword", "sha256",
717e0c4386eSCy Schubert                                      "saltSALT",
718e0c4386eSCy Schubert                                      &iterations, &mode);
719e0c4386eSCy Schubert 
720e0c4386eSCy Schubert     if (!TEST_ptr(params)
721e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_PBKDF2))
722e0c4386eSCy Schubert         /* A salt that is too small should fail */
723e0c4386eSCy Schubert         || !TEST_false(EVP_KDF_CTX_set_params(kctx, params)))
724e0c4386eSCy Schubert         goto err;
725e0c4386eSCy Schubert 
726e0c4386eSCy Schubert     ret = 1;
727e0c4386eSCy Schubert err:
728e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
729e0c4386eSCy Schubert     OPENSSL_free(params);
730e0c4386eSCy Schubert     return ret;
731e0c4386eSCy Schubert }
732e0c4386eSCy Schubert 
test_kdf_pbkdf2_small_iterations(void)733e0c4386eSCy Schubert static int test_kdf_pbkdf2_small_iterations(void)
734e0c4386eSCy Schubert {
735e0c4386eSCy Schubert     int ret = 0;
736e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
737e0c4386eSCy Schubert     unsigned int iterations = 1;
738e0c4386eSCy Schubert     int mode = 0;
739e0c4386eSCy Schubert     OSSL_PARAM *params;
740e0c4386eSCy Schubert 
741e0c4386eSCy Schubert     params = construct_pbkdf2_params("passwordPASSWORDpassword", "sha256",
742e0c4386eSCy Schubert                                      "saltSALTsaltSALTsaltSALTsaltSALTsalt",
743e0c4386eSCy Schubert                                      &iterations, &mode);
744e0c4386eSCy Schubert 
745e0c4386eSCy Schubert     if (!TEST_ptr(params)
746e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_PBKDF2))
747e0c4386eSCy Schubert         /* An iteration count that is too small should fail */
748e0c4386eSCy Schubert         || !TEST_false(EVP_KDF_CTX_set_params(kctx, params)))
749e0c4386eSCy Schubert         goto err;
750e0c4386eSCy Schubert 
751e0c4386eSCy Schubert     ret = 1;
752e0c4386eSCy Schubert err:
753e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
754e0c4386eSCy Schubert     OPENSSL_free(params);
755e0c4386eSCy Schubert     return ret;
756e0c4386eSCy Schubert }
757e0c4386eSCy Schubert 
test_kdf_pbkdf2_small_salt_pkcs5(void)758e0c4386eSCy Schubert static int test_kdf_pbkdf2_small_salt_pkcs5(void)
759e0c4386eSCy Schubert {
760e0c4386eSCy Schubert     int ret = 0;
761e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
762e0c4386eSCy Schubert     unsigned char out[25];
763e0c4386eSCy Schubert     unsigned int iterations = 4096;
764e0c4386eSCy Schubert     int mode = 1;
765e0c4386eSCy Schubert     OSSL_PARAM *params;
766e0c4386eSCy Schubert     OSSL_PARAM mode_params[2];
767e0c4386eSCy Schubert 
768e0c4386eSCy Schubert     params = construct_pbkdf2_params("passwordPASSWORDpassword", "sha256",
769e0c4386eSCy Schubert                                      "saltSALT",
770e0c4386eSCy Schubert                                      &iterations, &mode);
771e0c4386eSCy Schubert 
772e0c4386eSCy Schubert     if (!TEST_ptr(params)
773e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_PBKDF2))
774e0c4386eSCy Schubert         /* A salt that is too small should pass in pkcs5 mode */
775e0c4386eSCy Schubert         || !TEST_true(EVP_KDF_CTX_set_params(kctx, params))
776e0c4386eSCy Schubert         || !TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0))
777e0c4386eSCy Schubert         goto err;
778e0c4386eSCy Schubert 
779e0c4386eSCy Schubert     mode = 0;
780e0c4386eSCy Schubert     mode_params[0] = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS5, &mode);
781e0c4386eSCy Schubert     mode_params[1] = OSSL_PARAM_construct_end();
782e0c4386eSCy Schubert 
783e0c4386eSCy Schubert     /* If the "pkcs5" mode is disabled then the derive will now fail */
784e0c4386eSCy Schubert     if (!TEST_true(EVP_KDF_CTX_set_params(kctx, mode_params))
785e0c4386eSCy Schubert         || !TEST_int_eq(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0))
786e0c4386eSCy Schubert         goto err;
787e0c4386eSCy Schubert 
788e0c4386eSCy Schubert     ret = 1;
789e0c4386eSCy Schubert err:
790e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
791e0c4386eSCy Schubert     OPENSSL_free(params);
792e0c4386eSCy Schubert     return ret;
793e0c4386eSCy Schubert }
794e0c4386eSCy Schubert 
test_kdf_pbkdf2_small_iterations_pkcs5(void)795e0c4386eSCy Schubert static int test_kdf_pbkdf2_small_iterations_pkcs5(void)
796e0c4386eSCy Schubert {
797e0c4386eSCy Schubert     int ret = 0;
798e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
799e0c4386eSCy Schubert     unsigned char out[25];
800e0c4386eSCy Schubert     unsigned int iterations = 1;
801e0c4386eSCy Schubert     int mode = 1;
802e0c4386eSCy Schubert     OSSL_PARAM *params;
803e0c4386eSCy Schubert     OSSL_PARAM mode_params[2];
804e0c4386eSCy Schubert 
805e0c4386eSCy Schubert     params = construct_pbkdf2_params("passwordPASSWORDpassword", "sha256",
806e0c4386eSCy Schubert                                      "saltSALTsaltSALTsaltSALTsaltSALTsalt",
807e0c4386eSCy Schubert                                      &iterations, &mode);
808e0c4386eSCy Schubert 
809e0c4386eSCy Schubert     if (!TEST_ptr(params)
810e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_PBKDF2))
811e0c4386eSCy Schubert         /* An iteration count that is too small will pass in pkcs5 mode */
812e0c4386eSCy Schubert         || !TEST_true(EVP_KDF_CTX_set_params(kctx, params))
813e0c4386eSCy Schubert         || !TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0))
814e0c4386eSCy Schubert         goto err;
815e0c4386eSCy Schubert 
816e0c4386eSCy Schubert     mode = 0;
817e0c4386eSCy Schubert     mode_params[0] = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS5, &mode);
818e0c4386eSCy Schubert     mode_params[1] = OSSL_PARAM_construct_end();
819e0c4386eSCy Schubert 
820e0c4386eSCy Schubert     /* If the "pkcs5" mode is disabled then the derive will now fail */
821e0c4386eSCy Schubert     if (!TEST_true(EVP_KDF_CTX_set_params(kctx, mode_params))
822e0c4386eSCy Schubert         || !TEST_int_eq(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0))
823e0c4386eSCy Schubert         goto err;
824e0c4386eSCy Schubert 
825e0c4386eSCy Schubert     ret = 1;
826e0c4386eSCy Schubert err:
827e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
828e0c4386eSCy Schubert     OPENSSL_free(params);
829e0c4386eSCy Schubert     return ret;
830e0c4386eSCy Schubert }
831e0c4386eSCy Schubert 
test_kdf_pbkdf2_invalid_digest(void)832e0c4386eSCy Schubert static int test_kdf_pbkdf2_invalid_digest(void)
833e0c4386eSCy Schubert {
834e0c4386eSCy Schubert     int ret = 0;
835e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
836e0c4386eSCy Schubert     unsigned int iterations = 4096;
837e0c4386eSCy Schubert     int mode = 0;
838e0c4386eSCy Schubert     OSSL_PARAM *params;
839e0c4386eSCy Schubert 
840e0c4386eSCy Schubert     params = construct_pbkdf2_params("passwordPASSWORDpassword", "blah",
841e0c4386eSCy Schubert                                      "saltSALTsaltSALTsaltSALTsaltSALTsalt",
842e0c4386eSCy Schubert                                      &iterations, &mode);
843e0c4386eSCy Schubert 
844e0c4386eSCy Schubert     if (!TEST_ptr(params)
845e0c4386eSCy Schubert         || !TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_PBKDF2))
846e0c4386eSCy Schubert         /* Unknown digest should fail */
847e0c4386eSCy Schubert         || !TEST_false(EVP_KDF_CTX_set_params(kctx, params)))
848e0c4386eSCy Schubert         goto err;
849e0c4386eSCy Schubert 
850e0c4386eSCy Schubert     ret = 1;
851e0c4386eSCy Schubert err:
852e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
853e0c4386eSCy Schubert     OPENSSL_free(params);
854e0c4386eSCy Schubert     return ret;
855e0c4386eSCy Schubert }
856e0c4386eSCy Schubert 
857e0c4386eSCy Schubert #ifndef OPENSSL_NO_SCRYPT
test_kdf_scrypt(void)858e0c4386eSCy Schubert static int test_kdf_scrypt(void)
859e0c4386eSCy Schubert {
860*0d0c8621SEnji Cooper     int i, ret;
861e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
862e0c4386eSCy Schubert     OSSL_PARAM params[7], *p = params;
863e0c4386eSCy Schubert     unsigned char out[64];
864e0c4386eSCy Schubert     unsigned int nu = 1024, ru = 8, pu = 16, maxmem = 16;
865e0c4386eSCy Schubert     static const unsigned char expected[sizeof(out)] = {
866e0c4386eSCy Schubert         0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00,
867e0c4386eSCy Schubert         0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe,
868e0c4386eSCy Schubert         0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30,
869e0c4386eSCy Schubert         0xe7, 0x73, 0x76, 0x63, 0x4b, 0x37, 0x31, 0x62,
870e0c4386eSCy Schubert         0x2e, 0xaf, 0x30, 0xd9, 0x2e, 0x22, 0xa3, 0x88,
871e0c4386eSCy Schubert         0x6f, 0xf1, 0x09, 0x27, 0x9d, 0x98, 0x30, 0xda,
872e0c4386eSCy Schubert         0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, 0xee, 0x6d,
873e0c4386eSCy Schubert         0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40
874e0c4386eSCy Schubert     };
875e0c4386eSCy Schubert 
876e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
877e0c4386eSCy Schubert                                              (char *)"password", 8);
878e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
879e0c4386eSCy Schubert                                              (char *)"NaCl", 4);
880e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_SCRYPT_N, &nu);
881e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_SCRYPT_R, &ru);
882e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_SCRYPT_P, &pu);
883e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_SCRYPT_MAXMEM, &maxmem);
884e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
885e0c4386eSCy Schubert 
886*0d0c8621SEnji Cooper     ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SCRYPT));
887*0d0c8621SEnji Cooper     for (i = 0; ret && i < 2; ++i) {
888*0d0c8621SEnji Cooper         ret = ret
889*0d0c8621SEnji Cooper             && TEST_true(EVP_KDF_CTX_set_params(kctx, params));
890*0d0c8621SEnji Cooper         if (i == 0)
891*0d0c8621SEnji Cooper             ret = ret
892*0d0c8621SEnji Cooper                 && TEST_int_le(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0)
893e0c4386eSCy Schubert                 && TEST_true(OSSL_PARAM_set_uint(p - 1, 10 * 1024 * 1024))
894*0d0c8621SEnji Cooper                 && TEST_true(EVP_KDF_CTX_set_params(kctx, p - 1));
895*0d0c8621SEnji Cooper         ret = ret
896e0c4386eSCy Schubert             && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0)
897e0c4386eSCy Schubert             && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
898*0d0c8621SEnji Cooper         if (i == 0)
899*0d0c8621SEnji Cooper             EVP_KDF_CTX_reset(kctx);
900*0d0c8621SEnji Cooper     }
901e0c4386eSCy Schubert 
902e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
903e0c4386eSCy Schubert     return ret;
904e0c4386eSCy Schubert }
905e0c4386eSCy Schubert #endif /* OPENSSL_NO_SCRYPT */
906e0c4386eSCy Schubert 
test_kdf_ss_hash(void)907e0c4386eSCy Schubert static int test_kdf_ss_hash(void)
908e0c4386eSCy Schubert {
909e0c4386eSCy Schubert     int ret;
910e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
911e0c4386eSCy Schubert     OSSL_PARAM params[4], *p = params;
912e0c4386eSCy Schubert     unsigned char out[14];
913e0c4386eSCy Schubert     static unsigned char z[] = {
914e0c4386eSCy Schubert         0x6d,0xbd,0xc2,0x3f,0x04,0x54,0x88,0xe4,0x06,0x27,0x57,0xb0,0x6b,0x9e,
915e0c4386eSCy Schubert         0xba,0xe1,0x83,0xfc,0x5a,0x59,0x46,0xd8,0x0d,0xb9,0x3f,0xec,0x6f,0x62,
916e0c4386eSCy Schubert         0xec,0x07,0xe3,0x72,0x7f,0x01,0x26,0xae,0xd1,0x2c,0xe4,0xb2,0x62,0xf4,
917e0c4386eSCy Schubert         0x7d,0x48,0xd5,0x42,0x87,0xf8,0x1d,0x47,0x4c,0x7c,0x3b,0x18,0x50,0xe9
918e0c4386eSCy Schubert     };
919e0c4386eSCy Schubert     static unsigned char other[] = {
920e0c4386eSCy Schubert         0xa1,0xb2,0xc3,0xd4,0xe5,0x43,0x41,0x56,0x53,0x69,0x64,0x3c,0x83,0x2e,
921e0c4386eSCy Schubert         0x98,0x49,0xdc,0xdb,0xa7,0x1e,0x9a,0x31,0x39,0xe6,0x06,0xe0,0x95,0xde,
922e0c4386eSCy Schubert         0x3c,0x26,0x4a,0x66,0xe9,0x8a,0x16,0x58,0x54,0xcd,0x07,0x98,0x9b,0x1e,
923e0c4386eSCy Schubert         0xe0,0xec,0x3f,0x8d,0xbe
924e0c4386eSCy Schubert     };
925e0c4386eSCy Schubert     static const unsigned char expected[sizeof(out)] = {
926e0c4386eSCy Schubert         0xa4,0x62,0xde,0x16,0xa8,0x9d,0xe8,0x46,0x6e,0xf5,0x46,0x0b,0x47,0xb8
927e0c4386eSCy Schubert     };
928e0c4386eSCy Schubert 
929e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
930e0c4386eSCy Schubert                                             (char *)"sha224", 0);
931e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, z, sizeof(z));
932e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, other,
933e0c4386eSCy Schubert                                              sizeof(other));
934e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
935e0c4386eSCy Schubert 
936e0c4386eSCy Schubert     ret =
937e0c4386eSCy Schubert         TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SSKDF))
938e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0)
939e0c4386eSCy Schubert         && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
940e0c4386eSCy Schubert 
941e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
942e0c4386eSCy Schubert     return ret;
943e0c4386eSCy Schubert }
944e0c4386eSCy Schubert 
test_kdf_x963(void)945e0c4386eSCy Schubert static int test_kdf_x963(void)
946e0c4386eSCy Schubert {
947e0c4386eSCy Schubert     int ret;
948e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
949e0c4386eSCy Schubert     OSSL_PARAM params[4], *p = params;
950e0c4386eSCy Schubert     unsigned char out[1024 / 8];
951e0c4386eSCy Schubert     /*
952e0c4386eSCy Schubert      * Test data from https://csrc.nist.gov/CSRC/media/Projects/
953e0c4386eSCy Schubert      *  Cryptographic-Algorithm-Validation-Program/documents/components/
954e0c4386eSCy Schubert      *  800-135testvectors/ansx963_2001.zip
955e0c4386eSCy Schubert      */
956e0c4386eSCy Schubert     static unsigned char z[] = {
957e0c4386eSCy Schubert         0x00, 0xaa, 0x5b, 0xb7, 0x9b, 0x33, 0xe3, 0x89, 0xfa, 0x58, 0xce, 0xad,
958e0c4386eSCy Schubert         0xc0, 0x47, 0x19, 0x7f, 0x14, 0xe7, 0x37, 0x12, 0xf4, 0x52, 0xca, 0xa9,
959e0c4386eSCy Schubert         0xfc, 0x4c, 0x9a, 0xdb, 0x36, 0x93, 0x48, 0xb8, 0x15, 0x07, 0x39, 0x2f,
960e0c4386eSCy Schubert         0x1a, 0x86, 0xdd, 0xfd, 0xb7, 0xc4, 0xff, 0x82, 0x31, 0xc4, 0xbd, 0x0f,
961e0c4386eSCy Schubert         0x44, 0xe4, 0x4a, 0x1b, 0x55, 0xb1, 0x40, 0x47, 0x47, 0xa9, 0xe2, 0xe7,
962e0c4386eSCy Schubert         0x53, 0xf5, 0x5e, 0xf0, 0x5a, 0x2d
963e0c4386eSCy Schubert     };
964e0c4386eSCy Schubert     static unsigned char shared[] = {
965e0c4386eSCy Schubert         0xe3, 0xb5, 0xb4, 0xc1, 0xb0, 0xd5, 0xcf, 0x1d, 0x2b, 0x3a, 0x2f, 0x99,
966e0c4386eSCy Schubert         0x37, 0x89, 0x5d, 0x31
967e0c4386eSCy Schubert     };
968e0c4386eSCy Schubert     static const unsigned char expected[sizeof(out)] = {
969e0c4386eSCy Schubert         0x44, 0x63, 0xf8, 0x69, 0xf3, 0xcc, 0x18, 0x76, 0x9b, 0x52, 0x26, 0x4b,
970e0c4386eSCy Schubert         0x01, 0x12, 0xb5, 0x85, 0x8f, 0x7a, 0xd3, 0x2a, 0x5a, 0x2d, 0x96, 0xd8,
971e0c4386eSCy Schubert         0xcf, 0xfa, 0xbf, 0x7f, 0xa7, 0x33, 0x63, 0x3d, 0x6e, 0x4d, 0xd2, 0xa5,
972e0c4386eSCy Schubert         0x99, 0xac, 0xce, 0xb3, 0xea, 0x54, 0xa6, 0x21, 0x7c, 0xe0, 0xb5, 0x0e,
973e0c4386eSCy Schubert         0xef, 0x4f, 0x6b, 0x40, 0xa5, 0xc3, 0x02, 0x50, 0xa5, 0xa8, 0xee, 0xee,
974e0c4386eSCy Schubert         0x20, 0x80, 0x02, 0x26, 0x70, 0x89, 0xdb, 0xf3, 0x51, 0xf3, 0xf5, 0x02,
975e0c4386eSCy Schubert         0x2a, 0xa9, 0x63, 0x8b, 0xf1, 0xee, 0x41, 0x9d, 0xea, 0x9c, 0x4f, 0xf7,
976e0c4386eSCy Schubert         0x45, 0xa2, 0x5a, 0xc2, 0x7b, 0xda, 0x33, 0xca, 0x08, 0xbd, 0x56, 0xdd,
977e0c4386eSCy Schubert         0x1a, 0x59, 0xb4, 0x10, 0x6c, 0xf2, 0xdb, 0xbc, 0x0a, 0xb2, 0xaa, 0x8e,
978e0c4386eSCy Schubert         0x2e, 0xfa, 0x7b, 0x17, 0x90, 0x2d, 0x34, 0x27, 0x69, 0x51, 0xce, 0xcc,
979e0c4386eSCy Schubert         0xab, 0x87, 0xf9, 0x66, 0x1c, 0x3e, 0x88, 0x16
980e0c4386eSCy Schubert     };
981e0c4386eSCy Schubert 
982e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
983e0c4386eSCy Schubert                                             (char *)"sha512", 0);
984e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, z, sizeof(z));
985e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, shared,
986e0c4386eSCy Schubert                                              sizeof(shared));
987e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
988e0c4386eSCy Schubert 
989e0c4386eSCy Schubert     ret =
990e0c4386eSCy Schubert         TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_X963KDF))
991e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0)
992e0c4386eSCy Schubert         && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
993e0c4386eSCy Schubert 
994e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
995e0c4386eSCy Schubert     return ret;
996e0c4386eSCy Schubert }
997e0c4386eSCy Schubert 
998e0c4386eSCy Schubert #if !defined(OPENSSL_NO_CMAC) && !defined(OPENSSL_NO_CAMELLIA)
999e0c4386eSCy Schubert /*
1000e0c4386eSCy Schubert  * KBKDF test vectors from RFC 6803 (Camellia Encryption for Kerberos 5)
1001e0c4386eSCy Schubert  * section 10.
1002e0c4386eSCy Schubert  */
test_kdf_kbkdf_6803_128(void)1003e0c4386eSCy Schubert static int test_kdf_kbkdf_6803_128(void)
1004e0c4386eSCy Schubert {
1005e0c4386eSCy Schubert     int ret = 0, i, p;
1006e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1007e0c4386eSCy Schubert     OSSL_PARAM params[7];
1008e0c4386eSCy Schubert     static unsigned char input_key[] = {
1009e0c4386eSCy Schubert         0x57, 0xD0, 0x29, 0x72, 0x98, 0xFF, 0xD9, 0xD3,
1010e0c4386eSCy Schubert         0x5D, 0xE5, 0xA4, 0x7F, 0xB4, 0xBD, 0xE2, 0x4B,
1011e0c4386eSCy Schubert     };
1012e0c4386eSCy Schubert     static unsigned char constants[][5] = {
1013e0c4386eSCy Schubert         { 0x00, 0x00, 0x00, 0x02, 0x99 },
1014e0c4386eSCy Schubert         { 0x00, 0x00, 0x00, 0x02, 0xaa },
1015e0c4386eSCy Schubert         { 0x00, 0x00, 0x00, 0x02, 0x55 },
1016e0c4386eSCy Schubert     };
1017e0c4386eSCy Schubert     static unsigned char outputs[][16] = {
1018e0c4386eSCy Schubert         {0xD1, 0x55, 0x77, 0x5A, 0x20, 0x9D, 0x05, 0xF0,
1019e0c4386eSCy Schubert          0x2B, 0x38, 0xD4, 0x2A, 0x38, 0x9E, 0x5A, 0x56},
1020e0c4386eSCy Schubert         {0x64, 0xDF, 0x83, 0xF8, 0x5A, 0x53, 0x2F, 0x17,
1021e0c4386eSCy Schubert          0x57, 0x7D, 0x8C, 0x37, 0x03, 0x57, 0x96, 0xAB},
1022e0c4386eSCy Schubert         {0x3E, 0x4F, 0xBD, 0xF3, 0x0F, 0xB8, 0x25, 0x9C,
1023e0c4386eSCy Schubert          0x42, 0x5C, 0xB6, 0xC9, 0x6F, 0x1F, 0x46, 0x35}
1024e0c4386eSCy Schubert     };
1025e0c4386eSCy Schubert     static unsigned char iv[16] = { 0 };
1026e0c4386eSCy Schubert     unsigned char result[16] = { 0 };
1027e0c4386eSCy Schubert 
1028e0c4386eSCy Schubert     for (i = 0; i < 3; i++) {
1029e0c4386eSCy Schubert         p = 0;
1030e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_utf8_string(
1031e0c4386eSCy Schubert             OSSL_KDF_PARAM_CIPHER, "CAMELLIA-128-CBC", 0);
1032e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_utf8_string(
1033e0c4386eSCy Schubert             OSSL_KDF_PARAM_MAC, "CMAC", 0);
1034e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_utf8_string(
1035e0c4386eSCy Schubert             OSSL_KDF_PARAM_MODE, "FEEDBACK", 0);
1036e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_octet_string(
1037e0c4386eSCy Schubert             OSSL_KDF_PARAM_KEY, input_key, sizeof(input_key));
1038e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_octet_string(
1039e0c4386eSCy Schubert             OSSL_KDF_PARAM_SALT, constants[i], sizeof(constants[i]));
1040e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_octet_string(
1041e0c4386eSCy Schubert             OSSL_KDF_PARAM_SEED, iv, sizeof(iv));
1042e0c4386eSCy Schubert         params[p] = OSSL_PARAM_construct_end();
1043e0c4386eSCy Schubert 
1044e0c4386eSCy Schubert         kctx = get_kdfbyname("KBKDF");
1045e0c4386eSCy Schubert         ret = TEST_ptr(kctx)
1046e0c4386eSCy Schubert             && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result),
1047e0c4386eSCy Schubert                                           params), 0)
1048e0c4386eSCy Schubert             && TEST_mem_eq(result, sizeof(result), outputs[i],
1049e0c4386eSCy Schubert                            sizeof(outputs[i]));
1050e0c4386eSCy Schubert         EVP_KDF_CTX_free(kctx);
1051e0c4386eSCy Schubert         if (ret != 1)
1052e0c4386eSCy Schubert             return ret;
1053e0c4386eSCy Schubert     }
1054e0c4386eSCy Schubert 
1055e0c4386eSCy Schubert     return ret;
1056e0c4386eSCy Schubert }
1057e0c4386eSCy Schubert 
test_kdf_kbkdf_6803_256(void)1058e0c4386eSCy Schubert static int test_kdf_kbkdf_6803_256(void)
1059e0c4386eSCy Schubert {
1060e0c4386eSCy Schubert     int ret = 0, i, p;
1061e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1062e0c4386eSCy Schubert     OSSL_PARAM params[7];
1063e0c4386eSCy Schubert     static unsigned char input_key[] = {
1064e0c4386eSCy Schubert         0xB9, 0xD6, 0x82, 0x8B, 0x20, 0x56, 0xB7, 0xBE,
1065e0c4386eSCy Schubert         0x65, 0x6D, 0x88, 0xA1, 0x23, 0xB1, 0xFA, 0xC6,
1066e0c4386eSCy Schubert         0x82, 0x14, 0xAC, 0x2B, 0x72, 0x7E, 0xCF, 0x5F,
1067e0c4386eSCy Schubert         0x69, 0xAF, 0xE0, 0xC4, 0xDF, 0x2A, 0x6D, 0x2C,
1068e0c4386eSCy Schubert     };
1069e0c4386eSCy Schubert     static unsigned char constants[][5] = {
1070e0c4386eSCy Schubert         { 0x00, 0x00, 0x00, 0x02, 0x99 },
1071e0c4386eSCy Schubert         { 0x00, 0x00, 0x00, 0x02, 0xaa },
1072e0c4386eSCy Schubert         { 0x00, 0x00, 0x00, 0x02, 0x55 },
1073e0c4386eSCy Schubert     };
1074e0c4386eSCy Schubert     static unsigned char outputs[][32] = {
1075e0c4386eSCy Schubert         {0xE4, 0x67, 0xF9, 0xA9, 0x55, 0x2B, 0xC7, 0xD3,
1076e0c4386eSCy Schubert          0x15, 0x5A, 0x62, 0x20, 0xAF, 0x9C, 0x19, 0x22,
1077e0c4386eSCy Schubert          0x0E, 0xEE, 0xD4, 0xFF, 0x78, 0xB0, 0xD1, 0xE6,
1078e0c4386eSCy Schubert          0xA1, 0x54, 0x49, 0x91, 0x46, 0x1A, 0x9E, 0x50,
1079e0c4386eSCy Schubert         },
1080e0c4386eSCy Schubert         {0x41, 0x2A, 0xEF, 0xC3, 0x62, 0xA7, 0x28, 0x5F,
1081e0c4386eSCy Schubert          0xC3, 0x96, 0x6C, 0x6A, 0x51, 0x81, 0xE7, 0x60,
1082e0c4386eSCy Schubert          0x5A, 0xE6, 0x75, 0x23, 0x5B, 0x6D, 0x54, 0x9F,
1083e0c4386eSCy Schubert          0xBF, 0xC9, 0xAB, 0x66, 0x30, 0xA4, 0xC6, 0x04,
1084e0c4386eSCy Schubert         },
1085e0c4386eSCy Schubert         {0xFA, 0x62, 0x4F, 0xA0, 0xE5, 0x23, 0x99, 0x3F,
1086e0c4386eSCy Schubert          0xA3, 0x88, 0xAE, 0xFD, 0xC6, 0x7E, 0x67, 0xEB,
1087e0c4386eSCy Schubert          0xCD, 0x8C, 0x08, 0xE8, 0xA0, 0x24, 0x6B, 0x1D,
1088e0c4386eSCy Schubert          0x73, 0xB0, 0xD1, 0xDD, 0x9F, 0xC5, 0x82, 0xB0,
1089e0c4386eSCy Schubert         },
1090e0c4386eSCy Schubert     };
1091e0c4386eSCy Schubert     static unsigned char iv[16] = { 0 };
1092e0c4386eSCy Schubert     unsigned char result[32] = { 0 };
1093e0c4386eSCy Schubert 
1094e0c4386eSCy Schubert     for (i = 0; i < 3; i++) {
1095e0c4386eSCy Schubert         p = 0;
1096e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_utf8_string(
1097e0c4386eSCy Schubert             OSSL_KDF_PARAM_CIPHER, "CAMELLIA-256-CBC", 0);
1098e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_utf8_string(
1099e0c4386eSCy Schubert             OSSL_KDF_PARAM_MAC, "CMAC", 0);
1100e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_utf8_string(
1101e0c4386eSCy Schubert             OSSL_KDF_PARAM_MODE, "FEEDBACK", 0);
1102e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_octet_string(
1103e0c4386eSCy Schubert             OSSL_KDF_PARAM_KEY, input_key, sizeof(input_key));
1104e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_octet_string(
1105e0c4386eSCy Schubert             OSSL_KDF_PARAM_SALT, constants[i], sizeof(constants[i]));
1106e0c4386eSCy Schubert         params[p++] = OSSL_PARAM_construct_octet_string(
1107e0c4386eSCy Schubert             OSSL_KDF_PARAM_SEED, iv, sizeof(iv));
1108e0c4386eSCy Schubert         params[p] = OSSL_PARAM_construct_end();
1109e0c4386eSCy Schubert 
1110e0c4386eSCy Schubert         kctx = get_kdfbyname("KBKDF");
1111e0c4386eSCy Schubert         ret = TEST_ptr(kctx)
1112e0c4386eSCy Schubert             && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result),
1113e0c4386eSCy Schubert                                           params), 0)
1114e0c4386eSCy Schubert             && TEST_mem_eq(result, sizeof(result), outputs[i],
1115e0c4386eSCy Schubert                            sizeof(outputs[i]));
1116e0c4386eSCy Schubert         EVP_KDF_CTX_free(kctx);
1117e0c4386eSCy Schubert         if (ret != 1)
1118e0c4386eSCy Schubert             return ret;
1119e0c4386eSCy Schubert     }
1120e0c4386eSCy Schubert 
1121e0c4386eSCy Schubert     return ret;
1122e0c4386eSCy Schubert }
1123e0c4386eSCy Schubert #endif
1124e0c4386eSCy Schubert 
construct_kbkdf_params(char * digest,char * mac,unsigned char * key,size_t keylen,char * salt,char * info)1125e0c4386eSCy Schubert static OSSL_PARAM *construct_kbkdf_params(char *digest, char *mac, unsigned char *key,
1126e0c4386eSCy Schubert     size_t keylen, char *salt, char *info)
1127e0c4386eSCy Schubert {
1128e0c4386eSCy Schubert     OSSL_PARAM *params = OPENSSL_malloc(sizeof(OSSL_PARAM) * 7);
1129e0c4386eSCy Schubert     OSSL_PARAM *p = params;
1130e0c4386eSCy Schubert 
1131e0c4386eSCy Schubert     if (params == NULL)
1132e0c4386eSCy Schubert         return NULL;
1133e0c4386eSCy Schubert 
1134e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(
1135e0c4386eSCy Schubert         OSSL_KDF_PARAM_DIGEST, digest, 0);
1136e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(
1137e0c4386eSCy Schubert         OSSL_KDF_PARAM_MAC, mac, 0);
1138e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(
1139e0c4386eSCy Schubert         OSSL_KDF_PARAM_MODE, "COUNTER", 0);
1140e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(
1141e0c4386eSCy Schubert         OSSL_KDF_PARAM_KEY, key, keylen);
1142e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(
1143e0c4386eSCy Schubert         OSSL_KDF_PARAM_SALT, salt, strlen(salt));
1144e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(
1145e0c4386eSCy Schubert         OSSL_KDF_PARAM_INFO, info, strlen(info));
1146e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
1147e0c4386eSCy Schubert 
1148e0c4386eSCy Schubert     return params;
1149e0c4386eSCy Schubert }
1150e0c4386eSCy Schubert 
test_kdf_kbkdf_invalid_digest(void)1151e0c4386eSCy Schubert static int test_kdf_kbkdf_invalid_digest(void)
1152e0c4386eSCy Schubert {
1153e0c4386eSCy Schubert     int ret;
1154e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1155e0c4386eSCy Schubert     OSSL_PARAM *params;
1156e0c4386eSCy Schubert 
1157e0c4386eSCy Schubert     static unsigned char key[] = {0x01};
1158e0c4386eSCy Schubert 
1159e0c4386eSCy Schubert     params = construct_kbkdf_params("blah", "HMAC", key, 1, "prf", "test");
1160e0c4386eSCy Schubert     if (!TEST_ptr(params))
1161e0c4386eSCy Schubert         return 0;
1162e0c4386eSCy Schubert 
1163e0c4386eSCy Schubert     /* Negative test case - set_params should fail */
1164e0c4386eSCy Schubert     kctx = get_kdfbyname("KBKDF");
1165e0c4386eSCy Schubert     ret = TEST_ptr(kctx)
1166e0c4386eSCy Schubert         && TEST_false(EVP_KDF_CTX_set_params(kctx, params));
1167e0c4386eSCy Schubert 
1168e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1169e0c4386eSCy Schubert     OPENSSL_free(params);
1170e0c4386eSCy Schubert     return ret;
1171e0c4386eSCy Schubert }
1172e0c4386eSCy Schubert 
test_kdf_kbkdf_invalid_mac(void)1173e0c4386eSCy Schubert static int test_kdf_kbkdf_invalid_mac(void)
1174e0c4386eSCy Schubert {
1175e0c4386eSCy Schubert     int ret;
1176e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1177e0c4386eSCy Schubert     OSSL_PARAM *params;
1178e0c4386eSCy Schubert 
1179e0c4386eSCy Schubert     static unsigned char key[] = {0x01};
1180e0c4386eSCy Schubert 
1181e0c4386eSCy Schubert     params = construct_kbkdf_params("sha256", "blah", key, 1, "prf", "test");
1182e0c4386eSCy Schubert     if (!TEST_ptr(params))
1183e0c4386eSCy Schubert         return 0;
1184e0c4386eSCy Schubert 
1185e0c4386eSCy Schubert     /* Negative test case - set_params should fail */
1186e0c4386eSCy Schubert     kctx = get_kdfbyname("KBKDF");
1187e0c4386eSCy Schubert     ret = TEST_ptr(kctx)
1188e0c4386eSCy Schubert         && TEST_false(EVP_KDF_CTX_set_params(kctx, params));
1189e0c4386eSCy Schubert 
1190e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1191e0c4386eSCy Schubert     OPENSSL_free(params);
1192e0c4386eSCy Schubert     return ret;
1193e0c4386eSCy Schubert }
1194e0c4386eSCy Schubert 
test_kdf_kbkdf_empty_key(void)1195e0c4386eSCy Schubert static int test_kdf_kbkdf_empty_key(void)
1196e0c4386eSCy Schubert {
1197e0c4386eSCy Schubert     int ret;
1198e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1199e0c4386eSCy Schubert     OSSL_PARAM *params;
1200e0c4386eSCy Schubert 
1201e0c4386eSCy Schubert     static unsigned char key[] = {0x01};
1202e0c4386eSCy Schubert     unsigned char result[32] = { 0 };
1203e0c4386eSCy Schubert 
1204e0c4386eSCy Schubert     params = construct_kbkdf_params("sha256", "HMAC", key, 0, "prf", "test");
1205e0c4386eSCy Schubert     if (!TEST_ptr(params))
1206e0c4386eSCy Schubert         return 0;
1207e0c4386eSCy Schubert 
1208e0c4386eSCy Schubert     /* Negative test case - derive should fail */
1209e0c4386eSCy Schubert     kctx = get_kdfbyname("KBKDF");
1210e0c4386eSCy Schubert     ret = TEST_ptr(kctx)
1211e0c4386eSCy Schubert         && TEST_true(EVP_KDF_CTX_set_params(kctx, params))
1212e0c4386eSCy Schubert         && TEST_int_eq(EVP_KDF_derive(kctx, result, sizeof(result), NULL), 0);
1213e0c4386eSCy Schubert 
1214e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1215e0c4386eSCy Schubert     OPENSSL_free(params);
1216e0c4386eSCy Schubert     return ret;
1217e0c4386eSCy Schubert }
1218e0c4386eSCy Schubert 
test_kdf_kbkdf_1byte_key(void)1219e0c4386eSCy Schubert static int test_kdf_kbkdf_1byte_key(void)
1220e0c4386eSCy Schubert {
1221e0c4386eSCy Schubert     int ret;
1222e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1223e0c4386eSCy Schubert     OSSL_PARAM *params;
1224e0c4386eSCy Schubert 
1225e0c4386eSCy Schubert     static unsigned char key[] = {0x01};
1226e0c4386eSCy Schubert     unsigned char result[32] = { 0 };
1227e0c4386eSCy Schubert 
1228e0c4386eSCy Schubert     params = construct_kbkdf_params("sha256", "HMAC", key, 1, "prf", "test");
1229e0c4386eSCy Schubert     if (!TEST_ptr(params))
1230e0c4386eSCy Schubert         return 0;
1231e0c4386eSCy Schubert 
1232e0c4386eSCy Schubert     kctx = get_kdfbyname("KBKDF");
1233e0c4386eSCy Schubert     ret = TEST_ptr(kctx)
1234e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result), params), 0);
1235e0c4386eSCy Schubert 
1236e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1237e0c4386eSCy Schubert     OPENSSL_free(params);
1238e0c4386eSCy Schubert     return ret;
1239e0c4386eSCy Schubert }
1240e0c4386eSCy Schubert 
test_kdf_kbkdf_zero_output_size(void)1241e0c4386eSCy Schubert static int test_kdf_kbkdf_zero_output_size(void)
1242e0c4386eSCy Schubert {
1243e0c4386eSCy Schubert     int ret;
1244e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1245e0c4386eSCy Schubert     OSSL_PARAM *params;
1246e0c4386eSCy Schubert 
1247e0c4386eSCy Schubert     static unsigned char key[] = {0x01};
1248e0c4386eSCy Schubert     unsigned char result[32] = { 0 };
1249e0c4386eSCy Schubert 
1250e0c4386eSCy Schubert     params = construct_kbkdf_params("sha256", "HMAC", key, 1, "prf", "test");
1251e0c4386eSCy Schubert     if (!TEST_ptr(params))
1252e0c4386eSCy Schubert         return 0;
1253e0c4386eSCy Schubert 
1254e0c4386eSCy Schubert     /* Negative test case - derive should fail */
1255e0c4386eSCy Schubert     kctx = get_kdfbyname("KBKDF");
1256e0c4386eSCy Schubert     ret = TEST_ptr(kctx)
1257e0c4386eSCy Schubert         && TEST_true(EVP_KDF_CTX_set_params(kctx, params))
1258e0c4386eSCy Schubert         && TEST_int_eq(EVP_KDF_derive(kctx, result, 0, NULL), 0);
1259e0c4386eSCy Schubert 
1260e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1261e0c4386eSCy Schubert     OPENSSL_free(params);
1262e0c4386eSCy Schubert     return ret;
1263e0c4386eSCy Schubert }
1264e0c4386eSCy Schubert 
1265e0c4386eSCy Schubert /* Two test vectors from RFC 8009 (AES Encryption with HMAC-SHA2 for Kerberos
1266e0c4386eSCy Schubert  * 5) appendix A. */
test_kdf_kbkdf_8009_prf1(void)1267e0c4386eSCy Schubert static int test_kdf_kbkdf_8009_prf1(void)
1268e0c4386eSCy Schubert {
1269e0c4386eSCy Schubert     int ret, i = 0;
1270e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1271e0c4386eSCy Schubert     OSSL_PARAM params[6];
1272e0c4386eSCy Schubert     char *label = "prf", *digest = "sha256", *prf_input = "test",
1273e0c4386eSCy Schubert         *mac = "HMAC";
1274e0c4386eSCy Schubert     static unsigned char input_key[] = {
1275e0c4386eSCy Schubert         0x37, 0x05, 0xD9, 0x60, 0x80, 0xC1, 0x77, 0x28,
1276e0c4386eSCy Schubert         0xA0, 0xE8, 0x00, 0xEA, 0xB6, 0xE0, 0xD2, 0x3C,
1277e0c4386eSCy Schubert     };
1278e0c4386eSCy Schubert     static unsigned char output[] = {
1279e0c4386eSCy Schubert         0x9D, 0x18, 0x86, 0x16, 0xF6, 0x38, 0x52, 0xFE,
1280e0c4386eSCy Schubert         0x86, 0x91, 0x5B, 0xB8, 0x40, 0xB4, 0xA8, 0x86,
1281e0c4386eSCy Schubert         0xFF, 0x3E, 0x6B, 0xB0, 0xF8, 0x19, 0xB4, 0x9B,
1282e0c4386eSCy Schubert         0x89, 0x33, 0x93, 0xD3, 0x93, 0x85, 0x42, 0x95,
1283e0c4386eSCy Schubert     };
1284e0c4386eSCy Schubert     unsigned char result[sizeof(output)] = { 0 };
1285e0c4386eSCy Schubert 
1286e0c4386eSCy Schubert     params[i++] = OSSL_PARAM_construct_utf8_string(
1287e0c4386eSCy Schubert         OSSL_KDF_PARAM_DIGEST, digest, 0);
1288e0c4386eSCy Schubert     params[i++] = OSSL_PARAM_construct_utf8_string(
1289e0c4386eSCy Schubert         OSSL_KDF_PARAM_MAC, mac, 0);
1290e0c4386eSCy Schubert     params[i++] = OSSL_PARAM_construct_octet_string(
1291e0c4386eSCy Schubert         OSSL_KDF_PARAM_KEY, input_key, sizeof(input_key));
1292e0c4386eSCy Schubert     params[i++] = OSSL_PARAM_construct_octet_string(
1293e0c4386eSCy Schubert         OSSL_KDF_PARAM_SALT, label, strlen(label));
1294e0c4386eSCy Schubert     params[i++] = OSSL_PARAM_construct_octet_string(
1295e0c4386eSCy Schubert         OSSL_KDF_PARAM_INFO, prf_input, strlen(prf_input));
1296e0c4386eSCy Schubert     params[i] = OSSL_PARAM_construct_end();
1297e0c4386eSCy Schubert 
1298e0c4386eSCy Schubert     kctx = get_kdfbyname("KBKDF");
1299e0c4386eSCy Schubert     ret = TEST_ptr(kctx)
1300e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result), params), 0)
1301e0c4386eSCy Schubert         && TEST_mem_eq(result, sizeof(result), output, sizeof(output));
1302e0c4386eSCy Schubert 
1303e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1304e0c4386eSCy Schubert     return ret;
1305e0c4386eSCy Schubert }
1306e0c4386eSCy Schubert 
test_kdf_kbkdf_8009_prf2(void)1307e0c4386eSCy Schubert static int test_kdf_kbkdf_8009_prf2(void)
1308e0c4386eSCy Schubert {
1309e0c4386eSCy Schubert     int ret, i = 0;
1310e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1311e0c4386eSCy Schubert     OSSL_PARAM params[6];
1312e0c4386eSCy Schubert     char *label = "prf", *digest = "sha384", *prf_input = "test",
1313e0c4386eSCy Schubert         *mac = "HMAC";
1314e0c4386eSCy Schubert     static unsigned char input_key[] = {
1315e0c4386eSCy Schubert         0x6D, 0x40, 0x4D, 0x37, 0xFA, 0xF7, 0x9F, 0x9D,
1316e0c4386eSCy Schubert         0xF0, 0xD3, 0x35, 0x68, 0xD3, 0x20, 0x66, 0x98,
1317e0c4386eSCy Schubert         0x00, 0xEB, 0x48, 0x36, 0x47, 0x2E, 0xA8, 0xA0,
1318e0c4386eSCy Schubert         0x26, 0xD1, 0x6B, 0x71, 0x82, 0x46, 0x0C, 0x52,
1319e0c4386eSCy Schubert     };
1320e0c4386eSCy Schubert     static unsigned char output[] = {
1321e0c4386eSCy Schubert         0x98, 0x01, 0xF6, 0x9A, 0x36, 0x8C, 0x2B, 0xF6,
1322e0c4386eSCy Schubert         0x75, 0xE5, 0x95, 0x21, 0xE1, 0x77, 0xD9, 0xA0,
1323e0c4386eSCy Schubert         0x7F, 0x67, 0xEF, 0xE1, 0xCF, 0xDE, 0x8D, 0x3C,
1324e0c4386eSCy Schubert         0x8D, 0x6F, 0x6A, 0x02, 0x56, 0xE3, 0xB1, 0x7D,
1325e0c4386eSCy Schubert         0xB3, 0xC1, 0xB6, 0x2A, 0xD1, 0xB8, 0x55, 0x33,
1326e0c4386eSCy Schubert         0x60, 0xD1, 0x73, 0x67, 0xEB, 0x15, 0x14, 0xD2,
1327e0c4386eSCy Schubert     };
1328e0c4386eSCy Schubert     unsigned char result[sizeof(output)] = { 0 };
1329e0c4386eSCy Schubert 
1330e0c4386eSCy Schubert     params[i++] = OSSL_PARAM_construct_utf8_string(
1331e0c4386eSCy Schubert         OSSL_KDF_PARAM_DIGEST, digest, 0);
1332e0c4386eSCy Schubert     params[i++] = OSSL_PARAM_construct_utf8_string(
1333e0c4386eSCy Schubert         OSSL_KDF_PARAM_MAC, mac, 0);
1334e0c4386eSCy Schubert     params[i++] = OSSL_PARAM_construct_octet_string(
1335e0c4386eSCy Schubert         OSSL_KDF_PARAM_KEY, input_key, sizeof(input_key));
1336e0c4386eSCy Schubert     params[i++] = OSSL_PARAM_construct_octet_string(
1337e0c4386eSCy Schubert         OSSL_KDF_PARAM_SALT, label, strlen(label));
1338e0c4386eSCy Schubert     params[i++] = OSSL_PARAM_construct_octet_string(
1339e0c4386eSCy Schubert         OSSL_KDF_PARAM_INFO, prf_input, strlen(prf_input));
1340e0c4386eSCy Schubert     params[i] = OSSL_PARAM_construct_end();
1341e0c4386eSCy Schubert 
1342e0c4386eSCy Schubert     kctx = get_kdfbyname("KBKDF");
1343e0c4386eSCy Schubert     ret = TEST_ptr(kctx)
1344e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result), params), 0)
1345e0c4386eSCy Schubert         && TEST_mem_eq(result, sizeof(result), output, sizeof(output));
1346e0c4386eSCy Schubert 
1347e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1348e0c4386eSCy Schubert     return ret;
1349e0c4386eSCy Schubert }
1350e0c4386eSCy Schubert 
1351e0c4386eSCy Schubert #if !defined(OPENSSL_NO_CMAC)
1352e0c4386eSCy Schubert /*
1353e0c4386eSCy Schubert  * Test vector taken from
1354e0c4386eSCy Schubert  * https://csrc.nist.gov/CSRC/media/Projects/
1355e0c4386eSCy Schubert  *    Cryptographic-Algorithm-Validation-Program/documents/KBKDF800-108/CounterMode.zip
1356e0c4386eSCy Schubert  *    Note: Only 32 bit counter is supported ([RLEN=32_BITS])
1357e0c4386eSCy Schubert  */
test_kdf_kbkdf_fixedinfo(void)1358e0c4386eSCy Schubert static int test_kdf_kbkdf_fixedinfo(void)
1359e0c4386eSCy Schubert {
1360e0c4386eSCy Schubert     int ret;
1361e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1362e0c4386eSCy Schubert     OSSL_PARAM params[8], *p = params;
1363e0c4386eSCy Schubert     static char *cipher = "AES128";
1364e0c4386eSCy Schubert     static char *mac = "CMAC";
1365e0c4386eSCy Schubert     static char *mode = "COUNTER";
1366e0c4386eSCy Schubert     int use_l = 0;
1367e0c4386eSCy Schubert     int use_separator = 0;
1368e0c4386eSCy Schubert 
1369e0c4386eSCy Schubert     static unsigned char input_key[] = {
1370e0c4386eSCy Schubert         0xc1, 0x0b, 0x15, 0x2e, 0x8c, 0x97, 0xb7, 0x7e,
1371e0c4386eSCy Schubert         0x18, 0x70, 0x4e, 0x0f, 0x0b, 0xd3, 0x83, 0x05,
1372e0c4386eSCy Schubert     };
1373e0c4386eSCy Schubert     static unsigned char fixed_input[] = {
1374e0c4386eSCy Schubert         0x98, 0xcd, 0x4c, 0xbb, 0xbe, 0xbe, 0x15, 0xd1,
1375e0c4386eSCy Schubert         0x7d, 0xc8, 0x6e, 0x6d, 0xba, 0xd8, 0x00, 0xa2,
1376e0c4386eSCy Schubert         0xdc, 0xbd, 0x64, 0xf7, 0xc7, 0xad, 0x0e, 0x78,
1377e0c4386eSCy Schubert         0xe9, 0xcf, 0x94, 0xff, 0xdb, 0xa8, 0x9d, 0x03,
1378e0c4386eSCy Schubert         0xe9, 0x7e, 0xad, 0xf6, 0xc4, 0xf7, 0xb8, 0x06,
1379e0c4386eSCy Schubert         0xca, 0xf5, 0x2a, 0xa3, 0x8f, 0x09, 0xd0, 0xeb,
1380e0c4386eSCy Schubert         0x71, 0xd7, 0x1f, 0x49, 0x7b, 0xcc, 0x69, 0x06,
1381e0c4386eSCy Schubert         0xb4, 0x8d, 0x36, 0xc4,
1382e0c4386eSCy Schubert 
1383e0c4386eSCy Schubert     };
1384e0c4386eSCy Schubert     static unsigned char output[] = {
1385e0c4386eSCy Schubert         0x26, 0xfa, 0xf6, 0x19, 0x08, 0xad, 0x9e, 0xe8,
1386e0c4386eSCy Schubert         0x81, 0xb8, 0x30, 0x5c, 0x22, 0x1d, 0xb5, 0x3f,
1387e0c4386eSCy Schubert     };
1388e0c4386eSCy Schubert     unsigned char result[sizeof(output)] = { 0 };
1389e0c4386eSCy Schubert 
1390e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER, cipher, 0);
1391e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, mac, 0);
1392e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE, mode, 0);
1393e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, input_key,
1394e0c4386eSCy Schubert                                              sizeof(input_key));
1395e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
1396e0c4386eSCy Schubert                                              fixed_input, sizeof(fixed_input));
1397e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_KBKDF_USE_L, &use_l);
1398e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_KBKDF_USE_SEPARATOR,
1399e0c4386eSCy Schubert                                     &use_separator);
1400e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
1401e0c4386eSCy Schubert 
1402e0c4386eSCy Schubert     kctx = get_kdfbyname("KBKDF");
1403e0c4386eSCy Schubert     ret = TEST_ptr(kctx)
1404e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result), params), 0)
1405e0c4386eSCy Schubert         && TEST_mem_eq(result, sizeof(result), output, sizeof(output));
1406e0c4386eSCy Schubert 
1407e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1408e0c4386eSCy Schubert     return ret;
1409e0c4386eSCy Schubert }
1410e0c4386eSCy Schubert #endif /* OPENSSL_NO_CMAC */
1411e0c4386eSCy Schubert 
test_kdf_ss_hmac(void)1412e0c4386eSCy Schubert static int test_kdf_ss_hmac(void)
1413e0c4386eSCy Schubert {
1414e0c4386eSCy Schubert     int ret;
1415e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1416e0c4386eSCy Schubert     OSSL_PARAM params[6], *p = params;
1417e0c4386eSCy Schubert     unsigned char out[16];
1418e0c4386eSCy Schubert     static unsigned char z[] = {
1419e0c4386eSCy Schubert         0xb7,0x4a,0x14,0x9a,0x16,0x15,0x46,0xf8,0xc2,0x0b,0x06,0xac,0x4e,0xd4
1420e0c4386eSCy Schubert     };
1421e0c4386eSCy Schubert     static unsigned char other[] = {
1422e0c4386eSCy Schubert         0x34,0x8a,0x37,0xa2,0x7e,0xf1,0x28,0x2f,0x5f,0x02,0x0d,0xcc
1423e0c4386eSCy Schubert     };
1424e0c4386eSCy Schubert     static unsigned char salt[] = {
1425e0c4386eSCy Schubert         0x36,0x38,0x27,0x1c,0xcd,0x68,0xa2,0x5d,0xc2,0x4e,0xcd,0xdd,0x39,0xef,
1426e0c4386eSCy Schubert         0x3f,0x89
1427e0c4386eSCy Schubert     };
1428e0c4386eSCy Schubert     static const unsigned char expected[sizeof(out)] = {
1429e0c4386eSCy Schubert         0x44,0xf6,0x76,0xe8,0x5c,0x1b,0x1a,0x8b,0xbc,0x3d,0x31,0x92,0x18,0x63,
1430e0c4386eSCy Schubert         0x1c,0xa3
1431e0c4386eSCy Schubert     };
1432e0c4386eSCy Schubert 
1433e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC,
1434e0c4386eSCy Schubert                                             (char *)OSSL_MAC_NAME_HMAC, 0);
1435e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
1436e0c4386eSCy Schubert                                             (char *)"sha256", 0);
1437e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, z, sizeof(z));
1438e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, other,
1439e0c4386eSCy Schubert                                              sizeof(other));
1440e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, salt,
1441e0c4386eSCy Schubert                                              sizeof(salt));
1442e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
1443e0c4386eSCy Schubert 
1444e0c4386eSCy Schubert     ret =
1445e0c4386eSCy Schubert         TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SSKDF))
1446e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0)
1447e0c4386eSCy Schubert         && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
1448e0c4386eSCy Schubert 
1449e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1450e0c4386eSCy Schubert     return ret;
1451e0c4386eSCy Schubert }
1452e0c4386eSCy Schubert 
test_kdf_ss_kmac(void)1453e0c4386eSCy Schubert static int test_kdf_ss_kmac(void)
1454e0c4386eSCy Schubert {
1455e0c4386eSCy Schubert     int ret;
1456e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1457e0c4386eSCy Schubert     OSSL_PARAM params[7], *p = params;
1458e0c4386eSCy Schubert     unsigned char out[64];
1459e0c4386eSCy Schubert     size_t mac_size = 20;
1460e0c4386eSCy Schubert     static unsigned char z[] = {
1461e0c4386eSCy Schubert         0xb7,0x4a,0x14,0x9a,0x16,0x15,0x46,0xf8,0xc2,0x0b,0x06,0xac,0x4e,0xd4
1462e0c4386eSCy Schubert     };
1463e0c4386eSCy Schubert     static unsigned char other[] = {
1464e0c4386eSCy Schubert         0x34,0x8a,0x37,0xa2,0x7e,0xf1,0x28,0x2f,0x5f,0x02,0x0d,0xcc
1465e0c4386eSCy Schubert     };
1466e0c4386eSCy Schubert     static unsigned char salt[] = {
1467e0c4386eSCy Schubert         0x36,0x38,0x27,0x1c,0xcd,0x68,0xa2,0x5d,0xc2,0x4e,0xcd,0xdd,0x39,0xef,
1468e0c4386eSCy Schubert         0x3f,0x89
1469e0c4386eSCy Schubert     };
1470e0c4386eSCy Schubert     static const unsigned char expected[sizeof(out)] = {
1471e0c4386eSCy Schubert         0xe9,0xc1,0x84,0x53,0xa0,0x62,0xb5,0x3b,0xdb,0xfc,0xbb,0x5a,0x34,0xbd,
1472e0c4386eSCy Schubert         0xb8,0xe5,0xe7,0x07,0xee,0xbb,0x5d,0xd1,0x34,0x42,0x43,0xd8,0xcf,0xc2,
1473e0c4386eSCy Schubert         0xc2,0xe6,0x33,0x2f,0x91,0xbd,0xa5,0x86,0xf3,0x7d,0xe4,0x8a,0x65,0xd4,
1474e0c4386eSCy Schubert         0xc5,0x14,0xfd,0xef,0xaa,0x1e,0x67,0x54,0xf3,0x73,0xd2,0x38,0xe1,0x95,
1475e0c4386eSCy Schubert         0xae,0x15,0x7e,0x1d,0xe8,0x14,0x98,0x03
1476e0c4386eSCy Schubert     };
1477e0c4386eSCy Schubert 
1478e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC,
1479e0c4386eSCy Schubert                                             (char *)OSSL_MAC_NAME_KMAC128, 0);
1480e0c4386eSCy Schubert     /* The digest parameter is not needed here and should be ignored */
1481e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
1482e0c4386eSCy Schubert                                             (char *)"SHA256", 0);
1483e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, z, sizeof(z));
1484e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, other,
1485e0c4386eSCy Schubert                                              sizeof(other));
1486e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, salt,
1487e0c4386eSCy Schubert                                              sizeof(salt));
1488e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_MAC_SIZE, &mac_size);
1489e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
1490e0c4386eSCy Schubert 
1491e0c4386eSCy Schubert     ret =
1492e0c4386eSCy Schubert         TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SSKDF))
1493e0c4386eSCy Schubert         && TEST_size_t_eq(EVP_KDF_CTX_get_kdf_size(kctx), 0)
1494e0c4386eSCy Schubert         && TEST_int_eq(EVP_KDF_CTX_set_params(kctx, params), 1)
1495e0c4386eSCy Schubert         /* The bug fix for KMAC returning SIZE_MAX was added in 3.0.8 */
1496e0c4386eSCy Schubert         && (fips_provider_version_lt(NULL, 3, 0, 8)
1497e0c4386eSCy Schubert             || TEST_size_t_eq(EVP_KDF_CTX_get_kdf_size(kctx), SIZE_MAX))
1498e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0)
1499e0c4386eSCy Schubert         && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
1500e0c4386eSCy Schubert 
1501e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1502e0c4386eSCy Schubert     return ret;
1503e0c4386eSCy Schubert }
1504e0c4386eSCy Schubert 
test_kdf_sshkdf(void)1505e0c4386eSCy Schubert static int test_kdf_sshkdf(void)
1506e0c4386eSCy Schubert {
1507e0c4386eSCy Schubert     int ret;
1508e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1509e0c4386eSCy Schubert     OSSL_PARAM params[6], *p = params;
1510e0c4386eSCy Schubert     char kdftype = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV;
1511e0c4386eSCy Schubert     unsigned char out[8];
1512e0c4386eSCy Schubert     /* Test data from NIST CAVS 14.1 test vectors */
1513e0c4386eSCy Schubert     static unsigned char key[] = {
1514e0c4386eSCy Schubert         0x00, 0x00, 0x00, 0x81, 0x00, 0x87, 0x5c, 0x55, 0x1c, 0xef, 0x52, 0x6a,
1515e0c4386eSCy Schubert         0x4a, 0x8b, 0xe1, 0xa7, 0xdf, 0x27, 0xe9, 0xed, 0x35, 0x4b, 0xac, 0x9a,
1516e0c4386eSCy Schubert         0xfb, 0x71, 0xf5, 0x3d, 0xba, 0xe9, 0x05, 0x67, 0x9d, 0x14, 0xf9, 0xfa,
1517e0c4386eSCy Schubert         0xf2, 0x46, 0x9c, 0x53, 0x45, 0x7c, 0xf8, 0x0a, 0x36, 0x6b, 0xe2, 0x78,
1518e0c4386eSCy Schubert         0x96, 0x5b, 0xa6, 0x25, 0x52, 0x76, 0xca, 0x2d, 0x9f, 0x4a, 0x97, 0xd2,
1519e0c4386eSCy Schubert         0x71, 0xf7, 0x1e, 0x50, 0xd8, 0xa9, 0xec, 0x46, 0x25, 0x3a, 0x6a, 0x90,
1520e0c4386eSCy Schubert         0x6a, 0xc2, 0xc5, 0xe4, 0xf4, 0x8b, 0x27, 0xa6, 0x3c, 0xe0, 0x8d, 0x80,
1521e0c4386eSCy Schubert         0x39, 0x0a, 0x49, 0x2a, 0xa4, 0x3b, 0xad, 0x9d, 0x88, 0x2c, 0xca, 0xc2,
1522e0c4386eSCy Schubert         0x3d, 0xac, 0x88, 0xbc, 0xad, 0xa4, 0xb4, 0xd4, 0x26, 0xa3, 0x62, 0x08,
1523e0c4386eSCy Schubert         0x3d, 0xab, 0x65, 0x69, 0xc5, 0x4c, 0x22, 0x4d, 0xd2, 0xd8, 0x76, 0x43,
1524e0c4386eSCy Schubert         0xaa, 0x22, 0x76, 0x93, 0xe1, 0x41, 0xad, 0x16, 0x30, 0xce, 0x13, 0x14,
1525e0c4386eSCy Schubert         0x4e
1526e0c4386eSCy Schubert     };
1527e0c4386eSCy Schubert     static unsigned char xcghash[] = {
1528e0c4386eSCy Schubert         0x0e, 0x68, 0x3f, 0xc8, 0xa9, 0xed, 0x7c, 0x2f, 0xf0, 0x2d, 0xef, 0x23,
1529e0c4386eSCy Schubert         0xb2, 0x74, 0x5e, 0xbc, 0x99, 0xb2, 0x67, 0xda, 0xa8, 0x6a, 0x4a, 0xa7,
1530e0c4386eSCy Schubert         0x69, 0x72, 0x39, 0x08, 0x82, 0x53, 0xf6, 0x42
1531e0c4386eSCy Schubert     };
1532e0c4386eSCy Schubert     static unsigned char sessid[] = {
1533e0c4386eSCy Schubert         0x0e, 0x68, 0x3f, 0xc8, 0xa9, 0xed, 0x7c, 0x2f, 0xf0, 0x2d, 0xef, 0x23,
1534e0c4386eSCy Schubert         0xb2, 0x74, 0x5e, 0xbc, 0x99, 0xb2, 0x67, 0xda, 0xa8, 0x6a, 0x4a, 0xa7,
1535e0c4386eSCy Schubert         0x69, 0x72, 0x39, 0x08, 0x82, 0x53, 0xf6, 0x42
1536e0c4386eSCy Schubert     };
1537e0c4386eSCy Schubert     static const unsigned char expected[sizeof(out)] = {
1538e0c4386eSCy Schubert         0x41, 0xff, 0x2e, 0xad, 0x16, 0x83, 0xf1, 0xe6
1539e0c4386eSCy Schubert     };
1540e0c4386eSCy Schubert 
1541e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
1542e0c4386eSCy Schubert                                             (char *)"sha256", 0);
1543e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, key,
1544e0c4386eSCy Schubert                                              sizeof(key));
1545e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SSHKDF_XCGHASH,
1546e0c4386eSCy Schubert                                              xcghash, sizeof(xcghash));
1547e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SSHKDF_SESSION_ID,
1548e0c4386eSCy Schubert                                              sessid, sizeof(sessid));
1549e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE,
1550e0c4386eSCy Schubert                                             &kdftype, sizeof(kdftype));
1551e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
1552e0c4386eSCy Schubert 
1553e0c4386eSCy Schubert     ret =
1554e0c4386eSCy Schubert         TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SSHKDF))
1555e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0)
1556e0c4386eSCy Schubert         && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
1557e0c4386eSCy Schubert 
1558e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1559e0c4386eSCy Schubert     return ret;
1560e0c4386eSCy Schubert }
1561e0c4386eSCy Schubert 
test_kdfs_same(EVP_KDF * kdf1,EVP_KDF * kdf2)1562e0c4386eSCy Schubert static int test_kdfs_same( EVP_KDF *kdf1, EVP_KDF *kdf2)
1563e0c4386eSCy Schubert {
1564e0c4386eSCy Schubert     /* Fast path in case the two are the same algorithm pointer */
1565e0c4386eSCy Schubert     if (kdf1 == kdf2)
1566e0c4386eSCy Schubert         return 1;
1567e0c4386eSCy Schubert     /*
1568e0c4386eSCy Schubert      * Compare their names and providers instead.
1569e0c4386eSCy Schubert      * This is necessary in a non-caching build (or a cache flush during fetch)
1570e0c4386eSCy Schubert      * because without the algorithm in the cache, fetching it a second time
1571e0c4386eSCy Schubert      * will result in a different pointer.
1572e0c4386eSCy Schubert      */
1573e0c4386eSCy Schubert     return TEST_ptr_eq(EVP_KDF_get0_provider(kdf1), EVP_KDF_get0_provider(kdf2))
1574e0c4386eSCy Schubert            && TEST_str_eq(EVP_KDF_get0_name(kdf1), EVP_KDF_get0_name(kdf2));
1575e0c4386eSCy Schubert }
1576e0c4386eSCy Schubert 
test_kdf_get_kdf(void)1577e0c4386eSCy Schubert static int test_kdf_get_kdf(void)
1578e0c4386eSCy Schubert {
1579e0c4386eSCy Schubert     EVP_KDF *kdf1 = NULL, *kdf2 = NULL;
1580e0c4386eSCy Schubert     ASN1_OBJECT *obj;
1581e0c4386eSCy Schubert     int ok = 1;
1582e0c4386eSCy Schubert 
1583e0c4386eSCy Schubert     if (!TEST_ptr(obj = OBJ_nid2obj(NID_id_pbkdf2))
1584e0c4386eSCy Schubert         || !TEST_ptr(kdf1 = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_PBKDF2, NULL))
1585e0c4386eSCy Schubert         || !TEST_ptr(kdf2 = EVP_KDF_fetch(NULL, OBJ_nid2sn(OBJ_obj2nid(obj)),
1586e0c4386eSCy Schubert                                           NULL))
1587e0c4386eSCy Schubert         || !test_kdfs_same(kdf1, kdf2))
1588e0c4386eSCy Schubert         ok = 0;
1589e0c4386eSCy Schubert     EVP_KDF_free(kdf1);
1590e0c4386eSCy Schubert     kdf1 = NULL;
1591e0c4386eSCy Schubert     EVP_KDF_free(kdf2);
1592e0c4386eSCy Schubert     kdf2 = NULL;
1593e0c4386eSCy Schubert 
1594e0c4386eSCy Schubert     if (!TEST_ptr(kdf1 = EVP_KDF_fetch(NULL, SN_tls1_prf, NULL))
1595e0c4386eSCy Schubert         || !TEST_ptr(kdf2 = EVP_KDF_fetch(NULL, LN_tls1_prf, NULL))
1596e0c4386eSCy Schubert         || !test_kdfs_same(kdf1, kdf2))
1597e0c4386eSCy Schubert         ok = 0;
1598e0c4386eSCy Schubert     /* kdf1 is re-used below, so don't free it here */
1599e0c4386eSCy Schubert     EVP_KDF_free(kdf2);
1600e0c4386eSCy Schubert     kdf2 = NULL;
1601e0c4386eSCy Schubert 
1602e0c4386eSCy Schubert     if (!TEST_ptr(kdf2 = EVP_KDF_fetch(NULL, OBJ_nid2sn(NID_tls1_prf), NULL))
1603e0c4386eSCy Schubert         || !test_kdfs_same(kdf1, kdf2))
1604e0c4386eSCy Schubert         ok = 0;
1605e0c4386eSCy Schubert     EVP_KDF_free(kdf1);
1606e0c4386eSCy Schubert     kdf1 = NULL;
1607e0c4386eSCy Schubert     EVP_KDF_free(kdf2);
1608e0c4386eSCy Schubert     kdf2 = NULL;
1609e0c4386eSCy Schubert 
1610e0c4386eSCy Schubert     return ok;
1611e0c4386eSCy Schubert }
1612e0c4386eSCy Schubert 
1613e0c4386eSCy Schubert #if !defined(OPENSSL_NO_CMS) && !defined(OPENSSL_NO_DES)
test_kdf_x942_asn1(void)1614e0c4386eSCy Schubert static int test_kdf_x942_asn1(void)
1615e0c4386eSCy Schubert {
1616e0c4386eSCy Schubert     int ret;
1617e0c4386eSCy Schubert     EVP_KDF_CTX *kctx = NULL;
1618e0c4386eSCy Schubert     OSSL_PARAM params[4], *p = params;
1619e0c4386eSCy Schubert     const char *cek_alg = SN_id_smime_alg_CMS3DESwrap;
1620e0c4386eSCy Schubert     unsigned char out[24];
1621e0c4386eSCy Schubert     /* RFC2631 Section 2.1.6 Test data */
1622e0c4386eSCy Schubert     static unsigned char z[] = {
1623e0c4386eSCy Schubert         0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,
1624e0c4386eSCy Schubert         0x0e,0x0f,0x10,0x11,0x12,0x13
1625e0c4386eSCy Schubert     };
1626e0c4386eSCy Schubert     static const unsigned char expected[sizeof(out)] = {
1627e0c4386eSCy Schubert         0xa0,0x96,0x61,0x39,0x23,0x76,0xf7,0x04,
1628e0c4386eSCy Schubert         0x4d,0x90,0x52,0xa3,0x97,0x88,0x32,0x46,
1629e0c4386eSCy Schubert         0xb6,0x7f,0x5f,0x1e,0xf6,0x3e,0xb5,0xfb
1630e0c4386eSCy Schubert     };
1631e0c4386eSCy Schubert 
1632e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
1633e0c4386eSCy Schubert                                             (char *)"sha1", 0);
1634e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, z,
1635e0c4386eSCy Schubert                                              sizeof(z));
1636e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
1637e0c4386eSCy Schubert                                             (char *)cek_alg, 0);
1638e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
1639e0c4386eSCy Schubert 
1640e0c4386eSCy Schubert     ret =
1641e0c4386eSCy Schubert         TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_X942KDF_ASN1))
1642e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0)
1643e0c4386eSCy Schubert         && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
1644e0c4386eSCy Schubert 
1645e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1646e0c4386eSCy Schubert     return ret;
1647e0c4386eSCy Schubert }
1648e0c4386eSCy Schubert #endif /* OPENSSL_NO_CMS */
1649e0c4386eSCy Schubert 
test_kdf_krb5kdf(void)1650e0c4386eSCy Schubert static int test_kdf_krb5kdf(void)
1651e0c4386eSCy Schubert {
1652e0c4386eSCy Schubert     int ret;
1653e0c4386eSCy Schubert     EVP_KDF_CTX *kctx;
1654e0c4386eSCy Schubert     OSSL_PARAM params[4], *p = params;
1655e0c4386eSCy Schubert     unsigned char out[16];
1656e0c4386eSCy Schubert     static unsigned char key[] = {
1657e0c4386eSCy Schubert         0x42, 0x26, 0x3C, 0x6E, 0x89, 0xF4, 0xFC, 0x28,
1658e0c4386eSCy Schubert         0xB8, 0xDF, 0x68, 0xEE, 0x09, 0x79, 0x9F, 0x15
1659e0c4386eSCy Schubert     };
1660e0c4386eSCy Schubert     static unsigned char constant[] = {
1661e0c4386eSCy Schubert         0x00, 0x00, 0x00, 0x02, 0x99
1662e0c4386eSCy Schubert     };
1663e0c4386eSCy Schubert     static const unsigned char expected[sizeof(out)] = {
1664e0c4386eSCy Schubert         0x34, 0x28, 0x0A, 0x38, 0x2B, 0xC9, 0x27, 0x69,
1665e0c4386eSCy Schubert         0xB2, 0xDA, 0x2F, 0x9E, 0xF0, 0x66, 0x85, 0x4B
1666e0c4386eSCy Schubert     };
1667e0c4386eSCy Schubert 
1668e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER,
1669e0c4386eSCy Schubert                                             (char *)"AES-128-CBC", 0);
1670e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, key,
1671e0c4386eSCy Schubert                                              sizeof(key));
1672e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_CONSTANT,
1673e0c4386eSCy Schubert                                              constant, sizeof(constant));
1674e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
1675e0c4386eSCy Schubert 
1676e0c4386eSCy Schubert     ret =
1677e0c4386eSCy Schubert         TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_KRB5KDF))
1678e0c4386eSCy Schubert         && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0)
1679e0c4386eSCy Schubert         && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected));
1680e0c4386eSCy Schubert 
1681e0c4386eSCy Schubert     EVP_KDF_CTX_free(kctx);
1682e0c4386eSCy Schubert     return ret;
1683e0c4386eSCy Schubert }
1684e0c4386eSCy Schubert 
setup_tests(void)1685e0c4386eSCy Schubert int setup_tests(void)
1686e0c4386eSCy Schubert {
1687e0c4386eSCy Schubert     ADD_TEST(test_kdf_pbkdf1);
1688e0c4386eSCy Schubert     ADD_TEST(test_kdf_pbkdf1_key_too_long);
1689e0c4386eSCy Schubert #if !defined(OPENSSL_NO_CMAC) && !defined(OPENSSL_NO_CAMELLIA)
1690e0c4386eSCy Schubert     ADD_TEST(test_kdf_kbkdf_6803_128);
1691e0c4386eSCy Schubert     ADD_TEST(test_kdf_kbkdf_6803_256);
1692e0c4386eSCy Schubert #endif
1693e0c4386eSCy Schubert     ADD_TEST(test_kdf_kbkdf_invalid_digest);
1694e0c4386eSCy Schubert     ADD_TEST(test_kdf_kbkdf_invalid_mac);
1695e0c4386eSCy Schubert     ADD_TEST(test_kdf_kbkdf_zero_output_size);
1696e0c4386eSCy Schubert     ADD_TEST(test_kdf_kbkdf_empty_key);
1697e0c4386eSCy Schubert     ADD_TEST(test_kdf_kbkdf_1byte_key);
1698e0c4386eSCy Schubert     ADD_TEST(test_kdf_kbkdf_8009_prf1);
1699e0c4386eSCy Schubert     ADD_TEST(test_kdf_kbkdf_8009_prf2);
1700e0c4386eSCy Schubert #if !defined(OPENSSL_NO_CMAC)
1701e0c4386eSCy Schubert     ADD_TEST(test_kdf_kbkdf_fixedinfo);
1702e0c4386eSCy Schubert #endif
1703e0c4386eSCy Schubert     ADD_TEST(test_kdf_get_kdf);
1704e0c4386eSCy Schubert     ADD_TEST(test_kdf_tls1_prf);
1705e0c4386eSCy Schubert     ADD_TEST(test_kdf_tls1_prf_invalid_digest);
1706e0c4386eSCy Schubert     ADD_TEST(test_kdf_tls1_prf_zero_output_size);
1707e0c4386eSCy Schubert     ADD_TEST(test_kdf_tls1_prf_empty_secret);
1708e0c4386eSCy Schubert     ADD_TEST(test_kdf_tls1_prf_1byte_secret);
1709e0c4386eSCy Schubert     ADD_TEST(test_kdf_tls1_prf_empty_seed);
1710e0c4386eSCy Schubert     ADD_TEST(test_kdf_tls1_prf_1byte_seed);
1711e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf);
1712e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_invalid_digest);
1713e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_zero_output_size);
1714e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_empty_key);
1715e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_1byte_key);
1716e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_empty_salt);
1717e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_gettables);
1718e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_gettables_expandonly);
1719e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_gettables_no_digest);
1720e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_derive_set_params_fail);
1721e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_set_invalid_mode);
1722e0c4386eSCy Schubert     ADD_TEST(test_kdf_hkdf_set_ctx_param_fail);
1723e0c4386eSCy Schubert     ADD_TEST(test_kdf_pbkdf2);
1724e0c4386eSCy Schubert     ADD_TEST(test_kdf_pbkdf2_small_output);
1725e0c4386eSCy Schubert     ADD_TEST(test_kdf_pbkdf2_large_output);
1726e0c4386eSCy Schubert     ADD_TEST(test_kdf_pbkdf2_small_salt);
1727e0c4386eSCy Schubert     ADD_TEST(test_kdf_pbkdf2_small_iterations);
1728e0c4386eSCy Schubert     ADD_TEST(test_kdf_pbkdf2_small_salt_pkcs5);
1729e0c4386eSCy Schubert     ADD_TEST(test_kdf_pbkdf2_small_iterations_pkcs5);
1730e0c4386eSCy Schubert     ADD_TEST(test_kdf_pbkdf2_invalid_digest);
1731e0c4386eSCy Schubert #ifndef OPENSSL_NO_SCRYPT
1732e0c4386eSCy Schubert     ADD_TEST(test_kdf_scrypt);
1733e0c4386eSCy Schubert #endif
1734e0c4386eSCy Schubert     ADD_TEST(test_kdf_ss_hash);
1735e0c4386eSCy Schubert     ADD_TEST(test_kdf_ss_hmac);
1736e0c4386eSCy Schubert     ADD_TEST(test_kdf_ss_kmac);
1737e0c4386eSCy Schubert     ADD_TEST(test_kdf_sshkdf);
1738e0c4386eSCy Schubert     ADD_TEST(test_kdf_x963);
1739e0c4386eSCy Schubert #if !defined(OPENSSL_NO_CMS) && !defined(OPENSSL_NO_DES)
1740e0c4386eSCy Schubert     ADD_TEST(test_kdf_x942_asn1);
1741e0c4386eSCy Schubert #endif
1742e0c4386eSCy Schubert     ADD_TEST(test_kdf_krb5kdf);
1743e0c4386eSCy Schubert     return 1;
1744e0c4386eSCy Schubert }
1745