Merge pull request #6896 from SparkiDev/rsa_to_bin_len_ct

RSA: convert to bin with length in constant time
This commit is contained in:
JacobBarthelmeh
2023-10-25 08:34:37 -06:00
committed by GitHub
5 changed files with 72 additions and 1 deletions

View File

@ -2693,7 +2693,7 @@ static int RsaFunctionSync(const byte* in, word32 inLen, byte* out,
}
if (ret == 0) {
if (mp_to_unsigned_bin_len(tmp, out, (int)*outLen) != MP_OKAY)
if (mp_to_unsigned_bin_len_ct(tmp, out, (int)*outLen) != MP_OKAY)
ret = MP_TO_E;
}
#else

View File

@ -17774,6 +17774,73 @@ int sp_to_unsigned_bin_len(const sp_int* a, byte* out, int outSz)
return err;
}
/* Convert the multi-precision number to an array of bytes in big-endian format.
*
* Constant-time implementation.
*
* The array must be large enough for encoded number - use mp_unsigned_bin_size
* to calculate the number of bytes required.
* Front-pads the output array with zeros to make number the size of the array.
*
* @param [in] a SP integer.
* @param [out] out Array to put encoding into.
* @param [in] outSz Size of the array in bytes.
*
* @return MP_OKAY on success.
* @return MP_VAL when a or out is NULL.
*/
int sp_to_unsigned_bin_len_ct(const sp_int* a, byte* out, int outSz)
{
int err = MP_OKAY;
/* Validate parameters. */
if ((a == NULL) || (out == NULL) || (outSz < 0)) {
err = MP_VAL;
}
#if SP_WORD_SIZE > 8
if (err == MP_OKAY) {
/* Start at the end of the buffer - least significant byte. */
int j;
unsigned int i;
sp_digit mask = (sp_digit)-1;
sp_int_digit d;
/* Put each digit in. */
i = 0;
for (j = outSz - 1; j >= 0; ) {
int b;
d = a->dp[i];
/* Place each byte of a digit into the buffer. */
for (b = 0; (j >= 0) && (b < SP_WORD_SIZEOF); b++) {
out[j--] = (byte)(d & mask);
d >>= 8;
}
mask &= (sp_digit)0 - (i < a->used - 1);
i += (unsigned int)(1 & mask);
}
}
#else
if ((err == MP_OKAY) && ((unsigned int)outSz < a->used)) {
err = MP_VAL;
}
if (err == MP_OKAY) {
unsigned int i;
int j;
sp_digit mask = (sp_digit)-1;
i = 0;
for (j = outSz - 1; j >= 0; j--) {
out[j] = a->dp[i] & mask;
mask &= (sp_digit)0 - (i < a->used - 1);
i += (unsigned int)(1 & mask);
}
}
#endif
return err;
}
#if defined(WOLFSSL_SP_MATH_ALL) && !defined(NO_RSA) && \
!defined(WOLFSSL_RSA_VERIFY_ONLY)
/* Store the number in big-endian format in array at an offset.

View File

@ -313,6 +313,7 @@ MP_API int mp_unsigned_bin_size(const mp_int * a);
MP_API int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b);
MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b);
#define mp_to_unsigned_bin_len_ct mp_to_unsigned_bin_len
MP_API int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c);
MP_API int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
MP_API int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P,

View File

@ -1045,6 +1045,7 @@ MP_API int sp_unsigned_bin_size(const sp_int* a);
MP_API int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz);
MP_API int sp_to_unsigned_bin(const sp_int* a, byte* out);
MP_API int sp_to_unsigned_bin_len(const sp_int* a, byte* out, int outSz);
MP_API int sp_to_unsigned_bin_len_ct(const sp_int* a, byte* out, int outSz);
#ifdef WOLFSSL_SP_MATH_ALL
MP_API int sp_to_unsigned_bin_at_pos(int o, const sp_int* a,
unsigned char* out);
@ -1158,6 +1159,7 @@ WOLFSSL_LOCAL void sp_memzero_check(sp_int* sp);
#define mp_read_unsigned_bin sp_read_unsigned_bin
#define mp_to_unsigned_bin sp_to_unsigned_bin
#define mp_to_unsigned_bin_len sp_to_unsigned_bin_len
#define mp_to_unsigned_bin_len_ct sp_to_unsigned_bin_len_ct
#define mp_to_unsigned_bin_at_pos sp_to_unsigned_bin_at_pos
#define mp_read_radix sp_read_radix
#define mp_tohex sp_tohex

View File

@ -842,6 +842,7 @@ MP_API int mp_unsigned_bin_size(const mp_int * a);
MP_API int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b);
MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b);
#define mp_to_unsigned_bin_len_ct mp_to_unsigned_bin_len
MP_API int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c);
MP_API int mp_sub_d(fp_int *a, fp_digit b, fp_int *c);