When compiling GPG with -fsanitize=address I see that tests/openpgp/ecc.scm fails with the following:
Importing ECC secret keys Checking ECC encryption Checking ECDH decryption > msg_encrypted_256 msg_encrypted_384 msg_encrypted_521 < Checking ECC encryption and decryption > plain-1 ...len: 133 pubkey_len: 133 ================================================================= ==224378==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7b506eb01d81 at pc 0x7f5071ce4822 bp 0x7ffd98f7c8e0 sp 0x7ffd98f7c0a0 WRITE of size 133 at 0x7b506eb01d81 thread T0 #0 0x7f5071ce4821 in memcpy (/lib64/libasan.so.8+0xe4821) (BuildId: 6a82bb83b1f19d3f3a2118085acf79daa3b52371) #1 0x7f507192ce5a in _gcry_ecc_curve_keypair /home/collin/.local/src/libgcrypt/cipher/ecc-ecdh.c:178 #2 0x7f5071835f5c in _gcry_ecc_raw_keypair /home/collin/.local/src/libgcrypt/cipher/kem-ecc.c:128 #3 0x7f5071835fcf in _gcry_ecc_raw_encap /home/collin/.local/src/libgcrypt/cipher/kem-ecc.c:146 #4 0x7f507182d990 in _gcry_kem_encap /home/collin/.local/src/libgcrypt/cipher/kem.c:191 #5 0x7f507180408a in gcry_kem_encap /home/collin/.local/src/libgcrypt/src/visibility.c:1507 #6 0x000000580632 in do_encrypt_ecdh (/home/collin/.local/src/gnupg/g10/gpg+0x580632) (BuildId: 1ebb60ac0818488ba30f020093791b58323ac271) #7 0x0000005bff72 in write_pubkey_enc (/home/collin/.local/src/gnupg/g10/gpg+0x5bff72) (BuildId: 1ebb60ac0818488ba30f020093791b58323ac271) #8 0x0000005c0407 in write_pubkey_enc_from_list (/home/collin/.local/src/gnupg/g10/gpg+0x5c0407) (BuildId: 1ebb60ac0818488ba30f020093791b58323ac271) #9 0x0000005c0e88 in encrypt_crypt (/home/collin/.local/src/gnupg/g10/gpg+0x5c0e88) (BuildId: 1ebb60ac0818488ba30f020093791b58323ac271) #10 0x00000041a3cb in main (/home/collin/.local/src/gnupg/g10/gpg+0x41a3cb) (BuildId: 1ebb60ac0818488ba30f020093791b58323ac271) #11 0x7f5070e115f4 in __libc_start_call_main (/lib64/libc.so.6+0x35f4) (BuildId: 2b3c02fe7e4d3811767175b6f323692a10a4e116) #12 0x7f5070e116a7 in __libc_start_main@@GLIBC_2.34 (/lib64/libc.so.6+0x36a7) (BuildId: 2b3c02fe7e4d3811767175b6f323692a10a4e116) #13 0x00000041ffb4 in _start (/home/collin/.local/src/gnupg/g10/gpg+0x41ffb4) (BuildId: 1ebb60ac0818488ba30f020093791b58323ac271) Address 0x7b506eb01d81 is located in stack of thread T0 at offset 385 in frame #0 0x00000057ffbf in do_encrypt_ecdh (/home/collin/.local/src/gnupg/g10/gpg+0x57ffbf) (BuildId: 1ebb60ac0818488ba30f020093791b58323ac271) This frame has 8 object(s): [48, 52) 'nbits' (line 754) [64, 72) 'hd' (line 755) [96, 104) 'kdf_params_spec' (line 774) [128, 136) 'kdf_params' (line 778) [160, 168) 'kdf_params_len' (line 779) [192, 224) 'fp' (line 775) [256, 385) 'ecc_ct' (line 766) [464, 593) 'ecc_ecdh' (line 767) <== Memory access at offset 385 partially underflows this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow /home/collin/.local/src/libgcrypt/cipher/ecc-ecdh.c:178 in _gcry_ecc_curve_keypair Shadow bytes around the buggy address: 0x7b506eb01b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7b506eb01b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7b506eb01c00: f1 f1 f1 f1 f1 f1 04 f2 00 f2 f2 f2 00 f2 f2 f2 0x7b506eb01c80: 00 f2 f2 f2 00 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 0x7b506eb01d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x7b506eb01d80:[01]f2 f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 0x7b506eb01e00: 00 00 00 00 00 00 00 00 00 00 01 f3 f3 f3 f3 f3 0x7b506eb01e80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 0x7b506eb01f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7b506eb01f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7b506eb02000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==224378==ABORTING : (() ((throw (:stderr result)) (call-popen cmd input))) 0: #<CLOSURE> 1: tests.scm:425: (apply throw error) FAIL: <standard>tests/openpgp/ecc.scm
I tried looking into this yesterday but I am not too familiar with the gcrypt functions. It seems this failure was introduced by this recent commit:
commit d1c3bfda2a8c032165ad41dc750f31d92369cd37 Author: NIIBE Yutaka <gniibe@fsij.org> AuthorDate: Mon May 19 14:51:17 2025 +0900 Commit: NIIBE Yutaka <gniibe@fsij.org> CommitDate: Mon May 19 14:57:19 2025 +0900 gpg: Use the KEM API for ECC encryption. * g10/ecdh.c (gnupg_ecc_6637_kdf): New. (pk_ecdh_encrypt_with_shared_point, gen_k): Remove. (pk_ecdh_generate_ephemeral_key): Remove. * g10/pkglue.c (get_data_from_sexp): Remove. (do_encrypt_ecdh): Use gcry_kem_encap of the KEM API, gnupg_ecc_6637_kdf, and AESWRAP. * g10/pkglue.h (gnupg_ecc_6637_kdf): New. (pk_ecdh_encrypt_with_shared_point): Remove. (pk_ecdh_generate_ephemeral_key, pk_ecdh_encrypt): Remove. -- GnuPG-bug-id: 7649 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
@gniibe Can you take a look? I have a feeling you will be able to solve this much faster than me. Thanks!