diff --git a/library/constant_time.c b/library/constant_time.c index cbfc8e59a..d48d646ee 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -418,3 +418,24 @@ void mbedtls_cf_memcpy_if_eq( unsigned char *dst, for( size_t i = 0; i < len; i++ ) dst[i] = ( src[i] & mask ) | ( dst[i] & ~mask ); } + +/* + * Constant-flow memcpy from variable position in buffer. + * - functionally equivalent to memcpy(dst, src + offset_secret, len) + * - but with execution flow independent from the value of offset_secret. + */ +void mbedtls_cf_memcpy_offset( + unsigned char *dst, + const unsigned char *src_base, + size_t offset_secret, + size_t offset_min, size_t offset_max, + size_t len ) +{ + size_t offset; + + for( offset = offset_min; offset <= offset_max; offset++ ) + { + mbedtls_cf_memcpy_if_eq( dst, src_base + offset, len, + offset, offset_secret ); + } +} diff --git a/library/constant_time.h b/library/constant_time.h index ae491b892..060aca388 100644 --- a/library/constant_time.h +++ b/library/constant_time.h @@ -74,3 +74,27 @@ void mbedtls_cf_memcpy_if_eq( unsigned char *dst, const unsigned char *src, size_t len, size_t c1, size_t c2 ); + +/** Copy data from a secret position with constant flow. + * + * This function copies \p len bytes from \p src_base + \p offset_secret to \p + * dst, with a code flow and memory access pattern that does not depend on \p + * offset_secret, but only on \p offset_min, \p offset_max and \p len. + * + * \param dst The destination buffer. This must point to a writable + * buffer of at least \p len bytes. + * \param src_base The base of the source buffer. This must point to a + * readable buffer of at least \p offset_max + \p len + * bytes. + * \param offset_secret The offset in the source buffer from which to copy. + * This must be no less than \p offset_min and no greater + * than \p offset_max. + * \param offset_min The minimal value of \p offset_secret. + * \param offset_max The maximal value of \p offset_secret. + * \param len The number of bytes to copy. + */ +void mbedtls_cf_memcpy_offset( unsigned char *dst, + const unsigned char *src_base, + size_t offset_secret, + size_t offset_min, size_t offset_max, + size_t len ); diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 42579ea9a..fe73130b2 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -1133,27 +1133,6 @@ cleanup: mbedtls_md_free( &aux ); return( ret ); } - -/* - * Constant-flow memcpy from variable position in buffer. - * - functionally equivalent to memcpy(dst, src + offset_secret, len) - * - but with execution flow independent from the value of offset_secret. - */ -MBEDTLS_STATIC_TESTABLE void mbedtls_cf_memcpy_offset( - unsigned char *dst, - const unsigned char *src_base, - size_t offset_secret, - size_t offset_min, size_t offset_max, - size_t len ) -{ - size_t offset; - - for( offset = offset_min; offset <= offset_max; offset++ ) - { - mbedtls_cf_memcpy_if_eq( dst, src_base + offset, len, - offset, offset_secret ); - } -} #endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,