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