1 /* Copyright 2014 The BoringSSL Authors
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <openssl/digest.h>
16 #include <openssl/err.h>
17 #include <openssl/evp.h>
18 #include <openssl/hkdf.h>
19 #include <openssl/kdf.h>
20
21 #include <gtest/gtest.h>
22
23 #include "../../test/file_test.h"
24 #include "../../test/test_util.h"
25 #include "../../test/wycheproof_util.h"
26
27
28 namespace {
29
30 struct HKDFTestVector {
31 const EVP_MD *(*md_func)(void);
32 const uint8_t ikm[80];
33 const size_t ikm_len;
34 const uint8_t salt[80];
35 const size_t salt_len;
36 const uint8_t info[80];
37 const size_t info_len;
38 const uint8_t prk[EVP_MAX_MD_SIZE];
39 const size_t prk_len;
40 const size_t out_len;
41 const uint8_t out[82];
42 };
43
44 // These test vectors are from RFC 5869.
45 static const HKDFTestVector kTests[] = {
46 // clang-format off
47 {
48 EVP_sha256,
49 {
50 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
51 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
52 }, 22,
53 {
54 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
55 0x0c,
56 }, 13,
57 {
58 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
59 }, 10,
60 {
61 0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f, 0x0d,
62 0xc4, 0x7b, 0xba, 0x63, 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
63 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5,
64 }, 32,
65 42, {
66 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64,
67 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
68 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08,
69 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65
70 }
71 },
72 {
73 EVP_sha256,
74 {
75 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
76 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
77 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
78 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
79 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
80 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
81 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
82 }, 80,
83 {
84 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
85 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
86 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
87 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
88 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
89 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
90 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf
91 }, 80,
92 {
93 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
94 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
95 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
96 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
97 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
98 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
99 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
100 }, 80,
101 {
102 0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a, 0x06, 0x10, 0x4c, 0x9c,
103 0xeb, 0x35, 0xb4, 0x5c, 0xef, 0x76, 0x00, 0x14, 0x90, 0x46, 0x71, 0x01,
104 0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44,
105 }, 32,
106 82, {
107 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c,
108 0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
109 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c, 0x59, 0x04, 0x5a, 0x99,
110 0xca, 0xc7, 0x82, 0x72, 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
111 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, 0x36, 0x77, 0x93, 0xa9,
112 0xac, 0xa3, 0xdb, 0x71, 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
113 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f, 0x1d, 0x87
114 }
115 },
116 {
117 EVP_sha256,
118 {
119 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
120 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
121 }, 22,
122 {
123 0,
124 }, 0,
125 {
126 0,
127 }, 0,
128 {
129 0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16, 0x7f, 0x33, 0xa9, 0x1d,
130 0x6f, 0x64, 0x8b, 0xdf, 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77,
131 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04
132 }, 32,
133 42, {
134 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, 0x2a,
135 0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
136 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d, 0x20, 0x13, 0x95,
137 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8
138 }
139 },
140 {
141 EVP_sha1,
142 {
143 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
144 }, 11,
145 {
146 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
147 0x0c,
148 }, 13,
149 {
150 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
151 }, 10,
152 {
153 0x9b, 0x6c, 0x18, 0xc4, 0x32, 0xa7, 0xbf, 0x8f, 0x0e, 0x71, 0xc8, 0xeb,
154 0x88, 0xf4, 0xb3, 0x0b, 0xaa, 0x2b, 0xa2, 0x43
155 }, 20,
156 42, {
157 0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69, 0x33, 0x06, 0x8b, 0x56,
158 0xef, 0xa5, 0xad, 0x81, 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15,
159 0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2, 0xc2, 0x2e, 0x42, 0x24,
160 0x78, 0xd3, 0x05, 0xf3, 0xf8, 0x96
161 }
162 },
163 {
164 EVP_sha1,
165 {
166 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
167 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
168 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
169 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
170 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
171 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
172 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
173 }, 80,
174 {
175 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
176 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
177 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
178 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
179 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
180 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
181 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf
182 }, 80,
183 {
184 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb,
185 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
186 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
187 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
188 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
189 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
190 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
191 }, 80,
192 {
193 0x8a, 0xda, 0xe0, 0x9a, 0x2a, 0x30, 0x70, 0x59, 0x47, 0x8d, 0x30, 0x9b,
194 0x26, 0xc4, 0x11, 0x5a, 0x22, 0x4c, 0xfa, 0xf6,
195 }, 20,
196 82, {
197 0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7, 0xc9, 0xf1, 0x2c, 0xd5,
198 0x91, 0x2a, 0x06, 0xeb, 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19,
199 0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe, 0x8f, 0xa3, 0xf1, 0xa4,
200 0xe5, 0xad, 0x79, 0xf3, 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c,
201 0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed, 0x03, 0x4c, 0x7f, 0x9d,
202 0xfe, 0xb1, 0x5c, 0x5e, 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43,
203 0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52, 0xd3, 0xb4
204 }
205 },
206 {
207 EVP_sha1,
208 {
209 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
210 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
211 }, 22,
212 {
213 0,
214 }, 0,
215 {
216 0,
217 }, 0,
218 {
219 0xda, 0x8c, 0x8a, 0x73, 0xc7, 0xfa, 0x77, 0x28, 0x8e, 0xc6, 0xf5, 0xe7,
220 0xc2, 0x97, 0x78, 0x6a, 0xa0, 0xd3, 0x2d, 0x01,
221 }, 20,
222 42, {
223 0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61, 0xd1, 0xe5, 0x52, 0x98,
224 0xda, 0x9d, 0x05, 0x06, 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06,
225 0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0, 0xea, 0x00, 0x03, 0x3d,
226 0xe0, 0x39, 0x84, 0xd3, 0x49, 0x18
227 }
228 },
229 {
230 EVP_sha1,
231 {
232 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
233 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
234 }, 22,
235 {
236 0,
237 }, 0,
238 {
239 0,
240 }, 0,
241 {
242 0x2a, 0xdc, 0xca, 0xda, 0x18, 0x77, 0x9e, 0x7c, 0x20, 0x77, 0xad, 0x2e,
243 0xb1, 0x9d, 0x3f, 0x3e, 0x73, 0x13, 0x85, 0xdd,
244 }, 20,
245 42, {
246 0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3, 0x50, 0x0d, 0x63, 0x6a,
247 0x62, 0xf6, 0x4f, 0x0a, 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23,
248 0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5, 0x67, 0x3a, 0x08, 0x1d,
249 0x70, 0xcc, 0xe7, 0xac, 0xfc, 0x48
250 }
251 },
252 // clang-format on
253 };
254
TEST(HKDFTest,TestVectors)255 TEST(HKDFTest, TestVectors) {
256 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) {
257 SCOPED_TRACE(i);
258 const HKDFTestVector *test = &kTests[i];
259
260 uint8_t prk[EVP_MAX_MD_SIZE];
261 size_t prk_len;
262 ASSERT_TRUE(HKDF_extract(prk, &prk_len, test->md_func(), test->ikm,
263 test->ikm_len, test->salt, test->salt_len));
264 EXPECT_EQ(Bytes(test->prk, test->prk_len), Bytes(prk, prk_len));
265
266 uint8_t buf[82];
267 ASSERT_TRUE(HKDF_expand(buf, test->out_len, test->md_func(), prk, prk_len,
268 test->info, test->info_len));
269 EXPECT_EQ(Bytes(test->out, test->out_len), Bytes(buf, test->out_len));
270
271 ASSERT_TRUE(HKDF(buf, test->out_len, test->md_func(), test->ikm,
272 test->ikm_len, test->salt, test->salt_len, test->info,
273 test->info_len));
274 EXPECT_EQ(Bytes(test->out, test->out_len), Bytes(buf, test->out_len));
275
276 // Repeat the test with the OpenSSL compatibility |EVP_PKEY_derive| API.
277 bssl::UniquePtr<EVP_PKEY_CTX> ctx(
278 EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr));
279 ASSERT_TRUE(ctx);
280 ASSERT_TRUE(EVP_PKEY_derive_init(ctx.get()));
281 ASSERT_TRUE(
282 EVP_PKEY_CTX_hkdf_mode(ctx.get(), EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY));
283 ASSERT_TRUE(EVP_PKEY_CTX_set_hkdf_md(ctx.get(), test->md_func()));
284 ASSERT_TRUE(
285 EVP_PKEY_CTX_set1_hkdf_key(ctx.get(), test->ikm, test->ikm_len));
286 ASSERT_TRUE(
287 EVP_PKEY_CTX_set1_hkdf_salt(ctx.get(), test->salt, test->salt_len));
288 for (bool copy_ctx : {false, true}) {
289 SCOPED_TRACE(copy_ctx);
290 bssl::UniquePtr<EVP_PKEY_CTX> copy;
291 EVP_PKEY_CTX *use_ctx = ctx.get();
292 if (copy_ctx) {
293 copy.reset(EVP_PKEY_CTX_dup(ctx.get()));
294 ASSERT_TRUE(copy);
295 use_ctx = copy.get();
296 }
297
298 // A null output should report the length.
299 prk_len = 0;
300 ASSERT_TRUE(EVP_PKEY_derive(use_ctx, nullptr, &prk_len));
301 EXPECT_EQ(prk_len, test->prk_len);
302
303 // Too small of a buffer should cleanly fail.
304 prk_len = test->prk_len - 1;
305 EXPECT_FALSE(EVP_PKEY_derive(use_ctx, prk, &prk_len));
306 ERR_clear_error();
307
308 // Test the correct buffer size.
309 OPENSSL_memset(prk, 0, sizeof(prk));
310 prk_len = test->prk_len;
311 ASSERT_TRUE(EVP_PKEY_derive(use_ctx, prk, &prk_len));
312 EXPECT_EQ(Bytes(test->prk, test->prk_len), Bytes(prk, prk_len));
313
314 // Test a larger buffer than necessary.
315 OPENSSL_memset(prk, 0, sizeof(prk));
316 prk_len = test->prk_len + 1;
317 ASSERT_TRUE(EVP_PKEY_derive(use_ctx, prk, &prk_len));
318 EXPECT_EQ(Bytes(test->prk, test->prk_len), Bytes(prk, prk_len));
319 }
320
321 ctx.reset(EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr));
322 ASSERT_TRUE(ctx);
323 ASSERT_TRUE(EVP_PKEY_derive_init(ctx.get()));
324 ASSERT_TRUE(
325 EVP_PKEY_CTX_hkdf_mode(ctx.get(), EVP_PKEY_HKDEF_MODE_EXPAND_ONLY));
326 ASSERT_TRUE(EVP_PKEY_CTX_set_hkdf_md(ctx.get(), test->md_func()));
327 ASSERT_TRUE(
328 EVP_PKEY_CTX_set1_hkdf_key(ctx.get(), test->prk, test->prk_len));
329 // |info| can be passed in multiple parts.
330 size_t half = test->info_len / 2;
331 ASSERT_TRUE(EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), test->info, half));
332 ASSERT_TRUE(EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), test->info + half,
333 test->info_len - half));
334 for (bool copy_ctx : {false, true}) {
335 SCOPED_TRACE(copy_ctx);
336 bssl::UniquePtr<EVP_PKEY_CTX> copy;
337 EVP_PKEY_CTX *use_ctx = ctx.get();
338 if (copy_ctx) {
339 copy.reset(EVP_PKEY_CTX_dup(ctx.get()));
340 ASSERT_TRUE(copy);
341 use_ctx = copy.get();
342 }
343 OPENSSL_memset(buf, 0, sizeof(buf));
344 size_t len = test->out_len;
345 ASSERT_TRUE(EVP_PKEY_derive(use_ctx, buf, &len));
346 EXPECT_EQ(Bytes(test->out, test->out_len), Bytes(buf, len));
347 }
348
349 ctx.reset(EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr));
350 ASSERT_TRUE(ctx);
351 ASSERT_TRUE(EVP_PKEY_derive_init(ctx.get()));
352 ASSERT_TRUE(EVP_PKEY_CTX_hkdf_mode(ctx.get(),
353 EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND));
354 ASSERT_TRUE(EVP_PKEY_CTX_set_hkdf_md(ctx.get(), test->md_func()));
355 ASSERT_TRUE(
356 EVP_PKEY_CTX_set1_hkdf_key(ctx.get(), test->ikm, test->ikm_len));
357 ASSERT_TRUE(
358 EVP_PKEY_CTX_set1_hkdf_salt(ctx.get(), test->salt, test->salt_len));
359 // |info| can be passed in multiple parts.
360 ASSERT_TRUE(EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), test->info, half));
361 ASSERT_TRUE(EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), test->info + half,
362 test->info_len - half));
363 for (bool copy_ctx : {false, true}) {
364 SCOPED_TRACE(copy_ctx);
365 bssl::UniquePtr<EVP_PKEY_CTX> copy;
366 EVP_PKEY_CTX *use_ctx = ctx.get();
367 if (copy_ctx) {
368 copy.reset(EVP_PKEY_CTX_dup(ctx.get()));
369 ASSERT_TRUE(copy);
370 use_ctx = copy.get();
371 }
372 OPENSSL_memset(buf, 0, sizeof(buf));
373 size_t len = test->out_len;
374 ASSERT_TRUE(EVP_PKEY_derive(use_ctx, buf, &len));
375 EXPECT_EQ(Bytes(test->out, test->out_len), Bytes(buf, len));
376 }
377 }
378 }
379
RunWycheproofTest(const char * path,const EVP_MD * md)380 static void RunWycheproofTest(const char *path, const EVP_MD *md) {
381 SCOPED_TRACE(path);
382 FileTestGTest(path, [&](FileTest *t) {
383 t->IgnoreInstruction("keySize");
384 std::vector<uint8_t> ikm, info, okm, salt;
385 ASSERT_TRUE(t->GetBytes(&ikm, "ikm"));
386 ASSERT_TRUE(t->GetBytes(&info, "info"));
387 ASSERT_TRUE(t->GetBytes(&okm, "okm"));
388 ASSERT_TRUE(t->GetBytes(&salt, "salt"));
389 WycheproofResult result;
390 ASSERT_TRUE(GetWycheproofResult(t, &result));
391 std::string size_str;
392 ASSERT_TRUE(t->GetAttribute(&size_str, "size"));
393
394 std::vector<uint8_t> out(atoi(size_str.c_str()));
395 bool ret = HKDF(out.data(), out.size(), md, ikm.data(), ikm.size(),
396 salt.data(), salt.size(), info.data(), info.size());
397 EXPECT_EQ(result.IsValid(), ret);
398 if (result.IsValid()) {
399 EXPECT_EQ(Bytes(okm), Bytes(out));
400 }
401 });
402 }
403
TEST(HKDFTest,WycheproofSHA1)404 TEST(HKDFTest, WycheproofSHA1) {
405 RunWycheproofTest("third_party/wycheproof_testvectors/hkdf_sha1_test.txt",
406 EVP_sha1());
407 }
408
TEST(HKDFTest,WycheproofSHA256)409 TEST(HKDFTest, WycheproofSHA256) {
410 RunWycheproofTest("third_party/wycheproof_testvectors/hkdf_sha256_test.txt",
411 EVP_sha256());
412 }
413
TEST(HKDFTest,WycheproofSHA384)414 TEST(HKDFTest, WycheproofSHA384) {
415 RunWycheproofTest("third_party/wycheproof_testvectors/hkdf_sha384_test.txt",
416 EVP_sha384());
417 }
418
TEST(HKDFTest,WycheproofSHA512)419 TEST(HKDFTest, WycheproofSHA512) {
420 RunWycheproofTest("third_party/wycheproof_testvectors/hkdf_sha512_test.txt",
421 EVP_sha512());
422 }
423
424 } // namespace
425