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
