Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,13 @@
=====================================
Trusted Platform Module documentation
=====================================
.. toctree::
tpm_event_log
tpm-security
tpm_tis
tpm_vtpm_proxy
xen-tpmfront
tpm_ftpm_tee
tpm_ffa_crb
@@ -0,0 +1,216 @@
.. SPDX-License-Identifier: GPL-2.0-only
TPM Security
============
The object of this document is to describe how we make the kernel's
use of the TPM reasonably robust in the face of external snooping and
packet alteration attacks (called passive and active interposer attack
in the literature). The current security document is for TPM 2.0.
Introduction
------------
The TPM is usually a discrete chip attached to a PC via some type of
low bandwidth bus. There are exceptions to this such as the Intel
PTT, which is a software TPM running inside a software environment
close to the CPU, which are subject to different attacks, but right at
the moment, most hardened security environments require a discrete
hardware TPM, which is the use case discussed here.
Snooping and Alteration Attacks against the bus
-----------------------------------------------
The current state of the art for snooping the `TPM Genie`_ hardware
interposer which is a simple external device that can be installed in
a couple of seconds on any system or laptop. Recently attacks were
successfully demonstrated against the `Windows Bitlocker TPM`_ system.
Most recently the same `attack against TPM based Linux disk
encryption`_ schemes. The next phase of research seems to be hacking
existing devices on the bus to act as interposers, so the fact that
the attacker requires physical access for a few seconds might
evaporate. However, the goal of this document is to protect TPM
secrets and integrity as far as we are able in this environment and to
try to insure that if we can't prevent the attack then at least we can
detect it.
Unfortunately, most of the TPM functionality, including the hardware
reset capability can be controlled by an attacker who has access to
the bus, so we'll discuss some of the disruption possibilities below.
Measurement (PCR) Integrity
---------------------------
Since the attacker can send their own commands to the TPM, they can
send arbitrary PCR extends and thus disrupt the measurement system,
which would be an annoying denial of service attack. However, there
are two, more serious, classes of attack aimed at entities sealed to
trust measurements.
1. The attacker could intercept all PCR extends coming from the system
and completely substitute their own values, producing a replay of
an untampered state that would cause PCR measurements to attest to
a trusted state and release secrets
2. At some point in time the attacker could reset the TPM, clearing
the PCRs and then send down their own measurements which would
effectively overwrite the boot time measurements the TPM has
already done.
The first can be thwarted by always doing HMAC protection of the PCR
extend and read command meaning measurement values cannot be
substituted without producing a detectable HMAC failure in the
response. However, the second can only really be detected by relying
on some sort of mechanism for protection which would change over TPM
reset.
Secrets Guarding
----------------
Certain information passing in and out of the TPM, such as key sealing
and private key import and random number generation, is vulnerable to
interception which HMAC protection alone cannot protect against, so
for these types of command we must also employ request and response
encryption to prevent the loss of secret information.
Establishing Initial Trust with the TPM
---------------------------------------
In order to provide security from the beginning, an initial shared or
asymmetric secret must be established which must also be unknown to
the attacker. The most obvious avenues for this are the endorsement
and storage seeds, which can be used to derive asymmetric keys.
However, using these keys is difficult because the only way to pass
them into the kernel would be on the command line, which requires
extensive support in the boot system, and there's no guarantee that
either hierarchy would not have some type of authorization.
The mechanism chosen for the Linux Kernel is to derive the primary
elliptic curve key from the null seed using the standard storage seed
parameters. The null seed has two advantages: firstly the hierarchy
physically cannot have an authorization, so we are always able to use
it and secondly, the null seed changes across TPM resets, meaning if
we establish trust on the null seed at start of day, all sessions
salted with the derived key will fail if the TPM is reset and the seed
changes.
Obviously using the null seed without any other prior shared secrets,
we have to create and read the initial public key which could, of
course, be intercepted and substituted by the bus interposer.
However, the TPM has a key certification mechanism (using the EK
endorsement certificate, creating an attestation identity key and
certifying the null seed primary with that key) which is too complex
to run within the kernel, so we keep a copy of the null primary key
name, which is what is exported via sysfs so user-space can run the
full certification when it boots. The definitive guarantee here is
that if the null primary key certifies correctly, you know all your
TPM transactions since start of day were secure and if it doesn't, you
know there's an interposer on your system (and that any secret used
during boot may have been leaked).
Stacking Trust
--------------
In the current null primary scenario, the TPM must be completely
cleared before handing it on to the next consumer. However the kernel
hands to user-space the name of the derived null seed key which can
then be verified by certification in user-space. Therefore, this chain
of name handoff can be used between the various boot components as
well (via an unspecified mechanism). For instance, grub could use the
null seed scheme for security and hand the name off to the kernel in
the boot area. The kernel could make its own derivation of the key
and the name and know definitively that if they differ from the handed
off version that tampering has occurred. Thus it becomes possible to
chain arbitrary boot components together (UEFI to grub to kernel) via
the name handoff provided each successive component knows how to
collect the name and verifies it against its derived key.
Session Properties
------------------
All TPM commands the kernel uses allow sessions. HMAC sessions may be
used to check the integrity of requests and responses and decrypt and
encrypt flags may be used to shield parameters and responses. The
HMAC and encryption keys are usually derived from the shared
authorization secret, but for a lot of kernel operations that is well
known (and usually empty). Thus, every HMAC session used by the
kernel must be created using the null primary key as the salt key
which thus provides a cryptographic input into the session key
derivation. Thus, the kernel creates the null primary key once (as a
volatile TPM handle) and keeps it around in a saved context stored in
tpm_chip for every in-kernel use of the TPM. Currently, because of a
lack of de-gapping in the in-kernel resource manager, the session must
be created and destroyed for each operation, but, in future, a single
session may also be reused for the in-kernel HMAC, encryption and
decryption sessions.
Protection Types
----------------
For every in-kernel operation we use null primary salted HMAC to
protect the integrity. Additionally, we use parameter encryption to
protect key sealing and parameter decryption to protect key unsealing
and random number generation.
Null Primary Key Certification in Userspace
===========================================
Every TPM comes shipped with a couple of X.509 certificates for the
primary endorsement key. This document assumes that the Elliptic
Curve version of the certificate exists at 01C00002, but will work
equally well with the RSA certificate (at 01C00001).
The first step in the certification is primary creation using the
template from the `TCG EK Credential Profile`_ which allows comparison
of the generated primary key against the one in the certificate (the
public key must match). Note that generation of the EK primary
requires the EK hierarchy password, but a pre-generated version of the
EC primary should exist at 81010002 and a TPM2_ReadPublic() may be
performed on this without needing the key authority. Next, the
certificate itself must be verified to chain back to the manufacturer
root (which should be published on the manufacturer website). Once
this is done, an attestation key (AK) is generated within the TPM and
it's name and the EK public key can be used to encrypt a secret using
TPM2_MakeCredential. The TPM then runs TPM2_ActivateCredential which
will only recover the secret if the binding between the TPM, the EK
and the AK is true. the generated AK may now be used to run a
certification of the null primary key whose name the kernel has
exported. Since TPM2_MakeCredential/ActivateCredential are somewhat
complicated, a more simplified process involving an externally
generated private key is described below.
This process is a simplified abbreviation of the usual privacy CA
based attestation process. The assumption here is that the
attestation is done by the TPM owner who thus has access to only the
owner hierarchy. The owner creates an external public/private key
pair (assume elliptic curve in this case) and wraps the private key
for import using an inner wrapping process and parented to the EC
derived storage primary. The TPM2_Import() is done using a parameter
decryption HMAC session salted to the EK primary (which also does not
require the EK key authority) meaning that the inner wrapping key is
the encrypted parameter and thus the TPM will not be able to perform
the import unless is possesses the certified EK so if the command
succeeds and the HMAC verifies on return we know we have a loadable
copy of the private key only for the certified TPM. This key is now
loaded into the TPM and the Storage primary flushed (to free up space
for the null key generation).
The null EC primary is now generated using the Storage profile
outlined in the `TCG TPM v2.0 Provisioning Guidance`_; the name of
this key (the hash of the public area) is computed and compared to the
null seed name presented by the kernel in
/sys/class/tpm/tpm0/null_name. If the names do not match, the TPM is
compromised. If the names match, the user performs a TPM2_Certify()
using the null primary as the object handle and the loaded private key
as the sign handle and providing randomized qualifying data. The
signature of the returned certifyInfo is verified against the public
part of the loaded private key and the qualifying data checked to
prevent replay. If all of these tests pass, the user is now assured
that TPM integrity and privacy was preserved across the entire boot
sequence of this kernel.
.. _TPM Genie: https://www.nccgroup.trust/globalassets/about-us/us/documents/tpm-genie.pdf
.. _Windows Bitlocker TPM: https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network
.. _attack against TPM based Linux disk encryption: https://www.secura.com/blog/tpm-sniffing-attacks-against-non-bitlocker-targets
.. _TCG EK Credential Profile: https://trustedcomputinggroup.org/resource/tcg-ek-credential-profile-for-tpm-family-2-0/
.. _TCG TPM v2.0 Provisioning Guidance: https://trustedcomputinggroup.org/resource/tcg-tpm-v2-0-provisioning-guidance/
@@ -0,0 +1,55 @@
.. SPDX-License-Identifier: GPL-2.0
=============
TPM Event Log
=============
This document briefly describes what TPM log is and how it is handed
over from the preboot firmware to the operating system.
Introduction
============
The preboot firmware maintains an event log that gets new entries every
time something gets hashed by it to any of the PCR registers. The events
are segregated by their type and contain the value of the hashed PCR
register. Typically, the preboot firmware will hash the components to
who execution is to be handed over or actions relevant to the boot
process.
The main application for this is remote attestation and the reason why
it is useful is nicely put in the very first section of [1]:
"Attestation is used to provide information about the platform’s state
to a challenger. However, PCR contents are difficult to interpret;
therefore, attestation is typically more useful when the PCR contents
are accompanied by a measurement log. While not trusted on their own,
the measurement log contains a richer set of information than do the PCR
contents. The PCR contents are used to provide the validation of the
measurement log."
UEFI event log
==============
UEFI provided event log has a few somewhat weird quirks.
Before calling ExitBootServices() Linux EFI stub copies the event log to
a custom configuration table defined by the stub itself. Unfortunately,
the events generated by ExitBootServices() don't end up in the table.
The firmware provides so called final events configuration table to sort
out this issue. Events gets mirrored to this table after the first time
EFI_TCG2_PROTOCOL.GetEventLog() gets called.
This introduces another problem: nothing guarantees that it is not called
before the Linux EFI stub gets to run. Thus, it needs to calculate and save the
final events table size while the stub is still running to the custom
configuration table so that the TPM driver can later on skip these events when
concatenating two halves of the event log from the custom configuration table
and the final events table.
References
==========
- [1] https://trustedcomputinggroup.org/resource/pc-client-specific-platform-firmware-profile-specification/
- [2] The final concatenation is done in drivers/char/tpm/eventlog/efi.c
@@ -0,0 +1,65 @@
.. SPDX-License-Identifier: GPL-2.0
========================
TPM CRB over FF-A Driver
========================
The TPM Command Response Buffer (CRB) interface is a standard TPM interface
defined in the TCG PC Client Platform TPM Profile (PTP) Specification [1]_.
The CRB provides a structured set of control registers a client uses when
interacting with a TPM as well as a data buffer for storing TPM commands and
responses. A CRB interface can be implemented in:
- hardware registers in a discrete TPM chip
- in memory for a TPM running in isolated environment where shared memory
allows a client to interact with the TPM
The Firmware Framework for Arm A-profile (FF-A) [2]_ is a specification
that defines interfaces and protocols for the following purposes:
- Compartmentalize firmware into software partitions that run in the Arm
Secure world environment (also know as TrustZone)
- Provide a standard interface for software components in the Non-secure
state, for example OS and Hypervisors, to communicate with this firmware.
A TPM can be implemented as an FF-A secure service. This could be a firmware
TPM or could potentially be a TPM service that acts as a proxy to a discrete
TPM chip. An FF-A based TPM abstracts hardware details (e.g. bus controller
and chip selects) away from the OS and can protect locality 4 from access
by an OS. The TCG-defined CRB interface is used by clients to interact
with the TPM service.
The Arm TPM Service Command Response Buffer Interface Over FF-A [3]_
specification defines FF-A messages that can be used by a client to signal
when updates have been made to the CRB.
How the Linux CRB driver interacts with FF-A is summarized below:
- The tpm_crb_ffa driver registers with the FF-A subsystem in the kernel
with an architected TPM service UUID defined in the CRB over FF-A spec.
- If a TPM service is discovered by FF-A, the probe() function in the
tpm_crb_ffa driver runs, and the driver initializes.
- The probing and initialization of the Linux CRB driver is triggered
by the discovery of a TPM advertised via ACPI. The CRB driver can
detect the type of TPM through the ACPI 'start' method. The start
method for Arm FF-A was defined in TCG ACPI v1.4 [4]_.
- When the CRB driver performs its normal functions such as signaling 'start'
and locality request/relinquish it invokes the tpm_crb_ffa_start() funnction
in the tpm_crb_ffa driver which handles the FF-A messaging to the TPM.
References
==========
.. [1] **TCG PC Client Platform TPM Profile (PTP) Specification**
https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
.. [2] **Arm Firmware Framework for Arm A-profile (FF-A)**
https://developer.arm.com/documentation/den0077/latest/
.. [3] **Arm TPM Service Command Response Buffer Interface Over FF-A**
https://developer.arm.com/documentation/den0138/latest/
.. [4] **TCG ACPI Specification**
https://trustedcomputinggroup.org/resource/tcg-acpi-specification/
@@ -0,0 +1,27 @@
=============================================
Firmware TPM Driver
=============================================
This document describes the firmware Trusted Platform Module (fTPM)
device driver.
Introduction
============
This driver is a shim for firmware implemented in ARM's TrustZone
environment. The driver allows programs to interact with the TPM in the same
way they would interact with a hardware TPM.
Design
======
The driver acts as a thin layer that passes commands to and from a TPM
implemented in firmware. The driver itself doesn't contain much logic and is
used more like a dumb pipe between firmware and kernel/userspace.
The firmware itself is based on the following paper:
https://www.microsoft.com/en-us/research/wp-content/uploads/2017/06/ftpm1.pdf
When the driver is loaded it will expose ``/dev/tpmX`` character devices to
userspace which will enable userspace to communicate with the firmware TPM
through this device.
@@ -0,0 +1,46 @@
.. SPDX-License-Identifier: GPL-2.0
=========================
TPM FIFO interface driver
=========================
TCG PTP Specification defines two interface types: FIFO and CRB. The former is
based on sequenced read and write operations, and the latter is based on a
buffer containing the full command or response.
FIFO (First-In-First-Out) interface is used by the tpm_tis_core dependent
drivers. Originally Linux had only a driver called tpm_tis, which covered
memory mapped (aka MMIO) interface but it was later on extended to cover other
physical interfaces supported by the TCG standard.
For historical reasons above the original MMIO driver is called tpm_tis and the
framework for FIFO drivers is named as tpm_tis_core. The postfix "tis" in
tpm_tis comes from the TPM Interface Specification, which is the hardware
interface specification for TPM 1.x chips.
Communication is based on a 20 KiB buffer shared by the TPM chip through a
hardware bus or memory map, depending on the physical wiring. The buffer is
further split into five equal-size 4 KiB buffers, which provide equivalent
sets of registers for communication between the CPU and TPM. These
communication endpoints are called localities in the TCG terminology.
When the kernel wants to send commands to the TPM chip, it first reserves
locality 0 by setting the requestUse bit in the TPM_ACCESS register. The bit is
cleared by the chip when the access is granted. Once it completes its
communication, the kernel writes the TPM_ACCESS.activeLocality bit. This
informs the chip that the locality has been relinquished.
Pending localities are served in order by the chip in descending order, one at
a time:
- Locality 0 has the lowest priority.
- Locality 5 has the highest priority.
Further information on the purpose and meaning of the localities can be found
in section 3.2 of the TCG PC Client Platform TPM Profile Specification.
References
==========
TCG PC Client Platform TPM Profile (PTP) Specification
https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
@@ -0,0 +1,50 @@
=============================================
Virtual TPM Proxy Driver for Linux Containers
=============================================
| Authors:
| Stefan Berger <stefanb@linux.vnet.ibm.com>
This document describes the virtual Trusted Platform Module (vTPM)
proxy device driver for Linux containers.
Introduction
============
The goal of this work is to provide TPM functionality to each Linux
container. This allows programs to interact with a TPM in a container
the same way they interact with a TPM on the physical system. Each
container gets its own unique, emulated, software TPM.
Design
======
To make an emulated software TPM available to each container, the container
management stack needs to create a device pair consisting of a client TPM
character device ``/dev/tpmX`` (with X=0,1,2...) and a 'server side' file
descriptor. The former is moved into the container by creating a character
device with the appropriate major and minor numbers while the file descriptor
is passed to the TPM emulator. Software inside the container can then send
TPM commands using the character device and the emulator will receive the
commands via the file descriptor and use it for sending back responses.
To support this, the virtual TPM proxy driver provides a device ``/dev/vtpmx``
that is used to create device pairs using an ioctl. The ioctl takes as
an input flags for configuring the device. The flags for example indicate
whether TPM 1.2 or TPM 2 functionality is supported by the TPM emulator.
The result of the ioctl are the file descriptor for the 'server side'
as well as the major and minor numbers of the character device that was created.
Besides that the number of the TPM character device is returned. If for
example ``/dev/tpm10`` was created, the number (``dev_num``) 10 is returned.
Once the device has been created, the driver will immediately try to talk
to the TPM. All commands from the driver can be read from the file descriptor
returned by the ioctl. The commands should be responded to immediately.
UAPI
====
.. kernel-doc:: include/uapi/linux/vtpm_proxy.h
.. kernel-doc:: drivers/char/tpm/tpm_vtpm_proxy.c
:functions: vtpmx_ioc_new_dev
@@ -0,0 +1,124 @@
=============================
Virtual TPM interface for Xen
=============================
Authors: Matthew Fioravante (JHUAPL), Daniel De Graaf (NSA)
This document describes the virtual Trusted Platform Module (vTPM) subsystem for
Xen. The reader is assumed to have familiarity with building and installing Xen,
Linux, and a basic understanding of the TPM and vTPM concepts.
Introduction
------------
The goal of this work is to provide a TPM functionality to a virtual guest
operating system (in Xen terms, a DomU). This allows programs to interact with
a TPM in a virtual system the same way they interact with a TPM on the physical
system. Each guest gets its own unique, emulated, software TPM. However, each
of the vTPM's secrets (Keys, NVRAM, etc) are managed by a vTPM Manager domain,
which seals the secrets to the Physical TPM. If the process of creating each of
these domains (manager, vTPM, and guest) is trusted, the vTPM subsystem extends
the chain of trust rooted in the hardware TPM to virtual machines in Xen. Each
major component of vTPM is implemented as a separate domain, providing secure
separation guaranteed by the hypervisor. The vTPM domains are implemented in
mini-os to reduce memory and processor overhead.
This mini-os vTPM subsystem was built on top of the previous vTPM work done by
IBM and Intel corporation.
Design Overview
---------------
The architecture of vTPM is described below::
+------------------+
| Linux DomU | ...
| | ^ |
| v | |
| xen-tpmfront |
+------------------+
| ^
v |
+------------------+
| mini-os/tpmback |
| | ^ |
| v | |
| vtpm-stubdom | ...
| | ^ |
| v | |
| mini-os/tpmfront |
+------------------+
| ^
v |
+------------------+
| mini-os/tpmback |
| | ^ |
| v | |
| vtpmmgr-stubdom |
| | ^ |
| v | |
| mini-os/tpm_tis |
+------------------+
| ^
v |
+------------------+
| Hardware TPM |
+------------------+
* Linux DomU:
The Linux based guest that wants to use a vTPM. There may be
more than one of these.
* xen-tpmfront.ko:
Linux kernel virtual TPM frontend driver. This driver
provides vTPM access to a Linux-based DomU.
* mini-os/tpmback:
Mini-os TPM backend driver. The Linux frontend driver
connects to this backend driver to facilitate communications
between the Linux DomU and its vTPM. This driver is also
used by vtpmmgr-stubdom to communicate with vtpm-stubdom.
* vtpm-stubdom:
A mini-os stub domain that implements a vTPM. There is a
one to one mapping between running vtpm-stubdom instances and
logical vtpms on the system. The vTPM Platform Configuration
Registers (PCRs) are normally all initialized to zero.
* mini-os/tpmfront:
Mini-os TPM frontend driver. The vTPM mini-os domain
vtpm-stubdom uses this driver to communicate with
vtpmmgr-stubdom. This driver is also used in mini-os
domains such as pv-grub that talk to the vTPM domain.
* vtpmmgr-stubdom:
A mini-os domain that implements the vTPM manager. There is
only one vTPM manager and it should be running during the
entire lifetime of the machine. This domain regulates
access to the physical TPM on the system and secures the
persistent state of each vTPM.
* mini-os/tpm_tis:
Mini-os TPM version 1.2 TPM Interface Specification (TIS)
driver. This driver used by vtpmmgr-stubdom to talk directly to
the hardware TPM. Communication is facilitated by mapping
hardware memory pages into vtpmmgr-stubdom.
* Hardware TPM:
The physical TPM that is soldered onto the motherboard.
Integration With Xen
--------------------
Support for the vTPM driver was added in Xen using the libxl toolstack in Xen
4.3. See the Xen documentation (docs/misc/vtpm.txt) for details on setting up
the vTPM and vTPM Manager stub domains. Once the stub domains are running, a
vTPM device is set up in the same manner as a disk or network device in the
domain's configuration file.
In order to use features such as IMA that require a TPM to be loaded prior to
the initrd, the xen-tpmfront driver must be compiled in to the kernel. If not
using such features, the driver can be compiled as a module and will be loaded
as usual.