iPXE
pccrc_test.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  * You can also choose to distribute this program under the terms of
00020  * the Unmodified Binary Distribution Licence (as given in the file
00021  * COPYING.UBDL), provided that you have satisfied its requirements.
00022  */
00023 
00024 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00025 
00026 /** @file
00027  *
00028  * Peer Content Caching and Retrieval: Content Identification [MS-PCCRC] tests
00029  *
00030  */
00031 
00032 /* Forcibly enable assertions */
00033 #undef NDEBUG
00034 
00035 #include <stdint.h>
00036 #include <string.h>
00037 #include <assert.h>
00038 #include <ipxe/uaccess.h>
00039 #include <ipxe/pccrc.h>
00040 #include <ipxe/sha256.h>
00041 #include <ipxe/sha512.h>
00042 #include <ipxe/hmac.h>
00043 #include <ipxe/test.h>
00044 
00045 /** Define inline raw data */
00046 #define DATA(...) { __VA_ARGS__ }
00047 
00048 /**
00049  * Define an inline content range
00050  *
00051  * @v START             Start offset
00052  * @v END               End offset
00053  * @ret range           Content range
00054  */
00055 #define RANGE( START, END ) { .start = START, .end = END }
00056 
00057 /**
00058  * Define an inline trimmed content range
00059  *
00060  * @v START             Start offset
00061  * @v END               End offset
00062  * @ret trim            Trimmed content range
00063  */
00064 #define TRIM( START, END ) { .start = START, .end = END }
00065 
00066 /** A content information test */
00067 struct peerdist_info_test {
00068         /** Raw content information */
00069         const void *data;
00070         /** Length of raw content information */
00071         size_t len;
00072         /** Expected digest algorithm */
00073         struct digest_algorithm *expected_digest;
00074         /** Expected digest size */
00075         size_t expected_digestsize;
00076         /** Expected content range */
00077         struct peerdist_range expected_range;
00078         /** Expected trimmed content range */
00079         struct peerdist_range expected_trim;
00080         /** Expected number of segments */
00081         unsigned int expected_segments;
00082 };
00083 
00084 /**
00085  * Define a content information test
00086  *
00087  * @v name              Test name
00088  * @v DATA              Raw content information
00089  * @v DIGEST            Expected digest algorithm
00090  * @v DIGESTSIZE        Expected digest size
00091  * @v RANGE             Expected content range
00092  * @v TRIM              Expected trimmer content range
00093  * @v SEGMENTS          Expected number of segments
00094  * @ret test            Content information test
00095  *
00096  * Raw content information can be obtained from PeerDist-capable web
00097  * servers using wget's "--header" option to inject the relevant
00098  * PeerDist headers.  For example:
00099  *
00100  *   wget --header "Accept-Encoding: peerdist" \
00101  *        --header "X-P2P-PeerDist: Version=1.0" \
00102  *        http://peerdist.server.address/test.url -O - | xxd -i -c 11
00103  *
00104  * Version 1 content information can be retrieved using the headers:
00105  *
00106  *   Accept-Encoding: peerdist
00107  *   X-P2P-PeerDist: Version=1.0
00108  *
00109  * Version 2 content information can be retrieved (from compatible
00110  * servers) using the headers:
00111  *
00112  *   Accept-Encoding: peerdist
00113  *   X-P2P-PeerDist: Version=1.1
00114  *   X-P2P-PeerDistEx: MinContentInformation=2.0, MaxContentInformation=2.0
00115  */
00116 #define PEERDIST_INFO_TEST( name, DATA, DIGEST, DIGESTSIZE, RANGE,      \
00117                             TRIM, SEGMENTS )                            \
00118         static const uint8_t name ## _data[] = DATA;                    \
00119         static struct peerdist_info_test name = {                       \
00120                 .data = name ## _data,                                  \
00121                 .len = sizeof ( name ## _data ),                        \
00122                 .expected_digest = DIGEST,                              \
00123                 .expected_digestsize = DIGESTSIZE,                      \
00124                 .expected_range = RANGE,                                \
00125                 .expected_trim = TRIM,                                  \
00126                 .expected_segments = SEGMENTS,                          \
00127         }
00128 
00129 /** A content information segment test */
00130 struct peerdist_info_segment_test {
00131         /** Segment index */
00132         unsigned int index;
00133         /** Expected content range */
00134         struct peerdist_range expected_range;
00135         /** Expected number of blocks */
00136         unsigned int expected_blocks;
00137         /** Expected block size */
00138         size_t expected_blksize;
00139         /** Expected segment hash of data */
00140         uint8_t expected_hash[PEERDIST_DIGEST_MAX_SIZE];
00141         /** Expected segment secret */
00142         uint8_t expected_secret[PEERDIST_DIGEST_MAX_SIZE];
00143         /** Expected segment identifier */
00144         uint8_t expected_id[PEERDIST_DIGEST_MAX_SIZE];
00145 };
00146 
00147 /**
00148  * Define a content information segment test
00149  *
00150  * @v name              Test name
00151  * @v INDEX             Segment index
00152  * @v RANGE             Expected content range
00153  * @v BLOCKS            Expected number of blocks
00154  * @v BLKSIZE           Expected block size
00155  * @v HASH              Expected segment hash of data
00156  * @v SECRET            Expected segment secret
00157  * @v ID                Expected segment identifier
00158  * @ret test            Content information segment test
00159  */
00160 #define PEERDIST_INFO_SEGMENT_TEST( name, INDEX, RANGE, BLOCKS,         \
00161                                     BLKSIZE, HASH, SECRET, ID )         \
00162         static struct peerdist_info_segment_test name = {               \
00163                 .index = INDEX,                                         \
00164                 .expected_range = RANGE,                                \
00165                 .expected_blocks = BLOCKS,                              \
00166                 .expected_blksize = BLKSIZE,                            \
00167                 .expected_hash = HASH,                                  \
00168                 .expected_secret = SECRET,                              \
00169                 .expected_id = ID,                                      \
00170         }
00171 
00172 /** A content information block test */
00173 struct peerdist_info_block_test {
00174         /** Block index */
00175         unsigned int index;
00176         /** Expected content range */
00177         struct peerdist_range expected_range;
00178         /** Expected trimmed content range */
00179         struct peerdist_range expected_trim;
00180         /** Expected hash of data */
00181         uint8_t expected_hash[PEERDIST_DIGEST_MAX_SIZE];
00182 };
00183 
00184 /**
00185  * Define a content information block test
00186  *
00187  * @v name              Test name
00188  * @v INDEX             Block index
00189  * @v RANGE             Expected content range
00190  * @v TRIM              Expected trimmed content range
00191  * @v HASH              Expected hash of data
00192  * @ret test            Content information block test
00193  */
00194 #define PEERDIST_INFO_BLOCK_TEST( name, INDEX, RANGE, TRIM, HASH )      \
00195         static struct peerdist_info_block_test name = {                 \
00196                 .index = INDEX,                                         \
00197                 .expected_range = RANGE,                                \
00198                 .expected_trim = TRIM,                                  \
00199                 .expected_hash = HASH,                                  \
00200         }
00201 
00202 /**
00203  * Define a server passphrase
00204  *
00205  * @v name              Server passphrase name
00206  * @v DATA              Raw server passphrase
00207  *
00208  * The server passphrase can be exported from a Windows BranchCache
00209  * server using the command:
00210  *
00211  *   netsh branchcache exportkey exported.key somepassword
00212  *
00213  * and this encrypted exported key can be decrypted using the
00214  * oSSL_key_dx or mcrypt_key_dx utilities found in the (prototype)
00215  * Prequel project at https://fedorahosted.org/prequel/ :
00216  *
00217  *   oSSL_key_dx exported.key somepassword
00218  *     or
00219  *   mcrypt_key_dx exported.key somepassword
00220  *
00221  * Either command will display both the server passphrase and the
00222  * "Server Secret".  Note that this latter is the version 1 server
00223  * secret (i.e. the SHA-256 of the server passphrase); the
00224  * corresponding version 2 server secret can be obtained by
00225  * calculating the truncated SHA-512 of the server passphrase.
00226  *
00227  * We do not know the server passphrase during normal operation.  We
00228  * use it in the self-tests only to check for typos and other errors
00229  * in the test vectors, by checking that the segment secret defined in
00230  * a content information segment test is as expected.
00231  */
00232 #define SERVER_PASSPHRASE( name, DATA )                                 \
00233         static uint8_t name[] = DATA
00234 
00235 /** Server passphrase used for these test vectors */
00236 SERVER_PASSPHRASE ( passphrase,
00237       DATA ( 0x2a, 0x3d, 0x73, 0xeb, 0x43, 0x5e, 0x9f, 0x2b, 0x8a, 0x34, 0x42,
00238              0x67, 0xe7, 0x46, 0x7a, 0x3c, 0x73, 0x85, 0xc6, 0xe0, 0x55, 0xe2,
00239              0xb4, 0xd3, 0x0d, 0xfe, 0xc7, 0xc3, 0x8b, 0x0e, 0xd7, 0x2c ) );
00240 
00241 /** IIS logo (iis-85.png) content information version 1 */
00242 PEERDIST_INFO_TEST ( iis_85_png_v1,
00243         DATA ( 0x00, 0x01, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00244                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00245                0x00, 0x00, 0x00, 0x00, 0x7e, 0x85, 0x01, 0x00, 0x00, 0x00, 0x01,
00246                0x00, 0xd8, 0xd9, 0x76, 0x35, 0x4a, 0x48, 0x72, 0xe9, 0x25, 0x76,
00247                0x18, 0x03, 0xf4, 0x58, 0xd9, 0xda, 0xaa, 0x67, 0xf8, 0xe3, 0x1c,
00248                0x63, 0x0f, 0xb7, 0x4e, 0x6a, 0x31, 0x2e, 0xf8, 0xa2, 0x5a, 0xba,
00249                0x11, 0xaf, 0xc0, 0xd7, 0x94, 0x92, 0x43, 0xf9, 0x4f, 0x9c, 0x1f,
00250                0xab, 0x35, 0xd9, 0xfd, 0x1e, 0x33, 0x1f, 0xcf, 0x78, 0x11, 0xa2,
00251                0xe0, 0x1d, 0x35, 0x87, 0xb3, 0x8d, 0x77, 0x0a, 0x29, 0xe2, 0x02,
00252                0x00, 0x00, 0x00, 0x73, 0xc1, 0x8a, 0xb8, 0x54, 0x91, 0x10, 0xf8,
00253                0xe9, 0x0e, 0x71, 0xbb, 0xc3, 0xab, 0x2a, 0xa8, 0xc4, 0x4d, 0x13,
00254                0xf4, 0x92, 0x94, 0x99, 0x25, 0x5b, 0x66, 0x0f, 0x24, 0xec, 0x77,
00255                0x80, 0x0b, 0x97, 0x4b, 0xdd, 0x65, 0x56, 0x7f, 0xde, 0xec, 0xcd,
00256                0xaf, 0xe4, 0x57, 0xa9, 0x50, 0x3b, 0x45, 0x48, 0xf6, 0x6e, 0xd3,
00257                0xb1, 0x88, 0xdc, 0xfd, 0xa0, 0xac, 0x38, 0x2b, 0x09, 0x71, 0x1a,
00258                0xcc ),
00259         &sha256_algorithm, 32, RANGE ( 0, 99710 ), TRIM ( 0, 99710 ), 1 );
00260 
00261 /** IIS logo (iis-85.png) content information version 1 segment 0 */
00262 PEERDIST_INFO_SEGMENT_TEST ( iis_85_png_v1_s0, 0,
00263         RANGE ( 0, 99710 ), 2, 65536,
00264         DATA ( 0xd8, 0xd9, 0x76, 0x35, 0x4a, 0x48, 0x72, 0xe9, 0x25, 0x76, 0x18,
00265                0x03, 0xf4, 0x58, 0xd9, 0xda, 0xaa, 0x67, 0xf8, 0xe3, 0x1c, 0x63,
00266                0x0f, 0xb7, 0x4e, 0x6a, 0x31, 0x2e, 0xf8, 0xa2, 0x5a, 0xba ),
00267         DATA ( 0x11, 0xaf, 0xc0, 0xd7, 0x94, 0x92, 0x43, 0xf9, 0x4f, 0x9c, 0x1f,
00268                0xab, 0x35, 0xd9, 0xfd, 0x1e, 0x33, 0x1f, 0xcf, 0x78, 0x11, 0xa2,
00269                0xe0, 0x1d, 0x35, 0x87, 0xb3, 0x8d, 0x77, 0x0a, 0x29, 0xe2 ),
00270         DATA ( 0x49, 0x1b, 0x21, 0x7d, 0xbe, 0xe2, 0xb5, 0xf1, 0x2c, 0xa7, 0x9b,
00271                0x01, 0x5e, 0x06, 0xf4, 0xbb, 0xe6, 0x4f, 0x97, 0x45, 0xba, 0xd7,
00272                0x86, 0x7a, 0xef, 0x17, 0xde, 0x59, 0x92, 0x7e, 0xdc, 0xe9 ) );
00273 
00274 /** IIS logo (iis-85.png) content information version 1 segment 0 block 0 */
00275 PEERDIST_INFO_BLOCK_TEST ( iis_85_png_v1_s0_b0, 0,
00276         RANGE ( 0, 65536 ),
00277         TRIM ( 0, 65536 ),
00278         DATA ( 0x73, 0xc1, 0x8a, 0xb8, 0x54, 0x91, 0x10, 0xf8, 0xe9, 0x0e, 0x71,
00279                0xbb, 0xc3, 0xab, 0x2a, 0xa8, 0xc4, 0x4d, 0x13, 0xf4, 0x92, 0x94,
00280                0x99, 0x25, 0x5b, 0x66, 0x0f, 0x24, 0xec, 0x77, 0x80, 0x0b ) );
00281 
00282 /** IIS logo (iis-85.png) content information version 1 segment 0 block 1 */
00283 PEERDIST_INFO_BLOCK_TEST ( iis_85_png_v1_s0_b1, 1,
00284         RANGE ( 65536, 99710 ),
00285         TRIM ( 65536, 99710 ),
00286         DATA ( 0x97, 0x4b, 0xdd, 0x65, 0x56, 0x7f, 0xde, 0xec, 0xcd, 0xaf, 0xe4,
00287                0x57, 0xa9, 0x50, 0x3b, 0x45, 0x48, 0xf6, 0x6e, 0xd3, 0xb1, 0x88,
00288                0xdc, 0xfd, 0xa0, 0xac, 0x38, 0x2b, 0x09, 0x71, 0x1a, 0xcc ) );
00289 
00290 /** IIS logo (iis-85.png) content information version 2 */
00291 PEERDIST_INFO_TEST ( iis_85_png_v2,
00292         DATA ( 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00293                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00294                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00295                0x00, 0x00, 0x88, 0x00, 0x00, 0x99, 0xde, 0xe0, 0xd0, 0xc3, 0x58,
00296                0xe2, 0x68, 0x4b, 0x62, 0x33, 0x0d, 0x32, 0xb5, 0xf1, 0x97, 0x87,
00297                0x24, 0xa0, 0xd0, 0xa5, 0x2b, 0xdc, 0x5e, 0x78, 0x1f, 0xae, 0x71,
00298                0xff, 0x57, 0xa8, 0xbe, 0x3d, 0xd4, 0x58, 0x03, 0x7e, 0xd4, 0x04,
00299                0x11, 0x6b, 0xb6, 0x16, 0xd9, 0xb1, 0x41, 0x16, 0x08, 0x85, 0x20,
00300                0xc4, 0x7c, 0xdc, 0x50, 0xab, 0xce, 0xa3, 0xfa, 0xe1, 0x88, 0xa9,
00301                0x8e, 0xa2, 0x2d, 0xf3, 0xc0, 0x00, 0x00, 0xeb, 0xa0, 0x33, 0x81,
00302                0xd0, 0xd0, 0xcb, 0x74, 0xf4, 0xb6, 0x13, 0xd8, 0x21, 0x0f, 0x37,
00303                0xf0, 0x02, 0xa0, 0x6f, 0x39, 0x10, 0x58, 0x60, 0x96, 0xa1, 0x30,
00304                0xd3, 0x43, 0x98, 0xc0, 0x8e, 0x66, 0xd7, 0xbc, 0xb8, 0xb6, 0xeb,
00305                0x77, 0x83, 0xe4, 0xf8, 0x07, 0x64, 0x7b, 0x63, 0xf1, 0x46, 0xb5,
00306                0x2f, 0x4a, 0xc8, 0x9c, 0xcc, 0x7a, 0xbf, 0x5f, 0xa1, 0x1a, 0xca,
00307                0xfc, 0x2a, 0xcf, 0x50, 0x28, 0x58, 0x6c ),
00308         &sha512_algorithm, 32, RANGE ( 0, 99710 ), TRIM ( 0, 99710 ), 2 );
00309 
00310 /** IIS logo (iis-85.png) content information version 2 segment 0 */
00311 PEERDIST_INFO_SEGMENT_TEST ( iis_85_png_v2_s0, 0,
00312         RANGE ( 0, 39390 ), 1, 39390,
00313         DATA ( 0xe0, 0xd0, 0xc3, 0x58, 0xe2, 0x68, 0x4b, 0x62, 0x33, 0x0d, 0x32,
00314                0xb5, 0xf1, 0x97, 0x87, 0x24, 0xa0, 0xd0, 0xa5, 0x2b, 0xdc, 0x5e,
00315                0x78, 0x1f, 0xae, 0x71, 0xff, 0x57, 0xa8, 0xbe, 0x3d, 0xd4 ),
00316         DATA ( 0x58, 0x03, 0x7e, 0xd4, 0x04, 0x11, 0x6b, 0xb6, 0x16, 0xd9, 0xb1,
00317                0x41, 0x16, 0x08, 0x85, 0x20, 0xc4, 0x7c, 0xdc, 0x50, 0xab, 0xce,
00318                0xa3, 0xfa, 0xe1, 0x88, 0xa9, 0x8e, 0xa2, 0x2d, 0xf3, 0xc0 ),
00319         DATA ( 0x33, 0x71, 0xbb, 0xea, 0xdd, 0xb6, 0x23, 0x53, 0xad, 0xce, 0xf9,
00320                0x70, 0xa0, 0x6f, 0xdf, 0x65, 0x00, 0x1e, 0x04, 0x21, 0xf4, 0xc7,
00321                0x10, 0x82, 0x76, 0xb0, 0xc3, 0x7a, 0x9f, 0x9e, 0xc1, 0x0f ) );
00322 
00323 /** IIS logo (iis-85.png) content information version 2 segment 0 block 0 */
00324 PEERDIST_INFO_BLOCK_TEST ( iis_85_png_v2_s0_b0, 0,
00325         RANGE ( 0, 39390 ),
00326         TRIM ( 0, 39390 ),
00327         DATA ( 0xe0, 0xd0, 0xc3, 0x58, 0xe2, 0x68, 0x4b, 0x62, 0x33, 0x0d, 0x32,
00328                0xb5, 0xf1, 0x97, 0x87, 0x24, 0xa0, 0xd0, 0xa5, 0x2b, 0xdc, 0x5e,
00329                0x78, 0x1f, 0xae, 0x71, 0xff, 0x57, 0xa8, 0xbe, 0x3d, 0xd4 ) );
00330 
00331 /** IIS logo (iis-85.png) content information version 2 segment 1 */
00332 PEERDIST_INFO_SEGMENT_TEST ( iis_85_png_v2_s1, 1,
00333         RANGE ( 39390, 99710 ), 1, 60320,
00334         DATA ( 0x33, 0x81, 0xd0, 0xd0, 0xcb, 0x74, 0xf4, 0xb6, 0x13, 0xd8, 0x21,
00335                0x0f, 0x37, 0xf0, 0x02, 0xa0, 0x6f, 0x39, 0x10, 0x58, 0x60, 0x96,
00336                0xa1, 0x30, 0xd3, 0x43, 0x98, 0xc0, 0x8e, 0x66, 0xd7, 0xbc ),
00337         DATA ( 0xb8, 0xb6, 0xeb, 0x77, 0x83, 0xe4, 0xf8, 0x07, 0x64, 0x7b, 0x63,
00338                0xf1, 0x46, 0xb5, 0x2f, 0x4a, 0xc8, 0x9c, 0xcc, 0x7a, 0xbf, 0x5f,
00339                0xa1, 0x1a, 0xca, 0xfc, 0x2a, 0xcf, 0x50, 0x28, 0x58, 0x6c ),
00340         DATA ( 0xd7, 0xe9, 0x24, 0x42, 0x5e, 0x8f, 0x4f, 0x88, 0xf0, 0x1d, 0xc6,
00341                0xa9, 0xbb, 0x1b, 0xc3, 0x7b, 0xe1, 0x13, 0xec, 0x79, 0x17, 0xc7,
00342                0x45, 0xd4, 0x96, 0x5c, 0x2b, 0x55, 0xfa, 0x16, 0x3a, 0x6e ) );
00343 
00344 /** IIS logo (iis-85.png) content information version 2 segment 1 block 0 */
00345 PEERDIST_INFO_BLOCK_TEST ( iis_85_png_v2_s1_b0, 0,
00346         RANGE ( 39390, 99710 ),
00347         TRIM ( 39390, 99710 ),
00348         DATA ( 0x33, 0x81, 0xd0, 0xd0, 0xcb, 0x74, 0xf4, 0xb6, 0x13, 0xd8, 0x21,
00349                0x0f, 0x37, 0xf0, 0x02, 0xa0, 0x6f, 0x39, 0x10, 0x58, 0x60, 0x96,
00350                0xa1, 0x30, 0xd3, 0x43, 0x98, 0xc0, 0x8e, 0x66, 0xd7, 0xbc ) );
00351 
00352 /**
00353  * Report content information test result
00354  *
00355  * @v test              Content information test
00356  * @v info              Content information to fill in
00357  * @v file              Test code file
00358  * @v line              Test code line
00359  */
00360 static void peerdist_info_okx ( struct peerdist_info_test *test,
00361                                 struct peerdist_info *info,
00362                                 const char *file, unsigned int line ) {
00363 
00364         /* Parse content information */
00365         okx ( peerdist_info ( virt_to_user ( test->data ), test->len,
00366                               info ) == 0, file, line );
00367 
00368         /* Verify content information */
00369         okx ( info->raw.data == virt_to_user ( test->data ), file, line );
00370         okx ( info->raw.len == test->len, file, line );
00371         okx ( info->digest == test->expected_digest, file, line );
00372         okx ( info->digestsize == test->expected_digestsize, file, line );
00373         okx ( info->range.start == test->expected_range.start, file, line );
00374         okx ( info->range.end == test->expected_range.end, file, line );
00375         okx ( info->trim.start == test->expected_trim.start, file, line );
00376         okx ( info->trim.end == test->expected_trim.end, file, line );
00377         okx ( info->trim.start >= info->range.start, file, line );
00378         okx ( info->trim.end <= info->range.end, file, line );
00379         okx ( info->segments == test->expected_segments, file, line );
00380 }
00381 #define peerdist_info_ok( test, info ) \
00382         peerdist_info_okx ( test, info, __FILE__, __LINE__ )
00383 
00384 /**
00385  * Report content information segment test result
00386  *
00387  * @v test              Content information segment test
00388  * @v info              Content information
00389  * @v segment           Segment information to fill in
00390  * @v file              Test code file
00391  * @v line              Test code line
00392  */
00393 static void peerdist_info_segment_okx ( struct peerdist_info_segment_test *test,
00394                                         const struct peerdist_info *info,
00395                                         struct peerdist_info_segment *segment,
00396                                         const char *file, unsigned int line ) {
00397         size_t digestsize = info->digestsize;
00398 
00399         /* Parse content information segment */
00400         okx ( peerdist_info_segment ( info, segment, test->index ) == 0,
00401               file, line );
00402 
00403         /* Verify content information segment */
00404         okx ( segment->info == info, file, line );
00405         okx ( segment->index == test->index, file, line );
00406         okx ( segment->range.start == test->expected_range.start, file, line );
00407         okx ( segment->range.end == test->expected_range.end, file, line );
00408         okx ( segment->blocks == test->expected_blocks, file, line );
00409         okx ( segment->blksize == test->expected_blksize, file, line );
00410         okx ( memcmp ( segment->hash, test->expected_hash,
00411                        digestsize ) == 0, file, line );
00412         okx ( memcmp ( segment->secret, test->expected_secret,
00413                        digestsize ) == 0, file, line );
00414         okx ( memcmp ( segment->id, test->expected_id,
00415                        digestsize ) == 0, file, line );
00416 }
00417 #define peerdist_info_segment_ok( test, info, segment ) \
00418         peerdist_info_segment_okx ( test, info, segment, __FILE__, __LINE__ )
00419 
00420 /**
00421  * Report content information block test result
00422  *
00423  * @v test              Content information block test
00424  * @v segment           Segment information
00425  * @v block             Block information to fill in
00426  * @v file              Test code file
00427  * @v line              Test code line
00428  */
00429 static void
00430 peerdist_info_block_okx ( struct peerdist_info_block_test *test,
00431                           const struct peerdist_info_segment *segment,
00432                           struct peerdist_info_block *block,
00433                           const char *file, unsigned int line ) {
00434         const struct peerdist_info *info = segment->info;
00435         size_t digestsize = info->digestsize;
00436 
00437         /* Parse content information block */
00438         okx ( peerdist_info_block ( segment, block, test->index ) == 0,
00439               file, line );
00440 
00441         /* Verify content information block */
00442         okx ( block->segment == segment, file, line );
00443         okx ( block->index == test->index, file, line );
00444         okx ( block->range.start == test->expected_range.start, file, line );
00445         okx ( block->range.end == test->expected_range.end, file, line );
00446         okx ( block->trim.start == test->expected_trim.start, file, line );
00447         okx ( block->trim.end == test->expected_trim.end, file, line );
00448         okx ( memcmp ( block->hash, test->expected_hash,
00449                        digestsize ) == 0, file, line );
00450 }
00451 #define peerdist_info_block_ok( test, segment, block ) \
00452         peerdist_info_block_okx ( test, segment, block, __FILE__, __LINE__ )
00453 
00454 /**
00455  * Report server passphrase test result
00456  *
00457  * @v test              Content information segment test
00458  * @v info              Content information
00459  * @v pass              Server passphrase
00460  * @v pass_len          Length of server passphrase
00461  * @v file              Test code file
00462  * @v line              Test code line
00463  */
00464 static void
00465 peerdist_info_passphrase_okx ( struct peerdist_info_segment_test *test,
00466                                const struct peerdist_info *info,
00467                                uint8_t *pass, size_t pass_len,
00468                                const char *file, unsigned int line ) {
00469         struct digest_algorithm *digest = info->digest;
00470         uint8_t ctx[digest->ctxsize];
00471         uint8_t secret[digest->digestsize];
00472         uint8_t expected[digest->digestsize];
00473         size_t digestsize = info->digestsize;
00474         size_t secretsize = digestsize;
00475 
00476         /* Calculate server secret */
00477         digest_init ( digest, ctx );
00478         digest_update ( digest, ctx, pass, pass_len );
00479         digest_final ( digest, ctx, secret );
00480 
00481         /* Calculate expected segment secret */
00482         hmac_init ( digest, ctx, secret, &secretsize );
00483         assert ( secretsize == digestsize );
00484         hmac_update ( digest, ctx, test->expected_hash, digestsize );
00485         hmac_final ( digest, ctx, secret, &secretsize, expected );
00486         assert ( secretsize == digestsize );
00487 
00488         /* Verify segment secret */
00489         okx ( memcmp ( test->expected_secret, expected, digestsize ) == 0,
00490               file, line );
00491 }
00492 #define peerdist_info_passphrase_ok( test, info, pass, pass_len )       \
00493         peerdist_info_passphrase_okx ( test, info, pass, pass_len,      \
00494                                        __FILE__, __LINE__ )
00495 
00496 /**
00497  * Perform content information self-tests
00498  *
00499  */
00500 static void peerdist_info_test_exec ( void ) {
00501         struct peerdist_info info;
00502         struct peerdist_info_segment segment;
00503         struct peerdist_info_block block;
00504 
00505         /* IIS logo (iis-85.png) content information version 1 */
00506         peerdist_info_ok ( &iis_85_png_v1, &info );
00507         peerdist_info_passphrase_ok ( &iis_85_png_v1_s0, &info,
00508                                       passphrase, sizeof ( passphrase ) );
00509         peerdist_info_segment_ok ( &iis_85_png_v1_s0, &info, &segment );
00510         peerdist_info_block_ok ( &iis_85_png_v1_s0_b0, &segment, &block );
00511         peerdist_info_block_ok ( &iis_85_png_v1_s0_b1, &segment, &block );
00512 
00513         /* IIS logo (iis-85.png) content information version 2 */
00514         peerdist_info_ok ( &iis_85_png_v2, &info );
00515         peerdist_info_passphrase_ok ( &iis_85_png_v2_s0, &info,
00516                                       passphrase, sizeof ( passphrase ) );
00517         peerdist_info_segment_ok ( &iis_85_png_v2_s0, &info, &segment );
00518         peerdist_info_block_ok ( &iis_85_png_v2_s0_b0, &segment, &block );
00519         peerdist_info_passphrase_ok ( &iis_85_png_v2_s1, &info,
00520                                       passphrase, sizeof ( passphrase ) );
00521         peerdist_info_segment_ok ( &iis_85_png_v2_s1, &info, &segment );
00522         peerdist_info_block_ok ( &iis_85_png_v2_s1_b0, &segment, &block );
00523 }
00524 
00525 /** Content information self-test */
00526 struct self_test peerdist_info_test __self_test = {
00527         .name = "pccrc",
00528         .exec = peerdist_info_test_exec,
00529 };