iPXE
pccrc.h
Go to the documentation of this file.
1#ifndef _IPXE_PCCRC_H
2#define _IPXE_PCCRC_H
3
4/** @file
5 *
6 * Peer Content Caching and Retrieval: Content Identification [MS-PCCRC]
7 *
8 */
9
10FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11FILE_SECBOOT ( PERMITTED );
12
13#include <stdint.h>
14#include <byteswap.h>
15#include <ipxe/crypto.h>
16
17/******************************************************************************
18 *
19 * Content Information versioning
20 *
21 ******************************************************************************
22 *
23 * Note that version 1 data structures are little-endian, but version
24 * 2 data structures are big-endian.
25 */
26
27/** Content Information version number */
29 /** Raw version number
30 *
31 * Always little-endian, regardless of whether the
32 * encompassing structure is version 1 (little-endian) or
33 * version 2 (big-endian).
34 */
36 /** Major:minor version number */
37 struct {
38 /** Minor version number */
40 /** Major version number */
42 } __attribute__ (( packed ));
43} __attribute__ (( packed ));
44
45/** Content Information version 1 */
46#define PEERDIST_INFO_V1 0x0100
47
48/** Content Information version 2 */
49#define PEERDIST_INFO_V2 0x0200
50
51/******************************************************************************
52 *
53 * Content Information version 1
54 *
55 ******************************************************************************
56 */
57
58/** Content Information version 1 data structure header
59 *
60 * All fields are little-endian.
61 */
63 /** Version number */
65 /** Hash algorithm
66 *
67 * This is a @c PEERDIST_INFO_V1_HASH_XXX constant.
68 */
70 /** Length to skip in first segment
71 *
72 * Length at the start of the first segment which is not
73 * included within the content range.
74 */
76 /** Length to read in last segment, or zero
77 *
78 * Length within the last segment which is included within the
79 * content range. A zero value indicates that the whole of
80 * the last segment is included within the content range.
81 */
83 /** Number of segments within the content information */
85 /* Followed by a variable-length array of segment descriptions
86 * and a list of variable-length block descriptions:
87 *
88 * peerdist_info_v1_segment_t(digestsize) segment[segments];
89 * peerdist_info_v1_block_t(digestsize, block0.blocks) block0;
90 * peerdist_info_v1_block_t(digestsize, block1.blocks) block1;
91 * ...
92 * peerdist_info_v1_block_t(digestsize, blockN.blocks) blockN;
93 */
94} __attribute__ (( packed ));
95
96/** SHA-256 hash algorithm */
97#define PEERDIST_INFO_V1_HASH_SHA256 0x0000800cUL
98
99/** SHA-384 hash algorithm */
100#define PEERDIST_INFO_V1_HASH_SHA384 0x0000800dUL
101
102/** SHA-512 hash algorithm */
103#define PEERDIST_INFO_V1_HASH_SHA512 0x0000800eUL
104
105/** Content Information version 1 segment description header
106 *
107 * All fields are little-endian.
108 */
110 /** Offset of this segment within the content */
112 /** Length of this segment
113 *
114 * Should always be 32MB, except for the last segment within
115 * the content.
116 */
118 /** Block size for this segment
119 *
120 * Should always be 64kB. Note that the last block within the
121 * last segment may actually be less than 64kB.
122 */
124 /* Followed by two variable-length hashes:
125 *
126 * uint8_t hash[digestsize];
127 * uint8_t secret[digestsize];
128 *
129 * where digestsize is the digest size for the selected hash
130 * algorithm.
131 *
132 * Note that the hash is taken over (the hashes of all blocks
133 * within) the entire segment, even if the blocks do not
134 * intersect the content range (and so do not appear within
135 * the block list). It therefore functions only as a segment
136 * identifier; it cannot be used to verify the content of the
137 * segment (since we may not download all blocks within the
138 * segment).
139 */
140} __attribute__ (( packed ));
141
142/** Content Information version 1 segment description
143 *
144 * @v digestsize Digest size
145 */
146#define peerdist_info_v1_segment_t( digestsize ) \
147 struct { \
148 struct peerdist_info_v1_segment segment; \
149 uint8_t hash[digestsize]; \
150 uint8_t secret[digestsize]; \
151 } __attribute__ (( packed ))
152
153/** Content Information version 1 block description header
154 *
155 * All fields are little-endian.
156 */
158 /** Number of blocks within the block description
159 *
160 * This is the number of blocks within the segment which
161 * overlap the content range. It may therefore be less than
162 * the number of blocks within the segment.
163 */
165 /* Followed by an array of variable-length hashes:
166 *
167 * uint8_t hash[blocks][digestsize];
168 *
169 * where digestsize is the digest size for the selected hash
170 * algorithm.
171 */
172 } __attribute__ (( packed ));
173
174/** Content Information version 1 block description
175 *
176 * @v digestsize Digest size
177 * @v blocks Number of blocks
178 */
179#define peerdist_info_v1_block_t( digestsize, blocks ) \
180 struct { \
181 struct peerdist_info_v1_block block; \
182 uint8_t hash[blocks][digestsize]; \
183 } __attribute__ (( packed ))
184
185/******************************************************************************
186 *
187 * Content Information version 2
188 *
189 ******************************************************************************
190 */
191
192/** Content Information version 2 data structure header
193 *
194 * All fields are big-endian.
195 */
197 /** Version number */
199 /** Hash algorithm
200 *
201 * This is a @c PEERDIST_INFO_V2_HASH_XXX constant.
202 */
204 /** Offset of the first segment within the content */
206 /** Index of the first segment within the content */
208 /** Length to skip in first segment
209 *
210 * Length at the start of the first segment which is not
211 * included within the content range.
212 */
214 /** Length of content range, or zero
215 *
216 * Length of the content range. A zero indicates that
217 * everything up to the end of the last segment is included in
218 * the content range.
219 */
221 /* Followed by a list of chunk descriptions */
222} __attribute__ (( packed ));
223
224/** SHA-512 hash algorithm with output truncated to first 256 bits */
225#define PEERDIST_INFO_V2_HASH_SHA512_TRUNC 0x04
226
227/** Content Information version 2 chunk description header
228 *
229 * All fields are big-endian.
230 */
232 /** Chunk type */
234 /** Chunk data length */
236 /* Followed by an array of segment descriptions:
237 *
238 * peerdist_info_v2_segment_t(digestsize) segment[segments]
239 *
240 * where digestsize is the digest size for the selected hash
241 * algorithm, and segments is equal to @c len divided by the
242 * size of each segment array entry.
243 */
244} __attribute__ (( packed ));
245
246/** Content Information version 2 chunk description
247 *
248 * @v digestsize Digest size
249 */
250#define peerdist_info_v2_chunk_t( digestsize ) \
251 struct { \
252 struct peerdist_info_v2_chunk chunk; \
253 peerdist_info_v2_segment_t ( digestsize ) segment[0]; \
254 } __attribute__ (( packed ))
255
256/** Chunk type */
257#define PEERDIST_INFO_V2_CHUNK_TYPE 0x00
258
259/** Content Information version 2 segment description header
260 *
261 * All fields are big-endian.
262 */
264 /** Segment length */
266 /* Followed by two variable-length hashes:
267 *
268 * uint8_t hash[digestsize];
269 * uint8_t secret[digestsize];
270 *
271 * where digestsize is the digest size for the selected hash
272 * algorithm.
273 */
274} __attribute__ (( packed ));
275
276/** Content Information version 2 segment description
277 *
278 * @v digestsize Digest size
279 */
280#define peerdist_info_v2_segment_t( digestsize ) \
281 struct { \
282 struct peerdist_info_v2_segment segment; \
283 uint8_t hash[digestsize]; \
284 uint8_t secret[digestsize]; \
285 } __attribute__ (( packed ))
286
287/******************************************************************************
288 *
289 * Content Information
290 *
291 ******************************************************************************
292 */
293
294/** Maximum digest size for any supported algorithm
295 *
296 * The largest digest size that we support is for SHA-512 at 64 bytes
297 */
298#define PEERDIST_DIGEST_MAX_SIZE 64
299
300/** Raw content information */
302 /** Data buffer */
303 const void *data;
304 /** Length of data buffer */
305 size_t len;
306};
307
308/** A content range */
310 /** Start offset */
311 size_t start;
312 /** End offset */
313 size_t end;
314};
315
316/** Content information */
318 /** Raw content information */
320
321 /** Content information operations */
323 /** Digest algorithm */
325 /** Digest size
326 *
327 * Note that this may be shorter than the digest size of the
328 * digest algorithm. The truncation does not always take
329 * place as soon as a digest is calculated. For example,
330 * version 2 content information uses SHA-512 with a truncated
331 * digest size of 32 (256 bits), but the segment identifier
332 * ("HoHoDk") is calculated by using HMAC with the full
333 * SHA-512 digest and then truncating the HMAC output, rather
334 * than by simply using HMAC with the truncated SHA-512
335 * digest. This is, of course, totally undocumented.
336 */
338 /** Content range */
340 /** Trimmed content range */
342 /** Number of segments within the content information */
343 unsigned int segments;
344};
345
346/** A content information segment */
348 /** Content information */
349 const struct peerdist_info *info;
350 /** Segment index */
351 unsigned int index;
352
353 /** Content range
354 *
355 * Note that this range may exceed the overall content range.
356 */
358 /** Number of blocks within this segment */
359 unsigned int blocks;
360 /** Block size */
361 size_t blksize;
362 /** Segment hash of data
363 *
364 * This is MS-PCCRC's "HoD".
365 */
367 /** Segment secret
368 *
369 * This is MS-PCCRC's "Ke = Kp".
370 */
372 /** Segment identifier
373 *
374 * This is MS-PCCRC's "HoHoDk".
375 */
377};
378
379/** Magic string constant used to calculate segment identifier
380 *
381 * Note that the MS-PCCRC specification states that this constant is
382 *
383 * "the null-terminated ASCII string constant "MS_P2P_CACHING";
384 * string literals are all ASCII strings with NULL terminators
385 * unless otherwise noted."
386 *
387 * The specification lies. This constant is a UTF-16LE string, not an
388 * ASCII string. The terminating wNUL *is* included within the
389 * constant.
390 */
391#define PEERDIST_SEGMENT_ID_MAGIC L"MS_P2P_CACHING"
392
393/** A content information block */
395 /** Content information segment */
397 /** Block index */
398 unsigned int index;
399
400 /** Content range
401 *
402 * Note that this range may exceed the overall content range.
403 */
405 /** Trimmed content range */
407 /** Block hash */
409};
410
411/** Content information operations */
413 /**
414 * Populate content information
415 *
416 * @v info Content information to fill in
417 * @ret rc Return status code
418 */
419 int ( * info ) ( struct peerdist_info *info );
420 /**
421 * Populate content information segment
422 *
423 * @v segment Content information segment to fill in
424 * @ret rc Return status code
425 */
426 int ( * segment ) ( struct peerdist_info_segment *segment );
427 /**
428 * Populate content information block
429 *
430 * @v block Content information block to fill in
431 * @ret rc Return status code
432 */
433 int ( * block ) ( struct peerdist_info_block *block );
434};
435
437
438extern int peerdist_info ( const void *data, size_t len,
439 struct peerdist_info *info );
440extern int peerdist_info_segment ( const struct peerdist_info *info,
442 unsigned int index );
443extern int peerdist_info_block ( const struct peerdist_info_segment *segment,
445 unsigned int index );
446
447#endif /* _IPXE_PCCRC_H */
u32 info
Definition ar9003_mac.h:0
unsigned short uint16_t
Definition stdint.h:11
unsigned int uint32_t
Definition stdint.h:12
unsigned long long uint64_t
Definition stdint.h:13
unsigned char uint8_t
Definition stdint.h:10
long index
Definition bigint.h:65
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define __attribute__(x)
Definition compiler.h:10
Cryptographic API.
uint16_t segment
Code segment.
Definition librm.h:3
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
int peerdist_info_segment(const struct peerdist_info *info, struct peerdist_info_segment *segment, unsigned int index)
Populate content information segment.
Definition pccrc.c:724
int peerdist_info_block(const struct peerdist_info_segment *segment, struct peerdist_info_block *block, unsigned int index)
Populate content information block.
Definition pccrc.c:768
#define PEERDIST_DIGEST_MAX_SIZE
Maximum digest size for any supported algorithm.
Definition pccrc.h:298
struct digest_algorithm sha512_trunc_algorithm
int peerdist_info(const void *data, size_t len, struct peerdist_info *info)
Populate content information.
Definition pccrc.c:670
A message digest algorithm.
Definition crypto.h:19
A content information block.
Definition pccrc.h:394
struct peerdist_range range
Content range.
Definition pccrc.h:404
unsigned int index
Block index.
Definition pccrc.h:398
struct peerdist_range trim
Trimmed content range.
Definition pccrc.h:406
const struct peerdist_info_segment * segment
Content information segment.
Definition pccrc.h:396
uint8_t hash[PEERDIST_DIGEST_MAX_SIZE]
Block hash.
Definition pccrc.h:408
Content information operations.
Definition pccrc.h:412
int(* info)(struct peerdist_info *info)
Populate content information.
Definition pccrc.h:419
int(* segment)(struct peerdist_info_segment *segment)
Populate content information segment.
Definition pccrc.h:426
int(* block)(struct peerdist_info_block *block)
Populate content information block.
Definition pccrc.h:433
A content information segment.
Definition pccrc.h:347
unsigned int blocks
Number of blocks within this segment.
Definition pccrc.h:359
size_t blksize
Block size.
Definition pccrc.h:361
const struct peerdist_info * info
Content information.
Definition pccrc.h:349
unsigned int index
Segment index.
Definition pccrc.h:351
uint8_t hash[PEERDIST_DIGEST_MAX_SIZE]
Segment hash of data.
Definition pccrc.h:366
uint8_t secret[PEERDIST_DIGEST_MAX_SIZE]
Segment secret.
Definition pccrc.h:371
struct peerdist_range range
Content range.
Definition pccrc.h:357
Content Information version 1 block description header.
Definition pccrc.h:157
uint32_t blocks
Number of blocks within the block description.
Definition pccrc.h:164
Content Information version 1 segment description header.
Definition pccrc.h:109
uint32_t blksize
Block size for this segment.
Definition pccrc.h:123
uint64_t offset
Offset of this segment within the content.
Definition pccrc.h:111
uint32_t len
Length of this segment.
Definition pccrc.h:117
Content Information version 1 data structure header.
Definition pccrc.h:62
union peerdist_info_version version
Version number.
Definition pccrc.h:64
uint32_t segments
Number of segments within the content information.
Definition pccrc.h:84
uint32_t last
Length to read in last segment, or zero.
Definition pccrc.h:82
uint32_t hash
Hash algorithm.
Definition pccrc.h:69
uint32_t first
Length to skip in first segment.
Definition pccrc.h:75
Content Information version 2 chunk description header.
Definition pccrc.h:231
uint32_t len
Chunk data length.
Definition pccrc.h:235
uint8_t type
Chunk type.
Definition pccrc.h:233
Content Information version 2 segment description header.
Definition pccrc.h:263
uint32_t len
Segment length.
Definition pccrc.h:265
Content Information version 2 data structure header.
Definition pccrc.h:196
uint64_t offset
Offset of the first segment within the content.
Definition pccrc.h:205
union peerdist_info_version version
Version number.
Definition pccrc.h:198
uint64_t index
Index of the first segment within the content.
Definition pccrc.h:207
uint8_t hash
Hash algorithm.
Definition pccrc.h:203
uint32_t first
Length to skip in first segment.
Definition pccrc.h:213
uint64_t len
Length of content range, or zero.
Definition pccrc.h:220
Content information.
Definition pccrc.h:317
size_t digestsize
Digest size.
Definition pccrc.h:337
unsigned int segments
Number of segments within the content information.
Definition pccrc.h:343
struct peerdist_info_operations * op
Content information operations.
Definition pccrc.h:322
struct digest_algorithm * digest
Digest algorithm.
Definition pccrc.h:324
struct peerdist_range range
Content range.
Definition pccrc.h:339
struct peerdist_range trim
Trimmed content range.
Definition pccrc.h:341
struct peerdist_raw raw
Raw content information.
Definition pccrc.h:319
A content range.
Definition pccrc.h:309
size_t start
Start offset.
Definition pccrc.h:311
size_t end
End offset.
Definition pccrc.h:313
Raw content information.
Definition pccrc.h:301
const void * data
Data buffer.
Definition pccrc.h:303
size_t len
Length of data buffer.
Definition pccrc.h:305
Content Information version number.
Definition pccrc.h:28
uint16_t raw
Raw version number.
Definition pccrc.h:35
uint8_t minor
Minor version number.
Definition pccrc.h:39
uint8_t major
Major version number.
Definition pccrc.h:41