[peerdist] Add support for decoding PeerDist Content Information
[ipxe.git] / src / tests / pccrc_test.c
1 /*
2 * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 /** @file
27 *
28 * Peer Content Caching and Retrieval: Content Identification [MS-PCCRC] tests
29 *
30 */
31
32 /* Forcibly enable assertions */
33 #undef NDEBUG
34
35 #include <stdint.h>
36 #include <string.h>
37 #include <assert.h>
38 #include <ipxe/uaccess.h>
39 #include <ipxe/pccrc.h>
40 #include <ipxe/sha256.h>
41 #include <ipxe/sha512.h>
42 #include <ipxe/hmac.h>
43 #include <ipxe/test.h>
44
45 /** Define inline raw data */
46 #define DATA(...) { __VA_ARGS__ }
47
48 /** A content information test */
49 struct peerdist_info_test {
50 /** Raw content information */
51 const void *data;
52 /** Length of raw content information */
53 size_t len;
54 /** Expected digest algorithm */
55 struct digest_algorithm *expected_digest;
56 /** Expected digest size */
57 size_t expected_digestsize;
58 /** Expected trimmed content range */
59 struct peerdist_range expected_trim;
60 /** Expected number of segments */
61 unsigned int expected_segments;
62 };
63
64 /**
65 * Define a content information test
66 *
67 * @v name Test name
68 * @v DATA Raw content information
69 * @v DIGEST Expected digest algorithm
70 * @v DIGESTSIZE Expected digest size
71 * @v START Expected trimmed content range start offset
72 * @v END Expected trimmed content range end offset
73 * @v SEGMENTS Expected number of segments
74 * @ret test Content information test
75 *
76 * Raw content information can be obtained from PeerDist-capable web
77 * servers using wget's "--header" option to inject the relevant
78 * PeerDist headers. For example:
79 *
80 * wget --header "Accept-Encoding: peerdist" \
81 * --header "X-P2P-PeerDist: Version=1.0" \
82 * http://peerdist.server.address/test.url -O - | xxd -i -c 11
83 *
84 * Version 1 content information can be retrieved using the headers:
85 *
86 * Accept-Encoding: peerdist
87 * X-P2P-PeerDist: Version=1.0
88 *
89 * Version 2 content information can be retrieved (from compatible
90 * servers) using the headers:
91 *
92 * Accept-Encoding: peerdist
93 * X-P2P-PeerDist: Version=1.1
94 * X-P2P-PeerDistEx: MinContentInformation=2.0, MaxContentInformation=2.0
95 */
96 #define PEERDIST_INFO_TEST( name, DATA, DIGEST, DIGESTSIZE, START, END, \
97 SEGMENTS ) \
98 static const uint8_t name ## _data[] = DATA; \
99 static struct peerdist_info_test name = { \
100 .data = name ## _data, \
101 .len = sizeof ( name ## _data ), \
102 .expected_digest = DIGEST, \
103 .expected_digestsize = DIGESTSIZE, \
104 .expected_trim = { \
105 .start = START, \
106 .end = END, \
107 }, \
108 .expected_segments = SEGMENTS, \
109 }
110
111 /** A content information segment test */
112 struct peerdist_info_segment_test {
113 /** Segment index */
114 unsigned int index;
115 /** Expected content range */
116 struct peerdist_range expected_range;
117 /** Expected number of blocks */
118 unsigned int expected_blocks;
119 /** Expected block size */
120 size_t expected_blksize;
121 /** Expected segment hash of data */
122 uint8_t expected_hash[PEERDIST_DIGEST_MAX_SIZE];
123 /** Expected segment secret */
124 uint8_t expected_secret[PEERDIST_DIGEST_MAX_SIZE];
125 /** Expected segment identifier */
126 uint8_t expected_id[PEERDIST_DIGEST_MAX_SIZE];
127 };
128
129 /**
130 * Define a content information segment test
131 *
132 * @v name Test name
133 * @v INDEX Segment index
134 * @v START Expected content range start offset
135 * @v END Expected content range end offset
136 * @v BLOCKS Expected number of blocks
137 * @v BLKSIZE Expected block size
138 * @v HASH Expected segment hash of data
139 * @v SECRET Expected segment secret
140 * @v ID Expected segment identifier
141 * @ret test Content information segment test
142 */
143 #define PEERDIST_INFO_SEGMENT_TEST( name, INDEX, START, END, BLOCKS, \
144 BLKSIZE, HASH, SECRET, ID ) \
145 static struct peerdist_info_segment_test name = { \
146 .index = INDEX, \
147 .expected_range = { \
148 .start = START, \
149 .end = END, \
150 }, \
151 .expected_blocks = BLOCKS, \
152 .expected_blksize = BLKSIZE, \
153 .expected_hash = HASH, \
154 .expected_secret = SECRET, \
155 .expected_id = ID, \
156 }
157
158 /** A content information block test */
159 struct peerdist_info_block_test {
160 /** Block index */
161 unsigned int index;
162 /** Expected content range */
163 struct peerdist_range expected_range;
164 /** Expected hash of data */
165 uint8_t expected_hash[PEERDIST_DIGEST_MAX_SIZE];
166 };
167
168 /**
169 * Define a content information block test
170 *
171 * @v name Test name
172 * @v INDEX Block index
173 * @v START Expected content range start offset
174 * @v END Expected content range end offset
175 * @v HASH Expected hash of data
176 * @ret test Content information block test
177 */
178 #define PEERDIST_INFO_BLOCK_TEST( name, INDEX, START, END, HASH ) \
179 static struct peerdist_info_block_test name = { \
180 .index = INDEX, \
181 .expected_range = { \
182 .start = START, \
183 .end = END, \
184 }, \
185 .expected_hash = HASH, \
186 }
187
188 /**
189 * Define a server passphrase
190 *
191 * @v name Server passphrase name
192 * @v DATA Raw server passphrase
193 *
194 * The server passphrase can be exported from a Windows BranchCache
195 * server using the command:
196 *
197 * netsh branchcache exportkey exported.key somepassword
198 *
199 * and this encrypted exported key can be decrypted using the
200 * oSSL_key_dx or mcrypt_key_dx utilities found in the (prototype)
201 * Prequel project at https://fedorahosted.org/prequel/ :
202 *
203 * oSSL_key_dx exported.key somepassword
204 * or
205 * mcrypt_key_dx exported.key somepassword
206 *
207 * Either command will display both the server passphrase and the
208 * "Server Secret". Note that this latter is the version 1 server
209 * secret (i.e. the SHA-256 of the server passphrase); the
210 * corresponding version 2 server secret can be obtained by
211 * calculating the truncated SHA-512 of the server passphrase.
212 *
213 * We do not know the server passphrase during normal operation. We
214 * use it in the self-tests only to check for typos and other errors
215 * in the test vectors, by checking that the segment secret defined in
216 * a content information segment test is as expected.
217 */
218 #define SERVER_PASSPHRASE( name, DATA ) \
219 static uint8_t name[] = DATA
220
221 /** Server passphrase used for these test vectors */
222 SERVER_PASSPHRASE ( passphrase,
223 DATA ( 0x2a, 0x3d, 0x73, 0xeb, 0x43, 0x5e, 0x9f, 0x2b, 0x8a, 0x34, 0x42,
224 0x67, 0xe7, 0x46, 0x7a, 0x3c, 0x73, 0x85, 0xc6, 0xe0, 0x55, 0xe2,
225 0xb4, 0xd3, 0x0d, 0xfe, 0xc7, 0xc3, 0x8b, 0x0e, 0xd7, 0x2c ) );
226
227 /** IIS logo (iis-85.png) content information version 1 */
228 PEERDIST_INFO_TEST ( iis_85_png_v1,
229 DATA ( 0x00, 0x01, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00, 0x7e, 0x85, 0x01, 0x00, 0x00, 0x00, 0x01,
232 0x00, 0xd8, 0xd9, 0x76, 0x35, 0x4a, 0x48, 0x72, 0xe9, 0x25, 0x76,
233 0x18, 0x03, 0xf4, 0x58, 0xd9, 0xda, 0xaa, 0x67, 0xf8, 0xe3, 0x1c,
234 0x63, 0x0f, 0xb7, 0x4e, 0x6a, 0x31, 0x2e, 0xf8, 0xa2, 0x5a, 0xba,
235 0x11, 0xaf, 0xc0, 0xd7, 0x94, 0x92, 0x43, 0xf9, 0x4f, 0x9c, 0x1f,
236 0xab, 0x35, 0xd9, 0xfd, 0x1e, 0x33, 0x1f, 0xcf, 0x78, 0x11, 0xa2,
237 0xe0, 0x1d, 0x35, 0x87, 0xb3, 0x8d, 0x77, 0x0a, 0x29, 0xe2, 0x02,
238 0x00, 0x00, 0x00, 0x73, 0xc1, 0x8a, 0xb8, 0x54, 0x91, 0x10, 0xf8,
239 0xe9, 0x0e, 0x71, 0xbb, 0xc3, 0xab, 0x2a, 0xa8, 0xc4, 0x4d, 0x13,
240 0xf4, 0x92, 0x94, 0x99, 0x25, 0x5b, 0x66, 0x0f, 0x24, 0xec, 0x77,
241 0x80, 0x0b, 0x97, 0x4b, 0xdd, 0x65, 0x56, 0x7f, 0xde, 0xec, 0xcd,
242 0xaf, 0xe4, 0x57, 0xa9, 0x50, 0x3b, 0x45, 0x48, 0xf6, 0x6e, 0xd3,
243 0xb1, 0x88, 0xdc, 0xfd, 0xa0, 0xac, 0x38, 0x2b, 0x09, 0x71, 0x1a,
244 0xcc ),
245 &sha256_algorithm, 32, 0, 99710, 1 );
246
247 /** IIS logo (iis-85.png) content information version 1 segment 0 */
248 PEERDIST_INFO_SEGMENT_TEST ( iis_85_png_v1_s0, 0,
249 0, 99710, 2, 65536,
250 DATA ( 0xd8, 0xd9, 0x76, 0x35, 0x4a, 0x48, 0x72, 0xe9, 0x25, 0x76, 0x18,
251 0x03, 0xf4, 0x58, 0xd9, 0xda, 0xaa, 0x67, 0xf8, 0xe3, 0x1c, 0x63,
252 0x0f, 0xb7, 0x4e, 0x6a, 0x31, 0x2e, 0xf8, 0xa2, 0x5a, 0xba ),
253 DATA ( 0x11, 0xaf, 0xc0, 0xd7, 0x94, 0x92, 0x43, 0xf9, 0x4f, 0x9c, 0x1f,
254 0xab, 0x35, 0xd9, 0xfd, 0x1e, 0x33, 0x1f, 0xcf, 0x78, 0x11, 0xa2,
255 0xe0, 0x1d, 0x35, 0x87, 0xb3, 0x8d, 0x77, 0x0a, 0x29, 0xe2 ),
256 DATA ( 0x49, 0x1b, 0x21, 0x7d, 0xbe, 0xe2, 0xb5, 0xf1, 0x2c, 0xa7, 0x9b,
257 0x01, 0x5e, 0x06, 0xf4, 0xbb, 0xe6, 0x4f, 0x97, 0x45, 0xba, 0xd7,
258 0x86, 0x7a, 0xef, 0x17, 0xde, 0x59, 0x92, 0x7e, 0xdc, 0xe9 ) );
259
260 /** IIS logo (iis-85.png) content information version 1 segment 0 block 0 */
261 PEERDIST_INFO_BLOCK_TEST ( iis_85_png_v1_s0_b0, 0,
262 0, 65536,
263 DATA ( 0x73, 0xc1, 0x8a, 0xb8, 0x54, 0x91, 0x10, 0xf8, 0xe9, 0x0e, 0x71,
264 0xbb, 0xc3, 0xab, 0x2a, 0xa8, 0xc4, 0x4d, 0x13, 0xf4, 0x92, 0x94,
265 0x99, 0x25, 0x5b, 0x66, 0x0f, 0x24, 0xec, 0x77, 0x80, 0x0b ) );
266
267 /** IIS logo (iis-85.png) content information version 1 segment 0 block 1 */
268 PEERDIST_INFO_BLOCK_TEST ( iis_85_png_v1_s0_b1, 1,
269 65536, 99710,
270 DATA ( 0x97, 0x4b, 0xdd, 0x65, 0x56, 0x7f, 0xde, 0xec, 0xcd, 0xaf, 0xe4,
271 0x57, 0xa9, 0x50, 0x3b, 0x45, 0x48, 0xf6, 0x6e, 0xd3, 0xb1, 0x88,
272 0xdc, 0xfd, 0xa0, 0xac, 0x38, 0x2b, 0x09, 0x71, 0x1a, 0xcc ) );
273
274 /** IIS logo (iis-85.png) content information version 2 */
275 PEERDIST_INFO_TEST ( iis_85_png_v2,
276 DATA ( 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x88, 0x00, 0x00, 0x99, 0xde, 0xe0, 0xd0, 0xc3, 0x58,
280 0xe2, 0x68, 0x4b, 0x62, 0x33, 0x0d, 0x32, 0xb5, 0xf1, 0x97, 0x87,
281 0x24, 0xa0, 0xd0, 0xa5, 0x2b, 0xdc, 0x5e, 0x78, 0x1f, 0xae, 0x71,
282 0xff, 0x57, 0xa8, 0xbe, 0x3d, 0xd4, 0x58, 0x03, 0x7e, 0xd4, 0x04,
283 0x11, 0x6b, 0xb6, 0x16, 0xd9, 0xb1, 0x41, 0x16, 0x08, 0x85, 0x20,
284 0xc4, 0x7c, 0xdc, 0x50, 0xab, 0xce, 0xa3, 0xfa, 0xe1, 0x88, 0xa9,
285 0x8e, 0xa2, 0x2d, 0xf3, 0xc0, 0x00, 0x00, 0xeb, 0xa0, 0x33, 0x81,
286 0xd0, 0xd0, 0xcb, 0x74, 0xf4, 0xb6, 0x13, 0xd8, 0x21, 0x0f, 0x37,
287 0xf0, 0x02, 0xa0, 0x6f, 0x39, 0x10, 0x58, 0x60, 0x96, 0xa1, 0x30,
288 0xd3, 0x43, 0x98, 0xc0, 0x8e, 0x66, 0xd7, 0xbc, 0xb8, 0xb6, 0xeb,
289 0x77, 0x83, 0xe4, 0xf8, 0x07, 0x64, 0x7b, 0x63, 0xf1, 0x46, 0xb5,
290 0x2f, 0x4a, 0xc8, 0x9c, 0xcc, 0x7a, 0xbf, 0x5f, 0xa1, 0x1a, 0xca,
291 0xfc, 0x2a, 0xcf, 0x50, 0x28, 0x58, 0x6c ),
292 &sha512_algorithm, 32, 0, 99710, 2 );
293
294 /** IIS logo (iis-85.png) content information version 2 segment 0 */
295 PEERDIST_INFO_SEGMENT_TEST ( iis_85_png_v2_s0, 0,
296 0, 39390, 1, 39390,
297 DATA ( 0xe0, 0xd0, 0xc3, 0x58, 0xe2, 0x68, 0x4b, 0x62, 0x33, 0x0d, 0x32,
298 0xb5, 0xf1, 0x97, 0x87, 0x24, 0xa0, 0xd0, 0xa5, 0x2b, 0xdc, 0x5e,
299 0x78, 0x1f, 0xae, 0x71, 0xff, 0x57, 0xa8, 0xbe, 0x3d, 0xd4 ),
300 DATA ( 0x58, 0x03, 0x7e, 0xd4, 0x04, 0x11, 0x6b, 0xb6, 0x16, 0xd9, 0xb1,
301 0x41, 0x16, 0x08, 0x85, 0x20, 0xc4, 0x7c, 0xdc, 0x50, 0xab, 0xce,
302 0xa3, 0xfa, 0xe1, 0x88, 0xa9, 0x8e, 0xa2, 0x2d, 0xf3, 0xc0 ),
303 DATA ( 0x33, 0x71, 0xbb, 0xea, 0xdd, 0xb6, 0x23, 0x53, 0xad, 0xce, 0xf9,
304 0x70, 0xa0, 0x6f, 0xdf, 0x65, 0x00, 0x1e, 0x04, 0x21, 0xf4, 0xc7,
305 0x10, 0x82, 0x76, 0xb0, 0xc3, 0x7a, 0x9f, 0x9e, 0xc1, 0x0f ) );
306
307 /** IIS logo (iis-85.png) content information version 2 segment 0 block 0 */
308 PEERDIST_INFO_BLOCK_TEST ( iis_85_png_v2_s0_b0, 0,
309 0, 39390,
310 DATA ( 0xe0, 0xd0, 0xc3, 0x58, 0xe2, 0x68, 0x4b, 0x62, 0x33, 0x0d, 0x32,
311 0xb5, 0xf1, 0x97, 0x87, 0x24, 0xa0, 0xd0, 0xa5, 0x2b, 0xdc, 0x5e,
312 0x78, 0x1f, 0xae, 0x71, 0xff, 0x57, 0xa8, 0xbe, 0x3d, 0xd4 ) );
313
314 /** IIS logo (iis-85.png) content information version 2 segment 1 */
315 PEERDIST_INFO_SEGMENT_TEST ( iis_85_png_v2_s1, 1,
316 39390, 99710, 1, 60320,
317 DATA ( 0x33, 0x81, 0xd0, 0xd0, 0xcb, 0x74, 0xf4, 0xb6, 0x13, 0xd8, 0x21,
318 0x0f, 0x37, 0xf0, 0x02, 0xa0, 0x6f, 0x39, 0x10, 0x58, 0x60, 0x96,
319 0xa1, 0x30, 0xd3, 0x43, 0x98, 0xc0, 0x8e, 0x66, 0xd7, 0xbc ),
320 DATA ( 0xb8, 0xb6, 0xeb, 0x77, 0x83, 0xe4, 0xf8, 0x07, 0x64, 0x7b, 0x63,
321 0xf1, 0x46, 0xb5, 0x2f, 0x4a, 0xc8, 0x9c, 0xcc, 0x7a, 0xbf, 0x5f,
322 0xa1, 0x1a, 0xca, 0xfc, 0x2a, 0xcf, 0x50, 0x28, 0x58, 0x6c ),
323 DATA ( 0xd7, 0xe9, 0x24, 0x42, 0x5e, 0x8f, 0x4f, 0x88, 0xf0, 0x1d, 0xc6,
324 0xa9, 0xbb, 0x1b, 0xc3, 0x7b, 0xe1, 0x13, 0xec, 0x79, 0x17, 0xc7,
325 0x45, 0xd4, 0x96, 0x5c, 0x2b, 0x55, 0xfa, 0x16, 0x3a, 0x6e ) );
326
327 /** IIS logo (iis-85.png) content information version 2 segment 1 block 0 */
328 PEERDIST_INFO_BLOCK_TEST ( iis_85_png_v2_s1_b0, 0,
329 39390, 99710,
330 DATA ( 0x33, 0x81, 0xd0, 0xd0, 0xcb, 0x74, 0xf4, 0xb6, 0x13, 0xd8, 0x21,
331 0x0f, 0x37, 0xf0, 0x02, 0xa0, 0x6f, 0x39, 0x10, 0x58, 0x60, 0x96,
332 0xa1, 0x30, 0xd3, 0x43, 0x98, 0xc0, 0x8e, 0x66, 0xd7, 0xbc ) );
333
334 /**
335 * Report content information test result
336 *
337 * @v test Content information test
338 * @v info Content information to fill in
339 * @v file Test code file
340 * @v line Test code line
341 */
342 static void peerdist_info_okx ( struct peerdist_info_test *test,
343 struct peerdist_info *info,
344 const char *file, unsigned int line ) {
345
346 /* Parse content information */
347 okx ( peerdist_info ( virt_to_user ( test->data ), test->len,
348 info ) == 0, file, line );
349
350 /* Verify content information */
351 okx ( info->raw.data == virt_to_user ( test->data ), file, line );
352 okx ( info->raw.len == test->len, file, line );
353 okx ( info->digest == test->expected_digest, file, line );
354 okx ( info->digestsize == test->expected_digestsize, file, line );
355 okx ( info->trim.start >= info->range.start, file, line );
356 okx ( info->trim.start == test->expected_trim.start, file, line );
357 okx ( info->trim.end <= info->range.end, file, line );
358 okx ( info->trim.end == test->expected_trim.end, file, line );
359 okx ( info->segments == test->expected_segments, file, line );
360 }
361 #define peerdist_info_ok( test, info ) \
362 peerdist_info_okx ( test, info, __FILE__, __LINE__ )
363
364 /**
365 * Report content information segment test result
366 *
367 * @v test Content information segment test
368 * @v info Content information
369 * @v segment Segment information to fill in
370 * @v file Test code file
371 * @v line Test code line
372 */
373 static void peerdist_info_segment_okx ( struct peerdist_info_segment_test *test,
374 const struct peerdist_info *info,
375 struct peerdist_info_segment *segment,
376 const char *file, unsigned int line ) {
377 size_t digestsize = info->digestsize;
378
379 /* Parse content information segment */
380 okx ( peerdist_info_segment ( info, segment, test->index ) == 0,
381 file, line );
382
383 /* Verify content information segment */
384 okx ( segment->info == info, file, line );
385 okx ( segment->index == test->index, file, line );
386 okx ( segment->range.start == test->expected_range.start, file, line );
387 okx ( segment->range.end == test->expected_range.end, file, line );
388 okx ( segment->blocks == test->expected_blocks, file, line );
389 okx ( segment->blksize == test->expected_blksize, file, line );
390 okx ( memcmp ( segment->hash, test->expected_hash,
391 digestsize ) == 0, file, line );
392 okx ( memcmp ( segment->secret, test->expected_secret,
393 digestsize ) == 0, file, line );
394 okx ( memcmp ( segment->id, test->expected_id,
395 digestsize ) == 0, file, line );
396 }
397 #define peerdist_info_segment_ok( test, info, segment ) \
398 peerdist_info_segment_okx ( test, info, segment, __FILE__, __LINE__ )
399
400 /**
401 * Report content information block test result
402 *
403 * @v test Content information block test
404 * @v segment Segment information
405 * @v block Block information to fill in
406 * @v file Test code file
407 * @v line Test code line
408 */
409 static void
410 peerdist_info_block_okx ( struct peerdist_info_block_test *test,
411 const struct peerdist_info_segment *segment,
412 struct peerdist_info_block *block,
413 const char *file, unsigned int line ) {
414 const struct peerdist_info *info = segment->info;
415 size_t digestsize = info->digestsize;
416
417 /* Parse content information block */
418 okx ( peerdist_info_block ( segment, block, test->index ) == 0,
419 file, line );
420
421 /* Verify content information block */
422 okx ( block->segment == segment, file, line );
423 okx ( block->index == test->index, file, line );
424 okx ( block->range.start == test->expected_range.start, file, line );
425 okx ( block->range.end == test->expected_range.end, file, line );
426 okx ( memcmp ( block->hash, test->expected_hash,
427 digestsize ) == 0, file, line );
428 }
429 #define peerdist_info_block_ok( test, segment, block ) \
430 peerdist_info_block_okx ( test, segment, block, __FILE__, __LINE__ )
431
432 /**
433 * Report server passphrase test result
434 *
435 * @v test Content information segment test
436 * @v info Content information
437 * @v pass Server passphrase
438 * @v pass_len Length of server passphrase
439 * @v file Test code file
440 * @v line Test code line
441 */
442 static void
443 peerdist_info_passphrase_okx ( struct peerdist_info_segment_test *test,
444 const struct peerdist_info *info,
445 uint8_t *pass, size_t pass_len,
446 const char *file, unsigned int line ) {
447 struct digest_algorithm *digest = info->digest;
448 uint8_t ctx[digest->ctxsize];
449 uint8_t secret[digest->digestsize];
450 uint8_t expected[digest->digestsize];
451 size_t digestsize = info->digestsize;
452 size_t secretsize = digestsize;
453
454 /* Calculate server secret */
455 digest_init ( digest, ctx );
456 digest_update ( digest, ctx, pass, pass_len );
457 digest_final ( digest, ctx, secret );
458
459 /* Calculate expected segment secret */
460 hmac_init ( digest, ctx, secret, &secretsize );
461 assert ( secretsize == digestsize );
462 hmac_update ( digest, ctx, test->expected_hash, digestsize );
463 hmac_final ( digest, ctx, secret, &secretsize, expected );
464 assert ( secretsize == digestsize );
465
466 /* Verify segment secret */
467 okx ( memcmp ( test->expected_secret, expected, digestsize ) == 0,
468 file, line );
469 }
470 #define peerdist_info_passphrase_ok( test, info, pass, pass_len ) \
471 peerdist_info_passphrase_okx ( test, info, pass, pass_len, \
472 __FILE__, __LINE__ )
473
474 /**
475 * Perform content information self-tests
476 *
477 */
478 static void peerdist_info_test_exec ( void ) {
479 struct peerdist_info info;
480 struct peerdist_info_segment segment;
481 struct peerdist_info_block block;
482
483 /* IIS logo (iis-85.png) content information version 1 */
484 peerdist_info_ok ( &iis_85_png_v1, &info );
485 peerdist_info_passphrase_ok ( &iis_85_png_v1_s0, &info,
486 passphrase, sizeof ( passphrase ) );
487 peerdist_info_segment_ok ( &iis_85_png_v1_s0, &info, &segment );
488 peerdist_info_block_ok ( &iis_85_png_v1_s0_b0, &segment, &block );
489 peerdist_info_block_ok ( &iis_85_png_v1_s0_b1, &segment, &block );
490
491 /* IIS logo (iis-85.png) content information version 2 */
492 peerdist_info_ok ( &iis_85_png_v2, &info );
493 peerdist_info_passphrase_ok ( &iis_85_png_v2_s0, &info,
494 passphrase, sizeof ( passphrase ) );
495 peerdist_info_segment_ok ( &iis_85_png_v2_s0, &info, &segment );
496 peerdist_info_block_ok ( &iis_85_png_v2_s0_b0, &segment, &block );
497 peerdist_info_passphrase_ok ( &iis_85_png_v2_s1, &info,
498 passphrase, sizeof ( passphrase ) );
499 peerdist_info_segment_ok ( &iis_85_png_v2_s1, &info, &segment );
500 peerdist_info_block_ok ( &iis_85_png_v2_s1_b0, &segment, &block );
501 }
502
503 /** Content information self-test */
504 struct self_test peerdist_info_test __self_test = {
505 .name = "pccrc",
506 .exec = peerdist_info_test_exec,
507 };