In this blog post we discuss the details of two vulnerabilities we discovered in the Trusted Platform Module (TPM) 2.0 reference implementation code. These two vulnerabilities, an out-of-bounds write (CVE-2023-1017) and an out-of-bounds read (CVE-2023-1018), affected several TPM 2.0 software implementations (such as the ones used by virtualization software) as well as a number of hardware TPMs.
In October 2021, Microsoft released Windows 11. One of the installation requirements that stood out was the need for a Trusted Platform Module (TPM) 2.0. An implication of this requirement is that, in order to be able to run Windows 11 within a virtual machine, virtualization software must provide a TPM to VMs, either by doing passthrough to the hardware TPM on the host machine, or by supplying a virtual TPM to them.
We found this to be an interesting topic for vulnerability research, since the addition of virtual TPMs means extended attack surface on virtualization software that can be reached from within a guest, and so it could potentially be used for a virtual machine escape. As a result of the research effort, we discovered two security issues: an out-of-bounds write identified as CVE-2023-1017, and an out-of-bounds read identified as CVE-2023-1018. They can be triggered from user-mode applications by sending malicious TPM 2.0 commands with encrypted parameters. Interestingly, these two vulnerabilities turned out to have a way longer reach than we initially thought: given that they originate in the reference implementation code published by the Trusted Computing Group (TCG for short, the nonprofit organization that publishes and maintains the TPM specification), these security bugs affected not only every virtualization software we tested, but hardware implementations as well.
Note that most of our assessments in this blog post (e.g. regarding exploitability, impact, or which platforms are affected) are based on our analysis of software-based virtual TPMs, because we can debug them in an easy way to perform dynamic analysis (well, debugging Hyper-V's virtual TPM is harder because it runs as an IUM process, but that's another story). On the contrary, getting visibility of what's happening at runtime in the firmware of a TPM, running in a separate chip without debugging interfaces, is an entirely different problem to tackle. Even doing static analysis of the firmware of a hardware TPM proved to be difficult: the few TPM firmware updates we attempted to analyze happened to be encrypted. Therefore, the lack of specific assessment on hardware TPMs doesn't mean that they are not affected; it just means that we couldn't evaluate how most of them are impacted due to the lack of observability. However, using the Proof-of-Concept code published in this blog post, we have verified that at least some discrete TPM chips are vulnerable. After attempting the OOB write, the chip would stop responding (i.e. it didn't recognize commands anymore) and require a hard reboot of the computer to be operational again, thus confirming its vulnerable condition.
This is a non-exhaustive list of affected software and hardware platforms. Products listed here are those in which we could certainly demonstrate the existence of the vulnerabilities with the help of the PoC provided within this blog post, but it's very likely for other TPMs - either virtual or physical- to be vulnerable as well.
- The vulnerable code was present in the latest available version (at the time we performed our research) of the TPM 2.0 reference implementation: Trusted Platform Module Library Specification, Family "2.0", Level 00, Revision 01.59 – November 2019;
- Microsoft Hyper-V on Windows 10 (affected module:
- VMware Workstation version 16.2.4 build-20089737 (affected module:
tpm2emu.exe- no version information in the executable);
- Libtpms/SWTPM, used by Qemu and VirtualBox (compiled from the master branch, commit
- Nuvoton hardware TPM (firmware version: 22.214.171.124);
- In general, all TPMs 2.0 whose firmware is based on the Trusted Computing Group reference implementation code are expected to be affected.
A threat to cloud computing
All the major cloud computing providers offer instances with virtual TPMs. This exposes an interesting scenario, since a malicious actor could attempt to exploit these vulnerabilities in the virtual TPM in order to escape from a virtual machine and compromise the host system.
- Amazon AWS has NitroTPM;
- Microsoft Azure provides virtual TPMs as part of Trusted Launch;
- Google Cloud offers virtual TPMs as part of Shielded VMs;
- Oracle Cloud Infrastructure provides virtual TPMs as part of Shielded Instances.
Those providers using a virtual TPM based on the TCG reference implementation are expected to be vulnerable. In the case of Google Cloud, the blog post linked above mentions that the core of their virtual TPM comes from code published by IBM, which is extracted automatically from the full source code of the TPM 2.0 spec, and we verified that the bugs in the
CryptParameterDecryption function are present in it. In the case of Microsoft Azure, the documentation linked before mentions that their virtual TPM is "compliant with the TPM 2.0 spec", and we have verified that the virtual TPM included in the version of Hyper-V that is available on Windows 10 is indeed vulnerable. The bugs were also present in Microsoft's open source reference implementation.
Regarding Amazon AWS and Oracle Cloud Infrastructure, we don't have much details about what they use, except that the NitroTPM documentation mentions that it "conforms to the TPM 2.0 specification" with a link to the TCG website.
- The Trusted Computing Group published errata version 1.4 for TCG Trusted Platform Module Library, with suggested fixes for the two bugs.
- Microsoft patched the bugs in Hyper-V in their March, 2023 security update. Their assessment of impact for the OOB write is low in TPM 2.0 in Pluton/HCL/Overlake/Manticore standard server for Azure because the overwrite is only 2 bytes and their team have not identified a consistent and easily achievable way to obtain EoP or RCE with only 2 bytes.
- Microsoft also patched their open source reference implementation with commit 9bdd9f0aaba5e54b3c314cfff02cf532281a067e.
- VMware is expected to issue fixes for the bugs in April, 2023.
- Libtpms patched the bugs in commit 324dbb4c27ae789c73b69dbf4611242267919dd4.
- Chromium OS patched the vulnerabilities in commit 3b87ed233acb4c76c27872e1ac0b74dc032199f1.
- IBM patched their open source implementation in commit 102893a5f45dbb0b0ecc0eb52a8dd4defe559f92.
- Nuvoton published security advisory SA-003 for their NPCT65x TPM chip.
- Lenovo published security advisory LEN-118320 regarding affected products using said Nuvoton TPM.
Check the website of your computer manufacturer for TPM firmware updates.
A primer on TPM encrypted parameters
As described in the Trusted Platform Module Library Specification, Family 2.0, Part 1: Architecture document, Section 21 - "Session-based encryption", several TPM 2.0 commands have parameters that may need to be encrypted going to or from the TPM. Session-based encryption may be used to ensure confidentiality of these parameters. Quoting the specification:
A TPM 2.0 command with encrypted parameters is composed of a base command header, followed by a
handleArea, then a
sessionArea, finishing with the (encrypted)
parameterArea. The following diagram illustrates said structure:
In the TPM 2.0 reference implementation, the
ExecuteCommand function in
ExecCommand.c checks that the
authorizationSize field of the
sessionArea is at least
9 (). After that, at , it calculates the start of the
parameterArea (located right after the
sessionArea) and saves it to the
parmBufferStart variable. At
 it calculates the size of the
parameterArea, and saves it to the
parmBufferSize variable. Then it calls
ParseSessionBuffer() (), passing
parmBufferSize as parameters (, ).
SessionProcess.c parses the
sessionArea of the command. If a session has the
Decrypt attribute set (), and if the command code allows for parameter encryption, then
CryptParameterDecryption() (), propagating the
parmBufferSize () and
parmBufferStart () parameters:
Vulnerabilities in the CryptParameterDecryption function
CryptUtil.c performs in-place decryption of an encrypted command parameter.
Two security issues arise in this function:
- Bug #1 - OOB read (CVE-2023-1018): At , the function uses the
BYTE_ARRAY_TO_UINT16macro to read a 16-bit field (
cipherSize) from the buffer pointed by
parmBufferStartwithout checking if there's any parameter data past the session area. The only length check was performed earlier in function
ExecuteCommand, but that check only verified that the
sessionAreaof the command is at least 9 bytes in size. As a result, if a malformed command doesn't contain a
sessionArea, it will trigger an out-of-bounds memory read, making the TPM access memory past the end of the command.
Note that the
BYTE_ARRAY_TO_UINT16 macro doesn't perform any bounds check:
UINT16_Unmarshal function should have been used instead, which performs proper size checks before reading from a given buffer.
- Bug #2 - OOB write (CVE-2023-1017): If a proper
parameterAreais provided (avoiding bug #1), the first two bytes of the
parameterAreaare interpreted as the size of the data to be decrypted (
cipherSizevariable at ). Right after reading
cipherSize, at , the
bufferpointer is advanced by 2. At  there's a sanity check (if the
cipherSizevalue is greater than the actual buffer size, then it bails out), but there's a problem here: after reading the
cipherSize16-bit field and advancing the
bufferpointer by 2, the function forgets to subtract 2 from
bufferSize, to account for the two bytes that were already processed. Therefore, it is possible to successfully pass the sanity check at  with a
cipherSizevalue that is, in fact, larger by 2 than the actual size of the remaining data. As a consequence, when either
ParmDecryptSym()functions are called (at  and , respectively) to actually decrypt the data in the
cipherSizefield, the TPM ends up writing 2 bytes past the end of the buffer, resulting in an out-of-bounds write.
An OOB write of just 2 bytes may not seem like a very powerful primitive at first, but remember that last year our colleagues Damiano Melotti and Maxime Rossi Bellom managed to obtain code execution on Google's Titan M chip with an OOB write of a single byte with value
1) OOB read: function
CryptUtil.c can read 2 bytes past the end of the received TPM command. If an affected TPM doesn't zero out the command buffer between received commands, it can result in the affected function reading whatever 16-bit value was already there from the previous command. This is dependent on the implementation: for example, VMware doesn't clear out the command buffer between requests, so the OOB read can access whatever value is already there from the previous command; on the contrary, Hyper-V's virtual TPM pads the unused bytes in the command buffer with zeros every time it receives a request, so the OOB access ends up reading just zeros.
2) OOB write: functions
CryptUtil.c (called from
CryptParameterDecryption) can write 2 bytes past the end of the command buffer, resulting in memory corruption.
This second bug is definitely the most interesting one. The chances of being able to overwrite something useful depend on how each implementation allocates the buffer that receives TPM commands. As an example:
- VMware uses an oversized buffer of size 0x10000, way bigger than the usual maximum TPM command size of 0x1000 bytes;
- Hyper-V uses a static variable of size 0x1000 as the command buffer;
- SWTPM uses
malloc()to allocate a command buffer of size 0x1008 (8 bytes for a
send command prefixthat can be used to modify the
locality, plus 0x1000 bytes for the maximum TPM command size).
Therefore, the chances of having something useful adjacent to the command buffer that we can overwrite with the OOB write are really implementation-dependent. All the three virtual TPMs mentioned above use a completely different approach for allocating the command buffer. In a similar way, the likeliness of having something useful to overwrite located right after the command buffer in the firmware of a given hardware TPM depends entirely on how that specific hardware vendor allocates the buffer that holds incoming commands.
Triggering the bugs
In order to reproduce any of the 2 bugs described above, it is necessary to send 2 commands to the target TPM. In both cases, the first command must be a
TPM2_StartAuthSession command, to start an authorization session. For simplicity, we can specify
TPM_ALG_XOR as the symmetric algorithm to be used. As a result, we get a TPM response containing a session handle.
After that, we need to send a command that supports parameter encryption. We used
TPM2_CreatePrimary, although a few other commands should probably work as well. We pass the session handle obtained in the previous step in the
sessionArea of the
TPM2_CreatePrimary command, and we set the
Decrypt flag in the
sessionAttributes field. Then:
- To reproduce bug #1 (OOB read), we send the
TPM2_CreatePrimarycommand with a minimal valid
sessionArea, and no data after it, i.e. with a missing
- To reproduce bug #2 (OOB write), we send the
TPM2_CreatePrimarycommand with its total size equal to the maximum supported TPM command size (
0x1000bytes). In this case we do include a
parameterArea, with the
cipherSizefield set to
0x1000 - sizeof(command_base_header) - sizeof(handleArea) - sizeof(sessionArea)), followed by
0xfe3bytes with any value (filling the place of the encrypted parameter) to complete the
0x1000bytes of the whole
You can download here a Proof-of-Concept to reproduce both vulnerabilities. The
.zip file contains a Python version of the PoC, meant to be run on Linux systems, and a C version in case you intend to run it from a Windows machine.
We discovered two security issues in the code of the TPM 2.0 reference implementation: an out-of-bounds read and an out-of-bounds write. As a result, every TPM (either software or hardware implementations) whose firmware is based on the reference code published by the Trusted Computing Group is expected to be affected.
Interestingly, although all affected TPMs share the exact same vulnerable function, which stems from the reference implementation code, the likeliness of successful exploitation depends on how the command buffer is implemented, and that part is left to each implementation. From what we saw, everyone seems to handle it in a different way: some clear out the command buffer between received requests, but others don't; some allocate the command buffer in the heap via
malloc(), while others use a global variable for it.
We were able to verify that these vulnerabilities are present in the software TPMs included in major desktop virtualization solutions such as VMware Workstation, Microsoft Hyper-V and Qemu. Virtual TPMs available in the biggest cloud computing providers were also likely affected. For instance, Google Cloud uses code published by IBM automatically extracted from the TCG reference implementation, and we verified that the bugs were present in the code provided by IBM. In the case of Microsoft Azure, we already mentioned that Hyper-V on Windows 10 is affected, and since the Azure hypervisor is based on Hyper-V, we expect these two vulnerabilities to be present on Microsoft's cloud platform as well.
Finally, we expect most TPM hardware vendors to be affected too. The lack of a debugging setup to get visibility on what's going on in the TPM firmware at runtime makes it harder to confirm the presence of the vulnerabilities in a physical chip. Static analysis could be an alternative to assess whether a hardware TPM is vulnerable or not, but in the few TPM firmware updates we managed to get our hands on were encrypted.
I'd like to thank Iván Arce, for the lot of valuable inputs and ideas he provided while discussing these bugs, as well as for taking care of handling such a complicated disclosure process with so many parties involved.
This timeline is not exhaustive and only lists events that we deemed relevant to the disclosure process.
- 2022-11-24 Quarkslab sent the vulnerability report to VMWare.
- 2022-11-24 Quarkslab sent the vulnerability report and PoC to Microsoft.
- 2022-11-24 VMWare acknowledged the report.
- 2022-11-25 Quarkslab notified CERT/CC of vulns in TCG TPM2 reference implementation, and opened a case in the VINCE portal. The vulnerabilities are tracked as VU#782720.1 and VU#782720.2.
- 2022-11-28 Quarkslab notified CERT-FR of vulns in TCG TPM2 reference implementation.
- 2022-11-28 CERT-FR, CERT/CC and Google acknowledged the report.
- 2022-11-28 Quarkslab filed the vulnerability report in Google's security issue tracker stating that since their virtual TPM (vTPM) for Google Cloud Platform Shielded VMs uses the reference implementation, it is likely vulnerable.
- 2022-11-28 CERT/CC asked if a date is set for disclosure of the bugs.
- 2022-11-28 Quarkslab informed CERT/CC, VMWare and Google that the disclosure date was set to February 28th, 2023.
- 2022-11-28 Google requested a Proof-of-Concept program for Linux.
- 2022-11-28 Quarkslab sent Linux PoC to Google.
- 2022-11-29 Quarkslab sent the vulnerability report to STMicroelectronics, an automated acknowledgement was received.
- 2022-11-29 CERT/CC communicated to all vendors that it reserved two CVE IDs to identify the vulnerabilities.
- 2022-11-29 Google asked if the report was sent to the Trusted Computing Group and if the vulnerability is under a coordinated embargo, as it wanted to push a fix to public code and executables.
- 2022-11-29 Microsoft told Quarkslab that the report met their criteria for security servicing.
- 2022-11-29 Quarkslab told Google that the disclosure date was set to February 28th, 2023 to let other vendors work on fixes, as it is likely that vendors of TPM hardware will require more time to release fixed firmware, that CERT/CC has contacted the TCG and to discuss disclosure with other vendor on CERT's VINCE portal.
- 2022-11-29 Cisco indicated that it started tracking the report internally.
- 2022-12-02 Quarkslab noticed that more than 1600 vendors (up from 43 the prior day) had access to the vulnerability report on the VINCE portal and asked CERT/CC if it was a mistake or as intended.
- 2022-12-02 CERT/CC clarified that expanding access to all registered vendors was as intended because several PC OEM and hardware vendors expressed interest in reaching out to other vendors up and down their supply chain.
- 2022-12-02 Quarkslab told CERT/CC that the probability of information about the vulnerabilities being leaked is now considered significantly higher, and they should make preparations for that scenario.
- 2022-12-02 Aruba Networks asked if there was a PoC program for Linux, Quarkslab provided all parties with a PoC in Python that uses
/dev/tpm0to communicate with the TPM.
- 2022-12-02 Intel indicated that it was investigating the report.
- 2022-12-02 Fujistu PSIRT asked if Quarkslab analyzed TPM chips, Quarkslab replied that hardware TPMs were not analyzed due to lack of debugging or monitoring capabilities to determine what is running inside of them to find out if the bugs are triggered.
- 2022-12-04 Nuvoton indicated that current versions of their TPM chip firmware are not affected.
- 2022-12-05 Trusted Computing Group VRT indicated that it was tracking the issue and coordinating triage with TPM Group co-chairs.
- 2022-12-05 SUSE Linux identified
libtpmsas affected and asked if the maintainers were notified.
- 2022-12-05 Quarkslab replied to SUSE Linux saying that it had not notified the
libtpmsmaintainers and deferred to CERT/CC for coordination with them.
- 2022-12-05 CERT/CC indicated that it had notified the IBM security group, which owns the vulnerable code.
- 2022-12-05 Google notified Quarkslab that they've shared the PoC internally, forwarded comments about disclosure to the appropriate team and were in contact with Trusted Computing Group and would coordinate with them as appropriate.
- 2022-12-05 Quarkslab asked Google if it had an estimated date for the rollout of fixes, and if it planned to issue fixes for the vTPM code in GCP only or also to any externally visible code.
- 2022-12-05 The TCG notified all vendors that their Vulnerability Response Team (VRT) was engaged on the issue and reached out to the TPM Group co-chairs for triaging the report and would provide actionable information when available.
- 2022-12-05 A CERT notified all parties that information about the vulnerabilities was publicly available on the issue tracker of a China-based Linux distribution.
- 2022-12-06 CERT/CC notified all parties that upon their request the China-based Linux distribution had removed public access to the issues leaking the vulnerabilities. The coordinated disclosure date remains February 28th, 2023 and CERT/CC reminded everyone not to disclosure the issues publicly and to communicate the private nature of the report to any third parties that may receive the information.
- 2022-12-07 Conference call between CERT/CC and Quarkslab to discuss how to proceed in light of the leak, both parties agree to not modify the planned disclosure date and try to speed up the vendor's processes to release fixes. CERT/CC requested permission to share the PoC programs with the US DHS CISA Threats team. Quarkslab granted permission.
- 2022-12-07 Microsoft asked Quarkslab for additional information to reproduce the bugs.
- 2022-12-08 CERT-JP said it had notified multiple vendors in Japan making them aware of the embargo date.
- 2022-12-09 Quarkslab provided a new version of the PoC programs for Linux and Windows on CERT/CC's VINCE portal.
- 2022-12-12 Quarkslab asked Google for an update and estimated date to release fixes.
- 2022-12-13 Crestron Electronics asked if an output of
DeviceIOControl error 87 (Invalid Parameter)of the Windows PoC indicates that the TPM is not vulnerable. Quarkslab replied that the error message revealed a bug in the PoC(!) that will be fixed shortly, and that determining if a given TPM chip is vulnerable or not without any log or debugging capabilities is difficult and without source code access it is only possible to do it by reverse engineering firmware which is a very time-consuming effort.
- 2022-12-13 Siemens asked if the vulnerabilities were present in previous versions of TCG's TPM and if implementations of older versions are also affected. Quarkslab explained that the vulnerabilities were found in the code included in the TPM2.0 specification document and that they are present in all of IBM's
ibmswtpm2TPM2.0 reference implementation releases dating back to at least March 21st, 2017. Therefore any implementation of TPM2.0 based on them is likely affected. Quarkslab did not check any TPM1.2 implementation.
- 2022-12-14 Infineon stated that Infineon TPM chips are NOT affected by the reported issues.
- 2022-12-14 Microsoft reiterated their request for additional information to reproduce the bugs.
- 2022-12-16 Quarkslab updated the PoC programs for Linux and Windows fixing a bug that prevented testing certain TPMs.
- 2022-12-16 Quarkslab asked Google for an update and answers to the questions sent previously on Dec. 5th and 12th. Also notified Google that it found out that a fix for the vulns we reported was committed to the Chromium OS TPM2 code on December 1st, and that since the repository is publicly visible, Quarkslab considered knowledge about the existence of the bugs to be public now. Asked Google for their plan to roll out these fixes to supported devices.
- 2022-12-16 Quarkslab provided Microsoft a detailed description of how to debug the vTPM in Hyper-V to reproduce the bugs.
- 2022-12-16 Microsoft confirmed that it could reproduce the bugs. Quarkslab noted that they should coordinate disclosure with CERT/CC and the TCG.
- 2022-12-18 Google said they were with the proposed February 28, 2023 embargo date, and that were working with TCG and CERT to resolve the issue, and would get back with an answer to the remaining question as soon as they have one.
- 2022-12-19 Microsoft asked if it would be possible to coordinate disclosure for April 2023, to align with their security release of that month. Quarkslab replied that disclosure is being coordinated by CERT/CC, and that since other vendors are involved and a fix was already committed to a publicly available source code repository, it is more likely that the release of fixes and public disclosure will have to be accelerated rather than delayed. Suggested to discuss the matter with CERT/CC and other vendors.
- 2022-12-23 Quarkslab updated the PoC programs for Linux and Windows to query and print the manufacturer strings of the TPM implementation.
- 2022-12-26 Quarkslab updated the PoC programs for Linux and Windows to query and print the firmware version of the TPM implementation, also provided the output of a run of the PoC identifying a vulnerable chip.
- 2023-01-03 Google VRP informed that the bugs do not meet criteria for a reward, as they don't affect Google products but nonetheless passed the report to Chrome VRP for further evaluation.
- 2023-01-05 Google followed up indicating that while they consider the code changes to be public, they do not consider them to break embargo per discussion with CERT and TCG. Also that they cannot provide an answer to the question about their plan to roll out fixes to their devices.
- 2023-01-09 VMware asked if the disclosure date could be extended until the end of March or April.
- 2023-01-16 Quarkslab replied to VMware stating that the vulnerabilities should be considered public knowledge and the disclosure process involved multiple vendors as well as CERT and TCG, so it would be difficult to move it but they should discuss with them.
- 2023-01-16 Quarkslab asked Google VRP to clarify if the bugs are eligible because Google products aren't affected, are affected but not exploitable, or are in a third-party component. Noted that the fix committed in the Chromium OS repository seemed to indicate that at least one product was affected.
- 2023-01-17 Google replied that the issue was sent to the VRP panel for reconsideration.
- 2023-01-17 Chrome VRP informed that they were considering the issue. Gave access to the corresponding entry in their (separate) bug tracking system.
- 2023-01-17 Quarkslab gets access to the issue in the Chromium bug tracker. The entry, dated January 4th, indicated that the bugs were reported externally, were fixed, and their analysis deemed them not exploitable.
- 2023-02-01 STMicroelectronics reported that their products are not affected...
- 2023-02-02 Chrome VRP awards 20K USD for the bugs.
- 2023-02-08 Call with CERT to synchronize status and discuss further steps. Quarkslab agrees to publish technical details on March 14th, CERT and TCG will publish their security advisories and errata on February 28th.
- 2023-02-15 Microsoft informed that they will try to accelerate the release of the patches, and asked if they could preview the blog post to be published on March 14th.
- 2023-02-15 Quarkslab replied to Microsoft providing an updated PoC and agreed to send a draft of the blog post when it is ready.
- 2023-02-28 CERT/CC published their vulnerability note.
- 2023-02-28 Trusted Computing Group published their security advisory and errata.
- 2023-03-06 Nuvoton published a security advisory.
- 2023-03-06 Lenovo published a security advisory.
- 2023-03-06 libtpms added tests cases for the vulnerabilities.
- 2023-03-09 Microsoft committed a fix to their open source reference implementation.
- 2023-03-10 Draft of the blog post sent to Microsoft.
- 2023-03-13 Microsoft replied with their impact assessment for Azure servers.
- 2023-03-14 This blog post is published.