Merge branch 'md_hmac' into development

* md_hmac: (21 commits)
  Add more tests for MD utility functions
  Rework documentation of MD layer
  Check return value of the TLS PRF
  Make tls1_prf and tls12_prf more efficient
  Factor tls_prf_sha{256,384} together
  Reintroduce md_init_ctx compatibility wrapper
  Rename md_init_ctx() to md_setup()
  Update doxygen documentation on HMAC
  Clean up unneeded things
  Make hmac_ctx optional
  Make ipad/opad dynamic and more opaque
  Remove ipad and opad from specific md contexts
  Remove specific xxx_hmac functions
  Remove use of xxx_hmac() in program
  Remove calls to xxx_hmac() from SSL modules
  Remove references to xxx_hmac() from MD layer
  Remove tests for xxx_hmac()
  Implement hmac in the MD layer
  Add generic HMAC tests from mdx.data
  Fix tests and programs to use md_get_xxx()
  ...
diff --git a/ChangeLog b/ChangeLog
index b0900d2..82c9a88 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,11 @@
   * Support for DTLS 1.0 and 1.2 (RFC 6347).
 
 API Changes
+   * md_init_ctx() is deprecated in favour of md_setup(), that adds a third
+     argument (allowing memory savings if HMAC is not used)
+   * Removed individual mdX_hmac and shaX_hmac functions (use generic
+     md_hmac functions from md.h)
+   * 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/doxygen/input/doc_hashing.h b/doxygen/input/doc_hashing.h
index 38f8e81..0d194e6 100644
--- a/doxygen/input/doc_hashing.h
+++ b/doxygen/input/doc_hashing.h
@@ -12,13 +12,12 @@
  * for authentication, which is a message integrity control.
  *
  * All hash algorithms can be accessed via the generic MD layer (see
- * \c md_init_ctx())
+ * \c md_setup())
  *
  * The following hashing-algorithms are provided:
- * - MD2, MD4, MD5 128-bit one-way hash functions by Ron Rivest (see
- *   \c md2_hmac(), \c md4_hmac() and \c md5_hmac()).
+ * - MD2, MD4, MD5 128-bit one-way hash functions by Ron Rivest.
  * - SHA-1, SHA-256, SHA-384/512 160-bit or more one-way hash functions by
- *   NIST and NSA (see\c sha1_hmac(), \c sha256_hmac() and \c sha512_hmac()).
+ *   NIST and NSA.
  *
  * This module provides one-way hashing which can be used for authentication.
  */
diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h
index a1d6873..0f1b615 100644
--- a/include/mbedtls/md.h
+++ b/include/mbedtls/md.h
@@ -5,7 +5,7 @@
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
  *
- *  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 @@
 #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.
@@ -132,12 +78,10 @@
 
     /** Digest-specific context */
     void *md_ctx;
-} md_context_t;
 
-#define MD_CONTEXT_T_INIT { \
-    NULL, /* md_info */ \
-    NULL, /* md_ctx */ \
-}
+    /** HMAC part of the context */
+    void *hmac_ctx;
+} md_context_t;
 
 /**
  * \brief Returns the list of digests supported by the generic digest module.
@@ -170,35 +114,58 @@
 const md_info_t *md_info_from_type( md_type_t md_type );
 
 /**
- * \brief               Initialize a md_context (as NONE)
+ * \brief           Initialize a md_context (as NONE)
+ *                  This should always be called first.
+ *                  Prepares the context for md_setup() or md_free().
  */
 void md_init( md_context_t *ctx );
 
 /**
- * \brief               Free and clear the message-specific context of ctx.
- *                      Freeing ctx itself remains the responsibility of the
- *                      caller.
+ * \brief           Free and clear the internal structures of ctx.
+ *                  Can be called at any time after md_init().
+ *                  Mandatory once md_setup() has been called.
  */
 void md_free( md_context_t *ctx );
 
+#if ! defined(POLARSSL_DEPRECATED_REMOVED)
+#if defined(POLARSSL_DEPRECATED_WARNING)
+#define DEPRECATED    __attribute__((deprecated))
+#else
+#define DEPRECATED
+#endif
 /**
- * \brief          Initialises and fills the message digest context structure
- *                 with the appropriate values.
+ * \brief           Select MD to use and allocate internal structures.
+ *                  Should be called after md_init() or md_free().
+ *                  Makes it necessary to call md_free() later.
  *
- * \note           Currently also clears structure. In future versions you
- *                 will be required to call md_init() on the structure
- *                 first.
+ * \deprecated      Superseded by md_setup() in 2.0.0
  *
- * \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.
- * \param md_info  message digest to use.
+ * \param ctx       Context to set up.
+ * \param md_info   Message digest to use.
  *
- * \returns        \c 0 on success, \c POLARSSL_ERR_MD_BAD_INPUT_DATA on
- *                 parameter failure, \c POLARSSL_ERR_MD_ALLOC_FAILED if
- *                 allocation of the digest-specific context failed.
+ * \returns         \c 0 on success,
+ *                  \c POLARSSL_ERR_MD_BAD_INPUT_DATA on parameter failure,
+ *                  \c POLARSSL_ERR_MD_ALLOC_FAILED memory allocation failure.
  */
-int md_init_ctx( md_context_t *ctx, const md_info_t *md_info );
+int md_init_ctx( md_context_t *ctx, const md_info_t *md_info ) DEPRECATED;
+#undef DEPRECATED
+#endif /* POLARSSL_DEPRECATED_REMOVED */
+
+/**
+ * \brief           Select MD to use and allocate internal structures.
+ *                  Should be called after md_init() or md_free().
+ *                  Makes it necessary to call md_free() later.
+ *
+ * \param ctx       Context to set up.
+ * \param md_info   Message digest to use.
+ * \param hmac      0 to save some meory is HMAC will not be use,
+ *                  non-zero is HMAC is going to be used with this context.
+ *
+ * \returns         \c 0 on success,
+ *                  \c POLARSSL_ERR_MD_BAD_INPUT_DATA on parameter failure,
+ *                  \c POLARSSL_ERR_MD_ALLOC_FAILED memory allocation failure.
+ */
+int md_setup( md_context_t *ctx, const md_info_t *md_info, int hmac );
 
 /**
  * \brief           Returns the size of the message digest output.
@@ -207,13 +174,7 @@
  *
  * \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 +183,7 @@
  *
  * \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,44 +192,44 @@
  *
  * \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
+ * \brief           Prepare the context to digest a new message.
+ *                  Generally called after md_setup() or md_finish().
+ *                  Followed by md_update().
  *
- * \param ctx      generic message digest context.
+ * \param ctx       generic message digest context.
  *
- * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
- *                 verification fails.
+ * \returns         0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                  verification fails.
  */
 int md_starts( md_context_t *ctx );
 
 /**
- * \brief          Generic message digest process buffer
+ * \brief           Generic message digest process buffer
+ *                  Called between md_starts() and md_finish().
+ *                  May be called repeatedly.
  *
- * \param ctx      Generic message digest context
- * \param input    buffer holding the  datal
- * \param ilen     length of the input data
+ * \param ctx       Generic message digest context
+ * \param input     buffer holding the  datal
+ * \param ilen      length of the input data
  *
- * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
- *                 verification fails.
+ * \returns         0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                  verification fails.
  */
 int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen );
 
 /**
- * \brief          Generic message digest final digest
+ * \brief           Generic message digest final digest
+ *                  Called after md_update().
+ *                  Usually followed by md_free() or md_starts().
  *
- * \param ctx      Generic message digest context
- * \param output   Generic message digest checksum result
+ * \param ctx       Generic message digest context
+ * \param output    Generic message digest checksum result
  *
- * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
- *                 verification fails.
+ * \returns         0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                  verification fails.
  */
 int md_finish( md_context_t *ctx, unsigned char *output );
 
@@ -307,49 +262,57 @@
              unsigned char *output );
 
 /**
- * \brief          Generic HMAC context setup
+ * \brief           Set HMAC key and prepare to authenticate a new message.
+ *                  Usually called after md_setup() or md_hmac_finish().
  *
- * \param ctx      HMAC context to be initialized
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
+ * \param ctx       HMAC context
+ * \param key       HMAC secret key
+ * \param keylen    length of the HMAC key
  *
- * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
- *                 verification fails.
+ * \returns         0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                  verification fails.
  */
 int md_hmac_starts( md_context_t *ctx, const unsigned char *key,
                     size_t keylen );
 
 /**
- * \brief          Generic HMAC process buffer
+ * \brief           Generic HMAC process buffer.
+ *                  Called between md_hmac_starts() or md_hmac_reset()
+ *                  and md_hmac_finish().
+ *                  May be called repeatedly.
  *
- * \param ctx      HMAC context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
+ * \param ctx       HMAC context
+ * \param input     buffer holding the  data
+ * \param ilen      length of the input data
  *
- * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
- *                 verification fails.
+ * \returns         0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                  verification fails.
  */
 int md_hmac_update( md_context_t *ctx, const unsigned char *input,
                     size_t ilen );
 
 /**
- * \brief          Generic HMAC final digest
+ * \brief           Output HMAC.
+ *                  Called after md_hmac_update().
+ *                  Usually followed my md_hmac_reset(), md_hmac_starts(),
+ *                  or md_free().
  *
- * \param ctx      HMAC context
- * \param output   Generic HMAC checksum result
+ * \param ctx       HMAC context
+ * \param output    Generic HMAC checksum result
  *
- * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
- *                 verification fails.
+ * \returns         0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                  verification fails.
  */
 int md_hmac_finish( md_context_t *ctx, unsigned char *output);
 
 /**
- * \brief          Generic HMAC context reset
+ * \brief           Prepare to authenticate a new message with the same key.
+ *                  Called after md_hmac_finish() and before md_hmac_update().
  *
- * \param ctx      HMAC context to be reset
+ * \param ctx       HMAC context to be reset
  *
- * \returns        0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
- *                 verification fails.
+ * \returns         0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
+ *                  verification fails.
  */
 int md_hmac_reset( md_context_t *ctx );
 
diff --git a/include/mbedtls/md2.h b/include/mbedtls/md2.h
index 53c85f8..af400db 100644
--- a/include/mbedtls/md2.h
+++ b/include/mbedtls/md2.h
@@ -50,9 +50,6 @@
     unsigned char cksum[16];    /*!< checksum of the data block */
     unsigned char state[48];    /*!< intermediate digest state  */
     unsigned char buffer[16];   /*!< data block being processed */
-
-    unsigned char ipad[16];     /*!< HMAC: inner padding        */
-    unsigned char opad[16];     /*!< HMAC: outer padding        */
     size_t left;                /*!< amount of data in buffer   */
 }
 md2_context;
@@ -127,54 +124,6 @@
 int md2_file( const char *path, unsigned char output[16] );
 
 /**
- * \brief          MD2 HMAC context setup
- *
- * \param ctx      HMAC context to be initialized
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- */
-void md2_hmac_starts( md2_context *ctx, const unsigned char *key,
-                      size_t keylen );
-
-/**
- * \brief          MD2 HMAC process buffer
- *
- * \param ctx      HMAC context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- */
-void md2_hmac_update( md2_context *ctx, const unsigned char *input,
-                      size_t ilen );
-
-/**
- * \brief          MD2 HMAC final digest
- *
- * \param ctx      HMAC context
- * \param output   MD2 HMAC checksum result
- */
-void md2_hmac_finish( md2_context *ctx, unsigned char output[16] );
-
-/**
- * \brief          MD2 HMAC context reset
- *
- * \param ctx      HMAC context to be reset
- */
-void md2_hmac_reset( md2_context *ctx );
-
-/**
- * \brief          Output = HMAC-MD2( hmac key, input buffer )
- *
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   HMAC-MD2 result
- */
-void md2_hmac( const unsigned char *key, size_t keylen,
-               const unsigned char *input, size_t ilen,
-               unsigned char output[16] );
-
-/**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
diff --git a/include/mbedtls/md4.h b/include/mbedtls/md4.h
index 68ac6c1..30b904c 100644
--- a/include/mbedtls/md4.h
+++ b/include/mbedtls/md4.h
@@ -57,9 +57,6 @@
     uint32_t total[2];          /*!< number of bytes processed  */
     uint32_t state[4];          /*!< intermediate digest state  */
     unsigned char buffer[64];   /*!< data block being processed */
-
-    unsigned char ipad[64];     /*!< HMAC: inner padding        */
-    unsigned char opad[64];     /*!< HMAC: outer padding        */
 }
 md4_context;
 
@@ -133,54 +130,6 @@
 int md4_file( const char *path, unsigned char output[16] );
 
 /**
- * \brief          MD4 HMAC context setup
- *
- * \param ctx      HMAC context to be initialized
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- */
-void md4_hmac_starts( md4_context *ctx, const unsigned char *key,
-                      size_t keylen );
-
-/**
- * \brief          MD4 HMAC process buffer
- *
- * \param ctx      HMAC context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- */
-void md4_hmac_update( md4_context *ctx, const unsigned char *input,
-                      size_t ilen );
-
-/**
- * \brief          MD4 HMAC final digest
- *
- * \param ctx      HMAC context
- * \param output   MD4 HMAC checksum result
- */
-void md4_hmac_finish( md4_context *ctx, unsigned char output[16] );
-
-/**
- * \brief          MD4 HMAC context reset
- *
- * \param ctx      HMAC context to be reset
- */
-void md4_hmac_reset( md4_context *ctx );
-
-/**
- * \brief          Output = HMAC-MD4( hmac key, input buffer )
- *
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   HMAC-MD4 result
- */
-void md4_hmac( const unsigned char *key, size_t keylen,
-               const unsigned char *input, size_t ilen,
-               unsigned char output[16] );
-
-/**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
diff --git a/include/mbedtls/md5.h b/include/mbedtls/md5.h
index d5ce136..aa649ea 100644
--- a/include/mbedtls/md5.h
+++ b/include/mbedtls/md5.h
@@ -57,9 +57,6 @@
     uint32_t total[2];          /*!< number of bytes processed  */
     uint32_t state[4];          /*!< intermediate digest state  */
     unsigned char buffer[64];   /*!< data block being processed */
-
-    unsigned char ipad[64];     /*!< HMAC: inner padding        */
-    unsigned char opad[64];     /*!< HMAC: outer padding        */
 }
 md5_context;
 
@@ -136,54 +133,6 @@
 int md5_file( const char *path, unsigned char output[16] );
 
 /**
- * \brief          MD5 HMAC context setup
- *
- * \param ctx      HMAC context to be initialized
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- */
-void md5_hmac_starts( md5_context *ctx,
-                      const unsigned char *key, size_t keylen );
-
-/**
- * \brief          MD5 HMAC process buffer
- *
- * \param ctx      HMAC context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- */
-void md5_hmac_update( md5_context *ctx,
-                      const unsigned char *input, size_t ilen );
-
-/**
- * \brief          MD5 HMAC final digest
- *
- * \param ctx      HMAC context
- * \param output   MD5 HMAC checksum result
- */
-void md5_hmac_finish( md5_context *ctx, unsigned char output[16] );
-
-/**
- * \brief          MD5 HMAC context reset
- *
- * \param ctx      HMAC context to be reset
- */
-void md5_hmac_reset( md5_context *ctx );
-
-/**
- * \brief          Output = HMAC-MD5( hmac key, input buffer )
- *
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   HMAC-MD5 result
- */
-void md5_hmac( const unsigned char *key, size_t keylen,
-               const unsigned char *input, size_t ilen,
-               unsigned char output[16] );
-
-/**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
diff --git a/include/mbedtls/md_wrap.h b/include/mbedtls/md_wrap.h
index dd5fd6c..418b3f1 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 <dejong@fox-it.com>
  *
- *  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,49 @@
 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;
+
+    /** Block length of the digest function */
+    int block_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 );
+
+    /** 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/include/mbedtls/ripemd160.h b/include/mbedtls/ripemd160.h
index 2555eb4..48db853 100644
--- a/include/mbedtls/ripemd160.h
+++ b/include/mbedtls/ripemd160.h
@@ -57,9 +57,6 @@
     uint32_t total[2];          /*!< number of bytes processed  */
     uint32_t state[5];          /*!< intermediate digest state  */
     unsigned char buffer[64];   /*!< data block being processed */
-
-    unsigned char ipad[64];     /*!< HMAC: inner padding        */
-    unsigned char opad[64];     /*!< HMAC: outer padding        */
 }
 ripemd160_context;
 
@@ -140,54 +137,6 @@
 #endif /* POLARSSL_FS_IO */
 
 /**
- * \brief          RIPEMD-160 HMAC context setup
- *
- * \param ctx      HMAC context to be initialized
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- */
-void ripemd160_hmac_starts( ripemd160_context *ctx,
-                            const unsigned char *key, size_t keylen );
-
-/**
- * \brief          RIPEMD-160 HMAC process buffer
- *
- * \param ctx      HMAC context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- */
-void ripemd160_hmac_update( ripemd160_context *ctx,
-                            const unsigned char *input, size_t ilen );
-
-/**
- * \brief          RIPEMD-160 HMAC final digest
- *
- * \param ctx      HMAC context
- * \param output   RIPEMD-160 HMAC checksum result
- */
-void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] );
-
-/**
- * \brief          RIPEMD-160 HMAC context reset
- *
- * \param ctx      HMAC context to be reset
- */
-void ripemd160_hmac_reset( ripemd160_context *ctx );
-
-/**
- * \brief          Output = HMAC-RIPEMD-160( hmac key, input buffer )
- *
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   HMAC-RIPEMD-160 result
- */
-void ripemd160_hmac( const unsigned char *key, size_t keylen,
-                     const unsigned char *input, size_t ilen,
-                     unsigned char output[20] );
-
-/**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
diff --git a/include/mbedtls/sha1.h b/include/mbedtls/sha1.h
index e9e5a8e..3978883 100644
--- a/include/mbedtls/sha1.h
+++ b/include/mbedtls/sha1.h
@@ -57,9 +57,6 @@
     uint32_t total[2];          /*!< number of bytes processed  */
     uint32_t state[5];          /*!< intermediate digest state  */
     unsigned char buffer[64];   /*!< data block being processed */
-
-    unsigned char ipad[64];     /*!< HMAC: inner padding        */
-    unsigned char opad[64];     /*!< HMAC: outer padding        */
 }
 sha1_context;
 
@@ -136,54 +133,6 @@
 int sha1_file( const char *path, unsigned char output[20] );
 
 /**
- * \brief          SHA-1 HMAC context setup
- *
- * \param ctx      HMAC context to be initialized
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- */
-void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key,
-                       size_t keylen );
-
-/**
- * \brief          SHA-1 HMAC process buffer
- *
- * \param ctx      HMAC context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- */
-void sha1_hmac_update( sha1_context *ctx, const unsigned char *input,
-                       size_t ilen );
-
-/**
- * \brief          SHA-1 HMAC final digest
- *
- * \param ctx      HMAC context
- * \param output   SHA-1 HMAC checksum result
- */
-void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
-
-/**
- * \brief          SHA-1 HMAC context reset
- *
- * \param ctx      HMAC context to be reset
- */
-void sha1_hmac_reset( sha1_context *ctx );
-
-/**
- * \brief          Output = HMAC-SHA-1( hmac key, input buffer )
- *
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   HMAC-SHA-1 result
- */
-void sha1_hmac( const unsigned char *key, size_t keylen,
-                const unsigned char *input, size_t ilen,
-                unsigned char output[20] );
-
-/**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
diff --git a/include/mbedtls/sha256.h b/include/mbedtls/sha256.h
index f8917ff..ff511ad 100644
--- a/include/mbedtls/sha256.h
+++ b/include/mbedtls/sha256.h
@@ -57,9 +57,6 @@
     uint32_t total[2];          /*!< number of bytes processed  */
     uint32_t state[8];          /*!< intermediate digest state  */
     unsigned char buffer[64];   /*!< data block being processed */
-
-    unsigned char ipad[64];     /*!< HMAC: inner padding        */
-    unsigned char opad[64];     /*!< HMAC: outer padding        */
     int is224;                  /*!< 0 => SHA-256, else SHA-224 */
 }
 sha256_context;
