1/*
2 * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10/* Tests of the EVP_PKEY_CTX_set_* macro family */
11
12#include <stdio.h>
13#include <string.h>
14
15#include <openssl/evp.h>
16#include <openssl/kdf.h>
17#include "testutil.h"
18
19static int test_kdf_tls1_prf(void)
20{
21    int ret = 0;
22    EVP_PKEY_CTX *pctx;
23    unsigned char out[16];
24    size_t outlen = sizeof(out);
25
26    if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL)) == NULL) {
27        TEST_error("EVP_PKEY_TLS1_PRF");
28        goto err;
29    }
30    if (EVP_PKEY_derive_init(pctx) <= 0) {
31        TEST_error("EVP_PKEY_derive_init");
32        goto err;
33    }
34    if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha256()) <= 0) {
35        TEST_error("EVP_PKEY_CTX_set_tls1_prf_md");
36        goto err;
37    }
38    if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx,
39                                          (unsigned char *)"secret", 6) <= 0) {
40        TEST_error("EVP_PKEY_CTX_set1_tls1_prf_secret");
41        goto err;
42    }
43    if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx,
44                                        (unsigned char *)"seed", 4) <= 0) {
45        TEST_error("EVP_PKEY_CTX_add1_tls1_prf_seed");
46        goto err;
47    }
48    if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) {
49        TEST_error("EVP_PKEY_derive");
50        goto err;
51    }
52
53    {
54        const unsigned char expected[sizeof(out)] = {
55            0x8e, 0x4d, 0x93, 0x25, 0x30, 0xd7, 0x65, 0xa0,
56            0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc
57        };
58        if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) {
59            goto err;
60        }
61    }
62    ret = 1;
63err:
64    EVP_PKEY_CTX_free(pctx);
65    return ret;
66}
67
68static int test_kdf_hkdf(void)
69{
70    int ret = 0;
71    EVP_PKEY_CTX *pctx;
72    unsigned char out[10];
73    size_t outlen = sizeof(out);
74
75    if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)) == NULL) {
76        TEST_error("EVP_PKEY_HKDF");
77        goto err;
78    }
79    if (EVP_PKEY_derive_init(pctx) <= 0) {
80        TEST_error("EVP_PKEY_derive_init");
81        goto err;
82    }
83    if (EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0) {
84        TEST_error("EVP_PKEY_CTX_set_hkdf_md");
85        goto err;
86    }
87    if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, (const unsigned char *)"salt", 4)
88            <= 0) {
89        TEST_error("EVP_PKEY_CTX_set1_hkdf_salt");
90        goto err;
91    }
92    if (EVP_PKEY_CTX_set1_hkdf_key(pctx, (const unsigned char *)"secret", 6)
93            <= 0) {
94        TEST_error("EVP_PKEY_CTX_set1_hkdf_key");
95        goto err;
96    }
97    if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (const unsigned char *)"label", 5)
98            <= 0) {
99        TEST_error("EVP_PKEY_CTX_set1_hkdf_info");
100        goto err;
101    }
102    if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) {
103        TEST_error("EVP_PKEY_derive");
104        goto err;
105    }
106
107    {
108        const unsigned char expected[sizeof(out)] = {
109            0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8, 0xde, 0x13
110        };
111        if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) {
112            goto err;
113        }
114    }
115    ret = 1;
116err:
117    EVP_PKEY_CTX_free(pctx);
118    return ret;
119}
120
121#ifndef OPENSSL_NO_SCRYPT
122static int test_kdf_scrypt(void)
123{
124    int ret = 0;
125    EVP_PKEY_CTX *pctx;
126    unsigned char out[64];
127    size_t outlen = sizeof(out);
128
129    if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, NULL)) == NULL) {
130        TEST_error("EVP_PKEY_SCRYPT");
131        goto err;
132    }
133    if (EVP_PKEY_derive_init(pctx) <= 0) {
134        TEST_error("EVP_PKEY_derive_init");
135        goto err;
136    }
137    if (EVP_PKEY_CTX_set1_pbe_pass(pctx, "password", 8) <= 0) {
138        TEST_error("EVP_PKEY_CTX_set1_pbe_pass");
139        goto err;
140    }
141    if (EVP_PKEY_CTX_set1_scrypt_salt(pctx, (unsigned char *)"NaCl", 4) <= 0) {
142        TEST_error("EVP_PKEY_CTX_set1_scrypt_salt");
143        goto err;
144    }
145    if (EVP_PKEY_CTX_set_scrypt_N(pctx, 1024) <= 0) {
146        TEST_error("EVP_PKEY_CTX_set_scrypt_N");
147        goto err;
148    }
149    if (EVP_PKEY_CTX_set_scrypt_r(pctx, 8) <= 0) {
150        TEST_error("EVP_PKEY_CTX_set_scrypt_r");
151        goto err;
152    }
153    if (EVP_PKEY_CTX_set_scrypt_p(pctx, 16) <= 0) {
154        TEST_error("EVP_PKEY_CTX_set_scrypt_p");
155        goto err;
156    }
157    if (EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, 16) <= 0) {
158        TEST_error("EVP_PKEY_CTX_set_maxmem_bytes");
159        goto err;
160    }
161    if (EVP_PKEY_derive(pctx, out, &outlen) > 0) {
162        TEST_error("EVP_PKEY_derive should have failed");
163        goto err;
164    }
165    if (EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, 10 * 1024 * 1024) <= 0) {
166        TEST_error("EVP_PKEY_CTX_set_maxmem_bytes");
167        goto err;
168    }
169    if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) {
170        TEST_error("EVP_PKEY_derive");
171        goto err;
172    }
173
174    {
175        const unsigned char expected[sizeof(out)] = {
176            0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00,
177            0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe,
178            0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30,
179            0xe7, 0x73, 0x76, 0x63, 0x4b, 0x37, 0x31, 0x62,
180            0x2e, 0xaf, 0x30, 0xd9, 0x2e, 0x22, 0xa3, 0x88,
181            0x6f, 0xf1, 0x09, 0x27, 0x9d, 0x98, 0x30, 0xda,
182            0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, 0xee, 0x6d,
183            0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40
184        };
185        if (!TEST_mem_eq(out, sizeof(out), expected, sizeof(expected))) {
186            goto err;
187        }
188    }
189    ret = 1;
190err:
191    EVP_PKEY_CTX_free(pctx);
192    return ret;
193}
194#endif
195
196int setup_tests(void)
197{
198    ADD_TEST(test_kdf_tls1_prf);
199    ADD_TEST(test_kdf_hkdf);
200#ifndef OPENSSL_NO_SCRYPT
201    ADD_TEST(test_kdf_scrypt);
202#endif
203    return 1;
204}
205