Added SHA3 to MD.

This enables HMAC with SHA3.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
diff --git a/library/md.c b/library/md.c
index f2c1a90..ca3b9a0 100644
--- a/library/md.c
+++ b/library/md.c
@@ -35,6 +35,9 @@
 #include "mbedtls/sha1.h"
 #include "mbedtls/sha256.h"
 #include "mbedtls/sha512.h"
+#if defined(MBEDTLS_SHA3_C)
+#include "mbedtls/sha3.h"
+#endif
 
 #if defined(MBEDTLS_PLATFORM_C)
 #include "mbedtls/platform.h"
@@ -113,11 +116,46 @@
 };
 #endif
 
+#if defined(MBEDTLS_SHA3_C)
+const mbedtls_md_info_t mbedtls_sha3_224_info = {
+    "SHA3-224",
+    MBEDTLS_MD_SHA3_224,
+    28,
+    144,
+};
+const mbedtls_md_info_t mbedtls_sha3_256_info = {
+    "SHA3-256",
+    MBEDTLS_MD_SHA3_256,
+    32,
+    136,
+};
+const mbedtls_md_info_t mbedtls_sha3_384_info = {
+    "SHA3-384",
+    MBEDTLS_MD_SHA3_384,
+    48,
+    104,
+};
+const mbedtls_md_info_t mbedtls_sha3_512_info = {
+    "SHA3-512",
+    MBEDTLS_MD_SHA3_512,
+    64,
+    72,
+};
+#endif
+
+
 /*
  * Reminder: update profiles in x509_crt.c when adding a new hash!
  */
 static const int supported_digests[] = {
 
+#if defined(MBEDTLS_SHA3_C)
+        MBEDTLS_MD_SHA3_512,
+        MBEDTLS_MD_SHA3_384,
+        MBEDTLS_MD_SHA3_256,
+        MBEDTLS_MD_SHA3_224,
+#endif
+
 #if defined(MBEDTLS_SHA512_C)
         MBEDTLS_MD_SHA512,
 #endif
@@ -187,6 +225,16 @@
     if( !strcmp( "SHA512", md_name ) )
         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
 #endif
+#if defined(MBEDTLS_SHA3_C)
+    if( !strcmp( "SHA3-224", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_SHA3_224 );
+    if( !strcmp( "SHA3-256", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_SHA3_256 );
+    if( !strcmp( "SHA3-384", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_SHA3_384 );
+    if( !strcmp( "SHA3-512", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_SHA3_512 );
+#endif
     return( NULL );
 }
 
@@ -222,6 +270,16 @@
         case MBEDTLS_MD_SHA512:
             return( &mbedtls_sha512_info );
 #endif
+#if defined(MBEDTLS_SHA3_C)
+        case MBEDTLS_MD_SHA3_224:
+            return( &mbedtls_sha3_224_info );
+        case MBEDTLS_MD_SHA3_256:
+            return( &mbedtls_sha3_256_info );
+        case MBEDTLS_MD_SHA3_384:
+            return( &mbedtls_sha3_384_info );
+        case MBEDTLS_MD_SHA3_512:
+            return( &mbedtls_sha3_512_info );
+#endif
         default:
             return( NULL );
     }
@@ -285,6 +343,14 @@
                 mbedtls_sha512_free( ctx->md_ctx );
                 break;
 #endif
+#if defined(MBEDTLS_SHA3_C)
+            case MBEDTLS_MD_SHA3_224:
+            case MBEDTLS_MD_SHA3_256:
+            case MBEDTLS_MD_SHA3_384:
+            case MBEDTLS_MD_SHA3_512:
+                mbedtls_sha3_free( ctx->md_ctx );
+                break;
+#endif
             default:
                 /* Shouldn't happen */
                 break;
@@ -349,6 +415,14 @@
             mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
             break;
 #endif
+#if defined(MBEDTLS_SHA3_C)
+        case MBEDTLS_MD_SHA3_224:
+        case MBEDTLS_MD_SHA3_256:
+        case MBEDTLS_MD_SHA3_384:
+        case MBEDTLS_MD_SHA3_512:
+            mbedtls_sha3_clone( dst->md_ctx, src->md_ctx );
+            break;
+#endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
     }
@@ -411,6 +485,14 @@
             ALLOC( sha512 );
             break;
 #endif
+#if defined(MBEDTLS_SHA3_C)
+        case MBEDTLS_MD_SHA3_224:
+        case MBEDTLS_MD_SHA3_256:
+        case MBEDTLS_MD_SHA3_384:
+        case MBEDTLS_MD_SHA3_512:
+            ALLOC( sha3 );
+            break;
+#endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
     }
@@ -464,6 +546,16 @@
         case MBEDTLS_MD_SHA512:
             return( mbedtls_sha512_starts( ctx->md_ctx, 0 ) );
 #endif
+#if defined(MBEDTLS_SHA3_C)
+        case MBEDTLS_MD_SHA3_224:
+            return( mbedtls_sha3_starts( ctx->md_ctx, MBEDTLS_SHA3_224 ) );
+        case MBEDTLS_MD_SHA3_256:
+            return( mbedtls_sha3_starts( ctx->md_ctx, MBEDTLS_SHA3_256 ) );
+        case MBEDTLS_MD_SHA3_384:
+            return( mbedtls_sha3_starts( ctx->md_ctx, MBEDTLS_SHA3_384 ) );
+        case MBEDTLS_MD_SHA3_512:
+            return( mbedtls_sha3_starts( ctx->md_ctx, MBEDTLS_SHA3_512 ) );
+#endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
     }
