Even if you’re not entirely sure what a TPM is, you probably know that if you want to use Windows 11, you need one.
More precisely, you need TPM 2.0 (although there is an official Microsoft workaround for getting by with TPM 1.2, the previous, incompatible version of the technology).
TPM is an abbreviation of trusted platform modulean encryption-and-cybersecurity gizmo invented by an industry association known as the TCG, short for trusted compute groupwhose controlling members, known as Promoters, include AMD, Cisco, Dell, Hewlett Packard Enterprise, HP, Huawei, IBM, Infineon, Intel, Juniper, Lenovo, Microsoft and Toyota.
TPMs are sometimes implemented as a miniature plug-in board (usually with 14 or 20 pins in two rows of 7 or 10) that plug into a designated TPM socket on your computer’s motherboard.
These types of hardware TPMs contain a small, dedicated coprocessor with its own secure storage that provides a variety of security-related functionality, including hardware random number generation, cryptographic key trust, and secure digital signatures.
Other TPMs work by building the functionality into your computer’s regular firmware, or even by running a software-level emulator.
Obviously, a software TPM running as a Unix daemon or a Windows service under your regular operating system is useful when you want to run multiple VMs, or virtual machines, to simulate multiple computers on one device. But a software TPM can’t be activated until your operating system loads, so you can’t use this solution to install Windows 11 on a computer without a TPM at the hardware or firmware level. Windows 11 insists you have a TPM ready and running before Windows boots itself.
It’s all about safety (and other things)
One reason for forcing users to have a TPM is to secure the boot process to prevent attackers from tampering with your BIOS or computer firmware and installing malware that loads before the operating system itself gets going.
Another more controversial reason for requiring a TPM, especially in consumer laptops, is to use it for what is known as DRM, or Digital Rights Management.
DRM is accepted by many people as a reasonable anti-piracy solution, but others oppose it because it can provide a way for sellers to lock or restrict your access to content of your choice.
Whether you welcome DRM or not (or just don’t care), or whether you think a TPM gives you a potentially harder-to-hack Windows system than a computer without a…
… is largely irrelevant, because Microsoft insists you have one to use Windows 11.
(There are hacks that claim to get around this requirement, but we can’t recommend these tricks, and even in virtual machines we’ve had unsatisfactory results trying them out.)
Simple security can be complex
Unfortunately, and as you’ve probably guessed, the small size of TPM hardware devices comes with an extraordinary complexity that makes it difficult for anyone, even the TCG itself, to create a compliant implementation that is free of bugs.
The TPM Library 2.0 specifications alone, which are only a small part of the hundreds of different TCG specification documents, come in four parts, split into six documents – confusingly there are two part 3’s and two part 4’s, one subpart consisting of documentation only, and the other extant from interleaved code and explanation.
To give you an idea of the scope of TPM 2.0, the official specification files at the time of writing [2023-03-07] Are:
Microsoft’s GitHub copy of the TCG “reference implementation” contains 5 MBytes of source code totaling about 100,000 lines of C, broken down into nearly 500 files.
In addition, you need to import some cryptographic algorithms from another library and compile them into your TPM code.
You can’t rely on cryptographic functions provided by your operating system, because a TPM chip is designed to work independently of the rest of your computer, so it doesn’t depend on anything that can be easily replaced, subverted, or unpatched.
By default, Microsoft’s source structure allows you to choose from LibTomCrypt, OpenSSL, and wolfSSL as your underlying code provider for symmetric encryption, hashing, and large number arithmetic. (Accurate calculations involving numbers with hundreds or thousands of decimal digits are required to implement public key encryption algorithms such as RSA and Elliptic Curve cryptography.)
Watch out for lurking bugs
Underneath all this complexity, of course, lurks an unknown number of bugs, including two CVE-numbered vulnerabilities discovered in November 2022 by researchers at security spelunking company Quarkslab.
(We don’t know if you pronounce that company name work plate or kworx lab; we suspect it’s the latter, but secretly hope it’s the former.)
Quarkslab, admittedly with a dramatic flourish, announced the bugs as follows (their emphasis and capitalization):
Two vulnerabilities found by Quarkslab in the TPM2.0 reference implementation and reported in November 2022 have now been made public and can affect billions of devices.
Who can be affected? Major Tech Vendors[, and] organizations using Enterprise PCs, many servers, and embedded systems with a TPM.
In fact, the official TPM Library 2.0 “Errata” bulletin contains numerous other bugs besides these two, but as far as we know, the vulnerabilities reported by Quarkslab are the only two to receive an official CVE designation: CVE-2023-1017 And CVE-2023-1018.
Loosely speaking, these bugs are two sides of the same encryption coin:
The reported vulnerabilities occur when processing malicious TPM 2.0 commands with encrypted parameters. Both vulnerabilities are in the
CryptParameterDecryptionfunction, which is defined in the Part 4: Support Routines – Code document. […]
One of the vulnerabilities is an out-of-bounds read identified as CVE-2023-1018. The second is an out of bounds write identified as CVE-2023-1017. These vulnerabilities can be activated from user-mode applications by sending malicious commands to a TPM 2.0 whose firmware is based on an affected TCG reference implementation.
More cases may be identified due to the ongoing analysis of the TPM Working Group and may result in a wider scope of potential vulnerabilities included in TCGVRT0007.
A “quick fix” for these bugs was quickly published
libtpmsa popular software-based TPM implementation that can be used to provide as many virtual TPMs as you want for multiple virtual machines:
The lines highlighted in green have been added as patches against the flaws and we will now quickly explain them.
The underlying problem with the unpatched code is that the function
CryptParameterDecryption() receives redundant and possibly inconsistent information about how much data to process when decoding the parameter buffer being sent.
The function parameter
bufferSize tells you the size of the memory buffer into which decoded data is written.
But the first two (or, depending on how the code is constructed, four) bytes of the buffer itself tell you how much space there is for decoded data.
The original code therefore takes those first bytes from the buffer and uses them as a counter to see how much actual data needs to be decrypted…
… without bothering to check whether two or four bytes are actually available
buffer (as indicated by
bufferSize) to start with.
This bug can result in a read overflowwith the code accessing bytes it shouldn’t, therefore the updated code now includes a pre-flight check if the buffer has enough bytes to store the count value.
Even if the buffer safely contains enough data for the length count, preventing a read buffer overflow, the original code consumes some of the
bufferSize bytes in it
bufferby extracting the bytes that indicate the decoding length and the
buffer pointer accordingly.
But the code does not lower the value of
bufferSize correspond to the fact that the
buffer pointer is now moved in memory.
(If you “burn” the top two cards of a pack before you start dealing in a deck, you no longer have 52 cards left – you’re down to 50; if you’re dealing a poker hand, you’re probably fine, but if you deal for a round of bridge, two of the players fall short.)
This bug can result in a write overflowwhere decoding continues past the end of the buffer and changes two or four bytes that could belong to another process in the TPM’s memory.
More patches required
In fact, those patches alone are not enough, as the TCG bulletin warned above, and the
libtpms code has already been updated again, although the additional patches have not yet made it into an official release:
This time, the also faulty “partner function”
CryptParameterEncryption() has also been updated.
As you can see above, the original version of the encryption feature didn’t even have one
bufferSize parameter, and always just grab the effective buffer length and calculate it via the
This meant that the function prototype had to be changed, which in turn meant that everywhere in the TPM code calling this function also needed an update.
Fortunately, the code paths to the previously buggy code are easy to trace backward and retrofit with the required additional security checks.
What must we do?
- Reference implementations are not always correct. If you have your own hardware or software products that rely on this TPM library code, you must patch it. Unfortunately, the TCG has not yet provided any patches for its own code, merely describing the type of changes it believes should be made. If you’re wondering where to start, the
libtpmsproject is a useful place to look, as the developers have already started digging out the dangerous points. (Work your way through at least
- If in doubt, ask your hardware vendor for information about vulnerabilities. For example, Lenovo has already provided some information about products containing TPM code based on the reference implementation, and where to find security bulletins to quantify your risk.
- Don’t let untrusted callers tell you how to manage memory. If you pass buffer pointers and sizes to trusted code, make sure you check and clean them as much as possible, even if there is a performance cost (e.g. copying buffers in controlled ways to memory that is arranged to meet your own security needs) , before processing the commands you need to run.