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