xref: /aosp_15_r20/external/boringssl/src/crypto/fipsmodule/hkdf/hkdf_test.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
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