diff --git a/ChangeLog b/ChangeLog index b0900d2a0..ac04f8210 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ Features * Support for DTLS 1.0 and 1.2 (RFC 6347). API Changes + * Change md_info_t into an opaque structure (use md_get_xxx() accessors). * Some constness fixes * Signature of mpi_mul_mpi() changed to make the last argument unsigned * Remove the PBKDF2 module (use PKCS5). diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h index a1d6873c8..6728d8d33 100644 --- a/include/mbedtls/md.h +++ b/include/mbedtls/md.h @@ -5,7 +5,7 @@ * * \author Adriaan de Jong * - * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * * This file is part of mbed TLS (https://tls.mbed.org) * @@ -65,63 +65,9 @@ typedef enum { #endif /** - * Message digest information. Allows message digest functions to be called - * in a generic way. + * Opaque struct defined in md_wrap.h */ -typedef struct { - /** Digest identifier */ - md_type_t type; - - /** Name of the message digest */ - const char * name; - - /** Output length of the digest function */ - int size; - - /** Digest initialisation function */ - void (*starts_func)( void *ctx ); - - /** Digest update function */ - void (*update_func)( void *ctx, const unsigned char *input, size_t ilen ); - - /** Digest finalisation function */ - void (*finish_func)( void *ctx, unsigned char *output ); - - /** Generic digest function */ - void (*digest_func)( const unsigned char *input, size_t ilen, - unsigned char *output ); - - /** Generic file digest function */ - int (*file_func)( const char *path, unsigned char *output ); - - /** HMAC Initialisation function */ - void (*hmac_starts_func)( void *ctx, const unsigned char *key, - size_t keylen ); - - /** HMAC update function */ - void (*hmac_update_func)( void *ctx, const unsigned char *input, - size_t ilen ); - - /** HMAC finalisation function */ - void (*hmac_finish_func)( void *ctx, unsigned char *output); - - /** HMAC context reset function */ - void (*hmac_reset_func)( void *ctx ); - - /** Generic HMAC function */ - void (*hmac_func)( const unsigned char *key, size_t keylen, - const unsigned char *input, size_t ilen, - unsigned char *output ); - - /** Allocate a new context */ - void * (*ctx_alloc_func)( void ); - - /** Free the given context */ - void (*ctx_free_func)( void *ctx ); - - /** Internal use only */ - void (*process_func)( void *ctx, const unsigned char *input ); -} md_info_t; +typedef struct _md_info_t md_info_t; /** * Generic message digest context. @@ -191,7 +137,7 @@ void md_free( md_context_t *ctx ); * * \param ctx context to initialise. May not be NULL. The * digest-specific context (ctx->md_ctx) must be NULL. It will - * be allocated, and must be freed using md_free_ctx() later. + * be allocated, and must be freed using md_free() later. * \param md_info message digest to use. * * \returns \c 0 on success, \c POLARSSL_ERR_MD_BAD_INPUT_DATA on @@ -207,13 +153,7 @@ int md_init_ctx( md_context_t *ctx, const md_info_t *md_info ); * * \return size of the message digest output. */ -static inline unsigned char md_get_size( const md_info_t *md_info ) -{ - if( md_info == NULL ) - return( 0 ); - - return md_info->size; -} +unsigned char md_get_size( const md_info_t *md_info ); /** * \brief Returns the type of the message digest output. @@ -222,13 +162,7 @@ static inline unsigned char md_get_size( const md_info_t *md_info ) * * \return type of the message digest output. */ -static inline md_type_t md_get_type( const md_info_t *md_info ) -{ - if( md_info == NULL ) - return( POLARSSL_MD_NONE ); - - return md_info->type; -} +md_type_t md_get_type( const md_info_t *md_info ); /** * \brief Returns the name of the message digest output. @@ -237,13 +171,7 @@ static inline md_type_t md_get_type( const md_info_t *md_info ) * * \return name of the message digest output. */ -static inline const char *md_get_name( const md_info_t *md_info ) -{ - if( md_info == NULL ) - return( NULL ); - - return md_info->name; -} +const char *md_get_name( const md_info_t *md_info ); /** * \brief Set-up the given context for a new message digest diff --git a/include/mbedtls/md_wrap.h b/include/mbedtls/md_wrap.h index dd5fd6cf9..6fe377e2c 100644 --- a/include/mbedtls/md_wrap.h +++ b/include/mbedtls/md_wrap.h @@ -3,9 +3,11 @@ * * \brief Message digest wrappers. * + * \warning This in an internal header. Do not include directly. + * * \author Adriaan de Jong * - * Copyright (C) 2006-2011, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * * This file is part of mbed TLS (https://tls.mbed.org) * @@ -38,6 +40,65 @@ extern "C" { #endif +/** + * Message digest information. + * Allows message digest functions to be called in a generic way. + */ +struct _md_info_t { + /** Digest identifier */ + md_type_t type; + + /** Name of the message digest */ + const char * name; + + /** Output length of the digest function */ + int size; + + /** Digest initialisation function */ + void (*starts_func)( void *ctx ); + + /** Digest update function */ + void (*update_func)( void *ctx, const unsigned char *input, size_t ilen ); + + /** Digest finalisation function */ + void (*finish_func)( void *ctx, unsigned char *output ); + + /** Generic digest function */ + void (*digest_func)( const unsigned char *input, size_t ilen, + unsigned char *output ); + + /** Generic file digest function */ + int (*file_func)( const char *path, unsigned char *output ); + + /** HMAC Initialisation function */ + void (*hmac_starts_func)( void *ctx, const unsigned char *key, + size_t keylen ); + + /** HMAC update function */ + void (*hmac_update_func)( void *ctx, const unsigned char *input, + size_t ilen ); + + /** HMAC finalisation function */ + void (*hmac_finish_func)( void *ctx, unsigned char *output); + + /** HMAC context reset function */ + void (*hmac_reset_func)( void *ctx ); + + /** Generic HMAC function */ + void (*hmac_func)( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ); + + /** Allocate a new context */ + void * (*ctx_alloc_func)( void ); + + /** Free the given context */ + void (*ctx_free_func)( void *ctx ); + + /** Internal use only */ + void (*process_func)( void *ctx, const unsigned char *input ); +}; + #if defined(POLARSSL_MD2_C) extern const md_info_t md2_info; #endif diff --git a/library/ecdsa.c b/library/ecdsa.c index c95f90b81..c39c9c3e5 100644 --- a/library/ecdsa.c +++ b/library/ecdsa.c @@ -60,8 +60,9 @@ static const md_info_t *md_info_by_size( size_t min_size ) for( md_alg = md_list(); *md_alg != 0; md_alg++ ) { if( ( md_cur = md_info_from_type( (md_type_t) *md_alg ) ) == NULL || - (size_t) md_cur->size < min_size || - ( md_picked != NULL && md_cur->size > md_picked->size ) ) + (size_t) md_get_size( md_cur ) < min_size || + ( md_picked != NULL && + md_get_size( md_cur ) > md_get_size( md_picked ) ) ) continue; md_picked = md_cur; diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c index dc26b0d1a..2e4b682b6 100644 --- a/library/hmac_drbg.c +++ b/library/hmac_drbg.c @@ -62,7 +62,7 @@ static void polarssl_zeroize( void *v, size_t n ) { void hmac_drbg_update( hmac_drbg_context *ctx, const unsigned char *additional, size_t add_len ) { - size_t md_len = ctx->md_ctx.md_info->size; + size_t md_len = md_get_size( ctx->md_ctx.md_info ); unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; unsigned char sep[1]; unsigned char K[POLARSSL_MD_MAX_SIZE]; @@ -105,8 +105,8 @@ int hmac_drbg_init_buf( hmac_drbg_context *ctx, * Use the V memory location, which is currently all 0, to initialize the * MD context with an all-zero key. Then set V to its initial value. */ - md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size ); - memset( ctx->V, 0x01, md_info->size ); + md_hmac_starts( &ctx->md_ctx, ctx->V, md_get_size( md_info ) ); + memset( ctx->V, 0x01, md_get_size( md_info ) ); hmac_drbg_update( ctx, data, data_len ); @@ -165,7 +165,7 @@ int hmac_drbg_init( hmac_drbg_context *ctx, size_t len ) { int ret; - size_t entropy_len; + size_t entropy_len, md_size; memset( ctx, 0, sizeof( hmac_drbg_context ) ); @@ -174,13 +174,15 @@ int hmac_drbg_init( hmac_drbg_context *ctx, if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 ) return( ret ); + md_size = md_get_size( md_info ); + /* * Set initial working state. * Use the V memory location, which is currently all 0, to initialize the * MD context with an all-zero key. Then set V to its initial value. */ - md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size ); - memset( ctx->V, 0x01, md_info->size ); + md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ); + memset( ctx->V, 0x01, md_size ); ctx->f_entropy = f_entropy; ctx->p_entropy = p_entropy; @@ -194,9 +196,9 @@ int hmac_drbg_init( hmac_drbg_context *ctx, * * (This also matches the sizes used in the NIST test vectors.) */ - entropy_len = md_info->size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ - md_info->size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ - 32; /* better (256+) -> 256 bits */ + entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ + md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ + 32; /* better (256+) -> 256 bits */ /* * For initialisation, use more entropy to emulate a nonce diff --git a/library/md.c b/library/md.c index c34e1211e..d8f6a96af 100644 --- a/library/md.c +++ b/library/md.c @@ -329,4 +329,28 @@ int md_process( md_context_t *ctx, const unsigned char *data ) return( 0 ); } +unsigned char md_get_size( const md_info_t *md_info ) +{ + if( md_info == NULL ) + return( 0 ); + + return md_info->size; +} + +md_type_t md_get_type( const md_info_t *md_info ) +{ + if( md_info == NULL ) + return( POLARSSL_MD_NONE ); + + return md_info->type; +} + +const char *md_get_name( const md_info_t *md_info ) +{ + if( md_info == NULL ) + return( NULL ); + + return md_info->name; +} + #endif /* POLARSSL_MD_C */ diff --git a/library/pk.c b/library/pk.c index af4a302f9..f083b861c 100644 --- a/library/pk.c +++ b/library/pk.c @@ -166,7 +166,7 @@ static inline int pk_hashlen_helper( md_type_t md_alg, size_t *hash_len ) if( ( md_info = md_info_from_type( md_alg ) ) == NULL ) return( -1 ); - *hash_len = md_info->size; + *hash_len = md_get_size( md_info ); return( 0 ); } diff --git a/library/rsa.c b/library/rsa.c index e915e4fad..d3ab4ed06 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -473,7 +473,7 @@ static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, memset( mask, 0, POLARSSL_MD_MAX_SIZE ); memset( counter, 0, 4 ); - hlen = md_ctx->md_info->size; + hlen = md_get_size( md_ctx->md_info ); // Generate and apply dbMask // diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 2b94af87e..4fe767b90 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -2194,7 +2194,7 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl ) } SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : - (unsigned int) ( md_info_from_type( md_alg ) )->size ); + (unsigned int) ( md_get_size( md_info_from_type( md_alg ) ) ) ); /* * Verify signature diff --git a/library/ssl_srv.c b/library/ssl_srv.c index ff2c44bf7..b7c0335c5 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -3085,7 +3085,7 @@ curve_matching_done: } SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : - (unsigned int) ( md_info_from_type( md_alg ) )->size ); + (unsigned int) ( md_get_size( md_info_from_type( md_alg ) ) ) ); /* * Make the signature diff --git a/library/x509.c b/library/x509.c index 174e32dd2..67359a5d8 100644 --- a/library/x509.c +++ b/library/x509.c @@ -845,8 +845,8 @@ int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid, mgf_md_info = md_info_from_type( pss_opts->mgf1_hash_id ); ret = polarssl_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", - md_info ? md_info->name : "???", - mgf_md_info ? mgf_md_info->name : "???", + md_info ? md_get_name( md_info ) : "???", + mgf_md_info ? md_get_name( mgf_md_info ) : "???", pss_opts->expected_salt_len ); SAFE_SNPRINTF(); } diff --git a/library/x509_crt.c b/library/x509_crt.c index 8b9347364..7d12bcad0 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -1505,7 +1505,7 @@ static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca, md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ); if( pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, - crl_list->sig_md, hash, md_info->size, + crl_list->sig_md, hash, md_get_size( md_info ), crl_list->sig.p, crl_list->sig.len ) != 0 ) { flags |= BADCRL_NOT_TRUSTED; @@ -1768,7 +1768,7 @@ static int x509_crt_verify_top( } if( pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk, - child->sig_md, hash, md_info->size, + child->sig_md, hash, md_get_size( md_info ), child->sig.p, child->sig.len ) != 0 ) { continue; @@ -1864,7 +1864,7 @@ static int x509_crt_verify_child( md( md_info, child->tbs.p, child->tbs.len, hash ); if( pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, - child->sig_md, hash, md_info->size, + child->sig_md, hash, md_get_size( md_info ), child->sig.p, child->sig.len ) != 0 ) { *flags |= BADCERT_NOT_TRUSTED;