• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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