Add crypto support for MAC operations
Adds a sub-provider for extending the crypto provider to
support MAC operations.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I6d33ff963316c91730b01590b50edc5e167ebaa1
diff --git a/components/service/crypto/client/psa/psa_mac.c b/components/service/crypto/client/psa/psa_mac.c
index b8f29a2..8228fe6 100644
--- a/components/service/crypto/client/psa/psa_mac.c
+++ b/components/service/crypto/client/psa/psa_mac.c
@@ -10,27 +10,122 @@
#include "psa_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/mac.h>
#include <common/tlv/tlv.h>
+static psa_status_t common_mac_setup(psa_mac_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg,
+ uint32_t opcode)
+{
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_mac_setup_in req_msg;
+ size_t req_len = sizeof(struct ts_crypto_mac_setup_in);
+
+ req_msg.key_id = key;
+ req_msg.alg = alg;
+
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_begin(psa_crypto_client_instance.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);
+
+ psa_crypto_client_instance.rpc_status =
+ rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
+ opcode, &opstatus, &resp_buf, &resp_len);
+
+ if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ psa_status = opstatus;
+
+ if (psa_status == PSA_SUCCESS) {
+
+ if (resp_len >= sizeof(struct ts_crypto_mac_setup_out)) {
+
+ struct ts_crypto_mac_setup_out resp_msg;
+ memcpy(&resp_msg, resp_buf, sizeof(struct ts_crypto_mac_setup_out));
+ operation->handle = resp_msg.op_handle;
+ }
+ else {
+ /* Failed to decode response message */
+ psa_status = PSA_ERROR_GENERIC_ERROR;
+ }
+ }
+ }
+
+ rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
+ }
+
+ return psa_status;
+}
+
psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
psa_key_id_t key,
psa_algorithm_t alg)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ return common_mac_setup(operation, key, alg, TS_CRYPTO_OPCODE_MAC_SIGN_SETUP);
}
psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
psa_key_id_t key,
psa_algorithm_t alg)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ return common_mac_setup(operation, key, alg, TS_CRYPTO_OPCODE_MAC_VERIFY_SETUP);
}
psa_status_t psa_mac_update(psa_mac_operation_t *operation,
const uint8_t *input,
size_t input_length)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_mac_update_in req_msg;
+ size_t req_fixed_len = sizeof(struct ts_crypto_mac_update_in);
+ size_t req_len = req_fixed_len;
+
+ req_msg.op_handle = operation->handle;
+
+ /* Mandatory input data parameter */
+ struct tlv_record data_record;
+ data_record.tag = TS_CRYPTO_MAC_UPDATE_IN_TAG_DATA;
+ data_record.length = input_length;
+ data_record.value = input;
+ req_len += tlv_required_space(data_record.length);
+
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+ struct tlv_iterator req_iter;
+
+ memcpy(req_buf, &req_msg, req_fixed_len);
+
+ tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
+ tlv_encode(&req_iter, &data_record);
+
+ psa_crypto_client_instance.rpc_status =
+ rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
+ TS_CRYPTO_OPCODE_MAC_UPDATE, &opstatus, &resp_buf, &resp_len);
+
+ if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+
+ rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
+ }
+
+ return psa_status;
}
psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
@@ -38,19 +133,146 @@
size_t mac_size,
size_t *mac_length)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_mac_sign_finish_in req_msg;
+ size_t req_fixed_len = sizeof(struct ts_crypto_mac_sign_finish_in);
+ size_t req_len = req_fixed_len;
+
+ *mac_length = 0;
+ req_msg.op_handle = operation->handle;
+
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+
+ memcpy(req_buf, &req_msg, req_fixed_len);
+
+ psa_crypto_client_instance.rpc_status =
+ rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
+ TS_CRYPTO_OPCODE_MAC_SIGN_FINISH, &opstatus, &resp_buf, &resp_len);
+
+ if (psa_crypto_client_instance.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_MAC_SIGN_FINISH_OUT_TAG_MAC, &decoded_record)) {
+
+ if (decoded_record.length <= mac_size) {
+
+ memcpy(mac, decoded_record.value, decoded_record.length);
+ *mac_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(psa_crypto_client_instance.caller, call_handle);
+ }
+
+ return psa_status;
}
psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
const uint8_t *mac,
size_t mac_length)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_mac_verify_finish_in req_msg;
+ size_t req_fixed_len = sizeof(struct ts_crypto_mac_verify_finish_in);
+ size_t req_len = req_fixed_len;
+
+ req_msg.op_handle = operation->handle;
+
+ /* Mandatory input data parameter */
+ struct tlv_record data_record;
+ data_record.tag = TS_CRYPTO_MAC_VERIFY_FINISH_IN_TAG_MAC;
+ data_record.length = mac_length;
+ data_record.value = mac;
+ req_len += tlv_required_space(data_record.length);
+
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+ struct tlv_iterator req_iter;
+
+ memcpy(req_buf, &req_msg, req_fixed_len);
+
+ tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
+ tlv_encode(&req_iter, &data_record);
+
+ psa_crypto_client_instance.rpc_status =
+ rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
+ TS_CRYPTO_OPCODE_MAC_VERIFY_FINISH, &opstatus, &resp_buf, &resp_len);
+
+ if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+
+ rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
+ }
+
+ return psa_status;
}
psa_status_t psa_mac_abort(psa_mac_operation_t *operation)
{
- return PSA_ERROR_NOT_SUPPORTED;
+ psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+ struct ts_crypto_mac_abort_in req_msg;
+ size_t req_fixed_len = sizeof(struct ts_crypto_mac_abort_in);
+ size_t req_len = req_fixed_len;
+
+ req_msg.op_handle = operation->handle;
+
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
+
+ if (call_handle) {
+
+ uint8_t *resp_buf;
+ size_t resp_len;
+ int opstatus;
+
+ memcpy(req_buf, &req_msg, req_fixed_len);
+
+ psa_crypto_client_instance.rpc_status =
+ rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
+ TS_CRYPTO_OPCODE_MAC_ABORT, &opstatus, &resp_buf, &resp_len);
+
+ if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
+
+ rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
+ }
+
+ return psa_status;
}
psa_status_t psa_mac_verify(psa_key_id_t key,
diff --git a/components/service/crypto/factory/full/crypto_provider_factory.c b/components/service/crypto/factory/full/crypto_provider_factory.c
index af130aa..cc22b28 100644
--- a/components/service/crypto/factory/full/crypto_provider_factory.c
+++ b/components/service/crypto/factory/full/crypto_provider_factory.c
@@ -15,26 +15,31 @@
#include <service/crypto/provider/extension/cipher/serializer/packed-c/packedc_cipher_provider_serializer.h>
#include <service/crypto/provider/extension/key_derivation/key_derivation_provider.h>
#include <service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.h>
+#include <service/crypto/provider/extension/mac/mac_provider.h>
+#include <service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.h>
/**
- * A crypto provider factory that constucts a full-featured
- * crypto provider that is extended to support the full set of crypto
- * operations. This factory is only capable of constructing
- * a single service provider instance.
+ * A crypto provider factory that constucts a crypto provider
+ * that is extended to support the full set of crypto operations.
+ * This factory is only capable of constructing a single service
+ * provider instance.
*/
-static struct default_crypto_provider
+static struct full_crypto_provider
{
struct crypto_provider crypto_provider;
struct hash_provider hash_provider;
struct cipher_provider cipher_provider;
struct key_derivation_provider key_derivation_provider;
+ struct mac_provider mac_provider;
} instance;
struct crypto_provider *crypto_provider_factory_create(void)
{
- /* Initialize the base crypto provider -----------------------*/
+ /**
+ * Initialize the base crypto provider
+ */
crypto_provider_init(&instance.crypto_provider);
crypto_provider_register_serializer(&instance.crypto_provider,
@@ -42,7 +47,9 @@
crypto_provider_register_serializer(&instance.crypto_provider,
TS_RPC_ENCODING_PACKED_C, packedc_crypto_provider_serializer_instance());
- /* Extend with hash operations ---------------------------------*/
+ /**
+ * Extend with hash operations
+ */
hash_provider_init(&instance.hash_provider);
hash_provider_register_serializer(&instance.hash_provider,
@@ -51,7 +58,9 @@
crypto_provider_extend(&instance.crypto_provider,
&instance.hash_provider.base_provider);
- /* Extend with symmetric cipher operations --------------------*/
+ /**
+ * Extend with symmetric cipher operations
+ * */
cipher_provider_init(&instance.cipher_provider);
cipher_provider_register_serializer(&instance.cipher_provider,
@@ -60,7 +69,9 @@
crypto_provider_extend(&instance.crypto_provider,
&instance.cipher_provider.base_provider);
- /* Extend with key derivation operations ----------------------*/
+ /**
+ * Extend with key derivation operations
+ */
key_derivation_provider_init(&instance.key_derivation_provider);
key_derivation_provider_register_serializer(&instance.key_derivation_provider,
@@ -69,6 +80,17 @@
crypto_provider_extend(&instance.crypto_provider,
&instance.key_derivation_provider.base_provider);
+ /**
+ * Extend with mac operations
+ */
+ mac_provider_init(&instance.mac_provider);
+
+ mac_provider_register_serializer(&instance.mac_provider,
+ TS_RPC_ENCODING_PACKED_C, packedc_mac_provider_serializer_instance());
+
+ crypto_provider_extend(&instance.crypto_provider,
+ &instance.mac_provider.base_provider);
+
return &instance.crypto_provider;
}
@@ -83,4 +105,6 @@
crypto_provider_deinit(&instance.crypto_provider);
hash_provider_deinit(&instance.hash_provider);
cipher_provider_deinit(&instance.cipher_provider);
+ key_derivation_provider_deinit(&instance.key_derivation_provider);
+ mac_provider_deinit(&instance.mac_provider);
}
diff --git a/components/service/crypto/provider/extension/cipher/cipher_provider.h b/components/service/crypto/provider/extension/cipher/cipher_provider.h
index 939c333..df2a27d 100644
--- a/components/service/crypto/provider/extension/cipher/cipher_provider.h
+++ b/components/service/crypto/provider/extension/cipher/cipher_provider.h
@@ -18,7 +18,7 @@
#endif
/**
- * A service provider that can be used to add symmetric cipher operations to the base
+ * A service provider that can be used to add symmetric cipher operations to the core
* crypto provider.
*/
struct cipher_provider
diff --git a/components/service/crypto/provider/extension/hash/hash_provider.h b/components/service/crypto/provider/extension/hash/hash_provider.h
index 0c8e397..917d1f1 100644
--- a/components/service/crypto/provider/extension/hash/hash_provider.h
+++ b/components/service/crypto/provider/extension/hash/hash_provider.h
@@ -18,7 +18,7 @@
#endif
/**
- * A service provider that can be used to add hash operations to the base
+ * A service provider that can be used to add hash operations to the core
* crypto provider.
*/
struct hash_provider
diff --git a/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.h b/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.h
index 86e6b7b..1ac07f2 100644
--- a/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.h
+++ b/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.h
@@ -18,7 +18,7 @@
#endif
/**
- * A service provider that can be used to add key_derivation operations to the base
+ * A service provider that can be used to add key_derivation operations to the core
* crypto provider.
*/
struct key_derivation_provider
diff --git a/components/service/crypto/provider/extension/mac/component.cmake b/components/service/crypto/provider/extension/mac/component.cmake
new file mode 100644
index 0000000..a0f190c
--- /dev/null
+++ b/components/service/crypto/provider/extension/mac/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/mac_provider.c"
+ )
diff --git a/components/service/crypto/provider/extension/mac/mac_provider.c b/components/service/crypto/provider/extension/mac/mac_provider.c
new file mode 100644
index 0000000..96fe4cf
--- /dev/null
+++ b/components/service/crypto/provider/extension/mac/mac_provider.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <protocols/service/crypto/packed-c/opcodes.h>
+#include <service/crypto/provider/extension/mac/mac_provider.h>
+#include <protocols/rpc/common/packed-c/status.h>
+#include <psa/crypto.h>
+
+/* Service request handlers */
+static rpc_status_t mac_setup_handler(void *context, struct call_req* req);
+static rpc_status_t mac_update_handler(void *context, struct call_req* req);
+static rpc_status_t mac_sign_finish_handler(void *context, struct call_req* req);
+static rpc_status_t mac_verify_finish_handler(void *context, struct call_req* req);
+static rpc_status_t mac_abort_handler(void *context, struct call_req* req);
+
+/* Handler mapping table for service */
+static const struct service_handler handler_table[] = {
+ {TS_CRYPTO_OPCODE_MAC_SIGN_SETUP, mac_setup_handler},
+ {TS_CRYPTO_OPCODE_MAC_VERIFY_SETUP, mac_setup_handler},
+ {TS_CRYPTO_OPCODE_MAC_UPDATE, mac_update_handler},
+ {TS_CRYPTO_OPCODE_MAC_SIGN_FINISH, mac_sign_finish_handler},
+ {TS_CRYPTO_OPCODE_MAC_VERIFY_FINISH, mac_verify_finish_handler},
+ {TS_CRYPTO_OPCODE_MAC_ABORT, mac_abort_handler}
+};
+
+void mac_provider_init(struct mac_provider *context)
+{
+ crypto_context_pool_init(&context->context_pool);
+
+ for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
+ context->serializers[encoding] = NULL;
+
+ service_provider_init(&context->base_provider, context,
+ handler_table, sizeof(handler_table)/sizeof(struct service_handler));
+}
+
+void mac_provider_deinit(struct mac_provider *context)
+{
+ crypto_context_pool_deinit(&context->context_pool);
+}
+
+void mac_provider_register_serializer(struct mac_provider *context,
+ unsigned int encoding, const struct mac_provider_serializer *serializer)
+{
+ if (encoding < TS_RPC_ENCODING_LIMIT)
+ context->serializers[encoding] = serializer;
+}
+
+static const struct mac_provider_serializer* get_serializer(void *context,
+ const struct call_req *req)
+{
+ struct mac_provider *this_instance = (struct mac_provider*)context;
+ const struct mac_provider_serializer* serializer = NULL;
+ unsigned int encoding = call_req_get_encoding(req);
+
+ if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
+
+ return serializer;
+}
+
+static rpc_status_t mac_setup_handler(void *context, struct call_req* req)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct mac_provider_serializer *serializer = get_serializer(context, req);
+ struct mac_provider *this_instance = (struct mac_provider*)context;
+
+ psa_key_id_t key_id;
+ psa_algorithm_t alg;
+
+ if (serializer)
+ rpc_status = serializer->deserialize_mac_setup_req(req_buf, &key_id, &alg);
+
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ uint32_t op_handle;
+
+ struct crypto_context *crypto_context =
+ crypto_context_pool_alloc(&this_instance->context_pool,
+ CRYPTO_CONTEXT_OP_ID_MAC, call_req_get_caller_id(req),
+ &op_handle);
+
+ if (crypto_context) {
+
+ crypto_context->op.mac = psa_mac_operation_init();
+
+ psa_status_t psa_status =
+ (call_req_get_opcode(req) == TS_CRYPTO_OPCODE_MAC_SIGN_SETUP) ?
+ psa_mac_sign_setup(&crypto_context->op.mac, key_id, alg) :
+ psa_mac_verify_setup(&crypto_context->op.mac, key_id, alg);
+
+ if (psa_status == PSA_SUCCESS) {
+
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_mac_setup_resp(resp_buf, op_handle);
+ }
+
+ if ((psa_status != PSA_SUCCESS) || (rpc_status != TS_RPC_CALL_ACCEPTED)) {
+
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
+
+ call_req_set_opstatus(req, psa_status);
+ }
+ else {
+ /* Failed to allocate crypto context for transaction */
+ rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t mac_update_handler(void *context, struct call_req* req)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct mac_provider_serializer *serializer = get_serializer(context, req);
+ struct mac_provider *this_instance = (struct mac_provider*)context;
+
+ uint32_t op_handle;
+ const uint8_t *data;
+ size_t data_len;
+
+ if (serializer)
+ rpc_status = serializer->deserialize_mac_update_req(req_buf, &op_handle, &data, &data_len);
+
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ psa_status_t psa_status = PSA_ERROR_BAD_STATE;
+
+ struct crypto_context *crypto_context =
+ crypto_context_pool_find(&this_instance->context_pool,
+ CRYPTO_CONTEXT_OP_ID_MAC, call_req_get_caller_id(req),
+ op_handle);
+
+ if (crypto_context) {
+
+ psa_status = psa_mac_update(&crypto_context->op.mac, data, data_len);
+ }
+
+ call_req_set_opstatus(req, psa_status);
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t mac_sign_finish_handler(void *context, struct call_req* req)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct mac_provider_serializer *serializer = get_serializer(context, req);
+ struct mac_provider *this_instance = (struct mac_provider*)context;
+
+ uint32_t op_handle;
+
+ if (serializer)
+ rpc_status = serializer->deserialize_mac_sign_finish_req(req_buf, &op_handle);
+
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ psa_status_t psa_status = PSA_ERROR_BAD_STATE;
+
+ struct crypto_context *crypto_context =
+ crypto_context_pool_find(&this_instance->context_pool,
+ CRYPTO_CONTEXT_OP_ID_MAC, call_req_get_caller_id(req),
+ op_handle);
+
+ if (crypto_context) {
+
+ size_t mac_len;
+ uint8_t mac[PSA_MAC_MAX_SIZE];
+
+ psa_status = psa_mac_sign_finish(&crypto_context->op.mac, mac, sizeof(mac), &mac_len);
+
+ if (psa_status == PSA_SUCCESS) {
+
+ struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
+ rpc_status = serializer->serialize_mac_sign_finish_resp(resp_buf, mac, mac_len);
+ }
+
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
+
+ call_req_set_opstatus(req, psa_status);
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t mac_verify_finish_handler(void *context, struct call_req* req)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct mac_provider_serializer *serializer = get_serializer(context, req);
+ struct mac_provider *this_instance = (struct mac_provider*)context;
+
+ uint32_t op_handle;
+ const uint8_t *mac;
+ size_t mac_len;
+
+ if (serializer)
+ rpc_status = serializer->deserialize_mac_verify_finish_req(req_buf,
+ &op_handle, &mac, &mac_len);
+
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ psa_status_t psa_status = PSA_ERROR_BAD_STATE;
+
+ struct crypto_context *crypto_context =
+ crypto_context_pool_find(&this_instance->context_pool,
+ CRYPTO_CONTEXT_OP_ID_MAC, call_req_get_caller_id(req),
+ op_handle);
+
+ if (crypto_context) {
+
+ psa_status = psa_mac_verify_finish(&crypto_context->op.mac, mac, mac_len);
+
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
+
+ call_req_set_opstatus(req, psa_status);
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t mac_abort_handler(void *context, struct call_req* req)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
+ struct call_param_buf *req_buf = call_req_get_req_buf(req);
+ const struct mac_provider_serializer *serializer = get_serializer(context, req);
+ struct mac_provider *this_instance = (struct mac_provider*)context;
+
+ uint32_t op_handle;
+
+ if (serializer)
+ rpc_status = serializer->deserialize_mac_abort_req(req_buf, &op_handle);
+
+ if (rpc_status == TS_RPC_CALL_ACCEPTED) {
+
+ /* Return success if operation is no longer active and
+ * doesn't need aborting.
+ */
+ psa_status_t psa_status = PSA_SUCCESS;
+
+ struct crypto_context *crypto_context =
+ crypto_context_pool_find(&this_instance->context_pool,
+ CRYPTO_CONTEXT_OP_ID_MAC, call_req_get_caller_id(req),
+ op_handle);
+
+ if (crypto_context) {
+
+ psa_status = psa_mac_abort(&crypto_context->op.mac);
+ crypto_context_pool_free(&this_instance->context_pool, crypto_context);
+ }
+
+ call_req_set_opstatus(req, psa_status);
+ }
+
+ return rpc_status;
+}
diff --git a/components/service/crypto/provider/extension/mac/mac_provider.h b/components/service/crypto/provider/extension/mac/mac_provider.h
new file mode 100644
index 0000000..5e3cbe2
--- /dev/null
+++ b/components/service/crypto/provider/extension/mac/mac_provider.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MAC_PROVIDER_H
+#define MAC_PROVIDER_H
+
+#include <rpc/common/endpoint/rpc_interface.h>
+#include <service/common/provider/service_provider.h>
+#include <service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h>
+#include <service/crypto/provider/crypto_context_pool.h>
+#include <protocols/rpc/common/packed-c/encoding.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A service provider that can be used to add mac operations to the core
+ * crypto provider.
+ */
+struct mac_provider
+{
+ struct service_provider base_provider;
+ struct crypto_context_pool context_pool;
+ const struct mac_provider_serializer *serializers[TS_RPC_ENCODING_LIMIT];
+};
+
+/*
+ * Initializes an instance of the mac service provider.
+ */
+void mac_provider_init(struct mac_provider *context);
+
+/*
+ * When operation of the provider is no longer required, this function
+ * frees any resource used by the previously initialized provider instance.
+ */
+void mac_provider_deinit(struct mac_provider *context);
+
+/*
+ * Register a serializer for supportng a particular parameter encoding.
+ */
+void mac_provider_register_serializer(struct mac_provider *context,
+ unsigned int encoding, const struct mac_provider_serializer *serializer);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* MAC_PROVIDER_H */
diff --git a/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h b/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h
new file mode 100644
index 0000000..3f5e5c6
--- /dev/null
+++ b/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MAC_PROVIDER_SERIALIZER_H
+#define MAC_PROVIDER_SERIALIZER_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <psa/crypto.h>
+#include <rpc/common/endpoint/rpc_interface.h>
+
+/* Provides a common interface for parameter serialization operations
+ * for the mac service provider.
+ */
+struct mac_provider_serializer {
+
+ /* Operation: mac_setup */
+ rpc_status_t (*deserialize_mac_setup_req)(const struct call_param_buf *req_buf,
+ psa_key_id_t *key_id,
+ psa_algorithm_t *alg);
+
+ rpc_status_t (*serialize_mac_setup_resp)(struct call_param_buf *resp_buf,
+ uint32_t op_handle);
+
+ /* Operation: mac_update */
+ rpc_status_t (*deserialize_mac_update_req)(const struct call_param_buf *req_buf,
+ uint32_t *op_handle,
+ const uint8_t **data, size_t *data_len);
+
+ /* Operation: mac_sign_finish */
+ rpc_status_t (*deserialize_mac_sign_finish_req)(const struct call_param_buf *req_buf,
+ uint32_t *op_handle);
+
+ rpc_status_t (*serialize_mac_sign_finish_resp)(struct call_param_buf *resp_buf,
+ const uint8_t *mac, size_t mac_len);
+
+ /* Operation: mac_verify_finish */
+ rpc_status_t (*deserialize_mac_verify_finish_req)(const struct call_param_buf *req_buf,
+ uint32_t *op_handle,
+ const uint8_t **mac, size_t *mac_len);
+
+ /* Operation: mac_abort */
+ rpc_status_t (*deserialize_mac_abort_req)(const struct call_param_buf *req_buf,
+ uint32_t *op_handle);
+};
+
+#endif /* MAC_PROVIDER_SERIALIZER_H */
diff --git a/components/service/crypto/provider/extension/mac/serializer/packed-c/component.cmake b/components/service/crypto/provider/extension/mac/serializer/packed-c/component.cmake
new file mode 100644
index 0000000..c09b70e
--- /dev/null
+++ b/components/service/crypto/provider/extension/mac/serializer/packed-c/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/packedc_mac_provider_serializer.c"
+ )
diff --git a/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c b/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c
new file mode 100644
index 0000000..fa3a2c9
--- /dev/null
+++ b/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 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/service/crypto/packed-c/mac.h>
+#include "packedc_mac_provider_serializer.h"
+
+/* Operation: mac_setup */
+static rpc_status_t deserialize_mac_setup_req(const struct call_param_buf *req_buf,
+ psa_key_id_t *key_id,
+ psa_algorithm_t *alg)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_mac_setup_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_mac_setup_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *key_id = recv_msg.key_id;
+ *alg = recv_msg.alg;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_mac_setup_resp(struct call_param_buf *resp_buf,
+ uint32_t op_handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ struct ts_crypto_mac_setup_out resp_msg;
+ size_t fixed_len = sizeof(struct ts_crypto_mac_setup_out);
+
+ resp_msg.op_handle = op_handle;
+
+ if (fixed_len <= resp_buf->size) {
+
+ memcpy(resp_buf->data, &resp_msg, fixed_len);
+ resp_buf->data_len = fixed_len;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+/* Operation: mac_update */
+static rpc_status_t deserialize_mac_update_req(const struct call_param_buf *req_buf,
+ uint32_t *op_handle,
+ const uint8_t **data, size_t *data_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_mac_update_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_mac_update_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ struct tlv_const_iterator req_iter;
+ struct tlv_record decoded_record;
+
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+
+ *op_handle = recv_msg.op_handle;
+
+ tlv_const_iterator_begin(&req_iter,
+ (uint8_t*)req_buf->data + expected_fixed_len,
+ req_buf->data_len - expected_fixed_len);
+
+ if (tlv_find_decode(&req_iter, TS_CRYPTO_MAC_UPDATE_IN_TAG_DATA, &decoded_record)) {
+
+ *data = decoded_record.value;
+ *data_len = decoded_record.length;
+ }
+ else {
+ /* Default to a zero length data */
+ *data_len = 0;
+ }
+ }
+
+ return rpc_status;
+}
+
+/* Operation: mac_finish */
+static rpc_status_t deserialize_mac_sign_finish_req(const struct call_param_buf *req_buf,
+ uint32_t *op_handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_mac_sign_finish_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_mac_sign_finish_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *op_handle = recv_msg.op_handle;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_mac_sign_finish_resp(struct call_param_buf *resp_buf,
+ const uint8_t *mac, size_t mac_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_MAC_SIGN_FINISH_OUT_TAG_MAC;
+ out_record.length = mac_len;
+ out_record.value = mac;
+
+ 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(mac_len);
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+/* Operation: mac_verify_finish */
+static rpc_status_t deserialize_mac_verify_finish_req(const struct call_param_buf *req_buf,
+ uint32_t *op_handle,
+ const uint8_t **mac, size_t *mac_len)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_mac_verify_finish_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_mac_verify_finish_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ struct tlv_const_iterator req_iter;
+ struct tlv_record decoded_record;
+
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+
+ *op_handle = recv_msg.op_handle;
+
+ tlv_const_iterator_begin(&req_iter,
+ (uint8_t*)req_buf->data + expected_fixed_len,
+ req_buf->data_len - expected_fixed_len);
+
+ if (tlv_find_decode(&req_iter, TS_CRYPTO_MAC_SIGN_FINISH_OUT_TAG_MAC, &decoded_record)) {
+
+ *mac = decoded_record.value;
+ *mac_len = decoded_record.length;
+ }
+ else {
+ /* Default to a zero length data */
+ *mac_len = 0;
+ }
+ }
+
+ return rpc_status;
+}
+
+/* Operation: mac_abort */
+static rpc_status_t deserialize_mac_abort_req(const struct call_param_buf *req_buf,
+ uint32_t *op_handle)
+{
+ rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY;
+ struct ts_crypto_mac_abort_in recv_msg;
+ size_t expected_fixed_len = sizeof(struct ts_crypto_mac_abort_in);
+
+ if (expected_fixed_len <= req_buf->data_len) {
+
+ memcpy(&recv_msg, req_buf->data, expected_fixed_len);
+ *op_handle = recv_msg.op_handle;
+ rpc_status = TS_RPC_CALL_ACCEPTED;
+ }
+
+ return rpc_status;
+}
+
+/* Singleton method to provide access to the serializer instance */
+const struct mac_provider_serializer *packedc_mac_provider_serializer_instance(void)
+{
+ static const struct mac_provider_serializer instance = {
+ deserialize_mac_setup_req,
+ serialize_mac_setup_resp,
+ deserialize_mac_update_req,
+ deserialize_mac_sign_finish_req,
+ serialize_mac_sign_finish_resp,
+ deserialize_mac_verify_finish_req,
+ deserialize_mac_abort_req
+ };
+
+ return &instance;
+}
diff --git a/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.h b/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.h
new file mode 100644
index 0000000..4ca37de
--- /dev/null
+++ b/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PACKEDC_MAC_PROVIDER_SERIALIZER_H
+#define PACKEDC_MAC_PROVIDER_SERIALIZER_H
+
+#include <service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Singleton method to provide access to the packed-c serializer
+ * for the mac service provider.
+ */
+const struct mac_provider_serializer *packedc_mac_provider_serializer_instance(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* PACKEDC_MAC_PROVIDER_SERIALIZER_H */
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index 25ef2dc..4973793 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -75,6 +75,8 @@
"components/service/crypto/provider/extension/cipher/serializer/packed-c"
"components/service/crypto/provider/extension/key_derivation"
"components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
+ "components/service/crypto/provider/extension/mac"
+ "components/service/crypto/provider/extension/mac/serializer/packed-c"
"components/service/crypto/provider/test"
"components/service/crypto/backend/mbedcrypto"
"components/service/crypto/factory/full"
diff --git a/deployments/crypto/opteesp/CMakeLists.txt b/deployments/crypto/opteesp/CMakeLists.txt
index dab9ae1..f23a51d 100644
--- a/deployments/crypto/opteesp/CMakeLists.txt
+++ b/deployments/crypto/opteesp/CMakeLists.txt
@@ -54,6 +54,8 @@
"components/service/crypto/provider/extension/cipher/serializer/packed-c"
"components/service/crypto/provider/extension/key_derivation"
"components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
+ "components/service/crypto/provider/extension/mac"
+ "components/service/crypto/provider/extension/mac/serializer/packed-c"
"components/service/crypto/factory/full"
"components/service/crypto/backend/mbedcrypto"
"components/service/crypto/backend/mbedcrypto/trng_adapter/platform"
diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt
index eb56006..e2e1077 100644
--- a/deployments/libts/linux-pc/CMakeLists.txt
+++ b/deployments/libts/linux-pc/CMakeLists.txt
@@ -63,6 +63,8 @@
"components/service/crypto/provider/extension/cipher/serializer/packed-c"
"components/service/crypto/provider/extension/key_derivation"
"components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
+ "components/service/crypto/provider/extension/mac"
+ "components/service/crypto/provider/extension/mac/serializer/packed-c"
"components/service/crypto/factory/full"
"components/service/crypto/backend/mbedcrypto"
"components/service/crypto/backend/mbedcrypto/trng_adapter/linux"
diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt
index f8975e7..2b87cba 100644
--- a/deployments/se-proxy/opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/opteesp/CMakeLists.txt
@@ -66,6 +66,8 @@
"components/service/crypto/provider/extension/cipher/serializer/packed-c"
"components/service/crypto/provider/extension/key_derivation"
"components/service/crypto/provider/extension/key_derivation/serializer/packed-c"
+ "components/service/crypto/provider/extension/mac"
+ "components/service/crypto/provider/extension/mac/serializer/packed-c"
"components/service/crypto/factory/full"
"components/service/secure_storage/include"
"components/service/secure_storage/frontend/secure_storage_provider"
diff --git a/protocols/service/crypto/packed-c/mac.h b/protocols/service/crypto/packed-c/mac.h
new file mode 100644
index 0000000..34025ea
--- /dev/null
+++ b/protocols/service/crypto/packed-c/mac.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_MAC_H
+#define TS_CRYPTO_MAC_H
+
+#include <stdint.h>
+
+/**
+ * Protocol definitions for symmetric MAC operations
+ * using the packed-c serialization.
+ */
+
+/****************************************
+ * mac_setup operation definition (sign or verify)
+ */
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_mac_setup_in
+{
+ uint32_t key_id;
+ uint32_t alg;
+};
+
+/* Mandatory fixed sized output parameters */
+struct __attribute__ ((__packed__)) ts_crypto_mac_setup_out
+{
+ uint32_t op_handle;
+};
+
+/****************************************
+ * mac_update operation definition
+ */
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_mac_update_in
+{
+ uint32_t op_handle;
+};
+
+/* Variable length input parameter tags */
+enum
+{
+ TS_CRYPTO_MAC_UPDATE_IN_TAG_DATA = 1
+};
+
+/****************************************
+ * mac_sign_finish operation definition
+ */
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_mac_sign_finish_in
+{
+ uint32_t op_handle;
+};
+
+/* Variable length output parameter tags */
+enum
+{
+ TS_CRYPTO_MAC_SIGN_FINISH_OUT_TAG_MAC = 1
+};
+
+/****************************************
+ * mac_verify_finish operation definition
+ */
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_mac_verify_finish_in
+{
+ uint32_t op_handle;
+};
+
+/* Variable length input parameter tags */
+enum
+{
+ TS_CRYPTO_MAC_VERIFY_FINISH_IN_TAG_MAC = 1
+};
+
+/****************************************
+ * mac_abort operation definition
+ */
+
+/* Mandatory fixed sized input parameters */
+struct __attribute__ ((__packed__)) ts_crypto_mac_abort_in
+{
+ uint32_t op_handle;
+};
+
+#endif /* TS_CRYPTO_MAC_H */
diff --git a/protocols/service/crypto/packed-c/opcodes.h b/protocols/service/crypto/packed-c/opcodes.h
index 7ef5905..d9c2cc1 100644
--- a/protocols/service/crypto/packed-c/opcodes.h
+++ b/protocols/service/crypto/packed-c/opcodes.h
@@ -10,7 +10,7 @@
/* C/C++ definition of crypto service opcodes
*/
-/* Base operations */
+/* Core operations */
#define TS_CRYPTO_OPCODE_NOP (0x0000)
#define TS_CRYPTO_OPCODE_BASE (0x0100)
#define TS_CRYPTO_OPCODE_GENERATE_KEY (TS_CRYPTO_OPCODE_BASE + 1)
@@ -59,4 +59,13 @@
#define TS_CRYPTO_OPCODE_KEY_DERIVATION_KEY_AGREEMENT (TS_CRYPTO_OPCODE_KEY_DERIVATION_BASE + 9)
#define TS_CRYPTO_OPCODE_KEY_DERIVATION_RAW_KEY_AGREEMENT (TS_CRYPTO_OPCODE_KEY_DERIVATION_BASE + 10)
+/* MAC operations */
+#define TS_CRYPTO_OPCODE_MAC_BASE (0x0500)
+#define TS_CRYPTO_OPCODE_MAC_SIGN_SETUP (TS_CRYPTO_OPCODE_MAC_BASE + 1)
+#define TS_CRYPTO_OPCODE_MAC_VERIFY_SETUP (TS_CRYPTO_OPCODE_MAC_BASE + 2)
+#define TS_CRYPTO_OPCODE_MAC_UPDATE (TS_CRYPTO_OPCODE_MAC_BASE + 3)
+#define TS_CRYPTO_OPCODE_MAC_SIGN_FINISH (TS_CRYPTO_OPCODE_MAC_BASE + 4)
+#define TS_CRYPTO_OPCODE_MAC_VERIFY_FINISH (TS_CRYPTO_OPCODE_MAC_BASE + 5)
+#define TS_CRYPTO_OPCODE_MAC_ABORT (TS_CRYPTO_OPCODE_MAC_BASE + 6)
+
#endif /* TS_CRYPTO_OPCODES_H */