Add parameter validation to SHA-512 module
diff --git a/ChangeLog b/ChangeLog
index 66a8ce9..1c2614a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -41,6 +41,8 @@
      mbedtls_ctr_drbg_update() -> mbedtls_ctr_drbg_update_ret()
      mbedtls_hmac_drbg_update() -> mbedtls_hmac_drbg_update_ret()
    * Extend ECDH interface to enable alternative implementations.
+   * Add validation checks for input parameters to functions in the SHA-512
+     module.
 
 New deprecations
    * Deprecate mbedtls_ctr_drbg_update and mbedtls_hmac_drbg_update
diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
index 0c38889..851be1b 100644
--- a/include/mbedtls/error.h
+++ b/include/mbedtls/error.h
@@ -76,7 +76,7 @@
  * RIPEMD160 1                  0x0031-0x0031
  * SHA1      1                  0x0035-0x0035
  * SHA256    1                  0x0037-0x0037
- * SHA512    1                  0x0039-0x0039
+ * SHA512    1                  0x0039-0x0039 0x0075-0x0075
  * CHACHA20  3                  0x0051-0x0055
  * POLY1305  3                  0x0057-0x005B
  * CHACHAPOLY 2 0x0054-0x0056
diff --git a/include/mbedtls/sha512.h b/include/mbedtls/sha512.h
index 020f95d..257e8d4 100644
--- a/include/mbedtls/sha512.h
+++ b/include/mbedtls/sha512.h
@@ -37,6 +37,7 @@
 
 /* MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED is deprecated and should not be used. */
 #define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED                -0x0039  /**< SHA-512 hardware accelerator failed */
+#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA                 -0x0075  /**< Invalid input data. */
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/library/sha512.c b/library/sha512.c
index a9440e8..7a99170 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -88,8 +88,14 @@
 }
 #endif /* PUT_UINT64_BE */
 
+#define MBEDTLS_SHA512_VALIDATE_RET(cond)                           \
+    MBEDTLS_VALIDATE_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA, cond )
+#define MBEDTLS_SHA512_VALIDATE(cond)               MBEDTLS_VALIDATE( cond )
+
 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
 {
+    MBEDTLS_SHA512_VALIDATE( ctx != NULL );
+
     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
 }
 
@@ -104,6 +110,9 @@
 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
                            const mbedtls_sha512_context *src )
 {
+    MBEDTLS_SHA512_VALIDATE( dst != NULL );
+    MBEDTLS_SHA512_VALIDATE( src != NULL );
+
     *dst = *src;
 }
 
@@ -112,6 +121,8 @@
  */
 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
 {
+    MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
+
     ctx->total[0] = 0;
     ctx->total[1] = 0;
 
@@ -209,6 +220,9 @@
     uint64_t temp1, temp2, W[80];
     uint64_t A, B, C, D, E, F, G, H;
 
+    MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
+    MBEDTLS_SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
+
 #define  SHR(x,n) (x >> n)
 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
 
@@ -297,6 +311,9 @@
     if( ilen == 0 )
         return( 0 );
 
+    MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
+    MBEDTLS_SHA512_VALIDATE_RET( input != NULL );
+
     left = (unsigned int) (ctx->total[0] & 0x7F);
     fill = 128 - left;
 
@@ -351,6 +368,9 @@
     unsigned used;
     uint64_t high, low;
 
+    MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
+    MBEDTLS_SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
+
     /*
      * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
      */
@@ -427,6 +447,9 @@
     int ret;
     mbedtls_sha512_context ctx;
 
+    MBEDTLS_SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
+    MBEDTLS_SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
+
     mbedtls_sha512_init( &ctx );
 
     if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )