I have built the proposed fix in
https://launchpad.net/~lgp171188/+archive/ubuntu/libp11-noble-fix,
tested the built package and can confirm that the issue appears to be
resolved.

** Description changed:

  Note: This bug report, analysis of the issue, and the potential fix were
  created using the assistance of an LLM.
  
- OpenSSL 3.0.12–3.0.13 has a bug (openssl/openssl#23063
- (https://github.com/openssl/openssl/pull/23063)) in foreign EVP_PKEY
- handling that causes a NULL dereference when the engine's RSA signing
- path is invoked. libp11 0.4.13 (in plucky 25.04+) has a workaround;
- noble ships 0.4.12 which does not.
+ [ Impact ]
  
- The upstream commit 86c04043c0 in libp11
- (https://github.com/OpenSC/libp11/pull/554), backported to 0.4.12 to add
- the workaround for the problematic OpenSSL versions would fix this
- issue. Since the 0.4.12 version does not contain an existing `if`
- condition that the PR extends, the backported fix patch would add an
- OpenSSL version check in load_privkey() and calls
- ENGINE_set_default_string(engine, "PKEY_CRYPTO") to reroute signing
- through the EVP_PKEY path, avoiding the broken RSA_get_ex_data call.
+ Users on Ubuntu 24.04 noble who attempt to sign files via a PKCS#11
+ token using the OpenSSL PKCS#11 engine (libengine-pkcs11-openssl)
+ experience a segfault. This affects any tool that uses the engine for
+ signing, including sbsign (used for UEFI Secure Boot binary signing) and
+ osslsigncode. The crash occurs unconditionally on the affected OpenSSL
+ versions — there is no workaround available to users without replacing
+ the library.
  
- Environment:
- - Ubuntu 24.04 noble
- - YubiHSM2 device
- - Packages: yubihsm-connector (3.0.7-1), yubihsm-shell (2.7.3), 
yubihsm-pkcs11 (2.7.3) from Yubico YubiHSM2 SDK, libengine-pkcs11-openssl 
(0.4.12-1.1build2), sbsigntool (0.9.4-3.1ubuntu7), opensc 
(0.25.0~rc1-1ubuntu0.2)
+ The root cause is a regression introduced in OpenSSL commit 2b74e75
+ (shipped in 3.0.12) and fixed in OpenSSL commit 39ea783 (not backported
+ to the 3.0.x series in noble). libp11 0.4.13 (in plucky 25.04+) carries
+ a runtime workaround that detects the affected OpenSSL versions and
+ reroutes signing through PKEY_CRYPTO, avoiding the broken code path.
+ Noble ships 0.4.12 which does not have this workaround.
  
- Steps to reproduce:
- 1. Start yubihsm-connector and confirm it reaches the device:
-    curl -s http://127.0.0.1:12345/connector/status
- 2. Generate a test RSA-2048 key and self-signed certificate:
+ [ Test Plan ]
+ 
+ Requires a PKCS#11 token. Tested with a YubiHSM2 device; any PKCS#11
+ token with an RSA key should reproduce the issue.
+ 
+ 1. On a fresh noble system, install dependencies:
+    sudo apt install libengine-pkcs11-openssl sbsigntool opensc
+    # Also install yubihsm-connector, yubihsm-shell, yubihsm-pkcs11 from the 
Yubico SDK
+ 
+ 2. Start yubihsm-connector and confirm device is reachable:
+    curl -s http://127.0.0.1:12345/connector/status  # expect status=OK
+ 
+ 3. Generate a test RSA-2048 key and self-signed certificate:
     openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out test.key
     openssl req -new -x509 -key test.key -out test.crt -days 365 -subj 
"/CN=Test"
- 3. Load the key into the YubiHSM2 (factory default credentials):
+ 
+ 4. Load the key into the token (YubiHSM2 factory defaults):
     yubihsm-shell --connector http://127.0.0.1:12345 -p password --authkey 1 \
       -a put-asymmetric-key --object-id 257 --label "test-key" \
-      --domains 1 --capabilities sign-pkcs --algorithm rsa2048 \
-      --in test.key
- 4. Create the PKCS#11 connector config:
+      --domains 1 --capabilities sign-pkcs --algorithm rsa2048 --in test.key
+ 
+ 5. Create PKCS#11 connector config:
     echo "connector = http://127.0.0.1:12345"; > yubihsm_pkcs11.conf
- 5. Attempt to sign an EFI binary:
+ 
+ 6. Attempt to sign an EFI binary:
     YUBIHSM_PKCS11_CONF=$(pwd)/yubihsm_pkcs11.conf \
-    sbsign \
-      --engine pkcs11 \
+    sbsign --engine pkcs11 \
       --key "pkcs11:id=%01%01;type=private;pin-value=0001password" \
-      --cert test.crt \
-      --output test-output.efi \
-      /boot/efi/EFI/ubuntu/grubx64.efi
+      --cert test.crt --output test-output.efi /boot/efi/EFI/ubuntu/grubx64.efi
  
- Expected result: Signed EFI binary produced.
+    Before fix: Segmentation fault (core dumped)
+    After fix: signed binary produced; sbverify --cert test.crt 
test-output.efi returns OK. stderr will print "Workaround for OpenSSL 3.0.13 
enabled" — this is expected.
  
- Actual result: Segmentation fault (core dumped).
+ [ Where problems could occur ]
  
- Additional context: The crash is entirely within engines-3/pkcs11.so as shown 
by the backtrace:
- pkcs11.so → RSA_sign → EVP_DigestSignFinal → PKCS7_SIGNER_INFO_sign → 
PKCS7_dataFinal → sbsign
- SIGSEGV, si_code=SI_KERNEL, si_addr=NULL
+ The patch adds a call to ENGINE_set_default_string(engine,
+ "PKEY_CRYPTO") inside load_privkey() when an affected OpenSSL version is
+ detected. This reroutes all PKEY_CRYPTO operations for the engine
+ instance through the EVP_PKEY path rather than the legacy RSA_sign path.
  
- Root cause: OpenSSL 3.0.13 (shipped in noble) contains a regression
- introduced in commit openssl/openssl@2b74e75 and fixed in
- openssl/openssl@39ea783. The fix did not ship until OpenSSL 3.0.14.
- libp11 0.4.13 (plucky+) carries a workaround; noble's 0.4.12 does not.
+ Possible failure modes:
+ 
+ - Deployments using foreign keys from multiple engines simultaneously:
+ ENGINE_set_default_string   sets the default engine for PKEY_CRYPTO
+ globally for that engine instance. If an application loads private keys
+ from multiple engines and relies on per-key engine dispatch, this could
+ interfere. Such deployments are uncommon and would already be non-
+ functional on affected OpenSSL versions (the bug causes a segfault
+ regardless). The upstream comment in libp11 0.4.13   explicitly
+ acknowledges this trade-off.
+ 
+ - ENGINE_set_default_string failure: if the call fails on an affected
+ OpenSSL version, the patch logs "Failed to set PKEY_CRYPTO default
+ engine" to stderr and continues. The behaviour is then identical to the
+ unpatched package — a segfault on signing. This is not worse than the
+ current state but means the fix silently did not apply.
+ 
+ - The workaround emits "Workaround for OpenSSL X.Y.Z enabled" to stderr
+ on every key load on affected versions. Applications that parse or
+ suppress stderr output may be affected by this unexpected message.
+ 
+ [ Other Info ]
+ 
+ - Upstream fix: https://github.com/OpenSC/libp11/pull/554 (landed in libp11 
0.4.13)
+ - OpenSSL regression: openssl/openssl@2b74e75, fixed in 
openssl/openssl@39ea783
+ - The fix is present in plucky (0.4.13) and questing (0.4.16) without 
reported regressions.
+ - autopkgtest results: TODO

** Summary changed:

- sbsign (and any tool using the OpenSSL PKCS#11 engine) segfaults when signing 
via a PKCS#11 token on OpenSSL 3.0.13
+ [SRU] sbsign (and any tool using the OpenSSL PKCS#11 engine) segfaults when 
signing via a PKCS#11 token on OpenSSL 3.0.13

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

Title:
  [SRU] sbsign (and any tool using the OpenSSL PKCS#11 engine) segfaults
  when signing via a PKCS#11 token on OpenSSL 3.0.13

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


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

Reply via email to