security-advisory-tfv-10.rst 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. Advisory TFV-10 (CVE-2022-47630)
  2. ================================
  3. +----------------+-------------------------------------------------------------+
  4. | Title | Incorrect validation of X.509 certificate extensions can |
  5. | | result in an out-of-bounds read. |
  6. +================+=============================================================+
  7. | CVE ID | `CVE-2022-47630`_ |
  8. +----------------+-------------------------------------------------------------+
  9. | Date | Reported on 12 Dec 2022 |
  10. +----------------+-------------------------------------------------------------+
  11. | Versions | v1.2 to v2.8 |
  12. | Affected | |
  13. +----------------+-------------------------------------------------------------+
  14. | Configurations | BL1 and BL2 with Trusted Boot enabled with custom, |
  15. | Affected | downstream usages of ``get_ext()`` and/or ``auth_nvctr()`` |
  16. | | interfaces. Not exploitable in upstream TF-A code. |
  17. +----------------+-------------------------------------------------------------+
  18. | Impact | Out-of-bounds read. |
  19. +----------------+-------------------------------------------------------------+
  20. | Fix Version | - `fd37982a19a4a291`_ "fix(auth): forbid junk after |
  21. | | extensions" |
  22. | | |
  23. | | - `72460f50e2437a85`_ "fix(auth): require at least one |
  24. | | extension to be present" |
  25. | | |
  26. | | - `f5c51855d36e399e`_ "fix(auth): properly validate X.509 |
  27. | | extensions" |
  28. | | |
  29. | | - `abb8f936fd0ad085`_ "fix(auth): avoid out-of-bounds read |
  30. | | in auth_nvctr()" |
  31. | | |
  32. | | Note that `72460f50e2437a85`_ is not fixing any |
  33. | | vulnerability per se but it is required for |
  34. | | `f5c51855d36e399e`_ to apply cleanly. |
  35. +----------------+-------------------------------------------------------------+
  36. | Credit | Demi Marie Obenour, Invisible Things Lab |
  37. +----------------+-------------------------------------------------------------+
  38. This security advisory describes a vulnerability in the X.509 parser used to
  39. parse boot certificates in TF-A trusted boot: it is possible for a crafted
  40. certificate to cause an out-of-bounds memory read.
  41. Note that upstream platforms are **not** affected by this. Only downstream
  42. platforms may be, if (and only if) the interfaces described below are used in a
  43. different context than seen in upstream code. Details of such context is
  44. described in the rest of this document.
  45. To fully understand this security advisory, it is recommended to refer to the
  46. following standards documents:
  47. - `RFC 5280`_, *Internet X.509 Public Key Infrastructure Certificate and
  48. Certificate Revocation List (CRL) Profile*.
  49. - `ITU-T X.690`_, *ASN.1 encoding rules: Specification of Basic Encoding Rules
  50. (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules
  51. (DER).*
  52. Bug 1: Insufficient certificate validation
  53. ------------------------------------------
  54. The vulnerability lies in the following source file:
  55. ``drivers/auth/mbedtls/mbedtls_x509_parser.c``. By design, ``get_ext()`` does
  56. not check the return value of the various ``mbedtls_*()`` functions, as
  57. ``cert_parse()`` is assumed to have guaranteed that they will always succeed.
  58. However, it passes the end of an extension as the end pointer to these
  59. functions, whereas ``cert_parse()`` passes the end of the ``TBSCertificate``.
  60. Furthermore, ``cert_parse()`` does not check that the contents of the extension
  61. have the same length as the extension itself. It also does not check that the
  62. extension block extends to the end of the ``TBSCertificate``.
  63. This is a problem, as ``mbedtls_asn1_get_tag()`` leaves ``*p`` and ``*len``
  64. undefined on failure. In practice, this results in ``get_ext()`` continuing to
  65. parse at different offsets than were used (and validated) by ``cert_parse()``,
  66. which means that the in-bounds guarantee provided by ``cert_parse()`` no longer
  67. holds. The result is that it is possible for ``get_ext()`` to read memory past
  68. the end of the certificate. This could potentially access memory with dangerous
  69. read side effects, or leak microarchitectural state that could theoretically be
  70. retrieved through some side-channel attacks as part of a more complex attack.
  71. Bug 2: Missing bounds check in ``auth_nvctr()``
  72. -----------------------------------------------
  73. ``auth_nvctr()`` does not check that the buffer provided is
  74. long enough to hold an ``ASN.1 INTEGER``. Since ``auth_nvctr()`` will only ever
  75. read 6 bytes, it is possible to read up to 6 bytes past the end of the buffer.
  76. Exploitability Analysis
  77. -----------------------
  78. Upstream TF-A Code
  79. ~~~~~~~~~~~~~~~~~~
  80. In upstream TF-A code, the only caller of ``auth_nvctr()`` takes its input from
  81. ``get_ext()``, which means that the second bug is exploitable, so is the first.
  82. Therefore, only the first bug need be considered.
  83. All standard chains of trust provided in TF-A source tree (that is, under
  84. ``drivers/auth/``) require that the certificate's signature has already been
  85. validated prior to calling ``get_ext()``, or any function that calls ``get_ext()``.
  86. Platforms taking their chain of trust from a dynamic configuration file (such as
  87. ``fdts/tbbr_cot_descriptors.dtsi``) are also safe, as signature verification will
  88. always be done prior to any calls to ``get_ext()`` or ``auth_nvctr()`` in this
  89. case, no matter the order of the properties in the file. Therefore, it is not
  90. possible to exploit this vulnerability pre-authentication in upstream TF-A.
  91. Furthermore, the data read through ``get_ext()`` only
  92. ever gets used by the authentication framework (``drivers/auth/auth_mod.c``),
  93. which greatly reduces the range of inputs it will ever receive and thus the
  94. impact this has. Specifically, the authentication framework uses ``get_ext()``
  95. in three cases:
  96. 1. Retrieving a hash from an X.509 certificate to check the integrity of a
  97. child certificate (see ``auth_hash()``).
  98. 2. Retrieving the signature details from an X.509 certificate to check its
  99. authenticity and integrity (see ``auth_signature()``).
  100. 3. Retrieving the security counter value from an X.509 certificate to protect
  101. it from unauthorized rollback to a previous version (see ``auth_nvctr()``).
  102. None of these uses authentication framework write to the out-of-bounds memory,
  103. so no memory corruption is possible.
  104. In summary, there are 2 separate issues - one in ``get_ext()`` and another one
  105. in ``auth_nvctr()`` - but neither of these can be exploited in the context of
  106. TF-A upstream code.
  107. Only in the following 2 cases do we expect this vulnerability to be triggerable
  108. prior to authentication:
  109. - The platform uses a custom chain of trust which uses the non-volatile counter
  110. authentication method (``AUTH_METHOD_NV_CTR``) before the cryptographic
  111. authentication method (``AUTH_METHOD_SIG``).
  112. - The chain of trust uses a custom authentication method that calls
  113. ``get_ext()`` before cryptographic authentication.
  114. Custom Image Parsers
  115. ~~~~~~~~~~~~~~~~~~~~
  116. If the platform uses a custom image parser instead of the certificate parser,
  117. the bug in the certificate parser is obviously not relevant. The bug in
  118. ``auth_nvctr()`` *may* be relevant, but only if the returned data is:
  119. - Taken from an untrusted source (meaning that it is read prior to
  120. authentication).
  121. - Not already checked to be a primitively-encoded ASN.1 tag.
  122. In particular, if the custom image parser implementation wraps a 32-bit integer
  123. in an ASN.1 ``INTEGER``, it is not affected.
  124. .. _CVE-2022-47630: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-47630
  125. .. _fd37982a19a4a291: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=fd37982a19a4a291
  126. .. _72460f50e2437a85: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=72460f50e2437a85
  127. .. _f5c51855d36e399e: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=f5c51855d36e399e
  128. .. _abb8f936fd0ad085: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=abb8f936fd0ad085
  129. .. _RFC 5280: https://www.ietf.org/rfc/rfc5280.txt
  130. .. _ITU-T X.690: https://www.itu.int/ITU-T/studygroups/com10/languages/X.690_1297.pdf