Page MenuHome GnuPG

unreliable RSA decryption
Closed, ResolvedPublic

Description

with GnuPG 2.2.43, i sometimes see RSA decryption failing intermittently.

Using these files:

$ ./test
gpg: keybox '/home/dkg/tmp/tmp.s3bXNsf1tj/g/pubring.kbx' created
gpg: /home/dkg/tmp/tmp.s3bXNsf1tj/g/trustdb.gpg: trustdb created
gpg: key 7AF6724289FFC389: public key "someone@example.org" imported
gpg: key 7AF6724289FFC389: secret key imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
gpg: encrypted with ECDH key, ID 4A85CC85DB26C8E9
gpg: encrypted with 2048-bit RSA key, ID E8A4FCC42E7BBEA4, created 2024-05-28
      "someone@example.org"
дружбаgpg: encrypted with ECDH key, ID 4A85CC85DB26C8E9
gpg: encrypted with 2048-bit RSA key, ID E8A4FCC42E7BBEA4, created 2024-05-28
      "someone@example.org"
[…]
дружбаgpg: encrypted with ECDH key, ID 4A85CC85DB26C8E9
gpg: encrypted with 2048-bit RSA key, ID E8A4FCC42E7BBEA4, created 2024-05-28
      "someone@example.org"
gpg: public key decryption failed: Wrong secret key used
gpg: decryption failed: No secret key
Succeeded 50 times before failure
gpg (GnuPG) 2.2.43
libgcrypt 1.10.3
Copyright (C) 2023 g10 Code GmbH
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/dkg/tmp/tmp.s3bXNsf1tj/g
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
$ 

(this was first reported to sequoia while sequoia tries to use gpg-agent)

Details

Version
2.2.43

Event Timeline

werner claimed this task.
werner edited projects, added Not A Bug, OpenPGP; removed Bug Report.
werner added a subscriber: werner.

I can replicate that and it works if you disable the use of the CRT. Looking at the key:

pkey[0]: BC9E1CD66676208956B35357210C220508F9F883FE32F4D682CD36BFB4E8055938D4BA21C341D9F48527E420F951B80335B24DF6710F01C4364D554AF659FC35D322061B67CC2F303DC878076059E4F266CFAEF6AB7A29124E969B9C15B1FC2FBA0F0F90E6B059E36B5E3C9BEC4174162689108A1E0EF6D5DDEE61B6B48327A259746288A517B1D78A0E24F5EFF6E880FF39C0BEDDC464B66F787B559EC5487F248196C2CFB15730BD9695C48355DFB2839FA23D8A37FBD48C741F6BE19F9D48BF844C5147591E1E06803DA40BEA1186B3B39CDCBC0E7DAC9DACDBB60A20E56B7E6631E47A45989A256743FDD83C591CFD4110DEA1B04ADE91CCB575FB858C13
 pkey[1]: 010001
 skey[2]: 512FB977EB9872FECA8BDB96884A01A6AB2B7575D307B9ED4F55E777F2F55FBFFCBF4BF2D669D4D7F42CAC7C28F4ACC0ECEEF7B1D90E3D936850372352107F87E77E20A4D133C927F99FFD52277DEA17107BDA72A072AF950AB0B70023327E3B48D9CCB871237D3D6F6C9BA7FDB45AB46217E33FA01A8ED295795323E26505BC9471CAE4DDA94DBF4F35ED915B0CD025805DCA796EB6B208D8D3F63DBE52BC0045CF4CF9B128356359C7E55B661D7B9DCA57F8984095C5AD3FE4DBD19228B281D66609A154DD7E3EE940CFC66CC180DDC4DD00C45A52D5789286D89D49CA34E5F3C4E798D90955074DAE3D99F7F004CDFFBC9B8428E8EB603E240AE07BEE8D71
 skey[3]: F57D9F597750967DF272D9AC661DDC212D7C5CA4C6E91573A80756281351CDC3A2532B155D9251029F89A0A0807DF2BD177DC30FC6A847E07738B55606DF032ADAD8361E0AFEE9C0CF7D566793834977FAAE9C4B87132B94F665EFF463777CDE7EB89113FA3AAC194B6F2D30C40BE7C0DDE36A5855277C1E4D0204FC4C737BCB
 skey[4]: C4B135296B8F4390B953DDA84249FC8467CFF81FC715D1B5F3E01FCC8DC770813630AEA93982F2004705C4D272E07A10B1882AC5C09A45E88B14A1446B4C639B549420CE3BF90947E6E86503E426A8FDAC4C5CFC2809F5F0A1647ED5EE2457C054A40AA1F0666B28B2C970BE2093AE7B095A688B2D713CA8885826F23AFB37D9
 skey[5]: 0790A8E260C6CADC353FB3961D798EFD4F15F96752DA20B86841334C38861743DD7A1FEB2B750D0864F5901BE541B6C8FB63649B18FDC4A32A1233EF90872DCD35704A4B4063DB62752CF6A7FD00F086C6B1042A2B0CB6FB36B7D5269671DACF55242A838E60D514BA868354910CEB1C41FB9A43BF932B5036A6EFE35236FFC7

shows that p > q (skey[3] > skey[4]) which is wrong. See RFC4880 5.5.3:

  • MPI of RSA secret prime value p.
  • MPI of RSA secret prime value q (p < q).
  • MPI of u, the multiplicative inverse of p, mod q.

So i see a range of ways that any OpenPGP software could deal with this:

  1. Reject this key on import, warning the user that p > q and thus the key violates §5.5.3 of RFC 4880.
  2. Accept the key on import, but reorder p and q (maybe warning the user that this has happened?)
  3. Accept the key on import, but during decryption, stochastically fail, some of the time, while succeeding other times.

It looks like you're saying that option 3 is the preferred solution for GnuPG. Is that right?

I would lean toward option 2, even though it means that round-tripping the key (via import and export) would not be idempotent. It seems more user-friendly than option 1. Option 3 seems to me like it's the worst of all possible choices: It's unreliable, opaque, and confusing.

Maybe there's a 4th possible option that's better than the three i identified?

In more than 25 years of OpenPGP we only had a few new implementations which got it wrong. I see no need to fix it here - maybe import could indeed reject such a key, though.

It seems too late to reject on import, given that people might already have such a secret key in their ~/.gnupg/private-keys-v1.d/ They might have had it for years without knowing it, because the failure is so intermittent. They might just think that they did something wrong, and when they try again it works. It would be great to be more robust than that.