Merge pull request #248 from RonEld/stack_overflow_in_hmac_fix
Fix a buffer overflow in hmac_setup_internal
diff --git a/include/mbedtls/md_internal.h b/include/mbedtls/md_internal.h
index 267ceba..bb876ef 100644
--- a/include/mbedtls/md_internal.h
+++ b/include/mbedtls/md_internal.h
@@ -46,42 +46,17 @@
*/
struct mbedtls_md_info_t
{
- /** Digest identifier */
- mbedtls_md_type_t type;
-
/** Name of the message digest */
const char * name;
+ /** Digest identifier */
+ mbedtls_md_type_t type;
+
/** Output length of the digest function in bytes */
- int size;
+ unsigned char size;
/** Block length of the digest function in bytes */
- int block_size;
-
- /** Digest initialisation function */
- int (*starts_func)( void *ctx );
-
- /** Digest update function */
- int (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
-
- /** Digest finalisation function */
- int (*finish_func)( void *ctx, unsigned char *output );
-
- /** Generic digest function */
- int (*digest_func)( 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 );
-
- /** Clone state from a context */
- void (*clone_func)( void *dst, const void *src );
-
- /** Internal use only */
- int (*process_func)( void *ctx, const unsigned char *input );
+ unsigned char block_size;
};
#if defined(MBEDTLS_MD2_C)
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index d5e713e..71bad3b 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -367,15 +367,18 @@
* keys that can be opened with psa_open_key(). Such keys have a key identifier
* in the vendor range, as documented in the description of #psa_key_id_t.
*
- * The application must eventually close the handle with psa_close_key()
- * to release associated resources. If the application dies without calling
- * psa_close_key(), the implementation should perform the equivalent of a
- * call to psa_close_key().
+ * The application must eventually close the handle with psa_close_key() or
+ * psa_destroy_key() to release associated resources. If the application dies
+ * without calling one of these functions, the implementation should perform
+ * the equivalent of a call to psa_close_key().
*
* Some implementations permit an application to open the same key multiple
- * times. Applications that rely on this behavior will not be portable to
- * implementations that only permit a single key handle to be opened. See
- * also :ref:\`key-handles\`.
+ * times. If this is successful, each call to psa_open_key() will return a
+ * different key handle.
+ *
+ * \note Applications that rely on opening a key multiple times will not be
+ * portable to implementations that only permit a single key handle to be
+ * opened. See also :ref:\`key-handles\`.
*
* \param id The persistent identifier of the key.
* \param[out] handle On success, a handle to the key.
@@ -422,8 +425,10 @@
* Closing the key handle makes the handle invalid, and the key handle
* must not be used again by the application.
*
- * If the key is currently in use in a multipart operation, then closing the
- * last remaining handle to the key will abort the multipart operation.
+ * \note If the key handle was used to set up an active
+ * :ref:\`multipart operation <multipart-operations>\`, then closing the
+ * key handle can cause the multipart operation to fail. Applications should
+ * maintain the key handle until after the multipart operation has finished.
*
* \param handle The key handle to close.
*
@@ -521,13 +526,16 @@
* memory and, if applicable, non-volatile storage. Implementations shall
* make a best effort to ensure that that the key material cannot be recovered.
*
- * This function also erases any metadata such as policies and frees all
- * resources associated with the key.
+ * This function also erases any metadata such as policies and frees
+ * resources associated with the key. To free all resources associated with
+ * the key, all handles to the key must be closed or destroyed.
*
- * Destroying a key will invalidate all existing handles to the key.
+ * Destroying the key makes the handle invalid, and the key handle
+ * must not be used again by the application. Using other open handles to the
+ * destroyed key in a cryptographic operation will result in an error.
*
- * If the key is currently in use in a multipart operation, then destroying the
- * key will abort the multipart operation.
+ * If a key is currently in use in a multipart operation, then destroying the
+ * key will cause the multipart operation to fail.
*
* \param handle Handle to the key to erase.
*
@@ -1996,6 +2004,14 @@
*
* \retval #PSA_SUCCESS
* Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The total input size passed to this operation is not valid for
+ * this particular algorithm. For example, the algorithm is a based
+ * on block cipher and requires a whole number of blocks, but the
+ * total input size is not a multiple of the block size.
+ * \retval #PSA_ERROR_INVALID_PADDING
+ * This is a decryption operation for an algorithm that includes
+ * padding, and the ciphertext does not contain valid padding.
* \retval #PSA_ERROR_BAD_STATE
* The operation state is not valid (not set up, IV required but
* not set, or already completed).
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index b53e1c7..fc0f963 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -149,7 +149,7 @@
*
* \warning If a function returns this error, it is undetermined
* whether the requested action has completed or not. Implementations
- * should return #PSA_SUCCESS on successful completion whenver
+ * should return #PSA_SUCCESS on successful completion whenever
* possible, however functions may return #PSA_ERROR_COMMUNICATION_FAILURE
* if the requested action was completed successfully in an external
* cryptoprocessor but there was a breakdown of communication before
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index f4bb472..5c5ddc2 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -45,7 +45,6 @@
md2.c
md4.c
md5.c
- md_wrap.c
memory_buffer_alloc.c
nist_kw.c
oid.c
diff --git a/library/Makefile b/library/Makefile
index 8e27694..d7c1567 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -74,7 +74,7 @@
gcm.o havege.o \
hkdf.o \
hmac_drbg.o md.o md2.o \
- md4.o md5.o md_wrap.o \
+ md4.o md5.o \
memory_buffer_alloc.o nist_kw.o \
oid.o padlock.o pem.o \
pk.o pk_wrap.o pkcs12.o \
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 282481d..dcc7073 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -836,7 +836,7 @@
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
default:
- mbedtls_ecp_group_free( grp );
+ grp->id = MBEDTLS_ECP_DP_NONE;
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
}
}
diff --git a/library/md.c b/library/md.c
index ac8fac5..e1b5183 100644
--- a/library/md.c
+++ b/library/md.c
@@ -35,6 +35,14 @@
#include "mbedtls/md_internal.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/md2.h"
+#include "mbedtls/md4.h"
+#include "mbedtls/md5.h"
+#include "mbedtls/ripemd160.h"
+#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -49,6 +57,83 @@
#include <stdio.h>
#endif
+#if defined(MBEDTLS_MD2_C)
+const mbedtls_md_info_t mbedtls_md2_info = {
+ "MD2",
+ MBEDTLS_MD_MD2,
+ 16,
+ 16,
+};
+#endif
+
+#if defined(MBEDTLS_MD4_C)
+const mbedtls_md_info_t mbedtls_md4_info = {
+ "MD4",
+ MBEDTLS_MD_MD4,
+ 16,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+const mbedtls_md_info_t mbedtls_md5_info = {
+ "MD5",
+ MBEDTLS_MD_MD5,
+ 16,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_RIPEMD160_C)
+const mbedtls_md_info_t mbedtls_ripemd160_info = {
+ "RIPEMD160",
+ MBEDTLS_MD_RIPEMD160,
+ 20,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+const mbedtls_md_info_t mbedtls_sha1_info = {
+ "SHA1",
+ MBEDTLS_MD_SHA1,
+ 20,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+const mbedtls_md_info_t mbedtls_sha224_info = {
+ "SHA224",
+ MBEDTLS_MD_SHA224,
+ 28,
+ 64,
+};
+
+const mbedtls_md_info_t mbedtls_sha256_info = {
+ "SHA256",
+ MBEDTLS_MD_SHA256,
+ 32,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+const mbedtls_md_info_t mbedtls_sha384_info = {
+ "SHA384",
+ MBEDTLS_MD_SHA384,
+ 48,
+ 128,
+};
+
+const mbedtls_md_info_t mbedtls_sha512_info = {
+ "SHA512",
+ MBEDTLS_MD_SHA512,
+ 64,
+ 128,
+};
+#endif
+
/*
* Reminder: update profiles in Mbed TLS's x509_crt.c when adding a new hash!
*/
@@ -185,7 +270,52 @@
return;
if( ctx->md_ctx != NULL )
- ctx->md_info->ctx_free_func( ctx->md_ctx );
+ {
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ mbedtls_md2_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ mbedtls_md4_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ mbedtls_md5_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ mbedtls_ripemd160_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ mbedtls_sha1_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ mbedtls_sha256_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ case MBEDTLS_MD_SHA512:
+ mbedtls_sha512_free( ctx->md_ctx );
+ break;
+#endif
+ default:
+ /* Shouldn't happen */
+ break;
+ }
+ mbedtls_free( ctx->md_ctx );
+ }
if( ctx->hmac_ctx != NULL )
{
@@ -207,7 +337,48 @@
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
}
- dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
+ switch( src->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ mbedtls_md2_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ mbedtls_md4_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ mbedtls_sha1_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ case MBEDTLS_MD_SHA512:
+ mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
return( 0 );
}
@@ -219,20 +390,69 @@
}
#endif
+#define ALLOC( type ) \
+ do { \
+ ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \
+ if( ctx->md_ctx == NULL ) \
+ return( MBEDTLS_ERR_MD_ALLOC_FAILED ); \
+ mbedtls_##type##_init( ctx->md_ctx ); \
+ } \
+ while( 0 )
+
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
{
if( md_info == NULL || ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
- return( MBEDTLS_ERR_MD_ALLOC_FAILED );
+ switch( md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ ALLOC( md2 );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ ALLOC( md4 );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ ALLOC( md5 );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ ALLOC( ripemd160 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ ALLOC( sha1 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ ALLOC( sha256 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ case MBEDTLS_MD_SHA512:
+ ALLOC( sha512 );
+ break;
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
if( hmac != 0 )
{
ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
if( ctx->hmac_ctx == NULL )
{
- md_info->ctx_free_func( ctx->md_ctx );
+ mbedtls_md_free( ctx );
return( MBEDTLS_ERR_MD_ALLOC_FAILED );
}
}
@@ -241,13 +461,50 @@
return( 0 );
}
+#undef ALLOC
int mbedtls_md_starts( mbedtls_md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->starts_func( ctx->md_ctx ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_starts_ret( ctx->md_ctx, 1 ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_starts_ret( ctx->md_ctx, 0 ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_starts_ret( ctx->md_ctx, 1 ) );
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_starts_ret( ctx->md_ctx, 0 ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
@@ -255,7 +512,43 @@
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
@@ -263,7 +556,43 @@
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
@@ -272,7 +601,43 @@
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( md_info->digest_func( input, ilen, output ) );
+ switch( md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
#if defined(MBEDTLS_FS_IO)
@@ -295,17 +660,17 @@
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
goto cleanup;
- if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
goto cleanup;
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
- if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
+ if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 )
goto cleanup;
if( ferror( f ) != 0 )
ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
else
- ret = md_info->finish_func( ctx.md_ctx, output );
+ ret = mbedtls_md_finish( &ctx, output );
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -328,11 +693,11 @@
if( keylen > (size_t) ctx->md_info->block_size )
{
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )
+ if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 )
goto cleanup;
keylen = ctx->md_info->size;
@@ -351,10 +716,10 @@
opad[i] = (unsigned char)( opad[i] ^ key[i] );
}
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
- ctx->md_info->block_size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, ipad,
+ ctx->md_info->block_size ) ) != 0 )
goto cleanup;
cleanup:
@@ -368,7 +733,7 @@
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
+ return( mbedtls_md_update( ctx, input, ilen ) );
}
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
@@ -382,17 +747,17 @@
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
- if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )
+ if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,
- ctx->md_info->block_size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, opad,
+ ctx->md_info->block_size ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,
- ctx->md_info->size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, tmp,
+ ctx->md_info->size ) ) != 0 )
return( ret );
- return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
+ return( mbedtls_md_finish( ctx, output ) );
}
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
@@ -405,10 +770,9 @@
ipad = (unsigned char *) ctx->hmac_ctx;
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
return( ret );
- return( ctx->md_info->update_func( ctx->md_ctx, ipad,
- ctx->md_info->block_size ) );
+ return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
}
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
@@ -445,7 +809,43 @@
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->process_func( ctx->md_ctx, data ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_internal_md2_process( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_internal_md4_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
diff --git a/library/md_wrap.c b/library/md_wrap.c
deleted file mode 100644
index 32f0871..0000000
--- a/library/md_wrap.c
+++ /dev/null
@@ -1,586 +0,0 @@
-/**
- * \file md_wrap.c
- *
- * \brief Generic message digest wrapper for mbed TLS
- *
- * \author Adriaan de Jong <dejong@fox-it.com>
- *
- * 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)
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_MD_C)
-
-#include "mbedtls/md_internal.h"
-
-#if defined(MBEDTLS_MD2_C)
-#include "mbedtls/md2.h"
-#endif
-
-#if defined(MBEDTLS_MD4_C)
-#include "mbedtls/md4.h"
-#endif
-
-#if defined(MBEDTLS_MD5_C)
-#include "mbedtls/md5.h"
-#endif
-
-#if defined(MBEDTLS_RIPEMD160_C)
-#include "mbedtls/ripemd160.h"
-#endif
-
-#if defined(MBEDTLS_SHA1_C)
-#include "mbedtls/sha1.h"
-#endif
-
-#if defined(MBEDTLS_SHA256_C)
-#include "mbedtls/sha256.h"
-#endif
-
-#if defined(MBEDTLS_SHA512_C)
-#include "mbedtls/sha512.h"
-#endif
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdlib.h>
-#define mbedtls_calloc calloc
-#define mbedtls_free free
-#endif
-
-#if defined(MBEDTLS_MD2_C)
-
-static int md2_starts_wrap( void *ctx )
-{
- return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) );
-}
-
-static int md2_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) );
-}
-
-static int md2_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) );
-}
-
-static void *md2_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) );
-
- if( ctx != NULL )
- mbedtls_md2_init( (mbedtls_md2_context *) ctx );
-
- return( ctx );
-}
-
-static void md2_ctx_free( void *ctx )
-{
- mbedtls_md2_free( (mbedtls_md2_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md2_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md2_clone( (mbedtls_md2_context *) dst,
- (const mbedtls_md2_context *) src );
-}
-
-static int md2_process_wrap( void *ctx, const unsigned char *data )
-{
- ((void) data);
-
- return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
-}
-
-const mbedtls_md_info_t mbedtls_md2_info = {
- MBEDTLS_MD_MD2,
- "MD2",
- 16,
- 16,
- md2_starts_wrap,
- md2_update_wrap,
- md2_finish_wrap,
- mbedtls_md2_ret,
- md2_ctx_alloc,
- md2_ctx_free,
- md2_clone_wrap,
- md2_process_wrap,
-};
-
-#endif /* MBEDTLS_MD2_C */
-
-#if defined(MBEDTLS_MD4_C)
-
-static int md4_starts_wrap( void *ctx )
-{
- return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) );
-}
-
-static int md4_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) );
-}
-
-static int md4_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) );
-}
-
-static void *md4_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) );
-
- if( ctx != NULL )
- mbedtls_md4_init( (mbedtls_md4_context *) ctx );
-
- return( ctx );
-}
-
-static void md4_ctx_free( void *ctx )
-{
- mbedtls_md4_free( (mbedtls_md4_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md4_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md4_clone( (mbedtls_md4_context *) dst,
- (const mbedtls_md4_context *) src );
-}
-
-static int md4_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_md4_info = {
- MBEDTLS_MD_MD4,
- "MD4",
- 16,
- 64,
- md4_starts_wrap,
- md4_update_wrap,
- md4_finish_wrap,
- mbedtls_md4_ret,
- md4_ctx_alloc,
- md4_ctx_free,
- md4_clone_wrap,
- md4_process_wrap,
-};
-
-#endif /* MBEDTLS_MD4_C */
-
-#if defined(MBEDTLS_MD5_C)
-
-static int md5_starts_wrap( void *ctx )
-{
- return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) );
-}
-
-static int md5_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) );
-}
-
-static int md5_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) );
-}
-
-static void *md5_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) );
-
- if( ctx != NULL )
- mbedtls_md5_init( (mbedtls_md5_context *) ctx );
-
- return( ctx );
-}
-
-static void md5_ctx_free( void *ctx )
-{
- mbedtls_md5_free( (mbedtls_md5_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md5_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md5_clone( (mbedtls_md5_context *) dst,
- (const mbedtls_md5_context *) src );
-}
-
-static int md5_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_md5_info = {
- MBEDTLS_MD_MD5,
- "MD5",
- 16,
- 64,
- md5_starts_wrap,
- md5_update_wrap,
- md5_finish_wrap,
- mbedtls_md5_ret,
- md5_ctx_alloc,
- md5_ctx_free,
- md5_clone_wrap,
- md5_process_wrap,
-};
-
-#endif /* MBEDTLS_MD5_C */
-
-#if defined(MBEDTLS_RIPEMD160_C)
-
-static int ripemd160_starts_wrap( void *ctx )
-{
- return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) );
-}
-
-static int ripemd160_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx,
- input, ilen ) );
-}
-
-static int ripemd160_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx,
- output ) );
-}
-
-static void *ripemd160_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) );
-
- if( ctx != NULL )
- mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx );
-
- return( ctx );
-}
-
-static void ripemd160_ctx_free( void *ctx )
-{
- mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void ripemd160_clone_wrap( void *dst, const void *src )
-{
- mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst,
- (const mbedtls_ripemd160_context *) src );
-}
-
-static int ripemd160_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_ripemd160_process(
- (mbedtls_ripemd160_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_ripemd160_info = {
- MBEDTLS_MD_RIPEMD160,
- "RIPEMD160",
- 20,
- 64,
- ripemd160_starts_wrap,
- ripemd160_update_wrap,
- ripemd160_finish_wrap,
- mbedtls_ripemd160_ret,
- ripemd160_ctx_alloc,
- ripemd160_ctx_free,
- ripemd160_clone_wrap,
- ripemd160_process_wrap,
-};
-
-#endif /* MBEDTLS_RIPEMD160_C */
-
-#if defined(MBEDTLS_SHA1_C)
-
-static int sha1_starts_wrap( void *ctx )
-{
- return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) );
-}
-
-static int sha1_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx,
- input, ilen ) );
-}
-
-static int sha1_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) );
-}
-
-static void *sha1_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) );
-
- if( ctx != NULL )
- mbedtls_sha1_init( (mbedtls_sha1_context *) ctx );
-
- return( ctx );
-}
-
-static void sha1_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha1_clone( (mbedtls_sha1_context *) dst,
- (const mbedtls_sha1_context *) src );
-}
-
-static void sha1_ctx_free( void *ctx )
-{
- mbedtls_sha1_free( (mbedtls_sha1_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static int sha1_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha1_info = {
- MBEDTLS_MD_SHA1,
- "SHA1",
- 20,
- 64,
- sha1_starts_wrap,
- sha1_update_wrap,
- sha1_finish_wrap,
- mbedtls_sha1_ret,
- sha1_ctx_alloc,
- sha1_ctx_free,
- sha1_clone_wrap,
- sha1_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA1_C */
-
-/*
- * Wrappers for generic message digests
- */
-#if defined(MBEDTLS_SHA256_C)
-
-static int sha224_starts_wrap( void *ctx )
-{
- return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) );
-}
-
-static int sha224_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx,
- input, ilen ) );
-}
-
-static int sha224_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx,
- output ) );
-}
-
-static int sha224_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
-}
-
-static void *sha224_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) );
-
- if( ctx != NULL )
- mbedtls_sha256_init( (mbedtls_sha256_context *) ctx );
-
- return( ctx );
-}
-
-static void sha224_ctx_free( void *ctx )
-{
- mbedtls_sha256_free( (mbedtls_sha256_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void sha224_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha256_clone( (mbedtls_sha256_context *) dst,
- (const mbedtls_sha256_context *) src );
-}
-
-static int sha224_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha224_info = {
- MBEDTLS_MD_SHA224,
- "SHA224",
- 28,
- 64,
- sha224_starts_wrap,
- sha224_update_wrap,
- sha224_finish_wrap,
- sha224_wrap,
- sha224_ctx_alloc,
- sha224_ctx_free,
- sha224_clone_wrap,
- sha224_process_wrap,
-};
-
-static int sha256_starts_wrap( void *ctx )
-{
- return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) );
-}
-
-static int sha256_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha256_info = {
- MBEDTLS_MD_SHA256,
- "SHA256",
- 32,
- 64,
- sha256_starts_wrap,
- sha224_update_wrap,
- sha224_finish_wrap,
- sha256_wrap,
- sha224_ctx_alloc,
- sha224_ctx_free,
- sha224_clone_wrap,
- sha224_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA256_C */
-
-#if defined(MBEDTLS_SHA512_C)
-
-static int sha384_starts_wrap( void *ctx )
-{
- return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) );
-}
-
-static int sha384_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx,
- input, ilen ) );
-}
-
-static int sha384_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx,
- output ) );
-}
-
-static int sha384_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
-}
-
-static void *sha384_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) );
-
- if( ctx != NULL )
- mbedtls_sha512_init( (mbedtls_sha512_context *) ctx );
-
- return( ctx );
-}
-
-static void sha384_ctx_free( void *ctx )
-{
- mbedtls_sha512_free( (mbedtls_sha512_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void sha384_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha512_clone( (mbedtls_sha512_context *) dst,
- (const mbedtls_sha512_context *) src );
-}
-
-static int sha384_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha384_info = {
- MBEDTLS_MD_SHA384,
- "SHA384",
- 48,
- 128,
- sha384_starts_wrap,
- sha384_update_wrap,
- sha384_finish_wrap,
- sha384_wrap,
- sha384_ctx_alloc,
- sha384_ctx_free,
- sha384_clone_wrap,
- sha384_process_wrap,
-};
-
-static int sha512_starts_wrap( void *ctx )
-{
- return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) );
-}
-
-static int sha512_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha512_info = {
- MBEDTLS_MD_SHA512,
- "SHA512",
- 64,
- 128,
- sha512_starts_wrap,
- sha384_update_wrap,
- sha384_finish_wrap,
- sha512_wrap,
- sha384_ctx_alloc,
- sha384_ctx_free,
- sha384_clone_wrap,
- sha384_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA512_C */
-
-#endif /* MBEDTLS_MD_C */
diff --git a/tests/.gitignore b/tests/.gitignore
index 3c9b0cf..fbbd0df 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -7,3 +7,5 @@
data_files/hmac_drbg_seed
data_files/ctr_drbg_seed
data_files/entropy_seed
+
+/instrument_record_status.h
diff --git a/tests/Makefile b/tests/Makefile
index 4eb9142..f7505b6 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -28,6 +28,10 @@
LOCAL_CFLAGS += -g3
endif
+ifdef RECORD_PSA_STATUS_COVERAGE_LOG
+LOCAL_CFLAGS += -Werror -DRECORD_PSA_STATUS_COVERAGE_LOG
+endif
+
# if we're running on Windows, build for Windows
ifdef WINDOWS
WINDOWS_BUILD=1
@@ -163,3 +167,9 @@
endef
$(foreach app, $(APPS), $(foreach file, $(wildcard *.h), \
$(eval $(call copy_header_to_target,$(app),$(file)))))
+
+ifdef RECORD_PSA_STATUS_COVERAGE_LOG
+$(BINARIES): instrument_record_status.h
+instrument_record_status.h: ../include/psa/crypto.h Makefile
+ sed <../include/psa/crypto.h >$@ -n 's/^psa_status_t \([A-Za-z0-9_]*\)(.*/#define \1(...) RECORD_STATUS("\1", \1(__VA_ARGS__))/p'
+endif
diff --git a/tests/psa_crypto_helpers.h b/tests/psa_crypto_helpers.h
index 3780d16..19303de 100644
--- a/tests/psa_crypto_helpers.h
+++ b/tests/psa_crypto_helpers.h
@@ -72,4 +72,59 @@
*/
#define PSA_DONE( ) test_helper_psa_done( __LINE__, __FILE__ )
+
+
+#if defined(RECORD_PSA_STATUS_COVERAGE_LOG)
+#include <psa/crypto.h>
+
+/** Name of the file where return statuses are logged by #RECORD_STATUS. */
+#define STATUS_LOG_FILE_NAME "statuses.log"
+
+static psa_status_t record_status( psa_status_t status,
+ const char *func,
+ const char *file, int line,
+ const char *expr )
+{
+ /* We open the log file on first use.
+ * We never close the log file, so the record_status feature is not
+ * compatible with resource leak detectors such as Asan.
+ */
+ static FILE *log;
+ if( log == NULL )
+ log = fopen( STATUS_LOG_FILE_NAME, "a" );
+ fprintf( log, "%d:%s:%s:%d:%s\n", (int) status, func, file, line, expr );
+ return( status );
+}
+
+/** Return value logging wrapper macro.
+ *
+ * Evaluate \p expr. Write a line recording its value to the log file
+ * #STATUS_LOG_FILE_NAME and return the value. The line is a colon-separated
+ * list of fields:
+ * ```
+ * value of expr:string:__FILE__:__LINE__:expr
+ * ```
+ *
+ * The test code does not call this macro explicitly because that would
+ * be very invasive. Instead, we instrument the source code by defining
+ * a bunch of wrapper macros like
+ * ```
+ * #define psa_crypto_init() RECORD_STATUS("psa_crypto_init", psa_crypto_init())
+ * ```
+ * These macro definitions must be present in `instrument_record_status.h`
+ * when building the test suites.
+ *
+ * \param string A string, normally a function name.
+ * \param expr An expression to evaluate, normally a call of the function
+ * whose name is in \p string. This expression must return
+ * a value of type #psa_status_t.
+ * \return The value of \p expr.
+ */
+#define RECORD_STATUS( string, expr ) \
+ record_status( ( expr ), string, __FILE__, __LINE__, #expr )
+
+#include "instrument_record_status.h"
+
+#endif /* defined(RECORD_PSA_STATUS_COVERAGE_LOG) */
+
#endif /* PSA_CRYPTO_HELPERS_H */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 20458af..e3a8c0e 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -629,6 +629,16 @@
make test
}
+component_test_psa_collect_statuses () {
+ msg "build+test: psa_collect_statuses" # ~30s
+ scripts/config.pl full
+ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # slow and irrelevant
+ record_status tests/scripts/psa_collect_statuses.py
+ # Check that psa_crypto_init() succeeded at least once
+ record_status grep -q '^0:psa_crypto_init:' tests/statuses.log
+ rm -f tests/statuses.log
+}
+
component_test_full_cmake_clang () {
msg "build: cmake, full config, clang" # ~ 50s
scripts/config.pl full
diff --git a/tests/scripts/psa_collect_statuses.py b/tests/scripts/psa_collect_statuses.py
new file mode 100755
index 0000000..e38beea
--- /dev/null
+++ b/tests/scripts/psa_collect_statuses.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python3
+"""Describe the test coverage of PSA functions in terms of return statuses.
+
+1. Build Mbed Crypto with -DRECORD_PSA_STATUS_COVERAGE_LOG
+2. Run psa_collect_statuses.py
+
+The output is a series of line of the form "psa_foo PSA_ERROR_XXX". Each
+function/status combination appears only once.
+
+This script must be run from the top of an Mbed Crypto source tree.
+The build command is "make -DRECORD_PSA_STATUS_COVERAGE_LOG", which is
+only supported with make (as opposed to CMake or other build methods).
+"""
+
+import argparse
+import os
+import subprocess
+import sys
+
+DEFAULT_STATUS_LOG_FILE = 'tests/statuses.log'
+DEFAULT_PSA_CONSTANT_NAMES = 'programs/psa/psa_constant_names'
+
+class Statuses:
+ """Information about observed return statues of API functions."""
+
+ def __init__(self):
+ self.functions = {}
+ self.codes = set()
+ self.status_names = {}
+
+ def collect_log(self, log_file_name):
+ """Read logs from RECORD_PSA_STATUS_COVERAGE_LOG.
+
+ Read logs produced by running Mbed Crypto test suites built with
+ -DRECORD_PSA_STATUS_COVERAGE_LOG.
+ """
+ with open(log_file_name) as log:
+ for line in log:
+ value, function, tail = line.split(':', 2)
+ if function not in self.functions:
+ self.functions[function] = {}
+ fdata = self.functions[function]
+ if value not in self.functions[function]:
+ fdata[value] = []
+ fdata[value].append(tail)
+ self.codes.add(int(value))
+
+ def get_constant_names(self, psa_constant_names):
+ """Run psa_constant_names to obtain names for observed numerical values."""
+ values = [str(value) for value in self.codes]
+ cmd = [psa_constant_names, 'status'] + values
+ output = subprocess.check_output(cmd).decode('ascii')
+ for value, name in zip(values, output.rstrip().split('\n')):
+ self.status_names[value] = name
+
+ def report(self):
+ """Report observed return values for each function.
+
+ The report is a series of line of the form "psa_foo PSA_ERROR_XXX".
+ """
+ for function in sorted(self.functions.keys()):
+ fdata = self.functions[function]
+ names = [self.status_names[value] for value in fdata.keys()]
+ for name in sorted(names):
+ sys.stdout.write('{} {}\n'.format(function, name))
+
+def collect_status_logs(options):
+ """Build and run unit tests and report observed function return statuses.
+
+ Build Mbed Crypto with -DRECORD_PSA_STATUS_COVERAGE_LOG, run the
+ test suites and display information about observed return statuses.
+ """
+ rebuilt = False
+ if not options.use_existing_log and os.path.exists(options.log_file):
+ os.remove(options.log_file)
+ if not os.path.exists(options.log_file):
+ if options.clean_before:
+ subprocess.check_call(['make', 'clean'],
+ cwd='tests',
+ stdout=sys.stderr)
+ with open(os.devnull, 'w') as devnull:
+ make_q_ret = subprocess.call(['make', '-q', 'lib', 'tests'],
+ stdout=devnull, stderr=devnull)
+ if make_q_ret != 0:
+ subprocess.check_call(['make', 'RECORD_PSA_STATUS_COVERAGE_LOG=1'],
+ stdout=sys.stderr)
+ rebuilt = True
+ subprocess.check_call(['make', 'test'],
+ stdout=sys.stderr)
+ data = Statuses()
+ data.collect_log(options.log_file)
+ data.get_constant_names(options.psa_constant_names)
+ if rebuilt and options.clean_after:
+ subprocess.check_call(['make', 'clean'],
+ cwd='tests',
+ stdout=sys.stderr)
+ return data
+
+def main():
+ parser = argparse.ArgumentParser(description=globals()['__doc__'])
+ parser.add_argument('--clean-after',
+ action='store_true',
+ help='Run "make clean" after rebuilding')
+ parser.add_argument('--clean-before',
+ action='store_true',
+ help='Run "make clean" before regenerating the log file)')
+ parser.add_argument('--log-file', metavar='FILE',
+ default=DEFAULT_STATUS_LOG_FILE,
+ help='Log file location (default: {})'.format(
+ DEFAULT_STATUS_LOG_FILE
+ ))
+ parser.add_argument('--psa-constant-names', metavar='PROGRAM',
+ default=DEFAULT_PSA_CONSTANT_NAMES,
+ help='Path to psa_constant_names (default: {})'.format(
+ DEFAULT_PSA_CONSTANT_NAMES
+ ))
+ parser.add_argument('--use-existing-log', '-e',
+ action='store_true',
+ help='Don\'t regenerate the log file if it exists')
+ options = parser.parse_args()
+ data = collect_status_logs(options)
+ data.report()
+
+if __name__ == '__main__':
+ main()
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index 0456bc2..7f71a5a 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -269,7 +269,6 @@
<ClCompile Include="..\..\library\md2.c" />
<ClCompile Include="..\..\library\md4.c" />
<ClCompile Include="..\..\library\md5.c" />
- <ClCompile Include="..\..\library\md_wrap.c" />
<ClCompile Include="..\..\library\memory_buffer_alloc.c" />
<ClCompile Include="..\..\library\nist_kw.c" />
<ClCompile Include="..\..\library\oid.c" />