From faf848a9156678d80fb63047c395b4889a990994 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 30 Nov 2022 12:11:59 +1000 Subject: [PATCH 1/2] SP int: fix error checks when modulus even --- wolfcrypt/src/sp_int.c | 25 +++++++++++++------------ wolfcrypt/test/test.c | 10 ++++++++++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 0b82ab546..d74180319 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -11651,21 +11651,22 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r) sp_mod(m, a, v); /* v == 0 when a divides m evenly - no inverse. */ if (sp_iszero(v)) { - /* Force u to be the no inverse answer. */ - sp_set(u, 0); + err = MP_VAL; } evenMod = 1; } - /* Calculate inverse. */ - #if !defined(WOLFSSL_SP_SMALL) && (!defined(NO_RSA) || !defined(NO_DH)) - if (sp_count_bits(mm) >= 1024) { - err = _sp_invmod_div(ma, mm, u, v, b, c, c); - } - else - #endif - { - err = _sp_invmod(ma, mm, u, v, b, c); + if (err == MP_OKAY) { + /* Calculate inverse. */ + #if !defined(WOLFSSL_SP_SMALL) && (!defined(NO_RSA) || !defined(NO_DH)) + if (sp_count_bits(mm) >= 1024) { + err = _sp_invmod_div(ma, mm, u, v, b, c, c); + } + else + #endif + { + err = _sp_invmod(ma, mm, u, v, b, c); + } } /* Fixup for even modulus. */ @@ -11683,7 +11684,7 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r) sp_sub(m, c, r); } } - else { + else if (err == MP_OKAY) { err = sp_copy(c, r); } } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 7ce68117d..649d1f1af 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -43206,6 +43206,16 @@ static int mp_test_invmod(mp_int* a, mp_int* m, mp_int* r) ret = mp_invmod(a, m, r); if (ret != MP_VAL) return -13172; + mp_set(a, 3); + mp_set(m, 6); + ret = mp_invmod(a, m, r); + if (ret != MP_VAL) + return -13181; + mp_set(a, 5*9); + mp_set(m, 6*9); + ret = mp_invmod(a, m, r); + if (ret != MP_VAL) + return -13182; mp_set(a, 1); mp_set(m, 4); ret = mp_invmod(a, m, r); From c7c80be15e2545799f7f2f28d23734f84cc4a47c Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 30 Nov 2022 17:37:21 +1000 Subject: [PATCH 2/2] SP int: sp_invmod_div check div result before proceeding --- wolfcrypt/src/sp_int.c | 103 +++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index d74180319..538d29210 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -11430,8 +11430,8 @@ static int _sp_invmod_div(sp_int* a, sp_int* m, sp_int* x, sp_int* y, sp_int* b, sp_int* c, sp_int* inv) { int err = MP_OKAY; - sp_int* d; - sp_int* r; + sp_int* d = NULL; + sp_int* r = NULL; sp_int* s; #ifndef WOLFSSL_SP_INT_NEGATIVE int bneg = 0; @@ -11456,23 +11456,25 @@ static int _sp_invmod_div(sp_int* a, sp_int* m, sp_int* x, sp_int* y, sp_int* b, while ((err == MP_OKAY) && (!sp_isone(x)) && (!sp_iszero(x))) { /* 2.1. d = x / y, r = x mod y */ err = sp_div(x, y, d, r); - /* 2.2. c -= d * b */ - if (sp_isone(d)) { - /* c -= 1 * b */ - sp_sub(c, b, c); - } - else { - /* d *= b */ - err = sp_mul(d, b, d); - /* c -= d */ - if (err == MP_OKAY) { - sp_sub(c, d, c); + if (err == MP_OKAY) { + /* 2.2. c -= d * b */ + if (sp_isone(d)) { + /* c -= 1 * b */ + sp_sub(c, b, c); } + else { + /* d *= b */ + err = sp_mul(d, b, d); + /* c -= d */ + if (err == MP_OKAY) { + sp_sub(c, d, c); + } + } + /* 2.3. x = y, y = r */ + s = x; x = y; y = r; r = s; + /* 2.4. s = b, b = c, c = s */ + s = b; b = c; c = s; } - /* 2.3. x = y, y = r */ - s = x; x = y; y = r; r = s; - /* 2.4. s = b, b = c, c = s */ - s = b; b = c; c = s; } /* 3. If y != 0 then NO_INVERSE */ if ((err == MP_OKAY) && (!sp_iszero(y))) { @@ -11491,46 +11493,49 @@ static int _sp_invmod_div(sp_int* a, sp_int* m, sp_int* x, sp_int* y, sp_int* b, while ((err == MP_OKAY) && (!sp_isone(x)) && (!sp_iszero(x))) { /* 2.1. d = x / y, r = x mod y */ err = sp_div(x, y, d, r); - if (sp_isone(d)) { - /* c -= 1 * b */ - if ((bneg ^ cneg) == 1) { - /* c -= -b or -c -= b, therefore add. */ - _sp_add_off(c, b, c, 0); - } - else if (_sp_cmp_abs(c, b) == MP_LT) { - /* |c| < |b| and same sign, reverse subtract and negate. */ - _sp_sub_off(b, c, c, 0); - cneg = !cneg; - } - else { - /* |c| >= |b| */ - _sp_sub_off(c, b, c, 0); - } - } - else { - /* d *= b */ - err = sp_mul(d, b, d); - /* c -= d */ - if (err == MP_OKAY) { + if (err == MP_OKAY) { + if (sp_isone(d)) { + /* c -= 1 * b */ if ((bneg ^ cneg) == 1) { - /* c -= -d or -c -= d, therefore add. */ - _sp_add_off(c, d, c, 0); + /* c -= -b or -c -= b, therefore add. */ + _sp_add_off(c, b, c, 0); } - else if (_sp_cmp_abs(c, d) == MP_LT) { - /* |c| < |d| and same sign, reverse subtract and negate. */ - _sp_sub_off(d, c, c, 0); + else if (_sp_cmp_abs(c, b) == MP_LT) { + /* |c| < |b| and same sign, reverse subtract and negate. */ + _sp_sub_off(b, c, c, 0); cneg = !cneg; } else { - _sp_sub_off(c, d, c, 0); + /* |c| >= |b| */ + _sp_sub_off(c, b, c, 0); } } + else { + /* d *= b */ + err = sp_mul(d, b, d); + /* c -= d */ + if (err == MP_OKAY) { + if ((bneg ^ cneg) == 1) { + /* c -= -d or -c -= d, therefore add. */ + _sp_add_off(c, d, c, 0); + } + else if (_sp_cmp_abs(c, d) == MP_LT) { + /* |c| < |d| and same sign, reverse subtract and negate. + */ + _sp_sub_off(d, c, c, 0); + cneg = !cneg; + } + else { + _sp_sub_off(c, d, c, 0); + } + } + } + /* 2.3. x = y, y = r */ + s = x; x = y; y = r; r = s; + /* 2.4. s = b, b = c, c = s */ + s = b; b = c; c = s; + neg = bneg; bneg = cneg; cneg = neg; } - /* 2.3. x = y, y = r */ - s = x; x = y; y = r; r = s; - /* 2.4. s = b, b = c, c = s */ - s = b; b = c; c = s; - neg = bneg; bneg = cneg; cneg = neg; } /* 3. If y != 0 then NO_INVERSE */ if ((err == MP_OKAY) && (!sp_iszero(y))) {