libgcrypt 1.12.0: gcry_mpi_ec_curve_point corrupts point
Guido Vranken
guidovranken at gmail.com
Thu Jan 29 15:14:04 CET 2026
#include <stdio.h>
#include <gcrypt.h>
int main(void) {
gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
gcry_ctx_t ctx;
gcry_mpi_ec_new(&ctx, NULL, "sm2p256v1");
// Point with small X (1 limb), Z != 1
gcry_mpi_t X = gcry_mpi_set_ui(NULL, 9);
gcry_mpi_t Y, Z, scalar;
gcry_mpi_scan(&Y, GCRYMPI_FMT_HEX,
"3EE15EF0050F0FD70857D63C72B31A7066E9D02AEECCCE8B00D27AC9AC7A673A",
0, NULL);
Z = gcry_mpi_set_ui(NULL, 27);
scalar = gcry_mpi_set_ui(NULL, 27);
gcry_mpi_point_t P = gcry_mpi_point_new(0);
gcry_mpi_point_set(P, X, Y, Z);
gcry_mpi_point_t R1 = gcry_mpi_point_new(0);
gcry_mpi_ec_mul(R1, scalar, P, ctx);
gcry_mpi_point_set(P, X, Y, Z);
gcry_mpi_ec_curve_point(P, ctx); // BUG: corrupts P
gcry_mpi_point_t R2 = gcry_mpi_point_new(0);
gcry_mpi_ec_mul(R2, scalar, P, ctx);
gcry_mpi_t r1x = gcry_mpi_new(0), r2x = gcry_mpi_new(0);
gcry_mpi_ec_get_affine(r1x, NULL, R1, ctx);
gcry_mpi_ec_get_affine(r2x, NULL, R2, ctx);
unsigned char *buf;
size_t len;
printf("Test 1 (clean point): ");
gcry_mpi_aprint(GCRYMPI_FMT_HEX, &buf, &len, r1x);
printf("x = %s\n", buf);
gcry_free(buf);
printf("Test 2 (after gcry_mpi_ec_curve_point): ");
gcry_mpi_aprint(GCRYMPI_FMT_HEX, &buf, &len, r2x);
printf("x = %s\n", buf);
gcry_free(buf);
if (gcry_mpi_cmp(r1x, r2x) == 0)
printf("PASS: results match\n");
else
printf("FAIL: results differ\n");
return gcry_mpi_cmp(r1x, r2x) != 0;
}
Afaik this affects Weierstrass curves with points satisfying Z >= 2 and
limb count of X and/or Y != ctx->p->nlimbs. This is arguably a security
vulnerability.
Guido
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.gnupg.org/pipermail/gcrypt-devel/attachments/20260129/3e244aef/attachment.html>
More information about the Gcrypt-devel
mailing list