Public bug reported:

[ Description ]

On Ubuntu 24.04/22.04 with FIPS mode enabled, the default libtpms0 0.9.3
package can fail TPM 2.0 cryptographic self-tests when run through
swtpm. After a failing self-test, the TPM enters failure mode and
rejects commands. This prevents libvirt/QEMU guests using an emulated
TPM from starting.

The issue appears to be that the libtpms 0.9.3 build enables algorithms
including TDES, Camellia, and RSAES. Under FIPS-enabled OpenSSL
configuration, the corresponding crypto operations are unavailable. When
the TPM self-test requests them, the test fails and libtpms puts the TPM
into failure mode.

[ Environment ]

* Ubuntu 24.04/22.04, FIPS mode enabled
* Kernel reports `/proc/sys/crypto/fips_enabled` as `1`
* OpenSSL 3.0.13, with `base` and `fips` providers active
* Original package: `libtpms0 0.9.3-0ubuntu4.24.04.1` (on Noble)
* swtpm and swtpm-tools: `0.7.3-0ubuntu5.24.04.1`(on Noble)
* TPM 2.0

[ Steps to Reproduce ]

Launch a Noble VM, enable FIPS mode, and install the relevant packages:

lxc launch ubuntu:24.04 fips --vm -c limits.cpu=1 -c limits.memory=4GiB
lxc shell fips

Attach pro token and enable fips mode:

pro attach <pro-token>
pro enable fips-updates
reboot

Install required packages:

lxc shell fips

add-apt-repository universe
apt install -y qemu-system-x86 qemu-utils \
  libvirt-daemon-system libvirt-clients libvirt-daemon-driver-qemu \
  virtinst cloud-image-utils libtpms0 swtpm swtpm-tools
apt update && apt upgrade

Start libvirt and its default network if needed:

systemctl enable --now libvirtd.socket
virsh -c qemu:///system list --all
virsh -c qemu:///system net-list --all

Run this only if the default network is inactive:
virsh -c qemu:///system net-start default

Download the Ubuntu 24.04 cloud image and create a fresh VM disk:
install -d /var/lib/libvirt/images
wget -O /var/lib/libvirt/images/noble-server-cloudimg-amd64.img \
  https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img

qemu-img create -f qcow2 -F qcow2 \
  -b /var/lib/libvirt/images/noble-server-cloudimg-amd64.img \
  /var/lib/libvirt/images/tpm-fips-original.qcow2 20G

Create cloud-init metadata for the disposable guest:

cat > /tmp/tpm-fips-original-user-data <<'EOF'
#cloud-config
users:
  - default
packages:
  - tpm2-tools
EOF

cat > /tmp/tpm-fips-original-meta-data <<'EOF'
instance-id: tpm-fips-original
local-hostname: tpm-fips-original
EOF

cloud-localds /var/lib/libvirt/images/tpm-fips-original-seed.iso \
  /tmp/tpm-fips-original-user-data \
  /tmp/tpm-fips-original-meta-data

Define and start a VM with a libvirt-managed TPM 2.0:

virt-install \
  --connect qemu:///system \
  --name tpm-fips-original \
  --memory 2048 \
  --vcpus 2 \
  --os-variant ubuntu24.04 \
  --import \
  --disk path=/var/lib/libvirt/images/tpm-fips-original.qcow2,format=qcow2 \
  --disk path=/var/lib/libvirt/images/tpm-fips-original-seed.iso,device=cdrom \
  --network network=default,model=virtio \
  --tpm type=emulator,version=2.0 \
  --graphics none \
  --console pty,target_type=serial \
  --noautoconsole

Capture the expected TPM initialization failure from the host logs:

tail -n 7 /var/log/swtpm/libvirt/qemu/tpm-fips-original-swtpm.log

Example output:

Successfully created NVRAM area 0x1c00016 for ECC EK certificate.
Successfully activated PCR banks sha256 among sha1,sha256,sha384,sha512.
Successfully authored TPM state.
Ending vTPM manufacturing @ Wed 14 Oct 2026 07:19:17 PM UTC
libtpms/tpm2: Entering failure mode; code: 6, location: TestRsaEncryptDecrypt 
line 414
libtpms/tpm2: TPM2_Process: Entered failure mode through command:
80 01 00 00 00 0b 00 00 01 43 01

[ Other Info ]

I built a modified `libtpms 0.9.3` package for Ubuntu 24.04 here:
https://launchpad.net/~dmarx11/+archive/ubuntu/libtpms-fips-host/, with
changes to exclude the unavailable operations using compile-time
options. The changes compile out TDES, Camellia, and RSAES, reject raw
RSA and SHA-1 signatures, disable RSA-1024 and ECC P-192, and skip the
raw-RSA self-test. During testing, I found a separate RSA-PSS signing
failure where OpenSSL rejected the signing context when padding was
configured before its requested digest, so I modified it to set the
digest first along with some temporary RSA error logging for debugging.