@@ -504,6 +596,13 @@
         case MBEDTLS_MD_SHA512:
             return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) );
 #endif
+#if defined(MBEDTLS_SHA3_C)
+        case MBEDTLS_MD_SHA3_224:
+        case MBEDTLS_MD_SHA3_256:
+        case MBEDTLS_MD_SHA3_384:
+        case MBEDTLS_MD_SHA3_512:
+            return( mbedtls_sha3_update( ctx->md_ctx, input, ilen ) );
+#endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
     }
@@ -544,6 +643,13 @@
         case MBEDTLS_MD_SHA512:
             return( mbedtls_sha512_finish( ctx->md_ctx, output ) );
 #endif
+#if defined(MBEDTLS_SHA3_C)
+        case MBEDTLS_MD_SHA3_224:
+        case MBEDTLS_MD_SHA3_256:
+        case MBEDTLS_MD_SHA3_384:
+        case MBEDTLS_MD_SHA3_512:
+            return( mbedtls_sha3_finish( ctx->md_ctx, output, ctx->md_info->size ) );
+#endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
     }
@@ -585,6 +691,16 @@
         case MBEDTLS_MD_SHA512:
             return( mbedtls_sha512( input, ilen, output, 0 ) );
 #endif
+#if defined(MBEDTLS_SHA3_C)
+        case MBEDTLS_MD_SHA3_224:
+            return( mbedtls_sha3( MBEDTLS_SHA3_224, input, ilen, output, md_info->size ) );
+        case MBEDTLS_MD_SHA3_256:
+            return( mbedtls_sha3( MBEDTLS_SHA3_256, input, ilen, output, md_info->size ) );
+        case MBEDTLS_MD_SHA3_384:
+            return( mbedtls_sha3( MBEDTLS_SHA3_384, input, ilen, output, md_info->size ) );
+        case MBEDTLS_MD_SHA3_512:
+            return( mbedtls_sha3( MBEDTLS_SHA3_512, input, ilen, output, md_info->size ) );
+#endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
     }
@@ -789,6 +905,15 @@
         case MBEDTLS_MD_SHA512:
             return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
 #endif
+#if defined(MBEDTLS_SHA3_C)
+        /* mbedtls_md_process() is used for test suite. Since, sha3.c does not
+           implement mbedtls_sha3_process(), we silently return 0 */
+        case MBEDTLS_MD_SHA3_224:
+        case MBEDTLS_MD_SHA3_256:
+        case MBEDTLS_MD_SHA3_384:
+        case MBEDTLS_MD_SHA3_512:
+            return( 0 );
+#endif
         default:
             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
     }
diff --git a/library/md_wrap.h b/library/md_wrap.h
index 90c7957..50a4093 100644
--- a/library/md_wrap.h
+++ b/library/md_wrap.h
@@ -74,6 +74,12 @@
 #if defined(MBEDTLS_SHA512_C)
 extern const mbedtls_md_info_t mbedtls_sha512_info;
 #endif
+#if defined(MBEDTLS_SHA3_C)
+extern const mbedtls_md_info_t mbedtls_sha3_224_info;
+extern const mbedtls_md_info_t mbedtls_sha3_256_info;
+extern const mbedtls_md_info_t mbedtls_sha3_384_info;
+extern const mbedtls_md_info_t mbedtls_sha3_512_info;
+#endif
 
 #ifdef __cplusplus
 }