mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-10-30 19:20:40 -04:00 
			
		
		
		
	Implement use of internal DRBG for ecp_mul()
The case of MBEDTLS_ECP_RESTARTABLE isn't handled correctly yet: in that case the DRBG instance should persist when resuming the operation. This will be addressed in the next commit. When both CTR_DRBG and HMAC_DRBG are available, CTR_DRBG is preferred since both are suitable but CTR_DRBG tends to be faster and I needed a tie-breaker. There are currently three possible cases to test: - NO_INTERNAL_RNG is set -> tested in test_ecp_no_internal_rng - it's unset and CTR_DRBG is available -> tested in the default config - it's unset and CTR_DRBG is disabled -> tested in test_ecp_internal_rng_no_ctr_drbg Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This commit is contained in:
		
							parent
							
								
									1a3f9edc08
								
							
						
					
					
						commit
						c52a43c2bd
					
				| @ -104,6 +104,8 @@ typedef struct mbedtls_md_context_t | |||||||
|  * \brief           This function returns the list of digests supported by the |  * \brief           This function returns the list of digests supported by the | ||||||
|  *                  generic digest module. |  *                  generic digest module. | ||||||
|  * |  * | ||||||
|  |  * \note            The list starts with the strongest available hashes. | ||||||
|  |  * | ||||||
|  * \return          A statically allocated array of digests. Each element |  * \return          A statically allocated array of digests. Each element | ||||||
|  *                  in the returned list is an integer belonging to the |  *                  in the returned list is an integer belonging to the | ||||||
|  *                  message-digest enumeration #mbedtls_md_type_t. |  *                  message-digest enumeration #mbedtls_md_type_t. | ||||||
|  | |||||||
							
								
								
									
										137
									
								
								library/ecp.c
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								library/ecp.c
									
									
									
									
									
								
							| @ -105,6 +105,16 @@ | |||||||
| 
 | 
 | ||||||
| #include "mbedtls/ecp_internal.h" | #include "mbedtls/ecp_internal.h" | ||||||
| 
 | 
 | ||||||
|  | #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) | ||||||
|  | #if defined(MBEDTLS_CTR_DRBG_C) | ||||||
|  | #include "mbedtls/ctr_drbg.h" | ||||||
|  | #elif defined(MBEDTLS_HMAC_DRBG_C) | ||||||
|  | #include "mbedtls/hmac_drbg.h" | ||||||
|  | #else | ||||||
|  | #error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid." | ||||||
|  | #endif | ||||||
|  | #endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */ | ||||||
|  | 
 | ||||||
| #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ | #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ | ||||||
|     !defined(inline) && !defined(__cplusplus) |     !defined(inline) && !defined(__cplusplus) | ||||||
| #define inline __inline | #define inline __inline | ||||||
| @ -118,6 +128,113 @@ | |||||||
| static unsigned long add_count, dbl_count, mul_count; | static unsigned long add_count, dbl_count, mul_count; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) | ||||||
|  | /*
 | ||||||
|  |  * Currently ecp_mul() takes a RNG function as an argument, used for | ||||||
|  |  * side-channel protection, but it can be NULL. The initial reasonning was | ||||||
|  |  * that people will pass non-NULL RNG when they care about side-channels, but | ||||||
|  |  * unfortunately we have some APIs that call ecp_mul() with a NULL RNG, with | ||||||
|  |  * no opportunity for the user to do anything about it. | ||||||
|  |  * | ||||||
|  |  * The obvious strategies for addressing that include: | ||||||
|  |  * - change those APIs so that they take RNG arguments; | ||||||
|  |  * - require a global RNG to be available to all crypto modules. | ||||||
|  |  * | ||||||
|  |  * Unfortunately those would break compatibility. So what we do instead is | ||||||
|  |  * have our own internal DRBG instance, seeded from the secret scalar. | ||||||
|  |  * | ||||||
|  |  * The following is a light-weight abstraction layer for doing that with | ||||||
|  |  * CTR_DRBG or HMAC_DRBG. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if defined(MBEDTLS_CTR_DRBG_C) | ||||||
|  | /* DRBG context type */ | ||||||
|  | typedef mbedtls_ctr_drbg_context ecp_drbg_context; | ||||||
|  | 
 | ||||||
