| From 00b4f777b377c69f948f5a9d68cbfc8fa8c38a86 Mon Sep 17 00:00:00 2001 |
| From: Julian Hall <julian.hall@arm.com> |
| Date: Fri, 11 Feb 2022 14:24:53 +0000 |
| Subject: [PATCH] Integrate AEAD operation support |
| |
| Resolves issues and integrates AEAD support into the crypto service |
| provider and clients. |
| |
| Signed-off-by: Julian Hall <julian.hall@arm.com> |
| Change-Id: I5fbe78a2dd825f592e26fd665f60c18b576f9de9 |
| |
| Upstream-Status: Pending [Not submitted to upstream yet] |
| Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com> |
| |
| |
| --- |
| .../caller/packed-c/crypto_caller_aead.h | 70 +++--- |
| .../client/caller/stub/crypto_caller_aead.h | 12 +- |
| .../service/crypto/client/psa/psa_aead.c | 221 +++++++++++++++--- |
| .../factory/full/crypto_provider_factory.c | 16 +- |
| .../component-test/component-test.cmake | 4 +- |
| deployments/crypto/opteesp/CMakeLists.txt | 4 +- |
| deployments/libts/linux-pc/CMakeLists.txt | 4 +- |
| deployments/se-proxy/opteesp/CMakeLists.txt | 4 +- |
| 8 files changed, 263 insertions(+), 72 deletions(-) |
| |
| diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h |
| index 3d9947d5..c4ffb20c 100644 |
| --- a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h |
| +++ b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h |
| @@ -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 |
| */ |
| @@ -20,38 +20,6 @@ |
| extern "C" { |
| #endif |
| |
| -static inline psa_status_t crypto_caller_aead_encrypt(struct service_client *context, |
| - psa_key_id_t key, |
| - psa_algorithm_t alg, |
| - const uint8_t *nonce, |
| - size_t nonce_length, |
| - const uint8_t *additional_data, |
| - size_t additional_data_length, |
| - const uint8_t *plaintext, |
| - size_t plaintext_length, |
| - uint8_t *aeadtext, |
| - size_t aeadtext_size, |
| - size_t *aeadtext_length) |
| -{ |
| - return PSA_ERROR_NOT_SUPPORTED; |
| -} |
| - |
| -static inline psa_status_t crypto_caller_aead_decrypt(struct service_client *context, |
| - psa_key_id_t key, |
| - psa_algorithm_t alg, |
| - const uint8_t *nonce, |
| - size_t nonce_length, |
| - const uint8_t *additional_data, |
| - size_t additional_data_length, |
| - const uint8_t *aeadtext, |
| - size_t aeadtext_length, |
| - uint8_t *plaintext, |
| - size_t plaintext_size, |
| - size_t *plaintext_length) |
| -{ |
| - return PSA_ERROR_NOT_SUPPORTED; |
| -} |
| - |
| static inline psa_status_t common_aead_setup(struct service_client *context, |
| uint32_t *op_handle, |
| psa_key_id_t key, |
| @@ -247,7 +215,7 @@ static inline psa_status_t crypto_caller_aead_set_lengths(struct service_client |
| { |
| psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; |
| struct ts_crypto_aead_set_lengths_in req_msg; |
| - size_t req_fixed_len = sizeof(struct ts_crypto_aead_abort_in); |
| + size_t req_fixed_len = sizeof(struct ts_crypto_aead_set_lengths_in); |
| size_t req_len = req_fixed_len; |
| |
| req_msg.op_handle = op_handle; |
| @@ -611,6 +579,40 @@ static inline psa_status_t crypto_caller_aead_abort(struct service_client *conte |
| return psa_status; |
| } |
| |
| +/** |
| + * The maximum data length that may be carried in an update operation will be |
| + * constrained by the maximum call payload capacity imposed by the end-to-end |
| + * RPC call path. These functions return the maximum update size when serialization |
| + * overheads are considered. This allows large paylaods to be processed in |
| + * maximum size chunks. |
| + */ |
| +static inline size_t crypto_caller_aead_max_update_ad_size(const struct service_client *context) |
| +{ |
| + /* Returns the maximum number of bytes of additional data that may be |
| + * carried as a parameter of the aead_update_ad operation |
| + * using the packed-c encoding. |
| + */ |
| + size_t payload_space = context->service_info.max_payload; |
| + size_t overhead = sizeof(struct ts_crypto_aead_update_ad_in) + TLV_HDR_LEN; |
| + |
| + return (payload_space > overhead) ? payload_space - overhead : 0; |
| +} |
| + |
| +static inline size_t crypto_caller_aead_max_update_size(const struct service_client *context) |
| +{ |
| + /* Returns the maximum number of bytes that may be |
| + * carried as a parameter of the aead_update operation |
| + * using the packed-c encoding. |
| + */ |
| + size_t payload_space = context->service_info.max_payload; |
| + size_t overhead = sizeof(struct ts_crypto_aead_update_in) + TLV_HDR_LEN; |
| + |
| + /* Allow for output to be a whole number of blocks */ |
| + overhead += PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE; |
| + |
| + return (payload_space > overhead) ? payload_space - overhead : 0; |
| +} |
| + |
| #ifdef __cplusplus |
| } |
| #endif |
| diff --git a/components/service/crypto/client/caller/stub/crypto_caller_aead.h b/components/service/crypto/client/caller/stub/crypto_caller_aead.h |
| index 18aa8cec..455e7ac1 100644 |
| --- a/components/service/crypto/client/caller/stub/crypto_caller_aead.h |
| +++ b/components/service/crypto/client/caller/stub/crypto_caller_aead.h |
| @@ -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 |
| */ |
| @@ -135,6 +135,16 @@ static inline psa_status_t crypto_caller_aead_abort(struct service_client *conte |
| return PSA_ERROR_NOT_SUPPORTED; |
| } |
| |
| +static inline size_t crypto_caller_aead_max_update_ad_size(const struct service_client *context) |
| +{ |
| + return 0; |
| +} |
| + |
| +static inline size_t crypto_caller_aead_max_update_size(const struct service_client *context) |
| +{ |
| + return 0; |
| +} |
| + |
| #ifdef __cplusplus |
| } |
| #endif |
| diff --git a/components/service/crypto/client/psa/psa_aead.c b/components/service/crypto/client/psa/psa_aead.c |
| index 22fd3da1..e4579e63 100644 |
| --- a/components/service/crypto/client/psa/psa_aead.c |
| +++ b/components/service/crypto/client/psa/psa_aead.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 |
| */ |
| @@ -8,37 +8,6 @@ |
| #include "psa_crypto_client.h" |
| #include "crypto_caller_selector.h" |
| |
| - |
| -psa_status_t psa_aead_encrypt(psa_key_id_t key, |
| - psa_algorithm_t alg, |
| - const uint8_t *nonce, |
| - size_t nonce_length, |
| - const uint8_t *additional_data, |
| - size_t additional_data_length, |
| - const uint8_t *plaintext, |
| - size_t plaintext_length, |
| - uint8_t *aeadtext, |
| - size_t aeadtext_size, |
| - size_t *aeadtext_length) |
| -{ |
| - return PSA_ERROR_NOT_SUPPORTED; |
| -} |
| - |
| -psa_status_t psa_aead_decrypt(psa_key_id_t key, |
| - psa_algorithm_t alg, |
| - const uint8_t *nonce, |
| - size_t nonce_length, |
| - const uint8_t *additional_data, |
| - size_t additional_data_length, |
| - const uint8_t *aeadtext, |
| - size_t aeadtext_length, |
| - uint8_t *plaintext, |
| - size_t plaintext_size, |
| - size_t *plaintext_length) |
| -{ |
| - return PSA_ERROR_NOT_SUPPORTED; |
| -} |
| - |
| psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, |
| psa_key_id_t key, |
| psa_algorithm_t alg) |
| @@ -143,3 +112,191 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation) |
| return crypto_caller_aead_abort(&psa_crypto_client_instance.base, |
| operation->handle); |
| } |
| + |
| +static psa_status_t multi_aead_update_ad(psa_aead_operation_t *operation, |
| + const uint8_t *input, |
| + size_t input_length) |
| +{ |
| + psa_status_t psa_status = PSA_SUCCESS; |
| + size_t max_update_size = |
| + crypto_caller_aead_max_update_ad_size(&psa_crypto_client_instance.base); |
| + size_t bytes_input = 0; |
| + |
| + if (!max_update_size) { |
| + |
| + /* Don't know the max update size so assume that the entire |
| + * input and output can be handled in a single update. If |
| + * this isn't true, the first aead update operation will fail |
| + * safely. |
| + */ |
| + max_update_size = input_length; |
| + } |
| + |
| + while (bytes_input < input_length) { |
| + |
| + size_t bytes_remaining = input_length - bytes_input; |
| + size_t update_len = (bytes_remaining < max_update_size) ? |
| + bytes_remaining : |
| + max_update_size; |
| + |
| + psa_status = psa_aead_update_ad(operation, |
| + &input[bytes_input], update_len); |
| + |
| + if (psa_status != PSA_SUCCESS) break; |
| + |
| + bytes_input += update_len; |
| + } |
| + |
| + return psa_status; |
| +} |
| + |
| +static psa_status_t multi_aead_update(psa_aead_operation_t *operation, |
| + const uint8_t *input, |
| + size_t input_length, |
| + uint8_t *output, |
| + size_t output_size, |
| + size_t *output_length) |
| +{ |
| + psa_status_t psa_status = PSA_SUCCESS; |
| + size_t max_update_size = |
| + crypto_caller_aead_max_update_size(&psa_crypto_client_instance.base); |
| + size_t bytes_input = 0; |
| + size_t bytes_output = 0; |
| + |
| + *output_length = 0; |
| + |
| + if (!max_update_size) { |
| + |
| + /* Don't know the max update size so assume that the entire |
| + * input and output can be handled in a single update. If |
| + * this isn't true, the first aead update operation will fail |
| + * safely. |
| + */ |
| + max_update_size = input_length; |
| + } |
| + |
| + while ((bytes_input < input_length) && (bytes_output < output_size)) { |
| + |
| + size_t update_output_len = 0; |
| + size_t bytes_remaining = input_length - bytes_input; |
| + size_t update_len = (bytes_remaining < max_update_size) ? |
| + bytes_remaining : |
| + max_update_size; |
| + |
| + psa_status = psa_aead_update(operation, |
| + &input[bytes_input], update_len, |
| + &output[bytes_output], output_size - bytes_output, &update_output_len); |
| + |
| + if (psa_status != PSA_SUCCESS) break; |
| + |
| + bytes_input += update_len; |
| + bytes_output += update_output_len; |
| + } |
| + |
| + if (psa_status == PSA_SUCCESS) { |
| + |
| + *output_length = bytes_output; |
| + } |
| + |
| + return psa_status; |
| +} |
| + |
| +psa_status_t psa_aead_encrypt(psa_key_id_t key, |
| + psa_algorithm_t alg, |
| + const uint8_t *nonce, |
| + size_t nonce_length, |
| + const uint8_t *additional_data, |
| + size_t additional_data_length, |
| + const uint8_t *plaintext, |
| + size_t plaintext_length, |
| + uint8_t *aeadtext, |
| + size_t aeadtext_size, |
| + size_t *aeadtext_length) |
| +{ |
| + psa_aead_operation_t operation = psa_aead_operation_init(); |
| + size_t bytes_output = 0; |
| + *aeadtext_length = 0; |
| + |
| + psa_status_t psa_status = psa_aead_encrypt_setup(&operation, key, alg); |
| + if (psa_status != PSA_SUCCESS) return psa_status; |
| + |
| + if ((psa_status = psa_aead_set_lengths(&operation, additional_data_length, plaintext_length), |
| + psa_status == PSA_SUCCESS) && |
| + (psa_status = psa_aead_set_nonce(&operation, nonce, nonce_length), |
| + psa_status == PSA_SUCCESS) && |
| + (psa_status = multi_aead_update_ad(&operation, additional_data, additional_data_length), |
| + psa_status == PSA_SUCCESS) && |
| + (psa_status = multi_aead_update(&operation, plaintext, plaintext_length, |
| + aeadtext, aeadtext_size, &bytes_output), |
| + psa_status == PSA_SUCCESS)) |
| + { |
| + size_t remaining_aead_len = 0; |
| + size_t tag_len = 0; |
| + |
| + psa_status = psa_aead_finish(&operation, |
| + NULL, 0, &remaining_aead_len, |
| + &aeadtext[bytes_output], aeadtext_size - bytes_output, &tag_len); |
| + |
| + if (psa_status == PSA_SUCCESS) { |
| + |
| + *aeadtext_length = bytes_output + remaining_aead_len + tag_len; |
| + } |
| + } |
| + else { |
| + |
| + psa_aead_abort(&operation); |
| + } |
| + |
| + return psa_status; |
| +} |
| + |
| +psa_status_t psa_aead_decrypt(psa_key_id_t key, |
| + psa_algorithm_t alg, |
| + const uint8_t *nonce, |
| + size_t nonce_length, |
| + const uint8_t *additional_data, |
| + size_t additional_data_length, |
| + const uint8_t *aeadtext, |
| + size_t aeadtext_length, |
| + uint8_t *plaintext, |
| + size_t plaintext_size, |
| + size_t *plaintext_length) |
| +{ |
| + psa_aead_operation_t operation = psa_aead_operation_init(); |
| + size_t bytes_output = 0; |
| + *plaintext_length = 0; |
| + |
| + psa_status_t psa_status = psa_aead_decrypt_setup(&operation, key, alg); |
| + if (psa_status != PSA_SUCCESS) return psa_status; |
| + |
| + size_t tag_len = PSA_ALG_AEAD_GET_TAG_LENGTH(alg); |
| + size_t ciphertext_len = (aeadtext_length > tag_len) ? aeadtext_length - tag_len : 0; |
| + |
| + if ((psa_status = psa_aead_set_lengths(&operation, additional_data_length, ciphertext_len), |
| + psa_status == PSA_SUCCESS) && |
| + (psa_status = psa_aead_set_nonce(&operation, nonce, nonce_length), |
| + psa_status == PSA_SUCCESS) && |
| + (psa_status = multi_aead_update_ad(&operation, additional_data, additional_data_length), |
| + psa_status == PSA_SUCCESS) && |
| + (psa_status = multi_aead_update(&operation, aeadtext, ciphertext_len, |
| + plaintext, plaintext_size, &bytes_output), |
| + psa_status == PSA_SUCCESS)) |
| + { |
| + size_t remaining_plaintext_len = 0; |
| + |
| + psa_status = psa_aead_verify(&operation, |
| + NULL, 0, &remaining_plaintext_len, |
| + &aeadtext[bytes_output], aeadtext_length - bytes_output); |
| + |
| + if (psa_status == PSA_SUCCESS) { |
| + |
| + *plaintext_length = bytes_output + remaining_plaintext_len; |
| + } |
| + } |
| + else { |
| + |
| + psa_aead_abort(&operation); |
| + } |
| + |
| + return psa_status; |
| +} |
| diff --git a/components/service/crypto/factory/full/crypto_provider_factory.c b/components/service/crypto/factory/full/crypto_provider_factory.c |
| index 2d926eb6..ee2b4473 100644 |
| --- a/components/service/crypto/factory/full/crypto_provider_factory.c |
| +++ b/components/service/crypto/factory/full/crypto_provider_factory.c |
| @@ -1,5 +1,5 @@ |
| /* |
| - * Copyright (c) 2021, Arm Limited. All rights reserved. |
| + * Copyright (c) 2021-2022, Arm Limited. All rights reserved. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| * |
| @@ -17,6 +17,8 @@ |
| #include <service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.h> |
| #include <service/crypto/provider/extension/mac/mac_provider.h> |
| #include <service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.h> |
| +#include <service/crypto/provider/extension/aead/aead_provider.h> |
| +#include <service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.h> |
| #include <service/discovery/provider/discovery_provider.h> |
| #include <service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h> |
| |
| @@ -34,6 +36,7 @@ static struct full_crypto_provider |
| struct cipher_provider cipher_provider; |
| struct key_derivation_provider key_derivation_provider; |
| struct mac_provider mac_provider; |
| + struct aead_provider aead_provider; |
| |
| } instance; |
| |
| @@ -98,6 +101,17 @@ struct crypto_provider *crypto_provider_factory_create(void) |
| crypto_provider_extend(&instance.crypto_provider, |
| &instance.mac_provider.base_provider); |
| |
| + /** |
| + * Extend with aead operations |
| + */ |
| + aead_provider_init(&instance.aead_provider); |
| + |
| + aead_provider_register_serializer(&instance.aead_provider, |
| + TS_RPC_ENCODING_PACKED_C, packedc_aead_provider_serializer_instance()); |
| + |
| + crypto_provider_extend(&instance.crypto_provider, |
| + &instance.aead_provider.base_provider); |
| + |
| return &instance.crypto_provider; |
| } |
| |
| diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake |
| index a0233c34..c3b015ab 100644 |
| --- a/deployments/component-test/component-test.cmake |
| +++ b/deployments/component-test/component-test.cmake |
| @@ -1,5 +1,5 @@ |
| #------------------------------------------------------------------------------- |
| -# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved. |
| +# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved. |
| # |
| # SPDX-License-Identifier: BSD-3-Clause |
| # |
| @@ -85,6 +85,8 @@ add_components( |
| "components/service/crypto/provider/extension/key_derivation/serializer/packed-c" |
| "components/service/crypto/provider/extension/mac" |
| "components/service/crypto/provider/extension/mac/serializer/packed-c" |
| + "components/service/crypto/provider/extension/aead" |
| + "components/service/crypto/provider/extension/aead/serializer/packed-c" |
| "components/service/crypto/provider/test" |
| "components/service/crypto/backend/mbedcrypto" |
| "components/service/crypto/factory/full" |
| diff --git a/deployments/crypto/opteesp/CMakeLists.txt b/deployments/crypto/opteesp/CMakeLists.txt |
| index 8ada74e9..eb5d0847 100644 |
| --- a/deployments/crypto/opteesp/CMakeLists.txt |
| +++ b/deployments/crypto/opteesp/CMakeLists.txt |
| @@ -1,5 +1,5 @@ |
| #------------------------------------------------------------------------------- |
| -# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved. |
| +# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved. |
| # |
| # SPDX-License-Identifier: BSD-3-Clause |
| # |
| @@ -62,6 +62,8 @@ add_components(TARGET "crypto-sp" |
| "components/service/crypto/provider/extension/key_derivation/serializer/packed-c" |
| "components/service/crypto/provider/extension/mac" |
| "components/service/crypto/provider/extension/mac/serializer/packed-c" |
| + "components/service/crypto/provider/extension/aead" |
| + "components/service/crypto/provider/extension/aead/serializer/packed-c" |
| "components/service/crypto/factory/full" |
| "components/service/crypto/backend/mbedcrypto" |
| "components/service/crypto/backend/mbedcrypto/trng_adapter/platform" |
| diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt |
| index fc98407c..97eaaa73 100644 |
| --- a/deployments/libts/linux-pc/CMakeLists.txt |
| +++ b/deployments/libts/linux-pc/CMakeLists.txt |
| @@ -1,5 +1,5 @@ |
| #------------------------------------------------------------------------------- |
| -# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved. |
| +# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved. |
| # |
| # SPDX-License-Identifier: BSD-3-Clause |
| # |
| @@ -71,6 +71,8 @@ add_components( |
| "components/service/crypto/provider/extension/key_derivation/serializer/packed-c" |
| "components/service/crypto/provider/extension/mac" |
| "components/service/crypto/provider/extension/mac/serializer/packed-c" |
| + "components/service/crypto/provider/extension/aead" |
| + "components/service/crypto/provider/extension/aead/serializer/packed-c" |
| "components/service/crypto/factory/full" |
| "components/service/crypto/backend/mbedcrypto" |
| "components/service/crypto/backend/mbedcrypto/trng_adapter/linux" |
| diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt |
| index 953bb716..24a8ca65 100644 |
| --- a/deployments/se-proxy/opteesp/CMakeLists.txt |
| +++ b/deployments/se-proxy/opteesp/CMakeLists.txt |
| @@ -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 |
| # |
| @@ -70,6 +70,8 @@ add_components(TARGET "se-proxy" |
| "components/service/crypto/provider/extension/key_derivation/serializer/packed-c" |
| "components/service/crypto/provider/extension/mac" |
| "components/service/crypto/provider/extension/mac/serializer/packed-c" |
| + "components/service/crypto/provider/extension/aead" |
| + "components/service/crypto/provider/extension/aead/serializer/packed-c" |
| "components/service/crypto/factory/full" |
| "components/service/secure_storage/include" |
| "components/service/secure_storage/frontend/secure_storage_provider" |