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
