aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjulhal01 <julian.hall@arm.com>2020-12-21 10:27:41 +0000
committerGyorgy Szing <Gyorgy.Szing@arm.com>2021-04-14 16:59:09 +0200
commit734dbad7305293aad19f517c29f01db5d41495ab (patch)
treebd05626941b625bd3082711ec07ada64484949a4
parentc3f4e9a7550ee4fddf2d24127ef33ca514351806 (diff)
downloadtrusted-services-734dbad7305293aad19f517c29f01db5d41495ab.tar.gz
Add packed-c protocol support for crypto service
To provide a lightweight parameter encoding that is aligned to conventions used by SCMI, the packed-c parameter serialization has been added to the crypto service. This builds on generic components that allow other packed-c service access protocols to be added easily. Service level tests have been extended to use both protobuf and packed-c clients. Signed-off-by: julhal01 <julian.hall@arm.com> Change-Id: I9279b0814bcc9cf6c4aa4e30629e2f46f2df4c23
-rw-r--r--components/app/ts-demo/test/ts-demo_tests.cpp5
-rw-r--r--components/common/tlv/component.cmake13
-rw-r--r--components/common/tlv/test/component.cmake13
-rw-r--r--components/common/tlv/test/tlv_tests.cpp207
-rw-r--r--components/common/tlv/tlv.c99
-rw-r--r--components/common/tlv/tlv.h108
-rw-r--r--components/rpc/common/test/protocol/check_rpc_status_alignment.cpp34
-rw-r--r--components/rpc/common/test/protocol/component.cmake14
-rw-r--r--components/service/crypto/client/cpp/crypto_client.cpp774
-rw-r--r--components/service/crypto/client/cpp/crypto_client.h53
-rw-r--r--components/service/crypto/client/cpp/packed-c/component.cmake (renamed from protocols/rpc/common/packed-c/test/component.cmake)4
-rw-r--r--components/service/crypto/client/cpp/packed-c/packedc_crypto_client.cpp749
-rw-r--r--components/service/crypto/client/cpp/packed-c/packedc_crypto_client.h65
-rw-r--r--components/service/crypto/client/cpp/protobuf/component.cmake14
-rw-r--r--components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.cpp799
-rw-r--r--components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.h65
-rw-r--r--components/service/crypto/client/test/mock/mock_crypto_client.cpp4
-rw-r--r--components/service/crypto/client/test/standalone/standalone_crypto_client.cpp4
-rw-r--r--components/service/crypto/client/test/test_crypto_client.cpp4
-rw-r--r--components/service/crypto/client/test/test_crypto_client.h6
-rw-r--r--components/service/crypto/provider/serializer/packed-c/component.cmake14
-rw-r--r--components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c661
-rw-r--r--components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.h25
-rw-r--r--components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.c22
-rw-r--r--components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.h17
-rw-r--r--components/service/crypto/provider/serializer/protobuf/component.cmake6
-rw-r--r--components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c2
-rw-r--r--components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h5
-rw-r--r--components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h2
-rw-r--r--components/service/crypto/test/protocol/check_crypto_opcode_alignment.cpp34
-rw-r--r--components/service/crypto/test/protocol/check_crypto_packed-c_protocol_alignment.cpp136
-rw-r--r--components/service/crypto/test/protocol/check_crypto_protobuf_protocol_alignment.cpp136
-rw-r--r--components/service/crypto/test/protocol/component.cmake16
-rw-r--r--components/service/crypto/test/service/component.cmake4
-rw-r--r--components/service/crypto/test/service/crypto_service_limit_tests.cpp4
-rw-r--r--components/service/crypto/test/service/crypto_service_scenarios.cpp (renamed from components/service/crypto/test/service/crypto_service_op_tests.cpp)75
-rw-r--r--components/service/crypto/test/service/crypto_service_scenarios.h30
-rw-r--r--components/service/crypto/test/service/packed-c/component.cmake14
-rw-r--r--components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp88
-rw-r--r--components/service/crypto/test/service/protobuf/component.cmake14
-rw-r--r--components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp88
-rw-r--r--components/service/locator/standalone/services/crypto/crypto_service_context.cpp4
-rw-r--r--deployments/component-test/component-test.cmake10
-rw-r--r--deployments/crypto/opteesp/CMakeLists.txt2
-rw-r--r--deployments/crypto/opteesp/crypto_sp.c7
-rw-r--r--deployments/libts/linux-pc/CMakeLists.txt10
-rw-r--r--deployments/ts-demo/ts-demo.cmake10
-rw-r--r--deployments/ts-demo/ts-demo.cpp6
-rw-r--r--deployments/ts-service-test/ts-service-test.cmake6
-rw-r--r--protocols/rpc/common/packed-c/test/check_rpc_status_packed-c.cpp33
-rw-r--r--protocols/service/crypto/packed-c/asymmetric_decrypt.h31
-rw-r--r--protocols/service/crypto/packed-c/asymmetric_encrypt.h31
-rw-r--r--protocols/service/crypto/packed-c/close_key.h17
-rw-r--r--protocols/service/crypto/packed-c/component.cmake2
-rw-r--r--protocols/service/crypto/packed-c/destroy_key.h17
-rw-r--r--protocols/service/crypto/packed-c/export_key.h23
-rw-r--r--protocols/service/crypto/packed-c/export_public_key.h23
-rw-r--r--protocols/service/crypto/packed-c/generate_key.h24
-rw-r--r--protocols/service/crypto/packed-c/generate_random.h23
-rw-r--r--protocols/service/crypto/packed-c/import_key.h30
-rw-r--r--protocols/service/crypto/packed-c/key_attributes.h122
-rw-r--r--protocols/service/crypto/packed-c/opcodes.h2
-rw-r--r--protocols/service/crypto/packed-c/open_key.h23
-rw-r--r--protocols/service/crypto/packed-c/sign_hash.h30
-rw-r--r--protocols/service/crypto/packed-c/verify_hash.h25
-rw-r--r--protocols/service/crypto/protobuf/key_attributes.proto4
66 files changed, 4011 insertions, 931 deletions
diff --git a/components/app/ts-demo/test/ts-demo_tests.cpp b/components/app/ts-demo/test/ts-demo_tests.cpp
index 66295572a..5f23c2778 100644
--- a/components/app/ts-demo/test/ts-demo_tests.cpp
+++ b/components/app/ts-demo/test/ts-demo_tests.cpp
@@ -5,6 +5,7 @@
*/
#include <app/ts-demo/ts-demo.h>
+#include <service/crypto/client/cpp/packed-c/packedc_crypto_client.h>
#include <protocols/rpc/common/packed-c/encoding.h>
#include <CppUTest/TestHarness.h>
#include <service_locator.h>
@@ -27,10 +28,10 @@ TEST_GROUP(TsDemoTests) {
m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
CHECK(m_crypto_service_context);
- m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PROTOBUF, &caller);
+ m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
CHECK(m_rpc_session_handle);
- m_crypto_client = new crypto_client(caller);
+ m_crypto_client = new packedc_crypto_client(caller);
}
void teardown()
diff --git a/components/common/tlv/component.cmake b/components/common/tlv/component.cmake
new file mode 100644
index 000000000..6fafa16c7
--- /dev/null
+++ b/components/common/tlv/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-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}/tlv.c"
+ )
diff --git a/components/common/tlv/test/component.cmake b/components/common/tlv/test/component.cmake
new file mode 100644
index 000000000..4394d30ff
--- /dev/null
+++ b/components/common/tlv/test/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-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}/tlv_tests.cpp"
+ )
diff --git a/components/common/tlv/test/tlv_tests.cpp b/components/common/tlv/test/tlv_tests.cpp
new file mode 100644
index 000000000..661a81024
--- /dev/null
+++ b/components/common/tlv/test/tlv_tests.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cstring>
+#include <common/tlv/tlv.h>
+#include <CppUTest/TestHarness.h>
+
+TEST_GROUP(TlvTests)
+{
+
+};
+
+TEST(TlvTests, decodeGoodRecords)
+{
+ struct tlv_const_iterator iter;
+ struct tlv_record decoded_record;
+
+ /* Case 1: Valid single zero length record */
+ const uint8_t case_1[] = {
+ 0x77, 0x31, 0x00, 0x00
+ };
+
+ tlv_const_iterator_begin(&iter, case_1, sizeof(case_1));
+ CHECK_TRUE(tlv_decode(&iter, &decoded_record));
+ UNSIGNED_LONGS_EQUAL(0x7731, decoded_record.tag);
+ UNSIGNED_LONGS_EQUAL(0, decoded_record.length);
+ CHECK_FALSE(tlv_decode(&iter, &decoded_record));
+
+ /* Case 2: Two valid records */
+ const uint8_t case_2[] = {
+ 0x01, 0x10, 0x00, 0x01, 0x50,
+ 0x02, 0x11, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04
+ };
+
+ tlv_const_iterator_begin(&iter, case_2, sizeof(case_2));
+ CHECK_TRUE(tlv_decode(&iter, &decoded_record));
+ UNSIGNED_LONGS_EQUAL(0x0110, decoded_record.tag);
+ UNSIGNED_LONGS_EQUAL(1, decoded_record.length);
+ UNSIGNED_LONGS_EQUAL(0x50, decoded_record.value[0]);
+ CHECK_TRUE(tlv_decode(&iter, &decoded_record));
+ UNSIGNED_LONGS_EQUAL(0x0211, decoded_record.tag);
+ UNSIGNED_LONGS_EQUAL(4, decoded_record.length);
+ UNSIGNED_LONGS_EQUAL(0x01, decoded_record.value[0]);
+ UNSIGNED_LONGS_EQUAL(0x02, decoded_record.value[1]);
+ UNSIGNED_LONGS_EQUAL(0x03, decoded_record.value[2]);
+ UNSIGNED_LONGS_EQUAL(0x04, decoded_record.value[3]);
+ CHECK_FALSE(tlv_decode(&iter, &decoded_record));
+}
+
+TEST(TlvTests, findAndDecode)
+{
+ struct tlv_const_iterator iter;
+ struct tlv_record decoded_record;
+
+ /*
+ * Checks use of the tlv_find_decode method to extract known records
+ * from a sequence of records, encoded in ascending tag order, that includes
+ * ones that the receiver isn't interested in.
+ */
+ const uint8_t encoded_records[] = {
+ 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x03, 0x88, 0x88, 0x88,
+ 0x00, 0x07, 0x00, 0x02, 0x77, 0x77,
+ 0x00, 0x09, 0x00, 0x01, 0x77
+ };
+
+ tlv_const_iterator_begin(&iter, encoded_records, sizeof(encoded_records));
+ CHECK_TRUE(tlv_find_decode(&iter, 0x0001, &decoded_record));
+ UNSIGNED_LONGS_EQUAL(0, decoded_record.length);
+ CHECK_TRUE(tlv_find_decode(&iter, 0x0007, &decoded_record));
+ UNSIGNED_LONGS_EQUAL(2, decoded_record.length);
+ CHECK_TRUE(tlv_find_decode(&iter, 0x0009, &decoded_record));
+ UNSIGNED_LONGS_EQUAL(1, decoded_record.length);
+}
+
+TEST(TlvTests, decodeBadRecords)
+{
+ struct tlv_const_iterator iter;
+ struct tlv_record decoded_record;
+
+ /* Case 1: Too short to accommodate a valid header */
+ const uint8_t case_1[] = {
+ 0x77, 0x31, 0x00
+ };
+
+ tlv_const_iterator_begin(&iter, case_1, sizeof(case_1));
+ CHECK_FALSE(tlv_decode(&iter, &decoded_record));
+
+ /* Case 1: A complete record followed by a truncated one */
+ const uint8_t case_2[] = {
+ 0x77, 0x31, 0x00, 0x00,
+ 0x03, 0x21, 0x00, 0x03, 0xaa
+ };
+
+ tlv_const_iterator_begin(&iter, case_2, sizeof(case_2));
+ CHECK_TRUE(tlv_decode(&iter, &decoded_record));
+ CHECK_FALSE(tlv_decode(&iter, &decoded_record));
+}
+
+TEST(TlvTests, encodeRecords)
+{
+ struct tlv_iterator iter;
+ struct tlv_record record_to_encode;
+ size_t required_space;
+
+ /* Case 1: Encode zero length record */
+ const uint8_t case_1_expected[] = {
+ 0x66, 0x77, 0x00, 0x00
+ };
+ record_to_encode.tag = 0x6677;
+ record_to_encode.length = 0;
+ record_to_encode.value = NULL;
+ required_space = tlv_required_space(record_to_encode.length);
+ uint8_t case_1_actual[required_space];
+ tlv_iterator_begin(&iter, case_1_actual, required_space);
+ CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
+ MEMCMP_EQUAL(case_1_expected, case_1_actual, required_space);
+
+ /* Case 2: Encode two records */
+ const uint8_t case_2_expected[] = {
+ 0xa8, 0xa9, 0x00, 0x01, 0x88,
+ 0xa8, 0xaa, 0x00, 0x02, 0x01, 0x02
+ };
+
+ required_space = tlv_required_space(1) + tlv_required_space(2);
+ uint8_t case_2_actual[required_space];
+ tlv_iterator_begin(&iter, case_2_actual, required_space);
+
+ record_to_encode.tag = 0xa8a9;
+ record_to_encode.length = 1;
+ record_to_encode.value = &case_2_expected[4];
+ CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
+
+ record_to_encode.tag = 0xa8aa;
+ record_to_encode.length = 2;
+ record_to_encode.value = &case_2_expected[9];
+ CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
+
+ MEMCMP_EQUAL(case_2_expected, case_2_actual, required_space);
+
+ /* Check that you can't encode beyond the limit of the buffer */
+ CHECK_FALSE(tlv_encode(&iter, &record_to_encode));
+}
+
+TEST(TlvTests, encodeInsufficientSpace)
+{
+ struct tlv_iterator iter;
+ struct tlv_record record_to_encode;
+ size_t required_space;
+
+ /* Case 1: Encode record into buffer that isn't big enough */
+ const uint8_t case_1_expected[] = {
+ 0x66, 0x77, 0x00, 0x03, 0x01, 0x02, 0x03
+ };
+ record_to_encode.tag = 0x6677;
+ record_to_encode.length = 3;
+ record_to_encode.value = &case_1_expected[4];
+ required_space = tlv_required_space(record_to_encode.length) - 1;
+ uint8_t case_1_actual[required_space];
+ tlv_iterator_begin(&iter, case_1_actual, required_space);
+ CHECK_FALSE(tlv_encode(&iter, &record_to_encode));
+}
+
+TEST(TlvTests, encodeWrongOrder)
+{
+ struct tlv_iterator iter;
+ struct tlv_record record_to_encode;
+ size_t required_space;
+
+ /* Check defence against encoding successive records
+ * out of tag value order. Encoding rules require
+ * records to be in ascending tag value order.
+ */
+ const uint8_t record_value[] = {
+ 0x11, 0x22, 0x33, 0x44
+ };
+
+ /* Attemps to encode 4 records, the first 3 obey order
+ * rule, the last one doesn't
+ */
+ required_space = tlv_required_space(sizeof(record_value)) * 4;
+ uint8_t encode_buffer[required_space];
+ tlv_iterator_begin(&iter, encode_buffer, required_space);
+
+ record_to_encode.tag = 1;
+ record_to_encode.length = sizeof(record_value);
+ record_to_encode.value = record_value;
+ CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
+
+ record_to_encode.tag = 2;
+ record_to_encode.length = sizeof(record_value);
+ record_to_encode.value = record_value;
+ CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
+
+ record_to_encode.tag = 2;
+ record_to_encode.length = sizeof(record_value);
+ record_to_encode.value = record_value;
+ CHECK_TRUE(tlv_encode(&iter, &record_to_encode));
+
+ record_to_encode.tag = 1;
+ record_to_encode.length = sizeof(record_value);
+ record_to_encode.value = record_value;
+ CHECK_FALSE(tlv_encode(&iter, &record_to_encode));
+}
diff --git a/components/common/tlv/tlv.c b/components/common/tlv/tlv.c
new file mode 100644
index 000000000..13088321c
--- /dev/null
+++ b/components/common/tlv/tlv.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "tlv.h"
+#include <string.h>
+
+size_t tlv_required_space(size_t length)
+{
+ return TLV_HDR_LEN + length;
+}
+
+void tlv_iterator_begin(struct tlv_iterator *iter, uint8_t *buf, size_t bufsize)
+{
+ iter->pos = buf;
+ iter->limit = &buf[bufsize];
+
+ /* Defend against overflow */
+ if (iter->limit < buf) iter->limit = buf;
+
+ /* Used to enforce ascending tag order when encoding */
+ iter->prev_tag = 0;
+}
+
+void tlv_const_iterator_begin(struct tlv_const_iterator *iter, const uint8_t *buf, size_t bufsize)
+{
+ iter->pos = buf;
+ iter->limit = &buf[bufsize];
+
+ /* Defend against overflow */
+ if (iter->limit < buf) iter->limit = buf;
+}
+
+bool tlv_encode(struct tlv_iterator *iter, const struct tlv_record *input)
+{
+ bool success = false;
+ size_t required_space = tlv_required_space(input->length);
+ size_t available_space = iter->limit - iter->pos;
+
+ if (required_space <= available_space && input->tag >= iter->prev_tag) {
+
+ iter->pos[TLV_TAG_OFFSET + 0] = (uint8_t)(input->tag >> 8);
+ iter->pos[TLV_TAG_OFFSET + 1] = (uint8_t)(input->tag);
+ iter->pos[TLV_LENGTH_OFFSET + 0] = (uint8_t)(input->length >> 8);
+ iter->pos[TLV_LENGTH_OFFSET + 1] = (uint8_t)(input->length);
+
+ memcpy(&iter->pos[TLV_VALUE_OFFSET], input->value, input->length);
+
+ iter->pos += required_space;
+ iter->prev_tag = input->tag;
+ success = true;
+ }
+
+ return success;
+}
+
+bool tlv_decode(struct tlv_const_iterator *iter, struct tlv_record *output)
+{
+ bool success = false;
+ size_t max_space = iter->limit - iter->pos;
+
+ if (max_space >= TLV_HDR_LEN) {
+
+ size_t record_len;
+ output->tag = (iter->pos[TLV_TAG_OFFSET + 0] << 8) | iter->pos[TLV_TAG_OFFSET + 1];
+ output->length = (iter->pos[TLV_LENGTH_OFFSET + 0] << 8) | iter->pos[TLV_LENGTH_OFFSET + 1];
+ output->value = &iter->pos[TLV_VALUE_OFFSET];
+
+ record_len = output->length + TLV_HDR_LEN;
+
+ if (record_len <= max_space) {
+
+ iter->pos += record_len;
+ success = true;
+ }
+ }
+
+ return success;
+}
+
+bool tlv_find_decode(struct tlv_const_iterator *iter, uint16_t tag, struct tlv_record *output)
+{
+ while (tlv_decode(iter, output)) {
+
+ if (output->tag == tag) {
+ /* Found a record */
+ return true;
+ }
+ else if (output->tag > tag) {
+ /* Iterated beyond the expected parameter */
+ return false;
+ }
+ }
+
+ /* Reached the end of the buffer without finding a record with the requested tag */
+ return false;
+}
diff --git a/components/common/tlv/tlv.h b/components/common/tlv/tlv.h
new file mode 100644
index 000000000..64233a380
--- /dev/null
+++ b/components/common/tlv/tlv.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TLV_H
+#define TLV_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * TLV provides a general purpose serialization for variable length
+ * objects, identified by a tag. A serialized TLV record has the following
+ * structure:
+ * | Tag | Length | Value |
+ * | (16-bits) | (16-bits) | (Length bytes) |
+ *
+ * No assumptions are made about the alignment of the start of a serialized record.
+ * Tag and Length fields are encoded in Big Endian byte order.
+ */
+#define TLV_TAG_WIDTH (2)
+#define TLV_LENGTH_WIDTH (2)
+#define TLV_HDR_LEN (TLV_TAG_WIDTH + TLV_LENGTH_WIDTH)
+#define TLV_TAG_OFFSET (0)
+#define TLV_LENGTH_OFFSET TLV_TAG_WIDTH
+#define TLV_VALUE_OFFSET TLV_HDR_LEN
+
+/*
+ * TLV record structure provides access to a serialized record.
+ */
+struct tlv_record
+{
+ uint16_t tag;
+ uint16_t length;
+ const uint8_t *value;
+};
+
+/*
+ * Iterator state for interating over serialized tlv records when encoding.
+ */
+struct tlv_iterator
+{
+ uint8_t *pos;
+ uint8_t *limit;
+ uint16_t prev_tag;
+};
+
+/*
+ * Iterator state for interating over serialized tlv records when decoding.
+ */
+struct tlv_const_iterator
+{
+ const uint8_t *pos;
+ const uint8_t *limit;
+};
+
+/*
+ * Return the space required in bytes for a serialized record with the
+ * specified value length.
+ */
+size_t tlv_required_space(size_t length);
+
+/*
+ * Initializes a TLV iterator to the start of a buffer. Used when writing
+ * records to a buffer when encoding.
+ */
+void tlv_iterator_begin(struct tlv_iterator *iter, uint8_t *buf, size_t bufsize);
+
+/*
+ * Initializes a TLV const iterator to the start of a buffer. Used when reading
+ * records from a buffer when decoding.
+ */
+void tlv_const_iterator_begin(struct tlv_const_iterator *iter, const uint8_t *buf, size_t bufsize);
+
+/*
+ * Encode a serialized record and advance the iterator, ready to encode the next
+ * record. Returns true if successful, false if insufficient room.
+ */
+bool tlv_encode(struct tlv_iterator *iter, const struct tlv_record *input);
+
+/*
+ * Decode a serialized record and advance the iterator, ready to decode the next
+ * record (if there is one). Returns true if successful, false there is no serialized record
+ * or an incomplete one.
+ */
+bool tlv_decode(struct tlv_const_iterator *iter, struct tlv_record *output);
+
+/*
+ * Advances the iterator until a record with the specified tag is found. If
+ * it's found, it's decoded and the iterator is advanced to the next position.
+ * This can be used when decoding an expected set of records, encoded in ascending
+ * tag order. Any unrecognised records are skipped over. This is the typical
+ * decoding pattern.
+ */
+bool tlv_find_decode(struct tlv_const_iterator *iter, uint16_t tag, struct tlv_record *output);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TLV_H */
diff --git a/components/rpc/common/test/protocol/check_rpc_status_alignment.cpp b/components/rpc/common/test/protocol/check_rpc_status_alignment.cpp
new file mode 100644
index 000000000..81cf64e3f
--- /dev/null
+++ b/components/rpc/common/test/protocol/check_rpc_status_alignment.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <rpc/common/protobuf/status.pb.h>
+#include <protocols/rpc/common/packed-c/status.h>
+#include <CppUTest/TestHarness.h>
+
+/*
+ * Check alignment of RPC status protocol values for different protocol
+ * definition schemes.
+ */
+TEST_GROUP(RpcStatusProtocolChecks) {
+
+};
+
+TEST(RpcStatusProtocolChecks, checkProtobufRpcStatusCodes) {
+
+ /*
+ * Check alignment between packed-c and protobuf rpc status codes
+ */
+ LONGS_EQUAL(TS_RPC_CALL_ACCEPTED, ts_rpc_Status_CALL_ACCEPTED);
+ LONGS_EQUAL(TS_RPC_ERROR_EP_DOES_NOT_EXIT, ts_rpc_Status_ERROR_EP_DOES_NOT_EXIT);
+ LONGS_EQUAL(TS_RPC_ERROR_INVALID_OPCODE, ts_rpc_Status_ERROR_INVALID_OPCODE);
+ LONGS_EQUAL(TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED, ts_rpc_Status_ERROR_SERIALIZATION_NOT_SUPPORTED);
+ LONGS_EQUAL(TS_RPC_ERROR_INVALID_REQ_BODY, ts_rpc_Status_ERROR_INVALID_REQ_BODY);
+ LONGS_EQUAL(TS_RPC_ERROR_INVALID_RESP_BODY, ts_rpc_Status_ERROR_INVALID_RESP_BODY);
+ LONGS_EQUAL(TS_RPC_ERROR_RESOURCE_FAILURE, ts_rpc_Status_ERROR_RESOURCE_FAILURE);
+ LONGS_EQUAL(TS_RPC_ERROR_NOT_READY, ts_rpc_Status_ERROR_NOT_READY);
+ LONGS_EQUAL(TS_RPC_ERROR_INVALID_TRANSACTION, ts_rpc_Status_ERROR_INVALID_TRANSACTION);
+ LONGS_EQUAL(TS_RPC_ERROR_INTERNAL, ts_rpc_Status_ERROR_INTERNAL);
+ LONGS_EQUAL(TS_RPC_ERROR_INVALID_PARAMETER, ts_rpc_Status_ERROR_INVALID_PARAMETER);
+} \ No newline at end of file
diff --git a/components/rpc/common/test/protocol/component.cmake b/components/rpc/common/test/protocol/component.cmake
new file mode 100644
index 000000000..8c7dabe4c
--- /dev/null
+++ b/components/rpc/common/test/protocol/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-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}/check_rpc_status_alignment.cpp"
+ )
+
diff --git a/components/service/crypto/client/cpp/crypto_client.cpp b/components/service/crypto/client/cpp/crypto_client.cpp
index b27a58544..602a6b5bb 100644
--- a/components/service/crypto/client/cpp/crypto_client.cpp
+++ b/components/service/crypto/client/cpp/crypto_client.cpp
@@ -4,27 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <cstring>
-#include <cstdlib>
#include "crypto_client.h"
#include <protocols/rpc/common/packed-c/status.h>
-#include <service/common/serializer/protobuf/pb_helper.h>
-#include <rpc_caller.h>
-#include <service/crypto/protobuf/opcodes.pb.h>
-#include <service/crypto/protobuf/generate_key.pb.h>
-#include <service/crypto/protobuf/destroy_key.pb.h>
-#include <service/crypto/protobuf/import_key.pb.h>
-#include <service/crypto/protobuf/open_key.pb.h>
-#include <service/crypto/protobuf/close_key.pb.h>
-#include <service/crypto/protobuf/export_key.pb.h>
-#include <service/crypto/protobuf/export_public_key.pb.h>
-#include <service/crypto/protobuf/sign_hash.pb.h>
-#include <service/crypto/protobuf/verify_hash.pb.h>
-#include <service/crypto/protobuf/asymmetric_encrypt.pb.h>
-#include <service/crypto/protobuf/asymmetric_decrypt.pb.h>
-#include <service/crypto/protobuf/generate_random.pb.h>
-#include <pb_encode.h>
-#include <pb_decode.h>
crypto_client::crypto_client() :
m_caller(NULL),
@@ -54,758 +35,3 @@ int crypto_client::err_rpc_status() const
{
return m_err_rpc_status;
}
-
-psa_status_t crypto_client::generate_key(const psa_key_attributes_t *attributes, psa_key_handle_t *handle)
-{
- 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;
-
- if (pb_get_encoded_size(&req_len, ts_crypto_GenerateKeyIn_fields, &req_msg)) {
-
- 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;
-
- 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);
-
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
-
- psa_status = opstatus;
-
- 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);
-
- if (pb_decode(&istream, ts_crypto_GenerateKeyOut_fields, &resp_msg)) {
-
- *handle = resp_msg.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 crypto_client::destroy_key(psa_key_handle_t handle)
-{
- 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.handle = handle;
-
- if (pb_get_encoded_size(&req_len, ts_crypto_DestroyKeyIn_fields, &req_msg)) {
-
- 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;
-
- 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);
-
- 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 crypto_client::open_key(psa_key_id_t id, psa_key_handle_t *handle)
-{
- size_t req_len;
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_OpenKeyIn req_msg = ts_crypto_OpenKeyIn_init_default;
- req_msg.id = id;
-
- if (pb_get_encoded_size(&req_len, ts_crypto_OpenKeyIn_fields, &req_msg)) {
-
- 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;
-
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_OpenKeyIn_fields, &req_msg);
-
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_OPEN_KEY, &opstatus, &resp_buf, &resp_len);
-
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
-
- psa_status = opstatus;
-
- if (psa_status == PSA_SUCCESS) {
-
- ts_crypto_OpenKeyOut resp_msg = ts_crypto_OpenKeyOut_init_default;
- pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
-
- if (pb_decode(&istream, ts_crypto_OpenKeyOut_fields, &resp_msg)) {
-
- *handle = resp_msg.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 crypto_client::close_key(psa_key_handle_t handle)
-{
- size_t req_len;
- psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
- ts_crypto_CloseKeyIn req_msg = ts_crypto_CloseKeyIn_init_default;
-
- req_msg.handle = handle;
-
- if (pb_get_encoded_size(&req_len, ts_crypto_CloseKeyIn_fields, &req_msg)) {
-
- 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;
-
- pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
- pb_encode(&ostream, ts_crypto_CloseKeyIn_fields, &req_msg);
-
- m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
- ts_crypto_Opcode_CLOSE_KEY, &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 crypto_client::import_key(const psa_key_attributes_t *attributes,
- const uint8_t *data, size_t data_length, psa_key_handle_t *handle)
-{
- 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);
-
- if (pb_get_encoded_size(&req_len, ts_crypto_ImportKeyIn_fields, &req_msg)) {
-
- 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;
-
- 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);
-
- if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
-
- psa_status = opstatus;
-
- 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);
-
- if (pb_decode(&istream, ts_crypto_ImportKeyOut_fields, &resp_msg)) {
-
- *handle = resp_msg.handle;
- }
- else {
- /* Failed to decode response message */
- psa_status = PSA_ERROR_GENERIC_ERROR;
- }
- }
- }
-
- rpc_caller_end(m_caller, call_handle);
- }
- }
-
- ::free(key_byte_array);
-
- return psa_status;
-}
-
-psa_status_t crypto_client::export_key(psa_key_handle_t handle,
- 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.handle = handle;
-
- *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;
-
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
-
- if (call_handle) {
-
- 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);
-
- 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) {
-
- psa_status = opstatus;
-
- 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);
-
- if (exported_key) {
-
- 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 (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;
- }
-
- ::free(exported_key);
- }
- else {
- /* Failed to allocate buffer for exported key */
- psa_status = PSA_ERROR_INSUFFICIENT_MEMORY;
- }
- }
- }
-
- rpc_caller_end(m_caller, call_handle);
- }
- }
-
- return psa_status;
-}
-
-psa_status_t crypto_client::export_public_key(psa_key_handle_t handle,
- 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.handle = handle;
-
- *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;
-
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
-
- if (call_handle) {
-
- 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);
-
- 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) {
-
- psa_status = opstatus;
-
- 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);
-
- if (exported_key) {
-
- 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 (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;
- }
-
- ::free(exported_key);
- }
- else {
- /* Failed to alloocate buffer for exported key */
- psa_status = PSA_ERROR_INSUFFICIENT_MEMORY;
- }
- }
- }
-
- rpc_caller_end(m_caller, call_handle);
- }
- }
-
- return psa_status;
-}
-
-psa_status_t crypto_client::sign_hash(psa_key_handle_t handle, psa_algorithm_t alg,
- 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;
-
- *signature_length = 0; /* For failure case */
-
- req_msg.handle = handle;
- 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;
-
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
-
- if (call_handle) {
-
- 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);
-
- 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) {
-
- psa_status = opstatus;
-
- 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_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
-
- if (pb_decode(&istream, ts_crypto_SignHashOut_fields, &resp_msg)) {
-
- 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;
- }
-
- ::free(sig_byte_array);
- }
- }
-
- rpc_caller_end(m_caller, call_handle);
- }
- }
-
- ::free(hash_byte_array);
-
- return psa_status;
-}
-
-
-psa_status_t crypto_client::verify_hash(psa_key_handle_t handle, psa_algorithm_t alg,
- 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.handle = handle;
- req_msg.alg = alg;
- req_msg.hash = pb_out_byte_array(hash_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;
-
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
-
- if (call_handle) {
-
- 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);
-
- 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;
-
- rpc_caller_end(m_caller, call_handle);
- }
- }
-
- ::free(hash_byte_array);
- ::free(sig_byte_array);
-
- return psa_status;
-}
-
-psa_status_t crypto_client::asymmetric_encrypt(psa_key_handle_t handle, 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)
-{
- 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.handle = handle;
- req_msg.alg = alg;
- req_msg.plaintext = pb_out_byte_array(plaintext_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;
-
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
-
- if (call_handle) {
-
- 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);
-
- 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) {
-
- psa_status = opstatus;
-
- 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_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
-
- if (pb_decode(&istream, ts_crypto_AsymmetricEncryptOut_fields, &resp_msg)) {
-
- 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;
- }
-
- ::free(ciphertext_byte_array);
- }
- }
-
- rpc_caller_end(m_caller, call_handle);
- }
- }
-
- ::free(plaintext_byte_array);
- ::free(salt_byte_array);
-
- return psa_status;
-}
-
-psa_status_t crypto_client::asymmetric_decrypt(psa_key_handle_t handle, 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)
-{
- 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.handle = handle;
- req_msg.alg = alg;
- req_msg.ciphertext = pb_out_byte_array(ciphertext_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;
-
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
-
- if (call_handle) {
-
- 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);
-
- 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) {
-
- psa_status = opstatus;
-
- 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_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
-
- if (pb_decode(&istream, ts_crypto_AsymmetricDecryptOut_fields, &resp_msg)) {
-
- 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;
- }
-
- ::free(plaintext_byte_array);
- }
- }
-
- rpc_caller_end(m_caller, call_handle);
- }
- }
-
- ::free(ciphertext_byte_array);
- ::free(salt_byte_array);
-
- return psa_status;
-}
-
-psa_status_t 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;
-
- 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;
-
- call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
-
- if (call_handle) {
-
- 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);
-
- 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) {
-
- psa_status = opstatus;
-
- 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_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
-
- if (pb_decode(&istream, ts_crypto_GenerateRandomOut_fields, &resp_msg)) {
-
- 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;
- }
-
- ::free(output_byte_array);
- }
- }
-
- rpc_caller_end(m_caller, call_handle);
- }
- }
-
- return psa_status;
-}
-
-void crypto_client::translate_key_attributes(ts_crypto_KeyAttributes &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.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/crypto_client.h b/components/service/crypto/client/cpp/crypto_client.h
index 3d0366f3a..5f6f0e133 100644
--- a/components/service/crypto/client/cpp/crypto_client.h
+++ b/components/service/crypto/client/cpp/crypto_client.h
@@ -9,66 +9,61 @@
#include <cstdint>
#include <psa/crypto.h>
-#include <service/crypto/protobuf/key_attributes.pb.h>
-
struct rpc_caller;
-/** Provides a client interface for accessing an instance of the PSA Crypto service.
- **/
+/*
+ * Provides a client interface for accessing an instance of the Crypto service
+ * using a C++ version of the PSA Crypto API.
+ */
class crypto_client
{
public:
- crypto_client(struct rpc_caller *caller);
virtual ~crypto_client();
int err_rpc_status() const;
/* Key lifecycle methods */
- psa_status_t generate_key(const psa_key_attributes_t *attributes, psa_key_handle_t *handle);
- psa_status_t destroy_key(psa_key_handle_t handle);
- psa_status_t open_key(psa_key_id_t id, psa_key_handle_t *handle);
- psa_status_t close_key(psa_key_handle_t handle);
- psa_status_t import_key(const psa_key_attributes_t *attributes,
- const uint8_t *data, size_t data_length, psa_key_handle_t *handle);
+ virtual psa_status_t generate_key(const psa_key_attributes_t *attributes, psa_key_handle_t *handle) = 0;
+ virtual psa_status_t destroy_key(psa_key_handle_t handle) = 0;
+ virtual psa_status_t open_key(psa_key_id_t id, psa_key_handle_t *handle) = 0;
+ virtual psa_status_t close_key(psa_key_handle_t handle) = 0;
+ virtual psa_status_t import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data, size_t data_length, psa_key_handle_t *handle) = 0;
/* Key export methods */
- psa_status_t export_key(psa_key_handle_t handle,
+ virtual psa_status_t export_key(psa_key_handle_t handle,
uint8_t *data, size_t data_size,
- size_t *data_length);
- psa_status_t export_public_key(psa_key_handle_t handle,
- uint8_t *data, size_t data_size, size_t *data_length);
+ size_t *data_length) = 0;
+ virtual psa_status_t export_public_key(psa_key_handle_t handle,
+ uint8_t *data, size_t data_size, size_t *data_length) = 0;
/* Sign/verify methods */
- psa_status_t sign_hash(psa_key_handle_t handle, psa_algorithm_t alg,
+ virtual psa_status_t sign_hash(psa_key_handle_t handle, 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_handle_t handle, psa_algorithm_t alg,
+ uint8_t *signature, size_t signature_size, size_t *signature_length) = 0;
+ virtual psa_status_t verify_hash(psa_key_handle_t handle, psa_algorithm_t alg,
const uint8_t *hash, size_t hash_length,
- const uint8_t *signature, size_t signature_length);
+ const uint8_t *signature, size_t signature_length) = 0;
/* Asymmetric encrypt/decrypt */
- psa_status_t asymmetric_encrypt(psa_key_handle_t handle, psa_algorithm_t alg,
+ virtual psa_status_t asymmetric_encrypt(psa_key_handle_t handle, 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_handle_t handle, psa_algorithm_t alg,
+ uint8_t *output, size_t output_size, size_t *output_length) = 0;
+ virtual psa_status_t asymmetric_decrypt(psa_key_handle_t handle, 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);
+ uint8_t *output, size_t output_size, size_t *output_length) = 0;
/* Random number generation */
- psa_status_t generate_random(uint8_t *output, size_t output_size);
+ virtual psa_status_t generate_random(uint8_t *output, size_t output_size) = 0;
protected:
crypto_client();
+ crypto_client(struct rpc_caller *caller);
void set_caller(struct rpc_caller *caller);
-private:
-
- void translate_key_attributes(ts_crypto_KeyAttributes &proto_attributes,
- const psa_key_attributes_t &psa_attributes);
-
struct rpc_caller *m_caller;
int m_err_rpc_status;
};
diff --git a/protocols/rpc/common/packed-c/test/component.cmake b/components/service/crypto/client/cpp/packed-c/component.cmake
index 28a896bd4..7ad58abaf 100644
--- a/protocols/rpc/common/packed-c/test/component.cmake
+++ b/components/service/crypto/client/cpp/packed-c/component.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -9,6 +9,6 @@ if (NOT DEFINED TGT)
endif()
target_sources(${TGT} PRIVATE
- "${CMAKE_CURRENT_LIST_DIR}/check_rpc_status_packed-c.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/packedc_crypto_client.cpp"
)
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
new file mode 100644
index 000000000..e0e85e01b
--- /dev/null
+++ b/components/service/crypto/client/cpp/packed-c/packedc_crypto_client.cpp
@@ -0,0 +1,749 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cstring>
+#include <cstdlib>
+#include "packedc_crypto_client.h"
+#include <protocols/rpc/common/packed-c/status.h>
+#include <protocols/service/crypto/packed-c/opcodes.h>
+#include <protocols/service/crypto/packed-c/key_attributes.h>
+#include <protocols/service/crypto/packed-c/asymmetric_decrypt.h>
+#include <protocols/service/crypto/packed-c/asymmetric_encrypt.h>
+#include <protocols/service/crypto/packed-c/close_key.h>
+#include <protocols/service/crypto/packed-c/destroy_key.h>
+#include <protocols/service/crypto/packed-c/export_key.h>
+#include <protocols/service/crypto/packed-c/export_public_key.h>
+#include <protocols/service/crypto/packed-c/generate_key.h>
+#include <protocols/service/crypto/packed-c/generate_random.h>
+#include <protocols/service/crypto/packed-c/import_key.h>
+#include <protocols/service/crypto/packed-c/open_key.h>
+#include <protocols/service/crypto/packed-c/sign_hash.h>
+#include <protocols/service/crypto/packed-c/verify_hash.h>
+#include <common/tlv/tlv.h>
+#include <rpc_caller.h>
+
+
+packedc_crypto_client::packedc_crypto_client() :
+ crypto_client()
+{
+
+}
+
+packedc_crypto_client::packedc_crypto_client(struct rpc_caller *caller) :
+ crypto_client(caller)
+{
+
+}
+
+packedc_crypto_client::~packedc_crypto_client()
+{
+
+}
+
+psa_status_t packedc_crypto_client::generate_key(const psa_key_attributes_t *attributes, psa_key_handle_t *handle)
+{
+ 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);
+
+ 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_GENERATE_KEY, &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_generate_key_out)) {
+
+ struct ts_crypto_generate_key_out resp_msg;
+ memcpy(&resp_msg, resp_buf, sizeof(ts_crypto_generate_key_out));
+ *handle = resp_msg.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::destroy_key(psa_key_handle_t handle)
+{
+ 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.handle = 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_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;
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+
+ return psa_status;
+}
+
+psa_status_t packedc_crypto_client::open_key(psa_key_id_t id, psa_key_handle_t *handle)
+{
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_open_key_in req_msg;
+ size_t req_len = sizeof(ts_crypto_open_key_in);
+
+ req_msg.id = id;
+
+ 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_OPEN_KEY, &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_open_key_out)) {
+
+ struct ts_crypto_open_key_out resp_msg;
+ memcpy(&resp_msg, resp_buf, sizeof(ts_crypto_open_key_out));
+ *handle = resp_msg.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::close_key(psa_key_handle_t handle)
+{
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_close_key_in req_msg;
+ size_t req_len = sizeof(ts_crypto_close_key_in);
+
+ req_msg.handle = 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_len);
+
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ TS_CRYPTO_OPCODE_CLOSE_KEY, &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::import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data, size_t data_length, psa_key_handle_t *handle)
+{
+ 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);
+
+ 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;
+
+ 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, &key_record);
+
+ 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) {
+
+ psa_status = opstatus;
+
+ if (psa_status == PSA_SUCCESS) {
+
+ if (resp_len >= sizeof(ts_crypto_open_key_out)) {
+
+ struct ts_crypto_import_key_out resp_msg;
+ memcpy(&resp_msg, resp_buf, sizeof(ts_crypto_import_key_out));
+ *handle = resp_msg.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::export_key(psa_key_handle_t handle,
+ 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);
+
+ req_msg.handle = handle;
+
+ *data_length = 0; /* For failure case */
+
+ 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_EXPORT_KEY, &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_EXPORT_KEY_OUT_TAG_DATA, &decoded_record)) {
+
+ 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;
+ }
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+
+ return psa_status;
+}
+
+psa_status_t packedc_crypto_client::export_public_key(psa_key_handle_t handle,
+ 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);
+
+ req_msg.handle = handle;
+
+ *data_length = 0; /* For failure case */
+
+ 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_EXPORT_PUBLIC_KEY, &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_EXPORT_PUBLIC_KEY_OUT_TAG_DATA, &decoded_record)) {
+
+ 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;
+ }
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+
+ return psa_status;
+}
+
+psa_status_t packedc_crypto_client::sign_hash(psa_key_handle_t handle, 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 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 */
+
+ req_msg.handle = handle;
+ 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;
+
+ 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, &hash_record);
+
+ 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) {
+
+ 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_SIGN_HASH_OUT_TAG_SIGNATURE, &decoded_record)) {
+
+ 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;
+ }
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+
+ return psa_status;
+}
+
+
+psa_status_t packedc_crypto_client::verify_hash(psa_key_handle_t handle, psa_algorithm_t alg,
+ 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);
+
+ req_msg.handle = handle;
+ 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 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;
+
+ 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, &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);
+
+ 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::asymmetric_encrypt(psa_key_handle_t handle, 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 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 + tlv_required_space(input_length) + tlv_required_space(salt_length);
+
+ *output_length = 0; /* For failure case */
+
+ req_msg.handle = handle;
+ req_msg.alg = alg;
+
+ struct tlv_record plaintext_record;
+ plaintext_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_PLAINTEXT;
+ plaintext_record.length = input_length;
+ plaintext_record.value = input;
+
+ struct tlv_record salt_record;
+ salt_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_SALT;
+ salt_record.length = salt_length;
+ salt_record.value = salt;
+
+ 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 = PSA_ERROR_GENERIC_ERROR;
+ 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, &plaintext_record);
+ 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);
+
+ 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_ASYMMETRIC_ENCRYPT_OUT_TAG_CIPHERTEXT, &decoded_record)) {
+
+ 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;
+ }
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+
+ return psa_status;
+}
+
+psa_status_t packedc_crypto_client::asymmetric_decrypt(psa_key_handle_t handle, 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 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 + tlv_required_space(input_length) + tlv_required_space(salt_length);
+
+ *output_length = 0; /* For failure case */
+
+ req_msg.handle = handle;
+ req_msg.alg = alg;
+
+ struct tlv_record ciphertext_record;
+ ciphertext_record.tag = TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_CIPHERTEXT;
+ ciphertext_record.length = input_length;
+ ciphertext_record.value = input;
+
+ struct tlv_record salt_record;
+ salt_record.tag = TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_SALT;
+ salt_record.length = salt_length;
+ salt_record.value = salt;
+
+ 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, &ciphertext_record);
+ 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);
+
+ 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_ASYMMETRIC_DECRYPT_OUT_TAG_PLAINTEXT, &decoded_record)) {
+
+ 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;
+ }
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+
+ 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);
+
+ req_msg.size = output_size;
+
+ 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_GENERATE_RANDOM, &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_GENERATE_RANDOM_OUT_TAG_RANDOM_BYTES, &decoded_record)) {
+
+ 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;
+ }
+ }
+ }
+
+ 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
new file mode 100644
index 000000000..fb5d7729b
--- /dev/null
+++ b/components/service/crypto/client/cpp/packed-c/packedc_crypto_client.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PACKEDC_CRYPTO_CLIENT_H
+#define PACKEDC_CRYPTO_CLIENT_H
+
+#include <service/crypto/client/cpp/crypto_client.h>
+#include <protocols/service/crypto/packed-c/key_attributes.h>
+
+/*
+ * A concrete crypto_client that uses the packed-c based crypto access protocol
+ */
+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_handle_t *handle);
+ psa_status_t destroy_key(psa_key_handle_t handle);
+ psa_status_t open_key(psa_key_id_t id, psa_key_handle_t *handle);
+ psa_status_t close_key(psa_key_handle_t handle);
+ psa_status_t import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data, size_t data_length, psa_key_handle_t *handle);
+
+ /* Key export methods */
+ psa_status_t export_key(psa_key_handle_t handle,
+ uint8_t *data, size_t data_size,
+ size_t *data_length);
+ psa_status_t export_public_key(psa_key_handle_t handle,
+ uint8_t *data, size_t data_size, size_t *data_length);
+
+ /* Sign/verify methods */
+ psa_status_t sign_hash(psa_key_handle_t handle, 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_handle_t handle, 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_handle_t handle, 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_handle_t handle, 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);
+
+private:
+
+ 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/component.cmake b/components/service/crypto/client/cpp/protobuf/component.cmake
new file mode 100644
index 000000000..ddb3f6bf7
--- /dev/null
+++ b/components/service/crypto/client/cpp/protobuf/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-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}/protobuf_crypto_client.cpp"
+ )
+
diff --git a/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.cpp b/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.cpp
new file mode 100644
index 000000000..681859086
--- /dev/null
+++ b/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.cpp
@@ -0,0 +1,799 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cstring>
+#include <cstdlib>
+#include "protobuf_crypto_client.h"
+#include <protocols/rpc/common/packed-c/status.h>
+#include <service/common/serializer/protobuf/pb_helper.h>
+#include <rpc_caller.h>
+#include <service/crypto/protobuf/opcodes.pb.h>
+#include <service/crypto/protobuf/generate_key.pb.h>
+#include <service/crypto/protobuf/destroy_key.pb.h>
+#include <service/crypto/protobuf/import_key.pb.h>
+#include <service/crypto/protobuf/open_key.pb.h>
+#include <service/crypto/protobuf/close_key.pb.h>
+#include <service/crypto/protobuf/export_key.pb.h>
+#include <service/crypto/protobuf/export_public_key.pb.h>
+#include <service/crypto/protobuf/sign_hash.pb.h>
+#include <service/crypto/protobuf/verify_hash.pb.h>
+#include <service/crypto/protobuf/asymmetric_encrypt.pb.h>
+#include <service/crypto/protobuf/asymmetric_decrypt.pb.h>
+#include <service/crypto/protobuf/generate_random.pb.h>
+#include <pb_encode.h>
+#include <pb_decode.h>
+
+protobuf_crypto_client::protobuf_crypto_client() :
+ crypto_client()
+{
+
+}
+
+protobuf_crypto_client::protobuf_crypto_client(struct rpc_caller *caller) :
+ crypto_client(caller)
+{
+
+}
+
+protobuf_crypto_client::~protobuf_crypto_client()
+{
+
+}
+
+psa_status_t protobuf_crypto_client::generate_key(const psa_key_attributes_t *attributes, psa_key_handle_t *handle)
+{
+ 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;
+
+ if (pb_get_encoded_size(&req_len, ts_crypto_GenerateKeyIn_fields, &req_msg)) {
+
+ 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;
+
+ 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);
+
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ psa_status = opstatus;
+
+ 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);
+
+ if (pb_decode(&istream, ts_crypto_GenerateKeyOut_fields, &resp_msg)) {
+
+ *handle = resp_msg.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 protobuf_crypto_client::destroy_key(psa_key_handle_t handle)
+{
+ 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.handle = handle;
+
+ if (pb_get_encoded_size(&req_len, ts_crypto_DestroyKeyIn_fields, &req_msg)) {
+
+ 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;
+
+ 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);
+
+ 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 protobuf_crypto_client::open_key(psa_key_id_t id, psa_key_handle_t *handle)
+{
+ size_t req_len;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_OpenKeyIn req_msg = ts_crypto_OpenKeyIn_init_default;
+ req_msg.id = id;
+
+ if (pb_get_encoded_size(&req_len, ts_crypto_OpenKeyIn_fields, &req_msg)) {
+
+ 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;
+
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_OpenKeyIn_fields, &req_msg);
+
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_OPEN_KEY, &opstatus, &resp_buf, &resp_len);
+
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ psa_status = opstatus;
+
+ if (psa_status == PSA_SUCCESS) {
+
+ ts_crypto_OpenKeyOut resp_msg = ts_crypto_OpenKeyOut_init_default;
+ pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+
+ if (pb_decode(&istream, ts_crypto_OpenKeyOut_fields, &resp_msg)) {
+
+ *handle = resp_msg.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 protobuf_crypto_client::close_key(psa_key_handle_t handle)
+{
+ size_t req_len;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ ts_crypto_CloseKeyIn req_msg = ts_crypto_CloseKeyIn_init_default;
+
+ req_msg.handle = handle;
+
+ if (pb_get_encoded_size(&req_len, ts_crypto_CloseKeyIn_fields, &req_msg)) {
+
+ 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;
+
+ pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
+ pb_encode(&ostream, ts_crypto_CloseKeyIn_fields, &req_msg);
+
+ m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
+ ts_crypto_Opcode_CLOSE_KEY, &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 protobuf_crypto_client::import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data, size_t data_length, psa_key_handle_t *handle)
+{
+ 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);
+
+ if (pb_get_encoded_size(&req_len, ts_crypto_ImportKeyIn_fields, &req_msg)) {
+
+ 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;
+
+ 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);
+
+ if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ psa_status = opstatus;
+
+ 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);
+
+ if (pb_decode(&istream, ts_crypto_ImportKeyOut_fields, &resp_msg)) {
+
+ *handle = resp_msg.handle;
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
+
+ ::free(key_byte_array);
+
+ return psa_status;
+}
+
+psa_status_t protobuf_crypto_client::export_key(psa_key_handle_t handle,
+ 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.handle = handle;
+
+ *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;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ 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);
+
+ 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) {
+
+ psa_status = opstatus;
+
+ 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);
+
+ if (exported_key) {
+
+ 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 (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;
+ }
+
+ ::free(exported_key);
+ }
+ else {
+ /* Failed to allocate buffer for exported key */
+ psa_status = PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
+
+ return psa_status;
+}
+
+psa_status_t protobuf_crypto_client::export_public_key(psa_key_handle_t handle,
+ 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.handle = handle;
+
+ *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;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ 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);
+
+ 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) {
+
+ psa_status = opstatus;
+
+ 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);
+
+ if (exported_key) {
+
+ 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 (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;
+ }
+
+ ::free(exported_key);
+ }
+ else {
+ /* Failed to alloocate buffer for exported key */
+ psa_status = PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
+
+ return psa_status;
+}
+
+psa_status_t protobuf_crypto_client::sign_hash(psa_key_handle_t handle, psa_algorithm_t alg,
+ 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;
+
+ *signature_length = 0; /* For failure case */
+
+ req_msg.handle = handle;
+ 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;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ 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);
+
+ 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) {
+
+ psa_status = opstatus;
+
+ 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_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+
+ if (pb_decode(&istream, ts_crypto_SignHashOut_fields, &resp_msg)) {
+
+ 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;
+ }
+
+ ::free(sig_byte_array);
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
+
+ ::free(hash_byte_array);
+
+ return psa_status;
+}
+
+
+psa_status_t protobuf_crypto_client::verify_hash(psa_key_handle_t handle, psa_algorithm_t alg,
+ 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.handle = handle;
+ req_msg.alg = alg;
+ req_msg.hash = pb_out_byte_array(hash_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;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ 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);
+
+ 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;
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
+
+ ::free(hash_byte_array);
+ ::free(sig_byte_array);
+
+ return psa_status;
+}
+
+psa_status_t protobuf_crypto_client::asymmetric_encrypt(psa_key_handle_t handle, 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)
+{
+ 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.handle = handle;
+ req_msg.alg = alg;
+ req_msg.plaintext = pb_out_byte_array(plaintext_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;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ 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);
+
+ 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) {
+
+ psa_status = opstatus;
+
+ 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_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+
+ if (pb_decode(&istream, ts_crypto_AsymmetricEncryptOut_fields, &resp_msg)) {
+
+ 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;
+ }
+
+ ::free(ciphertext_byte_array);
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
+
+ ::free(plaintext_byte_array);
+ ::free(salt_byte_array);
+
+ return psa_status;
+}
+
+psa_status_t protobuf_crypto_client::asymmetric_decrypt(psa_key_handle_t handle, 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)
+{
+ 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.handle = handle;
+ req_msg.alg = alg;
+ req_msg.ciphertext = pb_out_byte_array(ciphertext_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;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ 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);
+
+ 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) {
+
+ psa_status = opstatus;
+
+ 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_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+
+ if (pb_decode(&istream, ts_crypto_AsymmetricDecryptOut_fields, &resp_msg)) {
+
+ 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;
+ }
+
+ ::free(plaintext_byte_array);
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
+
+ ::free(ciphertext_byte_array);
+ ::free(salt_byte_array);
+
+ 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;
+
+ 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;
+
+ call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ 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);
+
+ 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) {
+
+ psa_status = opstatus;
+
+ 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_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
+
+ if (pb_decode(&istream, ts_crypto_GenerateRandomOut_fields, &resp_msg)) {
+
+ 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;
+ }
+
+ ::free(output_byte_array);
+ }
+ }
+
+ rpc_caller_end(m_caller, call_handle);
+ }
+ }
+
+ return psa_status;
+}
+
+void protobuf_crypto_client::translate_key_attributes(ts_crypto_KeyAttributes &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.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
new file mode 100644
index 000000000..e2a355a1d
--- /dev/null
+++ b/components/service/crypto/client/cpp/protobuf/protobuf_crypto_client.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PROTOBUF_CRYPTO_CLIENT_H
+#define PROTOBUF_CRYPTO_CLIENT_H
+
+#include <service/crypto/client/cpp/crypto_client.h>
+#include <service/crypto/protobuf/key_attributes.pb.h>
+
+/*
+ * A concrete crypto_client that uses the protobuf based crypto access protocol
+ */
+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_handle_t *handle);
+ psa_status_t destroy_key(psa_key_handle_t handle);
+ psa_status_t open_key(psa_key_id_t id, psa_key_handle_t *handle);
+ psa_status_t close_key(psa_key_handle_t handle);
+ psa_status_t import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data, size_t data_length, psa_key_handle_t *handle);
+
+ /* Key export methods */
+ psa_status_t export_key(psa_key_handle_t handle,
+ uint8_t *data, size_t data_size,
+ size_t *data_length);
+ psa_status_t export_public_key(psa_key_handle_t handle,
+ uint8_t *data, size_t data_size, size_t *data_length);
+
+ /* Sign/verify methods */
+ psa_status_t sign_hash(psa_key_handle_t handle, 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_handle_t handle, 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_handle_t handle, 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_handle_t handle, 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);
+
+private:
+
+ 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/client/test/mock/mock_crypto_client.cpp b/components/service/crypto/client/test/mock/mock_crypto_client.cpp
index a654ed14a..4ca482a5e 100644
--- a/components/service/crypto/client/test/mock/mock_crypto_client.cpp
+++ b/components/service/crypto/client/test/mock/mock_crypto_client.cpp
@@ -6,6 +6,7 @@
#include "mock_crypto_client.h"
#include <service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h>
+#include <service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.h>
mock_crypto_client::mock_crypto_client() :
test_crypto_client(),
@@ -40,6 +41,9 @@ bool mock_crypto_client::init()
mbed_crypto_provider_register_serializer(&m_crypto_provider,
TS_RPC_ENCODING_PROTOBUF, pb_crypto_provider_serializer_instance());
+ mbed_crypto_provider_register_serializer(&m_crypto_provider,
+ TS_RPC_ENCODING_PACKED_C, packedc_crypto_provider_serializer_instance());
+
rpc_caller_set_encoding_scheme(crypto_caller, TS_RPC_ENCODING_PROTOBUF);
crypto_client::set_caller(crypto_caller);
diff --git a/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp b/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp
index 459e42d6c..343bec1ad 100644
--- a/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp
+++ b/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp
@@ -8,6 +8,7 @@
#include <protocols/rpc/common/packed-c/status.h>
#include <protocols/service/psa/packed-c/status.h>
#include <service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h>
+#include <service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.h>
standalone_crypto_client::standalone_crypto_client() :
test_crypto_client(),
@@ -58,6 +59,9 @@ bool standalone_crypto_client::init()
mbed_crypto_provider_register_serializer(&m_crypto_provider,
TS_RPC_ENCODING_PROTOBUF, pb_crypto_provider_serializer_instance());
+ mbed_crypto_provider_register_serializer(&m_crypto_provider,
+ TS_RPC_ENCODING_PACKED_C, packedc_crypto_provider_serializer_instance());
+
rpc_caller_set_encoding_scheme(crypto_caller, TS_RPC_ENCODING_PROTOBUF);
crypto_client::set_caller(crypto_caller);
diff --git a/components/service/crypto/client/test/test_crypto_client.cpp b/components/service/crypto/client/test/test_crypto_client.cpp
index 72327904c..3217c61ac 100644
--- a/components/service/crypto/client/test/test_crypto_client.cpp
+++ b/components/service/crypto/client/test/test_crypto_client.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +10,7 @@
test_crypto_client::factory *test_crypto_client::m_default_factory = NULL;
test_crypto_client::test_crypto_client() :
- crypto_client(),
+ protobuf_crypto_client(),
m_is_initialized(false),
m_injected_faults()
{
diff --git a/components/service/crypto/client/test/test_crypto_client.h b/components/service/crypto/client/test/test_crypto_client.h
index 5b927dbe0..f1d70a1d1 100644
--- a/components/service/crypto/client/test/test_crypto_client.h
+++ b/components/service/crypto/client/test/test_crypto_client.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,7 +7,7 @@
#ifndef TEST_CRYPTO_CLIENT_H
#define TEST_CRYPTO_CLIENT_H
-#include <service/crypto/client/cpp/crypto_client.h>
+#include <service/crypto/client/cpp/protobuf/protobuf_crypto_client.h>
#include <vector>
/*
@@ -20,7 +20,7 @@
* Each virtual test method is paired with a is_supported() method to
* allow test cases to adapt to circumstances.
*/
-class test_crypto_client : public crypto_client
+class test_crypto_client : public protobuf_crypto_client
{
public:
virtual ~test_crypto_client();
diff --git a/components/service/crypto/provider/serializer/packed-c/component.cmake b/components/service/crypto/provider/serializer/packed-c/component.cmake
new file mode 100644
index 000000000..f4b010621
--- /dev/null
+++ b/components/service/crypto/provider/serializer/packed-c/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-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}/packedc_crypto_provider_serializer.c"
+ "${CMAKE_CURRENT_LIST_DIR}/packedc_key_attributes_translator.c"
+ )
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
new file mode 100644
index 000000000..f39aa1cff
--- /dev/null
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
@@ -0,0 +1,661 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <common/tlv/tlv.h>
+#include <psa/crypto.h>
+#include <protocols/rpc/common/packed-c/status.h>
+#include <protocols/service/crypto/packed-c/key_attributes.h>
+#include <protocols/service/crypto/packed-c/asymmetric_decrypt.h>
+#include <protocols/service/crypto/packed-c/asymmetric_encrypt.h>
+#include <protocols/service/crypto/packed-c/close_key.h>
+#include <protocols/service/crypto/packed-c/destroy_key.h>
+#include <protocols/service/crypto/packed-c/export_key.h>
+#include <protocols/service/crypto/packed-c/export_public_key.h>
+#include <protocols/service/crypto/packed-c/generate_key.h>
+#include <protocols/service/crypto/packed-c/generate_random.h>
+#include <protocols/service/crypto/packed-c/import_key.h>
+#include <protocols/service/crypto/packed-c/open_key.h>
+#include <protocols/service/crypto/packed-c/sign_hash.h>
+#include <protocols/service/crypto/packed-c/verify_hash.h>
+#include "packedc_crypto_provider_serializer.h"
+#include "packedc_key_attributes_translator.h"
+
+/* Returns the maximum possible deserialized parameter size for a packed-c encoded message. */
+static size_t max_deserialised_parameter_size(const struct call_param_buf *req_buf)
+{
+ /*
+ * Assume that a deserialized parameter must be the same size or smaller than the
+ * entire serialized message.
+ */
+ return req_buf->data_len;
+}
+
+/* Operation: generate_key */
+static rpc_status_t deserialize_generate_key_req(const struct call_param_buf *req_buf,
+ psa_key_attributes_t *attributes)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_generate_key_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_generate_key_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ packedc_crypto_provider_translate_key_attributes(attributes, &recv_msg.attributes);
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_generate_key_resp(struct call_param_buf *resp_buf,
+ psa_key_handle_t handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct ts_crypto_generate_key_out resp_msg;
+ size_t fixed_len = sizeof(struct ts_crypto_generate_key_out);
+
+ resp_msg.handle = 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: destroy_key */
+static rpc_status_t deserialize_destroy_key_req(const struct call_param_buf *req_buf,
+ psa_key_handle_t *handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_destroy_key_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_destroy_key_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *handle = recv_msg.handle;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+/* Operation: open_key */
+static rpc_status_t deserialize_open_key_req(const struct call_param_buf *req_buf, psa_key_id_t *id)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_open_key_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_open_key_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *id = recv_msg.id;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_open_key_resp(struct call_param_buf *resp_buf,
+ psa_key_handle_t handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct ts_crypto_open_key_out resp_msg;
+ size_t fixed_len = sizeof(struct ts_crypto_open_key_out);
+
+ resp_msg.handle = 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: close_key */
+static rpc_status_t deserialize_close_key_req(const struct call_param_buf *req_buf,
+ psa_key_handle_t *handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_close_key_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_close_key_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *handle = recv_msg.handle;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+/* Operation: export_key */
+static rpc_status_t deserialize_export_key_req(const struct call_param_buf *req_buf,
+ psa_key_handle_t *handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_export_key_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_export_key_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *handle = recv_msg.handle;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_export_key_resp(struct call_param_buf *resp_buf,
+ const uint8_t *data, size_t data_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct tlv_iterator resp_iter;
+
+ struct tlv_record key_record;
+ key_record.tag = TS_CRYPTO_EXPORT_KEY_OUT_TAG_DATA;
+ key_record.length = data_len;
+ key_record.value = data;
+
+ tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+
+ if (tlv_encode(&resp_iter, &key_record)) {
+
+ resp_buf->data_len = tlv_required_space(data_len);
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+/* Operation: export_public_key */
+static rpc_status_t deserialize_export_public_key_req(const struct call_param_buf *req_buf,
+ psa_key_handle_t *handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_export_public_key_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_export_public_key_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *handle = recv_msg.handle;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_export_public_key_resp(struct call_param_buf *resp_buf,
+ const uint8_t *data, size_t data_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct tlv_iterator resp_iter;
+
+ struct tlv_record key_record;
+ key_record.tag = TS_CRYPTO_EXPORT_PUBLIC_KEY_OUT_TAG_DATA;
+ key_record.length = data_len;
+ key_record.value = data;
+
+ tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+
+ if (tlv_encode(&resp_iter, &key_record)) {
+
+ resp_buf->data_len = tlv_required_space(data_len);
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+/* Operation: import_key */
+static rpc_status_t deserialize_import_key_req(const struct call_param_buf *req_buf,
+ psa_key_attributes_t *attributes, uint8_t *data, size_t *data_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_import_key_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_import_key_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ packedc_crypto_provider_translate_key_attributes(attributes, &recv_msg.attributes);
+
+ tlv_const_iterator_begin(&resp_iter,
+ (uint8_t*)req_buf->data + expected_fixed_len,
+ req_buf->data_len - expected_fixed_len);
+
+ if (tlv_find_decode(&resp_iter, TS_CRYPTO_IMPORT_KEY_IN_TAG_DATA, &decoded_record)) {
+
+ if (decoded_record.length <= *data_len) {
+
+ memcpy(data, decoded_record.value, decoded_record.length);
+ *data_len = decoded_record.length;
+ }
+ else {
+ /* Buffer provided too small */
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+ }
+ }
+ else {
+ /* Default for missing parameter */
+ *data_len = 0;
+ }
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_import_key_resp(struct call_param_buf *resp_buf,
+ psa_key_handle_t handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct ts_crypto_import_key_out resp_msg;
+ size_t fixed_len = sizeof(struct ts_crypto_import_key_out);
+
+ resp_msg.handle = 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: sign_hash */
+static rpc_status_t deserialize_sign_hash_req(const struct call_param_buf *req_buf,
+ psa_key_handle_t *handle, psa_algorithm_t *alg,
+ uint8_t *hash, size_t *hash_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_sign_hash_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_sign_hash_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+
+ *handle = recv_msg.handle;
+ *alg = recv_msg.alg;
+
+ tlv_const_iterator_begin(&resp_iter,
+ (uint8_t*)req_buf->data + expected_fixed_len,
+ req_buf->data_len - expected_fixed_len);
+
+ if (tlv_find_decode(&resp_iter, TS_CRYPTO_SIGN_HASH_IN_TAG_HASH, &decoded_record)) {
+
+ if (decoded_record.length <= *hash_len) {
+
+ memcpy(hash, decoded_record.value, decoded_record.length);
+ *hash_len = decoded_record.length;
+ }
+ else {
+ /* Buffer provided too small */
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+ }
+ }
+ else {
+ /* Default to a zero length hash */
+ *hash_len = 0;
+ }
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_sign_hash_resp(struct call_param_buf *resp_buf,
+ const uint8_t *sig, size_t sig_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct tlv_iterator resp_iter;
+
+ struct tlv_record sig_record;
+ sig_record.tag = TS_CRYPTO_SIGN_HASH_OUT_TAG_SIGNATURE;
+ sig_record.length = sig_len;
+ sig_record.value = sig;
+
+ tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+
+ if (tlv_encode(&resp_iter, &sig_record)) {
+
+ resp_buf->data_len = tlv_required_space(sig_len);
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+/* Operation: verify_hash */
+static rpc_status_t deserialize_verify_hash_req(const struct call_param_buf *req_buf,
+ psa_key_handle_t *handle, psa_algorithm_t *alg,
+ uint8_t *hash, size_t *hash_len,
+ uint8_t *sig, size_t *sig_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_verify_hash_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_verify_hash_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+
+ *handle = recv_msg.handle;
+ *alg = recv_msg.alg;
+
+ tlv_const_iterator_begin(&resp_iter,
+ (uint8_t*)req_buf->data + expected_fixed_len,
+ req_buf->data_len - expected_fixed_len);
+
+ if (tlv_find_decode(&resp_iter, TS_CRYPTO_VERIFY_HASH_IN_TAG_HASH, &decoded_record)) {
+
+ if (decoded_record.length <= *hash_len) {
+
+ memcpy(hash, decoded_record.value, decoded_record.length);
+ *hash_len = decoded_record.length;
+ }
+ else {
+ /* Buffer provided too small */
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+ }
+ }
+ else {
+ /* Default to a zero length hash */
+ *hash_len = 0;
+ }
+
+ if (tlv_find_decode(&resp_iter, TS_CRYPTO_VERIFY_HASH_IN_TAG_SIGNATURE, &decoded_record)) {
+
+ if (decoded_record.length <= *sig_len) {
+
+ memcpy(sig, decoded_record.value, decoded_record.length);
+ *sig_len = decoded_record.length;
+ }
+ else {
+ /* Buffer provided too small */
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+ }
+ }
+ else {
+ /* Default to a zero length hash */
+ *sig_len = 0;
+ }
+ }
+
+ return rpc_status;
+}
+
+/* Operation: asymmetric_decrypt */
+static rpc_status_t deserialize_asymmetric_decrypt_req(const struct call_param_buf *req_buf,
+ psa_key_handle_t *handle, psa_algorithm_t *alg,
+ uint8_t *ciphertext, size_t *ciphertext_len,
+ uint8_t *salt, size_t *salt_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_asymmetric_decrypt_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_asymmetric_decrypt_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+
+ *handle = recv_msg.handle;
+ *alg = recv_msg.alg;
+
+ tlv_const_iterator_begin(&resp_iter,
+ (uint8_t*)req_buf->data + expected_fixed_len,
+ req_buf->data_len - expected_fixed_len);
+
+ if (tlv_find_decode(&resp_iter, TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_CIPHERTEXT, &decoded_record)) {
+
+ if (decoded_record.length <= *ciphertext_len) {
+
+ memcpy(ciphertext, decoded_record.value, decoded_record.length);
+ *ciphertext_len = decoded_record.length;
+ }
+ else {
+ /* Buffer provided too small */
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+ }
+ }
+ else {
+ /* Default to a zero length hash */
+ *ciphertext_len = 0;
+ }
+
+ if (tlv_find_decode(&resp_iter, TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_SALT, &decoded_record)) {
+
+ if (decoded_record.length <= *salt_len) {
+
+ memcpy(salt, decoded_record.value, decoded_record.length);
+ *salt_len = decoded_record.length;
+ }
+ else {
+ /* Buffer provided too small */
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+ }
+ }
+ else {
+ /* Default to a zero length hash */
+ *salt_len = 0;
+ }
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_asymmetric_decrypt_resp(struct call_param_buf *resp_buf,
+ const uint8_t *plaintext, size_t plaintext_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct tlv_iterator resp_iter;
+
+ struct tlv_record sig_record;
+ sig_record.tag = TS_CRYPTO_ASYMMETRIC_DECRYPT_OUT_TAG_PLAINTEXT;
+ sig_record.length = plaintext_len;
+ sig_record.value = plaintext;
+
+ tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+
+ if (tlv_encode(&resp_iter, &sig_record)) {
+
+ resp_buf->data_len = tlv_required_space(plaintext_len);
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+/* Operation: asymmetric_encrypt */
+static rpc_status_t deserialize_asymmetric_encrypt_req(const struct call_param_buf *req_buf,
+ psa_key_handle_t *handle, psa_algorithm_t *alg,
+ uint8_t *plaintext, size_t *plaintext_len,
+ uint8_t *salt, size_t *salt_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_asymmetric_encrypt_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_asymmetric_encrypt_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+
+ *handle = recv_msg.handle;
+ *alg = recv_msg.alg;
+
+ tlv_const_iterator_begin(&resp_iter,
+ (uint8_t*)req_buf->data + expected_fixed_len,
+ req_buf->data_len - expected_fixed_len);
+
+ if (tlv_find_decode(&resp_iter, TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_PLAINTEXT, &decoded_record)) {
+
+ if (decoded_record.length <= *plaintext_len) {
+
+ memcpy(plaintext, decoded_record.value, decoded_record.length);
+ *plaintext_len = decoded_record.length;
+ }
+ else {
+ /* Buffer provided too small */
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+ }
+ }
+ else {
+ /* Default to a zero length hash */
+ *plaintext_len = 0;
+ }
+
+ if (tlv_find_decode(&resp_iter, TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_SALT, &decoded_record)) {
+
+ if (decoded_record.length <= *salt_len) {
+
+ memcpy(salt, decoded_record.value, decoded_record.length);
+ *salt_len = decoded_record.length;
+ }
+ else {
+ /* Buffer provided too small */
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+ }
+ }
+ else {
+ /* Default to a zero length hash */
+ *salt_len = 0;
+ }
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_asymmetric_encrypt_resp(struct call_param_buf *resp_buf,
+ const uint8_t *ciphertext, size_t ciphertext_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct tlv_iterator resp_iter;
+
+ struct tlv_record sig_record;
+ sig_record.tag = TS_CRYPTO_ASYMMETRIC_ENCRYPT_OUT_TAG_CIPHERTEXT;
+ sig_record.length = ciphertext_len;
+ sig_record.value = ciphertext;
+
+ tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+
+ if (tlv_encode(&resp_iter, &sig_record)) {
+
+ resp_buf->data_len = tlv_required_space(ciphertext_len);
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+/* Operation: generate_random */
+static rpc_status_t deserialize_generate_random_req(const struct call_param_buf *req_buf,
+ size_t *size)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_generate_random_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_generate_random_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *size = recv_msg.size;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_generate_random_resp(struct call_param_buf *resp_buf,
+ const uint8_t *output, size_t output_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_GENERATE_RANDOM_OUT_TAG_RANDOM_BYTES;
+ out_record.length = output_len;
+ out_record.value = output;
+
+ 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(output_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)
+{
+ static const struct crypto_provider_serializer instance = {
+ max_deserialised_parameter_size,
+ deserialize_generate_key_req,
+ serialize_generate_key_resp,
+ deserialize_destroy_key_req,
+ deserialize_open_key_req,
+ serialize_open_key_resp,
+ deserialize_close_key_req,
+ deserialize_export_key_req,
+ serialize_export_key_resp,
+ deserialize_export_public_key_req,
+ serialize_export_public_key_resp,
+ deserialize_import_key_req,
+ serialize_import_key_resp,
+ deserialize_sign_hash_req,
+ serialize_sign_hash_resp,
+ deserialize_verify_hash_req,
+ deserialize_asymmetric_decrypt_req,
+ serialize_asymmetric_decrypt_resp,
+ deserialize_asymmetric_encrypt_req,
+ serialize_asymmetric_encrypt_resp,
+ deserialize_generate_random_req,
+ serialize_generate_random_resp
+ };
+
+ return &instance;
+}
diff --git a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.h b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.h
new file mode 100644
index 000000000..2fdac43f7
--- /dev/null
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PACKEDC_CRYPTO_PROVIDER_SERIALIZER_H
+#define PACKEDC_CRYPTO_PROVIDER_SERIALIZER_H
+
+#include <service/crypto/provider/serializer/crypto_provider_serializer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Singleton method to provide access to the packed-c serializer
+ * for the crypto service provider.
+ */
+const struct crypto_provider_serializer *packedc_crypto_provider_serializer_instance(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* PACKEDC_CRYPTO_PROVIDER_SERIALIZER_H */
diff --git a/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.c b/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.c
new file mode 100644
index 000000000..cb88ceca4
--- /dev/null
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "packedc_key_attributes_translator.h"
+
+void packedc_crypto_provider_translate_key_attributes(psa_key_attributes_t *psa_attributes,
+ const struct ts_crypto_key_attributes *proto_attributes) {
+
+ psa_set_key_type(psa_attributes, proto_attributes->type);
+ psa_set_key_bits(psa_attributes, proto_attributes->key_bits);
+ psa_set_key_lifetime(psa_attributes, proto_attributes->lifetime);
+
+ if (proto_attributes->lifetime == PSA_KEY_LIFETIME_PERSISTENT) {
+
+ psa_set_key_id(psa_attributes, proto_attributes->id);
+ }
+
+ psa_set_key_usage_flags(psa_attributes, proto_attributes->policy.usage);
+ psa_set_key_algorithm(psa_attributes, proto_attributes->policy.alg);
+}
diff --git a/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.h b/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.h
new file mode 100644
index 000000000..ae8871d82
--- /dev/null
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PACKEDC_CRYPTO_PROVIDER_KEY_ATTRIBUTES_TRANSLATOR_H
+#define PACKEDC_CRYPTO_PROVIDER_KEY_ATTRIBUTES_TRANSLATOR_H
+
+#include <protocols/service/crypto/packed-c/key_attributes.h>
+#include <psa/crypto.h>
+
+void packedc_crypto_provider_translate_key_attributes(
+ psa_key_attributes_t *psa_attributes,
+ const struct ts_crypto_key_attributes *proto_attributes);
+
+#endif /* PACKEDC_CRYPTO_PROVIDER_KEY_ATTRIBUTES_TRANSLATOR_H */ \ No newline at end of file
diff --git a/components/service/crypto/provider/serializer/protobuf/component.cmake b/components/service/crypto/provider/serializer/protobuf/component.cmake
index 2a075b74d..f2772bd52 100644
--- a/components/service/crypto/provider/serializer/protobuf/component.cmake
+++ b/components/service/crypto/provider/serializer/protobuf/component.cmake
@@ -12,9 +12,3 @@ target_sources(${TGT} PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/pb_crypto_provider_serializer.c"
"${CMAKE_CURRENT_LIST_DIR}/pb_key_attributes_translator.c"
)
-
-
-target_include_directories(${TGT}
- PRIVATE
- "${CMAKE_CURRENT_LIST_DIR}"
- )
diff --git a/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c
index 2cf38fee8..a2631eafe 100644
--- a/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c
+++ b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c
@@ -29,7 +29,7 @@
static size_t max_deserialised_parameter_size(const struct call_param_buf *req_buf)
{
/*
- * Assume that a deserialized parameter must be the same size or smalled than the
+ * Assume that a deserialized parameter must be the same size or smaller than the
* entire serialized message.
*/
return req_buf->data_len;
diff --git a/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h
index 64191c02d..08ca2f0bb 100644
--- a/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h
+++ b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h
@@ -13,10 +13,11 @@
extern "C" {
#endif
-/* Singleton method to provide access to the Protobuf serializer
+/*
+ * Singleton method to provide access to the Protobuf serializer
* for the crypto service provider.
*/
-extern const struct crypto_provider_serializer *pb_crypto_provider_serializer_instance(void);
+const struct crypto_provider_serializer *pb_crypto_provider_serializer_instance(void);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h b/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h
index 5de359bb3..ef77c7390 100644
--- a/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h
+++ b/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h
@@ -10,7 +10,7 @@
#include <service/crypto/protobuf/key_attributes.pb.h>
#include <psa/crypto.h>
-extern void pb_crypto_provider_translate_key_attributes(
+void pb_crypto_provider_translate_key_attributes(
psa_key_attributes_t *psa_attributes,
const ts_crypto_KeyAttributes *proto_attributes);
diff --git a/components/service/crypto/test/protocol/check_crypto_opcode_alignment.cpp b/components/service/crypto/test/protocol/check_crypto_opcode_alignment.cpp
new file mode 100644
index 000000000..40910fad7
--- /dev/null
+++ b/components/service/crypto/test/protocol/check_crypto_opcode_alignment.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <psa/crypto.h>
+#include <protocols/service/crypto/packed-c/opcodes.h>
+#include <service/crypto/protobuf/opcodes.pb.h>
+#include <CppUTest/TestHarness.h>
+
+/*
+ * Check alignment of Crypto service opcode definitions
+ */
+TEST_GROUP(CryptoProtocolOpcodeChecks)
+{
+
+};
+
+TEST(CryptoProtocolOpcodeChecks, checkPackedcToProtobuf)
+{
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_GENERATE_KEY, ts_crypto_Opcode_GENERATE_KEY);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_DESTROY_KEY, ts_crypto_Opcode_DESTROY_KEY);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_OPEN_KEY, ts_crypto_Opcode_OPEN_KEY);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_CLOSE_KEY, ts_crypto_Opcode_CLOSE_KEY);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_EXPORT_KEY, ts_crypto_Opcode_EXPORT_KEY);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, ts_crypto_Opcode_EXPORT_PUBLIC_KEY);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_IMPORT_KEY, ts_crypto_Opcode_IMPORT_KEY);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_SIGN_HASH, ts_crypto_Opcode_SIGN_HASH);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_VERIFY_HASH, ts_crypto_Opcode_VERIFY_HASH);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, ts_crypto_Opcode_ASYMMETRIC_DECRYPT);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, ts_crypto_Opcode_ASYMMETRIC_ENCRYPT);
+ CHECK_EQUAL(TS_CRYPTO_OPCODE_GENERATE_RANDOM, ts_crypto_Opcode_GENERATE_RANDOM);
+}
+
diff --git a/components/service/crypto/test/protocol/check_crypto_packed-c_protocol_alignment.cpp b/components/service/crypto/test/protocol/check_crypto_packed-c_protocol_alignment.cpp
new file mode 100644
index 000000000..ff7ee0f86
--- /dev/null
+++ b/components/service/crypto/test/protocol/check_crypto_packed-c_protocol_alignment.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <psa/crypto.h>
+#include <protocols/service/crypto/packed-c/key_attributes.h>
+#include <CppUTest/TestHarness.h>
+
+/*
+ * Check alignment of Crypto service packed-c protocol definitions for
+ * alignment with PSA C API definitions.
+ */
+TEST_GROUP(CryptoProtocolPackedcChecks)
+{
+
+};
+
+TEST(CryptoProtocolPackedcChecks, checkKeyType)
+{
+ /*
+ * Check alignment between PSA and protobuf key type definitions
+ */
+ CHECK_EQUAL(PSA_KEY_TYPE_RAW_DATA, TS_CRYPTO_KEY_TYPE_RAW_DATA);
+ CHECK_EQUAL(PSA_KEY_TYPE_HMAC, TS_CRYPTO_KEY_TYPE_HMAC);
+ CHECK_EQUAL(PSA_KEY_TYPE_DERIVE, TS_CRYPTO_KEY_TYPE_DERIVE);
+ CHECK_EQUAL(PSA_KEY_TYPE_AES, TS_CRYPTO_KEY_TYPE_AES);
+ CHECK_EQUAL(PSA_KEY_TYPE_DES, TS_CRYPTO_KEY_TYPE_DES);
+ CHECK_EQUAL(PSA_KEY_TYPE_CAMELLIA, TS_CRYPTO_KEY_TYPE_CAMELLIA);
+ CHECK_EQUAL(PSA_KEY_TYPE_ARC4, TS_CRYPTO_KEY_TYPE_ARC4);
+ CHECK_EQUAL(PSA_KEY_TYPE_CHACHA20, TS_CRYPTO_KEY_TYPE_CHACHA20);
+ CHECK_EQUAL(PSA_KEY_TYPE_RSA_PUBLIC_KEY, TS_CRYPTO_KEY_TYPE_RSA_PUBLIC_KEY);
+ CHECK_EQUAL(PSA_KEY_TYPE_RSA_KEY_PAIR, TS_CRYPTO_KEY_TYPE_RSA_KEY_PAIR);
+ CHECK_EQUAL(PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE, TS_CRYPTO_KEY_TYPE_ECC_PUBLIC_KEY_BASE);
+ CHECK_EQUAL(PSA_KEY_TYPE_ECC_KEY_PAIR_BASE, TS_CRYPTO_KEY_TYPE_ECC_KEY_PAIR_BASE);
+ CHECK_EQUAL(PSA_KEY_TYPE_ECC_CURVE_MASK, TS_CRYPTO_KEY_TYPE_ECC_CURVE_MASK);
+ CHECK_EQUAL(PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE, TS_CRYPTO_KEY_TYPE_DH_PUBLIC_KEY_BASE);
+ CHECK_EQUAL(PSA_KEY_TYPE_DH_KEY_PAIR_BASE, TS_CRYPTO_KEY_TYPE_DH_KEY_PAIR_BASE);
+ CHECK_EQUAL(PSA_KEY_TYPE_DH_GROUP_MASK, TS_CRYPTO_KEY_TYPE_DH_GROUP_MASK);
+}
+
+TEST(CryptoProtocolPackedcChecks, checkEccCurve)
+{
+ /*
+ * ECC curves for use with ECC Key types
+ */
+ CHECK_EQUAL(PSA_ECC_CURVE_SECP_K1, TS_CRYPTO_ECC_CURVE_SECP_K1);
+ CHECK_EQUAL(PSA_ECC_CURVE_SECP_R1, TS_CRYPTO_ECC_CURVE_SECP_R1);
+ CHECK_EQUAL(PSA_ECC_CURVE_SECP_R2, TS_CRYPTO_ECC_CURVE_SECP_R2);
+ CHECK_EQUAL(PSA_ECC_CURVE_SECT_K1, TS_CRYPTO_ECC_CURVE_SECT_K1);
+ CHECK_EQUAL(PSA_ECC_CURVE_SECT_R1, TS_CRYPTO_ECC_CURVE_SECT_R1);
+ CHECK_EQUAL(PSA_ECC_CURVE_SECT_R2, TS_CRYPTO_ECC_CURVE_SECT_R2);
+ CHECK_EQUAL(PSA_ECC_CURVE_BRAINPOOL_P_R1, TS_CRYPTO_ECC_CURVE_BRAINPOOL_P_R1);
+ CHECK_EQUAL(PSA_ECC_CURVE_MONTGOMERY, TS_CRYPTO_ECC_CURVE_MONTGOMERY);
+}
+
+TEST(CryptoProtocolPackedcChecks, checkDhGroup)
+{
+ /*
+ * Diffie-Hellman groups for use with DH key types
+ */
+ CHECK_EQUAL(PSA_DH_GROUP_RFC7919, TS_CRYPTO_DH_GROUP_RFC7919);
+}
+
+TEST(CryptoProtocolPackedcChecks, checkAlg)
+{
+ /*
+ * Crypto algorithms
+ */
+ CHECK_EQUAL(PSA_ALG_HASH_MASK, TS_CRYPTO_ALG_HASH_MASK);
+ CHECK_EQUAL(PSA_ALG_MD2, TS_CRYPTO_ALG_MD2);
+ CHECK_EQUAL(PSA_ALG_MD4, TS_CRYPTO_ALG_MD4);
+ CHECK_EQUAL(PSA_ALG_MD5, TS_CRYPTO_ALG_MD5);
+ CHECK_EQUAL(PSA_ALG_RIPEMD160, TS_CRYPTO_ALG_RIPEMD160);
+ CHECK_EQUAL(PSA_ALG_SHA_1, TS_CRYPTO_ALG_SHA_1);
+ CHECK_EQUAL(PSA_ALG_SHA_224, TS_CRYPTO_ALG_SHA_224);
+ CHECK_EQUAL(PSA_ALG_SHA_256, TS_CRYPTO_ALG_SHA_256);
+ CHECK_EQUAL(PSA_ALG_SHA_384, TS_CRYPTO_ALG_SHA_384);
+ CHECK_EQUAL(PSA_ALG_SHA_512, TS_CRYPTO_ALG_SHA_512);
+ CHECK_EQUAL(PSA_ALG_SHA_512_224, TS_CRYPTO_ALG_SHA_512_224);
+ CHECK_EQUAL(PSA_ALG_SHA_512_256, TS_CRYPTO_ALG_SHA_512_256);
+ CHECK_EQUAL(PSA_ALG_SHA3_224, TS_CRYPTO_ALG_SHA3_224);
+ CHECK_EQUAL(PSA_ALG_SHA3_256, TS_CRYPTO_ALG_SHA3_256);
+ CHECK_EQUAL(PSA_ALG_SHA3_384, TS_CRYPTO_ALG_SHA3_384);
+ CHECK_EQUAL(PSA_ALG_SHA3_512, TS_CRYPTO_ALG_SHA3_512);
+ CHECK_EQUAL(PSA_ALG_CBC_MAC, TS_CRYPTO_ALG_CBC_MAC);
+ CHECK_EQUAL(PSA_ALG_CMAC, TS_CRYPTO_ALG_CMAC);
+ CHECK_EQUAL(PSA_ALG_ARC4, TS_CRYPTO_ALG_ARC4);
+ CHECK_EQUAL(PSA_ALG_CHACHA20, TS_CRYPTO_ALG_CHACHA20);
+ CHECK_EQUAL(PSA_ALG_CTR, TS_CRYPTO_ALG_CTR);
+ CHECK_EQUAL(PSA_ALG_CFB, TS_CRYPTO_ALG_CFB);
+ CHECK_EQUAL(PSA_ALG_OFB, TS_CRYPTO_ALG_OFB);
+ CHECK_EQUAL(PSA_ALG_XTS, TS_CRYPTO_ALG_XTS);
+ CHECK_EQUAL(PSA_ALG_CBC_NO_PADDING, TS_CRYPTO_ALG_CBC_NO_PADDING);
+ CHECK_EQUAL(PSA_ALG_CBC_PKCS7, TS_CRYPTO_ALG_CBC_PKCS7);
+ CHECK_EQUAL(PSA_ALG_AEAD_FROM_BLOCK_FLAG, TS_CRYPTO_ALG_AEAD_FROM_BLOCK_FLAG);
+ CHECK_EQUAL(PSA_ALG_CCM, TS_CRYPTO_ALG_CCM);
+ CHECK_EQUAL(PSA_ALG_GCM, TS_CRYPTO_ALG_GCM);
+ CHECK_EQUAL(PSA_ALG_CHACHA20_POLY1305, TS_CRYPTO_ALG_CHACHA20_POLY1305);
+ CHECK_EQUAL(PSA_ALG_RSA_PKCS1V15_SIGN_BASE, TS_CRYPTO_ALG_RSA_PKCS1V15_SIGN_BASE);
+ CHECK_EQUAL(PSA_ALG_RSA_PSS_BASE, TS_CRYPTO_ALG_RSA_PSS_BASE);
+ CHECK_EQUAL(PSA_ALG_ECDSA_BASE, TS_CRYPTO_ALG_ECDSA_BASE);
+ CHECK_EQUAL(PSA_ALG_DETERMINISTIC_ECDSA_BASE, TS_CRYPTO_ALG_DETERMINISTIC_ECDSA_BASE);
+ CHECK_EQUAL(PSA_ALG_RSA_PKCS1V15_CRYPT, TS_CRYPTO_ALG_RSA_PKCS1V15_CRYPT);
+ CHECK_EQUAL(PSA_ALG_RSA_OAEP_BASE, TS_CRYPTO_ALG_RSA_OAEP_BASE);
+ CHECK_EQUAL(PSA_ALG_HKDF_BASE, TS_CRYPTO_ALG_HKDF_BASE);
+ CHECK_EQUAL(PSA_ALG_TLS12_PRF_BASE, TS_CRYPTO_ALG_TLS12_PRF_BASE);
+ CHECK_EQUAL(PSA_ALG_TLS12_PSK_TO_MS_BASE, TS_CRYPTO_ALG_TLS12_PSK_TO_MS_BASE);
+ CHECK_EQUAL(PSA_ALG_KEY_DERIVATION_MASK, TS_CRYPTO_ALG_KEY_DERIVATION_MASK);
+ CHECK_EQUAL(PSA_ALG_KEY_AGREEMENT_MASK, TS_CRYPTO_ALG_KEY_AGREEMENT_MASK);
+ CHECK_EQUAL(PSA_ALG_FFDH, TS_CRYPTO_ALG_FFDH);
+ CHECK_EQUAL(PSA_ALG_ECDH, TS_CRYPTO_ALG_ECDH);
+}
+
+TEST(CryptoProtocolPackedcChecks, checkKeyLifetime)
+{
+ /*
+ * Key lifetime
+ */
+ CHECK_EQUAL(PSA_KEY_LIFETIME_VOLATILE, TS_CRYPTO_KEY_LIFETIME_VOLATILE);
+ CHECK_EQUAL(PSA_KEY_LIFETIME_PERSISTENT, TS_CRYPTO_KEY_LIFETIME_PERSISTENT);
+}
+
+TEST(CryptoProtocolPackedcChecks, checkKeyUsage)
+{
+ /*
+ * Key usage constraints
+ */
+ CHECK_EQUAL(PSA_KEY_USAGE_EXPORT, TS_CRYPTO_KEY_USAGE_EXPORT);
+ CHECK_EQUAL(PSA_KEY_USAGE_COPY, TS_CRYPTO_KEY_USAGE_COPY);
+ CHECK_EQUAL(PSA_KEY_USAGE_ENCRYPT, TS_CRYPTO_KEY_USAGE_ENCRYPT);
+ CHECK_EQUAL(PSA_KEY_USAGE_DECRYPT, TS_CRYPTO_KEY_USAGE_DECRYPT);
+ CHECK_EQUAL(PSA_KEY_USAGE_SIGN_HASH, TS_CRYPTO_KEY_USAGE_SIGN_HASH);
+ CHECK_EQUAL(PSA_KEY_USAGE_VERIFY_HASH, TS_CRYPTO_KEY_USAGE_VERIFY_HASH);
+ CHECK_EQUAL(PSA_KEY_USAGE_DERIVE, TS_CRYPTO_KEY_USAGE_DERIVE);
+} \ No newline at end of file
diff --git a/components/service/crypto/test/protocol/check_crypto_protobuf_protocol_alignment.cpp b/components/service/crypto/test/protocol/check_crypto_protobuf_protocol_alignment.cpp
new file mode 100644
index 000000000..16f8cba5f
--- /dev/null
+++ b/components/service/crypto/test/protocol/check_crypto_protobuf_protocol_alignment.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <psa/crypto.h>
+#include <service/crypto/protobuf/key_attributes.pb.h>
+#include <CppUTest/TestHarness.h>
+
+/*
+ * Check alignment of Crypto service protobuf protocol definitions for
+ * alignment with PSA C API definitions.
+ */
+TEST_GROUP(CryptoProtocolProtobufChecks)
+{
+
+};
+
+TEST(CryptoProtocolProtobufChecks, checkKeyType)
+{
+ /*
+ * Check alignment between PSA and protobuf key type definitions
+ */
+ CHECK_EQUAL(PSA_KEY_TYPE_RAW_DATA, ts_crypto_KeyType_KEY_TYPE_RAW_DATA);
+ CHECK_EQUAL(PSA_KEY_TYPE_HMAC, ts_crypto_KeyType_KEY_TYPE_HMAC);
+ CHECK_EQUAL(PSA_KEY_TYPE_DERIVE, ts_crypto_KeyType_KEY_TYPE_DERIVE);
+ CHECK_EQUAL(PSA_KEY_TYPE_AES, ts_crypto_KeyType_KEY_TYPE_AES);
+ CHECK_EQUAL(PSA_KEY_TYPE_DES, ts_crypto_KeyType_KEY_TYPE_DES);
+ CHECK_EQUAL(PSA_KEY_TYPE_CAMELLIA, ts_crypto_KeyType_KEY_TYPE_CAMELLIA);
+ CHECK_EQUAL(PSA_KEY_TYPE_ARC4, ts_crypto_KeyType_KEY_TYPE_ARC4);
+ CHECK_EQUAL(PSA_KEY_TYPE_CHACHA20, ts_crypto_KeyType_KEY_TYPE_CHACHA20);
+ CHECK_EQUAL(PSA_KEY_TYPE_RSA_PUBLIC_KEY, ts_crypto_KeyType_KEY_TYPE_RSA_PUBLIC_KEY);
+ CHECK_EQUAL(PSA_KEY_TYPE_RSA_KEY_PAIR, ts_crypto_KeyType_KEY_TYPE_RSA_KEY_PAIR);
+ CHECK_EQUAL(PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE, ts_crypto_KeyType_KEY_TYPE_ECC_PUBLIC_KEY_BASE);
+ CHECK_EQUAL(PSA_KEY_TYPE_ECC_KEY_PAIR_BASE, ts_crypto_KeyType_KEY_TYPE_ECC_KEY_PAIR_BASE);
+ CHECK_EQUAL(PSA_KEY_TYPE_ECC_CURVE_MASK, ts_crypto_KeyType_KEY_TYPE_ECC_CURVE_MASK);
+ CHECK_EQUAL(PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE, ts_crypto_KeyType_KEY_TYPE_DH_PUBLIC_KEY_BASE);
+ CHECK_EQUAL(PSA_KEY_TYPE_DH_KEY_PAIR_BASE, ts_crypto_KeyType_KEY_TYPE_DH_KEY_PAIR_BASE);
+ CHECK_EQUAL(PSA_KEY_TYPE_DH_GROUP_MASK, ts_crypto_KeyType_KEY_TYPE_DH_GROUP_MASK);
+}
+
+TEST(CryptoProtocolProtobufChecks, checkEccCurve)
+{
+ /*
+ * ECC curves for use with ECC Key types
+ */
+ CHECK_EQUAL(PSA_ECC_CURVE_SECP_K1, ts_crypto_EccCurve_ECC_CURVE_SECP_K1);
+ CHECK_EQUAL(PSA_ECC_CURVE_SECP_R1, ts_crypto_EccCurve_ECC_CURVE_SECP_R1);
+ CHECK_EQUAL(PSA_ECC_CURVE_SECP_R2, ts_crypto_EccCurve_ECC_CURVE_SECP_R2);
+ CHECK_EQUAL(PSA_ECC_CURVE_SECT_K1, ts_crypto_EccCurve_ECC_CURVE_SECT_K1);
+ CHECK_EQUAL(PSA_ECC_CURVE_SECT_R1, ts_crypto_EccCurve_ECC_CURVE_SECT_R1);
+ CHECK_EQUAL(PSA_ECC_CURVE_SECT_R2, ts_crypto_EccCurve_ECC_CURVE_SECT_R2);
+ CHECK_EQUAL(PSA_ECC_CURVE_BRAINPOOL_P_R1, ts_crypto_EccCurve_ECC_CURVE_BRAINPOOL_P_R1);
+ CHECK_EQUAL(PSA_ECC_CURVE_MONTGOMERY, ts_crypto_EccCurve_ECC_CURVE_MONTGOMERY);
+}
+
+TEST(CryptoProtocolProtobufChecks, checkDhGroup)
+{
+ /*
+ * Diffie-Hellman groups for use with DH key types
+ */
+ CHECK_EQUAL(PSA_DH_GROUP_RFC7919, ts_crypto_DhGroup_DH_GROUP_RFC7919);
+}
+
+TEST(CryptoProtocolProtobufChecks, checkAlg)
+{
+ /*
+ * Crypto algorithms
+ */
+ CHECK_EQUAL(PSA_ALG_HASH_MASK, ts_crypto_Alg_ALG_HASH_MASK);
+ CHECK_EQUAL(PSA_ALG_MD2, ts_crypto_Alg_ALG_MD2);
+ CHECK_EQUAL(PSA_ALG_MD4, ts_crypto_Alg_ALG_MD4);
+ CHECK_EQUAL(PSA_ALG_MD5, ts_crypto_Alg_ALG_MD5);
+ CHECK_EQUAL(PSA_ALG_RIPEMD160, ts_crypto_Alg_ALG_RIPEMD160);
+ CHECK_EQUAL(PSA_ALG_SHA_1, ts_crypto_Alg_ALG_SHA_1);
+ CHECK_EQUAL(PSA_ALG_SHA_224, ts_crypto_Alg_ALG_SHA_224);
+ CHECK_EQUAL(PSA_ALG_SHA_256, ts_crypto_Alg_ALG_SHA_256);
+ CHECK_EQUAL(PSA_ALG_SHA_384, ts_crypto_Alg_ALG_SHA_384);
+ CHECK_EQUAL(PSA_ALG_SHA_512, ts_crypto_Alg_ALG_SHA_512);
+ CHECK_EQUAL(PSA_ALG_SHA_512_224, ts_crypto_Alg_ALG_SHA_512_224);
+ CHECK_EQUAL(PSA_ALG_SHA_512_256, ts_crypto_Alg_ALG_SHA_512_256);
+ CHECK_EQUAL(PSA_ALG_SHA3_224, ts_crypto_Alg_ALG_SHA3_224);
+ CHECK_EQUAL(PSA_ALG_SHA3_256, ts_crypto_Alg_ALG_SHA3_256);
+ CHECK_EQUAL(PSA_ALG_SHA3_384, ts_crypto_Alg_ALG_SHA3_384);
+ CHECK_EQUAL(PSA_ALG_SHA3_512, ts_crypto_Alg_ALG_SHA3_512);
+ CHECK_EQUAL(PSA_ALG_CBC_MAC, ts_crypto_Alg_ALG_CBC_MAC);
+ CHECK_EQUAL(PSA_ALG_CMAC, ts_crypto_Alg_ALG_CMAC);
+ CHECK_EQUAL(PSA_ALG_ARC4, ts_crypto_Alg_ALG_ARC4);
+ CHECK_EQUAL(PSA_ALG_CHACHA20, ts_crypto_Alg_ALG_CHACHA20);
+ CHECK_EQUAL(PSA_ALG_CTR, ts_crypto_Alg_ALG_CTR);
+ CHECK_EQUAL(PSA_ALG_CFB, ts_crypto_Alg_ALG_CFB);
+ CHECK_EQUAL(PSA_ALG_OFB, ts_crypto_Alg_ALG_OFB);
+ CHECK_EQUAL(PSA_ALG_XTS, ts_crypto_Alg_ALG_XTS);
+ CHECK_EQUAL(PSA_ALG_CBC_NO_PADDING, ts_crypto_Alg_ALG_CBC_NO_PADDING);
+ CHECK_EQUAL(PSA_ALG_CBC_PKCS7, ts_crypto_Alg_ALG_CBC_PKCS7);
+ CHECK_EQUAL(PSA_ALG_AEAD_FROM_BLOCK_FLAG, ts_crypto_Alg_ALG_AEAD_FROM_BLOCK_FLAG);
+ CHECK_EQUAL(PSA_ALG_CCM, ts_crypto_Alg_ALG_CCM);
+ CHECK_EQUAL(PSA_ALG_GCM, ts_crypto_Alg_ALG_GCM);
+ CHECK_EQUAL(PSA_ALG_CHACHA20_POLY1305, ts_crypto_Alg_ALG_CHACHA20_POLY1305);
+ CHECK_EQUAL(PSA_ALG_RSA_PKCS1V15_SIGN_BASE, ts_crypto_Alg_ALG_RSA_PKCS1V15_SIGN_BASE);
+ CHECK_EQUAL(PSA_ALG_RSA_PSS_BASE, ts_crypto_Alg_ALG_RSA_PSS_BASE);
+ CHECK_EQUAL(PSA_ALG_ECDSA_BASE, ts_crypto_Alg_ALG_ECDSA_BASE);
+ CHECK_EQUAL(PSA_ALG_DETERMINISTIC_ECDSA_BASE, ts_crypto_Alg_ALG_DETERMINISTIC_ECDSA_BASE);
+ CHECK_EQUAL(PSA_ALG_RSA_PKCS1V15_CRYPT, ts_crypto_Alg_ALG_RSA_PKCS1V15_CRYPT);
+ CHECK_EQUAL(PSA_ALG_RSA_OAEP_BASE, ts_crypto_Alg_ALG_RSA_OAEP_BASE);
+ CHECK_EQUAL(PSA_ALG_HKDF_BASE, ts_crypto_Alg_ALG_HKDF_BASE);
+ CHECK_EQUAL(PSA_ALG_TLS12_PRF_BASE, ts_crypto_Alg_ALG_TLS12_PRF_BASE);
+ CHECK_EQUAL(PSA_ALG_TLS12_PSK_TO_MS_BASE, ts_crypto_Alg_ALG_TLS12_PSK_TO_MS_BASE);
+ CHECK_EQUAL(PSA_ALG_KEY_DERIVATION_MASK, ts_crypto_Alg_ALG_KEY_DERIVATION_MASK);
+ CHECK_EQUAL(PSA_ALG_KEY_AGREEMENT_MASK, ts_crypto_Alg_ALG_KEY_AGREEMENT_MASK);
+ CHECK_EQUAL(PSA_ALG_FFDH, ts_crypto_Alg_ALG_FFDH);
+ CHECK_EQUAL(PSA_ALG_ECDH, ts_crypto_Alg_ALG_ECDH);
+}
+
+TEST(CryptoProtocolProtobufChecks, checkKeyLifetime)
+{
+ /*
+ * Key lifetime
+ */
+ CHECK_EQUAL(PSA_KEY_LIFETIME_VOLATILE, ts_crypto_KeyLifetime_KEY_LIFETIME_VOLATILE);
+ CHECK_EQUAL(PSA_KEY_LIFETIME_PERSISTENT, ts_crypto_KeyLifetime_KEY_LIFETIME_PERSISTENT);
+}
+
+TEST(CryptoProtocolProtobufChecks, checkKeyUsage)
+{
+ /*
+ * Key usage constraints
+ */
+ CHECK_EQUAL(PSA_KEY_USAGE_EXPORT, ts_crypto_KeyUsage_KEY_USAGE_EXPORT);
+ CHECK_EQUAL(PSA_KEY_USAGE_COPY, ts_crypto_KeyUsage_KEY_USAGE_COPY);
+ CHECK_EQUAL(PSA_KEY_USAGE_ENCRYPT, ts_crypto_KeyUsage_KEY_USAGE_ENCRYPT);
+ CHECK_EQUAL(PSA_KEY_USAGE_DECRYPT, ts_crypto_KeyUsage_KEY_USAGE_DECRYPT);
+ CHECK_EQUAL(PSA_KEY_USAGE_SIGN_HASH, ts_crypto_KeyUsage_KEY_USAGE_SIGN_HASH);
+ CHECK_EQUAL(PSA_KEY_USAGE_VERIFY_HASH, ts_crypto_KeyUsage_KEY_USAGE_VERIFY_HASH);
+ CHECK_EQUAL(PSA_KEY_USAGE_DERIVE, ts_crypto_KeyUsage_KEY_USAGE_DERIVE);
+}
diff --git a/components/service/crypto/test/protocol/component.cmake b/components/service/crypto/test/protocol/component.cmake
new file mode 100644
index 000000000..ed590bc94
--- /dev/null
+++ b/components/service/crypto/test/protocol/component.cmake
@@ -0,0 +1,16 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-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}/check_crypto_opcode_alignment.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/check_crypto_protobuf_protocol_alignment.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/check_crypto_packed-c_protocol_alignment.cpp"
+ )
+
diff --git a/components/service/crypto/test/service/component.cmake b/components/service/crypto/test/service/component.cmake
index 26366fd36..8aad32042 100644
--- a/components/service/crypto/test/service/component.cmake
+++ b/components/service/crypto/test/service/component.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -9,7 +9,7 @@ if (NOT DEFINED TGT)
endif()
target_sources(${TGT} PRIVATE
- "${CMAKE_CURRENT_LIST_DIR}/crypto_service_op_tests.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/crypto_service_scenarios.cpp"
"${CMAKE_CURRENT_LIST_DIR}/crypto_service_limit_tests.cpp"
)
diff --git a/components/service/crypto/test/service/crypto_service_limit_tests.cpp b/components/service/crypto/test/service/crypto_service_limit_tests.cpp
index 392391a10..2bb19f99a 100644
--- a/components/service/crypto/test/service/crypto_service_limit_tests.cpp
+++ b/components/service/crypto/test/service/crypto_service_limit_tests.cpp
@@ -8,7 +8,7 @@
#include <vector>
#include <cstring>
#include <cstdint>
-#include <service/crypto/client/cpp/crypto_client.h>
+#include <service/crypto/client/cpp/protobuf/protobuf_crypto_client.h>
#include <protocols/rpc/common/packed-c/encoding.h>
#include <service_locator.h>
#include <CppUTest/TestHarness.h>
@@ -36,7 +36,7 @@ TEST_GROUP(CryptoServiceLimitTests)
m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PROTOBUF, &caller);
CHECK(m_rpc_session_handle);
- m_crypto_client = new crypto_client(caller);
+ m_crypto_client = new protobuf_crypto_client(caller);
}
void teardown()
diff --git a/components/service/crypto/test/service/crypto_service_op_tests.cpp b/components/service/crypto/test/service/crypto_service_scenarios.cpp
index 569a196c8..80d727923 100644
--- a/components/service/crypto/test/service/crypto_service_op_tests.cpp
+++ b/components/service/crypto/test/service/crypto_service_scenarios.cpp
@@ -7,56 +7,23 @@
#include <string>
#include <cstring>
#include <cstdint>
-#include <service/crypto/client/cpp/crypto_client.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
-#include <service_locator.h>
#include <CppUTest/TestHarness.h>
+#include "crypto_service_scenarios.h"
-/*
- * Service-level tests that focus on exercising each supported operation.
- * These are mainly valid behaviour tests with the goal of checking
- * that the number of operations supported is as expected.
- */
-TEST_GROUP(CryptoServiceOpTests)
-{
- void setup()
- {
- struct rpc_caller *caller;
- int status;
-
- m_rpc_session_handle = NULL;
- m_crypto_service_context = NULL;
- m_crypto_client = NULL;
-
- service_locator_init();
-
- m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
- CHECK_TRUE(m_crypto_service_context);
-
- m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PROTOBUF, &caller);
- CHECK_TRUE(m_rpc_session_handle);
- m_crypto_client = new crypto_client(caller);
- }
-
- void teardown()
- {
- delete m_crypto_client;
- m_crypto_client = NULL;
-
- service_context_close(m_crypto_service_context, m_rpc_session_handle);
- m_rpc_session_handle = NULL;
+crypto_service_scenarios::crypto_service_scenarios(crypto_client *crypto_client) :
+ m_crypto_client(crypto_client)
+{
- service_context_relinquish(m_crypto_service_context);
- m_crypto_service_context = NULL;
- }
+}
- rpc_session_handle m_rpc_session_handle;
- struct service_context *m_crypto_service_context;
- crypto_client *m_crypto_client;
-};
+crypto_service_scenarios::~crypto_service_scenarios()
+{
+ delete m_crypto_client;
+ m_crypto_client = NULL;
+}
-TEST(CryptoServiceOpTests, generateVolatileKeys)
+void crypto_service_scenarios::generateVolatileKeys()
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -89,7 +56,7 @@ TEST(CryptoServiceOpTests, generateVolatileKeys)
psa_reset_key_attributes(&attributes);
}
-TEST(CryptoServiceOpTests, generatePersistentKeys)
+void crypto_service_scenarios::generatePersistentKeys()
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -151,7 +118,7 @@ TEST(CryptoServiceOpTests, generatePersistentKeys)
psa_reset_key_attributes(&attributes);
}
-TEST(CryptoServiceOpTests, exportPublicKey)
+void crypto_service_scenarios::exportPublicKey()
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -175,14 +142,14 @@ TEST(CryptoServiceOpTests, exportPublicKey)
status = m_crypto_client->export_public_key(key_handle, key_buf, sizeof(key_buf), &key_len);
CHECK_EQUAL(PSA_SUCCESS, status);
- CHECK(key_len > 0);
+ CHECK_TRUE(key_len > 0);
/* Remove the key */
status = m_crypto_client->destroy_key(key_handle);
CHECK_EQUAL(PSA_SUCCESS, status);
}
-TEST(CryptoServiceOpTests, exportAndImportKeyPair)
+void crypto_service_scenarios::exportAndImportKeyPair()
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -221,7 +188,7 @@ TEST(CryptoServiceOpTests, exportAndImportKeyPair)
CHECK_EQUAL(PSA_SUCCESS, status);
}
-TEST(CryptoServiceOpTests, signAndVerifyHash)
+void crypto_service_scenarios::signAndVerifyHash()
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -271,7 +238,7 @@ TEST(CryptoServiceOpTests, signAndVerifyHash)
CHECK_EQUAL(PSA_SUCCESS, status);
}
-TEST(CryptoServiceOpTests, asymEncryptDecrypt)
+void crypto_service_scenarios::asymEncryptDecrypt()
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@@ -310,14 +277,14 @@ TEST(CryptoServiceOpTests, asymEncryptDecrypt)
/* Expect the encrypted/decrypted message to match theh original */
CHECK_EQUAL(sizeof(message), plaintext_len);
- CHECK(memcmp(message, plaintext, plaintext_len) == 0);
+ MEMCMP_EQUAL(message, plaintext, plaintext_len);
/* Remove the key */
status = m_crypto_client->destroy_key(key_handle);
CHECK_EQUAL(PSA_SUCCESS, status);
}
-TEST(CryptoServiceOpTests, generateRandomNumbers)
+void crypto_service_scenarios::generateRandomNumbers()
{
psa_status_t status;
uint8_t num1_8bit[1];
@@ -373,9 +340,7 @@ TEST(CryptoServiceOpTests, generateRandomNumbers)
status = m_crypto_client->generate_random(num12_128bit, sizeof(num12_128bit));
CHECK_EQUAL(PSA_SUCCESS, status);
- /* Expect different numbers to be generated */
- CHECK(memcmp(num1_8bit, num2_8bit, sizeof(num1_8bit)) != 0);
- CHECK(memcmp(num3_16bit, num4_16bit, sizeof(num3_16bit)) != 0);
+ /* 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);
diff --git a/components/service/crypto/test/service/crypto_service_scenarios.h b/components/service/crypto/test/service/crypto_service_scenarios.h
new file mode 100644
index 000000000..2c7d18838
--- /dev/null
+++ b/components/service/crypto/test/service/crypto_service_scenarios.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <service/crypto/client/cpp/crypto_client.h>
+
+/*
+ * Service-level test scenarios for the crypto service that may be reused using
+ * different concrete crypto_clients to check end-to-end operation using different
+ * protocol serialization schemes.
+ */
+class crypto_service_scenarios
+{
+public:
+ crypto_service_scenarios(crypto_client *crypto_client);
+ ~crypto_service_scenarios();
+
+ void generateRandomNumbers();
+ void asymEncryptDecrypt();
+ void signAndVerifyHash();
+ void exportAndImportKeyPair();
+ void exportPublicKey();
+ void generatePersistentKeys();
+ void generateVolatileKeys();
+
+private:
+ crypto_client *m_crypto_client;
+};
diff --git a/components/service/crypto/test/service/packed-c/component.cmake b/components/service/crypto/test/service/packed-c/component.cmake
new file mode 100644
index 000000000..fcd6b2028
--- /dev/null
+++ b/components/service/crypto/test/service/packed-c/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-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_service_packedc_tests.cpp"
+ )
+
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
new file mode 100644
index 000000000..132bbc8ce
--- /dev/null
+++ b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <service/crypto/client/cpp/packed-c/packedc_crypto_client.h>
+#include <service/crypto/test/service/crypto_service_scenarios.h>
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <service_locator.h>
+#include <CppUTest/TestHarness.h>
+
+/*
+ * Service-level tests that use the Protobuf access protocol serialization
+ */
+TEST_GROUP(CryptoServicePackedcTests)
+{
+ void setup()
+ {
+ struct rpc_caller *caller;
+ int status;
+
+ m_rpc_session_handle = NULL;
+ m_crypto_service_context = NULL;
+ m_scenarios = NULL;
+
+ service_locator_init();
+
+ m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+ CHECK_TRUE(m_crypto_service_context);
+
+ m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
+ CHECK_TRUE(m_rpc_session_handle);
+
+ m_scenarios = new crypto_service_scenarios(new packedc_crypto_client(caller));
+ }
+
+ void teardown()
+ {
+ delete m_scenarios;
+ m_scenarios = NULL;
+
+ service_context_close(m_crypto_service_context, m_rpc_session_handle);
+ m_rpc_session_handle = NULL;
+
+ service_context_relinquish(m_crypto_service_context);
+ m_crypto_service_context = NULL;
+ }
+
+ rpc_session_handle m_rpc_session_handle;
+ struct service_context *m_crypto_service_context;
+ crypto_service_scenarios *m_scenarios;
+};
+
+TEST(CryptoServicePackedcTests, generateVolatileKeys)
+{
+ m_scenarios->generateVolatileKeys();
+}
+
+TEST(CryptoServicePackedcTests, generatePersistentKeys)
+{
+ m_scenarios->generatePersistentKeys();
+}
+
+TEST(CryptoServicePackedcTests, exportPublicKey)
+{
+ m_scenarios->exportPublicKey();
+}
+
+TEST(CryptoServicePackedcTests, exportAndImportKeyPair)
+{
+ m_scenarios->exportAndImportKeyPair();
+}
+
+TEST(CryptoServicePackedcTests, signAndVerifyHash)
+{
+ m_scenarios->signAndVerifyHash();
+}
+
+TEST(CryptoServicePackedcTests, asymEncryptDecrypt)
+{
+ m_scenarios->asymEncryptDecrypt();
+}
+
+TEST(CryptoServicePackedcTests, generateRandomNumbers)
+{
+ m_scenarios->generateRandomNumbers();
+}
diff --git a/components/service/crypto/test/service/protobuf/component.cmake b/components/service/crypto/test/service/protobuf/component.cmake
new file mode 100644
index 000000000..8d12774ae
--- /dev/null
+++ b/components/service/crypto/test/service/protobuf/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-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_service_protobuf_tests.cpp"
+ )
+
diff --git a/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp b/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp
new file mode 100644
index 000000000..3d728e22a
--- /dev/null
+++ b/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <service/crypto/client/cpp/protobuf/protobuf_crypto_client.h>
+#include <service/crypto/test/service/crypto_service_scenarios.h>
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <service_locator.h>
+#include <CppUTest/TestHarness.h>
+
+/*
+ * Service-level tests that use the Protobuf access protocol serialization
+ */
+TEST_GROUP(CryptoServiceProtobufTests)
+{
+ void setup()
+ {
+ struct rpc_caller *caller;
+ int status;
+
+ m_rpc_session_handle = NULL;
+ m_crypto_service_context = NULL;
+ m_scenarios = NULL;
+
+ service_locator_init();
+
+ m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status);
+ CHECK_TRUE(m_crypto_service_context);
+
+ m_rpc_session_handle = service_context_open(m_crypto_service_context, TS_RPC_ENCODING_PROTOBUF, &caller);
+ CHECK_TRUE(m_rpc_session_handle);
+
+ m_scenarios = new crypto_service_scenarios(new protobuf_crypto_client(caller));
+ }
+
+ void teardown()
+ {
+ delete m_scenarios;
+ m_scenarios = NULL;
+
+ service_context_close(m_crypto_service_context, m_rpc_session_handle);
+ m_rpc_session_handle = NULL;
+
+ service_context_relinquish(m_crypto_service_context);
+ m_crypto_service_context = NULL;
+ }
+
+ rpc_session_handle m_rpc_session_handle;
+ struct service_context *m_crypto_service_context;
+ crypto_service_scenarios *m_scenarios;
+};
+
+TEST(CryptoServiceProtobufTests, generateVolatileKeys)
+{
+ m_scenarios->generateVolatileKeys();
+}
+
+TEST(CryptoServiceProtobufTests, generatePersistentKeys)
+{
+ m_scenarios->generatePersistentKeys();
+}
+
+TEST(CryptoServiceProtobufTests, exportPublicKey)
+{
+ m_scenarios->exportPublicKey();
+}
+
+TEST(CryptoServiceProtobufTests, exportAndImportKeyPair)
+{
+ m_scenarios->exportAndImportKeyPair();
+}
+
+TEST(CryptoServiceProtobufTests, signAndVerifyHash)
+{
+ m_scenarios->signAndVerifyHash();
+}
+
+TEST(CryptoServiceProtobufTests, asymEncryptDecrypt)
+{
+ m_scenarios->asymEncryptDecrypt();
+}
+
+TEST(CryptoServiceProtobufTests, generateRandomNumbers)
+{
+ m_scenarios->generateRandomNumbers();
+}
diff --git a/components/service/locator/standalone/services/crypto/crypto_service_context.cpp b/components/service/locator/standalone/services/crypto/crypto_service_context.cpp
index 054581797..bff9ac101 100644
--- a/components/service/locator/standalone/services/crypto/crypto_service_context.cpp
+++ b/components/service/locator/standalone/services/crypto/crypto_service_context.cpp
@@ -6,6 +6,7 @@
#include "crypto_service_context.h"
#include <service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h>
+#include <service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.h>
crypto_service_context::crypto_service_context(const char *sn) :
standalone_service_context(sn),
@@ -30,6 +31,9 @@ void crypto_service_context::do_init()
mbed_crypto_provider_register_serializer(&m_crypto_provider,
TS_RPC_ENCODING_PROTOBUF, pb_crypto_provider_serializer_instance());
+ mbed_crypto_provider_register_serializer(&m_crypto_provider,
+ TS_RPC_ENCODING_PACKED_C, packedc_crypto_provider_serializer_instance());
+
standalone_service_context::set_rpc_interface(crypto_ep);
}
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index 3af6d021f..deadf114d 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -18,8 +18,11 @@ add_components(
"components/app/ts-demo/test"
"components/common/uuid"
"components/common/uuid/test"
+ "components/common/tlv"
+ "components/common/tlv/test"
"components/rpc/common/caller"
"components/rpc/common/interface"
+ "components/rpc/common/test/protocol"
"components/rpc/direct"
"components/rpc/dummy"
"components/service/common"
@@ -32,13 +35,19 @@ add_components(
"components/service/locator/standalone"
"components/service/locator/standalone/services/crypto"
"components/service/crypto/client/cpp"
+ "components/service/crypto/client/cpp/protobuf"
+ "components/service/crypto/client/cpp/packed-c"
"components/service/crypto/client/test"
"components/service/crypto/client/test/standalone"
"components/service/crypto/provider/mbedcrypto"
"components/service/crypto/provider/mbedcrypto/entropy_source/mock"
"components/service/crypto/provider/serializer/protobuf"
+ "components/service/crypto/provider/serializer/packed-c"
"components/service/crypto/test/unit"
"components/service/crypto/test/service"
+ "components/service/crypto/test/service/protobuf"
+ "components/service/crypto/test/service/packed-c"
+ "components/service/crypto/test/protocol"
"components/service/secure_storage/client/psa"
"components/service/secure_storage/provider/mock_store"
"components/service/secure_storage/provider/secure_flash_store"
@@ -47,7 +56,6 @@ add_components(
"components/service/secure_storage/test"
"protocols/rpc/common/protobuf"
"protocols/rpc/common/packed-c"
- "protocols/rpc/common/packed-c/test"
"protocols/service/crypto/packed-c"
"protocols/service/crypto/protobuf"
"protocols/service/secure_storage/packed-c"
diff --git a/deployments/crypto/opteesp/CMakeLists.txt b/deployments/crypto/opteesp/CMakeLists.txt
index fec7b6946..38bc42d2a 100644
--- a/deployments/crypto/opteesp/CMakeLists.txt
+++ b/deployments/crypto/opteesp/CMakeLists.txt
@@ -31,6 +31,7 @@ target_link_libraries(crypto-sp PRIVATE ${SP_DEV_KIT_LIBRARIES})
add_components(TARGET "crypto-sp"
BASE_DIR ${TS_ROOT}
COMPONENTS
+ "components/common/tlv"
"components/messaging/ffa/libsp"
"components/rpc/ffarpc/endpoint"
"components/rpc/ffarpc/caller/sp"
@@ -43,6 +44,7 @@ add_components(TARGET "crypto-sp"
"components/service/crypto/provider/mbedcrypto"
"components/service/crypto/provider/mbedcrypto/entropy_source/mock"
"components/service/crypto/provider/serializer/protobuf"
+ "components/service/crypto/provider/serializer/packed-c"
"components/service/secure_storage/client/psa"
"protocols/rpc/common/packed-c"
"protocols/service/secure_storage/packed-c"
diff --git a/deployments/crypto/opteesp/crypto_sp.c b/deployments/crypto/opteesp/crypto_sp.c
index 5756d1bdf..ea60d1c70 100644
--- a/deployments/crypto/opteesp/crypto_sp.c
+++ b/deployments/crypto/opteesp/crypto_sp.c
@@ -9,6 +9,7 @@
#include <service/secure_storage/client/psa/its/its_client.h>
#include <service/crypto/provider/mbedcrypto/crypto_provider.h>
#include <service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h>
+#include <service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.h>
#include <protocols/rpc/common/packed-c/status.h>
#include <ffa_api.h>
#include <sp_api.h>
@@ -59,9 +60,13 @@ void __noreturn sp_main(struct ffa_init_info *init_info)
/* Initialize the crypto service */
crypto_iface = mbed_crypto_provider_init(&crypto_provider, storage_caller);
- mbed_crypto_provider_register_serializer(&crypto_provider,
+
+ mbed_crypto_provider_register_serializer(&crypto_provider,
TS_RPC_ENCODING_PROTOBUF, pb_crypto_provider_serializer_instance());
+ mbed_crypto_provider_register_serializer(&crypto_provider,
+ TS_RPC_ENCODING_PACKED_C, packedc_crypto_provider_serializer_instance());
+
ffa_call_ep_init(&ffarpc_call_ep, crypto_iface);
/* End of boot phase */
diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt
index 8de05fde9..9c798ad3e 100644
--- a/deployments/libts/linux-pc/CMakeLists.txt
+++ b/deployments/libts/linux-pc/CMakeLists.txt
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -30,6 +30,7 @@ add_components(
BASE_DIR ${TS_ROOT}
COMPONENTS
"components/rpc/direct"
+ "components/common/tlv"
"components/service/common"
"components/service/common/serializer/protobuf"
"components/service/common/provider"
@@ -38,6 +39,7 @@ add_components(
"components/service/crypto/provider/mbedcrypto"
"components/service/crypto/provider/mbedcrypto/entropy_source/mock"
"components/service/crypto/provider/serializer/protobuf"
+ "components/service/crypto/provider/serializer/packed-c"
"components/service/secure_storage/client/psa"
"components/service/secure_storage/provider/secure_flash_store"
"components/service/secure_storage/provider/secure_flash_store/flash_fs"
@@ -82,10 +84,16 @@ add_components(
BASE_DIR ${TS_ROOT}
COMPONENTS
"components/app/test-runner"
+ "components/common/tlv"
"components/service/crypto/test/service"
+ "components/service/crypto/test/service/protobuf"
+ "components/service/crypto/test/service/packed-c"
"components/service/crypto/client/cpp"
+ "components/service/crypto/client/cpp/protobuf"
+ "components/service/crypto/client/cpp/packed-c"
"components/service/common/serializer/protobuf"
"protocols/service/crypto/protobuf"
+ "protocols/service/crypto/packed-c"
)
#-------------------------------------------------------------------------------
diff --git a/deployments/ts-demo/ts-demo.cmake b/deployments/ts-demo/ts-demo.cmake
index d6f10674a..828a31e8f 100644
--- a/deployments/ts-demo/ts-demo.cmake
+++ b/deployments/ts-demo/ts-demo.cmake
@@ -36,9 +36,10 @@ add_components(
BASE_DIR ${TS_ROOT}
COMPONENTS
"components/app/ts-demo"
+ "components/common/tlv"
"components/service/crypto/client/cpp"
- "components/service/common/serializer/protobuf"
- "protocols/service/crypto/protobuf"
+ "components/service/crypto/client/cpp/packed-c"
+ "protocols/service/crypto/packed-c"
)
#-------------------------------------------------------------------------------
@@ -46,11 +47,6 @@ add_components(
#
#-------------------------------------------------------------------------------
-# Nanopb
-include(${TS_ROOT}/external/nanopb/nanopb.cmake)
-target_link_libraries(ts-demo PRIVATE nanopb::protobuf-nanopb-static)
-protobuf_generate_all(TGT "ts-demo" NAMESPACE "protobuf" BASE_DIR "${TS_ROOT}/protocols")
-
# Mbedcrypto
include(${TS_ROOT}/external/mbed-crypto/mbedcrypto.cmake)
target_link_libraries(ts-demo PRIVATE mbedcrypto)
diff --git a/deployments/ts-demo/ts-demo.cpp b/deployments/ts-demo/ts-demo.cpp
index eaa8b5254..2f607e68f 100644
--- a/deployments/ts-demo/ts-demo.cpp
+++ b/deployments/ts-demo/ts-demo.cpp
@@ -3,7 +3,7 @@
* Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*/
-#include <service/crypto/client/cpp/crypto_client.h>
+#include <service/crypto/client/cpp/packed-c/packedc_crypto_client.h>
#include <protocols/rpc/common/packed-c/encoding.h>
#include <app/ts-demo/ts-demo.h>
#include <service_locator.h>
@@ -25,11 +25,11 @@ int main(int argc, char *argv[]) {
struct rpc_caller *caller;
rpc_session_handle rpc_session_handle;
- rpc_session_handle = service_context_open(crypto_service_context, TS_RPC_ENCODING_PROTOBUF, &caller);
+ rpc_session_handle = service_context_open(crypto_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
if (rpc_session_handle) {
- crypto_client crypto_client(caller);
+ packedc_crypto_client crypto_client(caller);
status = run_ts_demo(&crypto_client, true);
diff --git a/deployments/ts-service-test/ts-service-test.cmake b/deployments/ts-service-test/ts-service-test.cmake
index 5630a9940..4bd8c717e 100644
--- a/deployments/ts-service-test/ts-service-test.cmake
+++ b/deployments/ts-service-test/ts-service-test.cmake
@@ -27,10 +27,16 @@ add_components(
TARGET "ts-service-test"
BASE_DIR ${TS_ROOT}
COMPONENTS
+ "components/common/tlv"
"components/service/crypto/test/service"
+ "components/service/crypto/test/service/protobuf"
+ "components/service/crypto/test/service/packed-c"
"components/service/crypto/client/cpp"
+ "components/service/crypto/client/cpp/protobuf"
+ "components/service/crypto/client/cpp/packed-c"
"components/service/common/serializer/protobuf"
"protocols/service/crypto/protobuf"
+ "protocols/service/crypto/packed-c"
)
#-------------------------------------------------------------------------------
diff --git a/protocols/rpc/common/packed-c/test/check_rpc_status_packed-c.cpp b/protocols/rpc/common/packed-c/test/check_rpc_status_packed-c.cpp
deleted file mode 100644
index c377957c0..000000000
--- a/protocols/rpc/common/packed-c/test/check_rpc_status_packed-c.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#include <rpc/common/protobuf/status.pb.h>
-#include <protocols/rpc/common/packed-c/status.h>
-#include <CppUTest/TestHarness.h>
-
-/*
- * Check alignment of packed-c protocol values.
- */
-TEST_GROUP(PackedCrpcCommonProtocolChecks) {
-
-};
-
-TEST(PackedCrpcCommonProtocolChecks, checkRpcStatusCodes) {
-
- /*
- * Check alignment between packed-c and protobuf rpc status codes
- */
- CHECK_EQUAL(TS_RPC_CALL_ACCEPTED, ts_rpc_Status_CALL_ACCEPTED);
- CHECK_EQUAL(TS_RPC_ERROR_EP_DOES_NOT_EXIT, ts_rpc_Status_ERROR_EP_DOES_NOT_EXIT);
- CHECK_EQUAL(TS_RPC_ERROR_INVALID_OPCODE, ts_rpc_Status_ERROR_INVALID_OPCODE);
- CHECK_EQUAL(TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED, ts_rpc_Status_ERROR_SERIALIZATION_NOT_SUPPORTED);
- CHECK_EQUAL(TS_RPC_ERROR_INVALID_REQ_BODY, ts_rpc_Status_ERROR_INVALID_REQ_BODY);
- CHECK_EQUAL(TS_RPC_ERROR_INVALID_RESP_BODY, ts_rpc_Status_ERROR_INVALID_RESP_BODY);
- CHECK_EQUAL(TS_RPC_ERROR_RESOURCE_FAILURE, ts_rpc_Status_ERROR_RESOURCE_FAILURE);
- CHECK_EQUAL(TS_RPC_ERROR_NOT_READY, ts_rpc_Status_ERROR_NOT_READY);
- CHECK_EQUAL(TS_RPC_ERROR_INVALID_TRANSACTION, ts_rpc_Status_ERROR_INVALID_TRANSACTION);
- CHECK_EQUAL(TS_RPC_ERROR_INTERNAL, ts_rpc_Status_ERROR_INTERNAL);
- CHECK_EQUAL(TS_RPC_ERROR_INVALID_PARAMETER, ts_rpc_Status_ERROR_INVALID_PARAMETER);
-} \ No newline at end of file
diff --git a/protocols/service/crypto/packed-c/asymmetric_decrypt.h b/protocols/service/crypto/packed-c/asymmetric_decrypt.h
new file mode 100644
index 000000000..04c2c6ada
--- /dev/null
+++ b/protocols/service/crypto/packed-c/asymmetric_decrypt.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_ASYMMETRIC_DECRYPT_H
+#define TS_CRYPTO_ASYMMETRIC_DECRYPT_H
+
+#include <stdint.h>
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_asymmetric_decrypt_in
+{
+ uint32_t handle;
+ uint32_t alg;
+};
+
+/* Variable length input parameter tags */
+enum
+{
+ TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_CIPHERTEXT = 1,
+ TS_CRYPTO_ASYMMETRIC_DECRYPT_IN_TAG_SALT = 2
+};
+
+/* Variable length output parameter tags */
+enum
+{
+ TS_CRYPTO_ASYMMETRIC_DECRYPT_OUT_TAG_PLAINTEXT = 1
+};
+
+#endif /* TS_CRYPTO_ASYMMETRIC_DECRYPT_H */ \ No newline at end of file
diff --git a/protocols/service/crypto/packed-c/asymmetric_encrypt.h b/protocols/service/crypto/packed-c/asymmetric_encrypt.h
new file mode 100644
index 000000000..9854a9549
--- /dev/null
+++ b/protocols/service/crypto/packed-c/asymmetric_encrypt.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_ASYMMETRIC_ENCRYPT_H
+#define TS_CRYPTO_ASYMMETRIC_ENCRYPT_H
+
+#include <stdint.h>
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_asymmetric_encrypt_in
+{
+ uint32_t handle;
+ uint32_t alg;
+};
+
+/* Variable length input parameter tags */
+enum
+{
+ TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_PLAINTEXT = 1,
+ TS_CRYPTO_ASYMMETRIC_ENCRYPT_IN_TAG_SALT = 2
+};
+
+/* Variable length output parameter tags */
+enum
+{
+ TS_CRYPTO_ASYMMETRIC_ENCRYPT_OUT_TAG_CIPHERTEXT = 1
+};
+
+#endif /* TS_CRYPTO_ASYMMETRIC_ENCRYPT_H */
diff --git a/protocols/service/crypto/packed-c/close_key.h b/protocols/service/crypto/packed-c/close_key.h
new file mode 100644
index 000000000..db66c18a2
--- /dev/null
+++ b/protocols/service/crypto/packed-c/close_key.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_CLOSE_KEY_H
+#define TS_CRYPTO_CLOSE_KEY_H
+
+#include <stdint.h>
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_close_key_in
+{
+ uint32_t handle;
+};
+
+#endif /* TS_CRYPTO_CLOSE_KEY_H */ \ No newline at end of file
diff --git a/protocols/service/crypto/packed-c/component.cmake b/protocols/service/crypto/packed-c/component.cmake
index 041f7d549..a1b384236 100644
--- a/protocols/service/crypto/packed-c/component.cmake
+++ b/protocols/service/crypto/packed-c/component.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
diff --git a/protocols/service/crypto/packed-c/destroy_key.h b/protocols/service/crypto/packed-c/destroy_key.h
new file mode 100644
index 000000000..c14d9ea17
--- /dev/null
+++ b/protocols/service/crypto/packed-c/destroy_key.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_DESTROY_KEY_H
+#define TS_CRYPTO_DESTROY_KEY_H
+
+#include <stdint.h>
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_destroy_key_in
+{
+ uint32_t handle;
+};
+
+#endif /* TS_CRYPTO_DESTROY_KEY_H */
diff --git a/protocols/service/crypto/packed-c/export_key.h b/protocols/service/crypto/packed-c/export_key.h
new file mode 100644
index 000000000..3cc0a3ca1
--- /dev/null
+++ b/protocols/service/crypto/packed-c/export_key.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_EXPORT_KEY_H
+#define TS_CRYPTO_EXPORT_KEY_H
+
+#include <stdint.h>
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_export_key_in
+{
+ uint32_t handle;
+};
+
+/* Variable length output parameter tags */
+enum
+{
+ TS_CRYPTO_EXPORT_KEY_OUT_TAG_DATA = 1
+};
+
+#endif /* TS_CRYPTO_EXPORT_KEY_H */ \ No newline at end of file
diff --git a/protocols/service/crypto/packed-c/export_public_key.h b/protocols/service/crypto/packed-c/export_public_key.h
new file mode 100644
index 000000000..0644e2236
--- /dev/null
+++ b/protocols/service/crypto/packed-c/export_public_key.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_EXPORT_PUBLIC_KEY_H
+#define TS_CRYPTO_EXPORT_PUBLIC_KEY_H
+
+#include <stdint.h>
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_export_public_key_in
+{
+ uint32_t handle;
+};
+
+/* Variable length output parameter tags */
+enum
+{
+ TS_CRYPTO_EXPORT_PUBLIC_KEY_OUT_TAG_DATA = 1
+};
+
+#endif /* TS_CRYPTO_EXPORT_PUBLIC_KEY_H */ \ No newline at end of file
diff --git a/protocols/service/crypto/packed-c/generate_key.h b/protocols/service/crypto/packed-c/generate_key.h
new file mode 100644
index 000000000..828cf69a5
--- /dev/null
+++ b/protocols/service/crypto/packed-c/generate_key.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_GENERATE_KEY_H
+#define TS_CRYPTO_GENERATE_KEY_H
+
+#include <stdint.h>
+#include "key_attributes.h"
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_generate_key_in
+{
+ struct ts_crypto_key_attributes attributes;
+};
+
+/* Mandatory fixed sized output parameters */
+struct __attribute__ ((__packed__)) ts_crypto_generate_key_out
+{
+ uint32_t handle;
+};
+
+#endif /* TS_CRYPTO_GENERATE_KEY_H */
diff --git a/protocols/service/crypto/packed-c/generate_random.h b/protocols/service/crypto/packed-c/generate_random.h
new file mode 100644
index 000000000..6e8ccadef
--- /dev/null
+++ b/protocols/service/crypto/packed-c/generate_random.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_GENERATE_RANDOM_H
+#define TS_CRYPTO_GENERATE_RANDOM_H
+
+#include <stdint.h>
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_generate_random_in
+{
+ uint32_t size;
+};
+
+/* Variable length output parameter tags */
+enum
+{
+ TS_CRYPTO_GENERATE_RANDOM_OUT_TAG_RANDOM_BYTES = 1
+};
+
+#endif /* TS_CRYPTO_GENERATE_RANDOM_H */ \ No newline at end of file
diff --git a/protocols/service/crypto/packed-c/import_key.h b/protocols/service/crypto/packed-c/import_key.h
new file mode 100644
index 000000000..810151efe
--- /dev/null
+++ b/protocols/service/crypto/packed-c/import_key.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_IMPORT_KEY_H
+#define TS_CRYPTO_IMPORT_KEY_H
+
+#include <stdint.h>
+#include "key_attributes.h"
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_import_key_in
+{
+ struct ts_crypto_key_attributes attributes;
+};
+
+/* Variable length input parameter tags */
+enum
+{
+ TS_CRYPTO_IMPORT_KEY_IN_TAG_DATA = 1,
+};
+
+/* Mandatory fixed sized output parameters */
+struct __attribute__ ((__packed__)) ts_crypto_import_key_out
+{
+ uint32_t handle;
+};
+
+#endif /* TS_CRYPTO_IMPORT_KEY_H */
diff --git a/protocols/service/crypto/packed-c/key_attributes.h b/protocols/service/crypto/packed-c/key_attributes.h
new file mode 100644
index 000000000..881a8f54a
--- /dev/null
+++ b/protocols/service/crypto/packed-c/key_attributes.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_KEY_ATTRIBUTES_H
+#define TS_CRYPTO_KEY_ATTRIBUTES_H
+
+#include <stdint.h>
+
+/* Key types */
+#define TS_CRYPTO_KEY_TYPE_NONE (0x0000)
+#define TS_CRYPTO_KEY_TYPE_RAW_DATA (0x1001)
+#define TS_CRYPTO_KEY_TYPE_HMAC (0x1100)
+#define TS_CRYPTO_KEY_TYPE_DERIVE (0x1200)
+#define TS_CRYPTO_KEY_TYPE_AES (0x2400)
+#define TS_CRYPTO_KEY_TYPE_DES (0x2301)
+#define TS_CRYPTO_KEY_TYPE_CAMELLIA (0x2403)
+#define TS_CRYPTO_KEY_TYPE_ARC4 (0x2002)
+#define TS_CRYPTO_KEY_TYPE_CHACHA20 (0x2004)
+#define TS_CRYPTO_KEY_TYPE_RSA_PUBLIC_KEY (0x4001)
+#define TS_CRYPTO_KEY_TYPE_RSA_KEY_PAIR (0x7001)
+#define TS_CRYPTO_KEY_TYPE_ECC_PUBLIC_KEY_BASE (0x4100)
+#define TS_CRYPTO_KEY_TYPE_ECC_KEY_PAIR_BASE (0x7100)
+#define TS_CRYPTO_KEY_TYPE_ECC_CURVE_MASK (0x00ff)
+#define TS_CRYPTO_KEY_TYPE_DH_PUBLIC_KEY_BASE (0x4200)
+#define TS_CRYPTO_KEY_TYPE_DH_KEY_PAIR_BASE (0x7200)
+#define TS_CRYPTO_KEY_TYPE_DH_GROUP_MASK (0x00ff)
+
+/* ECC curves for use with ECC Key types */
+#define TS_CRYPTO_ECC_CURVE_NONE (0x00)
+#define TS_CRYPTO_ECC_CURVE_SECP_K1 (0x17)
+#define TS_CRYPTO_ECC_CURVE_SECP_R1 (0x12)
+#define TS_CRYPTO_ECC_CURVE_SECP_R2 (0x1b)
+#define TS_CRYPTO_ECC_CURVE_SECT_K1 (0x27)
+#define TS_CRYPTO_ECC_CURVE_SECT_R1 (0x22)
+#define TS_CRYPTO_ECC_CURVE_SECT_R2 (0x2b)
+#define TS_CRYPTO_ECC_CURVE_BRAINPOOL_P_R1 (0x30)
+#define TS_CRYPTO_ECC_CURVE_MONTGOMERY (0x41)
+
+/* Diffie-Hellman groups for use with DH key types */
+#define TS_CRYPTO_DH_GROUP_NONE (0x00)
+#define TS_CRYPTO_DH_GROUP_RFC7919 (0x03)
+
+/* Crypto algorithms */
+#define TS_CRYPTO_ALG_NONE (0x00000000)
+#define TS_CRYPTO_ALG_HASH_MASK (0x000000ff)
+#define TS_CRYPTO_ALG_MD2 (0x01000001)
+#define TS_CRYPTO_ALG_MD4 (0x01000002)
+#define TS_CRYPTO_ALG_MD5 (0x01000003)
+#define TS_CRYPTO_ALG_RIPEMD160 (0x01000004)
+#define TS_CRYPTO_ALG_SHA_1 (0x01000005)
+#define TS_CRYPTO_ALG_SHA_224 (0x01000008)
+#define TS_CRYPTO_ALG_SHA_256 (0x01000009)
+#define TS_CRYPTO_ALG_SHA_384 (0x0100000a)
+#define TS_CRYPTO_ALG_SHA_512 (0x0100000b)
+#define TS_CRYPTO_ALG_SHA_512_224 (0x0100000c)
+#define TS_CRYPTO_ALG_SHA_512_256 (0x0100000d)
+#define TS_CRYPTO_ALG_SHA3_224 (0x01000010)
+#define TS_CRYPTO_ALG_SHA3_256 (0x01000011)
+#define TS_CRYPTO_ALG_SHA3_384 (0x01000012)
+#define TS_CRYPTO_ALG_SHA3_512 (0x01000013)
+#define TS_CRYPTO_ALG_CBC_MAC (0x02c00001)
+#define TS_CRYPTO_ALG_CMAC (0x02c00002)
+#define TS_CRYPTO_ALG_ARC4 (0x04800001)
+#define TS_CRYPTO_ALG_CHACHA20 (0x04800005)
+#define TS_CRYPTO_ALG_CTR (0x04c00001)
+#define TS_CRYPTO_ALG_CFB (0x04c00002)
+#define TS_CRYPTO_ALG_OFB (0x04c00003)
+#define TS_CRYPTO_ALG_XTS (0x044000ff)
+#define TS_CRYPTO_ALG_CBC_NO_PADDING (0x04600100)
+#define TS_CRYPTO_ALG_CBC_PKCS7 (0x04600101)
+#define TS_CRYPTO_ALG_AEAD_FROM_BLOCK_FLAG (0x00400000)
+#define TS_CRYPTO_ALG_CCM (0x06401001)
+#define TS_CRYPTO_ALG_GCM (0x06401002)
+#define TS_CRYPTO_ALG_CHACHA20_POLY1305 (0x06001005)
+#define TS_CRYPTO_ALG_RSA_PKCS1V15_SIGN_BASE (0x10020000)
+#define TS_CRYPTO_ALG_RSA_PSS_BASE (0x10030000)
+#define TS_CRYPTO_ALG_ECDSA_BASE (0x10060000)
+#define TS_CRYPTO_ALG_DETERMINISTIC_ECDSA_BASE (0x10070000)
+#define TS_CRYPTO_ALG_RSA_PKCS1V15_CRYPT (0x12020000)
+#define TS_CRYPTO_ALG_RSA_OAEP_BASE (0x12030000)
+#define TS_CRYPTO_ALG_HKDF_BASE (0x20000100)
+#define TS_CRYPTO_ALG_TLS12_PRF_BASE (0x20000200)
+#define TS_CRYPTO_ALG_TLS12_PSK_TO_MS_BASE (0x20000300)
+#define TS_CRYPTO_ALG_KEY_DERIVATION_MASK (0x0803ffff)
+#define TS_CRYPTO_ALG_KEY_AGREEMENT_MASK (0x10fc0000)
+#define TS_CRYPTO_ALG_FFDH (0x30100000)
+#define TS_CRYPTO_ALG_ECDH (0x30200000)
+
+/* Key lifetime */
+#define TS_CRYPTO_KEY_LIFETIME_VOLATILE (0x00000000)
+#define TS_CRYPTO_KEY_LIFETIME_PERSISTENT (0x00000001)
+
+/* Key usage constraints */
+#define TS_CRYPTO_KEY_USAGE_NONE (0x00000000)
+#define TS_CRYPTO_KEY_USAGE_EXPORT (0x00000001)
+#define TS_CRYPTO_KEY_USAGE_COPY (0x00000002)
+#define TS_CRYPTO_KEY_USAGE_ENCRYPT (0x00000100)
+#define TS_CRYPTO_KEY_USAGE_DECRYPT (0x00000200)
+#define TS_CRYPTO_KEY_USAGE_SIGN_HASH (0x00000400)
+#define TS_CRYPTO_KEY_USAGE_VERIFY_HASH (0x00000800)
+#define TS_CRYPTO_KEY_USAGE_DERIVE (0x00001000)
+
+/* Key policy to define what key can be used for */
+struct __attribute__ ((__packed__)) ts_crypto_key_policy
+{
+ uint32_t usage;
+ uint32_t alg;
+};
+
+/* Key attributes object */
+struct __attribute__ ((__packed__)) ts_crypto_key_attributes
+{
+ uint32_t type;
+ uint32_t key_bits;
+ uint32_t lifetime;
+ uint32_t id;
+ struct ts_crypto_key_policy policy;
+};
+
+#endif /* TS_CRYPTO_KEY_ATTRIBUTES_H */ \ No newline at end of file
diff --git a/protocols/service/crypto/packed-c/opcodes.h b/protocols/service/crypto/packed-c/opcodes.h
index 40f8ab3ee..eee6ed735 100644
--- a/protocols/service/crypto/packed-c/opcodes.h
+++ b/protocols/service/crypto/packed-c/opcodes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/protocols/service/crypto/packed-c/open_key.h b/protocols/service/crypto/packed-c/open_key.h
new file mode 100644
index 000000000..68252adcc
--- /dev/null
+++ b/protocols/service/crypto/packed-c/open_key.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_OPEN_KEY_H
+#define TS_CRYPTO_OPEN_KEY_H
+
+#include <stdint.h>
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_open_key_in
+{
+ uint32_t id;
+};
+
+/* Mandatory fixed sized output parameters */
+struct __attribute__ ((__packed__)) ts_crypto_open_key_out
+{
+ uint32_t handle;
+};
+
+#endif /* TS_CRYPTO_OPEN_KEY_H */ \ No newline at end of file
diff --git a/protocols/service/crypto/packed-c/sign_hash.h b/protocols/service/crypto/packed-c/sign_hash.h
new file mode 100644
index 000000000..762125c1e
--- /dev/null
+++ b/protocols/service/crypto/packed-c/sign_hash.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_SIGN_HASH_H
+#define TS_CRYPTO_SIGN_HASH_H
+
+#include <stdint.h>
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_sign_hash_in
+{
+ uint32_t handle;
+ uint32_t alg;
+};
+
+/* Variable length input parameter tags */
+enum
+{
+ TS_CRYPTO_SIGN_HASH_IN_TAG_HASH = 1,
+};
+
+/* Variable length output parameter tags */
+enum
+{
+ TS_CRYPTO_SIGN_HASH_OUT_TAG_SIGNATURE = 1
+};
+
+#endif /* TS_CRYPTO_SIGN_HASH_H */ \ No newline at end of file
diff --git a/protocols/service/crypto/packed-c/verify_hash.h b/protocols/service/crypto/packed-c/verify_hash.h
new file mode 100644
index 000000000..fc3bbcab4
--- /dev/null
+++ b/protocols/service/crypto/packed-c/verify_hash.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_VERIFY_HASH_H
+#define TS_CRYPTO_VERIFY_HASH_H
+
+#include <stdint.h>
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_verify_hash_in
+{
+ uint32_t handle;
+ uint32_t alg;
+};
+
+/* Variable length input parameter tags */
+enum
+{
+ TS_CRYPTO_VERIFY_HASH_IN_TAG_HASH = 1,
+ TS_CRYPTO_VERIFY_HASH_IN_TAG_SIGNATURE = 2
+};
+
+#endif /* TS_CRYPTO_VERIFY_HASH_H */ \ No newline at end of file
diff --git a/protocols/service/crypto/protobuf/key_attributes.proto b/protocols/service/crypto/protobuf/key_attributes.proto
index 7e504f643..bae948b5c 100644
--- a/protocols/service/crypto/protobuf/key_attributes.proto
+++ b/protocols/service/crypto/protobuf/key_attributes.proto
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
syntax = "proto3";
@@ -19,7 +19,7 @@ enum KeyType {
KEY_TYPE_CAMELLIA = 0x2403;
KEY_TYPE_ARC4 = 0x2002;
KEY_TYPE_CHACHA20 = 0x2004;
- KEY_TYPE_PUBLIC_KEY = 0x4001;
+ KEY_TYPE_RSA_PUBLIC_KEY = 0x4001;
KEY_TYPE_RSA_KEY_PAIR = 0x7001;
KEY_TYPE_ECC_PUBLIC_KEY_BASE = 0x4100;
KEY_TYPE_ECC_KEY_PAIR_BASE = 0x7100;