The package successfully manufactures the vTPM after the libvirt/QEMU
guest repro steps:

Successfully created EK certificate locally.
Successfully created NVRAM area 0x1c00016 for ECC EK certificate.
Successfully activated PCR banks sha256 among sha1,sha256,sha384,sha512.
Successfully authored TPM state.
Ending vTPM manufacturing @ Wed 14 Oct 2026 07:50:43 PM UTC

It also passes the manual self-test on the guest (step-by-step below)

Shut off the guest first:

virsh -c qemu:///system shutdown tpm-fips-original

Then install a public key:

install -d -m 700 /root/.ssh
if [[ ! -f /root/.ssh/tpm-fips4 ]]; then
    ssh-keygen -t rsa -b 3072 -N '' -f /root/.ssh/tpm-fips4
fi
PUBKEY=$(cat /root/.ssh/tpm-fips4.pub)

Add the test user and key to cloud-init:

cat > /tmp/tpm-fips-original-user-data <<EOF
#cloud-config
users:
  - default
  - name: tester
    groups: [adm, sudo]
    shell: /bin/bash
    sudo: ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_keys:
      - ${PUBKEY}
ssh_pwauth: false
packages:
  - tpm2-tools
EOF

cat > /tmp/tpm-fips-original-meta-data <<'EOF'
instance-id: tpm-fips-original-ssh
local-hostname: tpm-fips-original
EOF

Recreate the guest disk:

rm -- /var/lib/libvirt/images/tpm-fips-original.qcow2 \
       /var/lib/libvirt/images/tpm-fips-original-seed.iso

qemu-img create -f qcow2 -F qcow2 \
  -b /var/lib/libvirt/images/noble-server-cloudimg-amd64.img \
  /var/lib/libvirt/images/tpm-fips-original.qcow2 20G

cloud-localds /var/lib/libvirt/images/tpm-fips-original-seed.iso \
  /tmp/tpm-fips-original-user-data \
  /tmp/tpm-fips-original-meta-data

Start the guest again and obtain its IP:

virsh -c qemu:///system start tpm-fips-original
virsh -c qemu:///system net-dhcp-leases default

Example:

2026-10-14 20:51:06   52:54:00:d0:3c:5d   ipv4       192.168.122.227/24
tpm-fips-original

SSH onto guest:

GUEST_IP='192.168.122.227'
ssh -i /root/.ssh/tpm-fips4 tester@"$GUEST_IP"

Wait for cloud-init, then run the self-test:

sudo cloud-init status --wait
sudo tpm2_selftest -f
echo $? # should return 0 for success

** Affects: libtpms (Ubuntu)
     Importance: Undecided
     Assignee: Canonical Security Certification 
(canonical-security-certification)
         Status: New

** Description changed:

  [ Description ]
  
  On Ubuntu 24.04/22.04 with FIPS mode enabled, the default libtpms0 0.9.3
  package can fail TPM 2.0 cryptographic self-tests when run through
  swtpm. After a failing self-test, the TPM enters failure mode and
  rejects commands. This prevents libvirt/QEMU guests using an emulated
  TPM from starting.
  
  The issue appears to be that the libtpms 0.9.3 build enables algorithms
  including TDES, Camellia, and RSAES. Under FIPS-enabled OpenSSL
  configuration, the corresponding crypto operations are unavailable. When
  the TPM self-test requests them, the test fails and libtpms puts the TPM
  into failure mode.
  
  [ Environment ]
  
  * Ubuntu 24.04/22.04, FIPS mode enabled
  * Kernel reports `/proc/sys/crypto/fips_enabled` as `1`
  * OpenSSL 3.0.13, with `base` and `fips` providers active
  * Original package: `libtpms0 0.9.3-0ubuntu4.24.04.1` (on Noble)
  * swtpm and swtpm-tools: `0.7.3-0ubuntu5.24.04.1`(on Noble)
  * TPM 2.0
  
  [ Steps to Reproduce ]
  
  Launch a Noble VM, enable FIPS mode, and install the relevant packages:
  
  lxc launch ubuntu:24.04 fips --vm -c limits.cpu=1 -c limits.memory=4GiB
  lxc shell fips
  
  Attach pro token and enable fips mode:
  
  pro attach <pro-token>
  pro enable fips-updates
  reboot
  
  Install required packages:
  
  lxc shell fips
  
  add-apt-repository universe
  apt install -y qemu-system-x86 qemu-utils \
