mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-11-04 04:32:24 -05:00 
			
		
		
		
	Add entropy callbacks to HMAC_DRBG
This commit is contained in:
		
							parent
							
								
									8208d167da
								
							
						
					
					
						commit
						fe34a5fb83
					
				@ -29,19 +29,40 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "md.h"
 | 
					#include "md.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * ! Same values as ctr_drbg.h !
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED        -0x0034  /**< The entropy source failed. */
 | 
				
			||||||
 | 
					#define POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG              -0x0036  /**< Too many random requested in single call. */
 | 
				
			||||||
 | 
					#define POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG                -0x0038  /**< Input too large (Entropy + additional). */
 | 
				
			||||||
 | 
					#define POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR                -0x003A  /**< Read/write error in file. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HMAC_DRBG_RESEED_INTERVAL   10000   /**< Interval before reseed is performed by default */
 | 
				
			||||||
 | 
					#define HMAC_DRBG_MAX_INPUT         256     /**< Maximum number of additional input bytes */
 | 
				
			||||||
 | 
					#define HMAC_DRBG_MAX_REQUEST       1024    /**< Maximum number of requested bytes per call */
 | 
				
			||||||
 | 
					#define HMAC_DRBG_MAX_SEED_INPUT    384     /**< Maximum size of (re)seed buffer */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/**
 | 
				
			||||||
 * Simplified HMAC_DRBG context.
 | 
					 * HMAC_DRBG context.
 | 
				
			||||||
 * No reseed counter, no prediction resistance flag.
 | 
					 * TODO: reseed counter, prediction resistance flag.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
