psa: Disallow repeated setup

Calling psa_*_setup() twice on a MAC, cipher, or hash context should
result in a PSA_ERROR_BAD_STATE error because the operation has already
been set up.

Fixes #10
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 1f96ae0..40c676a 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1379,7 +1379,13 @@
                              psa_algorithm_t alg )
 {
     int ret;
-    operation->alg = 0;
+
+    /* A context must be freshly initialized before it can be set up. */
+    if( operation->alg != 0 )
+    {
+        return( PSA_ERROR_BAD_STATE );
+    }
+
     switch( alg )
     {
 #if defined(MBEDTLS_MD2_C)
@@ -1998,6 +2004,12 @@
     unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
     psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
 
+    /* A context must be freshly initialized before it can be set up. */
+    if( operation->alg != 0 )
+    {
+        return( PSA_ERROR_BAD_STATE );
+    }
+
     status = psa_mac_init( operation, full_length_alg );
     if( status != PSA_SUCCESS )
         return( status );
@@ -2909,6 +2921,12 @@
                               PSA_KEY_USAGE_ENCRYPT :
                               PSA_KEY_USAGE_DECRYPT );
 
+    /* A context must be freshly initialized before it can be set up. */
+    if( operation->alg != 0 )
+    {
+        return( PSA_ERROR_BAD_STATE );
+    }
+
     status = psa_cipher_init( operation, alg );
     if( status != PSA_SUCCESS )
         return( status );
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 2499102..9ea6cc0 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -2012,6 +2012,12 @@
 
     PSA_ASSERT( psa_crypto_init( ) );
 
+    /* Call setup twice in a row. */
+    PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    TEST_EQUAL( psa_hash_setup( &operation, alg ),
+                PSA_ERROR_BAD_STATE );
+    PSA_ASSERT( psa_hash_abort( &operation ) );
+
     /* Call update without calling setup beforehand. */
     TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
                 PSA_ERROR_BAD_STATE );
@@ -2336,6 +2342,14 @@
                 PSA_ERROR_BAD_STATE );
     PSA_ASSERT( psa_mac_abort( &operation ) );
 
+    /* Call setup twice in a row. */
+    PSA_ASSERT( psa_mac_sign_setup( &operation,
+                                    handle, alg ) );
+    TEST_EQUAL( psa_mac_sign_setup( &operation,
+                                    handle, alg ),
+                PSA_ERROR_BAD_STATE );
+    PSA_ASSERT( psa_mac_abort( &operation ) );
+
     /* Call update after sign finish. */
     PSA_ASSERT( psa_mac_sign_setup( &operation,
                                     handle, alg ) );
@@ -2601,6 +2615,18 @@
                                 key, sizeof(key) ) );
 
 
+    /* Call encrypt setup twice in a row. */
+    PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
+    TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ),
+                PSA_ERROR_BAD_STATE );
+    PSA_ASSERT( psa_cipher_abort( &operation ) );
+
+    /* Call decrypt setup twice in a row. */
+    PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) );
+    TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ),
+                PSA_ERROR_BAD_STATE );
+    PSA_ASSERT( psa_cipher_abort( &operation ) );
+
     /* Generate an IV without calling setup beforehand. */
     TEST_EQUAL( psa_cipher_generate_iv( &operation,
                                         buffer, sizeof( buffer ),