From 3b155ebe1aaffc87acea7bfc4f637ccbc2a3e11f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Mi=C5=9B?= Date: Thu, 7 Jun 2018 18:00:26 +0200 Subject: [PATCH] [nrf52840] fix cc310 with mbedtls 2.9.0 (#2756) * Update ECP implementation using CC310 * Use software AES for AES-256 in nRF52840 platform --- .../openthread-core-nrf52840-config.h | 14 ++++++++ .../libraries/crypto/aes_alt.c | 5 ++- .../libraries/crypto/aes_alt.h | 4 +++ .../libraries/crypto/ecp_alt_cc310.c | 35 +++++++++++-------- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/examples/platforms/nrf52840/openthread-core-nrf52840-config.h b/examples/platforms/nrf52840/openthread-core-nrf52840-config.h index 1aeda9fe9..dc504842d 100644 --- a/examples/platforms/nrf52840/openthread-core-nrf52840-config.h +++ b/examples/platforms/nrf52840/openthread-core-nrf52840-config.h @@ -158,6 +158,20 @@ */ #define OPENTHREAD_CONFIG_HEAP_SIZE_NO_DTLS 2048 +/** + * @def NRF_MBEDTLS_AES_ALT_INTERRUPT_CONTEXT + * + * Define as 1 to enable AES usage in interrupt context and AES-256, by introducing a software AES under platform layer. + * + * @note This feature must be enabled to support AES-256 used by Commissioner and Joiner. + * + */ +#if OPENTHREAD_ENABLE_COMMISSIONER || OPENTHREAD_ENABLE_JOINER +#define NRF_MBEDTLS_AES_ALT_INTERRUPT_CONTEXT 1 +#else +#define NRF_MBEDTLS_AES_ALT_INTERRUPT_CONTEXT 0 +#endif + /* * Suppress the ARMCC warning on unreachable statement, * e.g. break after assert(false) or ExitNow() macro. diff --git a/third_party/NordicSemiconductor/libraries/crypto/aes_alt.c b/third_party/NordicSemiconductor/libraries/crypto/aes_alt.c index 78d21b12c..a5882db7c 100644 --- a/third_party/NordicSemiconductor/libraries/crypto/aes_alt.c +++ b/third_party/NordicSemiconductor/libraries/crypto/aes_alt.c @@ -64,6 +64,7 @@ void mbedtls_aes_init(mbedtls_aes_context * ctx) // Check if this function is called from main thread. if (active_vector_id == 0) { + aes_soft_init(ctx); #endif aes_cc310_init(ctx); #if NRF_MBEDTLS_AES_ALT_INTERRUPT_CONTEXT @@ -85,6 +86,7 @@ void mbedtls_aes_free(mbedtls_aes_context * ctx) #endif aes_cc310_free(ctx); #if NRF_MBEDTLS_AES_ALT_INTERRUPT_CONTEXT + aes_soft_free(ctx); } else { @@ -100,7 +102,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context * ctx, int result; #if NRF_MBEDTLS_AES_ALT_INTERRUPT_CONTEXT - if (ctx->using_cc310) + if (ctx->using_cc310 && keybits == 128) { #endif result = aes_cc310_setkey_enc(ctx, key, keybits); @@ -108,6 +110,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context * ctx, } else { + ctx->using_cc310 = false; result = aes_soft_setkey_enc(ctx, key, keybits); } #endif diff --git a/third_party/NordicSemiconductor/libraries/crypto/aes_alt.h b/third_party/NordicSemiconductor/libraries/crypto/aes_alt.h index e57394794..b0ecf287d 100644 --- a/third_party/NordicSemiconductor/libraries/crypto/aes_alt.h +++ b/third_party/NordicSemiconductor/libraries/crypto/aes_alt.h @@ -77,8 +77,10 @@ typedef struct bool using_cc310; ///< Indicate whether it's using cc310 or not. #endif +#if !NRF_MBEDTLS_AES_ALT_INTERRUPT_CONTEXT union { +#endif // !NRF_MBEDTLS_AES_ALT_INTERRUPT_CONTEXT struct { SaSiAesUserContext_t user_context; ///< User context for CC310 AES. @@ -92,7 +94,9 @@ typedef struct uint32_t *rk; ///< AES round keys */ uint32_t buf[68]; ///< unaligned data */ }; +#if !NRF_MBEDTLS_AES_ALT_INTERRUPT_CONTEXT }; +#endif // !NRF_MBEDTLS_AES_ALT_INTERRUPT_CONTEXT } mbedtls_aes_context; diff --git a/third_party/NordicSemiconductor/libraries/crypto/ecp_alt_cc310.c b/third_party/NordicSemiconductor/libraries/crypto/ecp_alt_cc310.c index 89ce8833f..9baa073c0 100644 --- a/third_party/NordicSemiconductor/libraries/crypto/ecp_alt_cc310.c +++ b/third_party/NordicSemiconductor/libraries/crypto/ecp_alt_cc310.c @@ -50,6 +50,7 @@ * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf * RFC 4492 for the related TLS structures and constants + * RFC 7748 for the Curve448 and Curve25519 curve definitions * * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf * @@ -157,7 +158,8 @@ static unsigned long add_count, dbl_count, mul_count; #define ECP_SHORTWEIERSTRASS #endif -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ + defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) #define ECP_MONTGOMERY #endif @@ -1898,7 +1900,6 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, #if defined(ECP_MONTGOMERY) if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) ret = ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ); - #endif #if defined(ECP_SHORTWEIERSTRASS) if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) @@ -1913,6 +1914,7 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, ret = ecp_mul_comb( grp, R, m, P, f_rng, p_rng ); } } + #endif #if defined(MBEDTLS_ECP_INTERNAL_ALT) cleanup: @@ -2060,6 +2062,8 @@ cleanup: static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) { /* [Curve25519 p. 5] Just check X is the correct number of bytes */ + /* Allow any public value, if it's too big then we'll just reduce it mod p + * (RFC 7748 sec. 5 para. 3). */ if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 ) return( MBEDTLS_ERR_ECP_INVALID_KEY ); @@ -2095,14 +2099,18 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi * #if defined(ECP_MONTGOMERY) if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) { - /* see [Curve25519] page 5 */ + /* see RFC 7748 sec. 5 para. 5 */ if( mbedtls_mpi_get_bit( d, 0 ) != 0 || mbedtls_mpi_get_bit( d, 1 ) != 0 || - mbedtls_mpi_get_bit( d, 2 ) != 0 || mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */ return( MBEDTLS_ERR_ECP_INVALID_KEY ); else - return( 0 ); + + /* see [Curve25519] page 5 */ + if( grp->nbits == 254 && mbedtls_mpi_get_bit( d, 2 ) != 0 ) + return( MBEDTLS_ERR_ECP_INVALID_KEY ); + + return( 0 ); } #endif /* ECP_MONTGOMERY */ #if defined(ECP_SHORTWEIERSTRASS) @@ -2223,10 +2231,14 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, else MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) ); - /* Make sure the last three bits are unset */ + /* Make sure the last two bits are unset for Curve448, three bits for + Curve25519 */ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) ); + if( grp->nbits == 254 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) ); + } } else #endif /* ECP_MONTGOMERY */ @@ -2242,7 +2254,6 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, { /* SEC1 3.2.1: Generate d such that 1 <= n < N */ int count = 0; - unsigned char rnd[MBEDTLS_ECP_MAX_BYTES]; /* * Match the procedure given in RFC 6979 (deterministic ECDSA): @@ -2253,8 +2264,7 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, */ do { - MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) ); /* @@ -2280,10 +2290,7 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); cleanup: - if( ret != 0 ) - return( ret ); - - return( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) ); + return( ret ); } /*