You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. #ifndef _IPXE_PCCRR_H
  2. #define _IPXE_PCCRR_H
  3. /** @file
  4. *
  5. * Peer Content Caching and Retrieval: Retrieval Protocol [MS-PCCRR]
  6. *
  7. * All fields are in network byte order.
  8. *
  9. */
  10. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  11. #include <stdint.h>
  12. #include <ipxe/uaccess.h>
  13. /** Magic retrieval URI path */
  14. #define PEERDIST_MAGIC_PATH "/116B50EB-ECE2-41ac-8429-9F9E963361B7/"
  15. /** Retrieval protocol version */
  16. union peerdist_msg_version {
  17. /** Raw version number */
  18. uint32_t raw;
  19. /** Major:minor version number */
  20. struct {
  21. /** Minor version number */
  22. uint16_t minor;
  23. /** Major version number */
  24. uint16_t major;
  25. } __attribute__ (( packed ));
  26. } __attribute__ (( packed ));
  27. /** Retrieval protocol version 1.0 */
  28. #define PEERDIST_MSG_VERSION_1_0 0x00000001UL
  29. /** Retrieval protocol version 2.0 */
  30. #define PEERDIST_MSG_VERSION_2_0 0x00000002UL
  31. /** Retrieval protocol supported versions */
  32. struct peerdist_msg_versions {
  33. /** Minimum supported protocol version */
  34. union peerdist_msg_version min;
  35. /** Maximum supported protocol version */
  36. union peerdist_msg_version max;
  37. } __attribute__ (( packed ));
  38. /** Retrieval protocol block range */
  39. struct peerdist_msg_range {
  40. /** First block in range */
  41. uint32_t first;
  42. /** Number of blocks in range */
  43. uint32_t count;
  44. } __attribute__ (( packed ));
  45. /** Retrieval protocol segment ID header */
  46. struct peerdist_msg_segment {
  47. /** Digest size (i.e. length of segment ID) */
  48. uint32_t digestsize;
  49. /* Followed by a single variable-length ID and padding:
  50. *
  51. * uint8_t id[digestsize];
  52. * uint8_t pad[ (-digestsize) & 0x3 ];
  53. */
  54. } __attribute__ (( packed ));
  55. /** Retrieval protocol segment ID
  56. *
  57. * @v digestsize Digest size
  58. */
  59. #define peerdist_msg_segment_t( digestsize ) \
  60. struct { \
  61. struct peerdist_msg_segment segment; \
  62. uint8_t id[digestsize]; \
  63. uint8_t pad[ ( -(digestsize) ) & 0x3 ]; \
  64. } __attribute__ (( packed ))
  65. /** Retrieval protocol block range list header */
  66. struct peerdist_msg_ranges {
  67. /** Number of ranges */
  68. uint32_t count;
  69. /* Followed by an array of block ranges:
  70. *
  71. * struct peerdist_msg_range range[count];
  72. */
  73. } __attribute__ (( packed ));
  74. /** Retrieval protocol block range list
  75. *
  76. * @v count Number of ranges
  77. */
  78. #define peerdist_msg_ranges_t( count ) \
  79. struct { \
  80. struct peerdist_msg_ranges ranges; \
  81. struct peerdist_msg_range range[count]; \
  82. } __attribute__ (( packed ))
  83. /** Retrieval protocol data block header */
  84. struct peerdist_msg_block {
  85. /** Length of data block */
  86. uint32_t len;
  87. /* Followed by the (encrypted) data block:
  88. *
  89. * uint8_t data[len];
  90. */
  91. } __attribute__ (( packed ));
  92. /** Retrieval protocol data block */
  93. #define peerdist_msg_block_t( len ) \
  94. struct { \
  95. struct peerdist_msg_block block; \
  96. uint8_t data[len]; \
  97. } __attribute__ (( packed ))
  98. /** Retrieval protocol initialisation vector header */
  99. struct peerdist_msg_iv {
  100. /** Cipher block size */
  101. uint32_t blksize;
  102. /* Followed by the initialisation vector:
  103. *
  104. * uint8_t data[blksize];
  105. */
  106. } __attribute__ (( packed ));
  107. /** Retrieval protocol initialisation vector */
  108. #define peerdist_msg_iv_t( blksize ) \
  109. struct { \
  110. struct peerdist_msg_iv iv; \
  111. uint8_t data[blksize]; \
  112. } __attribute__ (( packed ))
  113. /** Retrieval protocol useless VRF data header */
  114. struct peerdist_msg_useless_vrf {
  115. /** Length of useless VRF data */
  116. uint32_t len;
  117. /* Followed by a variable-length useless VRF data block and
  118. * padding:
  119. *
  120. * uint8_t data[len];
  121. * uint8_t pad[ (-len) & 0x3 ];
  122. */
  123. } __attribute__ (( packed ));
  124. /** Retrieval protocol useless VRF data */
  125. #define peerdist_msg_useless_vrf_t( vrf_len ) \
  126. struct { \
  127. struct peerdist_msg_useless_vrf vrf; \
  128. uint8_t data[vrf_len]; \
  129. uint8_t pad[ ( -(vrf_len) ) & 0x3 ]; \
  130. } __attribute__ (( packed ))
  131. /** Retrieval protocol message header */
  132. struct peerdist_msg_header {
  133. /** Protocol version
  134. *
  135. * This is the protocol version in which the message type was
  136. * first defined.
  137. */
  138. union peerdist_msg_version version;
  139. /** Message type */
  140. uint32_t type;
  141. /** Message size (including this header) */
  142. uint32_t len;
  143. /** Cryptographic algorithm ID */
  144. uint32_t algorithm;
  145. } __attribute__ (( packed ));
  146. /** Retrieval protocol cryptographic algorithm IDs */
  147. enum peerdist_msg_algorithm {
  148. /** No encryption */
  149. PEERDIST_MSG_PLAINTEXT = 0x00000000UL,
  150. /** AES-128 in CBC mode */
  151. PEERDIST_MSG_AES_128_CBC = 0x00000001UL,
  152. /** AES-192 in CBC mode */
  153. PEERDIST_MSG_AES_192_CBC = 0x00000002UL,
  154. /** AES-256 in CBC mode */
  155. PEERDIST_MSG_AES_256_CBC = 0x00000003UL,
  156. };
  157. /** Retrieval protocol transport response header */
  158. struct peerdist_msg_transport_header {
  159. /** Length (excluding this header)
  160. *
  161. * This seems to be identical in both purpose and value to the
  162. * length found within the message header, and therefore
  163. * serves no useful purpose.
  164. */
  165. uint32_t len;
  166. } __attribute__ (( packed ));
  167. /** Retrieval protocol negotiation request */
  168. struct peerdist_msg_nego_req {
  169. /** Message header */
  170. struct peerdist_msg_header hdr;
  171. /** Supported versions */
  172. struct peerdist_msg_versions versions;
  173. } __attribute__ (( packed ));
  174. /** Retrieval protocol negotiation request version */
  175. #define PEERDIST_MSG_NEGO_REQ_VERSION PEERDIST_MSG_VERSION_1_0
  176. /** Retrieval protocol negotiation request type */
  177. #define PEERDIST_MSG_NEGO_REQ_TYPE 0x00000000UL
  178. /** Retrieval protocol negotiation response */
  179. struct peerdist_msg_nego_resp {
  180. /** Message header */
  181. struct peerdist_msg_header hdr;
  182. /** Supported versions */
  183. struct peerdist_msg_versions versions;
  184. } __attribute__ (( packed ));
  185. /** Retrieval protocol negotiation response version */
  186. #define PEERDIST_MSG_NEGO_RESP_VERSION PEERDIST_MSG_VERSION_1_0
  187. /** Retrieval protocol negotiation response type */
  188. #define PEERDIST_MSG_NEGO_RESP_TYPE 0x00000001UL
  189. /** Retrieval protocol block list request header */
  190. struct peerdist_msg_getblklist {
  191. /** Message header */
  192. struct peerdist_msg_header hdr;
  193. /* Followed by a segment ID and a block range list:
  194. *
  195. * peerdist_msg_segment_t(digestsize) segment;
  196. * peerdist_msg_ranges_t(count) ranges;
  197. */
  198. } __attribute__ (( packed ));
  199. /** Retrieval protocol block list request
  200. *
  201. * @v digestsize Digest size
  202. * @v count Block range count
  203. */
  204. #define peerdist_msg_getblklist_t( digestsize, count ) \
  205. struct { \
  206. struct peerdist_msg_getblklist getblklist; \
  207. peerdist_msg_segment_t ( digestsize ) segment; \
  208. peerdist_msg_ranges_t ( count ) ranges; \
  209. } __attribute__ (( packed ))
  210. /** Retrieval protocol block list request version */
  211. #define PEERDIST_MSG_GETBLKLIST_VERSION PEERDIST_MSG_VERSION_1_0
  212. /** Retrieval protocol block list request type */
  213. #define PEERDIST_MSG_GETBLKLIST_TYPE 0x00000002UL
  214. /** Retrieval protocol block fetch request header */
  215. struct peerdist_msg_getblks {
  216. /** Message header */
  217. struct peerdist_msg_header hdr;
  218. /* Followed by a segment ID, a block range list, and a useless
  219. * VRF block:
  220. *
  221. * peerdist_msg_segment_t(digestsize) segment;
  222. * peerdist_msg_ranges_t(count) ranges;
  223. * peerdist_msg_vrf_t(vrf_len) vrf;
  224. */
  225. } __attribute__ (( packed ));
  226. /** Retrieval protocol block fetch request
  227. *
  228. * @v digestsize Digest size
  229. * @v count Block range count
  230. * @v vrf_len Length of uselessness
  231. */
  232. #define peerdist_msg_getblks_t( digestsize, count, vrf_len ) \
  233. struct { \
  234. struct peerdist_msg_getblks getblks; \
  235. peerdist_msg_segment_t ( digestsize ) segment; \
  236. peerdist_msg_ranges_t ( count ) ranges; \
  237. peerdist_msg_useless_vrf_t ( vrf_len ); \
  238. } __attribute__ (( packed ))
  239. /** Retrieval protocol block fetch request version */
  240. #define PEERDIST_MSG_GETBLKS_VERSION PEERDIST_MSG_VERSION_1_0
  241. /** Retrieval protocol block fetch request type */
  242. #define PEERDIST_MSG_GETBLKS_TYPE 0x00000003UL
  243. /** Retrieval protocol block list response header */
  244. struct peerdist_msg_blklist {
  245. /** Message header */
  246. struct peerdist_msg_header hdr;
  247. /* Followed by a segment ID, a block range list, and a next
  248. * block index:
  249. *
  250. * peerdist_msg_segment_t(digestsize) segment;
  251. * peerdist_msg_ranges_t(count) ranges;
  252. * uint32_t next;
  253. */
  254. } __attribute__ (( packed ));
  255. /** Retrieval protocol block list response
  256. *
  257. * @v digestsize Digest size
  258. * @v count Block range count
  259. */
  260. #define peerdist_msg_blklist_t( digestsize, count ) \
  261. struct { \
  262. struct peerdist_msg_blklist blklist; \
  263. peerdist_msg_segment_t ( digestsize ) segment; \
  264. peerdist_msg_ranges_t ( count ) ranges; \
  265. uint32_t next; \
  266. } __attribute__ (( packed ))
  267. /** Retrieval protocol block list response version */
  268. #define PEERDIST_MSG_BLKLIST_VERSION PEERDIST_MSG_VERSION_1_0
  269. /** Retrieval protocol block list response type */
  270. #define PEERDIST_MSG_BLKLIST_TYPE 0x00000004UL
  271. /** Retrieval protocol block fetch response header */
  272. struct peerdist_msg_blk {
  273. /** Message header */
  274. struct peerdist_msg_header hdr;
  275. /* Followed by a segment ID, a block index, a next block
  276. * index, a data block, a useless VRF block, and an
  277. * initialisation vector:
  278. *
  279. * peerdist_msg_segment_t(digestsize) segment;
  280. * uint32_t index;
  281. * uint32_t next;
  282. * peerdist_msg_block_t(len) data;
  283. * peerdist_msg_useless_vrf_t(vrf_len) vrf;
  284. * peerdist_msg_iv_t(blksize) iv;
  285. */
  286. } __attribute__ (( packed ));
  287. /** Retrieval protocol block fetch response
  288. *
  289. * @v digestsize Digest size
  290. * @v len Data block length
  291. * @v vrf_len Length of uselessness
  292. * @v blksize Cipher block size
  293. */
  294. #define peerdist_msg_blk_t( digestsize, len, vrf_len, blksize ) \
  295. struct { \
  296. struct peerdist_msg_blk blk; \
  297. peerdist_msg_segment_t ( digestsize ) segment; \
  298. uint32_t index; \
  299. uint32_t next; \
  300. peerdist_msg_block_t ( len ) block; \
  301. peerdist_msg_useless_vrf_t ( vrf_len ) vrf; \
  302. peerdist_msg_iv_t ( blksize ) iv; \
  303. } __attribute__ (( packed ))
  304. /** Retrieval protocol block fetch response version */
  305. #define PEERDIST_MSG_BLK_VERSION PEERDIST_MSG_VERSION_1_0
  306. /** Retrieval protocol block fetch response type */
  307. #define PEERDIST_MSG_BLK_TYPE 0x00000005UL
  308. /**
  309. * Parse retrieval protocol block fetch response
  310. *
  311. * @v raw Raw data
  312. * @v raw_len Length of raw data
  313. * @v digestsize Digest size
  314. * @v blksize Cipher block size
  315. * @v blk Structure to fill in
  316. * @ret rc Return status code
  317. */
  318. #define peerdist_msg_blk( raw, raw_len, digestsize, blksize, blk ) ( { \
  319. assert ( sizeof ( (blk)->segment.id ) == (digestsize) ); \
  320. assert ( sizeof ( (blk)->block.data ) == 0 ); \
  321. assert ( sizeof ( (blk)->vrf.data ) == 0 ); \
  322. assert ( sizeof ( (blk)->iv.data ) == blksize ); \
  323. peerdist_msg_blk_untyped ( (raw), (raw_len), (digestsize), \
  324. (blksize), blk ); \
  325. } )
  326. extern int peerdist_msg_blk_untyped ( userptr_t raw, size_t raw_len,
  327. size_t digestsize, size_t blksize,
  328. void *out );
  329. #endif /* _IPXE_PCCRR_H */