@@ -142,56 +139,6 @@
 int sha256_file( const char *path, unsigned char output[32], int is224 );
 
 /**
- * \brief          SHA-256 HMAC context setup
- *
- * \param ctx      HMAC context to be initialized
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- * \param is224    0 = use SHA256, 1 = use SHA224
- */
-void sha256_hmac_starts( sha256_context *ctx, const unsigned char *key,
-                         size_t keylen, int is224 );
-
-/**
- * \brief          SHA-256 HMAC process buffer
- *
- * \param ctx      HMAC context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- */
-void sha256_hmac_update( sha256_context *ctx, const unsigned char *input,
-                         size_t ilen );
-
-/**
- * \brief          SHA-256 HMAC final digest
- *
- * \param ctx      HMAC context
- * \param output   SHA-224/256 HMAC checksum result
- */
-void sha256_hmac_finish( sha256_context *ctx, unsigned char output[32] );
-
-/**
- * \brief          SHA-256 HMAC context reset
- *
- * \param ctx      HMAC context to be reset
- */
-void sha256_hmac_reset( sha256_context *ctx );
-
-/**
- * \brief          Output = HMAC-SHA-256( hmac key, input buffer )
- *
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   HMAC-SHA-224/256 result
- * \param is224    0 = use SHA256, 1 = use SHA224
- */
-void sha256_hmac( const unsigned char *key, size_t keylen,
-                  const unsigned char *input, size_t ilen,
-                  unsigned char output[32], int is224 );
-
-/**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index 15d266c..c5cb11b 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -56,9 +56,6 @@
     uint64_t total[2];          /*!< number of bytes processed  */
     uint64_t state[8];          /*!< intermediate digest state  */
     unsigned char buffer[128];  /*!< data block being processed */
-
-    unsigned char ipad[128];    /*!< HMAC: inner padding        */
-    unsigned char opad[128];    /*!< HMAC: outer padding        */
     int is384;                  /*!< 0 => SHA-512, else SHA-384 */
 }
 sha512_context;
@@ -138,56 +135,6 @@
 int sha512_file( const char *path, unsigned char output[64], int is384 );
 
 /**
- * \brief          SHA-512 HMAC context setup
- *
- * \param ctx      HMAC context to be initialized
- * \param is384    0 = use SHA512, 1 = use SHA384
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- */
-void sha512_hmac_starts( sha512_context *ctx, const unsigned char *key,
-                         size_t keylen, int is384 );
-
-/**
- * \brief          SHA-512 HMAC process buffer
- *
- * \param ctx      HMAC context
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- */
-void sha512_hmac_update( sha512_context *ctx, const unsigned char *input,
-                         size_t ilen );
-
-/**
- * \brief          SHA-512 HMAC final digest
- *
- * \param ctx      HMAC context
- * \param output   SHA-384/512 HMAC checksum result
- */
-void sha512_hmac_finish( sha512_context *ctx, unsigned char output[64] );
-
-/**
- * \brief          SHA-512 HMAC context reset
- *
- * \param ctx      HMAC context to be reset
- */
-void sha512_hmac_reset( sha512_context *ctx );
-
-/**
- * \brief          Output = HMAC-SHA-512( hmac key, input buffer )
- *
- * \param key      HMAC secret key
- * \param keylen   length of the HMAC key
- * \param input    buffer holding the  data
- * \param ilen     length of the input data
- * \param output   HMAC-SHA-384/512 result
- * \param is384    0 = use SHA512, 1 = use SHA384
- */
-void sha512_hmac( const unsigned char *key, size_t keylen,
-                const unsigned char *input, size_t ilen,
-                unsigned char output[64], int is384 );
-
-/**
  * \brief          Checkup routine
  *
  * \return         0 if successful, or 1 if the test failed
diff --git a/library/ecdsa.c b/library/ecdsa.c
index c95f90b..c39c9c3 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -60,8 +60,9 @@
     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 dc26b0d..159d72e 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -62,7 +62,7 @@
 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];
@@ -97,7 +97,7 @@
 
     md_init( &ctx->md_ctx );
 
-    if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 )
+    if( ( ret = md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
         return( ret );
 
     /*
@@ -105,8 +105,8 @@
      * 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,22 +165,24 @@
                     size_t len )
 {
     int ret;
-    size_t entropy_len;
+    size_t entropy_len, md_size;
 
     memset( ctx, 0, sizeof( hmac_drbg_context ) );
 
     md_init( &ctx->md_ctx );
 
-    if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 )
+    if( ( ret = md_setup( &ctx->md_ctx, md_info, 1 ) ) != 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 @@
      *
      * (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 c34e121..74038ae 100644
--- a/library/md.c
+++ b/library/md.c
@@ -35,7 +35,14 @@
 #include "mbedtls/md.h"
 #include "mbedtls/md_wrap.h"
 
+#if defined(POLARSSL_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
 #include <stdlib.h>
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <string.h>
 
 #if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \
@@ -177,28 +184,47 @@
 
 void md_free( md_context_t *ctx )
 {
-    if( ctx == NULL )
+    if( ctx == NULL || ctx->md_info == NULL )
         return;
 
-    if( ctx->md_ctx )
+    if( ctx->md_ctx != NULL )
         ctx->md_info->ctx_free_func( ctx->md_ctx );
 
+    if( ctx->hmac_ctx != NULL )
+    {
+        polarssl_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size );
+        polarssl_free( ctx->hmac_ctx );
+    }
+
     polarssl_zeroize( ctx, sizeof( md_context_t ) );
 }
 
+#if ! defined(POLARSSL_DEPRECATED_REMOVED)
 int md_init_ctx( md_context_t *ctx, const md_info_t *md_info )
 {
+    return md_setup( ctx, md_info, 1 );
+}
+#endif
+
+int md_setup( md_context_t *ctx, const md_info_t *md_info, int hmac )
+{
     if( md_info == NULL || ctx == NULL )
         return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
 
-    memset( ctx, 0, sizeof( md_context_t ) );
-
     if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
         return( POLARSSL_ERR_MD_ALLOC_FAILED );
 
-    ctx->md_info = md_info;
+    if( hmac != 0 )
+    {
+        ctx->hmac_ctx = polarssl_malloc( 2 * md_info->block_size );
+        if( ctx->hmac_ctx == NULL )
+        {
+            md_info->ctx_free_func( ctx->md_ctx );
+            return( POLARSSL_ERR_MD_ALLOC_FAILED );
+        }
+    }
 
-    md_info->starts_func( ctx->md_ctx );
+    ctx->md_info = md_info;
 
     return( 0 );
 }
@@ -269,40 +295,83 @@
 
 int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen )
 {
-    if( ctx == NULL || ctx->md_info == NULL )
+    unsigned char sum[POLARSSL_MD_MAX_SIZE];
+    unsigned char *ipad, *opad;
+    size_t i;
+
+    if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
         return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen );
+    if( keylen > (size_t) ctx->md_info->block_size )
+    {
+        ctx->md_info->starts_func( ctx->md_ctx );
+        ctx->md_info->update_func( ctx->md_ctx, key, keylen );
+        ctx->md_info->finish_func( ctx->md_ctx, sum );
+
+        keylen = ctx->md_info->size;
+        key = sum;
+    }
+
+    ipad = (unsigned char *) ctx->hmac_ctx;
+    opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
+
+    memset( ipad, 0x36, ctx->md_info->block_size );
+    memset( opad, 0x5C, ctx->md_info->block_size );
+
+    for( i = 0; i < keylen; i++ )
+    {
+        ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
+        opad[i] = (unsigned char)( opad[i] ^ key[i] );
+    }
+
+    polarssl_zeroize( sum, sizeof( sum ) );
+
+    ctx->md_info->starts_func( ctx->md_ctx );
+    ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size );
 
     return( 0 );
 }
 
 int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
 {
-    if( ctx == NULL || ctx->md_info == NULL )
+    if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
         return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->hmac_update_func( ctx->md_ctx, input, ilen );
+    ctx->md_info->update_func( ctx->md_ctx, input, ilen );
 
     return( 0 );
 }
 
 int md_hmac_finish( md_context_t *ctx, unsigned char *output )
 {
-    if( ctx == NULL || ctx->md_info == NULL )
+    unsigned char tmp[POLARSSL_MD_MAX_SIZE];
+    unsigned char *opad;
+
+    if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
         return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->hmac_finish_func( ctx->md_ctx, output );
+    opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
+
+    ctx->md_info->finish_func( ctx->md_ctx, tmp );
+    ctx->md_info->starts_func( ctx->md_ctx );
+    ctx->md_info->update_func( ctx->md_ctx, opad, ctx->md_info->block_size );
+    ctx->md_info->update_func( ctx->md_ctx, tmp, ctx->md_info->size );
+    ctx->md_info->finish_func( ctx->md_ctx, output );
 
     return( 0 );
 }
 
 int md_hmac_reset( md_context_t *ctx )
 {
-    if( ctx == NULL || ctx->md_info == NULL )
+    unsigned char *ipad;
+
+    if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
         return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->hmac_reset_func( ctx->md_ctx );
+    ipad = (unsigned char *) ctx->hmac_ctx;
+
+    ctx->md_info->starts_func( ctx->md_ctx );
+    ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size );
 
     return( 0 );
 }
@@ -311,10 +380,22 @@
                 const unsigned char *input, size_t ilen,
                 unsigned char *output )
 {
+    md_context_t ctx;
+    int ret;
+
     if( md_info == NULL )
         return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
 
-    md_info->hmac_func( key, keylen, input, ilen, output );
+    md_init( &ctx );
+
+    if( ( ret = md_setup( &ctx, md_info, 1 ) ) != 0 )
+        return( ret );
+
+    md_hmac_starts( &ctx, key, keylen );
+    md_hmac_update( &ctx, input, ilen );
+    md_hmac_finish( &ctx, output );
+
+    md_free( &ctx );
 
     return( 0 );
 }
@@ -329,4 +410,28 @@
     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/md2.c b/library/md2.c
index a8b67f3..9510843 100644
--- a/library/md2.c
+++ b/library/md2.c
@@ -245,87 +245,6 @@
 }
 #endif /* POLARSSL_FS_IO */
 
-/*
- * MD2 HMAC context setup
- */
-void md2_hmac_starts( md2_context *ctx, const unsigned char *key,
-                      size_t keylen )
-{
-    size_t i;
-    unsigned char sum[16];
-
-    if( keylen > 16 )
-    {
-        md2( key, keylen, sum );
-        keylen = 16;
-        key = sum;
-    }
-
-    memset( ctx->ipad, 0x36, 16 );
-    memset( ctx->opad, 0x5C, 16 );
-
-    for( i = 0; i < keylen; i++ )
-    {
-        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
-        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
-    }
-
-    md2_starts( ctx );
-    md2_update( ctx, ctx->ipad, 16 );
-
-    polarssl_zeroize( sum, sizeof( sum ) );
-}
-
-/*
- * MD2 HMAC process buffer
- */
-void md2_hmac_update( md2_context *ctx, const unsigned char *input,
-                      size_t ilen )
-{
-    md2_update( ctx, input, ilen );
-}
-
-/*
- * MD2 HMAC final digest
- */
-void md2_hmac_finish( md2_context *ctx, unsigned char output[16] )
-{
-    unsigned char tmpbuf[16];
-
-    md2_finish( ctx, tmpbuf );
-    md2_starts( ctx );
-    md2_update( ctx, ctx->opad, 16 );
-    md2_update( ctx, tmpbuf, 16 );
-    md2_finish( ctx, output );
-
-    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
-}
-
-/*
- * MD2 HMAC context reset
- */
-void md2_hmac_reset( md2_context *ctx )
-{
-    md2_starts( ctx );
-    md2_update( ctx, ctx->ipad, 16 );
-}
-
-/*
- * output = HMAC-MD2( hmac key, input buffer )
- */
-void md2_hmac( const unsigned char *key, size_t keylen,
-               const unsigned char *input, size_t ilen,
-               unsigned char output[16] )
-{
-    md2_context ctx;
-
-    md2_init( &ctx );
-    md2_hmac_starts( &ctx, key, keylen );
-    md2_hmac_update( &ctx, input, ilen );
-    md2_hmac_finish( &ctx, output );
-    md2_free( &ctx );
-}
-
 #if defined(POLARSSL_SELF_TEST)
 
 /*
diff --git a/library/md4.c b/library/md4.c
index e62a92d..47f762d 100644
--- a/library/md4.c
+++ b/library/md4.c
@@ -341,87 +341,6 @@
 }
 #endif /* POLARSSL_FS_IO */
 
-/*
- * MD4 HMAC context setup
- */
-void md4_hmac_starts( md4_context *ctx, const unsigned char *key,
-                      size_t keylen )
-{
-    size_t i;
-    unsigned char sum[16];
-
-    if( keylen > 64 )
-    {
-        md4( key, keylen, sum );
-        keylen = 16;
-        key = sum;
-    }
-
-    memset( ctx->ipad, 0x36, 64 );
-    memset( ctx->opad, 0x5C, 64 );
-
-    for( i = 0; i < keylen; i++ )
-    {
-        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
-        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
-    }
-
-    md4_starts( ctx );
-    md4_update( ctx, ctx->ipad, 64 );
-
-    polarssl_zeroize( sum, sizeof( sum ) );
-}
-
-/*
- * MD4 HMAC process buffer
- */
-void md4_hmac_update( md4_context *ctx, const unsigned char *input,
-                      size_t ilen )
-{
-    md4_update( ctx, input, ilen );
-}
-
-/*
- * MD4 HMAC final digest
- */
-void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
-{
-    unsigned char tmpbuf[16];
-
-    md4_finish( ctx, tmpbuf );
-    md4_starts( ctx );
-    md4_update( ctx, ctx->opad, 64 );
-    md4_update( ctx, tmpbuf, 16 );
-    md4_finish( ctx, output );
-
-    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
-}
-
-/*
- * MD4 HMAC context reset
- */
-void md4_hmac_reset( md4_context *ctx )
-{
-    md4_starts( ctx );
-    md4_update( ctx, ctx->ipad, 64 );
-}
-
-/*
- * output = HMAC-MD4( hmac key, input buffer )
- */
-void md4_hmac( const unsigned char *key, size_t keylen,
-               const unsigned char *input, size_t ilen,
-               unsigned char output[16] )
-{
-    md4_context ctx;
-
-    md4_init( &ctx );
-    md4_hmac_starts( &ctx, key, keylen );
-    md4_hmac_update( &ctx, input, ilen );
-    md4_hmac_finish( &ctx, output );
-    md4_free( &ctx );
-}
-
 #if defined(POLARSSL_SELF_TEST)
 
 /*
diff --git a/library/md5.c b/library/md5.c
index 05651cb..62f619b 100644
--- a/library/md5.c
+++ b/library/md5.c
@@ -358,87 +358,6 @@
 }
 #endif /* POLARSSL_FS_IO */
 
-/*
- * MD5 HMAC context setup
- */
-void md5_hmac_starts( md5_context *ctx, const unsigned char *key,
-                      size_t keylen )
-{
-    size_t i;
-    unsigned char sum[16];
-
-    if( keylen > 64 )
-    {
-        md5( key, keylen, sum );
-        keylen = 16;
-        key = sum;
-    }
-
-    memset( ctx->ipad, 0x36, 64 );
-    memset( ctx->opad, 0x5C, 64 );
-
-    for( i = 0; i < keylen; i++ )
-    {
-        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
-        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
-    }
-
-    md5_starts( ctx );
-    md5_update( ctx, ctx->ipad, 64 );
-
-    polarssl_zeroize( sum, sizeof( sum ) );
-}
-
-/*
- * MD5 HMAC process buffer
- */
-void md5_hmac_update( md5_context *ctx, const unsigned char *input,
-                      size_t ilen )
-{
-    md5_update( ctx, input, ilen );
-}
-
-/*
- * MD5 HMAC final digest
- */
-void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
-{
-    unsigned char tmpbuf[16];
-
-    md5_finish( ctx, tmpbuf );
-    md5_starts( ctx );
-    md5_update( ctx, ctx->opad, 64 );
-    md5_update( ctx, tmpbuf, 16 );
-    md5_finish( ctx, output );
-
-    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
-}
-
-/*
- * MD5 HMAC context reset
- */
-void md5_hmac_reset( md5_context *ctx )
-{
-    md5_starts( ctx );
-    md5_update( ctx, ctx->ipad, 64 );
-}
-
-/*
- * output = HMAC-MD5( hmac key, input buffer )
- */
-void md5_hmac( const unsigned char *key, size_t keylen,
-               const unsigned char *input, size_t ilen,
-               unsigned char output[16] )
-{
-    md5_context ctx;
-
-    md5_init( &ctx );
-    md5_hmac_starts( &ctx, key, keylen );
-    md5_hmac_update( &ctx, input, ilen );
-    md5_hmac_finish( &ctx, output );
-    md5_free( &ctx );
-}
-
 #if defined(POLARSSL_SELF_TEST)
 /*
  * RFC 1321 test vectors
@@ -479,77 +398,12 @@
 };
 
 /*
- * RFC 2202 test vectors
- */
-static const unsigned char md5_hmac_test_key[7][26] =
-{
-    { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
-    { "Jefe" },
-    { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
-    { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
-      "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
-    { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
-    { "" }, /* 0xAA 80 times */
-    { "" }
-};
-
-static const int md5_hmac_test_keylen[7] =
-{
-    16, 4, 16, 25, 16, 80, 80
-};
-
-static const unsigned char md5_hmac_test_buf[7][74] =
-{
-    { "Hi There" },
-    { "what do ya want for nothing?" },
-    { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
-    { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
-    { "Test With Truncation" },
-    { "Test Using Larger Than Block-Size Key - Hash Key First" },
-    { "Test Using Larger Than Block-Size Key and Larger"
-      " Than One Block-Size Data" }
-};
-
-static const int md5_hmac_test_buflen[7] =
-{
-    8, 28, 50, 50, 20, 54, 73
-};
-
-static const unsigned char md5_hmac_test_sum[7][16] =
-{
-    { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
-      0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
-    { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
-      0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
-    { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
-      0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
-    { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
-      0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
-    { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
-      0xF9, 0xBA, 0xB9, 0x95 },
-    { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
-      0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
-    { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
-      0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
-};
-
-/*
  * Checkup routine
  */
 int md5_self_test( int verbose )
 {
-    int i, buflen;
-    unsigned char buf[1024];
+    int i;
     unsigned char md5sum[16];
-    md5_context ctx;
 
     for( i = 0; i < 7; i++ )
     {
@@ -573,42 +427,6 @@
     if( verbose != 0 )
         polarssl_printf( "\n" );
 
-    for( i = 0; i < 7; i++ )
-    {
-        if( verbose != 0 )
-            polarssl_printf( "  HMAC-MD5 test #%d: ", i + 1 );
-
-        if( i == 5 || i == 6 )
-        {
-            memset( buf, 0xAA, buflen = 80 );
-            md5_hmac_starts( &ctx, buf, buflen );
-        }
-        else
-            md5_hmac_starts( &ctx, md5_hmac_test_key[i],
-                                   md5_hmac_test_keylen[i] );
-
-        md5_hmac_update( &ctx, md5_hmac_test_buf[i],
-                               md5_hmac_test_buflen[i] );
-
-        md5_hmac_finish( &ctx, md5sum );
-
-        buflen = ( i == 4 ) ? 12 : 16;
-
-        if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
-        {
-            if( verbose != 0 )
-                polarssl_printf( "failed\n" );
-
-            return( 1 );
-        }
-
-        if( verbose != 0 )
-            polarssl_printf( "passed\n" );
-    }
-
-    if( verbose != 0 )
-        polarssl_printf( "\n" );
-
     return( 0 );
 }
 
diff --git a/library/md_wrap.c b/library/md_wrap.c
index fcc3102..17c6ab4 100644
--- a/library/md_wrap.c
+++ b/library/md_wrap.c
@@ -104,28 +104,6 @@
 #endif
 }
 
-static void md2_hmac_starts_wrap( void *ctx, const unsigned char *key,
-                                  size_t keylen )
-{
-    md2_hmac_starts( (md2_context *) ctx, key, keylen );
-}
-
-static void md2_hmac_update_wrap( void *ctx, const unsigned char *input,
-                                  size_t ilen )
-{
-    md2_hmac_update( (md2_context *) ctx, input, ilen );
-}
-
-static void md2_hmac_finish_wrap( void *ctx, unsigned char *output )
-{
-    md2_hmac_finish( (md2_context *) ctx, output );
-}
-
-static void md2_hmac_reset_wrap( void *ctx )
-{
-    md2_hmac_reset( (md2_context *) ctx );
-}
-
 static void * md2_ctx_alloc( void )
 {
     return polarssl_malloc( sizeof( md2_context ) );
@@ -148,16 +126,12 @@
     POLARSSL_MD_MD2,
     "MD2",
     16,
+    16,
     md2_starts_wrap,
     md2_update_wrap,
     md2_finish_wrap,
     md2,
     md2_file_wrap,
-    md2_hmac_starts_wrap,
-    md2_hmac_update_wrap,
-    md2_hmac_finish_wrap,
-    md2_hmac_reset_wrap,
-    md2_hmac,
     md2_ctx_alloc,
     md2_ctx_free,
     md2_process_wrap,
@@ -194,28 +168,6 @@
 #endif
 }
 
-static void md4_hmac_starts_wrap( void *ctx, const unsigned char *key,
-                                  size_t keylen )
-{
-    md4_hmac_starts( (md4_context *) ctx, key, keylen );
-}
-
-static void md4_hmac_update_wrap( void *ctx, const unsigned char *input,
-                                  size_t ilen )
-{
-    md4_hmac_update( (md4_context *) ctx, input, ilen );
-}
-
-static void md4_hmac_finish_wrap( void *ctx, unsigned char *output )
-{
-    md4_hmac_finish( (md4_context *) ctx, output );
-}
-
-static void md4_hmac_reset_wrap( void *ctx )
-{
-    md4_hmac_reset( (md4_context *) ctx );
-}
-
 static void *md4_ctx_alloc( void )
 {
     return polarssl_malloc( sizeof( md4_context ) );
@@ -236,16 +188,12 @@
     POLARSSL_MD_MD4,
     "MD4",
     16,
+    64,
     md4_starts_wrap,
     md4_update_wrap,
     md4_finish_wrap,
     md4,
     md4_file_wrap,
-    md4_hmac_starts_wrap,
-    md4_hmac_update_wrap,
-    md4_hmac_finish_wrap,
-    md4_hmac_reset_wrap,
-    md4_hmac,
     md4_ctx_alloc,
     md4_ctx_free,
     md4_process_wrap,
@@ -282,28 +230,6 @@
 #endif
 }
 
-static void md5_hmac_starts_wrap( void *ctx, const unsigned char *key,
-                                  size_t keylen )
-{
-    md5_hmac_starts( (md5_context *) ctx, key, keylen );
-}
-
-static void md5_hmac_update_wrap( void *ctx, const unsigned char *input,
-                                  size_t ilen )
-{
-    md5_hmac_update( (md5_context *) ctx, input, ilen );
-}
-
-static void md5_hmac_finish_wrap( void *ctx, unsigned char *output )
-{
-    md5_hmac_finish( (md5_context *) ctx, output );
-}
-
-static void md5_hmac_reset_wrap( void *ctx )
-{
-    md5_hmac_reset( (md5_context *) ctx );
-}
-
 static void * md5_ctx_alloc( void )
 {
     return polarssl_malloc( sizeof( md5_context ) );
@@ -324,16 +250,12 @@
     POLARSSL_MD_MD5,
     "MD5",
     16,
+    64,
     md5_starts_wrap,
     md5_update_wrap,
     md5_finish_wrap,
     md5,
     md5_file_wrap,
-    md5_hmac_starts_wrap,
-    md5_hmac_update_wrap,
-    md5_hmac_finish_wrap,
-    md5_hmac_reset_wrap,
-    md5_hmac,
     md5_ctx_alloc,
     md5_ctx_free,
     md5_process_wrap,
@@ -370,28 +292,6 @@
 #endif
 }
 
-static void ripemd160_hmac_starts_wrap( void *ctx, const unsigned char *key,
-                                        size_t keylen )
-{
-    ripemd160_hmac_starts( (ripemd160_context *) ctx, key, keylen );
-}
-
-static void ripemd160_hmac_update_wrap( void *ctx, const unsigned char *input,
-                                        size_t ilen )
-{
-    ripemd160_hmac_update( (ripemd160_context *) ctx, input, ilen );
-}
-
-static void ripemd160_hmac_finish_wrap( void *ctx, unsigned char *output )
-{
-    ripemd160_hmac_finish( (ripemd160_context *) ctx, output );
-}
-
-static void ripemd160_hmac_reset_wrap( void *ctx )
-{
-    ripemd160_hmac_reset( (ripemd160_context *) ctx );
-}
-
 static void * ripemd160_ctx_alloc( void )
 {
     ripemd160_context *ctx;
@@ -420,16 +320,12 @@
     POLARSSL_MD_RIPEMD160,
     "RIPEMD160",
     20,
+    64,
     ripemd160_starts_wrap,
     ripemd160_update_wrap,
     ripemd160_finish_wrap,
     ripemd160,
     ripemd160_file_wrap,
-    ripemd160_hmac_starts_wrap,
-    ripemd160_hmac_update_wrap,
-    ripemd160_hmac_finish_wrap,
-    ripemd160_hmac_reset_wrap,
-    ripemd160_hmac,
     ripemd160_ctx_alloc,
     ripemd160_ctx_free,
     ripemd160_process_wrap,
@@ -466,28 +362,6 @@
 #endif
 }
 
-static void sha1_hmac_starts_wrap( void *ctx, const unsigned char *key,
-                                   size_t keylen )
-{
-    sha1_hmac_starts( (sha1_context *) ctx, key, keylen );
-}
-
-static void sha1_hmac_update_wrap( void *ctx, const unsigned char *input,
-                                   size_t ilen )
-{
-    sha1_hmac_update( (sha1_context *) ctx, input, ilen );
-}
-
-static void sha1_hmac_finish_wrap( void *ctx, unsigned char *output )
-{
-    sha1_hmac_finish( (sha1_context *) ctx, output );
-}
-
-static void sha1_hmac_reset_wrap( void *ctx )
-{
-    sha1_hmac_reset( (sha1_context *) ctx );
-}
-
 static void * sha1_ctx_alloc( void )
 {
     sha1_context *ctx;
@@ -516,16 +390,12 @@
     POLARSSL_MD_SHA1,
     "SHA1",
     20,
+    64,
     sha1_starts_wrap,
     sha1_update_wrap,
     sha1_finish_wrap,
     sha1,
     sha1_file_wrap,
-    sha1_hmac_starts_wrap,
-    sha1_hmac_update_wrap,
-    sha1_hmac_finish_wrap,
-    sha1_hmac_reset_wrap,
-    sha1_hmac,
     sha1_ctx_alloc,
     sha1_ctx_free,
     sha1_process_wrap,
@@ -571,35 +441,6 @@
 #endif
 }
 
-static void sha224_hmac_starts_wrap( void *ctx, const unsigned char *key,
-                                     size_t keylen )
-{
-    sha256_hmac_starts( (sha256_context *) ctx, key, keylen, 1 );
-}
-
-static void sha224_hmac_update_wrap( void *ctx, const unsigned char *input,
-                                     size_t ilen )
-{
-    sha256_hmac_update( (sha256_context *) ctx, input, ilen );
-}
-
-static void sha224_hmac_finish_wrap( void *ctx, unsigned char *output )
-{
-    sha256_hmac_finish( (sha256_context *) ctx, output );
-}
-
-static void sha224_hmac_reset_wrap( void *ctx )
-{
-    sha256_hmac_reset( (sha256_context *) ctx );
-}
-
-static void sha224_hmac_wrap( const unsigned char *key, size_t keylen,
-        const unsigned char *input, size_t ilen,
-        unsigned char *output )
-{
-    sha256_hmac( key, keylen, input, ilen, output, 1 );
-}
-
 static void * sha224_ctx_alloc( void )
 {
     return polarssl_malloc( sizeof( sha256_context ) );
@@ -620,16 +461,12 @@
     POLARSSL_MD_SHA224,
     "SHA224",
     28,
+    64,
     sha224_starts_wrap,
     sha224_update_wrap,
     sha224_finish_wrap,
     sha224_wrap,
     sha224_file_wrap,
-    sha224_hmac_starts_wrap,
-    sha224_hmac_update_wrap,
-    sha224_hmac_finish_wrap,
-    sha224_hmac_reset_wrap,
-    sha224_hmac_wrap,
     sha224_ctx_alloc,
     sha224_ctx_free,
     sha224_process_wrap,
@@ -668,35 +505,6 @@
 #endif
 }
 
-static void sha256_hmac_starts_wrap( void *ctx, const unsigned char *key,
-                                     size_t keylen )
-{
-    sha256_hmac_starts( (sha256_context *) ctx, key, keylen, 0 );
-}
-
-static void sha256_hmac_update_wrap( void *ctx, const unsigned char *input,
-                                     size_t ilen )
-{
-    sha256_hmac_update( (sha256_context *) ctx, input, ilen );
-}
-
-static void sha256_hmac_finish_wrap( void *ctx, unsigned char *output )
-{
-    sha256_hmac_finish( (sha256_context *) ctx, output );
-}
-
-static void sha256_hmac_reset_wrap( void *ctx )
-{
-    sha256_hmac_reset( (sha256_context *) ctx );
-}
-
-static void sha256_hmac_wrap( const unsigned char *key, size_t keylen,
-        const unsigned char *input, size_t ilen,
-        unsigned char *output )
-{
-    sha256_hmac( key, keylen, input, ilen, output, 0 );
-}
-
 static void * sha256_ctx_alloc( void )
 {
     sha256_context *ctx;
@@ -725,16 +533,12 @@
     POLARSSL_MD_SHA256,
     "SHA256",
     32,
+    64,
     sha256_starts_wrap,
     sha256_update_wrap,
     sha256_finish_wrap,
     sha256_wrap,
     sha256_file_wrap,
-    sha256_hmac_starts_wrap,
-    sha256_hmac_update_wrap,
-    sha256_hmac_finish_wrap,
-    sha256_hmac_reset_wrap,
-    sha256_hmac_wrap,
     sha256_ctx_alloc,
     sha256_ctx_free,
     sha256_process_wrap,
@@ -777,35 +581,6 @@
 #endif
 }
 
-static void sha384_hmac_starts_wrap( void *ctx, const unsigned char *key,
-                                     size_t keylen )
-{
-    sha512_hmac_starts( (sha512_context *) ctx, key, keylen, 1 );
-}
-
-static void sha384_hmac_update_wrap( void *ctx, const unsigned char *input,
-                                     size_t ilen )
-{
-    sha512_hmac_update( (sha512_context *) ctx, input, ilen );
-}
-
-static void sha384_hmac_finish_wrap( void *ctx, unsigned char *output )
-{
-    sha512_hmac_finish( (sha512_context *) ctx, output );
-}
-
-static void sha384_hmac_reset_wrap( void *ctx )
-{
-    sha512_hmac_reset( (sha512_context *) ctx );
-}
-
-static void sha384_hmac_wrap( const unsigned char *key, size_t keylen,
-        const unsigned char *input, size_t ilen,
-        unsigned char *output )
-{
-    sha512_hmac( key, keylen, input, ilen, output, 1 );
-}
-
 static void * sha384_ctx_alloc( void )
 {
     return polarssl_malloc( sizeof( sha512_context ) );
@@ -826,16 +601,12 @@
     POLARSSL_MD_SHA384,
     "SHA384",
     48,
+    128,
     sha384_starts_wrap,
     sha384_update_wrap,
     sha384_finish_wrap,
     sha384_wrap,
     sha384_file_wrap,
-    sha384_hmac_starts_wrap,
-    sha384_hmac_update_wrap,
-    sha384_hmac_finish_wrap,
-    sha384_hmac_reset_wrap,
-    sha384_hmac_wrap,
     sha384_ctx_alloc,
     sha384_ctx_free,
     sha384_process_wrap,
@@ -874,35 +645,6 @@
 #endif
 }
 
-static void sha512_hmac_starts_wrap( void *ctx, const unsigned char *key,
-                                     size_t keylen )
-{
-    sha512_hmac_starts( (sha512_context *) ctx, key, keylen, 0 );
-}
-
-static void sha512_hmac_update_wrap( void *ctx, const unsigned char *input,
-                                     size_t ilen )
-{
-    sha512_hmac_update( (sha512_context *) ctx, input, ilen );
-}
-
-static void sha512_hmac_finish_wrap( void *ctx, unsigned char *output )
-{
-    sha512_hmac_finish( (sha512_context *) ctx, output );
-}
-
-static void sha512_hmac_reset_wrap( void *ctx )
-{
-    sha512_hmac_reset( (sha512_context *) ctx );
-}
-
-static void sha512_hmac_wrap( const unsigned char *key, size_t keylen,
-        const unsigned char *input, size_t ilen,
-        unsigned char *output )
-{
-    sha512_hmac( key, keylen, input, ilen, output, 0 );
-}
-
 static void * sha512_ctx_alloc( void )
 {
     sha512_context *ctx;
@@ -931,16 +673,12 @@
     POLARSSL_MD_SHA512,
     "SHA512",
     64,
+    128,
     sha512_starts_wrap,
     sha512_update_wrap,
     sha512_finish_wrap,
     sha512_wrap,
     sha512_file_wrap,
-    sha512_hmac_starts_wrap,
-    sha512_hmac_update_wrap,
-    sha512_hmac_finish_wrap,
-    sha512_hmac_reset_wrap,
-    sha512_hmac_wrap,
     sha512_ctx_alloc,
     sha512_ctx_free,
     sha512_process_wrap,
diff --git a/library/pk.c b/library/pk.c
index af4a302..f083b86 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -166,7 +166,7 @@
     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/pkcs12.c b/library/pkcs12.c
index 66b29c1..0a25edd 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -268,7 +268,7 @@
 
     md_init( &md_ctx );
 
-    if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 )
+    if( ( ret = md_setup( &md_ctx, md_info, 0 ) ) != 0 )
         return( ret );
     hlen = md_get_size( md_info );
 
diff --git a/library/pkcs5.c b/library/pkcs5.c
index 280453a..9cce1a5 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -189,7 +189,7 @@
 
     memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
 
-    if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 )
+    if( ( ret = md_setup( &md_ctx, md_info, 1 ) ) != 0 )
         goto exit;
 
     if( ( ret = pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
@@ -365,7 +365,7 @@
         goto exit;
     }
 
-    if( ( ret = md_init_ctx( &sha1_ctx, info_sha1 ) ) != 0 )
+    if( ( ret = md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 )
     {
         ret = 1;
         goto exit;
diff --git a/library/ripemd160.c b/library/ripemd160.c
index 0ca354c..97ab530 100644
--- a/library/ripemd160.c
+++ b/library/ripemd160.c
@@ -416,88 +416,6 @@
 }
 #endif /* POLARSSL_FS_IO */
 
-/*
- * RIPEMD-160 HMAC context setup
- */
-void ripemd160_hmac_starts( ripemd160_context *ctx,
-                            const unsigned char *key, size_t keylen )
-{
-    size_t i;
-    unsigned char sum[20];
-
-    if( keylen > 64 )
-    {
-        ripemd160( key, keylen, sum );
-        keylen = 20;
-        key = sum;
-    }
-
-    memset( ctx->ipad, 0x36, 64 );
-    memset( ctx->opad, 0x5C, 64 );
-
-    for( i = 0; i < keylen; i++ )
-    {
-        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
-        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
-    }
-
-    ripemd160_starts( ctx );
-    ripemd160_update( ctx, ctx->ipad, 64 );
-
-    polarssl_zeroize( sum, sizeof( sum ) );
-}
-
-/*
- * RIPEMD-160 HMAC process buffer
- */
-void ripemd160_hmac_update( ripemd160_context *ctx,
-                            const unsigned char *input, size_t ilen )
-{
-    ripemd160_update( ctx, input, ilen );
-}
-
-/*
- * RIPEMD-160 HMAC final digest
- */
-void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] )
-{
-    unsigned char tmpbuf[20];
-
-    ripemd160_finish( ctx, tmpbuf );
-    ripemd160_starts( ctx );
-    ripemd160_update( ctx, ctx->opad, 64 );
-    ripemd160_update( ctx, tmpbuf, 20 );
-    ripemd160_finish( ctx, output );
-
-    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
-}
-
-/*
- * RIPEMD-160 HMAC context reset
- */
-void ripemd160_hmac_reset( ripemd160_context *ctx )
-{
-    ripemd160_starts( ctx );
-    ripemd160_update( ctx, ctx->ipad, 64 );
-}
-
-/*
- * output = HMAC-RIPEMD-160( hmac key, input buffer )
- */
-void ripemd160_hmac( const unsigned char *key, size_t keylen,
-                     const unsigned char *input, size_t ilen,
-                     unsigned char output[20] )
-{
-    ripemd160_context ctx;
-
-    ripemd160_init( &ctx );
-    ripemd160_hmac_starts( &ctx, key, keylen );
-    ripemd160_hmac_update( &ctx, input, ilen );
-    ripemd160_hmac_finish( &ctx, output );
-    ripemd160_free( &ctx );
-}
-
-
 #if defined(POLARSSL_SELF_TEST)
 /*
  * Test vectors from the RIPEMD-160 paper and
@@ -538,60 +456,12 @@
       0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
 };
 
-static const unsigned char ripemd160_test_hmac[KEYS][TESTS][20] =
-{
-  {
-    { 0xcf, 0x38, 0x76, 0x77, 0xbf, 0xda, 0x84, 0x83, 0xe6, 0x3b,
-      0x57, 0xe0, 0x6c, 0x3b, 0x5e, 0xcd, 0x8b, 0x7f, 0xc0, 0x55 },
-    { 0x0d, 0x35, 0x1d, 0x71, 0xb7, 0x8e, 0x36, 0xdb, 0xb7, 0x39,
-      0x1c, 0x81, 0x0a, 0x0d, 0x2b, 0x62, 0x40, 0xdd, 0xba, 0xfc },
-    { 0xf7, 0xef, 0x28, 0x8c, 0xb1, 0xbb, 0xcc, 0x61, 0x60, 0xd7,
-      0x65, 0x07, 0xe0, 0xa3, 0xbb, 0xf7, 0x12, 0xfb, 0x67, 0xd6 },
-    { 0xf8, 0x36, 0x62, 0xcc, 0x8d, 0x33, 0x9c, 0x22, 0x7e, 0x60,
-      0x0f, 0xcd, 0x63, 0x6c, 0x57, 0xd2, 0x57, 0x1b, 0x1c, 0x34 },
-    { 0x84, 0x3d, 0x1c, 0x4e, 0xb8, 0x80, 0xac, 0x8a, 0xc0, 0xc9,
-      0xc9, 0x56, 0x96, 0x50, 0x79, 0x57, 0xd0, 0x15, 0x5d, 0xdb },
-    { 0x60, 0xf5, 0xef, 0x19, 0x8a, 0x2d, 0xd5, 0x74, 0x55, 0x45,
-      0xc1, 0xf0, 0xc4, 0x7a, 0xa3, 0xfb, 0x57, 0x76, 0xf8, 0x81 },
-    { 0xe4, 0x9c, 0x13, 0x6a, 0x9e, 0x56, 0x27, 0xe0, 0x68, 0x1b,
-      0x80, 0x8a, 0x3b, 0x97, 0xe6, 0xa6, 0xe6, 0x61, 0xae, 0x79 },
-    { 0x31, 0xbe, 0x3c, 0xc9, 0x8c, 0xee, 0x37, 0xb7, 0x9b, 0x06,
-      0x19, 0xe3, 0xe1, 0xc2, 0xbe, 0x4f, 0x1a, 0xa5, 0x6e, 0x6c },
-  },
-  {
-    { 0xfe, 0x69, 0xa6, 0x6c, 0x74, 0x23, 0xee, 0xa9, 0xc8, 0xfa,
-      0x2e, 0xff, 0x8d, 0x9d, 0xaf, 0xb4, 0xf1, 0x7a, 0x62, 0xf5 },
-    { 0x85, 0x74, 0x3e, 0x89, 0x9b, 0xc8, 0x2d, 0xbf, 0xa3, 0x6f,
-      0xaa, 0xa7, 0xa2, 0x5b, 0x7c, 0xfd, 0x37, 0x24, 0x32, 0xcd },
-    { 0x6e, 0x4a, 0xfd, 0x50, 0x1f, 0xa6, 0xb4, 0xa1, 0x82, 0x3c,
-      0xa3, 0xb1, 0x0b, 0xd9, 0xaa, 0x0b, 0xa9, 0x7b, 0xa1, 0x82 },
-    { 0x2e, 0x06, 0x6e, 0x62, 0x4b, 0xad, 0xb7, 0x6a, 0x18, 0x4c,
-      0x8f, 0x90, 0xfb, 0xa0, 0x53, 0x33, 0x0e, 0x65, 0x0e, 0x92 },
-    { 0x07, 0xe9, 0x42, 0xaa, 0x4e, 0x3c, 0xd7, 0xc0, 0x4d, 0xed,
-      0xc1, 0xd4, 0x6e, 0x2e, 0x8c, 0xc4, 0xc7, 0x41, 0xb3, 0xd9 },
-    { 0xb6, 0x58, 0x23, 0x18, 0xdd, 0xcf, 0xb6, 0x7a, 0x53, 0xa6,
-      0x7d, 0x67, 0x6b, 0x8a, 0xd8, 0x69, 0xad, 0xed, 0x62, 0x9a },
-    { 0xf1, 0xbe, 0x3e, 0xe8, 0x77, 0x70, 0x31, 0x40, 0xd3, 0x4f,
-      0x97, 0xea, 0x1a, 0xb3, 0xa0, 0x7c, 0x14, 0x13, 0x33, 0xe2 },
-    { 0x85, 0xf1, 0x64, 0x70, 0x3e, 0x61, 0xa6, 0x31, 0x31, 0xbe,
-      0x7e, 0x45, 0x95, 0x8e, 0x07, 0x94, 0x12, 0x39, 0x04, 0xf9 },
-  },
-};
-
-static const unsigned char ripemd160_test_key[KEYS][20] =
-{
-    { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
-      0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x23, 0x45, 0x67 },
-    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc,
-      0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33 },
-};
-
 /*
  * Checkup routine
  */
 int ripemd160_self_test( int verbose )
 {
-    int i, j;
+    int i;
     unsigned char output[20];
 
     memset( output, 0, sizeof output );
@@ -615,32 +485,6 @@
 
         if( verbose != 0 )
             polarssl_printf( "passed\n" );
-
-        for( j = 0; j < KEYS; j++ )
-        {
-            if( verbose != 0 )
-                polarssl_printf( "  HMAC-RIPEMD-160 test #%d, key #%d: ",
-                                 i + 1, j + 1 );
-
-            ripemd160_hmac( ripemd160_test_key[j], 20,
-                            (const unsigned char *) ripemd160_test_input[i],
-                            strlen( ripemd160_test_input[i] ),
-                            output );
-
-            if( memcmp( output, ripemd160_test_hmac[j][i], 20 ) != 0 )
-            {
-                if( verbose != 0 )
-                    polarssl_printf( "failed\n" );
-
-                return( 1 );
-            }
-
-            if( verbose != 0 )
-                polarssl_printf( "passed\n" );
-        }
-
-        if( verbose != 0 )
-            polarssl_printf( "\n" );
     }
 
     return( 0 );
diff --git a/library/rsa.c b/library/rsa.c
index e915e4f..72f65a2 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -473,7 +473,7 @@
     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
     //
@@ -556,7 +556,7 @@
     memcpy( p, input, ilen );
 
     md_init( &md_ctx );
-    md_init_ctx( &md_ctx, md_info );
+    md_setup( &md_ctx, md_info, 0 );
 
     // maskedDB: Apply dbMask to DB
     //
@@ -725,7 +725,7 @@
     hlen = md_get_size( md_info );
 
     md_init( &md_ctx );
-    md_init_ctx( &md_ctx, md_info );
+    md_setup( &md_ctx, md_info, 0 );
 
     /* Generate lHash */
     md( md_info, label, label_len, lhash );
@@ -969,7 +969,7 @@
     p += slen;
 
     md_init( &md_ctx );
-    md_init_ctx( &md_ctx, md_info );
+    md_setup( &md_ctx, md_info, 0 );
 
     // Generate H = Hash( M' )
     //
@@ -1201,7 +1201,7 @@
         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
 
     md_init( &md_ctx );
-    md_init_ctx( &md_ctx, md_info );
+    md_setup( &md_ctx, md_info, 0 );
 
     mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
 
diff --git a/library/sha1.c b/library/sha1.c
index db9f2c1..086fd7f 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -391,87 +391,6 @@
 }
 #endif /* POLARSSL_FS_IO */
 
-/*
- * SHA-1 HMAC context setup
- */
-void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key,
-                       size_t keylen )
-{
-    size_t i;
-    unsigned char sum[20];
-
-    if( keylen > 64 )
-    {
-        sha1( key, keylen, sum );
-        keylen = 20;
-        key = sum;
-    }
-
-    memset( ctx->ipad, 0x36, 64 );
-    memset( ctx->opad, 0x5C, 64 );
-
-    for( i = 0; i < keylen; i++ )
-    {
-        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
-        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
-    }
-
-    sha1_starts( ctx );
-    sha1_update( ctx, ctx->ipad, 64 );
-
-    polarssl_zeroize( sum, sizeof( sum ) );
-}
-
-/*
- * SHA-1 HMAC process buffer
- */
-void sha1_hmac_update( sha1_context *ctx, const unsigned char *input,
-                       size_t ilen )
-{
-    sha1_update( ctx, input, ilen );
-}
-
-/*
- * SHA-1 HMAC final digest
- */
-void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
-{
-    unsigned char tmpbuf[20];
-
-    sha1_finish( ctx, tmpbuf );
-    sha1_starts( ctx );
-    sha1_update( ctx, ctx->opad, 64 );
-    sha1_update( ctx, tmpbuf, 20 );
-    sha1_finish( ctx, output );
-
-    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
-}
-
-/*
- * SHA1 HMAC context reset
- */
-void sha1_hmac_reset( sha1_context *ctx )
-{
-    sha1_starts( ctx );
-    sha1_update( ctx, ctx->ipad, 64 );
-}
-
-/*
- * output = HMAC-SHA-1( hmac key, input buffer )
- */
-void sha1_hmac( const unsigned char *key, size_t keylen,
-                const unsigned char *input, size_t ilen,
-                unsigned char output[20] )
-{
-    sha1_context ctx;
-
-    sha1_init( &ctx );
-    sha1_hmac_starts( &ctx, key, keylen );
-    sha1_hmac_update( &ctx, input, ilen );
-    sha1_hmac_finish( &ctx, output );
-    sha1_free( &ctx );
-}
-
 #if defined(POLARSSL_SELF_TEST)
 /*
  * FIPS-180-1 test vectors
@@ -499,72 +418,6 @@
 };
 
 /*
- * RFC 2202 test vectors
- */
-static const unsigned char sha1_hmac_test_key[7][26] =
-{
-    { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
-      "\x0B\x0B\x0B\x0B" },
-    { "Jefe" },
-    { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
-      "\xAA\xAA\xAA\xAA" },
-    { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
-      "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
-    { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
-      "\x0C\x0C\x0C\x0C" },
-    { "" }, /* 0xAA 80 times */
-    { "" }
-};
-
-static const int sha1_hmac_test_keylen[7] =
-{
-    20, 4, 20, 25, 20, 80, 80
-};
-
-static const unsigned char sha1_hmac_test_buf[7][74] =
-{
-    { "Hi There" },
-    { "what do ya want for nothing?" },
-    { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
-    { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
-    { "Test With Truncation" },
-    { "Test Using Larger Than Block-Size Key - Hash Key First" },
-    { "Test Using Larger Than Block-Size Key and Larger"
-      " Than One Block-Size Data" }
-};
-
-static const int sha1_hmac_test_buflen[7] =
-{
-    8, 28, 50, 50, 20, 54, 73
-};
-
-static const unsigned char sha1_hmac_test_sum[7][20] =
-{
-    { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
-      0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
-    { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
-      0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
-    { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
-      0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
-    { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
-      0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
-    { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
-      0x7B, 0xE1 },
-    { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
-      0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
-    { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
-      0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
-};
-
-/*
  * Checkup routine
  */
 int sha1_self_test( int verbose )
@@ -615,43 +468,6 @@
     if( verbose != 0 )
         polarssl_printf( "\n" );
 
-    for( i = 0; i < 7; i++ )
-    {
-        if( verbose != 0 )
-            polarssl_printf( "  HMAC-SHA-1 test #%d: ", i + 1 );
-
-        if( i == 5 || i == 6 )
-        {
-            memset( buf, 0xAA, buflen = 80 );
-            sha1_hmac_starts( &ctx, buf, buflen );
-        }
-        else
-            sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
-                                    sha1_hmac_test_keylen[i] );
-
-        sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
-                                sha1_hmac_test_buflen[i] );
-
-        sha1_hmac_finish( &ctx, sha1sum );
-
-        buflen = ( i == 4 ) ? 12 : 20;
-
-        if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
-        {
-            if( verbose != 0 )
-                polarssl_printf( "failed\n" );
-
-            ret = 1;
-            goto exit;
-        }
-
-        if( verbose != 0 )
-            polarssl_printf( "passed\n" );
-    }
-
-    if( verbose != 0 )
-        polarssl_printf( "\n" );
-
 exit:
     sha1_free( &ctx );
 
diff --git a/library/sha256.c b/library/sha256.c
index 3f7add6..7d4c32c 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -394,91 +394,6 @@
 }
 #endif /* POLARSSL_FS_IO */
 
-/*
- * SHA-256 HMAC context setup
- */
-void sha256_hmac_starts( sha256_context *ctx, const unsigned char *key,
-                         size_t keylen, int is224 )
-{
-    size_t i;
-    unsigned char sum[32];
-
-    if( keylen > 64 )
-    {
-        sha256( key, keylen, sum, is224 );
-        keylen = ( is224 ) ? 28 : 32;
-        key = sum;
-    }
-
-    memset( ctx->ipad, 0x36, 64 );
-    memset( ctx->opad, 0x5C, 64 );
-
-    for( i = 0; i < keylen; i++ )
-    {
-        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
-        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
-    }
-
-    sha256_starts( ctx, is224 );
-    sha256_update( ctx, ctx->ipad, 64 );
-
-    polarssl_zeroize( sum, sizeof( sum ) );
-}
-
-/*
- * SHA-256 HMAC process buffer
- */
-void sha256_hmac_update( sha256_context *ctx, const unsigned char *input,
-                         size_t ilen )
-{
-    sha256_update( ctx, input, ilen );
-}
-
-/*
- * SHA-256 HMAC final digest
- */
-void sha256_hmac_finish( sha256_context *ctx, unsigned char output[32] )
-{
-    int is224, hlen;
-    unsigned char tmpbuf[32];
-
-    is224 = ctx->is224;
-    hlen = ( is224 == 0 ) ? 32 : 28;
-
-    sha256_finish( ctx, tmpbuf );
-    sha256_starts( ctx, is224 );
-    sha256_update( ctx, ctx->opad, 64 );
-    sha256_update( ctx, tmpbuf, hlen );
-    sha256_finish( ctx, output );
-
-    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
-}
-
-/*
- * SHA-256 HMAC context reset
- */
-void sha256_hmac_reset( sha256_context *ctx )
-{
-    sha256_starts( ctx, ctx->is224 );
-    sha256_update( ctx, ctx->ipad, 64 );
-}
-
-/*
- * output = HMAC-SHA-256( hmac key, input buffer )
- */
-void sha256_hmac( const unsigned char *key, size_t keylen,
-                  const unsigned char *input, size_t ilen,
-                  unsigned char output[32], int is224 )
-{
-    sha256_context ctx;
-
-    sha256_init( &ctx );
-    sha256_hmac_starts( &ctx, key, keylen, is224 );
-    sha256_hmac_update( &ctx, input, ilen );
-    sha256_hmac_finish( &ctx, output );
-    sha256_free( &ctx );
-}
-
 #if defined(POLARSSL_SELF_TEST)
 /*
  * FIPS-180-2 test vectors
@@ -531,118 +446,6 @@
 };
 
 /*
- * RFC 4231 test vectors
- */
-static const unsigned char sha256_hmac_test_key[7][26] =
-{
-    { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
-      "\x0B\x0B\x0B\x0B" },
-    { "Jefe" },
-    { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
-      "\xAA\xAA\xAA\xAA" },
-    { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
-      "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
-    { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
-      "\x0C\x0C\x0C\x0C" },
-    { "" }, /* 0xAA 131 times */
-    { "" }
-};
-
-static const int sha256_hmac_test_keylen[7] =
-{
-    20, 4, 20, 25, 20, 131, 131
-};
-
-static const unsigned char sha256_hmac_test_buf[7][153] =
-{
-    { "Hi There" },
-    { "what do ya want for nothing?" },
-    { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
-    { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
-    { "Test With Truncation" },
-    { "Test Using Larger Than Block-Size Key - Hash Key First" },
-    { "This is a test using a larger than block-size key "
-      "and a larger than block-size data. The key needs to "
-      "be hashed before being used by the HMAC algorithm." }
-};
-
-static const int sha256_hmac_test_buflen[7] =
-{
-    8, 28, 50, 50, 20, 54, 152
-};
-
-static const unsigned char sha256_hmac_test_sum[14][32] =
-{
-    /*
-     * HMAC-SHA-224 test vectors
-     */
-    { 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19,
-      0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F,
-      0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F,
-      0x53, 0x68, 0x4B, 0x22 },
-    { 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF,
-      0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F,
-      0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00,
-      0x8F, 0xD0, 0x5E, 0x44 },
-    { 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6,
-      0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64,
-      0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1,
-      0xEC, 0x83, 0x33, 0xEA },
-    { 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC,
-      0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C,
-      0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D,
-      0xE7, 0xAF, 0xEC, 0x5A },
-    { 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37,
-      0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 },
-    { 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD,
-      0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2,
-      0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27,
-      0x3F, 0xA6, 0x87, 0x0E },
-    { 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02,
-      0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD,
-      0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9,
-      0xF6, 0xF5, 0x65, 0xD1 },
-
-    /*
-     * HMAC-SHA-256 test vectors
-     */
-    { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
-      0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
-      0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
-      0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 },
-    { 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E,
-      0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7,
-      0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83,
-      0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 },
-    { 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46,
-      0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7,
-      0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22,
-      0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE },
-    { 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E,
-      0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A,
-      0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07,
-      0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B },
-    { 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0,
-      0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B },
-    { 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F,
-      0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F,
-      0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14,
-      0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 },
-    { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
-      0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
-      0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
-      0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }
-};
-
-/*
  * Checkup routine
  */
 int sha256_self_test( int verbose )
@@ -693,46 +496,6 @@
     if( verbose != 0 )
         polarssl_printf( "\n" );
 
-    for( i = 0; i < 14; i++ )
-    {
-        j = i % 7;
-        k = i < 7;
-
-        if( verbose != 0 )
-            polarssl_printf( "  HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 );
-
-        if( j == 5 || j == 6 )
-        {
-            memset( buf, 0xAA, buflen = 131 );
-            sha256_hmac_starts( &ctx, buf, buflen, k );
-        }
-        else
-            sha256_hmac_starts( &ctx, sha256_hmac_test_key[j],
-                                      sha256_hmac_test_keylen[j], k );
-
-        sha256_hmac_update( &ctx, sha256_hmac_test_buf[j],
-                                  sha256_hmac_test_buflen[j] );
-
-        sha256_hmac_finish( &ctx, sha256sum );
-
-        buflen = ( j == 4 ) ? 16 : 32 - k * 4;
-
-        if( memcmp( sha256sum, sha256_hmac_test_sum[i], buflen ) != 0 )
-        {
-            if( verbose != 0 )
-                polarssl_printf( "failed\n" );
-
-            ret = 1;
-            goto exit;
-        }
-
-        if( verbose != 0 )
-            polarssl_printf( "passed\n" );
-    }
-
-    if( verbose != 0 )
-        polarssl_printf( "\n" );
-
 exit:
     sha256_free( &ctx );
 
diff --git a/library/sha512.c b/library/sha512.c
index 560a83d..86e28a9 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -398,91 +398,6 @@
 }
 #endif /* POLARSSL_FS_IO */
 
-/*
- * SHA-512 HMAC context setup
- */
-void sha512_hmac_starts( sha512_context *ctx, const unsigned char *key,
-                         size_t keylen, int is384 )
-{
-    size_t i;
-    unsigned char sum[64];
-
-    if( keylen > 128 )
-    {
-        sha512( key, keylen, sum, is384 );
-        keylen = ( is384 ) ? 48 : 64;
-        key = sum;
-    }
-
-    memset( ctx->ipad, 0x36, 128 );
-    memset( ctx->opad, 0x5C, 128 );
-
-    for( i = 0; i < keylen; i++ )
-    {
-        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
-        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
-    }
-
-    sha512_starts( ctx, is384 );
-    sha512_update( ctx, ctx->ipad, 128 );
-
-    polarssl_zeroize( sum, sizeof( sum ) );
-}
-
-/*
- * SHA-512 HMAC process buffer
- */
-void sha512_hmac_update( sha512_context  *ctx,
-                         const unsigned char *input, size_t ilen )
-{
-    sha512_update( ctx, input, ilen );
-}
-
-/*
- * SHA-512 HMAC final digest
- */
-void sha512_hmac_finish( sha512_context *ctx, unsigned char output[64] )
-{
-    int is384, hlen;
-    unsigned char tmpbuf[64];
-
-    is384 = ctx->is384;
-    hlen = ( is384 == 0 ) ? 64 : 48;
-
-    sha512_finish( ctx, tmpbuf );
-    sha512_starts( ctx, is384 );
-    sha512_update( ctx, ctx->opad, 128 );
-    sha512_update( ctx, tmpbuf, hlen );
-    sha512_finish( ctx, output );
-
-    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
-}
-
-/*
- * SHA-512 HMAC context reset
- */
-void sha512_hmac_reset( sha512_context *ctx )
-{
-    sha512_starts( ctx, ctx->is384 );
-    sha512_update( ctx, ctx->ipad, 128 );
-}
-
-/*
- * output = HMAC-SHA-512( hmac key, input buffer )
- */
-void sha512_hmac( const unsigned char *key, size_t keylen,
-                const unsigned char *input, size_t ilen,
-                unsigned char output[64], int is384 )
-{
-    sha512_context ctx;
-
-    sha512_init( &ctx );
-    sha512_hmac_starts( &ctx, key, keylen, is384 );
-    sha512_hmac_update( &ctx, input, ilen );
-    sha512_hmac_finish( &ctx, output );
-    sha512_free( &ctx );
-}
-
 #if defined(POLARSSL_SELF_TEST)
 
 /*
@@ -555,154 +470,6 @@
 };
 
 /*
- * RFC 4231 test vectors
- */
-static const unsigned char sha512_hmac_test_key[7][26] =
-{
-    { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
-      "\x0B\x0B\x0B\x0B" },
-    { "Jefe" },
-    { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
-      "\xAA\xAA\xAA\xAA" },
-    { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
-      "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
-    { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
-      "\x0C\x0C\x0C\x0C" },
-    { "" }, /* 0xAA 131 times */
-    { "" }
-};
-
-static const int sha512_hmac_test_keylen[7] =
-{
-    20, 4, 20, 25, 20, 131, 131
-};
-
-static const unsigned char sha512_hmac_test_buf[7][153] =
-{
-    { "Hi There" },
-    { "what do ya want for nothing?" },
-    { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
-      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
-    { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
-      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
-    { "Test With Truncation" },
-    { "Test Using Larger Than Block-Size Key - Hash Key First" },
-    { "This is a test using a larger than block-size key "
-      "and a larger than block-size data. The key needs to "
-      "be hashed before being used by the HMAC algorithm." }
-};
-
-static const int sha512_hmac_test_buflen[7] =
-{
-    8, 28, 50, 50, 20, 54, 152
-};
-
-static const unsigned char sha512_hmac_test_sum[14][64] =
-{
-    /*
-     * HMAC-SHA-384 test vectors
-     */
-    { 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62,
-      0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F,
-      0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6,
-      0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C,
-      0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F,
-      0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 },
-    { 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31,
-      0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B,
-      0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47,
-      0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E,
-      0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7,
-      0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 },
-    { 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A,
-      0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F,
-      0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB,
-      0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B,
-      0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9,
-      0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 },
-    { 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85,
-      0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7,
-      0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C,
-      0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E,
-      0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79,
-      0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB },
-    { 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23,
-      0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 },
-    { 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90,
-      0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4,
-      0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F,
-      0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6,
-      0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82,
-      0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 },
-    { 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D,
-      0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C,
-      0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A,
-      0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5,
-      0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D,
-      0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E },
-
-    /*
-     * HMAC-SHA-512 test vectors
-     */
-    { 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D,
-      0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0,
-      0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78,
-      0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE,
-      0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02,
-      0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4,
-      0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70,
-      0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 },
-    { 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2,
-      0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3,
-      0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6,
-      0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54,
-      0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A,
-      0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD,
-      0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B,
-      0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 },
-    { 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84,
-      0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9,
-      0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36,
-      0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39,
-      0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8,
-      0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07,
-      0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26,
-      0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB },
-    { 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69,
-      0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7,
-      0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D,
-      0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB,
-      0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4,
-      0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63,
-      0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D,
-      0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD },
-    { 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53,
-      0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 },
-    { 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB,
-      0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4,
-      0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1,
-      0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52,
-      0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98,
-      0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52,
-      0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC,
-      0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 },
-    { 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA,
-      0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD,
-      0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86,
-      0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44,
-      0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1,
-      0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15,
-      0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60,
-      0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 }
-};
-
-/*
  * Checkup routine
  */
 int sha512_self_test( int verbose )
@@ -753,46 +520,6 @@
     if( verbose != 0 )
         polarssl_printf( "\n" );
 
-    for( i = 0; i < 14; i++ )
-    {
-        j = i % 7;
-        k = i < 7;
-
-        if( verbose != 0 )
-            polarssl_printf( "  HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 );
-
-        if( j == 5 || j == 6 )
-        {
-            memset( buf, 0xAA, buflen = 131 );
-            sha512_hmac_starts( &ctx, buf, buflen, k );
-        }
-        else
-            sha512_hmac_starts( &ctx, sha512_hmac_test_key[j],
-                                      sha512_hmac_test_keylen[j], k );
-
-        sha512_hmac_update( &ctx, sha512_hmac_test_buf[j],
-                                  sha512_hmac_test_buflen[j] );
-
-        sha512_hmac_finish( &ctx, sha512sum );
-
-        buflen = ( j == 4 ) ? 16 : 64 - k * 16;
-
-        if( memcmp( sha512sum, sha512_hmac_test_sum[i], buflen ) != 0 )
-        {
-            if( verbose != 0 )
-                polarssl_printf( "failed\n" );
-
-            ret = 1;
-            goto exit;
-        }
-
-        if( verbose != 0 )
-            polarssl_printf( "passed\n" );
-    }
-
-    if( verbose != 0 )
-        polarssl_printf( "\n" );
-
 exit:
     sha512_free( &ctx );
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 2b94af8..beb8536 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -2172,10 +2172,10 @@
              *     ServerDHParams params;
              * };
              */
-            if( ( ret = md_init_ctx( &ctx,
-                                     md_info_from_type( md_alg ) ) ) != 0 )
+            if( ( ret = md_setup( &ctx,
+                                     md_info_from_type( md_alg ), 0 ) ) != 0 )
             {
-                SSL_DEBUG_RET( 1, "md_init_ctx", ret );
+                SSL_DEBUG_RET( 1, "md_setup", ret );
                 return( ret );
             }
 
@@ -2194,7 +2194,7 @@
         }
 
         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_cookie.c b/library/ssl_cookie.c
index c2fde82..2958c5c 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -104,7 +104,7 @@
     if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 )
         return( ret );
 
-    ret = md_init_ctx( &ctx->hmac_ctx, md_info_from_type( COOKIE_MD ) );
+    ret = md_setup( &ctx->hmac_ctx, md_info_from_type( COOKIE_MD ), 1 );
     if( ret != 0 )
         return( ret );
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index ff2c44b..1b2d4db 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -236,7 +236,12 @@
     p = state + enc_len;
 
     /* Compute and write MAC( key_name + iv + enc_state_len + enc_state ) */
-    sha256_hmac( ssl->ticket_keys->mac_key, 16, start, p - start, p, 0 );
+    if( ( ret = md_hmac( md_info_from_type( POLARSSL_MD_SHA256 ),
+                         ssl->ticket_keys->mac_key, 16,
+                         start, p - start, p ) ) != 0 )
+    {
+        return( ret );
+    }
     p += 32;
 
     *tlen = p - start;
@@ -282,8 +287,12 @@
     /* don't return yet, check the MAC anyway */
 
     /* Check mac, with constant-time buffer comparison */
-    sha256_hmac( ssl->ticket_keys->mac_key, 16, buf, len - 32,
-                 computed_mac, 0 );
+    if( ( ret = md_hmac( md_info_from_type( POLARSSL_MD_SHA256 ),
+                         ssl->ticket_keys->mac_key, 16,
+                         buf, len - 32, computed_mac ) ) != 0 )
+    {
+        return( ret );
+    }
 
     for( i = 0; i < 32; i++ )
         diff |= mac[i] ^ computed_mac[i];
@@ -3064,9 +3073,9 @@
              *     ServerDHParams params;
              * };
              */
-            if( ( ret = md_init_ctx( &ctx, md_info ) ) != 0 )
+            if( ( ret = md_setup( &ctx, md_info, 0 ) ) != 0 )
             {
-                SSL_DEBUG_RET( 1, "md_init_ctx", ret );
+                SSL_DEBUG_RET( 1, "md_setup", ret );
                 return( ret );
             }
 
@@ -3085,7 +3094,7 @@
         }
 
         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/ssl_tls.c b/library/ssl_tls.c
index bdc9c53..25f3a02 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -276,6 +276,11 @@
     const unsigned char *S1, *S2;
     unsigned char tmp[128];
     unsigned char h_i[20];
+    const md_info_t *md_info;
+    md_context_t md_ctx;
+    int ret;
+
+    md_init( &md_ctx );
 
     if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
         return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
@@ -292,12 +297,25 @@
     /*
      * First compute P_md5(secret,label+random)[0..dlen]
      */
-    md5_hmac( S1, hs, tmp + 20, nb, 4 + tmp );
+    if( ( md_info = md_info_from_type( POLARSSL_MD_MD5 ) ) == NULL )
+        return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
+
+    if( ( ret = md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+        return( ret );
+
+    md_hmac_starts( &md_ctx, S1, hs );
+    md_hmac_update( &md_ctx, tmp + 20, nb );
+    md_hmac_finish( &md_ctx, 4 + tmp );
 
     for( i = 0; i < dlen; i += 16 )
     {
-        md5_hmac( S1, hs, 4 + tmp, 16 + nb, h_i );
-        md5_hmac( S1, hs, 4 + tmp, 16,  4 + tmp );
+        md_hmac_reset ( &md_ctx );
+        md_hmac_update( &md_ctx, 4 + tmp, 16 + nb );
+        md_hmac_finish( &md_ctx, h_i );
+
+        md_hmac_reset ( &md_ctx );
+        md_hmac_update( &md_ctx, 4 + tmp, 16 );
+        md_hmac_finish( &md_ctx, 4 + tmp );
 
         k = ( i + 16 > dlen ) ? dlen % 16 : 16;
 
@@ -305,15 +323,30 @@
             dstbuf[i + j]  = h_i[j];
     }
 
+    md_free( &md_ctx );
+
     /*
      * XOR out with P_sha1(secret,label+random)[0..dlen]
      */
-    sha1_hmac( S2, hs, tmp + 20, nb, tmp );
+    if( ( md_info = md_info_from_type( POLARSSL_MD_SHA1 ) ) == NULL )
+        return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
+
+    if( ( ret = md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+        return( ret );
+
+    md_hmac_starts( &md_ctx, S2, hs );
+    md_hmac_update( &md_ctx, tmp + 20, nb );
+    md_hmac_finish( &md_ctx, tmp );
 
     for( i = 0; i < dlen; i += 20 )
     {
-        sha1_hmac( S2, hs, tmp, 20 + nb, h_i );
-        sha1_hmac( S2, hs, tmp, 20,      tmp );
+        md_hmac_reset ( &md_ctx );
+        md_hmac_update( &md_ctx, tmp, 20 + nb );
+        md_hmac_finish( &md_ctx, h_i );
+
+        md_hmac_reset ( &md_ctx );
+        md_hmac_update( &md_ctx, tmp, 20 );
+        md_hmac_finish( &md_ctx, tmp );
 
         k = ( i + 20 > dlen ) ? dlen % 20 : 20;
 
@@ -321,6 +354,8 @@
             dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] );
     }
 
+    md_free( &md_ctx );
+
     polarssl_zeroize( tmp, sizeof( tmp ) );
     polarssl_zeroize( h_i, sizeof( h_i ) );
 
@@ -329,45 +364,77 @@
 #endif /* POLARSSL_SSL_PROTO_TLS1) || POLARSSL_SSL_PROTO_TLS1_1 */
 
 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
+static int tls_prf_generic( md_type_t md_type,
+                            const unsigned char *secret, size_t slen,
+                            const char *label,
+                            const unsigned char *random, size_t rlen,
+                            unsigned char *dstbuf, size_t dlen )
+{
+    size_t nb;
+    size_t i, j, k, md_len;
+    unsigned char tmp[128];
+    unsigned char h_i[POLARSSL_MD_MAX_SIZE];
+    const md_info_t *md_info;
+    md_context_t md_ctx;
+    int ret;
+
+    md_init( &md_ctx );
+
+    if( ( md_info = md_info_from_type( md_type ) ) == NULL )
+        return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
+
+    md_len = md_get_size( md_info );
+
+    if( sizeof( tmp ) < md_len + strlen( label ) + rlen )
+        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+
+    nb = strlen( label );
+    memcpy( tmp + md_len, label, nb );
+    memcpy( tmp + md_len + nb, random, rlen );
+    nb += rlen;
+
+    /*
+     * Compute P_<hash>(secret, label + random)[0..dlen]
+     */
+    if ( ( ret = md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+        return( ret );
+
+    md_hmac_starts( &md_ctx, secret, slen );
+    md_hmac_update( &md_ctx, tmp + md_len, nb );
+    md_hmac_finish( &md_ctx, tmp );
+
+    for( i = 0; i < dlen; i += md_len )
+    {
+        md_hmac_reset ( &md_ctx );
+        md_hmac_update( &md_ctx, tmp, md_len + nb );
+        md_hmac_finish( &md_ctx, h_i );
+
+        md_hmac_reset ( &md_ctx );
+        md_hmac_update( &md_ctx, tmp, md_len );
+        md_hmac_finish( &md_ctx, tmp );
+
+        k = ( i + md_len > dlen ) ? dlen % md_len : md_len;
+
+        for( j = 0; j < k; j++ )
+            dstbuf[i + j]  = h_i[j];
+    }
+
+    md_free( &md_ctx );
+
+    polarssl_zeroize( tmp, sizeof( tmp ) );
+    polarssl_zeroize( h_i, sizeof( h_i ) );
+
+    return( 0 );
+}
+
 #if defined(POLARSSL_SHA256_C)
 static int tls_prf_sha256( const unsigned char *secret, size_t slen,
                            const char *label,
                            const unsigned char *random, size_t rlen,
                            unsigned char *dstbuf, size_t dlen )
 {
-    size_t nb;
-    size_t i, j, k;
-    unsigned char tmp[128];
-    unsigned char h_i[32];
-
-    if( sizeof( tmp ) < 32 + strlen( label ) + rlen )
-        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
-
-    nb = strlen( label );
-    memcpy( tmp + 32, label, nb );
-    memcpy( tmp + 32 + nb, random, rlen );
-    nb += rlen;
-
-    /*
-     * Compute P_<hash>(secret, label + random)[0..dlen]
-     */
-    sha256_hmac( secret, slen, tmp + 32, nb, tmp, 0 );
-
-    for( i = 0; i < dlen; i += 32 )
-    {
-        sha256_hmac( secret, slen, tmp, 32 + nb, h_i, 0 );
-        sha256_hmac( secret, slen, tmp, 32,      tmp, 0 );
-
-        k = ( i + 32 > dlen ) ? dlen % 32 : 32;
-
-        for( j = 0; j < k; j++ )
-            dstbuf[i + j]  = h_i[j];
-    }
-
-    polarssl_zeroize( tmp, sizeof( tmp ) );
-    polarssl_zeroize( h_i, sizeof( h_i ) );
-
-    return( 0 );
+    return( tls_prf_generic( POLARSSL_MD_SHA256, secret, slen,
+                             label, random, rlen, dstbuf, dlen ) );
 }
 #endif /* POLARSSL_SHA256_C */
 
@@ -377,39 +444,8 @@
                            const unsigned char *random, size_t rlen,
                            unsigned char *dstbuf, size_t dlen )
 {
-    size_t nb;
-    size_t i, j, k;
-    unsigned char tmp[128];
-    unsigned char h_i[48];
-
-    if( sizeof( tmp ) < 48 + strlen( label ) + rlen )
-        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
-
-    nb = strlen( label );
-    memcpy( tmp + 48, label, nb );
-    memcpy( tmp + 48 + nb, random, rlen );
-    nb += rlen;
-
-    /*
-     * Compute P_<hash>(secret, label + random)[0..dlen]
-     */
-    sha512_hmac( secret, slen, tmp + 48, nb, tmp, 1 );
-
-    for( i = 0; i < dlen; i += 48 )
-    {
-        sha512_hmac( secret, slen, tmp, 48 + nb, h_i, 1 );
-        sha512_hmac( secret, slen, tmp, 48,      tmp, 1 );
-
-        k = ( i + 48 > dlen ) ? dlen % 48 : 48;
-
-        for( j = 0; j < k; j++ )
-            dstbuf[i + j]  = h_i[j];
-    }
-
-    polarssl_zeroize( tmp, sizeof( tmp ) );
-    polarssl_zeroize( h_i, sizeof( h_i ) );
-
-    return( 0 );
+    return( tls_prf_generic( POLARSSL_MD_SHA384, secret, slen,
+                             label, random, rlen, dstbuf, dlen ) );
 }
 #endif /* POLARSSL_SHA512_C */
 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
@@ -571,17 +607,28 @@
 
             SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len );
 
-            handshake->tls_prf( handshake->premaster, handshake->pmslen,
-                                "extended master secret",
-                                session_hash, hash_len, session->master, 48 );
+            ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
+                                      "extended master secret",
+                                      session_hash, hash_len,
+                                      session->master, 48 );
+            if( ret != 0 )
+            {
+                SSL_DEBUG_RET( 1, "prf", ret );
+                return( ret );
+            }
 
         }
         else
 #endif
-        handshake->tls_prf( handshake->premaster, handshake->pmslen,
-                            "master secret",
-                            handshake->randbytes, 64, session->master, 48 );
-
+        ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
+                                  "master secret",
+                                  handshake->randbytes, 64,
+                                  session->master, 48 );
+        if( ret != 0 )
+        {
+            SSL_DEBUG_RET( 1, "prf", ret );
+            return( ret );
+        }
 
         polarssl_zeroize( handshake->premaster, sizeof(handshake->premaster) );
     }
@@ -608,8 +655,13 @@
      *  TLSv1:
      *    key block = PRF( master, "key expansion", randbytes )
      */
-    handshake->tls_prf( session->master, 48, "key expansion",
-                        handshake->randbytes, 64, keyblk, 256 );
+    ret = handshake->tls_prf( session->master, 48, "key expansion",
+                              handshake->randbytes, 64, keyblk, 256 );
+    if( ret != 0 )
+    {
+        SSL_DEBUG_RET( 1, "prf", ret );
+        return( ret );
+    }
 
     SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
                    ssl_get_ciphersuite_name( session->ciphersuite ) ) );
@@ -643,10 +695,10 @@
         int ret;
 
         /* Initialize HMAC contexts */
-        if( ( ret = md_init_ctx( &transform->md_ctx_enc, md_info ) ) != 0 ||
-            ( ret = md_init_ctx( &transform->md_ctx_dec, md_info ) ) != 0 )
+        if( ( ret = md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
+            ( ret = md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
         {
-            SSL_DEBUG_RET( 1, "md_init_ctx", ret );
+            SSL_DEBUG_RET( 1, "md_setup", ret );
             return( ret );
         }
 
diff --git a/library/x509.c b/library/x509.c
index 174e32d..67359a5 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -845,8 +845,8 @@
         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 8b93473..7d12bca 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1505,7 +1505,7 @@
         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 @@
         }
 
         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 @@
         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;
diff --git a/programs/aes/aescrypt2.c b/programs/aes/aescrypt2.c
index 5d733b4..712a941 100644
--- a/programs/aes/aescrypt2.c
+++ b/programs/aes/aescrypt2.c
@@ -34,15 +34,12 @@
 #define polarssl_printf     printf
 #endif
 
-#if defined(POLARSSL_AES_C) && defined(POLARSSL_SHA256_C) && \
- defined(POLARSSL_FS_IO)
 #include "mbedtls/aes.h"
-#include "mbedtls/sha256.h"
+#include "mbedtls/md.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#endif
 
 #if defined(_WIN32)
 #include <windows.h>
@@ -64,10 +61,12 @@
     "\n"
 
 #if !defined(POLARSSL_AES_C) || !defined(POLARSSL_SHA256_C) || \
-    !defined(POLARSSL_FS_IO)
+    !defined(POLARSSL_FS_IO) || !defined(POLARSSL_MD_C)
 int main( void )
 {
-    polarssl_printf("POLARSSL_AES_C and/or POLARSSL_SHA256_C and/or POLARSSL_FS_IO not defined.\n");
+    polarssl_printf("POLARSSL_AES_C and/or POLARSSL_SHA256_C "
+                    "and/or POLARSSL_FS_IO and/or POLARSSL_MD_C "
+                    "not defined.\n");
     return( 0 );
 }
 #else
@@ -88,7 +87,7 @@
     unsigned char diff;
 
     aes_context aes_ctx;
-    sha256_context sha_ctx;
+    md_context_t sha_ctx;
 
 #if defined(_WIN32_WCE)
     long filesize, offset;
@@ -100,7 +99,14 @@
 #endif
 
     aes_init( &aes_ctx );
-    sha256_init( &sha_ctx );
+    md_init( &sha_ctx );
+
+    ret = md_setup( &sha_ctx, md_info_from_type( POLARSSL_MD_SHA256 ), 1 );
+    if( ret != 0 )
+    {
+        polarssl_printf( "  ! md_setup() returned -0x%04x\n", -ret );
+        goto exit;
+    }
 
     /*
      * Parse the command-line arguments.
@@ -227,10 +233,10 @@
 
         p = argv[2];
 
-        sha256_starts( &sha_ctx, 0 );
-        sha256_update( &sha_ctx, buffer, 8 );
-        sha256_update( &sha_ctx, (unsigned char *) p, strlen( p ) );
-        sha256_finish( &sha_ctx, digest );
+        md_starts( &sha_ctx );
+        md_update( &sha_ctx, buffer, 8 );
+        md_update( &sha_ctx, (unsigned char *) p, strlen( p ) );
+        md_finish( &sha_ctx, digest );
 
         memcpy( IV, digest, 16 );
 
@@ -261,15 +267,15 @@
 
         for( i = 0; i < 8192; i++ )
         {
-            sha256_starts( &sha_ctx, 0 );
-            sha256_update( &sha_ctx, digest, 32 );
-            sha256_update( &sha_ctx, key, keylen );
-            sha256_finish( &sha_ctx, digest );
+            md_starts( &sha_ctx );
+            md_update( &sha_ctx, digest, 32 );
+            md_update( &sha_ctx, key, keylen );
+            md_finish( &sha_ctx, digest );
         }
 
         memset( key, 0, sizeof( key ) );
         aes_setkey_enc( &aes_ctx, digest, 256 );
-        sha256_hmac_starts( &sha_ctx, digest, 32, 0 );
+        md_hmac_starts( &sha_ctx, digest, 32 );
 
         /*
          * Encrypt and write the ciphertext.
@@ -289,7 +295,7 @@
                 buffer[i] = (unsigned char)( buffer[i] ^ IV[i] );
 
             aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, buffer, buffer );
-            sha256_hmac_update( &sha_ctx, buffer, 16 );
+            md_hmac_update( &sha_ctx, buffer, 16 );
 
             if( fwrite( buffer, 1, 16, fout ) != 16 )
             {
@@ -303,7 +309,7 @@
         /*
          * Finally write the HMAC.
          */
-        sha256_hmac_finish( &sha_ctx, digest );
+        md_hmac_finish( &sha_ctx, digest );
 
         if( fwrite( digest, 1, 32, fout ) != 32 )
         {
@@ -363,15 +369,15 @@
 
         for( i = 0; i < 8192; i++ )
         {
-            sha256_starts( &sha_ctx, 0 );
-            sha256_update( &sha_ctx, digest, 32 );
-            sha256_update( &sha_ctx, key, keylen );
-            sha256_finish( &sha_ctx, digest );
+            md_starts( &sha_ctx );
+            md_update( &sha_ctx, digest, 32 );
+            md_update( &sha_ctx, key, keylen );
+            md_finish( &sha_ctx, digest );
         }
 
         memset( key, 0, sizeof( key ) );
         aes_setkey_dec( &aes_ctx, digest, 256 );
-        sha256_hmac_starts( &sha_ctx, digest, 32, 0 );
+        md_hmac_starts( &sha_ctx, digest, 32 );
 
         /*
          * Decrypt and write the plaintext.
@@ -386,7 +392,7 @@
 
             memcpy( tmp, buffer, 16 );
 
-            sha256_hmac_update( &sha_ctx, buffer, 16 );
+            md_hmac_update( &sha_ctx, buffer, 16 );
             aes_crypt_ecb( &aes_ctx, AES_DECRYPT, buffer, buffer );
 
             for( i = 0; i < 16; i++ )
@@ -407,7 +413,7 @@
         /*
          * Verify the message authentication code.
          */
-        sha256_hmac_finish( &sha_ctx, digest );
+        md_hmac_finish( &sha_ctx, digest );
 
         if( fread( buffer, 1, 32, fin ) != 32 )
         {
@@ -440,7 +446,7 @@
     memset( digest, 0, sizeof( digest ) );
 
     aes_free( &aes_ctx );
-    sha256_free( &sha_ctx );
+    md_free( &sha_ctx );
 
     return( ret );
 }
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index b002934..d102b69 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -126,7 +126,7 @@
         while( *list )
         {
             md_info = md_info_from_type( *list );
-            polarssl_printf( "  %s\n", md_info->name );
+            polarssl_printf( "  %s\n", md_get_name( md_info ) );
             list++;
         }
 
@@ -185,7 +185,7 @@
         polarssl_fprintf( stderr, "Message Digest '%s' not found\n", argv[5] );
         goto exit;
     }
-    md_init_ctx( &md_ctx, md_info);
+    md_setup( &md_ctx, md_info, 1 );
 
     /*
      * Read the secret key and clean the command line.
diff --git a/programs/hash/generic_sum.c b/programs/hash/generic_sum.c
index 888f0f9..b63ebfb 100644
--- a/programs/hash/generic_sum.c
+++ b/programs/hash/generic_sum.c
@@ -69,7 +69,7 @@
     if( generic_wrapper( md_info, filename, sum ) != 0 )
         return( 1 );
 
-    for( i = 0; i < md_info->size; i++ )
+    for( i = 0; i < md_get_size( md_info ); i++ )
         polarssl_printf( "%02x", sum[i] );
 
     polarssl_printf( "  %s\n", filename );
@@ -104,15 +104,15 @@
     {
         n = strlen( line );
 
-        if( n < (size_t) 2 * md_info->size + 4 )
+        if( n < (size_t) 2 * md_get_size( md_info ) + 4 )
         {
-            polarssl_printf("No '%s' hash found on line.\n", md_info->name);
+            polarssl_printf("No '%s' hash found on line.\n", md_get_name( md_info ));
             continue;
         }
 
-        if( line[2 * md_info->size] != ' ' || line[2 * md_info->size + 1] != ' ' )
+        if( line[2 * md_get_size( md_info )] != ' ' || line[2 * md_get_size( md_info ) + 1] != ' ' )
         {
-            polarssl_printf("No '%s' hash found on line.\n", md_info->name);
+            polarssl_printf("No '%s' hash found on line.\n", md_get_name( md_info ));
             continue;
         }
 
@@ -121,7 +121,7 @@
 
         nb_tot1++;
 
-        if( generic_wrapper( md_info, line + 2 + 2 * md_info->size, sum ) != 0 )
+        if( generic_wrapper( md_info, line + 2 + 2 * md_get_size( md_info ), sum ) != 0 )
         {
             nb_err1++;
             continue;
@@ -129,12 +129,12 @@
 
         nb_tot2++;
 
-        for( i = 0; i < md_info->size; i++ )
+        for( i = 0; i < md_get_size( md_info ); i++ )
             sprintf( buf + i * 2, "%02x", sum[i] );
 
         /* Use constant-time buffer comparison */
         diff = 0;
-        for( i = 0; i < 2 * md_info->size; i++ )
+        for( i = 0; i < 2 * md_get_size( md_info ); i++ )
             diff |= line[i] ^ buf[i];
 
         if( diff != 0 )
@@ -183,7 +183,7 @@
         while( *list )
         {
             md_info = md_info_from_type( *list );
-            polarssl_printf( "  %s\n", md_info->name );
+            polarssl_printf( "  %s\n", md_get_name( md_info ) );
             list++;
         }
 
@@ -204,7 +204,7 @@
         polarssl_fprintf( stderr, "Message Digest '%s' not found\n", argv[1] );
         return( 1 );
     }
-    if( md_init_ctx( &md_ctx, md_info) )
+    if( md_setup( &md_ctx, md_info, 0 ) )
     {
         polarssl_fprintf( stderr, "Failed to initialize context.\n" );
         return( 1 );
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index af4b75f..63dfead 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -70,7 +70,6 @@
 add_test_suite(hmac_drbg hmac_drbg.no_reseed)
 add_test_suite(hmac_drbg hmac_drbg.nopr)
 add_test_suite(hmac_drbg hmac_drbg.pr)
-add_test_suite(hmac_shax)
 add_test_suite(md)
 add_test_suite(mdx)
 add_test_suite(memory_buffer_alloc)
diff --git a/tests/Makefile b/tests/Makefile
index 5b2c3a8..28c667c 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -67,7 +67,7 @@
 	test_suite_gcm.aes128_en$(EXEXT)				\
 	test_suite_gcm.aes192_en$(EXEXT)				\
 	test_suite_gcm.aes256_en$(EXEXT)				\
-	test_suite_gcm.camellia$(EXEXT)	test_suite_hmac_shax$(EXEXT)	\
+	test_suite_gcm.camellia$(EXEXT)					\
 	test_suite_hmac_drbg.misc$(EXEXT)				\
 	test_suite_hmac_drbg.no_reseed$(EXEXT)				\
 	test_suite_hmac_drbg.nopr$(EXEXT)				\
@@ -340,10 +340,6 @@
 	echo   "  CC    	$<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
-test_suite_hmac_shax$(EXEXT): test_suite_hmac_shax.c $(DEP)
-	echo   "  CC    	$<"
-	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
-
 test_suite_md$(EXEXT): test_suite_md.c $(DEP)
 	echo   "  CC    	$<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
diff --git a/tests/suites/test_suite_ecdsa.function b/tests/suites/test_suite_ecdsa.function
index 98d834a..864fade 100644
--- a/tests/suites/test_suite_ecdsa.function
+++ b/tests/suites/test_suite_ecdsa.function
@@ -117,7 +117,7 @@
 
     md_info = md_info_from_type( md_alg );
     TEST_ASSERT( md_info != NULL );
-    hlen = md_info->size;
+    hlen = md_get_size( md_info );
     md( md_info, (const unsigned char *) msg, strlen( msg ), hash );
 
     TEST_ASSERT( ecdsa_sign_det( &grp, &r, &s, &d, hash, hlen, md_alg ) == 0 );
diff --git a/tests/suites/test_suite_hmac_shax.data b/tests/suites/test_suite_hmac_shax.data
deleted file mode 100644
index 277eb8e..0000000
--- a/tests/suites/test_suite_hmac_shax.data
+++ /dev/null
@@ -1,143 +0,0 @@
-HMAC-SHA-1 Test Vector FIPS-198a #1
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:20:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":"53616d706c65202331":"4f4ca3d5d68ba7cc0a1208c9c61e9c5da0403c0a"
-
-HMAC-SHA-1 Test Vector FIPS-198a #2
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:20:"303132333435363738393a3b3c3d3e3f40414243":"53616d706c65202332":"0922d3405faa3d194f82a45830737d5cc6c75d24"
-
-HMAC-SHA-1 Test Vector FIPS-198a #3
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:20:"505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3":"53616d706c65202333":"bcf41eab8bb2d802f3d05caf7cb092ecf8d1a3aa"
-
-HMAC-SHA-1 Test Vector FIPS-198a #4
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:12:"707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0":"53616d706c65202334":"9ea886efe268dbecce420c75"
-
-HMAC-SHA-1 Test Vector NIST CAVS #1
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:10:"7b10f4124b15c82e":"27dcb5b1daf60cfd3e2f73d4d64ca9c684f8bf71fc682a46793b1790afa4feb100ca7aaff26f58f0e1d0ed42f1cdad1f474afa2e79d53a0c42892c4d7b327cbe46b295ed8da3b6ecab3d4851687a6f812b79df2f6b20f11f6706f5301790ca99625aad7391d84f78043d2a0a239b1477984c157bbc9276064e7a1a406b0612ca":"4ead12c2fe3d6ea43acb"
-
-HMAC-SHA-1 Test Vector NIST CAVS #2
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:10:"4fe9fb902172a21b":"4ceb3a7c13659c22fe51134f03dce4c239d181b63c6b0b59d367157fd05cab98384f92dfa482d2d5e78e72eef1b1838af4696026c54233d484ecbbe87f904df5546419f8567eafd232e6c2fcd3ee2b7682c63000524b078dbb2096f585007deae752562df1fe3b01278089e16f3be46e2d0f7cabac2d8e6cc02a2d0ca953425f":"564428a67be1924b5793"
-
-HMAC-SHA-1 Test Vector NIST CAVS #3
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:10:"d1f01455f78c4fb4":"00d40f67b57914bec456a3e3201ef1464be319a8d188c02e157af4b54f9b5a66d67f898a9bdbb19ff63a80aba6f246d013575721d52eb1b47a65def884011c49b257bcc2817fc853f106e8138ce386d7a5ac3103de0a3fa0ed6bb7af9ff66ebd1cc46fb86e4da0013d20a3c2dcd8fb828a4b70f7f104b41bf3f44682a66497ea":"56a665a7cdfe610f9fc5"
-
-HMAC-SHA-1 Test Vector NIST CAVS #4
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:10:"4e5ef77fdf033a5b":"e59326464e3201d195e29f2a3446ec1b1c9ff31154e2a4d0e40ed466f1bc855d29f76835624fa0127d29c9b1915939a046f385af7e5d47a23ba91f28bd22f811ea258dbbf3332bcd3543b8285d5df41bd064ffd64a341c22c4edb44f9c8d9e6df0c59dbf4a052a6c83da7478e179a6f3839c6870ff8ca8b9497f9ac1d725fdda":"981c0a7a8423b63a8fa6"
-
-HMAC-SHA-1 Test Vector NIST CAVS #5
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:10:"bcd9ff8aa60be2be":"51be4d0eb37bab714f92e19e9d70390655b363e8cd346a748245e731f437759cb8206412c8dab2ef1d4f36f880f41ff69d949da4594fdecb65e23cac1329b59e69e29bf875b38c31df6fa546c595f35cc2192aa750679a8a51a65e00e839d73a8d8c598a610d237fbe78955213589d80efcb73b95b8586f96d17b6f51a71c3b8":"84633f9f5040c8971478"
-
-HMAC-SHA-1 Test Vector NIST CAVS #6
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:10:"4a661bce6ed86d21":"5ff6c744f1aab1bc29697d71f67541b8b3cec3c7079183b10a83fb98a9ee251d4bac3e1cb581ca972aaed8efd7c2875a6fb4c991132f67c9742d45e53bc7e8eaa94b35b37a907be61086b426cd11088ac118934e85d968c9667fd69fc6f6ea38c0fe34710b7ece91211b9b7ea00acd31f022aa6726368f9928a1352f122233f1":"739df59353ac6694e55e"
-
-HMAC-SHA-1 Test Vector NIST CAVS #7
-depends_on:POLARSSL_SHA1_C
-sha1_hmac:10:"1287e1565a57b547":"390ffdccc6171c11568d85b8f913e019bf4cd982ca9cd21ea730d41bdf3fcc0bc88ff48ba13a8f23deb2d96ec1033e7b2a58ca72b0c1e17bf03330db25d1e360fa6918009c4294bd1215b5ccd159a8f58bc3dc3d490eb7c3b9f887e8c98dbbb274a75373dcb695a59abd0219529d88518a96f92abc0bbcbda985c388f1fbbcc9":"d78ddf08077c7d9e2ba6"
-
-HMAC-SHA-224 Test Vector NIST CAVS #1
-depends_on:POLARSSL_SHA256_C
-sha224_hmac:14:"e055eb756697ee573fd3214811a9f7fa":"3875847012ee42fe54a0027bdf38cca7021b83a2ed0503af69ef6c37c637bc1114fba40096c5947d736e19b7af3c68d95a4e3b8b073adbbb80f47e9db8f2d4f0018ddd847fabfdf9dd9b52c93e40458977725f6b7ba15f0816bb895cdf50401268f5d702b7e6a5f9faef57b8768c8a3fc14f9a4b3182b41d940e337d219b29ff":"40a453133361cc48da11baf616ee"
-
-HMAC-SHA-224 Test Vector NIST CAVS #2
-depends_on:POLARSSL_SHA256_C
-sha224_hmac:14:"88e5258b55b1623385eb9632fa7c57d6":"ada76bb604be14326551701cf30e48a65eee80b44f0b9d4a07b1844543b7844a621097fdc99de57387458ae9354899b620d0617eabcaefa9eef3d413a33628054335ce656c26fa2986e0f111a6351096b283101ec7868871d770b370973c7405983f9756b3005a3eab492cfd0e7eb42e5c2e15fa6be8718c0a50acc4e5717230":"81c783af538015cef3c60095df53"
-
-HMAC-SHA-224 Test Vector NIST CAVS #3
-depends_on:POLARSSL_SHA256_C
-sha224_hmac:14:"85d402d822114d31abf75526e2538705":"8020d8d98cc2e2298b32879c51c751e1dd5558fe2eabb8f158604297d6d072ce2261a1d6830b7cfe2617b57c7126f99c9476211d6161acd75d266da217ec8174b80484c9dc6f0448a0a036a3fc82e8bf54bdb71549368258d5d41f57978a4c266b92e8783ef66350215573d99be4089144b383ad8f3222bae8f3bf80ffb1bb2b":"2aa0340ac9deafe3be38129daca0"
-
-HMAC-SHA-224 Test Vector NIST CAVS #4
-depends_on:POLARSSL_SHA256_C
-sha224_hmac:14:"545c6eecc5ee46fa17c59f91a94f81ae":"8fb7f3565593170152ddb2021874784e951977cfdd22f8b72a72a61320a8f2a35697b5e913f717805559b1af1861ee3ed42fb788481e4fd276b17bdbefcae7b4501dc5d20de5b7626dd5efdcd65294db4bdf682c33d9a9255c6435383fa5f1c886326a3acbc6bd50a33ab5b2dbb034ce0112d4e226bbcd57e3731a519aa1d784":"3eb566eac54c4a3a9ef092469f24"
-
-HMAC-SHA-224 Test Vector NIST CAVS #5
-depends_on:POLARSSL_SHA256_C
-sha224_hmac:14:"4466ab4dc438841a9750c7f173dff02e":"2534c11c78c99cffaec8f722f04adc7045c7324d58ce98e37cfa94b6ed21ed7f58ce55379ef24b72d6d640ee9154f96c614734be9c408e225d7ba4cecc1179cc9f6e1808e1067aa8f244a99bd0c3267594c1887a40d167f8b7cf78db0d19f97b01fc50b8c86def490dfa7a5135002c33e71d77a8cce8ea0f93e0580439a33733":"59f44a9bbed4875b892d22d6b5ab"
-
-HMAC-SHA-224 Test Vector NIST CAVS #6
-depends_on:POLARSSL_SHA256_C
-sha224_hmac:28:"0e3dd9bb5e4cf0f09a4c11600af56d8d":"f4589fa76c328ea25cf8bae582026ba40a59d45a546ff31cf80eb826088f69bb954c452c74586836416dee90a5255bc5d56d3b405b3705a5197045688b32fa984c3a3dfbdc9c2460a0b5e6312a624048bb6f170306535e9b371a3ab134a2642a230ad03d2c688cca80baeaee9a20e1d4c548b1cede29c6a45bf4df2c8c476f1a":"12175b93e3da4c58217145e4dc0a1cf142fab9319bb501e037b350ba"
-
-HMAC-SHA-224 Test Vector NIST CAVS #7
-depends_on:POLARSSL_SHA256_C
-sha224_hmac:28:"cda5187b0c5dcb0f8e5a8beed2306584":"9011ae29b44c49b347487ce972965f16ade3c15be0856ce9c853a9739dba07e4f20d594ddc1dfe21560a65a4e458cfa17745575b915a30c7a9412ff8d1d689db9680dd2428c27588bb0dc92d2cd9445fe8f44b840a197c52c3c4333fff45533945134398df6436513cfab06c924046b8c795a5bd92e8d5f2de85bf306f2eed67":"4aaba92b40e2a600feab176eb9b292d814864195c03342aad6f67f08"
-
-HMAC-SHA-256 Test Vector NIST CAVS #1
-depends_on:POLARSSL_SHA256_C
-sha256_hmac:16:"cdffd34e6b16fdc0":"d83e78b99ab61709608972b36e76a575603db742269cc5dd4e7d5ca7816e26b65151c92632550cb4c5253c885d5fce53bc47459a1dbd5652786c4aac0145a532f12c05138af04cbb558101a7af5df478834c2146594dd73690d01a4fe72545894335f427ac70204798068cb86c5a600b40b414ede23590b41e1192373df84fe3":"c6f0dde266cb4a26d41e8259d33499cc"
-
-HMAC-SHA-256 Test Vector NIST CAVS #2
-depends_on:POLARSSL_SHA256_C
-sha256_hmac:16:"6d97bb5892245be2":"13c2b391d59c0252ca5d2302beaaf88c4bcd779bb505ad9a122003dfae4cc123ad2bd036f225c4f040021a6b9fb8bd6f0281cf2e2631a732bdc71693cc42ef6d52b6c6912a9ef77b3274eb85ad7f965ae6ed44ac1721962a884ec7acfb4534b1488b1c0c45afa4dae8da1eb7b0a88a3240365d7e4e7d826abbde9f9203fd99d7":"31588e241b015319a5ab8c4527296498"
-
-HMAC-SHA-256 Test Vector NIST CAVS #3
-depends_on:POLARSSL_SHA256_C
-sha256_hmac:16:"3c7fc8a70b49007a":"60024e428a39c8b8bb2e9591bad9dc2115dfbfd716b6eb7af30a6eb34560caccbbfa47b710fa8d523aca71e9e5ba10fc1feb1a43556d71f07ea4f33496f093044e8caf1d02b79e46eb1288d5964a7a7494f6b92574c35784eece054c6151281d80822f7d47b8231c35d07f5cb5cf4310ddc844845a01c6bfab514c048eccaf9f":"1c98c94a32bec9f253c21070f82f8438"
-
-HMAC-SHA-256 Test Vector NIST CAVS #4
-depends_on:POLARSSL_SHA256_C
-sha256_hmac:24:"369f33f85b927a07":"ae8e2a94ca386d448cbacdb0e9040ae3cb297c296363052cc157455da29a0c95897315fc11e3f12b81e2418da1ec280bccbc00e847584ce9d14deeba7b3c9b8dba958b04bba37551f6c9ba9c060be1a4b8cf43aa62e5078b76c6512c5619b71a6a7cf5727180e1ff14f5a1a3c1691bf8b6ebad365c151e58d749d57adb3a4986":"60b90383286533d309de46593e6ce39fc51fb00a8d88278c"
-
-HMAC-SHA-256 Test Vector NIST CAVS #5
-depends_on:POLARSSL_SHA256_C
-sha256_hmac:24:"e5179687582b4dc4":"ce103bdacdf32f614f6727bcb31ca1c2824a850d00f5585b016fb234fe1ef2cd687f302d3c6b738ed89a24060d65c36675d0d96307c72ef3e8a83bfa8402e226de9d5d1724ba75c4879bf41a4a465ce61887d9f49a34757849b48bae81c27ebed76faae2ad669bca04747d409148d40812776e0ae2c395b3cb9c89981ce72d5c":"509581f6816df4b8cc9f2cf42b7cc6e6a5a1e375a16f2412"
-
-HMAC-SHA-256 Test Vector NIST CAVS #6
-depends_on:POLARSSL_SHA256_C
-sha256_hmac:24:"63cec6246aeb1b61":"c178db908a405fa88aa255b8cad22b4057016585f139ee930388b083d86062fa0b3ea1f23f8a43bd11bee8464bcbd19b5ab9f6a8038d5245516f8274d20c8ee3033a07b908da528fa00343bb595deed500cab9745c4cb6391c23300f0d3584b090b3326c4cfa342620b78f9f5b4f27f7307ed770643ec1764aeae3dcf1a3ec69":"64f3dd861b7c7d29fce9ae0ce9ed954b5d7141806ee9eec7"
-
-HMAC-SHA-384 Test Vector NIST CAVS #1
-depends_on:POLARSSL_SHA512_C
-sha384_hmac:32:"91a7401817386948ca952f9a20ee55dc":"2fea5b91035d6d501f3a834fa178bff4e64b99a8450432dafd32e4466b0e1e7781166f8a73f7e036b3b0870920f559f47bd1400a1a906e85e0dcf00a6c26862e9148b23806680f285f1fe4f93cdaf924c181a965465739c14f2268c8be8b471847c74b222577a1310bcdc1a85ef1468aa1a3fd4031213c97324b7509c9050a3d":"6d7be9490058cf413cc09fd043c224c2ec4fa7859b13783000a9a593c9f75838"
-
-HMAC-SHA-384 Test Vector NIST CAVS #2
-depends_on:POLARSSL_SHA512_C
-sha384_hmac:32:"d6cac19657061aa90a6da11cd2e9ea47":"9f482e4655173135dfaa22a11bbbe6af263db48716406c5aec162ba3c4b41cad4f5a91558377521191c7343118beee65982929802913d67b6de5c4bdc3d27299bd722219d5ad2efa5bdb9ff7b229fc4bbc3f60719320cf2e7a51cad1133d21bad2d80919b1836ef825308b7c51c6b7677ac782e2bc30007afba065681cbdd215":"f3d5f3c008175321aa7b2ea379eaa4f8b9dcc60f895ec8940b8162f80a7dfe9f"
-
-HMAC-SHA-384 Test Vector NIST CAVS #3
-depends_on:POLARSSL_SHA512_C
-sha384_hmac:32:"e06366ad149b8442cd4c1abdddd0afde":"2d140a194c02a5598f69174834679b8371234a0d505491f1bd03e128dd91a8bca2fb812e9d5da71613b5b00952ea78bf450d5b7547dea79135925085c7d3e6f52009c51ca3d88c6c09e9d074b0ee110736e0ec9b478b93efb34d7bf1c41b54decec43eab077a3aa4998ede53f67b4ea36c266745f9643d5360bdc8337c70dabf":"c19c67eda6fe29f3667bee1c897c333ce7683094ae77e84b4c16378d290895a1"
-
-HMAC-SHA-384 Test Vector NIST CAVS #4
-depends_on:POLARSSL_SHA512_C
-sha384_hmac:48:"01ac59f42f8bb91d1bd10fe6990d7a87":"3caf18c476edd5615f343ac7b7d3a9da9efade755672d5ba4b8ae8a7505539ea2c124ff755ec0457fbe49e43480b3c71e7f4742ec3693aad115d039f90222b030fdc9440313691716d5302005808c07627483b916fdf61983063c2eb1268f2deeef42fc790334456bc6bad256e31fc9066de7cc7e43d1321b1866db45e905622":"1985fa2163a5943fc5d92f1fe8831215e7e91f0bff5332bc713a072bdb3a8f9e5c5157463a3bfeb36231416e65973e64"
-
-HMAC-SHA-384 Test Vector NIST CAVS #5
-depends_on:POLARSSL_SHA512_C
-sha384_hmac:48:"fd74b9d9e102a3a80df1baf0cb35bace":"1a068917584813d1689ccbd0370c2114d537cdc8cc52bf6db16d5535f8f7d1ad0c850a9fa0cf62373ffbf7642b1f1e8164010d350721d798d9f99e9724830399c2fce26377e83d38845675457865c03d4a07d741a505ef028343eb29fd46d0f761f3792886998c1e5c32ac3bc7e6f08faed194b34f06eff4d5d4a5b42c481e0e":"a981eaf5de3d78b20ebd4414a4edd0657e3667cd808a0dbc430cf7252f73a5b24efa136039207bd59806897457d74e0c"
-
-HMAC-SHA-384 Test Vector NIST CAVS #5
-depends_on:POLARSSL_SHA512_C
-sha384_hmac:48:"9fe794f0e26b669fa5f6883149377c6c":"6010c9745e8f1d44cfdc99e7e0fd79bc4271944c2d1d84dba589073dfc4ca5eb98c59356f60cd87bef28aeb83a832bde339b2087daf942aa1f67876c5d5ed33924bed4143bc12a2be532ccaf64daa7e2bc3c8872b9823b0533b6f5159135effe8c61545536975d7c3a61ba7365ec35f165bc92b4d19eb9156ade17dfa1bb4161":"915ae61f8754698c2b6ef9629e93441f8541bd4258a5e05372d19136cfaefc0473b48d96119291b38eb1a3cb1982a986"
-
-HMAC-SHA-512 Test Vector NIST CAVS #1
-depends_on:POLARSSL_SHA512_C
-sha512_hmac:32:"c95a17c09940a691ed2d621571b0eb844ede55a9":"99cd28262e81f34878cdcebf4128e05e2098a7009278a66f4c785784d0e5678f3f2b22f86e982d273b6273a222ec61750b4556d766f1550a7aedfe83faedbc4bdae83fa560d62df17eb914d05fdaa48940551bac81d700f5fca7147295e386e8120d66742ec65c6ee8d89a92217a0f6266d0ddc60bb20ef679ae8299c8502c2f":"6bc1379d156559ddee2ed420ea5d5c5ff3e454a1059b7ba72c350e77b6e9333c"
-
-HMAC-SHA-512 Test Vector NIST CAVS #2
-depends_on:POLARSSL_SHA512_C
-sha512_hmac:32:"3b10b8fa718840d1dea8e9fc317476bcf55875fd":"f04f5b7073d7d0274e8354433b390306c5607632f5f589c12edb62d55673aff2366d2e6b24de731adf92e654baa30b1cfd4a069788f65ec1b99b015d904d8832110dbd74eae35a81562d14ce4136d820ad0a55ff5489ba678fbbc1c27663ec1349d70e740f0e0ec27cfbe8971819f4789e486b50a2d7271d77e2aaea50de62fd":"fc3c38c7a17e3ce06db033f1c172866f01a00045db55f2e234f71c82264f2ba2"
-
-HMAC-SHA-512 Test Vector NIST CAVS #3
-depends_on:POLARSSL_SHA512_C
-sha512_hmac:32:"4803d311394600dc1e0d8fc8cedeb8bde3fe7c42":"a10c125dd702a97153ad923ba5e9889cfac1ba169de370debe51f233735aa6effcc9785c4b5c7e48c477dc5c411ae6a959118584e26adc94b42c2b29b046f3cf01c65b24a24bd2e620bdf650a23bb4a72655b1100d7ce9a4dab697c6379754b4396c825de4b9eb73f2e6a6c0d0353bbdeaf706612800e137b858fdb30f3311c6":"7cd8236c55102e6385f52279506df6fcc388ab75092da21395ce14a82b202ffa"
-
-HMAC-SHA-512 Test Vector NIST CAVS #4
-depends_on:POLARSSL_SHA512_C
-sha512_hmac:48:"aeb2f3b977fa6c8e71e07c5a5c74ff58166de092":"22457355dc76095abd46846b41cfe49a06ce42ac8857b4702fc771508dfb3626e0bfe851df897a07b36811ec433766e4b4166c26301b3493e7440d4554b0ef6ac20f1a530e58fac8aeba4e9ff2d4898d8a28783b49cd269c2965fd7f8e4f2d60cf1e5284f2495145b72382aad90e153a90ecae125ad75336fb128825c23fb8b0":"fa39bd8fcc3bfa218f9dea5d3b2ce10a7619e31678a56d8a9d927b1fe703b125af445debe9a89a07db6194d27b44d85a"
-
-HMAC-SHA-512 Test Vector NIST CAVS #5
-depends_on:POLARSSL_SHA512_C
-sha512_hmac:48:"4285d3d7744da52775bb44ca436a3154f7980309":"208f0b6f2de2e5aa5df11927ddc6df485edc1193181c484d0f0a434a95418803101d4de9fdb798f93516a6916fa38a8207de1666fe50fe3441c03b112eaaae6954ed063f7ac4e3c1e3f73b20d153fe9e4857f5e91430f0a70ee820529adac2467469fd18adf10e2af0fea27c0abc83c5a9af77c364a466cffce8bab4e2b70bc1":"fe7603f205b2774fe0f14ecfa3e338e90608a806d11ca459dff5ce36b1b264ecd3af5f0492a7521d8da3102ba20927a5"
-
-HMAC-SHA-512 Test Vector NIST CAVS #6
-depends_on:POLARSSL_SHA512_C
-sha512_hmac:48:"8ab783d5acf32efa0d9c0a21abce955e96630d89":"17371e013dce839963d54418e97be4bd9fa3cb2a368a5220f5aa1b8aaddfa3bdefc91afe7c717244fd2fb640f5cb9d9bf3e25f7f0c8bc758883b89dcdce6d749d9672fed222277ece3e84b3ec01b96f70c125fcb3cbee6d19b8ef0873f915f173bdb05d81629ba187cc8ac1934b2f75952fb7616ae6bd812946df694bd2763af":"9ac7ca8d1aefc166b046e4cf7602ebe181a0e5055474bff5b342106731da0d7e48e4d87bc0a6f05871574289a1b099f8"
diff --git a/tests/suites/test_suite_hmac_shax.function b/tests/suites/test_suite_hmac_shax.function
deleted file mode 100644
index 761c281..0000000
--- a/tests/suites/test_suite_hmac_shax.function
+++ /dev/null
@@ -1,300 +0,0 @@
-/* BEGIN_HEADER */
-#include "mbedtls/sha1.h"
-#include "mbedtls/sha256.h"
-#include "mbedtls/sha512.h"
-/* END_HEADER */
-
-/* BEGIN_CASE depends_on:POLARSSL_SHA1_C */
-void sha1_hmac( int trunc_size, char *hex_key_string, char *hex_src_string,
-                char *hex_hash_string)
-{
-    unsigned char src_str[10000];
-    unsigned char key_str[10000];
-    unsigned char hash_str[41];
-    unsigned char output[20];
-    int key_len, src_len;
-    sha1_context ctx;
-
-    memset(src_str, 0x00, sizeof src_str);
-    memset(key_str, 0x00, sizeof key_str);
-    sha1_init( &ctx );
-
-    key_len = unhexify( key_str, hex_key_string );
-    src_len = unhexify( src_str, hex_src_string );
-
-    /* Test the all-in-one interface */
-    memset(hash_str, 0x00, sizeof hash_str);
-    memset(output, 0x00, sizeof output);
-
-    sha1_hmac( key_str, key_len, src_str, src_len, output );
-
-    hexify( hash_str, output, sizeof output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Also test the "streaming" interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-    memset( &ctx, 0x00, sizeof ctx );
-
-    sha1_hmac_starts( &ctx, key_str, key_len );
-    sha1_hmac_update( &ctx, src_str, 0 );
-    sha1_hmac_update( &ctx, src_str, src_len / 2 );
-    sha1_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    sha1_hmac_update( &ctx, src_str + src_len, 0 );
-    sha1_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Again, to test hmac_reset() */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    sha1_hmac_reset( &ctx );
-    sha1_hmac_update( &ctx, src_str, src_len / 2 );
-    sha1_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    sha1_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-exit:
-    sha1_free( &ctx );
-}
-/* END_CASE */
-
-/* BEGIN_CASE depends_on:POLARSSL_SHA256_C */
-void sha224_hmac( int trunc_size, char *hex_key_string, char *hex_src_string,
-                  char *hex_hash_string)
-{
-    unsigned char src_str[10000];
-    unsigned char key_str[10000];
-    unsigned char hash_str[57];
-    unsigned char output[28];
-    int key_len, src_len;
-    sha256_context ctx;
-
-    memset(src_str, 0x00, sizeof src_str);
-    memset(key_str, 0x00, sizeof key_str);
-    sha256_init( &ctx );
-
-    key_len = unhexify( key_str, hex_key_string );
-    src_len = unhexify( src_str, hex_src_string );
-
-    /* Test the all-in-one interface */
-    memset(hash_str, 0x00, sizeof hash_str);
-    memset(output, 0x00, sizeof output);
-
-    sha256_hmac( key_str, key_len, src_str, src_len, output, 1 );
-
-    hexify( hash_str, output, sizeof output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Also test the "streaming" interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-    memset( &ctx, 0x00, sizeof ctx );
-
-    sha256_hmac_starts( &ctx, key_str, key_len, 1 );
-    sha256_hmac_update( &ctx, src_str, 0 );
-    sha256_hmac_update( &ctx, src_str, src_len / 2 );
-    sha256_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    sha256_hmac_update( &ctx, src_str + src_len, 0 );
-    sha256_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Again, to test hmac_reset() */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    sha256_hmac_reset( &ctx );
-    sha256_hmac_update( &ctx, src_str, src_len / 2 );
-    sha256_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    sha256_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-exit:
-    sha256_free( &ctx );
-}
-/* END_CASE */
-
-/* BEGIN_CASE depends_on:POLARSSL_SHA256_C */
-void sha256_hmac( int trunc_size, char *hex_key_string, char *hex_src_string,
-                  char *hex_hash_string)
-{
-    unsigned char src_str[10000];
-    unsigned char key_str[10000];
-    unsigned char hash_str[65];
-    unsigned char output[32];
-    int key_len, src_len;
-    sha256_context ctx;
-
-    memset(src_str, 0x00, sizeof src_str);
-    memset(key_str, 0x00, sizeof key_str);
-    sha256_init( &ctx );
-
-    key_len = unhexify( key_str, hex_key_string );
-    src_len = unhexify( src_str, hex_src_string );
-
-    /* Test the all-in-one interface */
-    memset(hash_str, 0x00, sizeof hash_str);
-    memset(output, 0x00, sizeof output);
-
-    sha256_hmac( key_str, key_len, src_str, src_len, output, 0 );
-
-    hexify( hash_str, output, sizeof output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Also test the "streaming" interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-    memset( &ctx, 0x00, sizeof ctx );
-
-    sha256_hmac_starts( &ctx, key_str, key_len, 0 );
-    sha256_hmac_update( &ctx, src_str, 0 );
-    sha256_hmac_update( &ctx, src_str, src_len / 2 );
-    sha256_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    sha256_hmac_update( &ctx, src_str + src_len, 0 );
-    sha256_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Again, to test hmac_reset() */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    sha256_hmac_reset( &ctx );
-    sha256_hmac_update( &ctx, src_str, src_len / 2 );
-    sha256_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    sha256_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-exit:
-    sha256_free( &ctx );
-}
-/* END_CASE */
-
-/* BEGIN_CASE depends_on:POLARSSL_SHA512_C */
-void sha384_hmac( int trunc_size, char *hex_key_string, char *hex_src_string,
-                  char *hex_hash_string)
-{
-    unsigned char src_str[10000];
-    unsigned char key_str[10000];
-    unsigned char hash_str[97];
-    unsigned char output[48];
-    int key_len, src_len;
-    sha512_context ctx;
-
-    memset(src_str, 0x00, sizeof src_str);
-    memset(key_str, 0x00, sizeof key_str);
-    sha512_init( &ctx );
-
-    key_len = unhexify( key_str, hex_key_string );
-    src_len = unhexify( src_str, hex_src_string );
-
-    /* Test the all-in-one interface */
-    memset(hash_str, 0x00, sizeof hash_str);
-    memset(output, 0x00, sizeof output);
-
-    sha512_hmac( key_str, key_len, src_str, src_len, output, 1 );
-
-    hexify( hash_str, output, sizeof output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Also test the "streaming" interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-    memset( &ctx, 0x00, sizeof ctx );
-
-    sha512_hmac_starts( &ctx, key_str, key_len, 1 );
-    sha512_hmac_update( &ctx, src_str, 0 );
-    sha512_hmac_update( &ctx, src_str, src_len / 2 );
-    sha512_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    sha512_hmac_update( &ctx, src_str + src_len, 0 );
-    sha512_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Again, to test hmac_reset() */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    sha512_hmac_reset( &ctx );
-    sha512_hmac_update( &ctx, src_str, src_len / 2 );
-    sha512_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    sha512_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-exit:
-    sha512_free( &ctx );
-}
-/* END_CASE */
-
-/* BEGIN_CASE depends_on:POLARSSL_SHA512_C */
-void sha512_hmac( int trunc_size, char *hex_key_string, char *hex_src_string,
-                  char *hex_hash_string)
-{
-    unsigned char src_str[10000];
-    unsigned char key_str[10000];
-    unsigned char hash_str[129];
-    unsigned char output[64];
-    int key_len, src_len;
-    sha512_context ctx;
-
-    memset(src_str, 0x00, sizeof src_str);
-    memset(key_str, 0x00, sizeof key_str);
-    sha512_init( &ctx );
-
-    key_len = unhexify( key_str, hex_key_string );
-    src_len = unhexify( src_str, hex_src_string );
-
-    /* Test the all-in-one interface */
-    memset(hash_str, 0x00, sizeof hash_str);
-    memset(output, 0x00, sizeof output);
-
-    sha512_hmac( key_str, key_len, src_str, src_len, output, 0 );
-
-    hexify( hash_str, output, sizeof output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Also test the "streaming" interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-    memset( &ctx, 0x00, sizeof ctx );
-
-    sha512_hmac_starts( &ctx, key_str, key_len, 0 );
-    sha512_hmac_update( &ctx, src_str, 0 );
-    sha512_hmac_update( &ctx, src_str, src_len / 2 );
-    sha512_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    sha512_hmac_update( &ctx, src_str + src_len, 0 );
-    sha512_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Again, to test hmac_reset() */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    sha512_hmac_reset( &ctx );
-    sha512_hmac_update( &ctx, src_str, src_len / 2 );
-    sha512_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    sha512_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-exit:
-    sha512_free( &ctx );
-}
-/* END_CASE */
diff --git a/tests/suites/test_suite_md.data b/tests/suites/test_suite_md.data
index 85be7df..b028b67 100644
--- a/tests/suites/test_suite_md.data
+++ b/tests/suites/test_suite_md.data
@@ -192,6 +192,18 @@
 depends_on:POLARSSL_MD5_C
 md_hmac:"md5":16:"61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161":"b91ce5ac77d33c234e61002ed6":"e97f623936f98a7f741c4bd0612fecc2"
 
+HMAC-MD2 Bouncy Castle test #1
+depends_on:POLARSSL_MD2_C
+md_hmac:"md2":16:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"dc1923ef5f161d35bef839ca8c807808"
+
+HMAC-MD4 Bouncy Castle test #1
+depends_on:POLARSSL_MD4_C
+md_hmac:"md4":16:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"5570ce964ba8c11756cdc3970278ff5a"
+
+HMAC-MD5 Bouncy Castle test #1
+depends_on:POLARSSL_MD5_C
+md_hmac:"md5":16:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"5ccec34ea9656392457fa1ac27f08fbc"
+
 generic HMAC-MD5 Test Vector RFC2202 #1
 depends_on:POLARSSL_MD5_C
 md_hmac:"md5":16:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"9294727a3638bb1c13f48ef8158bfc9d"
diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function
index 98dac47..fc17ba9 100644
--- a/tests/suites/test_suite_md.function
+++ b/tests/suites/test_suite_md.function
@@ -29,7 +29,7 @@
     {
         info = md_info_from_type( *md_type_ptr );
         TEST_ASSERT( info != NULL );
-        TEST_ASSERT( md_init_ctx( &ctx, info ) == 0 );
+        TEST_ASSERT( md_setup( &ctx, info, 0 ) == 0 );
         TEST_ASSERT( md_process( &ctx, buf ) == 0 );
         md_free( &ctx );
     }
@@ -49,13 +49,13 @@
     md_init( &ctx );
 
     TEST_ASSERT( md_get_size( NULL ) == 0 );
-
     TEST_ASSERT( md_get_type( NULL ) == POLARSSL_MD_NONE );
+    TEST_ASSERT( md_get_name( NULL ) == NULL );
 
     TEST_ASSERT( md_info_from_string( NULL ) == NULL );
 
-    TEST_ASSERT( md_init_ctx( &ctx, NULL ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
-    TEST_ASSERT( md_init_ctx( NULL, info ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_setup( &ctx, NULL, 0 ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+    TEST_ASSERT( md_setup( NULL, info, 0 ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
 
     TEST_ASSERT( md_starts( NULL ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
     TEST_ASSERT( md_starts( &ctx ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
@@ -93,6 +93,10 @@
 
     TEST_ASSERT( md_process( NULL, buf ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
     TEST_ASSERT( md_process( &ctx, buf ) == POLARSSL_ERR_MD_BAD_INPUT_DATA );
+
+    /* Ok, this is not NULL arg but NULL return... */
+    TEST_ASSERT( md_info_from_type( POLARSSL_MD_NONE ) == NULL );
+    TEST_ASSERT( md_info_from_string( "no such md" ) == NULL );
 }
 /* END_CASE */
 
@@ -109,6 +113,7 @@
 
     TEST_ASSERT( md_get_type( md_info ) == (md_type_t) md_type );
     TEST_ASSERT( md_get_size( md_info ) == (unsigned char) md_size );
+    TEST_ASSERT( strcmp( md_get_name( md_info ), md_name ) == 0 );
 
     found = 0;
     for( md_type_ptr = md_list(); *md_type_ptr != 0; md_type_ptr++ )
@@ -195,7 +200,7 @@
     strncpy( (char *) md_name, text_md_name, sizeof(md_name) - 1 );
     md_info = md_info_from_string(md_name);
     TEST_ASSERT( md_info != NULL );
-    TEST_ASSERT ( 0 == md_init_ctx( &ctx, md_info ) );
+    TEST_ASSERT ( 0 == md_setup( &ctx, md_info, 0 ) );
 
     TEST_ASSERT ( 0 == md_starts( &ctx ) );
     TEST_ASSERT ( ctx.md_ctx != NULL );
@@ -233,7 +238,7 @@
     strncpy( (char *) md_name, text_md_name, sizeof(md_name) - 1 );
     md_info = md_info_from_string(md_name);
     TEST_ASSERT( md_info != NULL );
-    TEST_ASSERT ( 0 == md_init_ctx( &ctx, md_info ) );
+    TEST_ASSERT ( 0 == md_setup( &ctx, md_info, 0 ) );
 
     src_len = unhexify( src_str, hex_src_string );
 
@@ -307,7 +312,7 @@
     strncpy( (char *) md_name, text_md_name, sizeof(md_name) - 1 );
     md_info = md_info_from_string( md_name );
     TEST_ASSERT( md_info != NULL );
-    TEST_ASSERT ( 0 == md_init_ctx( &ctx, md_info ) );
+    TEST_ASSERT ( 0 == md_setup( &ctx, md_info, 1 ) );
 
     key_len = unhexify( key_str, hex_key_string );
     src_len = unhexify( src_str, hex_src_string );
diff --git a/tests/suites/test_suite_mdx.data b/tests/suites/test_suite_mdx.data
index b815bd6..c97c851 100644
--- a/tests/suites/test_suite_mdx.data
+++ b/tests/suites/test_suite_mdx.data
@@ -85,84 +85,6 @@
 ripemd160 Test vector from paper #8
 ripemd160_text:"12345678901234567890123456789012345678901234567890123456789012345678901234567890":"9b752e45573d4b39f4dbd3323cab82bf63326bfb"
 
-HMAC-MD2 Hash File OpenSSL test #1
-md2_hmac:16:"61616161616161616161616161616161":"b91ce5ac77d33c234e61002ed6":"d5732582f494f5ddf35efd166c85af9c"
-
-HMAC-MD2 Hash File OpenSSL test #2
-md2_hmac:16:"61616161616161616161616161616161":"270fcf11f27c27448457d7049a7edb084a3e554e0b2acf5806982213f0ad516402e4c869c4ff2171e18e3489baa3125d2c3056ebb616296f9b6aa97ef68eeabcdc0b6dde47775004096a241efcf0a90d19b34e898cc7340cdc940f8bdd46e23e352f34bca131d4d67a7c2ddb8d0d68b67f06152a128168e1c341c37e0a66c5018999b7059bcc300beed2c19dd1152d2fe062853293b8f3c8b5":"54ab68503f7d1b5c7741340dff2722a9"
-
-HMAC-MD2 Hash File OpenSSL test #3
-md2_hmac:16:"61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161":"b91ce5ac77d33c234e61002ed6":"d850e5f554558cf0fe79a0612e1d0365"
-
-HMAC-MD4 Hash File OpenSSL test #1
-md4_hmac:16:"61616161616161616161616161616161":"b91ce5ac77d33c234e61002ed6":"eabd0fbefb82fb0063a25a6d7b8bdc0f"
-
-HMAC-MD4 Hash File OpenSSL test #2
-md4_hmac:16:"61616161616161616161616161616161":"270fcf11f27c27448457d7049a7edb084a3e554e0b2acf5806982213f0ad516402e4c869c4ff2171e18e3489baa3125d2c3056ebb616296f9b6aa97ef68eeabcdc0b6dde47775004096a241efcf0a90d19b34e898cc7340cdc940f8bdd46e23e352f34bca131d4d67a7c2ddb8d0d68b67f06152a128168e1c341c37e0a66c5018999b7059bcc300beed2c19dd1152d2fe062853293b8f3c8b5":"cec3c5e421a7b783aa89cacf78daf6dc"
-
-HMAC-MD4 Hash File OpenSSL test #3
-md4_hmac:16:"61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161":"b91ce5ac77d33c234e61002ed6":"ad5f0a04116109b397b57f9cc9b6df4b"
-
-HMAC-MD5 Hash File OpenSSL test #1
-md5_hmac:16:"61616161616161616161616161616161":"b91ce5ac77d33c234e61002ed6":"42552882f00bd4633ea81135a184b284"
-
-HMAC-MD5 Hash File OpenSSL test #2
-md5_hmac:16:"61616161616161616161616161616161":"270fcf11f27c27448457d7049a7edb084a3e554e0b2acf5806982213f0ad516402e4c869c4ff2171e18e3489baa3125d2c3056ebb616296f9b6aa97ef68eeabcdc0b6dde47775004096a241efcf0a90d19b34e898cc7340cdc940f8bdd46e23e352f34bca131d4d67a7c2ddb8d0d68b67f06152a128168e1c341c37e0a66c5018999b7059bcc300beed2c19dd1152d2fe062853293b8f3c8b5":"a16a842891786d01fe50ba7731db7464"
-
-HMAC-MD5 Hash File OpenSSL test #3
-md5_hmac:16:"61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161":"b91ce5ac77d33c234e61002ed6":"e97f623936f98a7f741c4bd0612fecc2"
-
-HMAC-MD5 Test Vector RFC2202 #1
-md5_hmac:16:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"9294727a3638bb1c13f48ef8158bfc9d"
-
-HMAC-MD5 Test Vector RFC2202 #2
-md5_hmac:16:"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"750c783e6ab0b503eaa86e310a5db738"
-
-HMAC-MD5 Test Vector RFC2202 #3
-md5_hmac:16:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"56be34521d144c88dbb8c733f0e8b3f6"
-
-HMAC-MD5 Test Vector RFC2202 #4
-md5_hmac:16:"0102030405060708090a0b0c0d0e0f10111213141516171819":"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"697eaf0aca3a3aea3a75164746ffaa79"
-
-HMAC-MD5 Test Vector RFC2202 #5
-md5_hmac:12:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"546573742057697468205472756e636174696f6e":"56461ef2342edc00f9bab995"
-
-HMAC-MD5 Test Vector RFC2202 #6
-md5_hmac:16:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"
-
-HMAC-MD5 Test Vector RFC2202 #7
-md5_hmac:16:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b657920616e64204c6172676572205468616e204f6e6520426c6f636b2d53697a652044617461":"6f630fad67cda0ee1fb1f562db3aa53e"
-
-HMAC-MD2 Bouncy Castle test #1
-md2_hmac:16:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"dc1923ef5f161d35bef839ca8c807808"
-
-HMAC-MD4 Bouncy Castle test #1
-md4_hmac:16:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"5570ce964ba8c11756cdc3970278ff5a"
-
-HMAC-MD5 Bouncy Castle test #1
-md5_hmac:16:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"5ccec34ea9656392457fa1ac27f08fbc"
-
-HMAC-RIPEMD160 Test vector RFC 2286 #1
-ripemd160_hmac:20:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"4869205468657265":"24cb4bd67d20fc1a5d2ed7732dcc39377f0a5668"
-
-HMAC-RIPEMD160 Test vector RFC 2286 #2
-ripemd160_hmac:20:"4a656665":"7768617420646f2079612077616e7420666f72206e6f7468696e673f":"dda6c0213a485a9e24f4742064a7f033b43c4069"
-
-HMAC-RIPEMD160 Test vector RFC 2286 #3
-ripemd160_hmac:20:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd":"b0b105360de759960ab4f35298e116e295d8e7c1"
-
-HMAC-RIPEMD160 Test vector RFC 2286 #4
-ripemd160_hmac:20:"0102030405060708090a0b0c0d0e0f10111213141516171819":"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd":"d5ca862f4d21d5e610e18b4cf1beb97a4365ecf4"
-
-HMAC-RIPEMD160 Test vector RFC 2286 #5
-ripemd160_hmac:20:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":"546573742057697468205472756e636174696f6e":"7619693978f91d90539ae786500ff3d8e0518e39"
-
-HMAC-RIPEMD160 Test vector RFC 2286 #6
-ripemd160_hmac:20:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374":"6466ca07ac5eac29e1bd523e5ada7605b791fd8b"
-
-HMAC-RIPEMD160 Test vector RFC 2286 #7
-ripemd160_hmac:20:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b657920616e64204c6172676572205468616e204f6e6520426c6f636b2d53697a652044617461":"69ea60798d71616cce5fd0871e23754cd75d5a0a"
-
 MD2 Hash file #1
 md2_file:"data_files/hash_file_1":"b593c098712d2e21628c8986695451a8"
 
diff --git a/tests/suites/test_suite_mdx.function b/tests/suites/test_suite_mdx.function
index 4615271..35d0874 100644
--- a/tests/suites/test_suite_mdx.function
+++ b/tests/suites/test_suite_mdx.function
@@ -85,242 +85,6 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:POLARSSL_MD2_C */
-void md2_hmac( int trunc_size, char *hex_key_string, char *hex_src_string,
-               char *hex_hash_string )
-{
-    unsigned char src_str[200];
-    unsigned char key_str[200];
-    unsigned char hash_str[33];
-    unsigned char output[16];
-    int key_len, src_len;
-    md2_context ctx;
-
-    memset( src_str, 0x00, sizeof src_str );
-    memset( key_str, 0x00, sizeof key_str );
-    md2_init( &ctx );
-
-    key_len = unhexify( key_str, hex_key_string );
-    src_len = unhexify( src_str, hex_src_string );
-
-    /* Test the all-in-one interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    md2_hmac( key_str, key_len, src_str, src_len, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Also test the "streaming" interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-    memset( &ctx, 0x00, sizeof ctx );
-
-    md2_hmac_starts( &ctx, key_str, key_len );
-    md2_hmac_update( &ctx, src_str, 0 );
-    md2_hmac_update( &ctx, src_str, src_len / 2 );
-    md2_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    md2_hmac_update( &ctx, src_str + src_len, 0 );
-    md2_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Again, to test hmac_reset() */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    md2_hmac_reset( &ctx );
-    md2_hmac_update( &ctx, src_str, src_len / 2 );
-    md2_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    md2_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-exit:
-    md2_free( &ctx );
-}
-/* END_CASE */
-
-/* BEGIN_CASE depends_on:POLARSSL_MD4_C */
-void md4_hmac( int trunc_size, char *hex_key_string, char *hex_src_string,
-               char *hex_hash_string )
-{
-    unsigned char src_str[200];
-    unsigned char key_str[200];
-    unsigned char hash_str[33];
-    unsigned char output[16];
-    int key_len, src_len;
-    md4_context ctx;
-
-    memset( src_str, 0x00, sizeof src_str );
-    memset( key_str, 0x00, sizeof key_str );
-    md4_init( &ctx );
-
-    key_len = unhexify( key_str, hex_key_string );
-    src_len = unhexify( src_str, hex_src_string );
-
-    /* Test the all-in-one interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    md4_hmac( key_str, key_len, src_str, src_len, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Also test the "streaming" interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-    memset( &ctx, 0x00, sizeof ctx );
-
-    md4_hmac_starts( &ctx, key_str, key_len );
-    md4_hmac_update( &ctx, src_str, 0 );
-    md4_hmac_update( &ctx, src_str, src_len / 2 );
-    md4_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    md4_hmac_update( &ctx, src_str + src_len, 0 );
-    md4_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Again, to test hmac_reset() */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    md4_hmac_reset( &ctx );
-    md4_hmac_update( &ctx, src_str, src_len / 2 );
-    md4_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    md4_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-exit:
-    md4_free( &ctx );
-}
-/* END_CASE */
-
-/* BEGIN_CASE depends_on:POLARSSL_MD5_C */
-void md5_hmac( int trunc_size, char *hex_key_string, char *hex_src_string,
-               char *hex_hash_string )
-{
-    unsigned char src_str[200];
-    unsigned char key_str[200];
-    unsigned char hash_str[33];
-    unsigned char output[16];
-    int key_len, src_len;
-    md5_context ctx;
-
-    memset( src_str, 0x00, sizeof src_str );
-    memset( key_str, 0x00, sizeof key_str );
-    md5_init( &ctx );
-
-    key_len = unhexify( key_str, hex_key_string );
-    src_len = unhexify( src_str, hex_src_string );
-
-    /* Test the all-in-one interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    md5_hmac( key_str, key_len, src_str, src_len, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Also test the "streaming" interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-    memset( &ctx, 0x00, sizeof ctx );
-
-    md5_hmac_starts( &ctx, key_str, key_len );
-    md5_hmac_update( &ctx, src_str, 0 );
-    md5_hmac_update( &ctx, src_str, src_len / 2 );
-    md5_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    md5_hmac_update( &ctx, src_str + src_len, 0 );
-    md5_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Again, to test hmac_reset() */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    md5_hmac_reset( &ctx );
-    md5_hmac_update( &ctx, src_str, src_len / 2 );
-    md5_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    md5_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-exit:
-    md5_free( &ctx );
-}
-/* END_CASE */
-
-/* BEGIN_CASE depends_on:POLARSSL_RIPEMD160_C */
-void ripemd160_hmac( int trunc_size, char *hex_key_string, char *hex_src_string,
-                     char *hex_hash_string )
-{
-    unsigned char src_str[200];
-    unsigned char key_str[200];
-    unsigned char hash_str[41];
-    unsigned char output[20];
-    int key_len, src_len;
-    ripemd160_context ctx;
-
-    memset( src_str, 0x00, sizeof src_str );
-    memset( key_str, 0x00, sizeof key_str );
-    ripemd160_init( &ctx );
-
-    key_len = unhexify( key_str, hex_key_string );
-    src_len = unhexify( src_str, hex_src_string );
-
-    /* Test the all-in-one interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    ripemd160_hmac( key_str, key_len, src_str, src_len, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Also test the "streaming" interface */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-    memset( &ctx, 0x00, sizeof ctx );
-
-    ripemd160_hmac_starts( &ctx, key_str, key_len );
-    ripemd160_hmac_update( &ctx, src_str, 0 );
-    ripemd160_hmac_update( &ctx, src_str, src_len / 2 );
-    ripemd160_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    ripemd160_hmac_update( &ctx, src_str + src_len, 0 );
-    ripemd160_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-    /* Again, to test hmac_reset() */
-    memset( hash_str, 0x00, sizeof hash_str );
-    memset( output, 0x00, sizeof output );
-
-    ripemd160_hmac_reset( &ctx );
-    ripemd160_hmac_update( &ctx, src_str, src_len / 2 );
-    ripemd160_hmac_update( &ctx, src_str + src_len / 2, src_len - src_len / 2 );
-    ripemd160_hmac_finish( &ctx, output );
-
-    hexify( hash_str, output, sizeof  output );
-    TEST_ASSERT( strncmp( (char *) hash_str, hex_hash_string, trunc_size * 2 ) == 0 );
-
-exit:
-    ripemd160_free( &ctx );
-}
-/* END_CASE */
-
 /* BEGIN_CASE depends_on:POLARSSL_MD2_C:POLARSSL_FS_IO */
 void md2_file( char *filename, char *hex_hash_string )
 {
diff --git a/tests/suites/test_suite_pkcs5.function b/tests/suites/test_suite_pkcs5.function
index 6074e04..7251e04 100644
--- a/tests/suites/test_suite_pkcs5.function
+++ b/tests/suites/test_suite_pkcs5.function
@@ -36,7 +36,7 @@
     TEST_ASSERT( info != NULL );
     if( info == NULL )
         return;
-    TEST_ASSERT( md_init_ctx( &ctx, info ) == 0 );
+    TEST_ASSERT( md_setup( &ctx, info, 1 ) == 0 );
     TEST_ASSERT( pkcs5_pbkdf2_hmac( &ctx, pw_str, pw_len, salt_str, salt_len,
                                      it_cnt, key_len, key ) == 0 );