From 4ced7c25069a728212bc3c57307550183b4f0363 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 18 Aug 2016 12:38:46 +0100 Subject: [PATCH] ECP: Add module and function level replacement options. --- .../mbedtls/alt_internal/ecp_function_alt.h | 82 +++++++++++++ include/mbedtls/check_config.h | 40 +++++++ include/mbedtls/config.h | 68 ++++++++++- include/mbedtls/ecp.h | 12 +- library/ecp.c | 111 +++++++++++++++++- library/ecp_curves.c | 4 + 6 files changed, 307 insertions(+), 10 deletions(-) create mode 100644 include/mbedtls/alt_internal/ecp_function_alt.h diff --git a/include/mbedtls/alt_internal/ecp_function_alt.h b/include/mbedtls/alt_internal/ecp_function_alt.h new file mode 100644 index 000000000..e1cca10d9 --- /dev/null +++ b/include/mbedtls/alt_internal/ecp_function_alt.h @@ -0,0 +1,82 @@ +/** + * \file alt_func_internal.h + * + * \brief Function declarations for alternate implementation. + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_ECP_FUNCTION_ALT_H +#define MBEDTLS_ECP_FUNCTION_ALT_H + + +#if defined(MBEDTLS_ECP_FUNCTION_ALT) + +unsigned char ecp_alt_grp_capable( const mbedtls_ecp_group *grp ); + +#if defined(MBEDTLS_ECP_ALT_INIT) +int ecp_alt_init( const mbedtls_ecp_group *grp ); +#endif + +#if defined(MBEDTLS_ECP_ALT_DEINIT) +void ecp_alt_deinit( const mbedtls_ecp_group *grp ); +#endif + +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) +int ecp_randomize_jac_alt( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); +#endif + +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) +int ecp_add_mixed_alt( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) +int ecp_double_jac_alt( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point *P ); +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) +int ecp_normalize_jac_many_alt( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *T[], size_t t_len ); +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) +int ecp_normalize_jac_alt( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt ); +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) +int ecp_double_add_mxz_alt( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, mbedtls_ecp_point *S, + const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q, + const mbedtls_mpi *d ); +#endif + +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) +int ecp_randomize_mxz_alt( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) +int ecp_normalize_mxz_alt( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P ); +#endif + +#endif // MBEDTLS_ECP_FUNCTION_ALT + +#endif /* ecp_function_alt.h */ + diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index fe86c1e8d..8495ef26b 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -150,6 +150,46 @@ #error "MBEDTLS_GCM_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_ECP_ALT_INIT) && !defined(MBEDTLS_ECP_FUNCTION_ALT) +#error "MBEDTLS_ECP_ALT_INIT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_ALT_DEINIT) && !defined(MBEDTLS_ECP_FUNCTION_ALT) +#error "MBEDTLS_ECP_ALT_DEINIT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_FUNCTION_ALT) +#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) && !defined(MBEDTLS_ECP_FUNCTION_ALT) +#error "MBEDTLS_ECP_ADD_MIXED_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && !defined(MBEDTLS_ECP_FUNCTION_ALT) +#error "MBEDTLS_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDTLS_ECP_FUNCTION_ALT) +#error "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDTLS_ECP_FUNCTION_ALT) +#error "MBEDTLS_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDTLS_ECP_FUNCTION_ALT) +#error "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_FUNCTION_ALT) +#error "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_FUNCTION_ALT) +#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C) #error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" #endif diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 0f7e29bcf..a6976dc3a 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -218,9 +218,9 @@ * \def MBEDTLS_AES_ALT * * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your - * alternate core implementation of a symmetric crypto or hash module (e.g. - * platform specific assembly optimized implementations). Keep in mind that - * the function prototypes should remain the same. + * alternate core implementation of a symmetric crypto, an arithmetic or hash + * module (e.g. platform specific assembly optimized implementations). Keep + * in mind that the function prototypes should remain the same. * * This replaces the whole module. If you only want to replace one of the * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. @@ -246,6 +246,14 @@ //#define MBEDTLS_SHA1_ALT //#define MBEDTLS_SHA256_ALT //#define MBEDTLS_SHA512_ALT +/* + * When replacing the elliptic curve module, pleace consider, that it is + * implemented with two .c files: + * - ecp.c + * - ecp_curves.c + * Please make sure that you provide functionality for both of them. + */ +//#define MBEDTLS_ECP_ALT /** * \def MBEDTLS_MD2_PROCESS_ALT @@ -285,6 +293,60 @@ //#define MBEDTLS_AES_ENCRYPT_ALT //#define MBEDTLS_AES_DECRYPT_ALT +/** + * \def MBEDTLS_ECP_FUNCTION_ALT + * + * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternate core implementation of elliptic curve arithmetic. Keep in mind that + * function prototypes should remain the same. + * + * This partially replaces one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation + * is still present and it is used for group structures not supported by the + * alternative. + * + * Any of these options become available by turning MBEDTLS_ECP_FUNCTION_ALT and + * implementing the following function: + * unsigned char ecp_alt_grp_capable( const mbedtls_ecp_group *grp ) + * This should return 1 if the replacement functions implement arithmetic for + * the given group and 0 otherwise. + * + * The functions + * int ecp_alt_init( const mbedtls_ecp_group *grp ) + * void ecp_alt_deinit( const mbedtls_ecp_group *grp ) + * can be turned on by MBEDTLS_ECP_ALT_INIT and MBEDTLS_ECP_ALT_DEINIT. + * They are called before and after each point operation and provide an + * opportunity to implement optimized set up and tear down instructions. + * + * Example: In case you uncomment MBEDTLS_ECP_FUNCTION_ALT and + * MBEDTLS_ECP_DOUBLE_JAC, mbed TLS will still provide the ecp_double_jac + * function, but will use your ecp_double_jac_alt if the group is supported + * (your ecp_alt_grp_capable function returns 1 when receives it as an + * argument). If the group is not supported then the original implementation is + * used. The other functions and the definition of mbedtls_ecp_group and + * mbedtls_ecp_point will not change, so your implementation of + * ecp_double_jac_alt and ecp_alt_grp_capable must be compatible with + * this definition. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +/* Required for all the functions in this section */ +//#define MBEDTLS_ECP_FUNCTION_ALT +/* Utility functions for setup and cleanup */ +//#define MBEDTLS_ECP_ALT_INIT +//#define MBEDTLS_ECP_ALT_DEINIT +/* Support for Weierstrass curves with Jacobi representation */ +//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +//#define MBEDTLS_ECP_ADD_MIXED_ALT +//#define MBEDTLS_ECP_DOUBLE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + /** * \def MBEDTLS_TEST_NULL_ENTROPY * diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 5246c789d..d75f038d4 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -37,6 +37,10 @@ #define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */ #define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< Signature is valid but shorter than the user-supplied length. */ +#if !defined(MBEDTLS_ECP_ALT) +// Regular implementation +// + #ifdef __cplusplus extern "C" { #endif @@ -654,16 +658,22 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv ); #if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * * \return 0 if successful, or 1 if a test failed */ int mbedtls_ecp_self_test( int verbose ); -#endif + +#endif // MBEDTLS_SELF_TEST #ifdef __cplusplus } #endif +#else /* MBEDTLS_ECP_ALT */ +#include "ecp_alt.h" +#endif /* MBEDTLS_ECP_ALT */ + #endif /* ecp.h */ diff --git a/library/ecp.c b/library/ecp.c index f51f2251e..be55b4853 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -52,6 +52,8 @@ #include +#if !defined(MBEDTLS_ECP_ALT) + #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else @@ -62,6 +64,8 @@ #define mbedtls_free free #endif +#include "mbedtls/alt_internal/ecp_function_alt.h" + #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline @@ -748,6 +752,12 @@ static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *p if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ) return( 0 ); +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) + if ( ecp_alt_grp_capable( grp ) ) + { + return ecp_normalize_jac_alt( grp, pt ); + } +#endif /* #if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) */ mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); /* @@ -796,6 +806,13 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp, if( t_len < 2 ) return( ecp_normalize_jac( grp, *T ) ); +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) + if ( ecp_alt_grp_capable( grp ) ) + { + return ecp_normalize_jac_many_alt(grp, T, t_len); + } +#endif + if( ( c = mbedtls_calloc( t_len, sizeof( mbedtls_mpi ) ) ) == NULL ) return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); @@ -912,6 +929,13 @@ static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, dbl_count++; #endif +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) + if ( ecp_alt_grp_capable( grp ) ) + { + return ecp_double_jac_alt( grp, R, P ); + } +#endif /* #if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) */ + mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U ); /* Special case for A = -3 */ @@ -1003,6 +1027,13 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, add_count++; #endif +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) + if ( ecp_alt_grp_capable( grp ) ) + { + return ecp_add_mixed_alt( grp, R, P, Q ); + } +#endif /* #if defined(MBEDTLS_ECP_ADD_MIXED_ALT) */ + /* * Trivial cases: P == 0 or Q == 0 (case 1) */ @@ -1080,9 +1111,17 @@ static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *p { int ret; mbedtls_mpi l, ll; - size_t p_size = ( grp->pbits + 7 ) / 8; + size_t p_size; int count = 0; +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) + if ( ecp_alt_grp_capable( grp ) ) + { + return ecp_randomize_jac_alt( grp, pt, f_rng, p_rng ); + } +#endif /* #if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) */ + + p_size = ( grp->pbits + 7 ) / 8; mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll ); /* Generate l such that 1 < l < p */ @@ -1234,6 +1273,7 @@ static int ecp_precompute_comb( const mbedtls_ecp_group *grp, MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); cleanup: + return( ret ); } @@ -1297,6 +1337,7 @@ static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R } cleanup: + mbedtls_ecp_point_free( &Txi ); return( ret ); @@ -1441,6 +1482,13 @@ static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P { int ret; +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) + if ( ecp_alt_grp_capable( grp ) ) + { + return ecp_normalize_mxz_alt( grp, P ); + } +#endif /* #if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) */ + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) ); @@ -1462,9 +1510,17 @@ static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P { int ret; mbedtls_mpi l; - size_t p_size = ( grp->pbits + 7 ) / 8; + size_t p_size; int count = 0; +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) + if ( ecp_alt_grp_capable( grp ) ) + { + return ecp_randomize_mxz_alt( grp, P, f_rng, p_rng ); + } +#endif /* #if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) */ + + p_size = ( grp->pbits + 7 ) / 8; mbedtls_mpi_init( &l ); /* Generate l such that 1 < l < p */ @@ -1512,6 +1568,13 @@ static int ecp_double_add_mxz( const mbedtls_ecp_group *grp, int ret; mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB; +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) + if ( ecp_alt_grp_capable( grp ) ) + { + return ecp_double_add_mxz_alt( grp, R, S, P, Q, d ); + } +#endif /* #if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) */ + mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B ); mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C ); mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB ); @@ -1612,7 +1675,7 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - int ret; + int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; /* Common sanity checks */ if( mbedtls_mpi_cmp_int( &P->Z, 1 ) != 0 ) @@ -1622,15 +1685,35 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, ( ret = mbedtls_ecp_check_pubkey( grp, P ) ) != 0 ) return( ret ); +#if defined(MBEDTLS_ECP_ALT_INIT) + if ( ecp_alt_grp_capable( grp ) ) + { + MBEDTLS_MPI_CHK( ecp_alt_init( grp ) ); + } +#endif + #if defined(ECP_MONTGOMERY) if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) - return( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) ); + 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 ) - return( ecp_mul_comb( grp, R, m, P, f_rng, p_rng ) ); + ret = ecp_mul_comb( grp, R, m, P, f_rng, p_rng ); #endif - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_ECP_ALT_INIT) + cleanup: +#endif + +#if defined(MBEDTLS_ECP_ALT_DEINIT) + if ( ecp_alt_grp_capable( grp ) ) + { + ecp_alt_deinit( grp ); + } +#endif + + return( ret ); } #if defined(ECP_SHORTWEIERSTRASS) @@ -1732,10 +1815,24 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, &mP, m, P ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, R, n, Q ) ); +#if defined(MBEDTLS_ECP_ALT_INIT) + if ( ecp_alt_grp_capable( grp ) ) + { + MBEDTLS_MPI_CHK( ecp_alt_init( grp ) ); + } +#endif MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) ); MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) ); cleanup: + +#if defined(MBEDTLS_ECP_ALT_DEINIT) + if ( ecp_alt_grp_capable( grp ) ) + { + ecp_alt_deinit( grp ); + } +#endif + mbedtls_ecp_point_free( &mP ); return( ret ); @@ -2089,4 +2186,6 @@ cleanup: #endif /* MBEDTLS_SELF_TEST */ +#endif /* !MBEDTLS_ECP_ALT */ + #endif /* MBEDTLS_ECP_C */ diff --git a/library/ecp_curves.c b/library/ecp_curves.c index a2a5495a9..df5ac3eea 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -31,6 +31,8 @@ #include +#if !defined(MBEDTLS_ECP_ALT) + #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline @@ -1322,4 +1324,6 @@ static int ecp_mod_p256k1( mbedtls_mpi *N ) } #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ +#endif /* !MBEDTLS_ECP_ALT */ + #endif /* MBEDTLS_ECP_C */