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.scmI 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!