DSA sign: use mp_to_unsigned_bin_len

mp_to_unsigned_len checks length and front pads with zeros.

Return MP_VAL when length is too small in all implemenations.
Make TFM implementation check length.
Add test case.
This commit is contained in:
Sean Parkinson
2023-01-23 09:14:24 +10:00
parent a40da56f11
commit 90e24d8ba5
4 changed files with 17 additions and 19 deletions

View File

@@ -662,7 +662,6 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
#endif #endif
mp_int* qMinus1; mp_int* qMinus1;
int ret = 0, halfSz = 0; int ret = 0, halfSz = 0;
byte* tmp; /* initial output pointer */
if (digest == NULL || out == NULL || key == NULL || rng == NULL) if (digest == NULL || out == NULL || key == NULL || rng == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
@@ -720,7 +719,6 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
break; break;
} }
tmp = out;
qMinus1 = kInv; qMinus1 = kInv;
/* NIST FIPS 186-4: B.2.2 /* NIST FIPS 186-4: B.2.2
@@ -904,21 +902,11 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng)
/* write out */ /* write out */
{ {
int rSz = mp_unsigned_bin_size(r); if (mp_to_unsigned_bin_len(r, out, halfSz) != MP_OKAY)
int sSz = mp_unsigned_bin_size(s);
while (rSz++ < halfSz) {
*out++ = 0x00; /* pad front with zeros */
}
if (mp_to_unsigned_bin(r, out) != MP_OKAY)
ret = MP_TO_E; ret = MP_TO_E;
else { else {
out = tmp + halfSz; /* advance to s in output */ out += halfSz; /* advance to s in output */
while (sSz++ < halfSz) { ret = mp_to_unsigned_bin_len(s, out, halfSz);
*out++ = 0x00; /* pad front with zeros */
}
ret = mp_to_unsigned_bin(s, out);
} }
} }
} while (0); } while (0);

View File

@@ -34,7 +34,6 @@ This library provides single precision (SP) integer math functions.
#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) #if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#include <wolfssl/wolfcrypt/error-crypt.h>
#ifdef NO_INLINE #ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h> #include <wolfssl/wolfcrypt/misc.h>
#else #else
@@ -16972,7 +16971,7 @@ int sp_to_unsigned_bin_len(const sp_int* a, byte* out, int outSz)
/* Stop if the output buffer is filled. */ /* Stop if the output buffer is filled. */
if (j < 0) { if (j < 0) {
if ((i < a->used - 1) || (d > 0)) { if ((i < a->used - 1) || (d > 0)) {
err = BUFFER_E; err = MP_VAL;
} }
break; break;
} }
@@ -16986,7 +16985,7 @@ int sp_to_unsigned_bin_len(const sp_int* a, byte* out, int outSz)
} }
#else #else
if ((err == MP_OKAY) && (outSz < a->used)) { if ((err == MP_OKAY) && (outSz < a->used)) {
err = BUFFER_E; err = MP_VAL;
} }
if (err == MP_OKAY) { if (err == MP_OKAY) {
int i; int i;

View File

@@ -3820,7 +3820,7 @@ int fp_to_unsigned_bin(fp_int *a, unsigned char *b)
int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c) int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c)
{ {
#if DIGIT_BIT == 64 || DIGIT_BIT == 32 #if DIGIT_BIT == 64 || DIGIT_BIT == 32 || DIGIT_BIT == 16
int i = 0; int i = 0;
int j = 0; int j = 0;
int x; int x;
@@ -3834,6 +3834,9 @@ int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c)
for (; x >= 0; x--) { for (; x >= 0; x--) {
b[x] = 0; b[x] = 0;
} }
if ((i < a->used - 1) || ((a->dp[i] >> j) != 0)) {
return FP_VAL;
}
return FP_OKAY; return FP_OKAY;
#else #else
@@ -3861,6 +3864,9 @@ int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c)
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
#endif #endif
if (!fp_iszero(t)) {
return FP_VAL;
}
return FP_OKAY; return FP_OKAY;
#endif #endif
} }

View File

@@ -39776,6 +39776,11 @@ static int mp_test_read_to_bin(mp_int* a)
} }
} }
/* Length too small. */
ret = mp_to_unsigned_bin_len(a, out, 1);
if (ret != MP_VAL)
return -12716;
ret = mp_read_unsigned_bin(a, NULL, 0); ret = mp_read_unsigned_bin(a, NULL, 0);
if (ret != 0) if (ret != 0)
return -12714; return -12714;