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