Skip to content

Commit fcf1406

Browse files
committed
RSA: convert to bin with length in constant time
Add mp_to_unsigned_bin_len_ct() which puts a number into a buffer with padding in constant time. Call mp_to_unsigned_bin_len_ct() in RSA when encoding result of exponentiation.
1 parent 1abaa94 commit fcf1406

5 files changed

Lines changed: 72 additions & 1 deletion

File tree

wolfcrypt/src/rsa.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2693,7 +2693,7 @@ static int RsaFunctionSync(const byte* in, word32 inLen, byte* out,
26932693
}
26942694

26952695
if (ret == 0) {
2696-
if (mp_to_unsigned_bin_len(tmp, out, (int)*outLen) != MP_OKAY)
2696+
if (mp_to_unsigned_bin_len_ct(tmp, out, (int)*outLen) != MP_OKAY)
26972697
ret = MP_TO_E;
26982698
}
26992699
#else

wolfcrypt/src/sp_int.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17774,6 +17774,73 @@ int sp_to_unsigned_bin_len(const sp_int* a, byte* out, int outSz)
1777417774
return err;
1777517775
}
1777617776

17777+
/* Convert the multi-precision number to an array of bytes in big-endian format.
17778+
*
17779+
* Constant-time implementation.
17780+
*
17781+
* The array must be large enough for encoded number - use mp_unsigned_bin_size
17782+
* to calculate the number of bytes required.
17783+
* Front-pads the output array with zeros to make number the size of the array.
17784+
*
17785+
* @param [in] a SP integer.
17786+
* @param [out] out Array to put encoding into.
17787+
* @param [in] outSz Size of the array in bytes.
17788+
*
17789+
* @return MP_OKAY on success.
17790+
* @return MP_VAL when a or out is NULL.
17791+
*/
17792+
int sp_to_unsigned_bin_len_ct(const sp_int* a, byte* out, int outSz)
17793+
{
17794+
int err = MP_OKAY;
17795+
17796+
/* Validate parameters. */
17797+
if ((a == NULL) || (out == NULL) || (outSz < 0)) {
17798+
err = MP_VAL;
17799+
}
17800+
17801+
#if SP_WORD_SIZE > 8
17802+
if (err == MP_OKAY) {
17803+
/* Start at the end of the buffer - least significant byte. */
17804+
int j;
17805+
unsigned int i;
17806+
sp_digit mask = (sp_digit)-1;
17807+
sp_int_digit d;
17808+
17809+
/* Put each digit in. */
17810+
i = 0;
17811+
for (j = outSz - 1; j >= 0; ) {
17812+
int b;
17813+
d = a->dp[i];
17814+
/* Place each byte of a digit into the buffer. */
17815+
for (b = 0; (j >= 0) && (b < SP_WORD_SIZEOF); b++) {
17816+
out[j--] = (byte)(d & mask);
17817+
d >>= 8;
17818+
}
17819+
mask &= (sp_digit)0 - (i < a->used - 1);
17820+
i += (unsigned int)(1 & mask);
17821+
}
17822+
}
17823+
#else
17824+
if ((err == MP_OKAY) && ((unsigned int)outSz < a->used)) {
17825+
err = MP_VAL;
17826+
}
17827+
if (err == MP_OKAY) {
17828+
unsigned int i;
17829+
int j;
17830+
sp_digit mask = (sp_digit)-1;
17831+
17832+
i = 0;
17833+
for (j = outSz - 1; j >= 0; j--) {
17834+
out[j] = a->dp[i] & mask;
17835+
mask &= (sp_digit)0 - (i < a->used - 1);
17836+
i += (unsigned int)(1 & mask);
17837+
}
17838+
}
17839+
#endif
17840+
17841+
return err;
17842+
}
17843+
1777717844
#if defined(WOLFSSL_SP_MATH_ALL) && !defined(NO_RSA) && \
1777817845
!defined(WOLFSSL_RSA_VERIFY_ONLY)
1777917846
/* Store the number in big-endian format in array at an offset.

wolfssl/wolfcrypt/integer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ MP_API int mp_unsigned_bin_size(const mp_int * a);
313313
MP_API int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
314314
MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b);
315315
MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b);
316+
#define mp_to_unsigned_bin_len_ct mp_to_unsigned_bin_len
316317
MP_API int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c);
317318
MP_API int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
318319
MP_API int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P,

wolfssl/wolfcrypt/sp_int.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,7 @@ MP_API int sp_unsigned_bin_size(const sp_int* a);
10451045
MP_API int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz);
10461046
MP_API int sp_to_unsigned_bin(const sp_int* a, byte* out);
10471047
MP_API int sp_to_unsigned_bin_len(const sp_int* a, byte* out, int outSz);
1048+
MP_API int sp_to_unsigned_bin_len_ct(const sp_int* a, byte* out, int outSz);
10481049
#ifdef WOLFSSL_SP_MATH_ALL
10491050
MP_API int sp_to_unsigned_bin_at_pos(int o, const sp_int* a,
10501051
unsigned char* out);
@@ -1158,6 +1159,7 @@ WOLFSSL_LOCAL void sp_memzero_check(sp_int* sp);
11581159
#define mp_read_unsigned_bin sp_read_unsigned_bin
11591160
#define mp_to_unsigned_bin sp_to_unsigned_bin
11601161
#define mp_to_unsigned_bin_len sp_to_unsigned_bin_len
1162+
#define mp_to_unsigned_bin_len_ct sp_to_unsigned_bin_len_ct
11611163
#define mp_to_unsigned_bin_at_pos sp_to_unsigned_bin_at_pos
11621164
#define mp_read_radix sp_read_radix
11631165
#define mp_tohex sp_tohex

wolfssl/wolfcrypt/tfm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,7 @@ MP_API int mp_unsigned_bin_size(const mp_int * a);
842842
MP_API int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
843843
MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b);
844844
MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b);
845+
#define mp_to_unsigned_bin_len_ct mp_to_unsigned_bin_len
845846
MP_API int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c);
846847

847848
MP_API int mp_sub_d(fp_int *a, fp_digit b, fp_int *c);

0 commit comments

Comments
 (0)