Version
master (a103f5a, 2026-08)
Description
mp_sqrmod() disagrees with itself about a zero modulus. Whether it returns an error depends on where the caller points the result:
mp_sqrmod(a, m, r) a=0, m=0, r distinct -> MP_VAL
mp_sqrmod(a, m, m) a=0, m=0 -> MP_OKAY, result 0
In wolfcrypt/src/sp_int.c, sp_sqrmod() sends the r != m case through sp_sqr() then sp_mod(), and sp_mod() rejects a zero modulus. The r == m case calls _sp_sqrmod(), which short-circuits on sp_iszero(a) and returns MP_OKAY without ever looking at m.
A zero modulus is undefined either way, but the two paths should agree.
Found via OSS-Fuzz 513887571 (cryptofuzz BignumCalc SqrMod).
Reproduction steps
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/integer.h>
#include <stdio.h>
int main(void) {
mp_int a, m, r;
mp_init_multi(&a, &m, &r, NULL, NULL, NULL);
mp_set_int(&a, 0);
mp_set_int(&m, 0);
printf("r != m: %d\n", mp_sqrmod(&a, &m, &r));
mp_set_int(&m, 0);
printf("r == m: %d\n", mp_sqrmod(&a, &m, &m));
return 0;
}
Built against ./configure --enable-static --disable-shared.
Relevant log output
r != m: -98
r == m: 0
Version
master (a103f5a, 2026-08)
Description
mp_sqrmod()disagrees with itself about a zero modulus. Whether it returns an error depends on where the caller points the result:In
wolfcrypt/src/sp_int.c,sp_sqrmod()sends ther != mcase throughsp_sqr()thensp_mod(), andsp_mod()rejects a zero modulus. Ther == mcase calls_sp_sqrmod(), which short-circuits onsp_iszero(a)and returnsMP_OKAYwithout ever looking atm.A zero modulus is undefined either way, but the two paths should agree.
Found via OSS-Fuzz 513887571 (cryptofuzz
BignumCalc SqrMod).Reproduction steps
Built against
./configure --enable-static --disable-shared.Relevant log output
r != m: -98
r == m: 0