summaryrefslogtreecommitdiff
path: root/thirdparty/mbedtls/library/rsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/mbedtls/library/rsa.c')
-rw-r--r--thirdparty/mbedtls/library/rsa.c442
1 files changed, 120 insertions, 322 deletions
diff --git a/thirdparty/mbedtls/library/rsa.c b/thirdparty/mbedtls/library/rsa.c
index c8c23dba8c..8a5d40ff1e 100644
--- a/thirdparty/mbedtls/library/rsa.c
+++ b/thirdparty/mbedtls/library/rsa.c
@@ -2,13 +2,7 @@
* The RSA public-key cryptosystem
*
* Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- *
- * This file is provided under the Apache License 2.0, or the
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -62,11 +35,7 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_RSA_C)
@@ -74,6 +43,9 @@
#include "mbedtls/rsa_internal.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
#include <string.h>
@@ -102,28 +74,12 @@
#define RSA_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-#if defined(MBEDTLS_PKCS1_V15)
-/* constant-time buffer comparison */
-static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
-{
- size_t i;
- const unsigned char *A = (const unsigned char *) a;
- const unsigned char *B = (const unsigned char *) b;
- unsigned char diff = 0;
-
- for( i = 0; i < n; i++ )
- diff |= A[i] ^ B[i];
-
- return( diff );
-}
-#endif /* MBEDTLS_PKCS1_V15 */
-
int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
const mbedtls_mpi *N,
const mbedtls_mpi *P, const mbedtls_mpi *Q,
const mbedtls_mpi *D, const mbedtls_mpi *E )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
RSA_VALIDATE_RET( ctx != NULL );
if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
@@ -132,7 +88,7 @@ int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
if( N != NULL )
@@ -172,7 +128,7 @@ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
cleanup:
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
return( 0 );
}
@@ -323,7 +279,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
&ctx->Q ) ) != 0 )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
ctx->len = mbedtls_mpi_size( &ctx->N );
@@ -338,7 +294,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
&ctx->P, &ctx->Q );
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
else if( d_missing )
@@ -348,7 +304,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
&ctx->E,
&ctx->D ) ) != 0 )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
}
@@ -363,7 +319,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
&ctx->DP, &ctx->DQ, &ctx->QP );
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
#endif /* MBEDTLS_RSA_NO_CRT */
@@ -426,7 +382,7 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
mbedtls_mpi *D, mbedtls_mpi *E )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
@@ -470,7 +426,7 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
@@ -491,13 +447,13 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
#else
if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
DP, DQ, QP ) ) != 0 )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
#endif
@@ -564,7 +520,7 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
void *p_rng,
unsigned int nbits, int exponent )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi H, G, L;
int prime_quality = 0;
RSA_VALIDATE_RET( ctx != NULL );
@@ -665,8 +621,9 @@ cleanup:
if( ret != 0 )
{
mbedtls_rsa_free( ctx );
+
if( ( -ret & ~0x7f ) == 0 )
- ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_KEY_GEN_FAILED, ret );
return( ret );
}
@@ -761,7 +718,7 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen;
mbedtls_mpi T;
RSA_VALIDATE_RET( ctx != NULL );
@@ -799,7 +756,7 @@ cleanup:
mbedtls_mpi_free( &T );
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_PUBLIC_FAILED, ret ) );
return( 0 );
}
@@ -899,7 +856,7 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen;
/* Temporary holding the result */
@@ -1115,7 +1072,7 @@ cleanup:
mbedtls_mpi_free( &I );
if( ret != 0 && ret >= -0x007f )
- return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret ) );
return( ret );
}
@@ -1192,7 +1149,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
unsigned char *output )
{
size_t olen;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = output;
unsigned int hlen;
const mbedtls_md_info_t *md_info;
@@ -1202,7 +1159,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
- RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
RSA_VALIDATE_RET( label_len == 0 || label != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
@@ -1228,7 +1185,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
/* Generate a random octet string seed */
if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
p += hlen;
@@ -1238,7 +1195,8 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
p += hlen;
p += olen - 2 * hlen - 2 - ilen;
*p++ = 1;
- memcpy( p, input, ilen );
+ if( ilen != 0 )
+ memcpy( p, input, ilen );
mbedtls_md_init( &md_ctx );
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
@@ -1278,14 +1236,14 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
unsigned char *output )
{
size_t nb_pad, olen;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = output;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
- RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1316,7 +1274,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
/* Check if RNG failed to generate data */
if( rng_dl == 0 || ret != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
p++;
}
@@ -1330,7 +1288,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
}
*p++ = 0;
- memcpy( p, input, ilen );
+ if( ilen != 0 )
+ memcpy( p, input, ilen );
return( ( mode == MBEDTLS_RSA_PUBLIC )
? mbedtls_rsa_public( ctx, output, output )
@@ -1352,7 +1311,7 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
- RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
switch( ctx->padding )
{
@@ -1387,7 +1346,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
unsigned char *output,
size_t output_max_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t ilen, i, pad_len;
unsigned char *p, bad, pad_done;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
@@ -1508,7 +1467,8 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
}
*olen = ilen - (p - buf);
- memcpy( output, p, *olen );
+ if( *olen != 0 )
+ memcpy( output, p, *olen );
ret = 0;
cleanup:
@@ -1520,126 +1480,21 @@ cleanup:
#endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_PKCS1_V15)
-/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches.
- *
- * \param value The value to analyze.
- * \return Zero if \p value is zero, otherwise all-bits-one.
- */
-static unsigned all_or_nothing_int( unsigned value )
-{
- /* MSVC has a warning about unary minus on unsigned, but this is
- * well-defined and precisely what we want to do here */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
- return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-}
-
-/** Check whether a size is out of bounds, without branches.
- *
- * This is equivalent to `size > max`, but is likely to be compiled to
- * to code using bitwise operation rather than a branch.
- *
- * \param size Size to check.
- * \param max Maximum desired value for \p size.
- * \return \c 0 if `size <= max`.
- * \return \c 1 if `size > max`.
- */
-static unsigned size_greater_than( size_t size, size_t max )
-{
- /* Return the sign bit (1 for negative) of (max - size). */
- return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) );
-}
-
-/** Choose between two integer values, without branches.
- *
- * This is equivalent to `cond ? if1 : if0`, but is likely to be compiled
- * to code using bitwise operation rather than a branch.
- *
- * \param cond Condition to test.
- * \param if1 Value to use if \p cond is nonzero.
- * \param if0 Value to use if \p cond is zero.
- * \return \c if1 if \p cond is nonzero, otherwise \c if0.
- */
-static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 )
-{
- unsigned mask = all_or_nothing_int( cond );
- return( ( mask & if1 ) | (~mask & if0 ) );
-}
-
-/** Shift some data towards the left inside a buffer without leaking
- * the length of the data through side channels.
- *
- * `mem_move_to_left(start, total, offset)` is functionally equivalent to
- * ```
- * memmove(start, start + offset, total - offset);
- * memset(start + offset, 0, total - offset);
- * ```
- * but it strives to use a memory access pattern (and thus total timing)
- * that does not depend on \p offset. This timing independence comes at
- * the expense of performance.
- *
- * \param start Pointer to the start of the buffer.
- * \param total Total size of the buffer.
- * \param offset Offset from which to copy \p total - \p offset bytes.
- */
-static void mem_move_to_left( void *start,
- size_t total,
- size_t offset )
-{
- volatile unsigned char *buf = start;
- size_t i, n;
- if( total == 0 )
- return;
- for( i = 0; i < total; i++ )
- {
- unsigned no_op = size_greater_than( total - offset, i );
- /* The first `total - offset` passes are a no-op. The last
- * `offset` passes shift the data one byte to the left and
- * zero out the last byte. */
- for( n = 0; n < total - 1; n++ )
- {
- unsigned char current = buf[n];
- unsigned char next = buf[n+1];
- buf[n] = if_int( no_op, current, next );
- }
- buf[total-1] = if_int( no_op, buf[total-1], 0 );
- }
-}
-
/*
* Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
*/
int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
- int mode, size_t *olen,
+ int mode,
+ size_t *olen,
const unsigned char *input,
unsigned char *output,
size_t output_max_len )
{
- int ret;
- size_t ilen, i, plaintext_max_size;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t ilen;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
- /* The following variables take sensitive values: their value must
- * not leak into the observable behavior of the function other than
- * the designated outputs (output, olen, return value). Otherwise
- * this would open the execution of the function to
- * side-channel-based variants of the Bleichenbacher padding oracle
- * attack. Potential side channels include overall timing, memory
- * access patterns (especially visible to an adversary who has access
- * to a shared memory cache), and branches (especially visible to
- * an adversary who has access to a shared code cache or to a shared
- * branch predictor). */
- size_t pad_count = 0;
- unsigned bad = 0;
- unsigned char pad_done = 0;
- size_t plaintext_size = 0;
- unsigned output_too_large;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
@@ -1649,9 +1504,6 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
RSA_VALIDATE_RET( olen != NULL );
ilen = ctx->len;
- plaintext_max_size = ( output_max_len > ilen - 11 ?
- ilen - 11 :
- output_max_len );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1666,109 +1518,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
if( ret != 0 )
goto cleanup;
- /* Check and get padding length in constant time and constant
- * memory trace. The first byte must be 0. */
- bad |= buf[0];
-
- if( mode == MBEDTLS_RSA_PRIVATE )
- {
- /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
- * where PS must be at least 8 nonzero bytes. */
- bad |= buf[1] ^ MBEDTLS_RSA_CRYPT;
-
- /* Read the whole buffer. Set pad_done to nonzero if we find
- * the 0x00 byte and remember the padding length in pad_count. */
- for( i = 2; i < ilen; i++ )
- {
- pad_done |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
- pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
- }
- }
- else
- {
- /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
- * where PS must be at least 8 bytes with the value 0xFF. */
- bad |= buf[1] ^ MBEDTLS_RSA_SIGN;
-
- /* Read the whole buffer. Set pad_done to nonzero if we find
- * the 0x00 byte and remember the padding length in pad_count.
- * If there's a non-0xff byte in the padding, the padding is bad. */
- for( i = 2; i < ilen; i++ )
- {
- pad_done |= if_int( buf[i], 0, 1 );
- pad_count += if_int( pad_done, 0, 1 );
- bad |= if_int( pad_done, 0, buf[i] ^ 0xFF );
- }
- }
-
- /* If pad_done is still zero, there's no data, only unfinished padding. */
- bad |= if_int( pad_done, 0, 1 );
-
- /* There must be at least 8 bytes of padding. */
- bad |= size_greater_than( 8, pad_count );
-
- /* If the padding is valid, set plaintext_size to the number of
- * remaining bytes after stripping the padding. If the padding
- * is invalid, avoid leaking this fact through the size of the
- * output: use the maximum message size that fits in the output
- * buffer. Do it without branches to avoid leaking the padding
- * validity through timing. RSA keys are small enough that all the
- * size_t values involved fit in unsigned int. */
- plaintext_size = if_int( bad,
- (unsigned) plaintext_max_size,
- (unsigned) ( ilen - pad_count - 3 ) );
-
- /* Set output_too_large to 0 if the plaintext fits in the output
- * buffer and to 1 otherwise. */
- output_too_large = size_greater_than( plaintext_size,
- plaintext_max_size );
-
- /* Set ret without branches to avoid timing attacks. Return:
- * - INVALID_PADDING if the padding is bad (bad != 0).
- * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
- * plaintext does not fit in the output buffer.
- * - 0 if the padding is correct. */
- ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
- if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
- 0 ) );
-
- /* If the padding is bad or the plaintext is too large, zero the
- * data that we're about to copy to the output buffer.
- * We need to copy the same amount of data
- * from the same buffer whether the padding is good or not to
- * avoid leaking the padding validity through overall timing or
- * through memory or cache access patterns. */
- bad = all_or_nothing_int( bad | output_too_large );
- for( i = 11; i < ilen; i++ )
- buf[i] &= ~bad;
-
- /* If the plaintext is too large, truncate it to the buffer size.
- * Copy anyway to avoid revealing the length through timing, because
- * revealing the length is as bad as revealing the padding validity
- * for a Bleichenbacher attack. */
- plaintext_size = if_int( output_too_large,
- (unsigned) plaintext_max_size,
- (unsigned) plaintext_size );
-
- /* Move the plaintext to the leftmost position where it can start in
- * the working buffer, i.e. make it start plaintext_max_size from
- * the end of the buffer. Do this with a memory access trace that
- * does not depend on the plaintext size. After this move, the
- * starting location of the plaintext is no longer sensitive
- * information. */
- mem_move_to_left( buf + ilen - plaintext_max_size,
- plaintext_max_size,
- plaintext_max_size - plaintext_size );
-
- /* Finally copy the decrypted plaintext plus trailing zeros
- * into the output buffer. */
- memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size );
-
- /* Report the amount of data we copied to the output buffer. In case
- * of errors (bad padding or output too large), the value of *olen
- * when this function returns is not specified. Making it equivalent
- * to the good case limits the risks of leaking the padding validity. */
- *olen = plaintext_size;
+ ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding( mode, buf, ilen,
+ output, output_max_len, olen );
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -1816,23 +1567,21 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
}
#if defined(MBEDTLS_PKCS1_V21)
-/*
- * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
- */
-int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
+static int rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode,
mbedtls_md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
+ int saltlen,
unsigned char *sig )
{
size_t olen;
unsigned char *p = sig;
- unsigned char salt[MBEDTLS_MD_MAX_SIZE];
+ unsigned char *salt = NULL;
size_t slen, min_slen, hlen, offset = 0;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t msb;
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
@@ -1868,31 +1617,44 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
hlen = mbedtls_md_get_size( md_info );
- /* Calculate the largest possible salt length. Normally this is the hash
- * length, which is the maximum length the salt can have. If there is not
- * enough room, use the maximum salt length that fits. The constraint is
- * that the hash length plus the salt length plus 2 bytes must be at most
- * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
- * (PKCS#1 v2.2) §9.1.1 step 3. */
- min_slen = hlen - 2;
- if( olen < hlen + min_slen + 2 )
+ if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY)
+ {
+ /* Calculate the largest possible salt length, up to the hash size.
+ * Normally this is the hash length, which is the maximum salt length
+ * according to FIPS 185-4 §5.5 (e) and common practice. If there is not
+ * enough room, use the maximum salt length that fits. The constraint is
+ * that the hash length plus the salt length plus 2 bytes must be at most
+ * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
+ * (PKCS#1 v2.2) §9.1.1 step 3. */
+ min_slen = hlen - 2;
+ if( olen < hlen + min_slen + 2 )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ else if( olen >= hlen + hlen + 2 )
+ slen = hlen;
+ else
+ slen = olen - hlen - 2;
+ }
+ else if ( (saltlen < 0) || (saltlen + hlen + 2 > olen) )
+ {
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- else if( olen >= hlen + hlen + 2 )
- slen = hlen;
+ }
else
- slen = olen - hlen - 2;
+ {
+ slen = (size_t) saltlen;
+ }
memset( sig, 0, olen );
- /* Generate salt of length slen */
- if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
-
/* Note: EMSA-PSS encoding is over the length of N - 1 bits */
msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
p += olen - hlen - slen - 2;
*p++ = 0x01;
- memcpy( p, salt, slen );
+
+ /* Generate salt of length slen in place in the encoded message */
+ salt = p;
+ if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
+
p += slen;
mbedtls_md_init( &md_ctx );
@@ -1926,8 +1688,6 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
p += hlen;
*p++ = 0xBC;
- mbedtls_platform_zeroize( salt, sizeof( salt ) );
-
exit:
mbedtls_md_free( &md_ctx );
@@ -1938,6 +1698,40 @@ exit:
? mbedtls_rsa_public( ctx, sig, sig )
: mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
}
+
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with
+ * the option to pass in the salt length.
+ */
+int mbedtls_rsa_rsassa_pss_sign_ext( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ int saltlen,
+ unsigned char *sig )
+{
+ return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, md_alg,
+ hashlen, hash, saltlen, sig );
+}
+
+
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
+ */
+int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
+{
+ return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
+ hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig );
+}
#endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_PKCS1_V15)
@@ -2087,7 +1881,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
const unsigned char *hash,
unsigned char *sig )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *sig_try = NULL, *verif = NULL;
RSA_VALIDATE_RET( ctx != NULL );
@@ -2139,7 +1933,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
- if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
+ if( mbedtls_ct_memcmp( verif, sig, ctx->len ) != 0 )
{
ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
goto cleanup;
@@ -2148,9 +1942,13 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
memcpy( sig, sig_try, ctx->len );
cleanup:
+ mbedtls_platform_zeroize( sig_try, ctx->len );
+ mbedtls_platform_zeroize( verif, ctx->len );
mbedtls_free( sig_try );
mbedtls_free( verif );
+ if( ret != 0 )
+ memset( sig, '!', ctx->len );
return( ret );
}
#endif /* MBEDTLS_PKCS1_V15 */
@@ -2209,7 +2007,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
int expected_salt_len,
const unsigned char *sig )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t siglen;
unsigned char *p;
unsigned char *hash_start;
@@ -2437,8 +2235,8 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
* Compare
*/
- if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected,
- sig_len ) ) != 0 )
+ if( ( ret = mbedtls_ct_memcmp( encoded, encoded_expected,
+ sig_len ) ) != 0 )
{
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
goto cleanup;
@@ -2506,7 +2304,7 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
*/
int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
RSA_VALIDATE_RET( dst != NULL );
RSA_VALIDATE_RET( src != NULL );