aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Hall <julian.hall@arm.com>2021-06-24 09:40:23 +0100
committerGyorgy Szing <Gyorgy.Szing@arm.com>2021-10-05 22:55:43 +0200
commitf57289645f3254d9184f3fd676b1a5154794ef1c (patch)
tree07e49f5ce93caa57de837f731c0c10d685d639a0
parentfc7222152b88ee0e52bb68b08159648e7907b4e6 (diff)
downloadtrusted-services-f57289645f3254d9184f3fd676b1a5154794ef1c.tar.gz
Add hash operation support to Crypto service provider
Adds support for multi-step hash operations. Only includes protocol support for packed-c serialization at the moment. Protobuf serialization still needs to be added. Includes crypto context management that can be used for any multi- step operations such as MAC and symmetric encrypt/decrypt. Signed-off-by: Julian Hall <julian.hall@arm.com> Change-Id: Ib51a9737f1987e1e7531da7edb38d9dc4095cc7e
-rw-r--r--components/service/crypto/client/cpp/crypto_client.h14
-rw-r--r--components/service/crypto/client/cpp/packed-c/packedc_crypto_client.cpp1021
-rw-r--r--components/service/crypto/client/cpp/packed-c/packedc_crypto_client.h86
-rw-r--r--components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.cpp914
-rw-r--r--components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.h86
-rw-r--r--components/service/crypto/provider/mbedcrypto/component.cmake1
-rw-r--r--components/service/crypto/provider/mbedcrypto/crypto_context_pool.c158
-rw-r--r--components/service/crypto/provider/mbedcrypto/crypto_context_pool.h118
-rw-r--r--components/service/crypto/provider/mbedcrypto/crypto_provider.c850
-rw-r--r--components/service/crypto/provider/mbedcrypto/crypto_provider.h2
-rw-r--r--components/service/crypto/provider/mbedcrypto/test/component.cmake13
-rw-r--r--components/service/crypto/provider/mbedcrypto/test/crypto_context_pool_tests.cpp130
-rw-r--r--components/service/crypto/provider/serializer/crypto_provider_serializer.h19
-rw-r--r--components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c124
-rw-r--r--components/service/crypto/test/service/component.cmake2
-rw-r--r--components/service/crypto/test/service/crypto_service_scenarios.cpp759
-rw-r--r--components/service/crypto/test/service/crypto_service_scenarios.h1
-rw-r--r--components/service/crypto/test/service/crypto_test_vectors.cpp73
-rw-r--r--components/service/crypto/test/service/crypto_test_vectors.h21
-rw-r--r--components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp5
-rw-r--r--components/service/crypto/test/service/psa_crypto_api/psa_crypto_api_client.cpp18
-rw-r--r--components/service/crypto/test/service/psa_crypto_api/psa_crypto_api_client.h80
-rw-r--r--deployments/component-test/component-test.cmake1
-rw-r--r--protocols/service/crypto/packed-c/hash.h67
-rw-r--r--protocols/service/crypto/packed-c/opcodes.h24
25 files changed, 2870 insertions, 1717 deletions
diff --git a/components/service/crypto/client/cpp/crypto_client.h b/components/service/crypto/client/cpp/crypto_client.h
index 488434479..03cf4b36a 100644
--- a/components/service/crypto/client/cpp/crypto_client.h
+++ b/components/service/crypto/client/cpp/crypto_client.h
@@ -24,7 +24,8 @@ public:
int err_rpc_status() const;
/* Key lifecycle methods */
- virtual psa_status_t generate_key(const psa_key_attributes_t *attributes, psa_key_id_t *id) = 0;
+ virtual psa_status_t generate_key(const psa_key_attributes_t *attributes,
+ psa_key_id_t *id) = 0;
virtual psa_status_t destroy_key(psa_key_id_t id) = 0;
virtual psa_status_t import_key(const psa_key_attributes_t *attributes,
const uint8_t *data, size_t data_length, psa_key_id_t *id) = 0;
@@ -39,7 +40,8 @@ public:
/* Sign/verify methods */
virtual psa_status_t sign_hash(psa_key_id_t id, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
- uint8_t *signature, size_t signature_size, size_t *signature_length) = 0;
+ uint8_t *signature, size_t signature_size,
+ size_t *signature_length) = 0;
virtual psa_status_t verify_hash(psa_key_id_t id, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length) = 0;
@@ -57,6 +59,14 @@ public:
/* Random number generation */
virtual psa_status_t generate_random(uint8_t *output, size_t output_size) = 0;
+ /* Hash methods */
+ virtual psa_status_t hash_setup(uint32_t *op_handle,
+ psa_algorithm_t alg) = 0;
+ virtual psa_status_t hash_update(uint32_t op_handle,
+ const uint8_t *input, size_t input_length) = 0;
+ virtual psa_status_t hash_finish(uint32_t op_handle,
+ uint8_t *hash, size_t hash_size, size_t *hash_length) = 0;
+
protected:
crypto_client();
crypto_client(struct rpc_caller *caller);
diff --git a/components/service/crypto/client/cpp/packed-c/packedc_crypto_client.cpp b/components/service/crypto/client/cpp/packed-c/packedc_crypto_client.cpp
index 36852194c..a7618ba78 100644
--- a/components/service/crypto/client/cpp/packed-c/packedc_crypto_client.cpp
+++ b/components/service/crypto/client/cpp/packed-c/packedc_crypto_client.cpp
@@ -20,18 +20,19 @@
#include <protocols/service/crypto/packed-c/import_key.h>
#include <protocols/service/crypto/packed-c/sign_hash.h>
#include <protocols/service/crypto/packed-c/verify_hash.h>
+#include <protocols/service/crypto/packed-c/hash.h>
#include <common/tlv/tlv.h>
#include <rpc_caller.h>
packedc_crypto_client::packedc_crypto_client() :
- crypto_client()
+ crypto_client()
{
}
packedc_crypto_client::packedc_crypto_client(struct rpc_caller *caller) :
- crypto_client(caller)
+ crypto_client(caller)
{
}
@@ -43,632 +44,798 @@ packedc_crypto_client::~packedc_crypto_client()
psa_status_t packedc_crypto_client::generate_key(const psa_key_attributes_t *attributes, psa_key_id_t *id)
{
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- struct ts_crypto_generate_key_in req_msg;
- size_t req_len = sizeof(ts_crypto_generate_key_in);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_generate_key_in req_msg;
+ size_t req_len = sizeof(ts_crypto_generate_key_in);
- translate_key_attributes(req_msg.attributes, *attributes);
+ translate_key_attributes(req_msg.attributes, *attributes);
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- memcpy(req_buf, &req_msg, req_len);
+ memcpy(req_buf, &req_msg, req_len);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- TS_CRYPTO_OPCODE_GENERATE_KEY, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_GENERATE_KEY, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- if (resp_len >= sizeof(ts_crypto_generate_key_out)) {
+ if (resp_len >= sizeof(ts_crypto_generate_key_out)) {
- struct ts_crypto_generate_key_out resp_msg;
- memcpy(&resp_msg, resp_buf, sizeof(ts_crypto_generate_key_out));
- *id = resp_msg.id;
- }
- else {
- /* Failed to decode response message */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
+ struct ts_crypto_generate_key_out resp_msg;
+ memcpy(&resp_msg, resp_buf, sizeof(ts_crypto_generate_key_out));
+ *id = resp_msg.id;
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t packedc_crypto_client::destroy_key(psa_key_id_t id)
{
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- struct ts_crypto_destroy_key_in req_msg;
- size_t req_len = sizeof(ts_crypto_destroy_key_in);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_destroy_key_in req_msg;
+ size_t req_len = sizeof(ts_crypto_destroy_key_in);
- req_msg.id = id;
+ req_msg.id = id;
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- memcpy(req_buf, &req_msg, req_len);
+ memcpy(req_buf, &req_msg, req_len);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- TS_CRYPTO_OPCODE_DESTROY_KEY, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_DESTROY_KEY, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
- rpc_caller_end(m_caller, call_handle);
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t packedc_crypto_client::import_key(const psa_key_attributes_t *attributes,
- const uint8_t *data, size_t data_length, psa_key_id_t *id)
+ const uint8_t *data, size_t data_length, psa_key_id_t *id)
{
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- struct ts_crypto_import_key_in req_msg;
- size_t req_fixed_len = sizeof(ts_crypto_import_key_in);
- size_t req_len = req_fixed_len + tlv_required_space(data_length);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_import_key_in req_msg;
+ size_t req_fixed_len = sizeof(ts_crypto_import_key_in);
+ size_t req_len = req_fixed_len + tlv_required_space(data_length);
- translate_key_attributes(req_msg.attributes, *attributes);
+ translate_key_attributes(req_msg.attributes, *attributes);
- struct tlv_record key_record;
- key_record.tag = TS_CRYPTO_IMPORT_KEY_IN_TAG_DATA;
- key_record.length = data_length;
- key_record.value = data;
+ struct tlv_record key_record;
+ key_record.tag = TS_CRYPTO_IMPORT_KEY_IN_TAG_DATA;
+ key_record.length = data_length;
+ key_record.value = data;
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
- struct tlv_iterator req_iter;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+ struct tlv_iterator req_iter;
- memcpy(req_buf, &req_msg, req_fixed_len);
+ memcpy(req_buf, &req_msg, req_fixed_len);
- tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
- tlv_encode(&req_iter, &key_record);
+ tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
+ tlv_encode(&req_iter, &key_record);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- TS_CRYPTO_OPCODE_IMPORT_KEY, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_IMPORT_KEY, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- if (resp_len >= sizeof(ts_crypto_import_key_out)) {
+ if (resp_len >= sizeof(ts_crypto_import_key_out)) {
- struct ts_crypto_import_key_out resp_msg;
- memcpy(&resp_msg, resp_buf, sizeof(ts_crypto_import_key_out));
- *id = resp_msg.id;
- }
- else {
- /* Failed to decode response message */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
+ struct ts_crypto_import_key_out resp_msg;
+ memcpy(&resp_msg, resp_buf, sizeof(ts_crypto_import_key_out));
+ *id = resp_msg.id;
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t packedc_crypto_client::export_key(psa_key_id_t id,
- uint8_t *data, size_t data_size,
- size_t *data_length)
+ uint8_t *data, size_t data_size,
+ size_t *data_length)
{
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- struct ts_crypto_export_key_in req_msg;
- size_t req_len = sizeof(ts_crypto_export_key_in);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_export_key_in req_msg;
+ size_t req_len = sizeof(ts_crypto_export_key_in);
- req_msg.id = id;
+ req_msg.id = id;
- *data_length = 0; /* For failure case */
+ *data_length = 0; /* For failure case */
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- memcpy(req_buf, &req_msg, req_len);
+ memcpy(req_buf, &req_msg, req_len);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- TS_CRYPTO_OPCODE_EXPORT_KEY, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_EXPORT_KEY, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct tlv_const_iterator resp_iter;
- struct tlv_record decoded_record;
- tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+ tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
- if (tlv_find_decode(&resp_iter, TS_CRYPTO_EXPORT_KEY_OUT_TAG_DATA, &decoded_record)) {
+ if (tlv_find_decode(&resp_iter,
+ TS_CRYPTO_EXPORT_KEY_OUT_TAG_DATA, &decoded_record)) {
- if (decoded_record.length <= data_size) {
+ if (decoded_record.length <= data_size) {
- memcpy(data, decoded_record.value, decoded_record.length);
- *data_length = decoded_record.length;
- }
- else {
- /* Provided buffer is too small */
- psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Mandatory response parameter missing */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
+ memcpy(data, decoded_record.value, decoded_record.length);
+ *data_length = decoded_record.length;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Mandatory response parameter missing */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t packedc_crypto_client::export_public_key(psa_key_id_t id,
- uint8_t *data, size_t data_size, size_t *data_length)
+ uint8_t *data, size_t data_size, size_t *data_length)
{
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- struct ts_crypto_export_public_key_in req_msg;
- size_t req_len = sizeof(ts_crypto_export_public_key_in);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_export_public_key_in req_msg;
+ size_t req_len = sizeof(ts_crypto_export_public_key_in);
- req_msg.id = id;
+ req_msg.id = id;
- *data_length = 0; /* For failure case */
+ *data_length = 0; /* For failure case */
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- memcpy(req_buf, &req_msg, req_len);
+ memcpy(req_buf, &req_msg, req_len);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct tlv_const_iterator resp_iter;
- struct tlv_record decoded_record;
- tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+ tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
- if (tlv_find_decode(&resp_iter, TS_CRYPTO_EXPORT_PUBLIC_KEY_OUT_TAG_DATA, &decoded_record)) {
+ if (tlv_find_decode(&resp_iter,
+ TS_CRYPTO_EXPORT_PUBLIC_KEY_OUT_TAG_DATA, &decoded_record)) {
- if (decoded_record.length <= data_size) {
+ if (decoded_record.length <= data_size) {
- memcpy(data, decoded_record.value, decoded_record.length);
- *data_length = decoded_record.length;
- }
- else {
- /* Provided buffer is too small */
- psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Mandatory response parameter missing */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
+ memcpy(data, decoded_record.value, decoded_record.length);
+ *data_length = decoded_record.length;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Mandatory response parameter missing */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t packedc_crypto_client::sign_hash(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *hash, size_t hash_length,
- uint8_t *signature, size_t signature_size, size_t *signature_length)
+ const uint8_t *hash, size_t hash_length,
+ uint8_t *signature, size_t signature_size, size_t *signature_length)
{
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- struct ts_crypto_sign_hash_in req_msg;
- size_t req_fixed_len = sizeof(ts_crypto_sign_hash_in);
- size_t req_len = req_fixed_len + tlv_required_space(hash_length);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_sign_hash_in req_msg;
+ size_t req_fixed_len = sizeof(ts_crypto_sign_hash_in);
+ size_t req_len = req_fixed_len + tlv_required_space(hash_length);
- *signature_length = 0; /* For failure case */
+ *signature_length = 0; /* For failure case */
- req_msg.id = id;
- req_msg.alg = alg;
+ req_msg.id = id;
+ req_msg.alg = alg;
- struct tlv_record hash_record;
- hash_record.tag = TS_CRYPTO_SIGN_HASH_IN_TAG_HASH;
- hash_record.length = hash_length;
- hash_record.value = hash;
+ struct tlv_record hash_record;
+ hash_record.tag = TS_CRYPTO_SIGN_HASH_IN_TAG_HASH;
+ hash_record.length = hash_length;
+ hash_record.value = hash;
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
- struct tlv_iterator req_iter;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+ struct tlv_iterator req_iter;
- memcpy(req_buf, &req_msg, req_fixed_len);
+ memcpy(req_buf, &req_msg, req_fixed_len);
- tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
- tlv_encode(&req_iter, &hash_record);
+ tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
+ tlv_encode(&req_iter, &hash_record);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- TS_CRYPTO_OPCODE_SIGN_HASH, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_SIGN_HASH, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct tlv_const_iterator resp_iter;
- struct tlv_record decoded_record;
- tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+ tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
- if (tlv_find_decode(&resp_iter, TS_CRYPTO_SIGN_HASH_OUT_TAG_SIGNATURE, &decoded_record)) {
+ if (tlv_find_decode(&resp_iter,
+ TS_CRYPTO_SIGN_HASH_OUT_TAG_SIGNATURE, &decoded_record)) {
- if (decoded_record.length <= signature_size) {
+ if (decoded_record.length <= signature_size) {
- memcpy(signature, decoded_record.value, decoded_record.length);
- *signature_length = decoded_record.length;
- }
- else {
- /* Provided buffer is too small */
- psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Mandatory response parameter missing */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
+ memcpy(signature, decoded_record.value, decoded_record.length);
+ *signature_length = decoded_record.length;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Mandatory response parameter missing */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t packedc_crypto_client::verify_hash(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *hash, size_t hash_length,
- const uint8_t *signature, size_t signature_length)
+ const uint8_t *hash, size_t hash_length,
+ const uint8_t *signature, size_t signature_length)
{
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- struct ts_crypto_verify_hash_in req_msg;
- size_t req_fixed_len = sizeof(ts_crypto_verify_hash_in);
- size_t req_len = req_fixed_len + tlv_required_space(hash_length) + tlv_required_space(signature_length);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_verify_hash_in req_msg;
+ size_t req_fixed_len = sizeof(ts_crypto_verify_hash_in);
+ size_t req_len = req_fixed_len +
+ tlv_required_space(hash_length) + tlv_required_space(signature_length);
- req_msg.id = id;
- req_msg.alg = alg;
+ req_msg.id = id;
+ req_msg.alg = alg;
- struct tlv_record hash_record;
- hash_record.tag = TS_CRYPTO_VERIFY_HASH_IN_TAG_HASH;
- hash_record.length = hash_length;
- hash_record.value = hash;
+ struct tlv_record hash_record;
+ hash_record.tag = TS_CRYPTO_VERIFY_HASH_IN_TAG_HASH;
+ hash_record.length = hash_length;
+ hash_record.value = hash;
- struct tlv_record sig_record;
- sig_record.tag = TS_CRYPTO_VERIFY_HASH_IN_TAG_SIGNATURE;
- sig_record.length = signature_length;
- sig_record.value = signature;
+ struct tlv_record sig_record;
+ sig_record.tag = TS_CRYPTO_VERIFY_HASH_IN_TAG_SIGNATURE;
+ sig_record.length = signature_length;
+ sig_record.value = signature;
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
- struct tlv_iterator req_iter;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+ struct tlv_iterator req_iter;
- memcpy(req_buf, &req_msg, req_fixed_len);
+ memcpy(req_buf, &req_msg, req_fixed_len);
- tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
- tlv_encode(&req_iter, &hash_record);
- tlv_encode(&req_iter, &sig_record);
+ tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
+ tlv_encode(&req_iter, &hash_record);
+ tlv_encode(&req_iter, &sig_record);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- TS_CRYPTO_OPCODE_VERIFY_HASH, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_VERIFY_HASH, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
- rpc_caller_end(m_caller, call_handle);
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t packedc_crypto_client::asymmetric_encrypt(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *input, size_t input_length,
- const uint8_t *salt, size_t salt_length,
- uint8_t *output, size_t output_size, size_t *output_length)
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length)
{
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- struct ts_crypto_asymmetric_encrypt_in req_msg;
- size_t req_fixed_len = sizeof(ts_crypto_asymmetric_encrypt_in);
- size_t req_len = req_fixed_len;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_asymmetric_encrypt_in req_msg;
+ size_t req_fixed_len = sizeof(ts_crypto_asymmetric_encrypt_in);
+ size_t req_len = req_fixed_len;
- *output_length = 0; /* For failure case */
+ *output_length = 0; /* For failure case */
- req_msg.id = id;
- req_msg.alg = alg;
+ req_msg.id = id;
+ req_msg.alg = alg;
- /* Mandatory parameter */
- struct tlv_record plaintext_record;
- plaintext_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_PLAINTEXT;
- plaintext_record.length = input_length;
- plaintext_record.value = input;
- req_len += tlv_required_space(plaintext_record.length);
+ /* Mandatory parameter */
+ struct tlv_record plaintext_record;
+ plaintext_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_PLAINTEXT;
+ plaintext_record.length = input_length;
+ plaintext_record.value = input;
+ req_len += tlv_required_space(plaintext_record.length);
- /* Optional parameter */
- struct tlv_record salt_record;
- salt_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_SALT;
- salt_record.length = (salt) ? salt_length : 0;
- salt_record.value = salt;
- if (salt) req_len += tlv_required_space(salt_record.length);
+ /* Optional parameter */
+ struct tlv_record salt_record;
+ salt_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_SALT;
+ salt_record.length = (salt) ? salt_length : 0;
+ salt_record.value = salt;
+ if (salt) req_len += tlv_required_space(salt_record.length);
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus = PSA_ERROR_GENERIC_ERROR;
- struct tlv_iterator req_iter;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus = PSA_ERROR_GENERIC_ERROR;
+ struct tlv_iterator req_iter;
- memcpy(req_buf, &req_msg, req_fixed_len);
+ memcpy(req_buf, &req_msg, req_fixed_len);
- tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
- tlv_encode(&req_iter, &plaintext_record);
- if (salt) tlv_encode(&req_iter, &salt_record);
+ tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
+ tlv_encode(&req_iter, &plaintext_record);
+ if (salt) tlv_encode(&req_iter, &salt_record);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct tlv_const_iterator resp_iter;
- struct tlv_record decoded_record;
- tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+ tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
- if (tlv_find_decode(&resp_iter, TS_CRYPTO_ASYMMETRIC_ENCRYPT_OUT_TAG_CIPHERTEXT, &decoded_record)) {
+ if (tlv_find_decode(&resp_iter,
+ TS_CRYPTO_ASYMMETRIC_ENCRYPT_OUT_TAG_CIPHERTEXT, &decoded_record)) {
- if (decoded_record.length <= output_size) {
+ if (decoded_record.length <= output_size) {
- memcpy(output, decoded_record.value, decoded_record.length);
- *output_length = decoded_record.length;
- }
- else {
- /* Provided buffer is too small */
- psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Mandatory response parameter missing */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
+ memcpy(output, decoded_record.value, decoded_record.length);
+ *output_length = decoded_record.length;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Mandatory response parameter missing */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t packedc_crypto_client::asymmetric_decrypt(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *input, size_t input_length,
- const uint8_t *salt, size_t salt_length,
- uint8_t *output, size_t output_size, size_t *output_length)
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length)
{
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- struct ts_crypto_asymmetric_decrypt_in req_msg;
- size_t req_fixed_len = sizeof(ts_crypto_asymmetric_decrypt_in);
- size_t req_len = req_fixed_len;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_asymmetric_decrypt_in req_msg;
+ size_t req_fixed_len = sizeof(ts_crypto_asymmetric_decrypt_in);
+ size_t req_len = req_fixed_len;
- *output_length = 0; /* For failure case */
+ *output_length = 0; /* For failure case */
- req_msg.id = id;
- req_msg.alg = alg;
+ req_msg.id = id;
+ req_msg.alg = alg;
- /* Mandatory parameter */
- struct tlv_record ciphertext_record;
- ciphertext_record.tag = TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_CIPHERTEXT;
- ciphertext_record.length = input_length;
- ciphertext_record.value = input;
- req_len += tlv_required_space(ciphertext_record.length);
+ /* Mandatory parameter */
+ struct tlv_record ciphertext_record;
+ ciphertext_record.tag = TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_CIPHERTEXT;
+ ciphertext_record.length = input_length;
+ ciphertext_record.value = input;
+ req_len += tlv_required_space(ciphertext_record.length);
- /* Optional parameter */
- struct tlv_record salt_record;
- salt_record.tag = TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_SALT;
- salt_record.length = (salt) ? salt_length : 0;
- salt_record.value = salt;
- if (salt) req_len += tlv_required_space(salt_record.length);
+ /* Optional parameter */
+ struct tlv_record salt_record;
+ salt_record.tag = TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_SALT;
+ salt_record.length = (salt) ? salt_length : 0;
+ salt_record.value = salt;
+ if (salt) req_len += tlv_required_space(salt_record.length);
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
- struct tlv_iterator req_iter;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+ struct tlv_iterator req_iter;
- memcpy(req_buf, &req_msg, req_fixed_len);
+ memcpy(req_buf, &req_msg, req_fixed_len);
- tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
- tlv_encode(&req_iter, &ciphertext_record);
- if (salt) tlv_encode(&req_iter, &salt_record);
+ tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
+ tlv_encode(&req_iter, &ciphertext_record);
+ if (salt) tlv_encode(&req_iter, &salt_record);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct tlv_const_iterator resp_iter;
- struct tlv_record decoded_record;
- tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+ tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
- if (tlv_find_decode(&resp_iter, TS_CRYPTO_ASYMMETRIC_DECRYPT_OUT_TAG_PLAINTEXT, &decoded_record)) {
+ if (tlv_find_decode(&resp_iter,
+ TS_CRYPTO_ASYMMETRIC_DECRYPT_OUT_TAG_PLAINTEXT, &decoded_record)) {
- if (decoded_record.length <= output_size) {
+ if (decoded_record.length <= output_size) {
- memcpy(output, decoded_record.value, decoded_record.length);
- *output_length = decoded_record.length;
- }
- else {
- /* Provided buffer is too small */
- psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Mandatory response parameter missing */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
+ memcpy(output, decoded_record.value, decoded_record.length);
+ *output_length = decoded_record.length;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Mandatory response parameter missing */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t packedc_crypto_client::generate_random(uint8_t *output, size_t output_size)
{
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- struct ts_crypto_generate_random_in req_msg;
- size_t req_len = sizeof(ts_crypto_generate_random_in);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_generate_random_in req_msg;
+ size_t req_len = sizeof(ts_crypto_generate_random_in);
- req_msg.size = output_size;
+ req_msg.size = output_size;
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- memcpy(req_buf, &req_msg, req_len);
+ memcpy(req_buf, &req_msg, req_len);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- TS_CRYPTO_OPCODE_GENERATE_RANDOM, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_GENERATE_RANDOM, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct tlv_const_iterator resp_iter;
- struct tlv_record decoded_record;
- tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+ tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
- if (tlv_find_decode(&resp_iter, TS_CRYPTO_GENERATE_RANDOM_OUT_TAG_RANDOM_BYTES, &decoded_record)) {
+ if (tlv_find_decode(&resp_iter,
+ TS_CRYPTO_GENERATE_RANDOM_OUT_TAG_RANDOM_BYTES, &decoded_record)) {
- if (decoded_record.length <= output_size) {
+ if (decoded_record.length <= output_size) {
- memcpy(output, decoded_record.value, decoded_record.length);
- }
- else {
- /* Provided buffer is too small */
- psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Mandatory response parameter missing */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
+ memcpy(output, decoded_record.value, decoded_record.length);
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Mandatory response parameter missing */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
- return psa_status;
+ return psa_status;
}
-void packedc_crypto_client::translate_key_attributes(struct ts_crypto_key_attributes &proto_attributes,
- const psa_key_attributes_t &psa_attributes)
+psa_status_t packedc_crypto_client::hash_setup(uint32_t *op_handle,
+ psa_algorithm_t alg)
{
- proto_attributes.type = psa_get_key_type(&psa_attributes);
- proto_attributes.key_bits = psa_get_key_bits(&psa_attributes);
- proto_attributes.lifetime = psa_get_key_lifetime(&psa_attributes);
- proto_attributes.id = psa_get_key_id(&psa_attributes);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_hash_setup_in req_msg;
+ size_t req_len = sizeof(ts_crypto_hash_setup_in);
- proto_attributes.policy.usage = psa_get_key_usage_flags(&psa_attributes);
- proto_attributes.policy.alg = psa_get_key_algorithm(&psa_attributes);
+ req_msg.alg = alg;
+
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+
+ memcpy(req_buf, &req_msg, req_len);
+
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_HASH_SETUP, &opstatus, &resp_buf, &resp_len);
+
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ psa_status = opstatus;
+
+ if (psa_status == PSA_SUCCESS) {
+
+ if (resp_len >= sizeof(ts_crypto_hash_setup_out)) {
+
+ struct ts_crypto_hash_setup_out resp_msg;
+ memcpy(&resp_msg, resp_buf, sizeof(ts_crypto_hash_setup_out));
+ *op_handle = resp_msg.op_handle;
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+
+ return psa_status;
+}
+
+psa_status_t packedc_crypto_client::hash_update(uint32_t op_handle,
+ const uint8_t *input, size_t input_length)
+{
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_hash_update_in req_msg;
+ size_t req_fixed_len = sizeof(ts_crypto_hash_update_in);
+ size_t req_len = req_fixed_len;
+
+ req_msg.op_handle = op_handle;
+
+ /* Mandatory input data parameter */
+ struct tlv_record data_record;
+ data_record.tag = TS_CRYPTO_HASH_UPDATE_IN_TAG_DATA;
+ data_record.length = input_length;
+ data_record.value = input;
+ req_len += tlv_required_space(data_record.length);
+
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+ struct tlv_iterator req_iter;
+
+ memcpy(req_buf, &req_msg, req_fixed_len);
+
+ tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
+ tlv_encode(&req_iter, &data_record);
+
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_HASH_UPDATE, &opstatus, &resp_buf, &resp_len);
+
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+
+ return psa_status;
+}
+
+psa_status_t packedc_crypto_client::hash_finish(uint32_t op_handle,
+ uint8_t *hash, size_t hash_size, size_t *hash_length)
+{
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_hash_finish_in req_msg;
+ size_t req_fixed_len = sizeof(ts_crypto_hash_finish_in);
+ size_t req_len = req_fixed_len;
+
+ *hash_length = 0;
+ req_msg.op_handle = op_handle;
+
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+
+ memcpy(req_buf, &req_msg, req_fixed_len);
+
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_HASH_FINISH, &opstatus, &resp_buf, &resp_len);
+
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ psa_status = opstatus;
+
+ if (psa_status == PSA_SUCCESS) {
+
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+ tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+
+ if (tlv_find_decode(&resp_iter,
+ TS_CRYPTO_HASH_FINISH_OUT_TAG_HASH, &decoded_record)) {
+
+ if (decoded_record.length <= hash_size) {
+
+ memcpy(hash, decoded_record.value, decoded_record.length);
+ *hash_length = decoded_record.length;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Mandatory response parameter missing */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+
+ return psa_status;
+}
+
+void packedc_crypto_client::translate_key_attributes(
+ struct ts_crypto_key_attributes &proto_attributes,
+ const psa_key_attributes_t &psa_attributes)
+{
+ proto_attributes.type = psa_get_key_type(&psa_attributes);
+ proto_attributes.key_bits = psa_get_key_bits(&psa_attributes);
+ proto_attributes.lifetime = psa_get_key_lifetime(&psa_attributes);
+ proto_attributes.id = psa_get_key_id(&psa_attributes);
+
+ proto_attributes.policy.usage = psa_get_key_usage_flags(&psa_attributes);
+ proto_attributes.policy.alg = psa_get_key_algorithm(&psa_attributes);
}
diff --git a/components/service/crypto/client/cpp/packed-c/packedc_crypto_client.h b/components/service/crypto/client/cpp/packed-c/packedc_crypto_client.h
index f3e002b2c..be4bb66c8 100644
--- a/components/service/crypto/client/cpp/packed-c/packedc_crypto_client.h
+++ b/components/service/crypto/client/cpp/packed-c/packedc_crypto_client.h
@@ -16,48 +16,56 @@
class packedc_crypto_client : public crypto_client
{
public:
- packedc_crypto_client();
- packedc_crypto_client(struct rpc_caller *caller);
- virtual ~packedc_crypto_client();
-
- /* Key lifecycle methods */
- psa_status_t generate_key(const psa_key_attributes_t *attributes, psa_key_id_t *id);
- psa_status_t destroy_key(psa_key_id_t id);
- psa_status_t import_key(const psa_key_attributes_t *attributes,
- const uint8_t *data, size_t data_length, psa_key_id_t *id);
-
- /* Key export methods */
- psa_status_t export_key(psa_key_id_t id,
- uint8_t *data, size_t data_size,
- size_t *data_length);
- psa_status_t export_public_key(psa_key_id_t id,
- uint8_t *data, size_t data_size, size_t *data_length);
-
- /* Sign/verify methods */
- psa_status_t sign_hash(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *hash, size_t hash_length,
- uint8_t *signature, size_t signature_size, size_t *signature_length);
- psa_status_t verify_hash(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *hash, size_t hash_length,
- const uint8_t *signature, size_t signature_length);
-
- /* Asymmetric encrypt/decrypt */
- psa_status_t asymmetric_encrypt(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *input, size_t input_length,
- const uint8_t *salt, size_t salt_length,
- uint8_t *output, size_t output_size, size_t *output_length);
- psa_status_t asymmetric_decrypt(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *input, size_t input_length,
- const uint8_t *salt, size_t salt_length,
- uint8_t *output, size_t output_size, size_t *output_length);
-
- /* Random number generation */
- psa_status_t generate_random(uint8_t *output, size_t output_size);
+ packedc_crypto_client();
+ packedc_crypto_client(struct rpc_caller *caller);
+ virtual ~packedc_crypto_client();
+
+ /* Key lifecycle methods */
+ psa_status_t generate_key(const psa_key_attributes_t *attributes, psa_key_id_t *id);
+ psa_status_t destroy_key(psa_key_id_t id);
+ psa_status_t import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data, size_t data_length, psa_key_id_t *id);
+
+ /* Key export methods */
+ psa_status_t export_key(psa_key_id_t id,
+ uint8_t *data, size_t data_size,
+ size_t *data_length);
+ psa_status_t export_public_key(psa_key_id_t id,
+ uint8_t *data, size_t data_size, size_t *data_length);
+
+ /* Sign/verify methods */
+ psa_status_t sign_hash(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *hash, size_t hash_length,
+ uint8_t *signature, size_t signature_size, size_t *signature_length);
+ psa_status_t verify_hash(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *hash, size_t hash_length,
+ const uint8_t *signature, size_t signature_length);
+
+ /* Asymmetric encrypt/decrypt */
+ psa_status_t asymmetric_encrypt(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length);
+ psa_status_t asymmetric_decrypt(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length);
+
+ /* Random number generation */
+ psa_status_t generate_random(uint8_t *output, size_t output_size);
+
+ /* Hash methods */
+ psa_status_t hash_setup(uint32_t *op_handle,
+ psa_algorithm_t alg);
+ psa_status_t hash_update(uint32_t op_handle,
+ const uint8_t *input, size_t input_length);
+ psa_status_t hash_finish(uint32_t op_handle,
+ uint8_t *hash, size_t hash_size, size_t *hash_length);
private:
- void translate_key_attributes(struct ts_crypto_key_attributes &proto_attributes,
- const psa_key_attributes_t &psa_attributes);
+ void translate_key_attributes(struct ts_crypto_key_attributes &proto_attributes,
+ const psa_key_attributes_t &psa_attributes);
};
#endif /* PACKEDC_CRYPTO_CLIENT_H */
diff --git a/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.cpp b/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.cpp
index 542d0fe64..32acd4c64 100644
--- a/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.cpp
+++ b/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.cpp
@@ -25,13 +25,13 @@
#include <pb_decode.h>
protobuf_crypto_client::protobuf_crypto_client() :
- crypto_client()
+ crypto_client()
{
}
protobuf_crypto_client::protobuf_crypto_client(struct rpc_caller *caller) :
- crypto_client(caller)
+ crypto_client(caller)
{
}
@@ -41,668 +41,702 @@ protobuf_crypto_client::~protobuf_crypto_client()
}
-psa_status_t protobuf_crypto_client::generate_key(const psa_key_attributes_t *attributes, psa_key_id_t *id)
+psa_status_t protobuf_crypto_client::generate_key(const psa_key_attributes_t *attributes,
+ psa_key_id_t *id)
{
- size_t req_len;
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_GenerateKeyIn req_msg = ts_crypto_GenerateKeyIn_init_default;
+ size_t req_len;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_GenerateKeyIn req_msg = ts_crypto_GenerateKeyIn_init_default;
- translate_key_attributes(req_msg.attributes, *attributes);
- req_msg.has_attributes = true;
+ translate_key_attributes(req_msg.attributes, *attributes);
+ req_msg.has_attributes = true;
- if (pb_get_encoded_size(&req_len, ts_crypto_GenerateKeyIn_fields, &req_msg)) {
+ if (pb_get_encoded_size(&req_len, ts_crypto_GenerateKeyIn_fields, &req_msg)) {
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_GenerateKeyIn_fields, &req_msg);
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_GenerateKeyIn_fields, &req_msg);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_GENERATE_KEY, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_GENERATE_KEY, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- ts_crypto_GenerateKeyOut resp_msg = ts_crypto_GenerateKeyOut_init_default;
- pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+ ts_crypto_GenerateKeyOut resp_msg = ts_crypto_GenerateKeyOut_init_default;
+ pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
- if (pb_decode(&istream, ts_crypto_GenerateKeyOut_fields, &resp_msg)) {
+ if (pb_decode(&istream, ts_crypto_GenerateKeyOut_fields, &resp_msg)) {
- *id = resp_msg.id;
- }
- else {
- /* Failed to decode response message */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
+ *id = resp_msg.id;
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t protobuf_crypto_client::destroy_key(psa_key_id_t id)
{
- size_t req_len;
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_DestroyKeyIn req_msg = ts_crypto_DestroyKeyIn_init_default;
+ size_t req_len;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_DestroyKeyIn req_msg = ts_crypto_DestroyKeyIn_init_default;
- req_msg.id = id;
+ req_msg.id = id;
- if (pb_get_encoded_size(&req_len, ts_crypto_DestroyKeyIn_fields, &req_msg)) {
+ if (pb_get_encoded_size(&req_len, ts_crypto_DestroyKeyIn_fields, &req_msg)) {
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_DestroyKeyIn_fields, &req_msg);
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_DestroyKeyIn_fields, &req_msg);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_DESTROY_KEY, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_DESTROY_KEY, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
- rpc_caller_end(m_caller, call_handle);
- }
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t protobuf_crypto_client::import_key(const psa_key_attributes_t *attributes,
- const uint8_t *data, size_t data_length, psa_key_id_t *id)
+ const uint8_t *data, size_t data_length, psa_key_id_t *id)
{
- size_t req_len;
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_ImportKeyIn req_msg = ts_crypto_ImportKeyIn_init_default;
- pb_bytes_array_t *key_byte_array = pb_malloc_byte_array_containing_bytes(data, data_length);
+ size_t req_len;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_ImportKeyIn req_msg = ts_crypto_ImportKeyIn_init_default;
+ pb_bytes_array_t *key_byte_array =
+ pb_malloc_byte_array_containing_bytes(data, data_length);
- translate_key_attributes(req_msg.attributes, *attributes);
- req_msg.has_attributes = true;
- req_msg.data = pb_out_byte_array(key_byte_array);
+ translate_key_attributes(req_msg.attributes, *attributes);
+ req_msg.has_attributes = true;
+ req_msg.data = pb_out_byte_array(key_byte_array);
- if (pb_get_encoded_size(&req_len, ts_crypto_ImportKeyIn_fields, &req_msg)) {
+ if (pb_get_encoded_size(&req_len, ts_crypto_ImportKeyIn_fields, &req_msg)) {
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_ImportKeyIn_fields, &req_msg);
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_ImportKeyIn_fields, &req_msg);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_IMPORT_KEY, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_IMPORT_KEY, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- ts_crypto_ImportKeyOut resp_msg = ts_crypto_ImportKeyOut_init_default;
- pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+ ts_crypto_ImportKeyOut resp_msg = ts_crypto_ImportKeyOut_init_default;
+ pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
- if (pb_decode(&istream, ts_crypto_ImportKeyOut_fields, &resp_msg)) {
+ if (pb_decode(&istream, ts_crypto_ImportKeyOut_fields, &resp_msg)) {
- *id = resp_msg.id;
- }
- else {
- /* Failed to decode response message */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
+ *id = resp_msg.id;
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
- ::free(key_byte_array);
+ ::free(key_byte_array);
- return psa_status;
+ return psa_status;
}
psa_status_t protobuf_crypto_client::export_key(psa_key_id_t id,
- uint8_t *data, size_t data_size,
- size_t *data_length)
+ uint8_t *data, size_t data_size,
+ size_t *data_length)
{
- size_t req_len;
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_ExportKeyIn req_msg = ts_crypto_ExportKeyIn_init_default;
- req_msg.id = id;
+ size_t req_len;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_ExportKeyIn req_msg = ts_crypto_ExportKeyIn_init_default;
+ req_msg.id = id;
- *data_length = 0; /* For failure case */
+ *data_length = 0; /* For failure case */
if (pb_get_encoded_size(&req_len, ts_crypto_ExportKeyIn_fields, &req_msg)) {
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_ExportKeyIn_fields, &req_msg);
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_ExportKeyIn_fields, &req_msg);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_EXPORT_KEY, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_EXPORT_KEY, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- ts_crypto_ExportKeyOut resp_msg = ts_crypto_ExportKeyOut_init_default;
- pb_bytes_array_t *exported_key = pb_malloc_byte_array(resp_len);
+ ts_crypto_ExportKeyOut resp_msg = ts_crypto_ExportKeyOut_init_default;
+ pb_bytes_array_t *exported_key = pb_malloc_byte_array(resp_len);
- if (exported_key) {
+ if (exported_key) {
- resp_msg.data = pb_in_byte_array(exported_key);
- pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+ resp_msg.data = pb_in_byte_array(exported_key);
+ pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
- if (pb_decode(&istream, ts_crypto_ExportKeyOut_fields, &resp_msg)) {
+ if (pb_decode(&istream, ts_crypto_ExportKeyOut_fields, &resp_msg)) {
- if (exported_key->size <= data_size) {
+ if (exported_key->size <= data_size) {
- memcpy(data, exported_key->bytes, exported_key->size);
- *data_length = exported_key->size;
- }
- else {
- /* Provided buffer is too small */
- psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Failed to decode response message */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
+ memcpy(data, exported_key->bytes, exported_key->size);
+ *data_length = exported_key->size;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
- ::free(exported_key);
- }
- else {
- /* Failed to allocate buffer for exported key */
- psa_status = PSA_ERROR_INSUFFICIENT_MEMORY;
- }
- }
- }
+ ::free(exported_key);
+ }
+ else {
+ /* Failed to allocate buffer for exported key */
+ psa_status = PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t protobuf_crypto_client::export_public_key(psa_key_id_t id,
- uint8_t *data, size_t data_size, size_t *data_length)
+ uint8_t *data, size_t data_size, size_t *data_length)
{
- size_t req_len;
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_ExportPublicKeyIn req_msg = ts_crypto_ExportPublicKeyIn_init_default;
- req_msg.id = id;
+ size_t req_len;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_ExportPublicKeyIn req_msg = ts_crypto_ExportPublicKeyIn_init_default;
+ req_msg.id = id;
- *data_length = 0; /* For failure case */
+ *data_length = 0; /* For failure case */
if (pb_get_encoded_size(&req_len, ts_crypto_ExportPublicKeyIn_fields, &req_msg)) {
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_ExportPublicKeyIn_fields, &req_msg);
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_ExportPublicKeyIn_fields, &req_msg);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_EXPORT_PUBLIC_KEY, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_EXPORT_PUBLIC_KEY, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- ts_crypto_ExportPublicKeyOut resp_msg = ts_crypto_ExportPublicKeyOut_init_default;
- pb_bytes_array_t *exported_key = pb_malloc_byte_array(resp_len);
+ ts_crypto_ExportPublicKeyOut resp_msg =
+ ts_crypto_ExportPublicKeyOut_init_default;
+ pb_bytes_array_t *exported_key = pb_malloc_byte_array(resp_len);
- if (exported_key) {
+ if (exported_key) {
- resp_msg.data = pb_in_byte_array(exported_key);
- pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+ resp_msg.data = pb_in_byte_array(exported_key);
+ pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
- if (pb_decode(&istream, ts_crypto_ExportPublicKeyOut_fields, &resp_msg)) {
+ if (pb_decode(&istream, ts_crypto_ExportPublicKeyOut_fields, &resp_msg)) {
- if (exported_key->size <= data_size) {
+ if (exported_key->size <= data_size) {
- memcpy(data, exported_key->bytes, exported_key->size);
- *data_length = exported_key->size;
- }
- else {
- /* Provided buffer is too small */
- psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Failed to decode response message */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
+ memcpy(data, exported_key->bytes, exported_key->size);
+ *data_length = exported_key->size;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
- ::free(exported_key);
- }
- else {
- /* Failed to alloocate buffer for exported key */
- psa_status = PSA_ERROR_INSUFFICIENT_MEMORY;
- }
- }
- }
+ ::free(exported_key);
+ }
+ else {
+ /* Failed to alloocate buffer for exported key */
+ psa_status = PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
- return psa_status;
+ return psa_status;
}
psa_status_t protobuf_crypto_client::sign_hash(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *hash, size_t hash_length,
- uint8_t *signature, size_t signature_size, size_t *signature_length)
+ const uint8_t *hash, size_t hash_length,
+ uint8_t *signature, size_t signature_size, size_t *signature_length)
{
- size_t req_len;
- pb_bytes_array_t *hash_byte_array = pb_malloc_byte_array_containing_bytes(hash, hash_length);
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_SignHashIn req_msg = ts_crypto_SignHashIn_init_default;
+ size_t req_len;
+ pb_bytes_array_t *hash_byte_array =
+ pb_malloc_byte_array_containing_bytes(hash, hash_length);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_SignHashIn req_msg = ts_crypto_SignHashIn_init_default;
- *signature_length = 0; /* For failure case */
+ *signature_length = 0; /* For failure case */
- req_msg.id = id;
- req_msg.alg = alg;
+ req_msg.id = id;
+ req_msg.alg = alg;
req_msg.hash = pb_out_byte_array(hash_byte_array);
if (pb_get_encoded_size(&req_len, ts_crypto_SignHashIn_fields, &req_msg)) {
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_SignHashIn_fields, &req_msg);
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_SignHashIn_fields, &req_msg);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_SIGN_HASH, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_SIGN_HASH, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- pb_bytes_array_t *sig_byte_array = pb_malloc_byte_array(PSA_SIGNATURE_MAX_SIZE);
- ts_crypto_SignHashOut resp_msg = ts_crypto_SignHashOut_init_default;
- resp_msg.signature = pb_in_byte_array(sig_byte_array);
+ pb_bytes_array_t *sig_byte_array =
+ pb_malloc_byte_array(PSA_SIGNATURE_MAX_SIZE);
+ ts_crypto_SignHashOut resp_msg = ts_crypto_SignHashOut_init_default;
+ resp_msg.signature = pb_in_byte_array(sig_byte_array);
- pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+ pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
- if (pb_decode(&istream, ts_crypto_SignHashOut_fields, &resp_msg)) {
+ if (pb_decode(&istream, ts_crypto_SignHashOut_fields, &resp_msg)) {
- if (sig_byte_array->size <= signature_size) {
+ if (sig_byte_array->size <= signature_size) {
- memcpy(signature, sig_byte_array->bytes, sig_byte_array->size);
- *signature_length = sig_byte_array->size;
- }
- else {
- /* Provided buffer is too small */
- psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Failed to decode response message */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
+ memcpy(signature,
+ sig_byte_array->bytes, sig_byte_array->size);
+ *signature_length = sig_byte_array->size;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
- ::free(sig_byte_array);
- }
- }
+ ::free(sig_byte_array);
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
- ::free(hash_byte_array);
+ ::free(hash_byte_array);
- return psa_status;
+ return psa_status;
}
psa_status_t protobuf_crypto_client::verify_hash(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *hash, size_t hash_length,
- const uint8_t *signature, size_t signature_length)
+ const uint8_t *hash, size_t hash_length,
+ const uint8_t *signature, size_t signature_length)
{
- size_t req_len;
- pb_bytes_array_t *hash_byte_array = pb_malloc_byte_array_containing_bytes(hash, hash_length);
- pb_bytes_array_t *sig_byte_array = pb_malloc_byte_array_containing_bytes(signature, signature_length);
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_VerifyHashIn req_msg = ts_crypto_VerifyHashIn_init_default;
-
- req_msg.id = id;
- req_msg.alg = alg;
+ size_t req_len;
+ pb_bytes_array_t *hash_byte_array =
+ pb_malloc_byte_array_containing_bytes(hash, hash_length);
+ pb_bytes_array_t *sig_byte_array =
+ pb_malloc_byte_array_containing_bytes(signature, signature_length);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_VerifyHashIn req_msg = ts_crypto_VerifyHashIn_init_default;
+
+ req_msg.id = id;
+ req_msg.alg = alg;
req_msg.hash = pb_out_byte_array(hash_byte_array);
- req_msg.signature = pb_out_byte_array(sig_byte_array);
+ req_msg.signature = pb_out_byte_array(sig_byte_array);
if (pb_get_encoded_size(&req_len, ts_crypto_VerifyHashIn_fields, &req_msg)) {
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_VerifyHashIn_fields, &req_msg);
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_VerifyHashIn_fields, &req_msg);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_VERIFY_HASH, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_VERIFY_HASH, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
- rpc_caller_end(m_caller, call_handle);
- }
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
- ::free(hash_byte_array);
- ::free(sig_byte_array);
+ ::free(hash_byte_array);
+ ::free(sig_byte_array);
- return psa_status;
+ return psa_status;
}
psa_status_t protobuf_crypto_client::asymmetric_encrypt(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *input, size_t input_length,
- const uint8_t *salt, size_t salt_length,
- uint8_t *output, size_t output_size, size_t *output_length)
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length)
{
- size_t req_len;
- pb_bytes_array_t *plaintext_byte_array = pb_malloc_byte_array_containing_bytes(input, input_length);
- pb_bytes_array_t *salt_byte_array = pb_malloc_byte_array_containing_bytes(salt, salt_length);
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_AsymmetricEncryptIn req_msg = ts_crypto_AsymmetricEncryptIn_init_default;
-
- *output_length = 0; /* For failure case */
-
- req_msg.id = id;
- req_msg.alg = alg;
+ size_t req_len;
+ pb_bytes_array_t *plaintext_byte_array =
+ pb_malloc_byte_array_containing_bytes(input, input_length);
+ pb_bytes_array_t *salt_byte_array =
+ pb_malloc_byte_array_containing_bytes(salt, salt_length);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_AsymmetricEncryptIn req_msg = ts_crypto_AsymmetricEncryptIn_init_default;
+
+ *output_length = 0; /* For failure case */
+
+ req_msg.id = id;
+ req_msg.alg = alg;
req_msg.plaintext = pb_out_byte_array(plaintext_byte_array);
- req_msg.salt = pb_out_byte_array(salt_byte_array);
+ req_msg.salt = pb_out_byte_array(salt_byte_array);
if (pb_get_encoded_size(&req_len, ts_crypto_AsymmetricEncryptIn_fields, &req_msg)) {
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus = PSA_ERROR_GENERIC_ERROR;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus = PSA_ERROR_GENERIC_ERROR;
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_AsymmetricEncryptIn_fields, &req_msg);
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_AsymmetricEncryptIn_fields, &req_msg);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_ASYMMETRIC_ENCRYPT, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_ASYMMETRIC_ENCRYPT, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- pb_bytes_array_t *ciphertext_byte_array = pb_malloc_byte_array(output_size);
- ts_crypto_AsymmetricEncryptOut resp_msg = ts_crypto_AsymmetricEncryptOut_init_default;
- resp_msg.ciphertext = pb_in_byte_array(ciphertext_byte_array);
+ pb_bytes_array_t *ciphertext_byte_array = pb_malloc_byte_array(output_size);
+ ts_crypto_AsymmetricEncryptOut resp_msg =
+ ts_crypto_AsymmetricEncryptOut_init_default;
+ resp_msg.ciphertext = pb_in_byte_array(ciphertext_byte_array);
- pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+ pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
- if (pb_decode(&istream, ts_crypto_AsymmetricEncryptOut_fields, &resp_msg)) {
+ if (pb_decode(&istream, ts_crypto_AsymmetricEncryptOut_fields, &resp_msg)) {
- if (ciphertext_byte_array->size <= output_size) {
+ if (ciphertext_byte_array->size <= output_size) {
- memcpy(output, ciphertext_byte_array->bytes, ciphertext_byte_array->size);
- *output_length = ciphertext_byte_array->size;
- }
- else {
- /* Provided buffer is too small */
- psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Failed to decode response message */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
+ memcpy(output,
+ ciphertext_byte_array->bytes, ciphertext_byte_array->size);
+ *output_length = ciphertext_byte_array->size;
+ }
+ else {
+ /* Provided buffer is too small */
+ psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
- ::free(ciphertext_byte_array);
- }
- }
+ ::free(ciphertext_byte_array);
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
- ::free(plaintext_byte_array);
- ::free(salt_byte_array);
+ ::free(plaintext_byte_array);
+ ::free(salt_byte_array);
- return psa_status;
+ return psa_status;
}
psa_status_t protobuf_crypto_client::asymmetric_decrypt(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *input, size_t input_length,
- const uint8_t *salt, size_t salt_length,
- uint8_t *output, size_t output_size, size_t *output_length)
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length)
{
- size_t req_len;
- pb_bytes_array_t *ciphertext_byte_array = pb_malloc_byte_array_containing_bytes(input, input_length);
- pb_bytes_array_t *salt_byte_array = pb_malloc_byte_array_containing_bytes(salt, salt_length);
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_AsymmetricDecryptIn req_msg = ts_crypto_AsymmetricDecryptIn_init_default;
-
- *output_length = 0; /* For failure case */
-
- req_msg.id = id;
- req_msg.alg = alg;
+ size_t req_len;
+ pb_bytes_array_t *ciphertext_byte_array =
+ pb_malloc_byte_array_containing_bytes(input, input_length);
+ pb_bytes_array_t *salt_byte_array =
+ pb_malloc_byte_array_containing_bytes(salt, salt_length);
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_AsymmetricDecryptIn req_msg = ts_crypto_AsymmetricDecryptIn_init_default;
+
+ *output_length = 0; /* For failure case */
+
+ req_msg.id = id;
+ req_msg.alg = alg;
req_msg.ciphertext = pb_out_byte_array(ciphertext_byte_array);
- req_msg.salt = pb_out_byte_array(salt_byte_array);
+ req_msg.salt = pb_out_byte_array(salt_byte_array);
if (pb_get_encoded_size(&req_len, ts_crypto_AsymmetricDecryptIn_fields, &req_msg)) {
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_AsymmetricDecryptIn_fields, &req_msg);
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_AsymmetricDecryptIn_fields, &req_msg);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_ASYMMETRIC_DECRYPT, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_ASYMMETRIC_DECRYPT, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- pb_bytes_array_t *plaintext_byte_array = pb_malloc_byte_array(output_size);
- ts_crypto_AsymmetricDecryptOut resp_msg = ts_crypto_AsymmetricDecryptOut_init_default;
- resp_msg.plaintext = pb_in_byte_array(plaintext_byte_array);
+ pb_bytes_array_t *plaintext_byte_array = pb_malloc_byte_array(output_size);
+ ts_crypto_AsymmetricDecryptOut resp_msg =
+ ts_crypto_AsymmetricDecryptOut_init_default;
+ resp_msg.plaintext = pb_in_byte_array(plaintext_byte_array);
- pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+ pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
- if (pb_decode(&istream, ts_crypto_AsymmetricDecryptOut_fields, &resp_msg)) {
+ if (pb_decode(&istream, ts_crypto_AsymmetricDecryptOut_fields, &resp_msg)) {
- if (plaintext_byte_array->size <= output_size) {
+ if (plaintext_byte_array->size <= output_size) {
- memcpy(output, plaintext_byte_array->bytes, plaintext_byte_array->size);
- *output_length = plaintext_byte_array->size;
- }
- else {
- /* Provided buffer is too small */
- m_err_rpc_status = PSA_ERROR_BUFFER_TOO_SMALL;
- }
- }
- else {
- /* Failed to decode response message */
- m_err_rpc_status = PSA_ERROR_GENERIC_ERROR;
- }
+ memcpy(output,
+ plaintext_byte_array->bytes, plaintext_byte_array->size);
+ *output_length = plaintext_byte_array->size;
+ }
+ else {
+ /* Provided buffer is too small */
+ m_err_rpc_status = PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ }
+ else {
+ /* Failed to decode response message */
+ m_err_rpc_status = PSA_ERROR_GENERIC_ERROR;
+ }
- ::free(plaintext_byte_array);
- }
- }
+ ::free(plaintext_byte_array);
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
- ::free(ciphertext_byte_array);
- ::free(salt_byte_array);
+ ::free(ciphertext_byte_array);
+ ::free(salt_byte_array);
- return psa_status;
+ return psa_status;
}
psa_status_t protobuf_crypto_client::generate_random(uint8_t *output, size_t output_size)
{
- size_t req_len;
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_GenerateRandomIn req_msg = ts_crypto_GenerateRandomIn_init_default;
+ size_t req_len;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_GenerateRandomIn req_msg = ts_crypto_GenerateRandomIn_init_default;
- req_msg.size = output_size;
+ req_msg.size = output_size;
if (pb_get_encoded_size(&req_len, ts_crypto_GenerateRandomIn_fields, &req_msg)) {
- rpc_call_handle call_handle;
- uint8_t *req_buf;
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
- if (call_handle) {
+ if (call_handle) {
- uint8_t *resp_buf;
- size_t resp_len;
- int opstatus;
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_GenerateRandomIn_fields, &req_msg);
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_GenerateRandomIn_fields, &req_msg);
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_GENERATE_RANDOM, &opstatus, &resp_buf, &resp_len);
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_GENERATE_RANDOM, &opstatus, &resp_buf, &resp_len);
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status = opstatus;
+ psa_status = opstatus;
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- pb_bytes_array_t *output_byte_array = pb_malloc_byte_array(output_size);
- ts_crypto_GenerateRandomOut resp_msg = ts_crypto_GenerateRandomOut_init_default;
- resp_msg.random_bytes = pb_in_byte_array(output_byte_array);
+ pb_bytes_array_t *output_byte_array = pb_malloc_byte_array(output_size);
+ ts_crypto_GenerateRandomOut resp_msg = ts_crypto_GenerateRandomOut_init_default;
+ resp_msg.random_bytes = pb_in_byte_array(output_byte_array);
- pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+ pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
- if (pb_decode(&istream, ts_crypto_GenerateRandomOut_fields, &resp_msg)) {
+ if (pb_decode(&istream, ts_crypto_GenerateRandomOut_fields, &resp_msg)) {
- if (output_byte_array->size == output_size) {
+ if (output_byte_array->size == output_size) {
- memcpy(output, output_byte_array->bytes, output_byte_array->size);
- }
- else {
- /* Mismatch between requested and generated length */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- else {
- /* Failed to decode response message */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
+ memcpy(output, output_byte_array->bytes, output_byte_array->size);
+ }
+ else {
+ /* Mismatch between requested and generated length */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
- ::free(output_byte_array);
- }
- }
+ ::free(output_byte_array);
+ }
+ }
- rpc_caller_end(m_caller, call_handle);
- }
- }
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
- return psa_status;
+ return psa_status;
+}
+
+psa_status_t protobuf_crypto_client::hash_setup(uint32_t *op_handle,
+ psa_algorithm_t alg)
+{
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+psa_status_t protobuf_crypto_client::hash_update(uint32_t op_handle,
+ const uint8_t *input, size_t input_length)
+{
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+psa_status_t protobuf_crypto_client::hash_finish(uint32_t op_handle,
+ uint8_t *hash, size_t hash_size, size_t *hash_length)
+{
+ return PSA_ERROR_NOT_SUPPORTED;
}
void protobuf_crypto_client::translate_key_attributes(ts_crypto_KeyAttributes &proto_attributes,
- const psa_key_attributes_t &psa_attributes)
+ const psa_key_attributes_t &psa_attributes)
{
- proto_attributes.type = psa_get_key_type(&psa_attributes);
- proto_attributes.key_bits = psa_get_key_bits(&psa_attributes);
- proto_attributes.lifetime = psa_get_key_lifetime(&psa_attributes);
- proto_attributes.id = psa_get_key_id(&psa_attributes);
-
- proto_attributes.has_policy = true;
- proto_attributes.policy.usage = psa_get_key_usage_flags(&psa_attributes);
- proto_attributes.policy.alg = psa_get_key_algorithm(&psa_attributes);
+ proto_attributes.type = psa_get_key_type(&psa_attributes);
+ proto_attributes.key_bits = psa_get_key_bits(&psa_attributes);
+ proto_attributes.lifetime = psa_get_key_lifetime(&psa_attributes);
+ proto_attributes.id = psa_get_key_id(&psa_attributes);
+
+ proto_attributes.has_policy = true;
+ proto_attributes.policy.usage = psa_get_key_usage_flags(&psa_attributes);
+ proto_attributes.policy.alg = psa_get_key_algorithm(&psa_attributes);
}
diff --git a/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.h b/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.h
index 0ada2ca57..bc407d145 100644
--- a/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.h
+++ b/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.h
@@ -16,48 +16,56 @@
class protobuf_crypto_client : public crypto_client
{
public:
- protobuf_crypto_client();
- protobuf_crypto_client(struct rpc_caller *caller);
- virtual ~protobuf_crypto_client();
-
- /* Key lifecycle methods */
- psa_status_t generate_key(const psa_key_attributes_t *attributes, psa_key_id_t *id);
- psa_status_t destroy_key(psa_key_id_t id);
- psa_status_t import_key(const psa_key_attributes_t *attributes,
- const uint8_t *data, size_t data_length, psa_key_id_t *id);
-
- /* Key export methods */
- psa_status_t export_key(psa_key_id_t id,
- uint8_t *data, size_t data_size,
- size_t *data_length);
- psa_status_t export_public_key(psa_key_id_t id,
- uint8_t *data, size_t data_size, size_t *data_length);
-
- /* Sign/verify methods */
- psa_status_t sign_hash(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *hash, size_t hash_length,
- uint8_t *signature, size_t signature_size, size_t *signature_length);
- psa_status_t verify_hash(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *hash, size_t hash_length,
- const uint8_t *signature, size_t signature_length);
-
- /* Asymmetric encrypt/decrypt */
- psa_status_t asymmetric_encrypt(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *input, size_t input_length,
- const uint8_t *salt, size_t salt_length,
- uint8_t *output, size_t output_size, size_t *output_length);
- psa_status_t asymmetric_decrypt(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *input, size_t input_length,
- const uint8_t *salt, size_t salt_length,
- uint8_t *output, size_t output_size, size_t *output_length);
-
- /* Random number generation */
- psa_status_t generate_random(uint8_t *output, size_t output_size);
+ protobuf_crypto_client();
+ protobuf_crypto_client(struct rpc_caller *caller);
+ virtual ~protobuf_crypto_client();
+
+ /* Key lifecycle methods */
+ psa_status_t generate_key(const psa_key_attributes_t *attributes, psa_key_id_t *id);
+ psa_status_t destroy_key(psa_key_id_t id);
+ psa_status_t import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data, size_t data_length, psa_key_id_t *id);
+
+ /* Key export methods */
+ psa_status_t export_key(psa_key_id_t id,
+ uint8_t *data, size_t data_size,
+ size_t *data_length);
+ psa_status_t export_public_key(psa_key_id_t id,
+ uint8_t *data, size_t data_size, size_t *data_length);
+
+ /* Sign/verify methods */
+ psa_status_t sign_hash(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *hash, size_t hash_length,
+ uint8_t *signature, size_t signature_size, size_t *signature_length);
+ psa_status_t verify_hash(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *hash, size_t hash_length,
+ const uint8_t *signature, size_t signature_length);
+
+ /* Asymmetric encrypt/decrypt */
+ psa_status_t asymmetric_encrypt(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length);
+ psa_status_t asymmetric_decrypt(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length);
+
+ /* Random number generation */
+ psa_status_t generate_random(uint8_t *output, size_t output_size);
+
+ /* Hash methods */
+ psa_status_t hash_setup(uint32_t *op_handle,
+ psa_algorithm_t alg);
+ psa_status_t hash_update(uint32_t op_handle,
+ const uint8_t *input, size_t input_length);
+ psa_status_t hash_finish(uint32_t op_handle,
+ uint8_t *hash, size_t hash_size, size_t *hash_length);
private:
- void translate_key_attributes(ts_crypto_KeyAttributes &proto_attributes,
- const psa_key_attributes_t &psa_attributes);
+ void translate_key_attributes(ts_crypto_KeyAttributes &proto_attributes,
+ const psa_key_attributes_t &psa_attributes);
};
#endif /* PROTOBUF_CRYPTO_CLIENT_H */
diff --git a/components/service/crypto/provider/mbedcrypto/component.cmake b/components/service/crypto/provider/mbedcrypto/component.cmake
index 0df1138ec..6413cb9a2 100644
--- a/components/service/crypto/provider/mbedcrypto/component.cmake
+++ b/components/service/crypto/provider/mbedcrypto/component.cmake
@@ -10,6 +10,7 @@ endif()
target_sources(${TGT} PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/crypto_provider.c"
+ "${CMAKE_CURRENT_LIST_DIR}/crypto_context_pool.c"
)
target_include_directories(${TGT}
diff --git a/components/service/crypto/provider/mbedcrypto/crypto_context_pool.c b/components/service/crypto/provider/mbedcrypto/crypto_context_pool.c
new file mode 100644
index 000000000..753cb9fbe
--- /dev/null
+++ b/components/service/crypto/provider/mbedcrypto/crypto_context_pool.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+#include "crypto_context_pool.h"
+
+static void add_to_free_list(struct crypto_context_pool *pool,
+ struct crypto_context *context);
+
+static uint32_t alloc_op_handle(struct crypto_context_pool *pool);
+static bool op_handle_in_use(struct crypto_context_pool *pool, uint32_t candidate);
+
+
+void crypto_context_pool_init(struct crypto_context_pool *pool)
+{
+ pool->free = NULL;
+ pool->active_head = NULL;
+ pool->active_tail = NULL;
+ pool->most_recent_op_handle = 0;
+
+ for (size_t i = 0; i < CRYPTO_CONTEXT_POOL_SIZE; i++) {
+
+ add_to_free_list(pool, &pool->contexts[i]);
+ }
+}
+
+void crypto_context_pool_deinit(struct crypto_context_pool *pool)
+{
+ (void)pool;
+}
+
+struct crypto_context *crypto_context_pool_alloc(struct crypto_context_pool *pool,
+ enum crypto_context_op_id usage,
+ uint32_t client_id,
+ uint32_t *op_handle)
+{
+ struct crypto_context *context = NULL;
+
+ /* Re-cycle least-recently used context if there are no free contexts */
+ if (!pool->free && pool->active_tail) crypto_context_pool_free(pool, pool->active_tail);
+
+ /* Active context are held in a linked list in most recently allocated order */
+ if (pool->free) {
+
+ context = pool->free;
+ pool->free = context->next;
+
+ context->next = pool->active_head;
+ context->prev = NULL;
+ pool->active_head = context;
+
+ if (!pool->active_tail) pool->active_tail = context;
+ if (context->next) context->next->prev = context;
+
+ context->usage = usage;
+ context->client_id = client_id;
+
+ context->op_handle = alloc_op_handle(pool);
+ *op_handle = context->op_handle;
+ }
+
+ return context;
+}
+
+void crypto_context_pool_free(struct crypto_context_pool *pool,
+ struct crypto_context *context)
+{
+ /* Remove from active list */
+ if (context->prev) {
+ context->prev->next = context->next;
+ }
+ else {
+ pool->active_head = context->next;
+ }
+
+ if (context->next) {
+ context->next->prev = context->prev;
+ }
+ else {
+ pool->active_tail = context->prev;
+ }
+
+ /* Add to free list */
+ add_to_free_list(pool, context);
+}
+
+struct crypto_context *crypto_context_pool_find(struct crypto_context_pool *pool,
+ enum crypto_context_op_id usage,
+ uint32_t client_id,
+ uint32_t op_handle)
+{
+ /* Finds an active context that looks as though it legitimately belongs to the
+ * requesting client. Defends against bad behaviour from the client such
+ * as misusing a context for a different operation from the one that was
+ * setup.
+ */
+ struct crypto_context *found = NULL;
+ struct crypto_context *context = pool->active_head;
+
+ while (context) {
+
+ if ((context->op_handle == op_handle) &&
+ (context->usage == usage) &&
+ (context->client_id == client_id)) {
+
+ found = context;
+ break;
+ }
+
+ context = context->next;
+ }
+
+ return found;
+}
+
+static void add_to_free_list(struct crypto_context_pool *pool,
+ struct crypto_context *context)
+{
+ context->usage = CRYPTO_CONTEXT_OP_ID_NONE;
+ context->op_handle = 0;
+ context->next = pool->free;
+ context->prev = NULL;
+ pool->free = context;
+}
+
+static uint32_t alloc_op_handle(struct crypto_context_pool *pool)
+{
+ /* op handles need to be unique and to minimize the probability
+ * of a client using a stale handle that collides with a legitmately
+ * active one, use a rolling 32-bit integer.
+ */
+ uint32_t candidate = pool->most_recent_op_handle + 1;
+
+ while (op_handle_in_use(pool, candidate)) ++candidate;
+
+ pool->most_recent_op_handle = candidate;
+
+ return candidate;
+}
+
+static bool op_handle_in_use(struct crypto_context_pool *pool, uint32_t candidate)
+{
+ bool in_use = false;
+ struct crypto_context *context = pool->active_head;
+
+ while (context && !in_use) {
+
+ in_use = (candidate == context->op_handle);
+ context = context->next;
+ }
+
+ return in_use;
+}
diff --git a/components/service/crypto/provider/mbedcrypto/crypto_context_pool.h b/components/service/crypto/provider/mbedcrypto/crypto_context_pool.h
new file mode 100644
index 000000000..8d7e56497
--- /dev/null
+++ b/components/service/crypto/provider/mbedcrypto/crypto_context_pool.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CRYPTO_CONTEXT_POOL_H
+#define CRYPTO_CONTEXT_POOL_H
+
+#include <stdint.h>
+#include <psa/crypto.h>
+
+/**
+ * Some crypto transactions require state to be held between separate
+ * service operations. A typical multi-call transaction such as a
+ * hash calculation comprises a setup, one or more updates and a finish
+ * operation. This pool is used for allocating state context for multi-call
+ * transactions. For a well behaved client, a fresh context is allocated
+ * on a setup and freed on the finish. To cope with badly behaved clients
+ * that may never finish a transaction, if no free contexts are available
+ * for a new transaction, the least recently used active context is
+ * recycled.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Identifier for the operation type that a context is used for.
+ */
+enum crypto_context_op_id
+{
+ CRYPTO_CONTEXT_OP_ID_NONE,
+ CRYPTO_CONTEXT_OP_ID_HASH,
+ CRYPTO_CONTEXT_OP_ID_MAC,
+ CRYPTO_CONTEXT_OP_ID_CIPHER
+};
+
+/**
+ * A crypto context, used to hold state for a multi-step transaction.
+ */
+struct crypto_context
+{
+ enum crypto_context_op_id usage;
+ uint32_t client_id;
+ uint32_t op_handle;
+ struct crypto_context *next;
+ struct crypto_context *prev;
+
+ union context_variant
+ {
+ struct psa_hash_operation_s hash;
+ struct psa_mac_operation_s mac;
+ struct psa_cipher_operation_s cipher;
+ } op;
+};
+
+/**
+ * The default pool size. This may be overridden to meet the needs
+ * of a particular deployment.
+ */
+#ifndef CRYPTO_CONTEXT_POOL_SIZE
+#define CRYPTO_CONTEXT_POOL_SIZE (10)
+#endif
+
+/**
+ * The crypto context pool structure.
+ */
+struct crypto_context_pool
+{
+ struct crypto_context contexts[CRYPTO_CONTEXT_POOL_SIZE];
+ struct crypto_context *free;
+ struct crypto_context *active_head;
+ struct crypto_context *active_tail;
+ uint32_t most_recent_op_handle;
+};
+
+/*
+ * Initializes a crypto_context_pool, called once during setup.
+ */
+void crypto_context_pool_init(struct crypto_context_pool *pool);
+
+/*
+ * De-initializes a crypto_context_pool, called once during tear-down.
+ */
+void crypto_context_pool_deinit(struct crypto_context_pool *pool);
+
+/*
+ * Allocate a fresh context. On success, a pointer to a crypto_context object
+ * is returned and an op handle is provided for reacqiring the context during
+ * sunsequent operations.
+ */
+struct crypto_context *crypto_context_pool_alloc(struct crypto_context_pool *pool,
+ enum crypto_context_op_id usage,
+ uint32_t client_id,
+ uint32_t *op_handle);
+
+/*
+ * Frees a context after use.
+ */
+void crypto_context_pool_free(struct crypto_context_pool *pool,
+ struct crypto_context *context);
+
+/*
+ * Find an allocated context. Returns NULL is no qualifying context is held.
+ */
+struct crypto_context *crypto_context_pool_find(struct crypto_context_pool *pool,
+ enum crypto_context_op_id usage,
+ uint32_t client_id,
+ uint32_t op_handle);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CRYPTO_CONTEXT_POOL_H */
diff --git a/components/service/crypto/provider/mbedcrypto/crypto_provider.c b/components/service/crypto/provider/mbedcrypto/crypto_provider.c
index 1b2fffda9..292c18047 100644
--- a/components/service/crypto/provider/mbedcrypto/crypto_provider.c
+++ b/components/service/crypto/provider/mbedcrypto/crypto_provider.c
@@ -24,559 +24,697 @@ static rpc_status_t verify_hash_handler(void *context, struct call_req* req);
static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req);
static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req);
static rpc_status_t generate_random_handler(void *context, struct call_req* req);
+static rpc_status_t hash_setup_handler(void *context, struct call_req* req);
+static rpc_status_t hash_update_handler(void *context, struct call_req* req);
+static rpc_status_t hash_finish_handler(void *context, struct call_req* req);
/* Handler mapping table for service */
static const struct service_handler handler_table[] = {
- {TS_CRYPTO_OPCODE_NOP, nop_handler},
- {TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler},
- {TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler},
- {TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler},
- {TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler},
- {TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler},
- {TS_CRYPTO_OPCODE_SIGN_HASH, sign_hash_handler},
- {TS_CRYPTO_OPCODE_VERIFY_HASH, verify_hash_handler},
- {TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler},
- {TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler},
- {TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler}
+ {TS_CRYPTO_OPCODE_NOP, nop_handler},
+ {TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler},
+ {TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler},
+ {TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler},
+ {TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler},
+ {TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler},
+ {TS_CRYPTO_OPCODE_SIGN_HASH, sign_hash_handler},
+ {TS_CRYPTO_OPCODE_VERIFY_HASH, verify_hash_handler},
+ {TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler},
+ {TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler},
+ {TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler},
+ {TS_CRYPTO_OPCODE_HASH_SETUP, hash_setup_handler},
+ {TS_CRYPTO_OPCODE_HASH_UPDATE, hash_update_handler},
+ {TS_CRYPTO_OPCODE_HASH_FINISH, hash_finish_handler}
};
struct rpc_interface *mbed_crypto_provider_init(struct mbed_crypto_provider *context,
- struct storage_backend *storage_backend,
- int trng_instance)
+ struct storage_backend *storage_backend,
+ int trng_instance)
{
- struct rpc_interface *rpc_interface = NULL;
+ struct rpc_interface *rpc_interface = NULL;
- trng_adapter_init(trng_instance);
+ crypto_context_pool_init(&context->context_pool);
+ trng_adapter_init(trng_instance);
- /*
- * A storage provider is required for persistent key storage. As this
- * is a mandatory feature of the crypto service, insist on a storage
- * provider being available.
- */
- if (context && storage_backend) {
+ /*
+ * A storage provider is required for persistent key storage. As this
+ * is a mandatory feature of the crypto service, insist on a storage
+ * provider being available.
+ */
+ if (context && storage_backend) {
- for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
- context->serializers[encoding] = NULL;
+ for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
+ context->serializers[encoding] = NULL;
- service_provider_init(&context->base_provider, context,
- handler_table, sizeof(handler_table)/sizeof(struct service_handler));
+ service_provider_init(&context->base_provider, context,
+ handler_table, sizeof(handler_table)/sizeof(struct service_handler));
- if ((psa_its_frontend_init(storage_backend) == PSA_SUCCESS) &&
- (psa_crypto_init() == PSA_SUCCESS)) {
+ if ((psa_its_frontend_init(storage_backend) == PSA_SUCCESS) &&
+ (psa_crypto_init() == PSA_SUCCESS)) {
- rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
- }
- }
+ rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
+ }
+ }
- return rpc_interface;
+ return rpc_interface;
}
void mbed_crypto_provider_deinit(struct mbed_crypto_provider *context)
{
- (void)context;
- trng_adapter_deinit();
+ trng_adapter_deinit();
+ crypto_context_pool_deinit(&context->context_pool);
}
void mbed_crypto_provider_register_serializer(struct mbed_crypto_provider *context,
- unsigned int encoding, const struct crypto_provider_serializer *serializer)
+ unsigned int encoding, const struct crypto_provider_serializer *serializer)
{
- if (encoding < TS_RPC_ENCODING_LIMIT)
- context->serializers[encoding] = serializer;
+ if (encoding < TS_RPC_ENCODING_LIMIT)
+ context->serializers[encoding] = serializer;
}
static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
- const struct call_req *req)
+ const struct call_req *req)
{
- struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
- const struct crypto_provider_serializer* serializer = NULL;
- unsigned int encoding = call_req_get_encoding(req);
+ struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
+ const struct crypto_provider_serializer* serializer = NULL;
+ unsigned int encoding = call_req_get_encoding(req);
- if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
+ if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
- return serializer;
+ return serializer;
}
static rpc_status_t nop_handler(void *context, struct call_req* req)
{
- /* Responds to a request by returning success */
- rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
- psa_status_t psa_status = PSA_SUCCESS;
+ /* Responds to a request by returning success */
+ rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
+ psa_status_t psa_status = PSA_SUCCESS;
- (void)context;
- call_req_set_opstatus(req, psa_status);
+ (void)context;
+ call_req_set_opstatus(req, psa_status);
- return rpc_status;
+ return rpc_status;
}
static rpc_status_t generate_key_handler(void *context, struct call_req* req)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
- struct call_param_buf *req_buf = call_req_get_req_buf(req);
- const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- if (serializer)
- rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
+ if (serializer)
+ rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
- if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status_t psa_status;
- psa_key_id_t id;
+ psa_status_t psa_status;
+ psa_key_id_t id;
- psa_status = psa_generate_key(&attributes, &id);
+ psa_status = psa_generate_key(&attributes, &id);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
- rpc_status = serializer->serialize_generate_key_resp(resp_buf, id);
- }
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_generate_key_resp(resp_buf, id);
+ }
- call_req_set_opstatus(req, psa_status);
- }
+ call_req_set_opstatus(req, psa_status);
+ }
- psa_reset_key_attributes(&attributes);
+ psa_reset_key_attributes(&attributes);
- return rpc_status;
+ return rpc_status;
}
static rpc_status_t destroy_key_handler(void *context, struct call_req* req)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
- struct call_param_buf *req_buf = call_req_get_req_buf(req);
- const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
- psa_key_id_t id;
+ psa_key_id_t id;
- if (serializer)
- rpc_status = serializer->deserialize_destroy_key_req(req_buf, &id);
+ if (serializer)
+ rpc_status = serializer->deserialize_destroy_key_req(req_buf, &id);
- if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status_t psa_status;
+ psa_status_t psa_status;
- psa_status = psa_destroy_key(id);
- call_req_set_opstatus(req, psa_status);
- }
+ psa_status = psa_destroy_key(id);
+ call_req_set_opstatus(req, psa_status);
+ }
- return rpc_status;
+ return rpc_status;
}
static rpc_status_t export_key_handler(void *context, struct call_req* req)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
- struct call_param_buf *req_buf = call_req_get_req_buf(req);
- const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
- psa_key_id_t id;
+ psa_key_id_t id;
- if (serializer)
- rpc_status = serializer->deserialize_export_key_req(req_buf, &id);
+ if (serializer)
+ rpc_status = serializer->deserialize_export_key_req(req_buf, &id);
- if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status_t psa_status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t psa_status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_status = psa_get_key_attributes(id, &attributes);
+ psa_status = psa_get_key_attributes(id, &attributes);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- size_t max_export_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
- psa_get_key_type(&attributes),
- psa_get_key_bits(&attributes));
+ size_t max_export_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
+ psa_get_key_type(&attributes),
+ psa_get_key_bits(&attributes));
- uint8_t *key_buffer = malloc(max_export_size);
+ uint8_t *key_buffer = malloc(max_export_size);
- if (key_buffer) {
+ if (key_buffer) {
- size_t export_size;
- psa_status = psa_export_key(id, key_buffer, max_export_size, &export_size);
+ size_t export_size;
+ psa_status = psa_export_key(id, key_buffer, max_export_size, &export_size);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
- rpc_status = serializer->serialize_export_key_resp(resp_buf, key_buffer, export_size);
- }
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_export_key_resp(resp_buf, key_buffer, export_size);
+ }
- free(key_buffer);
- }
- else {
- /* Failed to allocate key buffer */
- rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
- }
- }
+ free(key_buffer);
+ }
+ else {
+ /* Failed to allocate key buffer */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
- call_req_set_opstatus(req, psa_status);
- psa_reset_key_attributes(&attributes);
- }
+ call_req_set_opstatus(req, psa_status);
+ psa_reset_key_attributes(&attributes);
+ }
- return rpc_status;
+ return rpc_status;
}
static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
- struct call_param_buf *req_buf = call_req_get_req_buf(req);
- const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
- psa_key_id_t id;
+ psa_key_id_t id;
- if (serializer)
- rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
+ if (serializer)
+ rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
- if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status_t psa_status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t psa_status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_status = psa_get_key_attributes(id, &attributes);
+ psa_status = psa_get_key_attributes(id, &attributes);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(
- PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)),
- psa_get_key_bits(&attributes));
+ size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(
+ PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)),
+ psa_get_key_bits(&attributes));
- uint8_t *key_buffer = malloc(max_export_size);
+ uint8_t *key_buffer = malloc(max_export_size);
- if (key_buffer) {
+ if (key_buffer) {
- size_t export_size;
- psa_status = psa_export_public_key(id, key_buffer, max_export_size, &export_size);
+ size_t export_size;
+ psa_status = psa_export_public_key(id, key_buffer, max_export_size, &export_size);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
- rpc_status = serializer->serialize_export_public_key_resp(resp_buf, key_buffer, export_size);
- }
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_export_public_key_resp(resp_buf, key_buffer, export_size);
+ }
- free(key_buffer);
- }
- else {
- /* Failed to allocate key buffer */
- rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
- }
- }
+ free(key_buffer);
+ }
+ else {
+ /* Failed to allocate key buffer */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
- call_req_set_opstatus(req, psa_status);
- psa_reset_key_attributes(&attributes);
- }
+ call_req_set_opstatus(req, psa_status);
+ psa_reset_key_attributes(&attributes);
+ }
- return rpc_status;
+ return rpc_status;
}
static rpc_status_t import_key_handler(void *context, struct call_req* req)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
- struct call_param_buf *req_buf = call_req_get_req_buf(req);
- const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
- if (serializer) {
+ if (serializer) {
- size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
- uint8_t *key_buffer = malloc(key_data_len);
+ size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
+ uint8_t *key_buffer = malloc(key_data_len);
- if (key_buffer) {
+ if (key_buffer) {
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes, key_buffer, &key_data_len);
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes, key_buffer, &key_data_len);
- if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status_t psa_status;
- psa_key_id_t id;
+ psa_status_t psa_status;
+ psa_key_id_t id;
- psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &id);
+ psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &id);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
- rpc_status = serializer->serialize_import_key_resp(resp_buf, id);
- }
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_import_key_resp(resp_buf, id);
+ }
- call_req_set_opstatus(req, psa_status);
- }
+ call_req_set_opstatus(req, psa_status);
+ }
- psa_reset_key_attributes(&attributes);
- free(key_buffer);
- }
- else {
+ psa_reset_key_attributes(&attributes);
+ free(key_buffer);
+ }
+ else {
- rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
- }
- }
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
- return rpc_status;
+ return rpc_status;
}
static rpc_status_t sign_hash_handler(void *context, struct call_req* req)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
- struct call_param_buf *req_buf = call_req_get_req_buf(req);
- const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
- psa_key_id_t id;
- psa_algorithm_t alg;
- size_t hash_len = PSA_HASH_MAX_SIZE;
- uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
+ psa_key_id_t id;
+ psa_algorithm_t alg;
+ size_t hash_len = PSA_HASH_MAX_SIZE;
+ uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
- if (serializer)
- rpc_status = serializer->deserialize_sign_hash_req(req_buf, &id, &alg, hash_buffer, &hash_len);
+ if (serializer)
+ rpc_status = serializer->deserialize_sign_hash_req(req_buf, &id, &alg, hash_buffer, &hash_len);
- if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status_t psa_status;
- size_t sig_len;
- uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
+ psa_status_t psa_status;
+ size_t sig_len;
+ uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
- psa_status = psa_sign_hash(id, alg,
- hash_buffer, hash_len,
- sig_buffer, sizeof(sig_buffer), &sig_len);
+ psa_status = psa_sign_hash(id, alg,
+ hash_buffer, hash_len,
+ sig_buffer, sizeof(sig_buffer), &sig_len);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
- rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
- }
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
+ }
- call_req_set_opstatus(req, psa_status);
- }
+ call_req_set_opstatus(req, psa_status);
+ }
- return rpc_status;
+ return rpc_status;
}
static rpc_status_t verify_hash_handler(void *context, struct call_req* req)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
- struct call_param_buf *req_buf = call_req_get_req_buf(req);
- const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
- psa_key_id_t id;
- psa_algorithm_t alg;
- size_t hash_len = PSA_HASH_MAX_SIZE;
- uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
- size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
- uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
+ psa_key_id_t id;
+ psa_algorithm_t alg;
+ size_t hash_len = PSA_HASH_MAX_SIZE;
+ uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
+ size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
+ uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
- if (serializer)
- rpc_status = serializer->deserialize_verify_hash_req(req_buf, &id, &alg,
- hash_buffer, &hash_len,
- sig_buffer, &sig_len);
+ if (serializer)
+ rpc_status = serializer->deserialize_verify_hash_req(req_buf, &id, &alg,
+ hash_buffer, &hash_len,
+ sig_buffer, &sig_len);
- if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status_t psa_status;
+ psa_status_t psa_status;
- psa_status = psa_verify_hash(id, alg,
- hash_buffer, hash_len,
- sig_buffer, sig_len);
+ psa_status = psa_verify_hash(id, alg,
+ hash_buffer, hash_len,
+ sig_buffer, sig_len);
- call_req_set_opstatus(req, psa_status);
- }
+ call_req_set_opstatus(req, psa_status);
+ }
- return rpc_status;
+ return rpc_status;
}
static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
- struct call_param_buf *req_buf = call_req_get_req_buf(req);
- const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
- if (serializer) {
+ if (serializer) {
- size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
+ size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
- psa_key_id_t id;
- psa_algorithm_t alg;
- size_t ciphertext_len = max_param_size;
- uint8_t *ciphertext_buffer = malloc(ciphertext_len);
- size_t salt_len = max_param_size;
- uint8_t *salt_buffer = malloc(salt_len);
+ psa_key_id_t id;
+ psa_algorithm_t alg;
+ size_t ciphertext_len = max_param_size;
+ uint8_t *ciphertext_buffer = malloc(ciphertext_len);
+ size_t salt_len = max_param_size;
+ uint8_t *salt_buffer = malloc(salt_len);
- if (ciphertext_buffer && salt_buffer) {
+ if (ciphertext_buffer && salt_buffer) {
- rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
- &id, &alg,
- ciphertext_buffer, &ciphertext_len,
- salt_buffer, &salt_len);
+ rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
+ &id, &alg,
+ ciphertext_buffer, &ciphertext_len,
+ salt_buffer, &salt_len);
- if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status_t psa_status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t psa_status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_status = psa_get_key_attributes(id, &attributes);
+ psa_status = psa_get_key_attributes(id, &attributes);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
- psa_get_key_type(&attributes),
- psa_get_key_bits(&attributes),
- alg);
+ size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
+ psa_get_key_type(&attributes),
+ psa_get_key_bits(&attributes),
+ alg);
- size_t plaintext_len;
- uint8_t *plaintext_buffer = malloc(max_decrypt_size);
+ size_t plaintext_len;
+ uint8_t *plaintext_buffer = malloc(max_decrypt_size);
- if (plaintext_buffer) {
+ if (plaintext_buffer) {
- /* Salt is an optional parameter */
- uint8_t *salt = (salt_len) ? salt_buffer : NULL;
+ /* Salt is an optional parameter */
+ uint8_t *salt = (salt_len) ? salt_buffer : NULL;
- psa_status = psa_asymmetric_decrypt(id, alg,
- ciphertext_buffer, ciphertext_len,
- salt, salt_len,
- plaintext_buffer, max_decrypt_size, &plaintext_len);
+ psa_status = psa_asymmetric_decrypt(id, alg,
+ ciphertext_buffer, ciphertext_len,
+ salt, salt_len,
+ plaintext_buffer, max_decrypt_size, &plaintext_len);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
- rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
- plaintext_buffer, plaintext_len);
- }
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
+ plaintext_buffer, plaintext_len);
+ }
- free(plaintext_buffer);
- }
- else {
- /* Failed to allocate ouptput buffer */
- rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
- }
- }
+ free(plaintext_buffer);
+ }
+ else {
+ /* Failed to allocate ouptput buffer */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
- call_req_set_opstatus(req, psa_status);
- psa_reset_key_attributes(&attributes);
- }
- }
- else {
- /* Failed to allocate buffers */
- rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
- }
+ call_req_set_opstatus(req, psa_status);
+ psa_reset_key_attributes(&attributes);
+ }
+ }
+ else {
+ /* Failed to allocate buffers */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
- free(ciphertext_buffer);
- free(salt_buffer);
- }
+ free(ciphertext_buffer);
+ free(salt_buffer);
+ }
- return rpc_status;
+ return rpc_status;
}
static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
- struct call_param_buf *req_buf = call_req_get_req_buf(req);
- const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
- if (serializer) {
+ if (serializer) {
- size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
+ size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
- psa_key_id_t id;
- psa_algorithm_t alg;
- size_t plaintext_len = max_param_size;
- uint8_t *plaintext_buffer = malloc(plaintext_len);
- size_t salt_len = max_param_size;
- uint8_t *salt_buffer = malloc(salt_len);
+ psa_key_id_t id;
+ psa_algorithm_t alg;
+ size_t plaintext_len = max_param_size;
+ uint8_t *plaintext_buffer = malloc(plaintext_len);
+ size_t salt_len = max_param_size;
+ uint8_t *salt_buffer = malloc(salt_len);
- if (plaintext_buffer && salt_buffer) {
+ if (plaintext_buffer && salt_buffer) {
- rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
- &id, &alg,
- plaintext_buffer, &plaintext_len,
- salt_buffer, &salt_len);
+ rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
+ &id, &alg,
+ plaintext_buffer, &plaintext_len,
+ salt_buffer, &salt_len);
- if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status_t psa_status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t psa_status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_status = psa_get_key_attributes(id, &attributes);
+ psa_status = psa_get_key_attributes(id, &attributes);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
- psa_get_key_type(&attributes),
- psa_get_key_bits(&attributes),
- alg);
+ size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
+ psa_get_key_type(&attributes),
+ psa_get_key_bits(&attributes),
+ alg);
- size_t ciphertext_len;
- uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
+ size_t ciphertext_len;
+ uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
- if (ciphertext_buffer) {
+ if (ciphertext_buffer) {
- /* Salt is an optional parameter */
- uint8_t *salt = (salt_len) ? salt_buffer : NULL;
+ /* Salt is an optional parameter */
+ uint8_t *salt = (salt_len) ? salt_buffer : NULL;
- psa_status = psa_asymmetric_encrypt(id, alg,
- plaintext_buffer, plaintext_len,
- salt, salt_len,
- ciphertext_buffer, max_encrypt_size, &ciphertext_len);
+ psa_status = psa_asymmetric_encrypt(id, alg,
+ plaintext_buffer, plaintext_len,
+ salt, salt_len,
+ ciphertext_buffer, max_encrypt_size, &ciphertext_len);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
- rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
- ciphertext_buffer, ciphertext_len);
- }
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
+ ciphertext_buffer, ciphertext_len);
+ }
- free(ciphertext_buffer);
- }
- else {
- /* Failed to allocate ouptput buffer */
- rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
- }
- }
+ free(ciphertext_buffer);
+ }
+ else {
+ /* Failed to allocate ouptput buffer */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
- call_req_set_opstatus(req, psa_status);
- psa_reset_key_attributes(&attributes);
- }
- }
- else {
- /* Failed to allocate buffers */
- rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
- }
+ call_req_set_opstatus(req, psa_status);
+ psa_reset_key_attributes(&attributes);
+ }
+ }
+ else {
+ /* Failed to allocate buffers */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
- free(plaintext_buffer);
- free(salt_buffer);
- }
+ free(plaintext_buffer);
+ free(salt_buffer);
+ }
- return rpc_status;
+ return rpc_status;
}
static rpc_status_t generate_random_handler(void *context, struct call_req* req)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
- struct call_param_buf *req_buf = call_req_get_req_buf(req);
- const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
- size_t output_size;
+ size_t output_size;
- if (serializer)
- rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
+ if (serializer)
+ rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
- if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
- psa_status_t psa_status;
- uint8_t *output_buffer = malloc(output_size);
+ psa_status_t psa_status;
+ uint8_t *output_buffer = malloc(output_size);
- if (output_buffer) {
+ if (output_buffer) {
- psa_status = psa_generate_random(output_buffer, output_size);
+ psa_status = psa_generate_random(output_buffer, output_size);
- if (psa_status == PSA_SUCCESS) {
+ if (psa_status == PSA_SUCCESS) {
- struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
- rpc_status = serializer->serialize_generate_random_resp(resp_buf,
- output_buffer, output_size);
- }
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_generate_random_resp(resp_buf,
+ output_buffer, output_size);
+ }
- call_req_set_opstatus(req, psa_status);
- free(output_buffer);
- }
- else {
- /* Failed to allocate output buffer */
- rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
- }
- }
+ call_req_set_opstatus(req, psa_status);
+ free(output_buffer);
+ }
+ else {
+ /* Failed to allocate output buffer */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
- return rpc_status;
+ return rpc_status;
+}
+
+static rpc_status_t hash_setup_handler(void *context, struct call_req* req)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
+
+ psa_algorithm_t alg;
+
+ if (serializer)
+ rpc_status = serializer->deserialize_hash_setup_req(req_buf, &alg);
+
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ uint32_t op_handle;
+
+ struct crypto_context *crypto_context =
+ crypto_context_pool_alloc(&this_instance->context_pool,
+ CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
+ &op_handle);
+
+ if (crypto_context) {
+
+ psa_status_t psa_status;
+
+ crypto_context->op.hash = psa_hash_operation_init();
+ psa_status = psa_hash_setup(&crypto_context->op.hash, alg);
+
+ if (psa_status == PSA_SUCCESS) {
+
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_hash_setup_resp(resp_buf, op_handle);
+ }
+
+ if ((psa_status != PSA_SUCCESS) || (rpc_status != TS_RPC_CALL_ACCEPTED)) {
+
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
+
+ call_req_set_opstatus(req, psa_status);
+ }
+ else {
+ /* Failed to allocate crypto context for transaction */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t hash_update_handler(void *context, struct call_req* req)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
+
+ uint32_t op_handle;
+ const uint8_t *data;
+ size_t data_len;
+
+ if (serializer)
+ rpc_status = serializer->deserialize_hash_update_req(req_buf, &op_handle, &data, &data_len);
+
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ struct crypto_context *crypto_context =
+ crypto_context_pool_find(&this_instance->context_pool,
+ CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
+ op_handle);
+
+ if (crypto_context) {
+
+ psa_status_t psa_status = psa_hash_update(&crypto_context->op.hash, data, data_len);
+ call_req_set_opstatus(req, psa_status);
+ }
+ else {
+ /* Requested context doesn't exist */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t hash_finish_handler(void *context, struct call_req* req)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+ struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
+
+ uint32_t op_handle;
+
+ if (serializer)
+ rpc_status = serializer->deserialize_hash_finish_req(req_buf, &op_handle);
+
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ struct crypto_context *crypto_context =
+ crypto_context_pool_find(&this_instance->context_pool,
+ CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
+ op_handle);
+
+ if (crypto_context) {
+
+ psa_status_t psa_status;
+ size_t hash_len;
+ uint8_t hash[PSA_HASH_MAX_SIZE];
+
+ psa_status = psa_hash_finish(&crypto_context->op.hash, hash, sizeof(hash), &hash_len);
+
+ if (psa_status == PSA_SUCCESS) {
+
+ 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);
+
+ call_req_set_opstatus(req, psa_status);
+ }
+ else {
+ /* Requested context doesn't exist */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
+
+ return rpc_status;
}
diff --git a/components/service/crypto/provider/mbedcrypto/crypto_provider.h b/components/service/crypto/provider/mbedcrypto/crypto_provider.h
index 3c0f8d897..19bc2c2d7 100644
--- a/components/service/crypto/provider/mbedcrypto/crypto_provider.h
+++ b/components/service/crypto/provider/mbedcrypto/crypto_provider.h
@@ -12,6 +12,7 @@
#include <service/crypto/provider/serializer/crypto_provider_serializer.h>
#include <service/secure_storage/backend/storage_backend.h>
#include <protocols/rpc/common/packed-c/encoding.h>
+#include "crypto_context_pool.h"
#ifdef __cplusplus
extern "C" {
@@ -20,6 +21,7 @@ extern "C" {
struct mbed_crypto_provider
{
struct service_provider base_provider;
+ struct crypto_context_pool context_pool;
const struct crypto_provider_serializer *serializers[TS_RPC_ENCODING_LIMIT];
};
diff --git a/components/service/crypto/provider/mbedcrypto/test/component.cmake b/components/service/crypto/provider/mbedcrypto/test/component.cmake
new file mode 100644
index 000000000..4f754a226
--- /dev/null
+++ b/components/service/crypto/provider/mbedcrypto/test/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/crypto_context_pool_tests.cpp"
+ )
diff --git a/components/service/crypto/provider/mbedcrypto/test/crypto_context_pool_tests.cpp b/components/service/crypto/provider/mbedcrypto/test/crypto_context_pool_tests.cpp
new file mode 100644
index 000000000..1b6a12ee9
--- /dev/null
+++ b/components/service/crypto/provider/mbedcrypto/test/crypto_context_pool_tests.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+#include <service/crypto/provider/mbedcrypto/crypto_context_pool.h>
+#include <CppUTest/TestHarness.h>
+
+/*
+ * Component tests for the crypto_context_pool.
+ */
+TEST_GROUP(CryptoContextPoolTests)
+{
+ void setup()
+ {
+ crypto_context_pool_init(&pool_under_test);
+ }
+
+ void teardown()
+ {
+ crypto_context_pool_deinit(&pool_under_test);
+ }
+
+ struct crypto_context_pool pool_under_test;
+};
+
+TEST(CryptoContextPoolTests, checkEmptyPool)
+{
+ struct crypto_context *context =
+ crypto_context_pool_find(&pool_under_test, CRYPTO_CONTEXT_OP_ID_HASH, 0, 0);
+
+ /* Expect a freshly initialized pool to fail to find a context */
+ CHECK_FALSE(context);
+}
+
+TEST(CryptoContextPoolTests, singleContext)
+{
+ uint32_t op_handle;
+ uint32_t client_id = 22;
+
+ struct crypto_context *initial_context =
+ crypto_context_pool_alloc(&pool_under_test,
+ CRYPTO_CONTEXT_OP_ID_HASH, client_id,
+ &op_handle);
+
+ CHECK_TRUE(initial_context);
+
+ struct crypto_context *follow_on_context =
+ crypto_context_pool_find(&pool_under_test,
+ CRYPTO_CONTEXT_OP_ID_HASH, client_id,
+ op_handle);
+
+ UNSIGNED_LONGS_EQUAL(initial_context, follow_on_context);
+
+ crypto_context_pool_free(&pool_under_test, initial_context);
+}
+
+TEST(CryptoContextPoolTests, multipleContexts)
+{
+ /* Test multiple concurrent contexts but never exceeding the pool size */
+ struct crypto_context *context;
+ uint32_t zombie_handle_1, zombie_handle_2;
+
+ /* First start a couple of zombie contexts. This will occur if a client
+ * starts a transaction but never finishes it. This could happen due to a
+ * misbehaving client or if a client process crashes. This checks that
+ * recycling of least recently used contexts is working.
+ */
+ context = crypto_context_pool_alloc(&pool_under_test,
+ CRYPTO_CONTEXT_OP_ID_MAC, 77,
+ &zombie_handle_1);
+ CHECK_TRUE(context);
+
+ context = crypto_context_pool_alloc(&pool_under_test,
+ CRYPTO_CONTEXT_OP_ID_CIPHER, 88,
+ &zombie_handle_2);
+ CHECK_TRUE(context);
+
+ /* Now run through the normal life-cycle for a load of concurrent contexts */
+ for (unsigned int i = 0; i < 1000; ++i) {
+
+ uint32_t op_handles[CRYPTO_CONTEXT_POOL_SIZE];
+ unsigned int num_concurrent = (rand() % CRYPTO_CONTEXT_POOL_SIZE) + 1;
+
+ /* Start some concurrent contexts, each belonging to different clients */
+ for (unsigned int context_index = 0; context_index < num_concurrent; ++context_index) {
+
+ context = crypto_context_pool_alloc(&pool_under_test,
+ CRYPTO_CONTEXT_OP_ID_HASH, context_index,
+ &op_handles[context_index]);
+
+ CHECK_TRUE(context);
+ }
+
+ /* Expect the find to work for all active contexts */
+ for (unsigned int context_index = 0; context_index < num_concurrent; ++context_index) {
+
+ context = crypto_context_pool_find(&pool_under_test,
+ CRYPTO_CONTEXT_OP_ID_HASH, context_index,
+ op_handles[context_index]);
+
+ CHECK_TRUE(context);
+ }
+
+ /* Then find and free all contexts */
+ for (unsigned int context_index = 0; context_index < num_concurrent; ++context_index) {
+
+ context = crypto_context_pool_find(&pool_under_test,
+ CRYPTO_CONTEXT_OP_ID_HASH, context_index,
+ op_handles[context_index]);
+
+ CHECK_TRUE(context);
+
+ crypto_context_pool_free(&pool_under_test, context);
+ }
+ }
+
+ /* Expect the zombie contexts to have been recycled */
+ context = crypto_context_pool_find(&pool_under_test,
+ CRYPTO_CONTEXT_OP_ID_MAC, 77,
+ zombie_handle_1);
+ CHECK_FALSE(context);
+
+ context = crypto_context_pool_find(&pool_under_test,
+ CRYPTO_CONTEXT_OP_ID_CIPHER, 88,
+ zombie_handle_2);
+ CHECK_FALSE(context);
+}
diff --git a/components/service/crypto/provider/serializer/crypto_provider_serializer.h b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
index 9bcc305bc..96bee3acc 100644
--- a/components/service/crypto/provider/serializer/crypto_provider_serializer.h
+++ b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
@@ -97,6 +97,25 @@ struct crypto_provider_serializer {
rpc_status_t (*serialize_generate_random_resp)(struct call_param_buf *resp_buf,
const uint8_t *output, size_t output_len);
+
+ /* Operation: hash_setup */
+ rpc_status_t (*deserialize_hash_setup_req)(const struct call_param_buf *req_buf,
+ psa_algorithm_t *alg);
+
+ rpc_status_t (*serialize_hash_setup_resp)(struct call_param_buf *resp_buf,
+ uint32_t op_handle);
+
+ /* Operation: hash_update */
+ rpc_status_t (*deserialize_hash_update_req)(const struct call_param_buf *req_buf,
+ uint32_t *op_handle,
+ const uint8_t **data, size_t *data_len);
+
+ /* Operation: hash_finish */
+ rpc_status_t (*deserialize_hash_finish_req)(const struct call_param_buf *req_buf,
+ uint32_t *op_handle);
+
+ rpc_status_t (*serialize_hash_finish_resp)(struct call_param_buf *resp_buf,
+ const uint8_t *hash, size_t hash_len);
};
#endif /* CRYPTO_PROVIDER_SERIALIZER_H */
diff --git a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
index e69defbd0..ffccc73f4 100644
--- a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
@@ -19,6 +19,7 @@
#include <protocols/service/crypto/packed-c/import_key.h>
#include <protocols/service/crypto/packed-c/sign_hash.h>
#include <protocols/service/crypto/packed-c/verify_hash.h>
+#include <protocols/service/crypto/packed-c/hash.h>
#include "packedc_crypto_provider_serializer.h"
#include "packedc_key_attributes_translator.h"
@@ -573,6 +574,122 @@ static rpc_status_t serialize_generate_random_resp(struct call_param_buf *resp_b
return rpc_status;
}
+/* Operation: hash_setup */
+static rpc_status_t deserialize_hash_setup_req(const struct call_param_buf *req_buf,
+ psa_algorithm_t *alg)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_hash_setup_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_hash_setup_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *alg = recv_msg.alg;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_hash_setup_resp(struct call_param_buf *resp_buf,
+ uint32_t op_handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct ts_crypto_hash_setup_out resp_msg;
+ size_t fixed_len = sizeof(struct ts_crypto_hash_setup_out);
+
+ resp_msg.op_handle = op_handle;
+
+ if (fixed_len <= resp_buf->size) {
+
+ memcpy(resp_buf->data, &resp_msg, fixed_len);
+ resp_buf->data_len = fixed_len;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+
+}
+
+/* Operation: hash_update */
+static rpc_status_t deserialize_hash_update_req(const struct call_param_buf *req_buf,
+ uint32_t *op_handle,
+ const uint8_t **data, size_t *data_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_hash_update_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_hash_update_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ struct tlv_const_iterator req_iter;
+ struct tlv_record decoded_record;
+
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+
+ *op_handle = recv_msg.op_handle;
+
+ tlv_const_iterator_begin(&req_iter,
+ (uint8_t*)req_buf->data + expected_fixed_len,
+ req_buf->data_len - expected_fixed_len);
+
+ if (tlv_find_decode(&req_iter, TS_CRYPTO_HASH_UPDATE_IN_TAG_DATA, &decoded_record)) {
+
+ *data = decoded_record.value;
+ *data_len = decoded_record.length;
+ }
+ else {
+ /* Default to a zero length data */
+ *data_len = 0;
+ }
+ }
+
+ return rpc_status;
+}
+
+/* Operation: hash_finish */
+static rpc_status_t deserialize_hash_finish_req(const struct call_param_buf *req_buf,
+ uint32_t *op_handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_hash_finish_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_hash_finish_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *op_handle = recv_msg.op_handle;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_hash_finish_resp(struct call_param_buf *resp_buf,
+ const uint8_t *hash, size_t hash_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct tlv_iterator resp_iter;
+
+ struct tlv_record out_record;
+ out_record.tag = TS_CRYPTO_HASH_FINISH_OUT_TAG_HASH;
+ out_record.length = hash_len;
+ out_record.value = hash;
+
+ tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+
+ if (tlv_encode(&resp_iter, &out_record)) {
+
+ resp_buf->data_len = tlv_required_space(hash_len);
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
/* Singleton method to provide access to the serializer instance */
const struct crypto_provider_serializer *packedc_crypto_provider_serializer_instance(void)
{
@@ -595,7 +712,12 @@ const struct crypto_provider_serializer *packedc_crypto_provider_serializer_inst
deserialize_asymmetric_encrypt_req,
serialize_asymmetric_encrypt_resp,
deserialize_generate_random_req,
- serialize_generate_random_resp
+ serialize_generate_random_resp,
+ deserialize_hash_setup_req,
+ serialize_hash_setup_resp,
+ deserialize_hash_update_req,
+ deserialize_hash_finish_req,
+ serialize_hash_finish_resp
};
return &instance;
diff --git a/components/service/crypto/test/service/component.cmake b/components/service/crypto/test/service/component.cmake
index 8aad32042..be087937e 100644
--- a/components/service/crypto/test/service/component.cmake
+++ b/components/service/crypto/test/service/component.cmake
@@ -11,5 +11,5 @@ endif()
target_sources(${TGT} PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/crypto_service_scenarios.cpp"
"${CMAKE_CURRENT_LIST_DIR}/crypto_service_limit_tests.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/crypto_test_vectors.cpp"
)
-
diff --git a/components/service/crypto/test/service/crypto_service_scenarios.cpp b/components/service/crypto/test/service/crypto_service_scenarios.cpp
index 7056b4a3e..276a86043 100644
--- a/components/service/crypto/test/service/crypto_service_scenarios.cpp
+++ b/components/service/crypto/test/service/crypto_service_scenarios.cpp
@@ -7,422 +7,449 @@
#include <string>
#include <cstring>
#include <cstdint>
+#include <vector>
#include <CppUTest/TestHarness.h>
#include "crypto_service_scenarios.h"
-
+#include "crypto_test_vectors.h"
crypto_service_scenarios::crypto_service_scenarios(crypto_client *crypto_client) :
- m_crypto_client(crypto_client)
+ m_crypto_client(crypto_client)
{
}
crypto_service_scenarios::~crypto_service_scenarios()
{
- delete m_crypto_client;
- m_crypto_client = NULL;
+ delete m_crypto_client;
+ m_crypto_client = NULL;
}
void crypto_service_scenarios::generateVolatileKeys()
{
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-
- psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
- psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
- psa_set_key_bits(&attributes, 256);
-
- /* Generate first key */
- psa_key_id_t key_id_1;
- status = m_crypto_client->generate_key(&attributes, &key_id_1);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- /* And another */
- psa_key_id_t key_id_2;
- status = m_crypto_client->generate_key(&attributes, &key_id_2);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- /* Expect the key IDs to be different */
- CHECK(key_id_1 != key_id_2);
-
- /* Remove the keys */
- status = m_crypto_client->destroy_key(key_id_1);
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->destroy_key(key_id_2);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- psa_reset_key_attributes(&attributes);
+ psa_status_t status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
+ psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
+ psa_set_key_bits(&attributes, 256);
+
+ /* Generate first key */
+ psa_key_id_t key_id_1;
+ status = m_crypto_client->generate_key(&attributes, &key_id_1);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* And another */
+ psa_key_id_t key_id_2;
+ status = m_crypto_client->generate_key(&attributes, &key_id_2);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* Expect the key IDs to be different */
+ CHECK(key_id_1 != key_id_2);
+
+ /* Remove the keys */
+ status = m_crypto_client->destroy_key(key_id_1);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->destroy_key(key_id_2);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ psa_reset_key_attributes(&attributes);
}
void crypto_service_scenarios::generatePersistentKeys()
{
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
- psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
- psa_set_key_bits(&attributes, 256);
-
- /* First try and generate a key with an invalid key id */
- psa_key_id_t key_id;
- psa_set_key_id(&attributes, 0);
- status = m_crypto_client->generate_key(&attributes, &key_id);
- CHECK_EQUAL(PSA_ERROR_INVALID_HANDLE, status);
-
- /* Generate first key */
- psa_key_id_t key_id_1;
- psa_set_key_id(&attributes, 100000);
- status = m_crypto_client->generate_key(&attributes, &key_id_1);
- CHECK_EQUAL(PSA_SUCCESS, status);
- CHECK_EQUAL(100000, key_id_1);
-
- /* And another */
- psa_key_id_t key_id_2;
- psa_set_key_id(&attributes, 2);
- status = m_crypto_client->generate_key(&attributes, &key_id_2);
- CHECK_EQUAL(PSA_SUCCESS, status);
- CHECK_EQUAL(2, key_id_2);
-
- /* Remove the keys */
- status = m_crypto_client->destroy_key(key_id_1);
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->destroy_key(key_id_2);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- psa_reset_key_attributes(&attributes);
+ psa_status_t status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
+ psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
+ psa_set_key_bits(&attributes, 256);
+
+ /* First try and generate a key with an invalid key id */
+ psa_key_id_t key_id;
+ psa_set_key_id(&attributes, 0);
+ status = m_crypto_client->generate_key(&attributes, &key_id);
+ CHECK_EQUAL(PSA_ERROR_INVALID_HANDLE, status);
+
+ /* Generate first key */
+ psa_key_id_t key_id_1;
+ psa_set_key_id(&attributes, 100000);
+ status = m_crypto_client->generate_key(&attributes, &key_id_1);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ CHECK_EQUAL(100000, key_id_1);
+
+ /* And another */
+ psa_key_id_t key_id_2;
+ psa_set_key_id(&attributes, 2);
+ status = m_crypto_client->generate_key(&attributes, &key_id_2);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ CHECK_EQUAL(2, key_id_2);
+
+ /* Remove the keys */
+ status = m_crypto_client->destroy_key(key_id_1);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->destroy_key(key_id_2);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ psa_reset_key_attributes(&attributes);
}
void crypto_service_scenarios::exportPublicKey()
{
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_key_id_t key_id;
+ psa_status_t status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t key_id;
- psa_set_key_id(&attributes, 10);
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
- psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
- psa_set_key_bits(&attributes, 256);
+ psa_set_key_id(&attributes, 10);
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
+ psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
+ psa_set_key_bits(&attributes, 256);
- /* Generate a key */
- status = m_crypto_client->generate_key(&attributes, &key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
+ /* Generate a key */
+ status = m_crypto_client->generate_key(&attributes, &key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
- psa_reset_key_attributes(&attributes);
+ psa_reset_key_attributes(&attributes);
- /* Export the public key */
- uint8_t key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
- size_t key_len = 0;
+ /* Export the public key */
+ uint8_t key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
+ size_t key_len = 0;
- status = m_crypto_client->export_public_key(key_id, key_buf, sizeof(key_buf), &key_len);
- CHECK_EQUAL(PSA_SUCCESS, status);
- CHECK_TRUE(key_len > 0);
+ status = m_crypto_client->export_public_key(key_id, key_buf, sizeof(key_buf), &key_len);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ CHECK_TRUE(key_len > 0);
- /* Remove the key */
- status = m_crypto_client->destroy_key(key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
+ /* Remove the key */
+ status = m_crypto_client->destroy_key(key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
}
void crypto_service_scenarios::exportAndImportKeyPair()
{
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_key_id_t key_id_1;
- psa_key_id_t key_id_2;
-
- psa_set_key_id(&attributes, 11);
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT);
- psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
- psa_set_key_bits(&attributes, 256);
-
- /* Generate a key */
- status = m_crypto_client->generate_key(&attributes, &key_id_1);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- /* Export the key pair */
- uint8_t key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
- size_t key_len = 0;
-
- status = m_crypto_client->export_key(key_id_1, key_buf, sizeof(key_buf), &key_len);
- CHECK_EQUAL(PSA_SUCCESS, status);
- CHECK(key_len > 0);
-
- /* Import the key pair value with a different key id */
- psa_set_key_id(&attributes, 12);
- status = m_crypto_client->import_key(&attributes, key_buf, key_len, &key_id_2);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- psa_reset_key_attributes(&attributes);
-
- /* Remove the keys */
- status = m_crypto_client->destroy_key(key_id_1);
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->destroy_key(key_id_2);
- CHECK_EQUAL(PSA_SUCCESS, status);
+ psa_status_t status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t key_id_1;
+ psa_key_id_t key_id_2;
+
+ psa_set_key_id(&attributes, 11);
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT);
+ psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
+ psa_set_key_bits(&attributes, 256);
+
+ /* Generate a key */
+ status = m_crypto_client->generate_key(&attributes, &key_id_1);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* Export the key pair */
+ uint8_t key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
+ size_t key_len = 0;
+
+ status = m_crypto_client->export_key(key_id_1, key_buf, sizeof(key_buf), &key_len);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ CHECK(key_len > 0);
+
+ /* Import the key pair value with a different key id */
+ psa_set_key_id(&attributes, 12);
+ status = m_crypto_client->import_key(&attributes, key_buf, key_len, &key_id_2);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ psa_reset_key_attributes(&attributes);
+
+ /* Remove the keys */
+ status = m_crypto_client->destroy_key(key_id_1);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->destroy_key(key_id_2);
+ CHECK_EQUAL(PSA_SUCCESS, status);
}
void crypto_service_scenarios::signAndVerifyHash()
{
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_key_id_t key_id;
-
- psa_set_key_id(&attributes, 13);
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
- psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
- psa_set_key_bits(&attributes, 256);
-
- /* Generate a key */
- status = m_crypto_client->generate_key(&attributes, &key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- psa_reset_key_attributes(&attributes);
-
- /* Sign a hash */
- uint8_t hash[20];
- uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
- size_t signature_length;
-
- memset(hash, 0x71, sizeof(hash));
-
- status = m_crypto_client->sign_hash(key_id,
- PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
- signature, sizeof(signature), &signature_length);
-
- CHECK_EQUAL(PSA_SUCCESS, status);
- CHECK(signature_length > 0);
-
- /* Verify the signature */
- status = m_crypto_client->verify_hash(key_id,
- PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
- signature, signature_length);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- /* Change the hash and expect verify to fail */
- hash[0] = 0x72;
- status = m_crypto_client->verify_hash(key_id,
- PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
- signature, signature_length);
- CHECK_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status);
-
- /* Remove the key */
- status = m_crypto_client->destroy_key(key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
+ psa_status_t status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t key_id;
+
+ psa_set_key_id(&attributes, 13);
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
+ psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
+ psa_set_key_bits(&attributes, 256);
+
+ /* Generate a key */
+ status = m_crypto_client->generate_key(&attributes, &key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ psa_reset_key_attributes(&attributes);
+
+ /* Sign a hash */
+ uint8_t hash[20];
+ uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
+ size_t signature_length;
+
+ memset(hash, 0x71, sizeof(hash));
+
+ status = m_crypto_client->sign_hash(key_id,
+ PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
+ signature, sizeof(signature), &signature_length);
+
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ CHECK(signature_length > 0);
+
+ /* Verify the signature */
+ status = m_crypto_client->verify_hash(key_id,
+ PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
+ signature, signature_length);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* Change the hash and expect verify to fail */
+ hash[0] = 0x72;
+ status = m_crypto_client->verify_hash(key_id,
+ PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
+ signature, signature_length);
+ CHECK_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status);
+
+ /* Remove the key */
+ status = m_crypto_client->destroy_key(key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
}
void crypto_service_scenarios::signAndVerifyEat()
{
- /* Sign and verify a hash using EAT key type and algorithm */
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_key_id_t key_id;
-
- psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
-
- psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1));
- psa_set_key_bits(&attributes, 256);
-
- /* Generate a key */
- status = m_crypto_client->generate_key(&attributes, &key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- psa_reset_key_attributes(&attributes);
-
- /* Sign a hash */
- uint8_t hash[64];
- uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
- size_t signature_length;
-
- memset(hash, 0x71, sizeof(hash));
-
- status = m_crypto_client->sign_hash(key_id,
- PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
- signature, sizeof(signature), &signature_length);
-
- CHECK_EQUAL(PSA_SUCCESS, status);
- CHECK(signature_length > 0);
-
- /* Verify the signature */
- status = m_crypto_client->verify_hash(key_id,
- PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
- signature, signature_length);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- /* Change the hash and expect verify to fail */
- hash[0] = 0x72;
- status = m_crypto_client->verify_hash(key_id,
- PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
- signature, signature_length);
- CHECK_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status);
-
- /* Remove the key */
- status = m_crypto_client->destroy_key(key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
+ /* Sign and verify a hash using EAT key type and algorithm */
+ psa_status_t status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t key_id;
+
+ psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
+
+ psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1));
+ psa_set_key_bits(&attributes, 256);
+
+ /* Generate a key */
+ status = m_crypto_client->generate_key(&attributes, &key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ psa_reset_key_attributes(&attributes);
+
+ /* Sign a hash */
+ uint8_t hash[64];
+ uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
+ size_t signature_length;
+
+ memset(hash, 0x71, sizeof(hash));
+
+ status = m_crypto_client->sign_hash(key_id,
+ PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
+ signature, sizeof(signature), &signature_length);
+
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ CHECK(signature_length > 0);
+
+ /* Verify the signature */
+ status = m_crypto_client->verify_hash(key_id,
+ PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
+ signature, signature_length);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* Change the hash and expect verify to fail */
+ hash[0] = 0x72;
+ status = m_crypto_client->verify_hash(key_id,
+ PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
+ signature, signature_length);
+ CHECK_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status);
+
+ /* Remove the key */
+ status = m_crypto_client->destroy_key(key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
}
void crypto_service_scenarios::asymEncryptDecrypt()
{
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_key_id_t key_id;
-
- psa_set_key_id(&attributes, 14);
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
- psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
- psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
- psa_set_key_bits(&attributes, 256);
-
- /* Generate a key */
- status = m_crypto_client->generate_key(&attributes, &key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- psa_reset_key_attributes(&attributes);
-
- /* Encrypt a message */
- uint8_t message[] = {'q','u','i','c','k','b','r','o','w','n','f','o','x'};
- uint8_t ciphertext[256];
- size_t ciphertext_len = 0;
-
- status = m_crypto_client->asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
- message, sizeof(message), NULL, 0,
- ciphertext, sizeof(ciphertext), &ciphertext_len);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- /* Decrypt it */
- uint8_t plaintext[256];
- size_t plaintext_len = 0;
-
- status = m_crypto_client->asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
- ciphertext, ciphertext_len, NULL, 0,
- plaintext, sizeof(plaintext), &plaintext_len);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- /* Expect the encrypted/decrypted message to match theh original */
- CHECK_EQUAL(sizeof(message), plaintext_len);
- MEMCMP_EQUAL(message, plaintext, plaintext_len);
-
- /* Remove the key */
- status = m_crypto_client->destroy_key(key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
+ psa_status_t status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t key_id;
+
+ psa_set_key_id(&attributes, 14);
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
+ psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
+ psa_set_key_bits(&attributes, 256);
+
+ /* Generate a key */
+ status = m_crypto_client->generate_key(&attributes, &key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ psa_reset_key_attributes(&attributes);
+
+ /* Encrypt a message */
+ uint8_t message[] = {'q','u','i','c','k','b','r','o','w','n','f','o','x'};
+ uint8_t ciphertext[256];
+ size_t ciphertext_len = 0;
+
+ status = m_crypto_client->asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
+ message, sizeof(message), NULL, 0,
+ ciphertext, sizeof(ciphertext), &ciphertext_len);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* Decrypt it */
+ uint8_t plaintext[256];
+ size_t plaintext_len = 0;
+
+ status = m_crypto_client->asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
+ ciphertext, ciphertext_len, NULL, 0,
+ plaintext, sizeof(plaintext), &plaintext_len);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* Expect the encrypted/decrypted message to match theh original */
+ CHECK_EQUAL(sizeof(message), plaintext_len);
+ MEMCMP_EQUAL(message, plaintext, plaintext_len);
+
+ /* Remove the key */
+ status = m_crypto_client->destroy_key(key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
}
void crypto_service_scenarios::asymEncryptDecryptWithSalt()
{
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_key_id_t key_id;
-
- psa_set_key_id(&attributes, 15);
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
- psa_set_key_algorithm(&attributes, PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
- psa_set_key_bits(&attributes, 1024);
-
- /* Generate a key */
- status = m_crypto_client->generate_key(&attributes, &key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- psa_reset_key_attributes(&attributes);
-
- /* Encrypt a message */
- uint8_t message[] = {'q','u','i','c','k','b','r','o','w','n','f','o','x'};
- uint8_t ciphertext[128];
- size_t ciphertext_len = 0;
-
- /* With salt */
- uint8_t salt[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
-
- status = m_crypto_client->asymmetric_encrypt(key_id, PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256),
- message, sizeof(message),
- salt, sizeof(salt),
- ciphertext, sizeof(ciphertext), &ciphertext_len);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- /* Decrypt it */
- uint8_t plaintext[256];
- size_t plaintext_len = 0;
-
- status = m_crypto_client->asymmetric_decrypt(key_id, PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256),
- ciphertext, ciphertext_len,
- salt, sizeof(salt),
- plaintext, sizeof(plaintext), &plaintext_len);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- /* Expect the encrypted/decrypted message to match theh original */
- CHECK_EQUAL(sizeof(message), plaintext_len);
- MEMCMP_EQUAL(message, plaintext, plaintext_len);
-
- /* Remove the key */
- status = m_crypto_client->destroy_key(key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
+ psa_status_t status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t key_id;
+
+ psa_set_key_id(&attributes, 15);
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
+ psa_set_key_algorithm(&attributes, PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256));
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
+ psa_set_key_bits(&attributes, 1024);
+
+ /* Generate a key */
+ status = m_crypto_client->generate_key(&attributes, &key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ psa_reset_key_attributes(&attributes);
+
+ /* Encrypt a message */
+ uint8_t message[] = {'q','u','i','c','k','b','r','o','w','n','f','o','x'};
+ uint8_t ciphertext[128];
+ size_t ciphertext_len = 0;
+
+ /* With salt */
+ uint8_t salt[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+
+ status = m_crypto_client->asymmetric_encrypt(key_id, PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256),
+ message, sizeof(message),
+ salt, sizeof(salt),
+ ciphertext, sizeof(ciphertext), &ciphertext_len);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* Decrypt it */
+ uint8_t plaintext[256];
+ size_t plaintext_len = 0;
+
+ status = m_crypto_client->asymmetric_decrypt(key_id, PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256),
+ ciphertext, ciphertext_len,
+ salt, sizeof(salt),
+ plaintext, sizeof(plaintext), &plaintext_len);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* Expect the encrypted/decrypted message to match theh original */
+ CHECK_EQUAL(sizeof(message), plaintext_len);
+ MEMCMP_EQUAL(message, plaintext, plaintext_len);
+
+ /* Remove the key */
+ status = m_crypto_client->destroy_key(key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+}
+
+void crypto_service_scenarios::calculateHash()
+{
+ psa_status_t status;
+ std::vector<uint8_t> input;
+ std::vector<uint8_t> expected_output;
+ uint8_t output[PSA_HASH_MAX_SIZE];
+ size_t output_len;
+
+ crypto_test_vectors::plaintext_1_len_610(input);
+ crypto_test_vectors::sha256_1(expected_output);
+
+ uint32_t op_handle = 0;
+
+ status = m_crypto_client->hash_setup(&op_handle, PSA_ALG_SHA_256);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ status = m_crypto_client->hash_update(op_handle, &input[0], input.size());
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ status = m_crypto_client->hash_finish(op_handle, output, sizeof(output), &output_len);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ UNSIGNED_LONGS_EQUAL(expected_output.size(), output_len);
+ MEMCMP_EQUAL(&expected_output[0], &output[0], output_len);
}
void crypto_service_scenarios::generateRandomNumbers()
{
- psa_status_t status;
- uint8_t num1_8bit[1];
- uint8_t num2_8bit[1];
- uint8_t num3_16bit[2];
- uint8_t num4_16bit[2];
- uint8_t num5_24bit[3];
- uint8_t num6_24bit[3];
- uint8_t num7_32bit[4];
- uint8_t num8_32bit[4];
- uint8_t num9_64bit[8];
- uint8_t num10_64bit[8];
- uint8_t num11_128bit[16];
- uint8_t num12_128bit[16];
-
- /* Clear all buffers */
- memset(num1_8bit, 0, sizeof(num1_8bit));
- memset(num2_8bit, 0, sizeof(num2_8bit));
- memset(num3_16bit, 0, sizeof(num3_16bit));
- memset(num4_16bit, 0, sizeof(num4_16bit));
- memset(num5_24bit, 0, sizeof(num5_24bit));
- memset(num6_24bit, 0, sizeof(num6_24bit));
- memset(num7_32bit, 0, sizeof(num7_32bit));
- memset(num8_32bit, 0, sizeof(num8_32bit));
- memset(num9_64bit, 0, sizeof(num9_64bit));
- memset(num10_64bit, 0, sizeof(num10_64bit));
- memset(num11_128bit, 0, sizeof(num11_128bit));
- memset(num12_128bit, 0, sizeof(num12_128bit));
-
- /* Generate some different size random numbers */
- status = m_crypto_client->generate_random(num1_8bit, sizeof(num1_8bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num2_8bit, sizeof(num2_8bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num3_16bit, sizeof(num3_16bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num4_16bit, sizeof(num4_16bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num5_24bit, sizeof(num5_24bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num6_24bit, sizeof(num6_24bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num7_32bit, sizeof(num7_32bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num8_32bit, sizeof(num8_32bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num9_64bit, sizeof(num9_64bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num10_64bit, sizeof(num10_64bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num11_128bit, sizeof(num11_128bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
- status = m_crypto_client->generate_random(num12_128bit, sizeof(num12_128bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- /* For larger numbers, it should be improbable that numbers are the same */
- CHECK(memcmp(num5_24bit, num6_24bit, sizeof(num5_24bit)) != 0);
- CHECK(memcmp(num7_32bit, num8_32bit, sizeof(num7_32bit)) != 0);
- CHECK(memcmp(num9_64bit, num10_64bit, sizeof(num9_64bit)) != 0);
- CHECK(memcmp(num11_128bit, num12_128bit, sizeof(num11_128bit)) != 0);
+ psa_status_t status;
+ uint8_t num1_8bit[1];
+ uint8_t num2_8bit[1];
+ uint8_t num3_16bit[2];
+ uint8_t num4_16bit[2];
+ uint8_t num5_24bit[3];
+ uint8_t num6_24bit[3];
+ uint8_t num7_32bit[4];
+ uint8_t num8_32bit[4];
+ uint8_t num9_64bit[8];
+ uint8_t num10_64bit[8];
+ uint8_t num11_128bit[16];
+ uint8_t num12_128bit[16];
+
+ /* Clear all buffers */
+ memset(num1_8bit, 0, sizeof(num1_8bit));
+ memset(num2_8bit, 0, sizeof(num2_8bit));
+ memset(num3_16bit, 0, sizeof(num3_16bit));
+ memset(num4_16bit, 0, sizeof(num4_16bit));
+ memset(num5_24bit, 0, sizeof(num5_24bit));
+ memset(num6_24bit, 0, sizeof(num6_24bit));
+ memset(num7_32bit, 0, sizeof(num7_32bit));
+ memset(num8_32bit, 0, sizeof(num8_32bit));
+ memset(num9_64bit, 0, sizeof(num9_64bit));
+ memset(num10_64bit, 0, sizeof(num10_64bit));
+ memset(num11_128bit, 0, sizeof(num11_128bit));
+ memset(num12_128bit, 0, sizeof(num12_128bit));
+
+ /* Generate some different size random numbers */
+ status = m_crypto_client->generate_random(num1_8bit, sizeof(num1_8bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num2_8bit, sizeof(num2_8bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num3_16bit, sizeof(num3_16bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num4_16bit, sizeof(num4_16bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num5_24bit, sizeof(num5_24bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num6_24bit, sizeof(num6_24bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num7_32bit, sizeof(num7_32bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num8_32bit, sizeof(num8_32bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num9_64bit, sizeof(num9_64bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num10_64bit, sizeof(num10_64bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num11_128bit, sizeof(num11_128bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ status = m_crypto_client->generate_random(num12_128bit, sizeof(num12_128bit));
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* For larger numbers, it should be improbable that numbers are the same */
+ CHECK(memcmp(num5_24bit, num6_24bit, sizeof(num5_24bit)) != 0);
+ CHECK(memcmp(num7_32bit, num8_32bit, sizeof(num7_32bit)) != 0);
+ CHECK(memcmp(num9_64bit, num10_64bit, sizeof(num9_64bit)) != 0);
+ CHECK(memcmp(num11_128bit, num12_128bit, sizeof(num11_128bit)) != 0);
}
diff --git a/components/service/crypto/test/service/crypto_service_scenarios.h b/components/service/crypto/test/service/crypto_service_scenarios.h
index 648baaeaf..ddfaa626f 100644
--- a/components/service/crypto/test/service/crypto_service_scenarios.h
+++ b/components/service/crypto/test/service/crypto_service_scenarios.h
@@ -26,6 +26,7 @@ public:
void exportPublicKey();
void generatePersistentKeys();
void generateVolatileKeys();
+ void calculateHash();
private:
crypto_client *m_crypto_client;
diff --git a/components/service/crypto/test/service/crypto_test_vectors.cpp b/components/service/crypto/test/service/crypto_test_vectors.cpp
new file mode 100644
index 000000000..7f781b4a5
--- /dev/null
+++ b/components/service/crypto/test/service/crypto_test_vectors.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cstring>
+#include "crypto_test_vectors.h"
+
+void crypto_test_vectors::plaintext_1_len_610(std::vector<uint8_t> &plaintext)
+{
+ /* Plaintext 1 - data length 610 bytes */
+ const uint8_t data[] =
+ {
+ 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x00,0x00,0x00,
+ 0x53,0x70,0x65,0x63,0x20,0x49,0x44,0x20,0x45,0x76,0x65,0x6e,0x74,0x30,0x33,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x0b,0x00,0x20,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,
+ 0x00,0x00,0x00,0x53,0x74,0x61,0x72,0x74,0x75,0x70,0x4c,0x6f,0x63,0x61,0x6c,0x69,
+ 0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x0b,0x00,0xa8,0x4f,0xb4,0x7b,0x54,0xd9,0x4b,0xab,0x49,0x73,0x63,0xf7,0x9b,0xfc,
+ 0x66,0xcb,0x85,0x12,0xab,0x18,0x6f,0x24,0x74,0x01,0x5d,0xcf,0x33,0xf3,0x80,0x9e,
+ 0x9b,0x20,0x05,0x00,0x00,0x00,0x42,0x4c,0x5f,0x32,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x2f,0xd3,0x43,0x6c,0x6f,0xef,0x9b,
+ 0x11,0xc2,0x16,0xdd,0x1f,0x8b,0xdf,0x9b,0xa5,0x24,0x14,0xa5,0xc1,0x97,0x0c,0x3a,
+ 0x6c,0x78,0xbf,0xef,0x64,0x0f,0xc1,0x23,0xe1,0x06,0x00,0x00,0x00,0x42,0x4c,0x5f,
+ 0x33,0x31,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,
+ 0x00,0xf3,0xde,0x4e,0x17,0xa1,0xa5,0xa7,0xfe,0xd9,0xd9,0xf4,0x16,0x3c,0x49,0x36,
+ 0x7e,0xae,0xf7,0x2f,0x2a,0xa8,0x87,0xe6,0xb6,0x22,0x89,0xcd,0x27,0xdc,0x1c,0x80,
+ 0x25,0x0a,0x00,0x00,0x00,0x48,0x57,0x5f,0x43,0x4f,0x4e,0x46,0x49,0x47,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x4e,0xe4,0x8e,
+ 0x5a,0xe6,0x50,0xed,0xe0,0xb5,0xa3,0x54,0x8a,0x1f,0xd6,0x0e,0x8a,0xea,0x0e,0x71,
+ 0x75,0x0e,0xa4,0x3f,0x82,0x76,0xce,0xaf,0xcd,0x7c,0xb0,0x91,0xe0,0x0e,0x00,0x00,
+ 0x00,0x53,0x4f,0x43,0x5f,0x46,0x57,0x5f,0x43,0x4f,0x4e,0x46,0x49,0x47,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x62,0x22,0x4f,
+ 0x0f,0xb0,0x5d,0xb4,0x77,0x1b,0x3f,0xa5,0x2e,0xab,0x76,0x1e,0x61,0x17,0xb8,0xc6,
+ 0x6e,0xac,0x8c,0xc8,0x4d,0x2e,0xb0,0x7d,0x70,0x08,0x60,0x4b,0x41,0x06,0x00,0x00,
+ 0x00,0x42,0x4c,0x5f,0x33,0x32,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x0b,0x00,0x39,0xd2,0xb8,0x5d,0x93,0x5d,0xf6,0xd8,0xf8,0xed,0x0c,
+ 0x1a,0x3a,0xe3,0xc8,0x90,0x72,0x19,0xf4,0x88,0x5c,0x79,0x15,0x05,0x7b,0xf0,0x76,
+ 0xdb,0xc1,0x4c,0x5d,0x77,0x12,0x00,0x00,0x00,0x42,0x4c,0x33,0x32,0x5f,0x45,0x58,
+ 0x54,0x52,0x41,0x31,0x5f,0x49,0x4d,0x41,0x47,0x45,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0xb5,0xd6,0x08,0x61,0xdd,0xfa,0x6d,
+ 0xda,0xa3,0xf7,0xa5,0xde,0xd6,0x8f,0x6f,0x39,0x25,0xb1,0x57,0xfa,0x3e,0xdb,0x46,
+ 0x42,0x58,0x24,0x8e,0x81,0x1c,0x45,0x5d,0x38,0x06,0x00,0x00,0x00,0x42,0x4c,0x5f,
+ 0x33,0x33,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,
+ 0x00,0x25,0x10,0x60,0x5d,0xd4,0xbc,0x9d,0x82,0x7a,0x16,0x9f,0x8a,0xcc,0x47,0x95,
+ 0xa6,0xfd,0xca,0xa0,0xc1,0x2b,0xc9,0x99,0x8f,0x51,0x20,0xff,0xc6,0xed,0x74,0x68,
+ 0x5a,0x0d,0x00,0x00,0x00,0x4e,0x54,0x5f,0x46,0x57,0x5f,0x43,0x4f,0x4e,0x46,0x49,
+ 0x47,0x00
+ };
+
+ plaintext.resize(sizeof(data));
+ memcpy(&plaintext[0], data, sizeof(data));
+}
+
+void crypto_test_vectors::sha256_1(std::vector<uint8_t> &hash)
+{
+ /* SHA256 for plaintext_1 */
+ const uint8_t data[] =
+ {
+ 0x47, 0x25, 0x0e, 0xe2, 0x39, 0xe2, 0x87, 0xfc,
+ 0x07, 0x0d, 0xce, 0x67, 0xe8, 0x96, 0x6f, 0xc8,
+ 0x42, 0xae, 0xe7, 0xaa, 0x7f, 0xa3, 0xbc, 0x3c,
+ 0xc9, 0x8e, 0x7e, 0x7a, 0xca, 0x24, 0x2c, 0xfc
+ };
+
+ hash.resize(sizeof(data));
+ memcpy(&hash[0], data, sizeof(data));
+}
diff --git a/components/service/crypto/test/service/crypto_test_vectors.h b/components/service/crypto/test/service/crypto_test_vectors.h
new file mode 100644
index 000000000..828fafbce
--- /dev/null
+++ b/components/service/crypto/test/service/crypto_test_vectors.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cstdint>
+#include <vector>
+
+/*
+ * A selection of test vectors in the form of blocks of plaintext,
+ * ciphertext, expected hashes etc.
+ */
+class crypto_test_vectors
+{
+public:
+
+ static void plaintext_1_len_610(std::vector<uint8_t> &plaintext);
+ static void sha256_1(std::vector<uint8_t> &hash);
+
+};
diff --git a/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
index 9ceb0d51e..094969c67 100644
--- a/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
+++ b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
@@ -92,6 +92,11 @@ TEST(CryptoServicePackedcTests, asymEncryptDecryptWithSalt)
m_scenarios->asymEncryptDecryptWithSalt();
}
+TEST(CryptoServicePackedcTests, calculateHash)
+{
+ m_scenarios->calculateHash();
+}
+
TEST(CryptoServicePackedcTests, generateRandomNumbers)
{
m_scenarios->generateRandomNumbers();
diff --git a/components/service/crypto/test/service/psa_crypto_api/psa_crypto_api_client.cpp b/components/service/crypto/test/service/psa_crypto_api/psa_crypto_api_client.cpp
index 6bf43fef9..0c790c9b6 100644
--- a/components/service/crypto/test/service/psa_crypto_api/psa_crypto_api_client.cpp
+++ b/components/service/crypto/test/service/psa_crypto_api/psa_crypto_api_client.cpp
@@ -119,3 +119,21 @@ psa_status_t psa_crypto_api_client::generate_random(uint8_t *output, size_t outp
return psa_status;
}
+
+psa_status_t psa_crypto_api_client::hash_setup(uint32_t *op_handle,
+ psa_algorithm_t alg)
+{
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+psa_status_t psa_crypto_api_client::hash_update(uint32_t op_handle,
+ const uint8_t *input, size_t input_length)
+{
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+psa_status_t psa_crypto_api_client::hash_finish(uint32_t op_handle,
+ uint8_t *hash, size_t hash_size, size_t *hash_length)
+{
+ return PSA_ERROR_NOT_SUPPORTED;
+}
diff --git a/components/service/crypto/test/service/psa_crypto_api/psa_crypto_api_client.h b/components/service/crypto/test/service/psa_crypto_api/psa_crypto_api_client.h
index 66f4431a4..fe72bf229 100644
--- a/components/service/crypto/test/service/psa_crypto_api/psa_crypto_api_client.h
+++ b/components/service/crypto/test/service/psa_crypto_api/psa_crypto_api_client.h
@@ -15,42 +15,50 @@
class psa_crypto_api_client : public crypto_client
{
public:
- psa_crypto_api_client();
- virtual ~psa_crypto_api_client();
-
- /* Key lifecycle methods */
- psa_status_t generate_key(const psa_key_attributes_t *attributes, psa_key_id_t *id);
- psa_status_t destroy_key(psa_key_id_t id);
- psa_status_t import_key(const psa_key_attributes_t *attributes,
- const uint8_t *data, size_t data_length, psa_key_id_t *id);
-
- /* Key export methods */
- psa_status_t export_key(psa_key_id_t id,
- uint8_t *data, size_t data_size,
- size_t *data_length);
- psa_status_t export_public_key(psa_key_id_t id,
- uint8_t *data, size_t data_size, size_t *data_length);
-
- /* Sign/verify methods */
- psa_status_t sign_hash(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *hash, size_t hash_length,
- uint8_t *signature, size_t signature_size, size_t *signature_length);
- psa_status_t verify_hash(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *hash, size_t hash_length,
- const uint8_t *signature, size_t signature_length);
-
- /* Asymmetric encrypt/decrypt */
- psa_status_t asymmetric_encrypt(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *input, size_t input_length,
- const uint8_t *salt, size_t salt_length,
- uint8_t *output, size_t output_size, size_t *output_length);
- psa_status_t asymmetric_decrypt(psa_key_id_t id, psa_algorithm_t alg,
- const uint8_t *input, size_t input_length,
- const uint8_t *salt, size_t salt_length,
- uint8_t *output, size_t output_size, size_t *output_length);
-
- /* Random number generation */
- psa_status_t generate_random(uint8_t *output, size_t output_size);
+ psa_crypto_api_client();
+ virtual ~psa_crypto_api_client();
+
+ /* Key lifecycle methods */
+ psa_status_t generate_key(const psa_key_attributes_t *attributes, psa_key_id_t *id);
+ psa_status_t destroy_key(psa_key_id_t id);
+ psa_status_t import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data, size_t data_length, psa_key_id_t *id);
+
+ /* Key export methods */
+ psa_status_t export_key(psa_key_id_t id,
+ uint8_t *data, size_t data_size,
+ size_t *data_length);
+ psa_status_t export_public_key(psa_key_id_t id,
+ uint8_t *data, size_t data_size, size_t *data_length);
+
+ /* Sign/verify methods */
+ psa_status_t sign_hash(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *hash, size_t hash_length,
+ uint8_t *signature, size_t signature_size, size_t *signature_length);
+ psa_status_t verify_hash(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *hash, size_t hash_length,
+ const uint8_t *signature, size_t signature_length);
+
+ /* Asymmetric encrypt/decrypt */
+ psa_status_t asymmetric_encrypt(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length);
+ psa_status_t asymmetric_decrypt(psa_key_id_t id, psa_algorithm_t alg,
+ const uint8_t *input, size_t input_length,
+ const uint8_t *salt, size_t salt_length,
+ uint8_t *output, size_t output_size, size_t *output_length);
+
+ /* Random number generation */
+ psa_status_t generate_random(uint8_t *output, size_t output_size);
+
+ /* Hash methods */
+ psa_status_t hash_setup(uint32_t *op_handle,
+ psa_algorithm_t alg);
+ psa_status_t hash_update(uint32_t op_handle,
+ const uint8_t *input, size_t input_length);
+ psa_status_t hash_finish(uint32_t op_handle,
+ uint8_t *hash, size_t hash_size, size_t *hash_length);
};
#endif /* PSA_CRYPTO_API_CLIENT_H */
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index 6b2f9e56b..dfa006825 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -67,6 +67,7 @@ add_components(
"components/service/crypto/provider/mbedcrypto"
"components/service/crypto/provider/serializer/protobuf"
"components/service/crypto/provider/serializer/packed-c"
+ "components/service/crypto/provider/mbedcrypto/test"
"components/service/crypto/test/unit"
"components/service/crypto/test/service"
"components/service/crypto/test/service/protobuf"
diff --git a/protocols/service/crypto/packed-c/hash.h b/protocols/service/crypto/packed-c/hash.h
new file mode 100644
index 000000000..13ae3b9dd
--- /dev/null
+++ b/protocols/service/crypto/packed-c/hash.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_HASH_H
+#define TS_CRYPTO_HASH_H
+
+#include <stdint.h>
+
+/**
+ * Hash operations on arbitrary sized data involve three operations,
+ * a setup, called once, an update called 1..* times and a finish
+ * to finalise theh hash operation.
+ */
+
+
+/********
+ * hash_setup operation definition
+ */
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_hash_setup_in
+{
+ uint32_t alg;
+};
+
+/* Mandatory fixed sized output parameters */
+struct __attribute__ ((__packed__)) ts_crypto_hash_setup_out
+{
+ uint32_t op_handle;
+};
+
+/*********
+ * hash_update operation definition
+ */
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_hash_update_in
+{
+ uint32_t op_handle;
+};
+
+/* Variable length input parameter tags */
+enum
+{
+ TS_CRYPTO_HASH_UPDATE_IN_TAG_DATA = 1
+};
+
+/*********
+ * hash_finish operation definition
+ */
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_hash_finish_in
+{
+ uint32_t op_handle;
+};
+
+/* Variable length output parameter tags */
+enum
+{
+ TS_CRYPTO_HASH_FINISH_OUT_TAG_HASH = 1
+};
+
+
+#endif /* TS_CRYPTO_HASH_H */
diff --git a/protocols/service/crypto/packed-c/opcodes.h b/protocols/service/crypto/packed-c/opcodes.h
index f0102b0a1..54ee9e9c0 100644
--- a/protocols/service/crypto/packed-c/opcodes.h
+++ b/protocols/service/crypto/packed-c/opcodes.h
@@ -9,16 +9,20 @@
/* C/C++ definition of crypto service opcodes
*/
+#define TS_CRYPTO_OPCODE_BASE (0x0100)
#define TS_CRYPTO_OPCODE_NOP (0x0000)
-#define TS_CRYPTO_OPCODE_GENERATE_KEY (0x0101)
-#define TS_CRYPTO_OPCODE_DESTROY_KEY (0x0102)
-#define TS_CRYPTO_OPCODE_EXPORT_KEY (0x0105)
-#define TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY (0x0106)
-#define TS_CRYPTO_OPCODE_IMPORT_KEY (0x0107)
-#define TS_CRYPTO_OPCODE_SIGN_HASH (0x0108)
-#define TS_CRYPTO_OPCODE_VERIFY_HASH (0x0109)
-#define TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT (0x010a)
-#define TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT (0x010b)
-#define TS_CRYPTO_OPCODE_GENERATE_RANDOM (0x010c)
+#define TS_CRYPTO_OPCODE_GENERATE_KEY (TS_CRYPTO_OPCODE_BASE + 1)
+#define TS_CRYPTO_OPCODE_DESTROY_KEY (TS_CRYPTO_OPCODE_BASE + 2)
+#define TS_CRYPTO_OPCODE_EXPORT_KEY (TS_CRYPTO_OPCODE_BASE + 5)
+#define TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY (TS_CRYPTO_OPCODE_BASE + 6)
+#define TS_CRYPTO_OPCODE_IMPORT_KEY (TS_CRYPTO_OPCODE_BASE + 7)
+#define TS_CRYPTO_OPCODE_SIGN_HASH (TS_CRYPTO_OPCODE_BASE + 8)
+#define TS_CRYPTO_OPCODE_VERIFY_HASH (TS_CRYPTO_OPCODE_BASE + 9)
+#define TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT (TS_CRYPTO_OPCODE_BASE + 10)
+#define TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT (TS_CRYPTO_OPCODE_BASE + 11)
+#define TS_CRYPTO_OPCODE_GENERATE_RANDOM (TS_CRYPTO_OPCODE_BASE + 12)
+#define TS_CRYPTO_OPCODE_HASH_SETUP (TS_CRYPTO_OPCODE_BASE + 13)
+#define TS_CRYPTO_OPCODE_HASH_UPDATE (TS_CRYPTO_OPCODE_BASE + 14)
+#define TS_CRYPTO_OPCODE_HASH_FINISH (TS_CRYPTO_OPCODE_BASE + 15)
#endif /* TS_CRYPTO_OPCODES_H */