Add additional parameter validation tests for the AES module

This adds additional tests to validate the AES module parameter validation
checks which are enabled using the MBEDTLS_CHECK_PARAMS option.
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 32b1b79..4c105ed 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -23,6 +23,11 @@
 #include "mbedtls/memory_buffer_alloc.h"
 #endif
 
+#if defined(MBEDTLS_CHECK_PARAMS)
+#include <setjmp.h>
+#define MBEDTLS_PARAM_FAILED(x)    mbedtls_param_failed( #x )
+#endif
+
 #ifdef _MSC_VER
 #include <basetsd.h>
 typedef UINT8 uint8_t;
@@ -69,15 +74,166 @@
 /*----------------------------------------------------------------------------*/
 /* Macros */
 
-#define TEST_ASSERT( TEST )                         \
-    do {                                            \
-        if( ! (TEST) )                              \
-        {                                           \
-            test_fail( #TEST, __LINE__, __FILE__ ); \
-            goto exit;                              \
-        }                                           \
+#if defined(MBEDTLS_CHECK_PARAMS)
+
+/**
+ * \brief   This macro tests the expression passed to it as a test step or
+ *          individual test in a test case.
+ *
+ *          It allows a library function to return a value and return an error
+ *          code that can be tested.
+ *
+ *          When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
+ *          callback, MBEDTLS_PARAM_FAIL, will be assumed to be a test failure.
+ *
+ *          This macro is not suitable for negative parameter validation tests,
+ *          as it assumes the test step will not create an error.
+ *
+ * \param   TEST    The test expression to be tested.
+ */
+#define TEST_ASSERT( TEST )                             \
+    do {                                                \
+        if ( setjmp( param_fail_jmp ) == 0 )            \
+        {                                               \
+            if( ! (TEST) )                              \
+            {                                           \
+                test_fail( #TEST, __LINE__, __FILE__ ); \
+                goto exit;                              \
+            }                                           \
+        }                                               \
+        else                                            \
+        {                                               \
+            test_fail( #TEST, __LINE__, __FILE__ );     \
+            goto exit;                                  \
+        }                                               \
+       memset( param_fail_jmp, 0, sizeof(jmp_buf) );    \
     } while( 0 )
 
+/**
+ * \brief   This macro tests and individual function call as a test step or
+ *          individual test in a test case.
+ *
+ *          It does not require a library function to return a value, and cannot
+            tets a return error code that can be tested.
+ *
+ *          When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
+ *          callback, MBEDTLS_PARAM_FAIL, will be assumed to be a test failure.
+ *
+ *          This macro is not suitable for negative parameter validation tests
+ *          as it assumes the test step will not create an error.
+ *
+ * \param   TEST    The test statement to be executed.
+ */
+#define TEST_FN( TEST )                                 \
+    do {                                                \
+        if ( setjmp( param_fail_jmp ) == 0 )            \
+        {                                               \
+            TEST;                                       \
+        }                                               \
+        else                                            \
+        {                                               \
+            test_fail( #TEST, __LINE__, __FILE__ );     \
+            goto exit;                                  \
+        }                                               \
+       memset( param_fail_jmp, 0, sizeof(jmp_buf) );    \
+    } while( 0 )
+
+/**
+ * \brief   This macro tests the statement passed to it as a test step or
+ *          individual test in a test case. The macro assumes the test will fail
+ *          and will generate an error.
+ *
+ *          It allows a library function to return a value and tests the return
+ *          code on return to confirm the given error code was returned.
+ *
+ *          When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
+ *          callback, MBEDTLS_PARAM_FAIL, are assumed to indicate the
+ *          expected failure, and the test will pass.
+ *
+ *          This macro is intended for negative parameter validation tests,
+ *          where the failing function may return an error value or call
+ *          MBEDTLS_PARAM_FAIL to indicate the error.
+ *
+ * \param   PARAM_ERROR_VALUE   The expected error code.
+ *
+ * \param   TEST                The test expression to be tested.
+ */
+#define TEST_INVALID_PARAM_RET( PARAM_ERR_VALUE, TEST ) \
+    do {                                                \
+        if ( setjmp( param_fail_jmp ) == 0 )            \
+        {                                               \
+            if( (TEST) != PARAM_ERR_VALUE)              \
+            {                                           \
+                test_fail( #TEST, __LINE__, __FILE__ ); \
+                goto exit;                              \
+            }                                           \
+       }                                                \
+       memset( param_fail_jmp, 0, sizeof(jmp_buf) );    \
+    } while( 0 )
+
+/**
+ * \brief   This macro tests the statement passed to it as a test step or
+ *          individual test in a test case. The macro assumes the test will fail
+ *          and will generate an error.
+ *
+ *          It assumes the library function under test cannot return a value and
+ *          assumes errors can only be indicated byt calls to
+ *          MBEDTLS_PARAM_FAIL.
+ *
+ *          When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
+ *          callback, MBEDTLS_PARAM_FAIL, are assumed to indicate the
+ *          expected failure. If MBEDTLS_CHECK_PARAMS is not enabled, no test
+ *          can be made.
+ *
+ *          This macro is intended for negative parameter validation tests,
+ *          where the failing function can only return an error by calling
+ *          MBEDTLS_PARAM_FAIL to indicate the error.
+ *
+ * \param   TEST                The test expression to be tested.
+ */
+#define TEST_INVALID_PARAM( TEST ) \
+    do {                                                \
+        if ( setjmp( param_fail_jmp ) == 0 )            \
+        {                                               \
+            TEST;                                       \
+            test_fail( #TEST, __LINE__, __FILE__ );     \
+            goto exit;                                  \
+       }                                                \
+       memset( param_fail_jmp, 0, sizeof(jmp_buf) );    \
+    } while( 0 )
+
+#else
+
+#define TEST_ASSERT( TEST )                             \
+    do {                                                \
+        if( ! (TEST) )                                  \
+        {                                               \
+            test_fail( #TEST, __LINE__, __FILE__ );     \
+            goto exit;                                  \
+        }                                               \
+    } while( 0 )
+
+#define TEST_FN( TEST )                                 \
+    do {                                                \
+            TEST;                                       \
+    } while( 0 )
+
+#define TEST_INVALID_PARAM_RET( PARAM_ERR_VALUE, TEST ) \
+    do {                                                \
+        if( (TEST) != (PARAM_ERR_VALUE) )               \
+        {                                               \
+            test_fail( #TEST, __LINE__, __FILE__ );     \
+            goto exit;                                  \
+        }                                               \
+   } while( 0 )
+
+#define TEST_INVALID_PARAM( TEST )     \
+    do {                                                \
+        TEST;                                           \
+    } while( 0 )
+
+#endif /* !defined( MBEDTLS_CHECK_PARAMS ) */
+
 #define assert(a) if( !( a ) )                                      \
 {                                                                   \
     mbedtls_fprintf( stderr, "Assertion Failed at %s:%d - %s\n",   \
@@ -126,6 +282,10 @@
 mbedtls_platform_context platform_ctx;
 #endif
 
+#if defined(MBEDTLS_CHECK_PARAMS)
+jmp_buf param_fail_jmp;
+#endif
+
 /*----------------------------------------------------------------------------*/
 /* Helper flags for complex dependencies */
 
@@ -159,6 +319,17 @@
 #endif /* MBEDTLS_PLATFORM_C */
 }
 
+#if defined(MBEDTLS_CHECK_PARAMS)
+void mbedtls_param_failed( char* failure_condition, char* file, int line )
+{
+    (void)failure_condition;
+    (void)file;
+    (void)line;
+
+    longjmp( param_fail_jmp, 1 );
+}
+#endif
+
 #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
 static int redirect_output( FILE** out_stream, const char* path )
 {
diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function
index a797e69..24b5e4d 100644
--- a/tests/suites/test_suite_aes.function
+++ b/tests/suites/test_suite_aes.function
@@ -15,8 +15,8 @@
     mbedtls_aes_context ctx;
 
     memset(output, 0x00, 100);
-    mbedtls_aes_init( &ctx );
 
+    TEST_FN( mbedtls_aes_init( &ctx ) );
 
     TEST_ASSERT( mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 ) == setkey_result );
     if( setkey_result == 0 )
@@ -39,8 +39,8 @@
     mbedtls_aes_context ctx;
 
     memset(output, 0x00, 100);
-    mbedtls_aes_init( &ctx );
 
+    TEST_FN( mbedtls_aes_init( &ctx ) );
 
     TEST_ASSERT( mbedtls_aes_setkey_dec( &ctx, key_str->x, key_str->len * 8 ) == setkey_result );
     if( setkey_result == 0 )
@@ -64,8 +64,8 @@
     mbedtls_aes_context ctx;
 
     memset(output, 0x00, 100);
-    mbedtls_aes_init( &ctx );
 
+    TEST_FN( mbedtls_aes_init( &ctx ) );
 
     mbedtls_aes_setkey_enc( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cbc( &ctx, MBEDTLS_AES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
@@ -91,7 +91,6 @@
     memset(output, 0x00, 100);
     mbedtls_aes_init( &ctx );
 
-
     mbedtls_aes_setkey_dec( &ctx, key_str->x, key_str->len * 8 );
     TEST_ASSERT( mbedtls_aes_crypt_cbc( &ctx, MBEDTLS_AES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
     if( cbc_result == 0)
@@ -372,6 +371,34 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void aes_invalid_param( )
+{
+    mbedtls_aes_context dummy_ctx;
+    const unsigned char key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+
+    TEST_INVALID_PARAM( mbedtls_aes_init( NULL ) );
+
+    /* mbedtls_aes_setkey_enc() */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_setkey_enc( NULL, key, 128 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_setkey_enc( &dummy_ctx, NULL, 128 ) );
+
+    /* mbedtls_aes_setkey_dec() */
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_setkey_dec( NULL, key, 128 ) );
+
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA,
+                            mbedtls_aes_setkey_dec( &dummy_ctx, NULL, 128 ) );
+
+
+exit:
+    return;
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
 void aes_selftest(  )
 {
diff --git a/tests/suites/test_suite_aes.rest.data b/tests/suites/test_suite_aes.rest.data
index bbb222f..3ec916d 100644
--- a/tests/suites/test_suite_aes.rest.data
+++ b/tests/suites/test_suite_aes.rest.data
@@ -10,6 +10,10 @@
 AES-256-CBC Decrypt (Invalid input length)
 aes_decrypt_cbc:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"623a52fcea5d443e48d9181ab32c74":"":MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
 
+AES - Invalid parameters
+depends_on:MBEDTLS_CHECK_PARAMS
+aes_invalid_param:
+
 AES Selftest
 depends_on:MBEDTLS_SELF_TEST
 aes_selftest: