Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSA: convert to bin with length in constant time #6896

Merged
merged 1 commit into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion wolfcrypt/src/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
67 changes: 67 additions & 0 deletions wolfcrypt/src/sp_int.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions wolfssl/wolfcrypt/integer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions wolfssl/wolfcrypt/sp_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions wolfssl/wolfcrypt/tfm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down