file_parser.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*############################################################################
  2. # Copyright 2016 Intel Corporation
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. ############################################################################*/
  16. /*!
  17. * \file
  18. *
  19. * \brief Implementation of issuer material file parsing utilities.
  20. *
  21. */
  22. #include "epid/common/file_parser.h"
  23. #include <string.h>
  24. #include "epid/common/math/ecdsa.h"
  25. #include "epid/common/src/memory.h"
  26. #include "epid/common/src/file_parser-internal.h"
  27. const OctStr16 kEpidVersionCode[kNumEpidVersions] = {
  28. {0x01, 0x00}, {0x02, 0x00},
  29. };
  30. const OctStr16 kEpidFileTypeCode[kNumFileTypes] = {
  31. {0x00, 0x11}, {0x00, 0x0C}, {0x00, 0x0D}, {0x00, 0x0E},
  32. {0x00, 0x0F}, {0x00, 0x03}, {0x00, 0x0B}, {0x00, 0x13},
  33. };
  34. /// Intel(R) EPID 2.0 Group Public Key binary format
  35. typedef struct EpidGroupPubKeyCertificate {
  36. EpidFileHeader header; ///< Intel(R) EPID binary file header
  37. GroupId gid; ///< group ID
  38. G1ElemStr h1; ///< an element in G1
  39. G1ElemStr h2; ///< an element in G1
  40. G2ElemStr w; ///< an element in G2
  41. EcdsaSignature signature; ///< ECDSA Signature on SHA-256 of above values
  42. } EpidGroupPubKeyCertificate;
  43. /// Intel(R) EPID version
  44. static const OctStr16 kEpidVersion = {0x02, 0x00};
  45. /// Verify that certificate contains of EC secp256r1 parameters
  46. EpidStatus EpidVerifyCaCertificate(EpidCaCertificate const* cert) {
  47. // Prime of GF(p) for secp256r1
  48. static const unsigned char secp256r1_p[] = {
  49. // 2^256 -2^224 +2^192 +2^96 -1
  50. 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  51. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
  52. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  53. // Coefficient of E Curve secp256r1
  54. static const unsigned char secp256r1_a[] = {
  55. 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  56. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
  57. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc};
  58. // Coefficient of E Curve secp256r1
  59. static const unsigned char secp256r1_b[] = {
  60. 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd,
  61. 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
  62. 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b};
  63. // X coordinate of Base point G of secp256r1
  64. static const unsigned char secp256r1_gx[] = {
  65. 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6,
  66. 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb,
  67. 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96};
  68. // Y coordinate of Base point G of secp256r1
  69. static const unsigned char secp256r1_gy[] = {
  70. 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
  71. 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
  72. 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5};
  73. // Order of base point of secp256r1
  74. static const unsigned char secp256r1_r[] = {
  75. 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
  76. 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
  77. 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
  78. };
  79. if (!cert) return kEpidBadArgErr;
  80. // Verify that certificate contains of correct file header
  81. if (0 !=
  82. memcmp(&cert->header.epid_version, &kEpidVersion, sizeof(kEpidVersion))) {
  83. return kEpidBadArgErr;
  84. }
  85. if (0 != memcmp(&cert->header.file_type,
  86. &kEpidFileTypeCode[kIssuingCaPubKeyFile],
  87. sizeof(cert->header.file_type))) {
  88. return kEpidBadArgErr;
  89. }
  90. // Verify that certificate contains of EC secp256r1 parameters
  91. if (0 != memcmp(&cert->prime, secp256r1_p, sizeof(secp256r1_p))) {
  92. return kEpidBadArgErr;
  93. }
  94. if (0 != memcmp(&cert->a, secp256r1_a, sizeof(secp256r1_a))) {
  95. return kEpidBadArgErr;
  96. }
  97. if (0 != memcmp(&cert->b, secp256r1_b, sizeof(secp256r1_b))) {
  98. return kEpidBadArgErr;
  99. }
  100. if (0 != memcmp(&cert->x, secp256r1_gx, sizeof(secp256r1_gx))) {
  101. return kEpidBadArgErr;
  102. }
  103. if (0 != memcmp(&cert->y, secp256r1_gy, sizeof(secp256r1_gy))) {
  104. return kEpidBadArgErr;
  105. }
  106. if (0 != memcmp(&cert->r, secp256r1_r, sizeof(secp256r1_r))) {
  107. return kEpidBadArgErr;
  108. }
  109. return kEpidNoErr;
  110. }
  111. EpidStatus EpidParseFileHeader(void const* buf, size_t len,
  112. EpidVersion* epid_version,
  113. EpidFileType* file_type) {
  114. EpidFileHeader* header = (EpidFileHeader*)buf;
  115. if (!buf || len < sizeof(EpidFileHeader)) return kEpidBadArgErr;
  116. if (epid_version) {
  117. if (0 == memcmp((void*)&header->epid_version, &kEpidVersionCode[kEpid1x],
  118. sizeof(header->epid_version))) {
  119. *epid_version = kEpid1x;
  120. } else if (0 == memcmp((void*)&header->epid_version,
  121. &kEpidVersionCode[kEpid2x],
  122. sizeof(header->epid_version))) {
  123. *epid_version = kEpid2x;
  124. } else {
  125. // set default value
  126. *epid_version = kNumEpidVersions;
  127. }
  128. }
  129. if (file_type) {
  130. if (0 == memcmp((void*)&header->file_type,
  131. &kEpidFileTypeCode[kIssuingCaPubKeyFile],
  132. sizeof(header->file_type))) {
  133. *file_type = kIssuingCaPubKeyFile;
  134. } else if (0 == memcmp((void*)&header->file_type,
  135. &kEpidFileTypeCode[kGroupPubKeyFile],
  136. sizeof(header->file_type))) {
  137. *file_type = kGroupPubKeyFile;
  138. } else if (0 == memcmp((void*)&header->file_type,
  139. &kEpidFileTypeCode[kPrivRlFile],
  140. sizeof(header->file_type))) {
  141. *file_type = kPrivRlFile;
  142. } else if (0 == memcmp((void*)&header->file_type,
  143. &kEpidFileTypeCode[kSigRlFile],
  144. sizeof(header->file_type))) {
  145. *file_type = kSigRlFile;
  146. } else if (0 == memcmp((void*)&header->file_type,
  147. &kEpidFileTypeCode[kGroupRlFile],
  148. sizeof(header->file_type))) {
  149. *file_type = kGroupRlFile;
  150. } else if (0 == memcmp((void*)&header->file_type,
  151. &kEpidFileTypeCode[kPrivRlRequestFile],
  152. sizeof(header->file_type))) {
  153. *file_type = kPrivRlRequestFile;
  154. } else if (0 == memcmp((void*)&header->file_type,
  155. &kEpidFileTypeCode[kSigRlRequestFile],
  156. sizeof(header->file_type))) {
  157. *file_type = kSigRlRequestFile;
  158. } else if (0 == memcmp((void*)&header->file_type,
  159. &kEpidFileTypeCode[kGroupRlRequestFile],
  160. sizeof(header->file_type))) {
  161. *file_type = kGroupRlRequestFile;
  162. } else {
  163. // set default value
  164. *file_type = kNumFileTypes;
  165. }
  166. }
  167. return kEpidNoErr;
  168. }
  169. /// Parse a file with a revocation list of any type
  170. static EpidStatus EpidParseRlFile(void const* buf, size_t len,
  171. EpidCaCertificate const* cert, void* rl,
  172. size_t* rl_len, EpidFileType file_type) {
  173. size_t min_rl_file_size = 0;
  174. size_t empty_rl_size = 0;
  175. size_t rl_entry_size = 0;
  176. EpidStatus result = kEpidErr;
  177. EpidFileHeader const* file_header = (EpidFileHeader*)buf;
  178. void const* buf_rl =
  179. (void const*)((unsigned char*)buf + sizeof(EpidFileHeader));
  180. size_t buf_rl_len = 0;
  181. EcdsaSignature const* signature = NULL;
  182. if (!buf || !cert || !rl_len) return kEpidBadArgErr;
  183. switch (file_type) {
  184. case kPrivRlFile:
  185. empty_rl_size = sizeof(PrivRl) - sizeof(((PrivRl*)0)->f[0]);
  186. rl_entry_size = sizeof(((PrivRl*)0)->f[0]);
  187. min_rl_file_size = sizeof(EpidFileHeader) + sizeof(PrivRl) -
  188. sizeof(((PrivRl*)0)->f[0]) + sizeof(EcdsaSignature);
  189. break;
  190. case kSigRlFile:
  191. empty_rl_size = sizeof(SigRl) - sizeof(((SigRl*)0)->bk[0]);
  192. rl_entry_size = sizeof(((SigRl*)0)->bk[0]);
  193. min_rl_file_size = sizeof(EpidFileHeader) + sizeof(SigRl) -
  194. sizeof(((SigRl*)0)->bk[0]) + sizeof(EcdsaSignature);
  195. break;
  196. case kGroupRlFile:
  197. empty_rl_size = sizeof(GroupRl) - sizeof(((GroupRl*)0)->gid[0]);
  198. rl_entry_size = sizeof(((GroupRl*)0)->gid[0]);
  199. min_rl_file_size = sizeof(EpidFileHeader) + sizeof(GroupRl) -
  200. sizeof(((GroupRl*)0)->gid[0]) + sizeof(EcdsaSignature);
  201. break;
  202. default:
  203. return kEpidErr;
  204. }
  205. if (min_rl_file_size > len) return kEpidBadArgErr;
  206. // Verify that Intel(R) EPID file header in the buffer is correct
  207. if (0 !=
  208. memcmp(&file_header->epid_version, &kEpidVersion, sizeof(kEpidVersion))) {
  209. return kEpidBadArgErr;
  210. }
  211. if (0 != memcmp(&file_header->file_type, &kEpidFileTypeCode[file_type],
  212. sizeof(file_header->file_type))) {
  213. return kEpidBadArgErr;
  214. }
  215. // Verify that CA certificate is correct
  216. result = EpidVerifyCaCertificate(cert);
  217. if (kEpidNoErr != result) return result;
  218. // Verify that RL in file buffer contains of integer number of entries
  219. buf_rl_len = len - sizeof(EpidFileHeader) - sizeof(EcdsaSignature);
  220. if (0 != ((buf_rl_len - empty_rl_size) % rl_entry_size)) {
  221. return kEpidBadArgErr;
  222. }
  223. signature =
  224. (EcdsaSignature*)((unsigned char*)buf + len - sizeof(EcdsaSignature));
  225. // Authenticate signature for buffer
  226. result = EcdsaVerifyBuffer(buf, len - sizeof(EcdsaSignature),
  227. (EcdsaPublicKey*)&cert->pubkey, signature);
  228. if (kEpidSigValid != result) return result;
  229. buf_rl_len = len - sizeof(EpidFileHeader) - sizeof(EcdsaSignature);
  230. // If pointer to output buffer is NULL it should return required size of RL
  231. if (!rl) {
  232. *rl_len = buf_rl_len;
  233. return kEpidNoErr;
  234. }
  235. if (*rl_len < buf_rl_len) return kEpidBadArgErr;
  236. *rl_len = buf_rl_len;
  237. // Copy revocation list from file buffer to output
  238. // Memory copy is used to copy a revocation list of variable length
  239. if (0 != memcpy_S(rl, *rl_len, buf_rl, buf_rl_len)) return kEpidBadArgErr;
  240. return kEpidNoErr;
  241. }
  242. EpidStatus EpidParseGroupPubKeyFile(void const* buf, size_t len,
  243. EpidCaCertificate const* cert,
  244. GroupPubKey* pubkey) {
  245. EpidStatus result;
  246. EpidGroupPubKeyCertificate* buf_pubkey = (EpidGroupPubKeyCertificate*)buf;
  247. if (!buf || !cert || !pubkey) {
  248. return kEpidBadArgErr;
  249. }
  250. if (sizeof(EpidGroupPubKeyCertificate) > len) {
  251. return kEpidBadArgErr;
  252. }
  253. // Verify that Intel(R) EPID file header in the buffer is correct
  254. if (0 != memcmp(&buf_pubkey->header.epid_version, &kEpidVersion,
  255. sizeof(kEpidVersion))) {
  256. return kEpidBadArgErr;
  257. }
  258. if (0 != memcmp(&buf_pubkey->header.file_type,
  259. &kEpidFileTypeCode[kGroupPubKeyFile],
  260. sizeof(buf_pubkey->header.file_type))) {
  261. return kEpidBadArgErr;
  262. }
  263. // Verify that CA certificate is correct
  264. result = EpidVerifyCaCertificate(cert);
  265. if (kEpidNoErr != result) return result;
  266. // Authenticate signature for buffer
  267. result = EcdsaVerifyBuffer(
  268. buf_pubkey, sizeof(EpidGroupPubKeyCertificate) - sizeof(EcdsaSignature),
  269. (EcdsaPublicKey*)&cert->pubkey, &buf_pubkey->signature);
  270. if (kEpidSigValid != result) return result;
  271. // Copy public from the buffer to output
  272. pubkey->gid = buf_pubkey->gid;
  273. pubkey->h1 = buf_pubkey->h1;
  274. pubkey->h2 = buf_pubkey->h2;
  275. pubkey->w = buf_pubkey->w;
  276. return kEpidNoErr;
  277. }
  278. EpidStatus EpidParsePrivRlFile(void const* buf, size_t len,
  279. EpidCaCertificate const* cert, PrivRl* rl,
  280. size_t* rl_len) {
  281. return EpidParseRlFile(buf, len, cert, rl, rl_len, kPrivRlFile);
  282. }
  283. EpidStatus EpidParseSigRlFile(void const* buf, size_t len,
  284. EpidCaCertificate const* cert, SigRl* rl,
  285. size_t* rl_len) {
  286. return EpidParseRlFile(buf, len, cert, rl, rl_len, kSigRlFile);
  287. }
  288. EpidStatus EpidParseGroupRlFile(void const* buf, size_t len,
  289. EpidCaCertificate const* cert, GroupRl* rl,
  290. size_t* rl_len) {
  291. return EpidParseRlFile(buf, len, cert, rl, rl_len, kGroupRlFile);
  292. }