https://bugs.kde.org/show_bug.cgi?id=514194
Marco Martin <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|REPORTED |RESOLVED Resolution|--- |FIXED Latest Commit| |https://invent.kde.org/fram | |eworks/kwallet/-/commit/307 | |db62637ac2ca78ff670d746433b | |e9381a923b --- Comment #4 from Marco Martin <[email protected]> --- Git commit 307db62637ac2ca78ff670d746433be9381a923b by Marco Martin, on behalf of Matthias Kurz. Committed on 20/03/2026 at 09:10. Pushed by mart into branch 'master'. ksecretd: fix intermittent Secret Service session key mismatches with libsecret ## Summary This MR fixes intermittent `libsecret` / Secret Service interoperability failures in `ksecretd` that are tracked in [BUG 514194](https://bugs.kde.org/show_bug.cgi?id=514194). The user-visible symptom is that repeated lookups sometimes fail with: ```text libsecret-INFO: ... received an invalid or unencryptable secret ``` even though the secret was stored correctly and most lookups succeed. ## Reproducer Store a secret once: ```bash secret-tool store --label="some random secret" attr1 val1 ``` Then repeatedly look it up: ```bash while true; do G_MESSAGES_DEBUG=libsecret secret-tool lookup attr1 val1; sleep 0.1; done ``` Before this fix, the loop intermittently produced: ```text libsecret-INFO: ... received an invalid or unencryptable secret ``` ## Root cause There were two separate incompatibilities in `ksecretd`'s DH/AES session handling. ### 1. The DH shared secret width was not normalized to the 1024-bit group size `libsecret` derives the AES session key from the Diffie-Hellman shared secret after normalizing it to the prime width (128 bytes), see [`egg_dh_gen_secret()` in `egg/egg-dh-libgcrypt.c`](https://gitlab.gnome.org/GNOME/libsecret/-/blob/0.21.7/egg/egg-dh-libgcrypt.c#L186-190) and the subsequent HKDF step in [`response_open_session_aes()` in `libsecret/secret-session.c`](https://gitlab.gnome.org/GNOME/libsecret/-/blob/0.21.7/libsecret/secret-session.c#L175-182). `ksecretd` previously passed the raw QCA output directly into HKDF. If the shared secret had leading zero bytes, QCA returned a shorter value and ksecretd derived a different AES key than libsecret. ### 2. DH public keys were handled as signed integers instead of unsigned big-endian values QCA's `BigInteger` import/export uses sign-extended network byte order. `libsecret`, on the other hand, treats the exchanged DH public keys as unsigned values: - it imports the peer public key with [`gcry_mpi_scan(..., GCRYMPI_FMT_USG, ...)`](https://gitlab.gnome.org/GNOME/libsecret/-/blob/0.21.7/egg/egg-dh-libgcrypt.c#L263-266) - and it exports its own public key with [`gcry_mpi_aprint(..., GCRYMPI_FMT_USG, ...)`](https://gitlab.gnome.org/GNOME/libsecret/-/blob/0.21.7/egg/egg-dh-libgcrypt.c#L247-248) This meant that: - incoming client public keys could be misinterpreted when the high bit was set - outgoing server public keys could sometimes be encoded as 129 bytes instead of the expected unsigned 128-byte form That again caused both sides to derive different session keys intermittently. ## Fixes in this MR This MR applies two fixes, and both are needed: 1. Normalize the derived DH shared secret to exactly 128 bytes before HKDF 2. Normalize DH public keys to unsigned 128-byte values on both input and output With only one of these fixes applied, the bug could still be reproduced. With both fixes applied, I was no longer able to reproduce the failure, including long runs of the loop above. ## Tests This MR includes autotest coverage for both failure modes: - a regression test for a short DH shared secret - a regression test for a client public key with the high bit set ## Bug Fixes: [BUG 514194](https://bugs.kde.org/show_bug.cgi?id=514194) M +141 -20 src/runtime/ksecretd/autotests/fdo_secrets_test.cpp M +4 -0 src/runtime/ksecretd/autotests/fdo_secrets_test.h M +9 -7 src/runtime/ksecretd/kwalletfreedesktopservice.cpp M +23 -1 src/runtime/ksecretd/kwalletfreedesktopsession.cpp M +3 -0 src/runtime/ksecretd/kwalletfreedesktopsession.h https://invent.kde.org/frameworks/kwallet/-/commit/307db62637ac2ca78ff670d746433be9381a923b -- You are receiving this mail because: You are watching all bug changes.
