-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
fix: Constant-time enhancements for bignum.c and ecdsa.c #3309
Changes from 1 commit
7ea6cb8
c4dc4ee
506c8dc
f8a714a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -124,18 +124,42 @@ | |
#endif /* !MBEDTLS_HAVE_INT64 */ | ||
typedef int64_t mbedtls_mpi_sint; | ||
typedef uint64_t mbedtls_mpi_uint; | ||
#if !defined(MBEDTLS_MPI_UINT_BITS) | ||
#define MBEDTLS_MPI_UINT_BITS 64 | ||
#endif /* MBEDTLS_MPI_UINT_BITS */ | ||
#if !defined(MBEDTLS_MPI_HALF_MASK) | ||
#define MBEDTLS_MPI_HALF_MASK 0xffffffff | ||
#endif /* MBEDTLS_MPI_HALF_MASK */ | ||
#if !defined(MBEDTLS_MPI_HALF_BITS) | ||
#define MBEDTLS_MPI_HALF_BITS 32 | ||
#endif /* MBEDTLS_MPI_HALF_BITS */ | ||
#if !defined(MBEDTLS_MPI_UINT_MASK) | ||
#define MBEDTLS_MPI_UINT_MASK 0x7fffffffffffffffLL | ||
#endif /* MBEDTLS_MPI_UINT_MASK */ | ||
#elif defined(__GNUC__) && ( \ | ||
defined(__amd64__) || defined(__x86_64__) || \ | ||
defined(__ppc64__) || defined(__powerpc64__) || \ | ||
defined(__ia64__) || defined(__alpha__) || \ | ||
( defined(__sparc__) && defined(__arch64__) ) || \ | ||
defined(__s390x__) || defined(__mips64) || \ | ||
defined(__aarch64__) ) | ||
#if !defined(MBEDTLS_HAVE_INT64) | ||
#if !defined(MBEDTLS_HAVE_INT64) | ||
#define MBEDTLS_HAVE_INT64 | ||
#endif /* MBEDTLS_HAVE_INT64 */ | ||
typedef int64_t mbedtls_mpi_sint; | ||
typedef uint64_t mbedtls_mpi_uint; | ||
#if !defined(MBEDTLS_MPI_UINT_BITS) | ||
#define MBEDTLS_MPI_UINT_BITS 64 | ||
#endif /* MBEDTLS_MPI_UINT_BITS */ | ||
#if !defined(MBEDTLS_MPI_UINT_MASK) | ||
scottarc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#define MBEDTLS_MPI_UINT_MASK 0x7fffffffffffffffLL | ||
#endif /* MBEDTLS_MPI_UINT_MASK */ | ||
#if !defined(MBEDTLS_MPI_HALF_MASK) | ||
#define MBEDTLS_MPI_HALF_MASK 0xffffffff | ||
#endif /* MBEDTLS_MPI_HALF_MASK */ | ||
#if !defined(MBEDTLS_MPI_HALF_BITS) | ||
#define MBEDTLS_MPI_HALF_BITS 32 | ||
#endif /* MBEDTLS_MPI_HALF_BITS */ | ||
#if !defined(MBEDTLS_NO_UDBL_DIVISION) | ||
/* mbedtls_t_udbl defined as 128-bit unsigned int */ | ||
typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); | ||
|
@@ -151,6 +175,18 @@ | |
#endif /* !MBEDTLS_HAVE_INT64 */ | ||
typedef int64_t mbedtls_mpi_sint; | ||
typedef uint64_t mbedtls_mpi_uint; | ||
#if !defined(MBEDTLS_MPI_UINT_BITS) | ||
#define MBEDTLS_MPI_UINT_BITS 64 | ||
#endif /* MBEDTLS_MPI_UINT_BITS */ | ||
#if !defined(MBEDTLS_MPI_UINT_MASK) | ||
#define MBEDTLS_MPI_UINT_MASK 0x7fffffffffffffffLL | ||
#endif /* MBEDTLS_MPI_UINT_MASK */ | ||
#if !defined(MBEDTLS_MPI_HALF_MASK) | ||
#define MBEDTLS_MPI_HALF_MASK 0xffffffff | ||
#endif /* MBEDTLS_MPI_HALF_MASK */ | ||
#if !defined(MBEDTLS_MPI_HALF_BITS) | ||
#define MBEDTLS_MPI_HALF_BITS 32 | ||
#endif /* MBEDTLS_MPI_HALF_BITS */ | ||
#if !defined(MBEDTLS_NO_UDBL_DIVISION) | ||
/* mbedtls_t_udbl defined as 128-bit unsigned int */ | ||
typedef __uint128_t mbedtls_t_udbl; | ||
|
@@ -160,6 +196,18 @@ | |
/* Force 64-bit integers with unknown compiler */ | ||
typedef int64_t mbedtls_mpi_sint; | ||
typedef uint64_t mbedtls_mpi_uint; | ||
#if !defined(MBEDTLS_MPI_UINT_BITS) | ||
#define MBEDTLS_MPI_UINT_BITS 64 | ||
#endif /* MBEDTLS_MPI_UINT_BITS */ | ||
#if !defined(MBEDTLS_MPI_UINT_MASK) | ||
#define MBEDTLS_MPI_UINT_MASK 0x7fffffffffffffffLL | ||
#endif /* MBEDTLS_MPI_UINT_MASK */ | ||
#if !defined(MBEDTLS_MPI_HALF_MASK) | ||
#define MBEDTLS_MPI_HALF_MASK 0xffffffff | ||
#endif /* MBEDTLS_MPI_HALF_MASK */ | ||
#if !defined(MBEDTLS_MPI_HALF_BITS) | ||
#define MBEDTLS_MPI_HALF_BITS 32 | ||
#endif /* MBEDTLS_MPI_HALF_BITS */ | ||
#endif | ||
#endif /* !MBEDTLS_HAVE_INT32 */ | ||
|
||
|
@@ -170,6 +218,18 @@ | |
#endif /* !MBEDTLS_HAVE_INT32 */ | ||
typedef int32_t mbedtls_mpi_sint; | ||
typedef uint32_t mbedtls_mpi_uint; | ||
#if !defined(MBEDTLS_MPI_UINT_BITS) | ||
#define MBEDTLS_MPI_UINT_BITS 32 | ||
#endif /* MBEDTLS_MPI_UINT_BITS */ | ||
#if !defined(MBEDTLS_MPI_UINT_MASK) | ||
#define MBEDTLS_MPI_UINT_MASK 0x7fffffff | ||
#endif /* MBEDTLS_MPI_UINT_MASK */ | ||
#if !defined(MBEDTLS_MPI_HALF_MASK) | ||
#define MBEDTLS_MPI_HALF_MASK 0xffff | ||
#endif /* MBEDTLS_MPI_HALF_MASK */ | ||
#if !defined(MBEDTLS_MPI_HALF_BITS) | ||
#define MBEDTLS_MPI_HALF_BITS 16 | ||
#endif /* MBEDTLS_MPI_HALF_BITS */ | ||
#if !defined(MBEDTLS_NO_UDBL_DIVISION) | ||
typedef uint64_t mbedtls_t_udbl; | ||
#define MBEDTLS_HAVE_UDBL | ||
|
@@ -546,6 +606,27 @@ int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, | |
int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X, | ||
unsigned char *buf, size_t buflen ); | ||
|
||
/** | ||
* \brief Return the index of the highest non-zero limb in X. | ||
* | ||
* \param out | ||
* \param X The MPI to analyze. | ||
* This must point to an initialized MPI. | ||
* | ||
* \return Index of the highest nonzero limb in X. | ||
*/ | ||
int mbedtls_mpi_first_nonzero(size_t *out, const mbedtls_mpi *X); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This probably doesn't need to be a public function. Currently it doesn't seem to be used outside (In the past we have often exposed too much in the public API of each module, and we're trying to get better at it.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On another note, the function description doesn't state if it's constant-time. |
||
|
||
/** | ||
* \brief Is this equal to zero? (Constant-time) | ||
* | ||
* \param X The MPI to analyze. | ||
* This must point to an initialized MPI. | ||
* | ||
* \return 1 if all limbs in X == 0, 0 otherwise. | ||
*/ | ||
int mbedtls_mpi_is_zero( mbedtls_mpi *X ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note on naming: it would probably be good to use the (In an ideal world it should be the other way round: all functions would be constant-time except perhaps a few exceptions that would have a scary suffix such as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Second note: is that not a bit redundant with |
||
|
||
/** | ||
* \brief Perform a left-shift on an MPI: X <<= count | ||
* | ||
|
@@ -594,6 +675,30 @@ int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ); | |
*/ | ||
int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ); | ||
|
||
/** | ||
* \brief Compare two MPIs. Constant-time. | ||
* | ||
* \param X The left-hand MPI. This must point to an initialized MPI. | ||
* \param Y The right-hand MPI. This must point to an initialized MPI. | ||
* | ||
* \return \c 1 if \p X is greater than \p Y. | ||
* \return \c -1 if \p X is lesser than \p Y. | ||
* \return \c 0 if \p X is equal to \p Y. | ||
*/ | ||
int mbedtls_mpi_cmp_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way you're adding this function is very reasonable and is what we usually do when we want to extend an existing function. However, in this particular instance I don't think being leaky was ever part of the contract of the original function, so I think we can consider just changing the original function to the new constant-time implementation. The obvious concern is performance, but unless the difference is demonstrably large enough, security and code size usually trump performance. (Code size matters especially for LTS branches, where people want to be able to pick up updates and still fit in the flash of already deployed devices.) Could you try replacing the implementation of the existing function with your new CT implementation, running |
||
|
||
/** | ||
* \brief Compare an MPI with an integer. Constant-time. | ||
* | ||
* \param X The left-hand MPI. This must point to an initialized MPI. | ||
* \param z The integer value to compare \p X to. | ||
* | ||
* \return \c 1 if \p X is greater than \p z. | ||
* \return \c -1 if \p X is lesser than \p z. | ||
* \return \c 0 if \p X is equal to \p z. | ||
*/ | ||
int mbedtls_mpi_cmp_int_ct( const mbedtls_mpi *X, mbedtls_mpi_sint z ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as above. |
||
|
||
/** | ||
* \brief Check if an MPI is less than the other in constant time. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is indentation change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My IDE did that. I'll correct it on my next commit.