Page MenuHome GnuPG

gnupg: Use KEM interface for encryption/decryption
Testing, HighPublic

Description

T7014: agent: Enhancement of PKDECRYPT for KEM interface introduced use of KEM API (of libgcrypt) to gpg-agent.
It is good (for industrial certification(s) and auditors) to use KEM API in gpg frontend.

Event Timeline

gniibe triaged this task as High priority.
gniibe created this task.
gniibe renamed this task from gnupg: Use KEM interface for decryption to gnupg: Use KEM interface for encryption/decryption.May 19 2025, 2:35 AM
gniibe changed the task status from Open to Testing.May 22 2025, 8:05 AM

Pushed all changes needed. Actually, agent side too.
Clean up will be done.

FYI: I'd like to get a new release out after these changes.

Clean up finished by rG681d75404300: gpg,agent: Clean up around using ECC KEM.
Tested by make check and decrypting tests/openpgp/samplemsgs/pqc-sample-*.enc.asc.

@werner I think these changes caused an ASAN failure that I reported in T7664. I think it would be good to get that sorted before a release.

Another possible change will be use of KEM interface for gpgsm.
Not high priority, but for long term code maintenance.

secp256k1 is an --expert option and not supported by other *PGP
implementations. We should actually hide this thing even more and not
even display it with --expert. Thus do no expect an immediate 2.5.9
release to fix this issue.

I realized that I enbugged in rG5efabec21883: gpg:ecc: Use the common function of gnupg_get_ecc_params..
It has been regression since 2.5.9.

Fix will be something like:

diff --git a/g10/pkglue.c b/g10/pkglue.c
index a6bd893b3..11d252f0a 100644
--- a/g10/pkglue.c
+++ b/g10/pkglue.c
@@ -486,8 +486,8 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
       goto leave;
     }
   ecc_ct_len = ecc_ecdh_len = ecc->point_len;
-  ecc_ss_len = ecc->scalar_len;
   ecc_hash_algo = ecc->hash_algo;
+  ecc_ss_len = gcry_md_get_algo_dlen (ecc_hash_algo);
 
   ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
   ecc_pubkey_len = (nbits+7)/8;
gniibe mentioned this in Unknown Object (Maniphest Task).Aug 11 2025, 7:16 AM

@gniibe @werner Is this change is supposed to work only for PQC stuff, or non-PQC as well, and where it is defined? As it breaks RNP tests for ordinary ECDH encryption (as it looks up for 0x40 prefix). It's not a problematic to update our code, but just want to know the reason for that.

@onickolay The change was originally introduced for PQC stuff. And then, we applied use of KEM API (of libgcrypt) also for ordinary ECDH, so, it affected ordinary ECDH encryption (between 2.5.9 and 2.5.12).
The intention is follow the recommendation of use of KEM. IIUC, next FIPS certification will require use of KEM, possibly.

I noticed the mistake of mine (which does not add the 0x40 prefix for encryption for PGP) when I applied the KEM API for S/MIME.
The fix is commit: rG973122f54aa3: gpg: Take care about the prefix for Curve25519 encryption.
It is in 2.5.13.

Here is a reference:
NIST SP 800-227
Recommendations for Key-Encapsulation Mechanisms
https://doi.org/10.6028/NIST.SP.800-227

There is a section: 5.1.1. A KEM From Diffie-Hellman

Note that we only apply KEM API for ECDH (not for RSA).

@gniibe Thanks for the detailed reply. Looks like we were lucky to hit v2.5.12 when building our CI containers few weeks ago, rebuilding those now with 2.5.13 fixed the problem. Thanks again!

Let me explain the background.

Vendors like RedHat, Canonical, etc. need to get FIPS 140 certification for their 'products'. libgcrypt is one of the components to be certified in their OS. And libgcrypt supports FIPS mode which limits its functionalities following FIPS standards and recommendations. In FIPS mode, bare low level routines for ECC are not available. So, an application need to do ECC encryption/decryption through higher level abstraction, that's KEM API.

In short, it's internal issue when an application uses libgcrypt.