typedef struct
 | 
					typedef struct
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    md_context_t md_ctx;
 | 
					    md_context_t md_ctx;
 | 
				
			||||||
    unsigned char V[POLARSSL_MD_MAX_SIZE];
 | 
					    unsigned char V[POLARSSL_MD_MAX_SIZE];
 | 
				
			||||||
    unsigned char K[POLARSSL_MD_MAX_SIZE];
 | 
					    unsigned char K[POLARSSL_MD_MAX_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t entropy_len;         /*!< entropy bytes grabbed on each (re)seed */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Callbacks (Entropy)
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    int (*f_entropy)(void *, unsigned char *, size_t);
 | 
				
			||||||
 | 
					    void *p_entropy;            /*!< context for the entropy function */
 | 
				
			||||||
} hmac_drbg_context;
 | 
					} hmac_drbg_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -49,16 +70,45 @@ typedef struct
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * \param ctx           HMAC_DRBG context to be initialised
 | 
					 * \param ctx           HMAC_DRBG context to be initialised
 | 
				
			||||||
 * \param md_info       MD algorithm to use for HMAC_DRBG
 | 
					 * \param md_info       MD algorithm to use for HMAC_DRBG
 | 
				
			||||||
 * \param data          Concatenation of entropy string and additional data
 | 
					 * \param f_entropy     Entropy callback (p_entropy, buffer to fill, buffer
 | 
				
			||||||
 * \param data_len      Length of data in bytes
 | 
					 *                      length)
 | 
				
			||||||
 | 
					 * \param p_entropy     Entropy context
 | 
				
			||||||
 | 
					 * \param custom        Personalization data (Device specific identifiers)
 | 
				
			||||||
 | 
					 *                      (Can be NULL)
 | 
				
			||||||
 | 
					 * \param len           Length of personalization data
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \todo                Use entropy callback rather than buffer.
 | 
					 * \note                The "security strength" as defined by NIST is set to:
 | 
				
			||||||
 | 
					 *                      128 bits if md_alg is SHA-1,
 | 
				
			||||||
 | 
					 *                      192 bits if md_alg is SHA-224,
 | 
				
			||||||
 | 
					 *                      256 bits if md_alg is SHA-256 or higher.
 | 
				
			||||||
 | 
					 *                      Note that SHA-256 is just as efficient as SHA-224.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \return              0 if successful, or
 | 
					 * \return              0 if successful, or
 | 
				
			||||||
 *                      POLARSSL_ERR_MD_BAD_INPUT_DATA, or
 | 
					 *                      POLARSSL_ERR_MD_BAD_INPUT_DATA, or
 | 
				
			||||||
 *                      POLARSSL_ERR_MD_ALLOC_FAILED
 | 
					 *                      POLARSSL_ERR_MD_ALLOC_FAILED, or
 | 
				
			||||||
 | 
					 *                      POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int hmac_drbg_init( hmac_drbg_context *ctx,
 | 
					int hmac_drbg_init( hmac_drbg_context *ctx,
 | 
				
			||||||
 | 
					                    const md_info_t * md_info,
 | 
				
			||||||
 | 
					                    int (*f_entropy)(void *, unsigned char *, size_t),
 | 
				
			||||||
 | 
					                    void *p_entropy,
 | 
				
			||||||
 | 
					                    const unsigned char *custom,
 | 
				
			||||||
 | 
					                    size_t len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * \brief               Simplified HMAC_DRBG initialisation.
 | 
				
			||||||
 | 
					 *                      (For use with deterministic ECDSA.)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \param ctx           HMAC_DRBG context to be initialised
 | 
				
			||||||
 | 
					 * \param md_info       MD algorithm to use for HMAC_DRBG
 | 
				
			||||||
 | 
					 * \param data          Concatenation of entropy string and additional data
 | 
				
			||||||
 | 
					 * \param data_len      Length of data in bytes
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \return              0 if successful, or
 | 
				
			||||||
 | 
					 *                      POLARSSL_ERR_MD_BAD_INPUT_DATA, or
 | 
				
			||||||
 | 
					 *                      POLARSSL_ERR_MD_ALLOC_FAILED.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int hmac_drbg_init_buf( hmac_drbg_context *ctx,
 | 
				
			||||||
                        const md_info_t * md_info,
 | 
					                        const md_info_t * md_info,
 | 
				
			||||||
                        const unsigned char *data, size_t data_len );
 | 
					                        const unsigned char *data, size_t data_len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -193,7 +193,7 @@ int ecdsa_sign_det( ecp_group *grp, mpi *r, mpi *s,
 | 
				
			|||||||
    MPI_CHK( mpi_write_binary( d, data, grp_len ) );
 | 
					    MPI_CHK( mpi_write_binary( d, data, grp_len ) );
 | 
				
			||||||
    MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
 | 
					    MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
 | 
				
			||||||
    MPI_CHK( mpi_write_binary( &h, data + grp_len, grp_len ) );
 | 
					    MPI_CHK( mpi_write_binary( &h, data + grp_len, grp_len ) );
 | 
				
			||||||
    hmac_drbg_init( &rng_ctx, md_info, data, 2 * grp_len );
 | 
					    hmac_drbg_init_buf( &rng_ctx, md_info, data, 2 * grp_len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = ecdsa_sign( grp, r, s, d, buf, blen,
 | 
					    ret = ecdsa_sign( grp, r, s, d, buf, blen,
 | 
				
			||||||
                      hmac_drbg_random, &rng_ctx );
 | 
					                      hmac_drbg_random, &rng_ctx );
 | 
				
			||||||
 | 
				
			|||||||
@ -63,9 +63,9 @@ void hmac_drbg_update( hmac_drbg_context *ctx,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Simplified HMAC_DRBG initialisation.
 | 
					 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int hmac_drbg_init( hmac_drbg_context *ctx,
 | 
					int hmac_drbg_init_buf( hmac_drbg_context *ctx,
 | 
				
			||||||
                        const md_info_t * md_info,
 | 
					                        const md_info_t * md_info,
 | 
				
			||||||
                        const unsigned char *data, size_t data_len )
 | 
					                        const unsigned char *data, size_t data_len )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -84,6 +84,78 @@ int hmac_drbg_init( hmac_drbg_context *ctx,
 | 
				
			|||||||
    return( 0 );
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * HMAC_DRBG initialisation
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int hmac_drbg_init( hmac_drbg_context *ctx,
 | 
				
			||||||
 | 
					                    const md_info_t * md_info,
 | 
				
			||||||
 | 
					                    int (*f_entropy)(void *, unsigned char *, size_t),
 | 
				
			||||||
 | 
					                    void *p_entropy,
 | 
				
			||||||
 | 
					                    const unsigned char *custom,
 | 
				
			||||||
 | 
					                    size_t len )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    unsigned char seed[HMAC_DRBG_MAX_SEED_INPUT];
 | 
				
			||||||
 | 
					    size_t seedlen, init_entropy_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset( ctx, 0, sizeof( hmac_drbg_context ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 )
 | 
				
			||||||
 | 
					        return( ret );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
 | 
				
			||||||
 | 
					     * each hash function, then according to SP800-90A rev1 10.1 table 2,
 | 
				
			||||||
 | 
					     * min_entropy_len (in bits) is security_strength.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ctx->entropy_len = md_info->size <= 20 ? 16 : /* 160-bits hash -> 128 */
 | 
				
			||||||
 | 
					                       md_info->size <= 28 ? 24 : /* 224-bits hash -> 192 */
 | 
				
			||||||
 | 
					                                             32;  /* better (256+) -> 256 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ctx->f_entropy = f_entropy;
 | 
				
			||||||
 | 
					    ctx->p_entropy = p_entropy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * For initialisation, use more entropy to emulate a nonce
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    init_entropy_len = ctx->entropy_len * 3 / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if( init_entropy_len + len > HMAC_DRBG_MAX_SEED_INPUT )
 | 
				
			||||||
 | 
					        return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset( seed, 0, HMAC_DRBG_MAX_SEED_INPUT );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Gather init_entropy_len bytes of entropy for initial seed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
 | 
				
			||||||
 | 
					                             init_entropy_len ) )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return( POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    seedlen = init_entropy_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Add additional data
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if( custom != NULL && len != 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        memcpy( seed + seedlen, custom, len );
 | 
				
			||||||
 | 
					        seedlen += len;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Set initial state and update it with initialisation data
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    memset( ctx->V, 0x01, md_info->size );
 | 
				
			||||||
 | 
					    /* ctx->K is already 0 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hmac_drbg_update( ctx, seed, seedlen );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return( 0 );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * HMAC_DRBG random function with optional additional data (10.1.2.5)
 | 
					 * HMAC_DRBG random function with optional additional data (10.1.2.5)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user