Skip to content

sp_sqrmod: zero modulus rejected or accepted depending on output aliasing #11063

Description

@MarkAtwood

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions