Implement hmac in the MD layer
diff --git a/library/md.c b/library/md.c
index d8f6a96..5f09c84 100644
--- a/library/md.c
+++ b/library/md.c
@@ -269,10 +269,35 @@
 
 int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen )
 {
+    unsigned char sum[POLARSSL_MD_MAX_SIZE];
+    size_t i;
+
     if( ctx == NULL || ctx->md_info == 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;
+    }
+
+    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] );
+    }
+
+    polarssl_zeroize( sum, sizeof( sum ) );
+
+    ctx->md_info->starts_func( ctx->md_ctx );
+    ctx->md_info->update_func( ctx->md_ctx, ctx->ipad, ctx->md_info->block_size );
 
     return( 0 );
 }
@@ -282,17 +307,23 @@
     if( ctx == NULL || ctx->md_info == 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 )
 {
+    unsigned char tmp[POLARSSL_MD_MAX_SIZE];
+
     if( ctx == NULL || ctx->md_info == NULL )
         return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->hmac_finish_func( ctx->md_ctx, output );
+    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, 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 );
 }
@@ -302,7 +333,8 @@
     if( ctx == NULL || ctx->md_info == NULL )
         return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
 
-    ctx->md_info->hmac_reset_func( ctx->md_ctx );
+    ctx->md_info->starts_func( ctx->md_ctx );
+    ctx->md_info->update_func( ctx->md_ctx, ctx->ipad, ctx->md_info->block_size );
 
     return( 0 );
 }
@@ -311,10 +343,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_init_ctx( &ctx, md_info ) ) != 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 );
 }
diff --git a/library/md_wrap.c b/library/md_wrap.c
index fcc3102..603a4ac 100644
--- a/library/md_wrap.c
+++ b/library/md_wrap.c
@@ -148,6 +148,7 @@
     POLARSSL_MD_MD2,
     "MD2",
     16,
+    16,
     md2_starts_wrap,
     md2_update_wrap,
     md2_finish_wrap,
@@ -236,6 +237,7 @@
     POLARSSL_MD_MD4,
     "MD4",
     16,
+    64,
     md4_starts_wrap,
     md4_update_wrap,
     md4_finish_wrap,
@@ -324,6 +326,7 @@
     POLARSSL_MD_MD5,
     "MD5",
     16,
+    64,
     md5_starts_wrap,
     md5_update_wrap,
     md5_finish_wrap,
@@ -420,6 +423,7 @@
     POLARSSL_MD_RIPEMD160,
     "RIPEMD160",
     20,
+    64,
     ripemd160_starts_wrap,
     ripemd160_update_wrap,
     ripemd160_finish_wrap,
@@ -516,6 +520,7 @@
     POLARSSL_MD_SHA1,
     "SHA1",
     20,
+    64,
     sha1_starts_wrap,
     sha1_update_wrap,
     sha1_finish_wrap,
@@ -620,6 +625,7 @@
     POLARSSL_MD_SHA224,
     "SHA224",
     28,
+    64,
     sha224_starts_wrap,
     sha224_update_wrap,
     sha224_finish_wrap,
@@ -725,6 +731,7 @@
     POLARSSL_MD_SHA256,
     "SHA256",
     32,
+    64,
     sha256_starts_wrap,
     sha256_update_wrap,
     sha256_finish_wrap,
@@ -826,6 +833,7 @@
     POLARSSL_MD_SHA384,
     "SHA384",
     48,
+    128,
     sha384_starts_wrap,
     sha384_update_wrap,
     sha384_finish_wrap,
@@ -931,6 +939,7 @@
     POLARSSL_MD_SHA512,
     "SHA512",
     64,
+    128,
     sha512_starts_wrap,
     sha512_update_wrap,
     sha512_finish_wrap,