-   libvirt-daemon-system libvirt-clients libvirt-daemon-driver-qemu \
-   virtinst cloud-image-utils libtpms0 swtpm swtpm-tools
+   libvirt-daemon-system libvirt-clients libvirt-daemon-driver-qemu \
+   virtinst cloud-image-utils libtpms0 swtpm swtpm-tools
  apt update && apt upgrade
  
  Start libvirt and its default network if needed:
  
  systemctl enable --now libvirtd.socket
  virsh -c qemu:///system list --all
  virsh -c qemu:///system net-list --all
  
  Run this only if the default network is inactive:
  virsh -c qemu:///system net-start default
  
  Download the Ubuntu 24.04 cloud image and create a fresh VM disk:
  install -d /var/lib/libvirt/images
  wget -O /var/lib/libvirt/images/noble-server-cloudimg-amd64.img \
-   
https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
+   
https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
  
  qemu-img create -f qcow2 -F qcow2 \
-   -b /var/lib/libvirt/images/noble-server-cloudimg-amd64.img \
-   /var/lib/libvirt/images/tpm-fips-original.qcow2 20G
+   -b /var/lib/libvirt/images/noble-server-cloudimg-amd64.img \
+   /var/lib/libvirt/images/tpm-fips-original.qcow2 20G
  
  Create cloud-init metadata for the disposable guest:
  
  cat > /tmp/tpm-fips-original-user-data <<'EOF'
  #cloud-config
  users:
-   - default
+   - default
  packages:
-   - tpm2-tools
+   - tpm2-tools
  EOF
  
  cat > /tmp/tpm-fips-original-meta-data <<'EOF'
  instance-id: tpm-fips-original
  local-hostname: tpm-fips-original
  EOF
  
  cloud-localds /var/lib/libvirt/images/tpm-fips-original-seed.iso \
-   /tmp/tpm-fips-original-user-data \
-   /tmp/tpm-fips-original-meta-data
+   /tmp/tpm-fips-original-user-data \
+   /tmp/tpm-fips-original-meta-data
  
  Define and start a VM with a libvirt-managed TPM 2.0:
  
  virt-install \
-   --connect qemu:///system \
-   --name tpm-fips-original \
-   --memory 2048 \
-   --vcpus 2 \
-   --os-variant ubuntu24.04 \
-   --import \
-   --disk path=/var/lib/libvirt/images/tpm-fips-original.qcow2,format=qcow2 \
-   --disk path=/var/lib/libvirt/images/tpm-fips-original-seed.iso,device=cdrom 
\
-   --network network=default,model=virtio \
-   --tpm type=emulator,version=2.0 \
-   --graphics none \
-   --console pty,target_type=serial \
-   --noautoconsole
+   --connect qemu:///system \
+   --name tpm-fips-original \
+   --memory 2048 \
+   --vcpus 2 \
+   --os-variant ubuntu24.04 \
+   --import \
+   --disk path=/var/lib/libvirt/images/tpm-fips-original.qcow2,format=qcow2 \
+   --disk path=/var/lib/libvirt/images/tpm-fips-original-seed.iso,device=cdrom 
\
+   --network network=default,model=virtio \
+   --tpm type=emulator,version=2.0 \
+   --graphics none \
+   --console pty,target_type=serial \
+   --noautoconsole
  
  Capture the expected TPM initialization failure from the host logs:
  
  tail -n 7 /var/log/swtpm/libvirt/qemu/tpm-fips-original-swtpm.log
  
  Example output:
  
  Successfully created NVRAM area 0x1c00016 for ECC EK certificate.
  Successfully activated PCR banks sha256 among sha1,sha256,sha384,sha512.
  Successfully authored TPM state.
  Ending vTPM manufacturing @ Wed 14 Oct 2026 07:19:17 PM UTC
  libtpms/tpm2: Entering failure mode; code: 6, location: TestRsaEncryptDecrypt 
line 414
  libtpms/tpm2: TPM2_Process: Entered failure mode through command:
- 80 01 00 00 00 0b 00 00 01 43 01 
+ 80 01 00 00 00 0b 00 00 01 43 01
  
  [ Other Info ]
  
