Fix multi-part termination on error
For multi-part operations, the PSA Crypto API specifies that if
the final operation does not return PSA_SUCCESS, the abort
operaion must be called by a client to clean-up the operation.
This change modifies the behaviour of the crypto provider
to only clear its operation context on success. This leaves
the operation context allocated, ensuring that the correct
PSA API status is returned when a client makes the mandatory
call to abort the failed operation. If the client never calls
abort, the context will eventually get recycled.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I9a6e2f2b96febec2e1b1b91c5d4f5189b1b24f8f
diff --git a/components/service/crypto/client/psa/psa_aead.c b/components/service/crypto/client/psa/psa_aead.c
index e4579e6..559eb6a 100644
--- a/components/service/crypto/client/psa/psa_aead.c
+++ b/components/service/crypto/client/psa/psa_aead.c
@@ -241,6 +241,10 @@
*aeadtext_length = bytes_output + remaining_aead_len + tag_len;
}
+ else {
+
+ psa_aead_abort(&operation);
+ }
}
else {
@@ -292,6 +296,10 @@
*plaintext_length = bytes_output + remaining_plaintext_len;
}
+ else {
+
+ psa_aead_abort(&operation);
+ }
}
else {
diff --git a/components/service/crypto/client/psa/psa_cipher.c b/components/service/crypto/client/psa/psa_cipher.c
index 24a8c28..d6e6540 100644
--- a/components/service/crypto/client/psa/psa_cipher.c
+++ b/components/service/crypto/client/psa/psa_cipher.c
@@ -149,6 +149,10 @@
*output_length = bytes_output + finish_output_len;
}
+ else {
+
+ psa_cipher_abort(operation);
+ }
}
else {
diff --git a/components/service/crypto/client/psa/psa_hash.c b/components/service/crypto/client/psa/psa_hash.c
index 83278de..e5dd003 100644
--- a/components/service/crypto/client/psa/psa_hash.c
+++ b/components/service/crypto/client/psa/psa_hash.c
@@ -137,6 +137,11 @@
if (psa_status == PSA_SUCCESS) {
psa_status = psa_hash_verify(&operation, hash, hash_length);
+
+ if (psa_status != PSA_SUCCESS) {
+
+ psa_hash_abort(&operation);
+ }
}
return psa_status;
@@ -155,6 +160,11 @@
if (psa_status == PSA_SUCCESS) {
psa_status = psa_hash_finish(&operation, hash, hash_size, hash_length);
+
+ if (psa_status != PSA_SUCCESS) {
+
+ psa_hash_abort(&operation);
+ }
}
return psa_status;
diff --git a/components/service/crypto/client/psa/psa_mac.c b/components/service/crypto/client/psa/psa_mac.c
index 5c5eb32..a3db864 100644
--- a/components/service/crypto/client/psa/psa_mac.c
+++ b/components/service/crypto/client/psa/psa_mac.c
@@ -129,6 +129,11 @@
if (psa_status == PSA_SUCCESS) {
psa_status = psa_mac_verify_finish(&operation, mac, mac_length);
+
+ if (psa_status != PSA_SUCCESS) {
+
+ psa_mac_abort(&operation);
+ }
}
return psa_status;
@@ -153,6 +158,11 @@
if (psa_status == PSA_SUCCESS) {
psa_status = psa_mac_sign_finish(&operation, mac, mac_size, mac_length);
+
+ if (psa_status != PSA_SUCCESS) {
+
+ psa_mac_abort(&operation);
+ }
}
return psa_status;
diff --git a/components/service/crypto/provider/extension/aead/aead_provider.c b/components/service/crypto/provider/extension/aead/aead_provider.c
index f4e81a0..14a2543 100644
--- a/components/service/crypto/provider/extension/aead/aead_provider.c
+++ b/components/service/crypto/provider/extension/aead/aead_provider.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -369,9 +369,9 @@
rpc_status = serializer->serialize_aead_finish_resp(resp_buf,
ciphertext, ciphertext_len,
tag, tag_len);
- }
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
@@ -418,9 +418,9 @@
struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
rpc_status = serializer->serialize_aead_verify_resp(resp_buf,
plaintext, plaintext_len);
- }
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
diff --git a/components/service/crypto/provider/extension/cipher/cipher_provider.c b/components/service/crypto/provider/extension/cipher/cipher_provider.c
index 8e7a86d..a5dd037 100644
--- a/components/service/crypto/provider/extension/cipher/cipher_provider.c
+++ b/components/service/crypto/provider/extension/cipher/cipher_provider.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -283,9 +283,9 @@
struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
rpc_status = serializer->serialize_cipher_finish_resp(resp_buf, output, output_len);
- }
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
diff --git a/components/service/crypto/provider/extension/hash/hash_provider.c b/components/service/crypto/provider/extension/hash/hash_provider.c
index 2c56051..b50fac1 100644
--- a/components/service/crypto/provider/extension/hash/hash_provider.c
+++ b/components/service/crypto/provider/extension/hash/hash_provider.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -179,9 +179,9 @@
struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
rpc_status = serializer->serialize_hash_finish_resp(resp_buf, hash, hash_len);
- }
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
@@ -252,6 +252,9 @@
if (crypto_context) {
psa_status = psa_hash_verify(&crypto_context->op.hash, hash, hash_len);
+
+ if (psa_status == PSA_SUCCESS)
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
}
call_req_set_opstatus(req, psa_status);
diff --git a/components/service/crypto/provider/extension/mac/mac_provider.c b/components/service/crypto/provider/extension/mac/mac_provider.c
index 96fe4cf..eef5558 100644
--- a/components/service/crypto/provider/extension/mac/mac_provider.c
+++ b/components/service/crypto/provider/extension/mac/mac_provider.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -181,9 +181,9 @@
struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
rpc_status = serializer->serialize_mac_sign_finish_resp(resp_buf, mac, mac_len);
- }
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);
@@ -220,7 +220,10 @@
psa_status = psa_mac_verify_finish(&crypto_context->op.mac, mac, mac_len);
- crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ if (psa_status == PSA_SUCCESS) {
+
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
}
call_req_set_opstatus(req, psa_status);