mbedtls_x509_parser.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. /*
  2. * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. /*
  7. * X509 parser based on mbed TLS
  8. *
  9. * This module implements functions to check the integrity of a X509v3
  10. * certificate ASN.1 structure and extract authentication parameters from the
  11. * extensions field, such as an image hash or a public key.
  12. */
  13. #include <assert.h>
  14. #include <stddef.h>
  15. #include <stdint.h>
  16. #include <string.h>
  17. /* mbed TLS headers */
  18. #include <mbedtls/asn1.h>
  19. #include <mbedtls/oid.h>
  20. #include <mbedtls/platform.h>
  21. #include <arch_helpers.h>
  22. #include <drivers/auth/img_parser_mod.h>
  23. #include <drivers/auth/mbedtls/mbedtls_common.h>
  24. #include <lib/utils.h>
  25. /* Maximum OID string length ("a.b.c.d.e.f ...") */
  26. #define MAX_OID_STR_LEN 64
  27. #define LIB_NAME "mbed TLS X509v3"
  28. /* Temporary variables to speed up the authentication parameters search. These
  29. * variables are assigned once during the integrity check and used any time an
  30. * authentication parameter is requested, so we do not have to parse the image
  31. * again */
  32. static mbedtls_asn1_buf tbs;
  33. static mbedtls_asn1_buf v3_ext;
  34. static mbedtls_asn1_buf pk;
  35. static mbedtls_asn1_buf sig_alg;
  36. static mbedtls_asn1_buf signature;
  37. /*
  38. * Clear all static temporary variables.
  39. */
  40. static void clear_temp_vars(void)
  41. {
  42. #define ZERO_AND_CLEAN(x) \
  43. do { \
  44. zeromem(&x, sizeof(x)); \
  45. clean_dcache_range((uintptr_t)&x, sizeof(x)); \
  46. } while (0);
  47. ZERO_AND_CLEAN(tbs)
  48. ZERO_AND_CLEAN(v3_ext);
  49. ZERO_AND_CLEAN(pk);
  50. ZERO_AND_CLEAN(sig_alg);
  51. ZERO_AND_CLEAN(signature);
  52. #undef ZERO_AND_CLEAN
  53. }
  54. /*
  55. * Get X509v3 extension
  56. *
  57. * Global variable 'v3_ext' must point to the extensions region
  58. * in the certificate. OID may be NULL to request that get_ext()
  59. * is only being called for integrity checking.
  60. */
  61. static int get_ext(const char *oid, void **ext, unsigned int *ext_len)
  62. {
  63. int oid_len, ret, is_critical;
  64. size_t len;
  65. unsigned char *p;
  66. const unsigned char *end;
  67. char oid_str[MAX_OID_STR_LEN];
  68. mbedtls_asn1_buf extn_oid;
  69. p = v3_ext.p;
  70. end = v3_ext.p + v3_ext.len;
  71. /*
  72. * Check extensions integrity. At least one extension is
  73. * required: the ASN.1 specifies a minimum size of 1, and at
  74. * least one extension is needed to authenticate the next stage
  75. * in the boot chain.
  76. */
  77. do {
  78. unsigned char *end_ext_data;
  79. ret = mbedtls_asn1_get_tag(&p, end, &len,
  80. MBEDTLS_ASN1_CONSTRUCTED |
  81. MBEDTLS_ASN1_SEQUENCE);
  82. if (ret != 0) {
  83. return IMG_PARSER_ERR_FORMAT;
  84. }
  85. end_ext_data = p + len;
  86. /* Get extension ID */
  87. ret = mbedtls_asn1_get_tag(&p, end_ext_data, &extn_oid.len,
  88. MBEDTLS_ASN1_OID);
  89. if (ret != 0) {
  90. return IMG_PARSER_ERR_FORMAT;
  91. }
  92. extn_oid.tag = MBEDTLS_ASN1_OID;
  93. extn_oid.p = p;
  94. p += extn_oid.len;
  95. /* Get optional critical */
  96. ret = mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical);
  97. if ((ret != 0) && (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
  98. return IMG_PARSER_ERR_FORMAT;
  99. }
  100. /*
  101. * Data should be octet string type and must use all bytes in
  102. * the Extension.
  103. */
  104. ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len,
  105. MBEDTLS_ASN1_OCTET_STRING);
  106. if ((ret != 0) || ((p + len) != end_ext_data)) {
  107. return IMG_PARSER_ERR_FORMAT;
  108. }
  109. /* Detect requested extension */
  110. oid_len = mbedtls_oid_get_numeric_string(oid_str,
  111. MAX_OID_STR_LEN,
  112. &extn_oid);
  113. if ((oid_len == MBEDTLS_ERR_OID_BUF_TOO_SMALL) || (oid_len < 0)) {
  114. return IMG_PARSER_ERR;
  115. }
  116. if ((oid != NULL) &&
  117. ((size_t)oid_len == strlen(oid_str)) &&
  118. (strcmp(oid, oid_str) == 0)) {
  119. /* Extension must be ASN.1 DER */
  120. if (len < 2) {
  121. /* too short */
  122. return IMG_PARSER_ERR_FORMAT;
  123. }
  124. if ((p[0] & 0x1F) == 0x1F) {
  125. /* multi-byte ASN.1 DER tag, not allowed */
  126. return IMG_PARSER_ERR_FORMAT;
  127. }
  128. if ((p[0] & 0xDF) == 0) {
  129. /* UNIVERSAL 0 tag, not allowed */
  130. return IMG_PARSER_ERR_FORMAT;
  131. }
  132. *ext = (void *)p;
  133. *ext_len = (unsigned int)len;
  134. /* Advance past the tag byte */
  135. p++;
  136. if (mbedtls_asn1_get_len(&p, end_ext_data, &len)) {
  137. /* not valid DER */
  138. return IMG_PARSER_ERR_FORMAT;
  139. }
  140. if (p + len != end_ext_data) {
  141. /* junk after ASN.1 object */
  142. return IMG_PARSER_ERR_FORMAT;
  143. }
  144. return IMG_PARSER_OK;
  145. }
  146. /* Next */
  147. p = end_ext_data;
  148. } while (p < end);
  149. return (oid == NULL) ? IMG_PARSER_OK : IMG_PARSER_ERR_NOT_FOUND;
  150. }
  151. /*
  152. * Check the integrity of the certificate ASN.1 structure.
  153. *
  154. * Extract the relevant data that will be used later during authentication.
  155. *
  156. * This function doesn't clear the static variables located on the top of this
  157. * file in case of an error. It is only called from check_integrity(), which
  158. * performs the cleanup if necessary.
  159. */
  160. static int cert_parse(void *img, unsigned int img_len)
  161. {
  162. int ret;
  163. size_t len;
  164. unsigned char *p, *end, *crt_end, *pk_end;
  165. mbedtls_asn1_buf sig_alg1;
  166. /*
  167. * The unique ASN.1 DER encoding of [0] EXPLICIT INTEGER { v3(2} }.
  168. */
  169. static const char v3[] = {
  170. /* The outer CONTEXT SPECIFIC 0 tag */
  171. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0,
  172. /* The number bytes used to encode the inner INTEGER */
  173. 3,
  174. /* The tag of the inner INTEGER */
  175. MBEDTLS_ASN1_INTEGER,
  176. /* The number of bytes needed to represent 2 */
  177. 1,
  178. /* The actual value 2 */
  179. 2,
  180. };
  181. p = (unsigned char *)img;
  182. len = img_len;
  183. crt_end = p + len;
  184. end = crt_end;
  185. /*
  186. * Certificate ::= SEQUENCE {
  187. * tbsCertificate TBSCertificate,
  188. * signatureAlgorithm AlgorithmIdentifier,
  189. * signatureValue BIT STRING }
  190. */
  191. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
  192. MBEDTLS_ASN1_SEQUENCE);
  193. if ((ret != 0) || ((p + len) != end)) {
  194. return IMG_PARSER_ERR_FORMAT;
  195. }
  196. /*
  197. * TBSCertificate ::= SEQUENCE {
  198. */
  199. tbs.p = p;
  200. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
  201. MBEDTLS_ASN1_SEQUENCE);
  202. if (ret != 0) {
  203. return IMG_PARSER_ERR_FORMAT;
  204. }
  205. end = p + len;
  206. tbs.len = end - tbs.p;
  207. /*
  208. * Version ::= [0] EXPLICIT INTEGER { v1(0), v2(1), v3(2) }
  209. * -- only v3 accepted
  210. */
  211. if (((end - p) <= (ptrdiff_t)sizeof(v3)) ||
  212. (memcmp(p, v3, sizeof(v3)) != 0)) {
  213. return IMG_PARSER_ERR_FORMAT;
  214. }
  215. p += sizeof(v3);
  216. /*
  217. * CertificateSerialNumber ::= INTEGER
  218. */
  219. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
  220. if (ret != 0) {
  221. return IMG_PARSER_ERR_FORMAT;
  222. }
  223. p += len;
  224. /*
  225. * signature AlgorithmIdentifier
  226. */
  227. sig_alg1.p = p;
  228. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
  229. MBEDTLS_ASN1_SEQUENCE);
  230. if (ret != 0) {
  231. return IMG_PARSER_ERR_FORMAT;
  232. }
  233. sig_alg1.len = (p + len) - sig_alg1.p;
  234. p += len;
  235. /*
  236. * issuer Name
  237. */
  238. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
  239. MBEDTLS_ASN1_SEQUENCE);
  240. if (ret != 0) {
  241. return IMG_PARSER_ERR_FORMAT;
  242. }
  243. p += len;
  244. /*
  245. * Validity ::= SEQUENCE {
  246. * notBefore Time,
  247. * notAfter Time }
  248. *
  249. */
  250. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
  251. MBEDTLS_ASN1_SEQUENCE);
  252. if (ret != 0) {
  253. return IMG_PARSER_ERR_FORMAT;
  254. }
  255. p += len;
  256. /*
  257. * subject Name
  258. */
  259. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
  260. MBEDTLS_ASN1_SEQUENCE);
  261. if (ret != 0) {
  262. return IMG_PARSER_ERR_FORMAT;
  263. }
  264. p += len;
  265. /*
  266. * SubjectPublicKeyInfo
  267. */
  268. pk.p = p;
  269. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
  270. MBEDTLS_ASN1_SEQUENCE);
  271. if (ret != 0) {
  272. return IMG_PARSER_ERR_FORMAT;
  273. }
  274. pk_end = p + len;
  275. pk.len = pk_end - pk.p;
  276. /* algorithm */
  277. ret = mbedtls_asn1_get_tag(&p, pk_end, &len, MBEDTLS_ASN1_CONSTRUCTED |
  278. MBEDTLS_ASN1_SEQUENCE);
  279. if (ret != 0) {
  280. return IMG_PARSER_ERR_FORMAT;
  281. }
  282. p += len;
  283. /* Key is a BIT STRING and must use all bytes in SubjectPublicKeyInfo */
  284. ret = mbedtls_asn1_get_bitstring_null(&p, pk_end, &len);
  285. if ((ret != 0) || (p + len != pk_end)) {
  286. return IMG_PARSER_ERR_FORMAT;
  287. }
  288. p = pk_end;
  289. /*
  290. * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
  291. * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
  292. * -- technically these contain BIT STRINGs but that is not worth
  293. * -- validating
  294. */
  295. for (int i = 1; i < 3; i++) {
  296. ret = mbedtls_asn1_get_tag(&p, end, &len,
  297. MBEDTLS_ASN1_CONTEXT_SPECIFIC |
  298. MBEDTLS_ASN1_CONSTRUCTED | i);
  299. /*
  300. * Unique IDs are obsolete, so MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
  301. * is the common case.
  302. */
  303. if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
  304. if (ret != 0) {
  305. return IMG_PARSER_ERR_FORMAT;
  306. }
  307. p += len;
  308. }
  309. }
  310. /*
  311. * extensions [3] EXPLICIT Extensions OPTIONAL
  312. * }
  313. *
  314. * X.509 and RFC5280 allow omitting the extensions entirely.
  315. * However, in TF-A, a certificate with no extensions would
  316. * always fail later on, as the extensions contain the
  317. * information needed to authenticate the next stage in the
  318. * boot chain. Furthermore, get_ext() assumes that the
  319. * extensions have been parsed into v3_ext, and allowing
  320. * there to be no extensions would pointlessly complicate
  321. * the code. Therefore, just reject certificates without
  322. * extensions. This is also why version 1 and 2 certificates
  323. * are rejected above.
  324. */
  325. ret = mbedtls_asn1_get_tag(&p, end, &len,
  326. MBEDTLS_ASN1_CONTEXT_SPECIFIC |
  327. MBEDTLS_ASN1_CONSTRUCTED | 3);
  328. if ((ret != 0) || (len != (size_t)(end - p))) {
  329. return IMG_PARSER_ERR_FORMAT;
  330. }
  331. /*
  332. * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
  333. * -- must use all remaining bytes in TBSCertificate
  334. */
  335. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
  336. MBEDTLS_ASN1_SEQUENCE);
  337. if ((ret != 0) || (len != (size_t)(end - p))) {
  338. return IMG_PARSER_ERR_FORMAT;
  339. }
  340. v3_ext.p = p;
  341. v3_ext.len = len;
  342. p += len;
  343. /* Check extensions integrity */
  344. ret = get_ext(NULL, NULL, NULL);
  345. if (ret != IMG_PARSER_OK) {
  346. return ret;
  347. }
  348. end = crt_end;
  349. /*
  350. * }
  351. * -- end of TBSCertificate
  352. *
  353. * signatureAlgorithm AlgorithmIdentifier
  354. * -- Does not need to be parsed. Ensuring it is bitwise
  355. * -- identical (including the tag!) with the first signature
  356. * -- algorithm is sufficient.
  357. */
  358. if ((sig_alg1.len >= (size_t)(end - p)) ||
  359. (0 != memcmp(sig_alg1.p, p, sig_alg1.len))) {
  360. return IMG_PARSER_ERR_FORMAT;
  361. }
  362. p += sig_alg1.len;
  363. memcpy(&sig_alg, &sig_alg1, sizeof(sig_alg));
  364. /*
  365. * signatureValue BIT STRING
  366. * } -- must consume all bytes
  367. */
  368. signature.p = p;
  369. ret = mbedtls_asn1_get_bitstring_null(&p, end, &len);
  370. if ((ret != 0) || ((p + len) != end)) {
  371. return IMG_PARSER_ERR_FORMAT;
  372. }
  373. signature.len = end - signature.p;
  374. return IMG_PARSER_OK;
  375. }
  376. /* Exported functions */
  377. static void init(void)
  378. {
  379. mbedtls_init();
  380. }
  381. /*
  382. * Wrapper for cert_parse() that clears the static variables used by it in case
  383. * of an error.
  384. */
  385. static int check_integrity(void *img, unsigned int img_len)
  386. {
  387. int rc = cert_parse(img, img_len);
  388. if (rc != IMG_PARSER_OK)
  389. clear_temp_vars();
  390. return rc;
  391. }
  392. /*
  393. * Extract an authentication parameter from an X509v3 certificate
  394. *
  395. * This function returns a pointer to the extracted data and its length.
  396. * Depending on the type of parameter, a pointer to the data stored in the
  397. * certificate may be returned (i.e. an octet string containing a hash). Other
  398. * data may need to be copied and formatted (i.e. integers). In the later case,
  399. * a buffer of the correct type needs to be statically allocated, filled and
  400. * returned.
  401. */
  402. static int get_auth_param(const auth_param_type_desc_t *type_desc,
  403. void *img, unsigned int img_len,
  404. void **param, unsigned int *param_len)
  405. {
  406. int rc = IMG_PARSER_OK;
  407. /* We do not use img because the check_integrity function has already
  408. * extracted the relevant data (v3_ext, pk, sig_alg, etc) */
  409. switch (type_desc->type) {
  410. case AUTH_PARAM_RAW_DATA:
  411. /* Data to be signed */
  412. *param = (void *)tbs.p;
  413. *param_len = (unsigned int)tbs.len;
  414. break;
  415. case AUTH_PARAM_HASH:
  416. case AUTH_PARAM_NV_CTR:
  417. /* All these parameters are included as X509v3 extensions */
  418. rc = get_ext(type_desc->cookie, param, param_len);
  419. break;
  420. case AUTH_PARAM_PUB_KEY:
  421. if (type_desc->cookie != NULL) {
  422. /* Get public key from extension */
  423. rc = get_ext(type_desc->cookie, param, param_len);
  424. } else {
  425. /* Get the subject public key */
  426. *param = (void *)pk.p;
  427. *param_len = (unsigned int)pk.len;
  428. }
  429. break;
  430. case AUTH_PARAM_SIG_ALG:
  431. /* Get the certificate signature algorithm */
  432. *param = (void *)sig_alg.p;
  433. *param_len = (unsigned int)sig_alg.len;
  434. break;
  435. case AUTH_PARAM_SIG:
  436. /* Get the certificate signature */
  437. *param = (void *)signature.p;
  438. *param_len = (unsigned int)signature.len;
  439. break;
  440. default:
  441. rc = IMG_PARSER_ERR_NOT_FOUND;
  442. break;
  443. }
  444. return rc;
  445. }
  446. REGISTER_IMG_PARSER_LIB(IMG_CERT, LIB_NAME, init,
  447. check_integrity, get_auth_param);