- I built a modified `libtpms 0.9.3` package for Ubuntu 24.04
- [here](https://launchpad.net/~dmarx11/+archive/ubuntu/libtpms-fips-
- host/), with changes to exclude the unavailable operations using
- compile-time options. The changes compile out TDES, Camellia, and RSAES,
- reject raw RSA and SHA-1 signatures, disable RSA-1024 and ECC P-192, and
- skip the raw-RSA self-test. During testing, I found a separate RSA-PSS
- signing failure where OpenSSL rejected the signing context when padding
- was configured before its requested digest, so I modified it to set the
+ I built a modified `libtpms 0.9.3` package for Ubuntu 24.04 here:
+ https://launchpad.net/~dmarx11/+archive/ubuntu/libtpms-fips-host/, with
+ changes to exclude the unavailable operations using compile-time
+ options. The changes compile out TDES, Camellia, and RSAES, reject raw
+ RSA and SHA-1 signatures, disable RSA-1024 and ECC P-192, and skip the
+ raw-RSA self-test. During testing, I found a separate RSA-PSS signing
+ failure where OpenSSL rejected the signing context when padding was
+ configured before its requested digest, so I modified it to set the
  digest first along with some temporary RSA error logging for debugging.
  
  The package successfully manufactures the vTPM after the libvirt/QEMU
  guest repro steps:
  
  Successfully created EK certificate locally.
  Successfully created NVRAM area 0x1c00016 for ECC EK certificate.
  Successfully activated PCR banks sha256 among sha1,sha256,sha384,sha512.
  Successfully authored TPM state.
  Ending vTPM manufacturing @ Wed 14 Oct 2026 07:50:43 PM UTC
  
  It also passes the manual self-test on the guest (step-by-step below)
  
  Shut off the guest first:
  
  virsh -c qemu:///system shutdown tpm-fips-original
  
  Then install a public key:
  
  install -d -m 700 /root/.ssh
  if [[ ! -f /root/.ssh/tpm-fips4 ]]; then
-     ssh-keygen -t rsa -b 3072 -N '' -f /root/.ssh/tpm-fips4
+     ssh-keygen -t rsa -b 3072 -N '' -f /root/.ssh/tpm-fips4
  fi
  PUBKEY=$(cat /root/.ssh/tpm-fips4.pub)
  
  Add the test user and key to cloud-init:
  
  cat > /tmp/tpm-fips-original-user-data <<EOF
  #cloud-config
  users:
-   - default
-   - name: tester
-     groups: [adm, sudo]
-     shell: /bin/bash
-     sudo: ALL=(ALL) NOPASSWD:ALL
-     ssh_authorized_keys:
-       - ${PUBKEY}
+   - default
+   - name: tester
+     groups: [adm, sudo]
+     shell: /bin/bash
+     sudo: ALL=(ALL) NOPASSWD:ALL
+     ssh_authorized_keys:
+       - ${PUBKEY}
  ssh_pwauth: false
  packages:
-   - tpm2-tools
+   - tpm2-tools
  EOF
  
  cat > /tmp/tpm-fips-original-meta-data <<'EOF'
  instance-id: tpm-fips-original-ssh
  local-hostname: tpm-fips-original
  EOF
  
  Recreate the guest disk:
  
  rm -- /var/lib/libvirt/images/tpm-fips-original.qcow2 \
-        /var/lib/libvirt/images/tpm-fips-original-seed.iso
+        /var/lib/libvirt/images/tpm-fips-original-seed.iso
  
  qemu-img create -f qcow2 -F qcow2 \
-   -b /var/lib/libvirt/images/noble-server-cloudimg-amd64.img \
-   /var/lib/libvirt/images/tpm-fips-original.qcow2 20G
+   -b /var/lib/libvirt/images/noble-server-cloudimg-amd64.img \
+   /var/lib/libvirt/images/tpm-fips-original.qcow2 20G
  
  cloud-localds /var/lib/libvirt/images/tpm-fips-original-seed.iso \
-   /tmp/tpm-fips-original-user-data \
-   /tmp/tpm-fips-original-meta-data
-   
+   /tmp/tpm-fips-original-user-data \
+   /tmp/tpm-fips-original-meta-data
+ 
  Start the guest again and obtain its IP:
  
  virsh -c qemu:///system start tpm-fips-original
  virsh -c qemu:///system net-dhcp-leases default
  
  Example:
  
- 2026-10-14 20:51:06   52:54:00:d0:3c:5d   ipv4       192.168.122.227/24   
tpm-fips-original   
-  
- SSH onto guest: 
-  
+ 2026-10-14 20:51:06   52:54:00:d0:3c:5d   ipv4       192.168.122.227/24
+ tpm-fips-original
+ 
+ SSH onto guest:
+ 
  GUEST_IP='192.168.122.227'
  ssh -i /root/.ssh/tpm-fips4 tester@"$GUEST_IP"
  
  Wait for cloud-init, then run the self-test:
  
  sudo cloud-init status --wait
  sudo tpm2_selftest -f
  echo $? # should return 0 for success

** Changed in: libtpms (Ubuntu)
     Assignee: (unassigned) => Canonical Security Certification 
(canonical-security-certification)

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2170896

Title:
  libtpms TPM 2.0 self-tests fail under FIPS mode

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/libtpms/+bug/2170896/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to