Squashed commit upgrading to mbedtls-2.16.5
Squash merging branch import/mbedtls-2.16.5
058aefb2bfa4 ("core: mbedtls: use SHA-256 crypto accelerated routines")
bcef9baed8f1 ("core: mbedtls: use SHA-1 crypto accelerated routines")
c9359f31db12 ("core: mbedtls: use AES crypto accelerated routines")
0e6c1e2642c7 ("core: merge tee_*_get_digest_size() into a single function")
0cb3c28a2f4d ("libmbedtls: mbedtls_mpi_exp_mod(): optimize mempool usage")
5abf0e6ab72e ("libmbedtls: mbedtls_mpi_exp_mod(): reduce stack usage")
2ccc08ac7fef ("libmbedtls: preserve mempool usage on reinit")
cd2a24648569 ("libmbedtls: mbedtls_mpi_exp_mod() initialize W")
7727182ecb56 ("libmbedtls: fix no CRT issue")
120737075dcf ("libmbedtls: add interfaces in mbedtls for context memory operation")
1126250b3af8 ("libmbedtls: add missing source file chachapoly.c")
23972e9f1c98 ("libmedtls: mpi_miller_rabin: increase count limit")
1fcbc05b3cd2 ("libmbedtls: add mbedtls_mpi_init_mempool()")
66e03f068078 ("libmbedtls: make mbedtls_mpi_mont*() available")
d07e0ce56236 ("libmbedtls: refine mbedtls license header")
491ee2cd0ff4 ("mbedtls: configure mbedtls to reach for config")
9b6cee685d9a ("mbedtls: remove default include/mbedtls/config.h")
84f7467a0a91 ("Import mbedtls-2.16.5")
Signed-off-by: Jerome Forissier <jerome@forissier.org>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/lib/libmbedtls/mbedtls/library/ecdsa.c b/lib/libmbedtls/mbedtls/library/ecdsa.c
index bb32596..517d187 100644
--- a/lib/libmbedtls/mbedtls/library/ecdsa.c
+++ b/lib/libmbedtls/mbedtls/library/ecdsa.c
@@ -172,11 +172,11 @@
}
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
-#define ECDSA_RS_ECP &rs_ctx->ecp
+#define ECDSA_RS_ECP ( rs_ctx == NULL ? NULL : &rs_ctx->ecp )
/* Utility macro for checking and updating ops budget */
#define ECDSA_BUDGET( ops ) \
- MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, &rs_ctx->ecp, ops ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, ECDSA_RS_ECP, ops ) );
/* Call this when entering a function that needs its own sub-context */
#define ECDSA_RS_ENTER( SUB ) do { \
@@ -254,6 +254,8 @@
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+ int (*f_rng_blind)(void *, unsigned char *, size_t),
+ void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
int ret, key_tries, sign_tries;
@@ -295,7 +297,7 @@
*p_sign_tries = 0;
do
{
- if( *p_sign_tries++ > 10 )
+ if( (*p_sign_tries)++ > 10 )
{
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup;
@@ -308,7 +310,7 @@
*p_key_tries = 0;
do
{
- if( *p_key_tries++ > 10 )
+ if( (*p_key_tries)++ > 10 )
{
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup;
@@ -323,7 +325,9 @@
mul:
#endif
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &R, pk, &grp->G,
- f_rng, p_rng, ECDSA_RS_ECP ) );
+ f_rng_blind,
+ p_rng_blind,
+ ECDSA_RS_ECP ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pr, &R.X, &grp->N ) );
}
while( mbedtls_mpi_cmp_int( pr, 0 ) == 0 );
@@ -349,7 +353,8 @@
* Generate a random value to blind inv_mod in next step,
* avoiding a potential timing leak.
*/
- MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &t, f_rng, p_rng ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &t, f_rng_blind,
+ p_rng_blind ) );
/*
* Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
@@ -358,6 +363,7 @@
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pk, pk, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
@@ -392,8 +398,9 @@
ECDSA_VALIDATE_RET( f_rng != NULL );
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
+ /* Use the same RNG for both blinding and ephemeral key generation */
return( ecdsa_sign_restartable( grp, r, s, d, buf, blen,
- f_rng, p_rng, NULL ) );
+ f_rng, p_rng, f_rng, p_rng, NULL ) );
}
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
@@ -405,6 +412,8 @@
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg,
+ int (*f_rng_blind)(void *, unsigned char *, size_t),
+ void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
int ret;
@@ -451,8 +460,70 @@
ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, p_rng );
#else
- ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
- mbedtls_hmac_drbg_random, p_rng, rs_ctx );
+ if( f_rng_blind != NULL )
+ ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
+ mbedtls_hmac_drbg_random, p_rng,
+ f_rng_blind, p_rng_blind, rs_ctx );
+ else
+ {
+ mbedtls_hmac_drbg_context *p_rng_blind_det;
+
+#if !defined(MBEDTLS_ECP_RESTARTABLE)
+ /*
+ * To avoid reusing rng_ctx and risking incorrect behavior we seed a
+ * second HMAC-DRBG with the same seed. We also apply a label to avoid
+ * reusing the bits of the ephemeral key for blinding and eliminate the
+ * risk that they leak this way.
+ */
+ const char* blind_label = "BLINDING CONTEXT";
+ mbedtls_hmac_drbg_context rng_ctx_blind;
+
+ mbedtls_hmac_drbg_init( &rng_ctx_blind );
+ p_rng_blind_det = &rng_ctx_blind;
+
+ mbedtls_hmac_drbg_seed_buf( p_rng_blind_det, md_info,
+ data, 2 * grp_len );
+ ret = mbedtls_hmac_drbg_update_ret( p_rng_blind_det,
+ (const unsigned char*) blind_label,
+ strlen( blind_label ) );
+ if( ret != 0 )
+ {
+ mbedtls_hmac_drbg_free( &rng_ctx_blind );
+ goto cleanup;
+ }
+#else
+ /*
+ * In the case of restartable computations we would either need to store
+ * the second RNG in the restart context too or set it up at every
+ * restart. The first option would penalize the correct application of
+ * the function and the second would defeat the purpose of the
+ * restartable feature.
+ *
+ * Therefore in this case we reuse the original RNG. This comes with the
+ * price that the resulting signature might not be a valid deterministic
+ * ECDSA signature with a very low probability (same magnitude as
+ * successfully guessing the private key). However even then it is still
+ * a valid ECDSA signature.
+ */
+ p_rng_blind_det = p_rng;
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+ /*
+ * Since the output of the RNGs is always the same for the same key and
+ * message, this limits the efficiency of blinding and leaks information
+ * through side channels. After mbedtls_ecdsa_sign_det() is removed NULL
+ * won't be a valid value for f_rng_blind anymore. Therefore it should
+ * be checked by the caller and this branch and check can be removed.
+ */
+ ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
+ mbedtls_hmac_drbg_random, p_rng,
+ mbedtls_hmac_drbg_random, p_rng_blind_det,
+ rs_ctx );
+
+#if !defined(MBEDTLS_ECP_RESTARTABLE)
+ mbedtls_hmac_drbg_free( &rng_ctx_blind );
+#endif
+ }
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
cleanup:
@@ -465,11 +536,12 @@
}
/*
- * Deterministic signature wrapper
+ * Deterministic signature wrappers
*/
-int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
- const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
- mbedtls_md_type_t md_alg )
+int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+ mbedtls_mpi *s, const mbedtls_mpi *d,
+ const unsigned char *buf, size_t blen,
+ mbedtls_md_type_t md_alg )
{
ECDSA_VALIDATE_RET( grp != NULL );
ECDSA_VALIDATE_RET( r != NULL );
@@ -477,7 +549,27 @@
ECDSA_VALIDATE_RET( d != NULL );
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
- return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, NULL ) );
+ return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg,
+ NULL, NULL, NULL ) );
+}
+
+int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+ mbedtls_mpi *s, const mbedtls_mpi *d,
+ const unsigned char *buf, size_t blen,
+ mbedtls_md_type_t md_alg,
+ int (*f_rng_blind)(void *, unsigned char *,
+ size_t),
+ void *p_rng_blind )
+{
+ ECDSA_VALIDATE_RET( grp != NULL );
+ ECDSA_VALIDATE_RET( r != NULL );
+ ECDSA_VALIDATE_RET( s != NULL );
+ ECDSA_VALIDATE_RET( d != NULL );
+ ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
+ ECDSA_VALIDATE_RET( f_rng_blind != NULL );
+
+ return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg,
+ f_rng_blind, p_rng_blind, NULL ) );
}
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@@ -656,11 +748,9 @@
mbedtls_mpi_init( &s );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
- (void) f_rng;
- (void) p_rng;
-
MBEDTLS_MPI_CHK( ecdsa_sign_det_restartable( &ctx->grp, &r, &s, &ctx->d,
- hash, hlen, md_alg, rs_ctx ) );
+ hash, hlen, md_alg, f_rng,
+ p_rng, rs_ctx ) );
#else
(void) md_alg;
@@ -668,8 +758,10 @@
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
hash, hlen, f_rng, p_rng ) );
#else
+ /* Use the same RNG for both blinding and ephemeral key generation */
MBEDTLS_MPI_CHK( ecdsa_sign_restartable( &ctx->grp, &r, &s, &ctx->d,
- hash, hlen, f_rng, p_rng, rs_ctx ) );
+ hash, hlen, f_rng, p_rng, f_rng,
+ p_rng, rs_ctx ) );
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@@ -800,11 +892,16 @@
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
+ int ret = 0;
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( f_rng != NULL );
- return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
- mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
+ ret = mbedtls_ecp_group_load( &ctx->grp, gid );
+ if( ret != 0 )
+ return( ret );
+
+ return( mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d,
+ &ctx->Q, f_rng, p_rng ) );
}
#endif /* !MBEDTLS_ECDSA_GENKEY_ALT */