diff options
author | Julian Hall <julian.hall@arm.com> | 2021-06-24 09:40:23 +0100 |
---|---|---|
committer | Gyorgy Szing <Gyorgy.Szing@arm.com> | 2021-10-05 22:55:43 +0200 |
commit | f57289645f3254d9184f3fd676b1a5154794ef1c (patch) | |
tree | 07e49f5ce93caa57de837f731c0c10d685d639a0 | |
parent | fc7222152b88ee0e52bb68b08159648e7907b4e6 (diff) | |
download | trusted-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
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 */ |