|  | /* DRBG context init */ | ||||||
|  | static inline void ecp_drbg_init( ecp_drbg_context *ctx ) | ||||||
|  | { | ||||||
|  |     mbedtls_ctr_drbg_init( ctx ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* DRBG context free */ | ||||||
|  | static inline void ecp_drbg_free( ecp_drbg_context *ctx ) | ||||||
|  | { | ||||||
|  |     mbedtls_ctr_drbg_free( ctx ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* DRBG function */ | ||||||
|  | static inline int ecp_drbg_random( void *p_rng, | ||||||
|  |                                    unsigned char *output, size_t output_len ) | ||||||
|  | { | ||||||
|  |     return( mbedtls_ctr_drbg_random( p_rng, output, output_len ) ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Since CTR_DRBG doesn't have a seed_buf() function the way HMAC_DRBG does, | ||||||
|  |  * we need to pass an entropy function when seeding. So we use a dummy | ||||||
|  |  * function for that, and pass the actual entropy as customisation string. | ||||||
|  |  * (During seeding of CTR_DRBG the entropy input and customisation string are | ||||||
|  |  * concatenated before being used to update the secret state.) | ||||||
|  |  */ | ||||||
|  | static int ecp_ctr_drbg_null_entropy(void *ctx, unsigned char *out, size_t len) | ||||||
|  | { | ||||||
|  |     (void) ctx; | ||||||
|  |     memset( out, 0, len ); | ||||||
|  |     return( 0 ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* DRBG context seeding */ | ||||||
|  | static int ecp_drbg_seed( ecp_drbg_context *ctx, const mbedtls_mpi *secret ) | ||||||
|  | { | ||||||
|  |     const unsigned char *secret_p = (const unsigned char *) secret->p; | ||||||
|  |     const size_t secret_size = secret->n * sizeof( mbedtls_mpi_uint ); | ||||||
|  | 
 | ||||||
|  |     return( mbedtls_ctr_drbg_seed( ctx, ecp_ctr_drbg_null_entropy, NULL, | ||||||
|  |                                    secret_p, secret_size ) ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #elif defined(MBEDTLS_HMAC_DRBG_C) | ||||||
|  | /* DRBG context type */ | ||||||
|  | typedef mbedtls_hmac_drbg_context ecp_drbg_context; | ||||||
|  | 
 | ||||||
|  | /* DRBG context init */ | ||||||
|  | static inline void ecp_drbg_init( ecp_drbg_context *ctx ) | ||||||
|  | { | ||||||
|  |     mbedtls_hmac_drbg_init( ctx ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* DRBG context free */ | ||||||
|  | static inline void ecp_drbg_free( ecp_drbg_context *ctx ) | ||||||
|  | { | ||||||
|  |     mbedtls_hmac_drbg_free( ctx ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* DRBG function */ | ||||||
|  | static inline int ecp_drbg_random( void *p_rng, | ||||||
|  |                                    unsigned char *output, size_t output_len ) | ||||||
|  | { | ||||||
|  |     return( mbedtls_hmac_drbg_random( p_rng, output, output_len ) ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* DRBG context seeding */ | ||||||
|  | static int ecp_drbg_seed( ecp_drbg_context *ctx, const mbedtls_mpi *secret ) | ||||||
|  | { | ||||||
|  |     const unsigned char *secret_p = (const unsigned char *) secret->p; | ||||||
|  |     const size_t secret_size = secret->n * sizeof( mbedtls_mpi_uint ); | ||||||
|  | 
 | ||||||
|  |     /* The list starts with strong hashes */ | ||||||
|  |     const mbedtls_md_type_t md_type = mbedtls_md_list()[0]; | ||||||
|  |     const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_type ); | ||||||
|  | 
 | ||||||
|  |     return( mbedtls_hmac_drbg_seed_buf( ctx, md_info, secret_p, secret_size ) ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #else | ||||||
|  | #error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid." | ||||||
|  | #endif /* DRBG modules */ | ||||||
|  | #endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */ | ||||||
|  | 
 | ||||||
| #if defined(MBEDTLS_ECP_RESTARTABLE) | #if defined(MBEDTLS_ECP_RESTARTABLE) | ||||||
| /*
 | /*
 | ||||||
|  * Maximum number of "basic operations" to be done in a row. |  * Maximum number of "basic operations" to be done in a row. | ||||||
| @ -2443,12 +2560,19 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, | |||||||
|     int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; |     int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; | ||||||
| #if defined(MBEDTLS_ECP_INTERNAL_ALT) | #if defined(MBEDTLS_ECP_INTERNAL_ALT) | ||||||
|     char is_grp_capable = 0; |     char is_grp_capable = 0; | ||||||
|  | #endif | ||||||
|  | #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) | ||||||
|  |     ecp_drbg_context drbg_ctx; | ||||||
| #endif | #endif | ||||||
|     ECP_VALIDATE_RET( grp != NULL ); |     ECP_VALIDATE_RET( grp != NULL ); | ||||||
|     ECP_VALIDATE_RET( R   != NULL ); |     ECP_VALIDATE_RET( R   != NULL ); | ||||||
|     ECP_VALIDATE_RET( m   != NULL ); |     ECP_VALIDATE_RET( m   != NULL ); | ||||||
|     ECP_VALIDATE_RET( P   != NULL ); |     ECP_VALIDATE_RET( P   != NULL ); | ||||||
| 
 | 
 | ||||||
|  | #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) | ||||||
|  |     ecp_drbg_init( &drbg_ctx ); | ||||||
|  | #endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */ | ||||||
|  | 
 | ||||||
| #if defined(MBEDTLS_ECP_RESTARTABLE) | #if defined(MBEDTLS_ECP_RESTARTABLE) | ||||||
|     /* reset ops count for this call if top-level */ |     /* reset ops count for this call if top-level */ | ||||||
|     if( rs_ctx != NULL && rs_ctx->depth++ == 0 ) |     if( rs_ctx != NULL && rs_ctx->depth++ == 0 ) | ||||||
| @ -2460,6 +2584,15 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, | |||||||
|         MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); |         MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); | ||||||
| #endif /* MBEDTLS_ECP_INTERNAL_ALT */ | #endif /* MBEDTLS_ECP_INTERNAL_ALT */ | ||||||
| 
 | 
 | ||||||
|  | #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) | ||||||
|  |     if( f_rng == NULL ) | ||||||
|  |     { | ||||||
|  |         MBEDTLS_MPI_CHK( ecp_drbg_seed( &drbg_ctx, m ) ); | ||||||
|  |         f_rng = &ecp_drbg_random; | ||||||
|  |         p_rng = &drbg_ctx; | ||||||
|  |     } | ||||||
|  | #endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */ | ||||||
|  | 
 | ||||||
| #if defined(MBEDTLS_ECP_RESTARTABLE) | #if defined(MBEDTLS_ECP_RESTARTABLE) | ||||||
|     /* skip argument check when restarting */ |     /* skip argument check when restarting */ | ||||||
|     if( rs_ctx == NULL || rs_ctx->rsm == NULL ) |     if( rs_ctx == NULL || rs_ctx->rsm == NULL ) | ||||||
| @ -2490,6 +2623,10 @@ cleanup: | |||||||
|         mbedtls_internal_ecp_free( grp ); |         mbedtls_internal_ecp_free( grp ); | ||||||
| #endif /* MBEDTLS_ECP_INTERNAL_ALT */ | #endif /* MBEDTLS_ECP_INTERNAL_ALT */ | ||||||
| 
 | 
 | ||||||
|  | #if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG) | ||||||
|  |     ecp_drbg_free( &drbg_ctx ); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #if defined(MBEDTLS_ECP_RESTARTABLE) | #if defined(MBEDTLS_ECP_RESTARTABLE) | ||||||
|     if( rs_ctx != NULL ) |     if( rs_ctx != NULL ) | ||||||
|         rs_ctx->depth--; |         rs_ctx->depth--; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Manuel Pégourié-Gonnard
						Manuel Pégourié-Gonnard