Enable owner labelling of keys in Mbed TLS
This change modifies the build configuration for Mbed TLS when it is
used as a backend for the crypto provider to enable labelling of key IDs
using an externally provided identifier. This allows the key store to be
partitioned to protect keys from unauthorized access. Currently, the
partitioning is based on the caller ID that identifies a calling client.
For FF-A deployments, this is the source partition ID. Because the
configuration change alters the PSA Crypto API exposed by mbedcrypto, a
number of changes were needed to allow the modified API to coexist in
builds alongside clients that depend on the standard API. Some old unit
test cases that were not practical to modify have been removed. From a
coverage perspective, most of the same areas are covered by the
extensive set of service level tests.
Signed-off-by: Balint Dobszay <balint.dobszay@arm.com>
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I2762c91bba2dba0a6305aefe61f256355defaf3a
diff --git a/components/service/attestation/test/component/attestation_reporter_tests.cpp b/components/service/attestation/test/component/attestation_reporter_tests.cpp
index 59386ea..3aaf4f4 100644
--- a/components/service/attestation/test/component/attestation_reporter_tests.cpp
+++ b/components/service/attestation/test/component/attestation_reporter_tests.cpp
@@ -5,7 +5,6 @@
*/
#include <psa/error.h>
-#include <psa/crypto.h>
#include <psa/lifecycle.h>
#include <qcbor/qcbor_spiffy_decode.h>
#include <t_cose/t_cose_sign1_verify.h>
@@ -20,6 +19,8 @@
#include <service/attestation/key_mngr/attest_key_mngr.h>
#include <service/attestation/key_mngr/local/local_attest_key_mngr.h>
#include <protocols/service/attestation/packed-c/eat.h>
+#include <service/crypto/client/psa/psa_crypto_client.h>
+#include <service_locator.h>
#include <CppUTest/TestHarness.h>
@@ -32,7 +33,7 @@
report = NULL;
report_len = 0;
- psa_crypto_init();
+ open_crypto_session();
local_attest_key_mngr_init(LOCAL_ATTEST_KEY_MNGR_VOLATILE_IAK);
/* The set of registered claim_sources determines the content
@@ -64,8 +65,36 @@
attest_report_destroy(report);
claims_register_deinit();
local_attest_key_mngr_deinit();
+ close_crypto_session();
}
+ void open_crypto_session()
+ {
+ m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
+ if (m_crypto_service_context) {
+ m_crypto_session = service_context_open(m_crypto_service_context);
+ if (m_crypto_session) {
+ psa_crypto_client_init(m_crypto_session);
+ psa_crypto_init();
+ }
+ }
+ }
+
+ void close_crypto_session()
+ {
+ psa_crypto_client_deinit();
+
+ if (m_crypto_service_context && m_crypto_session) {
+ service_context_close(m_crypto_service_context, m_crypto_session);
+ m_crypto_session = NULL;
+
+ service_context_relinquish(m_crypto_service_context);
+ m_crypto_service_context = NULL;
+ }
+ }
+
+ struct service_context *m_crypto_service_context;
+ struct rpc_caller_session *m_crypto_session;
struct event_log_claim_source event_log_claim_source;
struct boot_seed_generator boot_seed_claim_source;
struct null_lifecycle_claim_source lifecycle_claim_source;
diff --git a/components/service/crypto/backend/mbedcrypto/component.cmake b/components/service/crypto/backend/mbedcrypto/component.cmake
index 36fd3df..dd6f60c 100644
--- a/components/service/crypto/backend/mbedcrypto/component.cmake
+++ b/components/service/crypto/backend/mbedcrypto/component.cmake
@@ -21,3 +21,9 @@
"${TS_ROOT}/components/service/common/include"
"${TS_ROOT}/components/service/secure_storage/include"
CACHE STRING "PSA ITS for MbedTLS" FORCE)
+
+# Override the default crypto backend interface with an alternative that is
+# compatible with the configuration of mbedtls that this component imposes.
+target_compile_definitions(${TGT} PUBLIC
+ ALTERNATIVE_CRYPTO_BACKEND="${CMAKE_CURRENT_LIST_DIR}/mbedtls_psa_crypto_backend.h"
+ )
diff --git a/components/service/crypto/backend/mbedcrypto/mbedcrypto_backend.c b/components/service/crypto/backend/mbedcrypto/mbedcrypto_backend.c
index d9596bb..1989003 100644
--- a/components/service/crypto/backend/mbedcrypto/mbedcrypto_backend.c
+++ b/components/service/crypto/backend/mbedcrypto/mbedcrypto_backend.c
@@ -4,10 +4,9 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <service/crypto/backend/mbedcrypto/mbedtls_psa_crypto_backend.h>
#include <service/crypto/backend/mbedcrypto/trng_adapter/trng_adapter.h>
#include <service/secure_storage/frontend/psa/its/its_frontend.h>
-#include <psa/crypto.h>
-
psa_status_t mbedcrypto_backend_init(struct storage_backend *storage_backend,
int trng_instance_num)
diff --git a/components/service/crypto/backend/mbedcrypto/mbedtls_psa_crypto_backend.h b/components/service/crypto/backend/mbedcrypto/mbedtls_psa_crypto_backend.h
new file mode 100644
index 0000000..afe45fe
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/mbedtls_psa_crypto_backend.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_PSA_CRYPTO_BACKEND_H
+#define MBEDTLS_PSA_CRYPTO_BACKEND_H
+
+/**
+ * A crypto backend that uses a configuration of mbedtls to provide the
+ * backend interface used by a crypto provider. The build configuration
+ * enables namespacing of key ids.
+ */
+
+#ifdef MBEDTLS_PSA_CRYPTO_H
+#include MBEDTLS_PSA_CRYPTO_H
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Mbedtls supports key id namespacing via the mbedtls_svc_key_id_t
+ * type that combines a key id with an owner id.
+ */
+typedef mbedtls_svc_key_id_t namespaced_key_id_t;
+#define NAMESPACED_KEY_ID_INIT MBEDTLS_SVC_KEY_ID_INIT
+
+/**
+ * Map to the mbedtls owner id type for the namespace.
+ */
+typedef mbedtls_key_owner_id_t key_id_namespace_t;
+#define KEY_ID_NAMESPACE_INIT 0
+
+/**
+ * \brief Initialize a namespaced key id
+ *
+ * This default implementation just discards the namespace.
+ *
+ * \param namespaced_key_id The object to initialize
+ * \param key_namespace The namespace
+ * \param key_id The key id
+ */
+static inline void namespaced_key_id_init(namespaced_key_id_t *namespaced_key_id,
+ key_id_namespace_t key_namespace,
+ psa_key_id_t key_id)
+{
+ *namespaced_key_id = mbedtls_svc_key_id_make(key_namespace, key_id);
+}
+
+/**
+ * \brief Get the key id from a namespaced_key_id_t
+ *
+ * \param namespaced_key_id Namespaced key id
+ * \return Key id without namespace
+ */
+static inline psa_key_id_t namespaced_key_id_get_key_id(namespaced_key_id_t namespaced_key_id)
+{
+ return MBEDTLS_SVC_KEY_ID_GET_KEY_ID(namespaced_key_id);
+}
+
+/**
+ * \brief Set the key id namespace associated with a key attributes object
+ *
+ * The default implementation discards the namespace
+ *
+ * \param attributes Key attributes object
+ * \param key_namespace Key id namespace
+ */
+static inline void namespaced_key_id_set_namespace(psa_key_attributes_t *attributes,
+ key_id_namespace_t key_namespace)
+{
+ mbedtls_set_key_owner_id(attributes, key_namespace);
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* MBEDTLS_PSA_CRYPTO_BACKEND_H */
diff --git a/components/service/crypto/client/test/component.cmake b/components/service/crypto/client/test/component.cmake
deleted file mode 100644
index 0374e84..0000000
--- a/components/service/crypto/client/test/component.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2020, 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}/test_crypto_client.cpp"
- )
-
diff --git a/components/service/crypto/client/test/standalone/component.cmake b/components/service/crypto/client/test/standalone/component.cmake
deleted file mode 100644
index 13488e8..0000000
--- a/components/service/crypto/client/test/standalone/component.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2020, 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}/standalone_crypto_client.cpp"
- )
-
diff --git a/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp b/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp
deleted file mode 100644
index 6146477..0000000
--- a/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include "standalone_crypto_client.h"
-#include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
-#include "service/crypto/provider/crypto_uuid.h"
-#include <service/crypto/factory/crypto_provider_factory.h>
-#include <service/crypto/backend/mbedcrypto/mbedcrypto_backend.h>
-#include <service/secure_storage/backend/secure_flash_store/secure_flash_store.h>
-#include <service/secure_storage/backend/secure_flash_store/flash/ram/sfs_flash_ram.h>
-
-standalone_crypto_client::standalone_crypto_client() :
- test_crypto_client(),
- m_crypto_provider(NULL),
- m_storage_provider(),
- m_storage_client(),
- m_crypto_caller(),
- m_storage_caller(),
- m_crypto_session(),
- m_storage_session()
-{
-
-}
-
-standalone_crypto_client::~standalone_crypto_client()
-{
-
-}
-
-bool standalone_crypto_client::init()
-{
- bool should_do = test_crypto_client::init();
-
- if (should_do) {
- const struct rpc_uuid storage_uuid = { .uuid = TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID };
- const struct rpc_uuid crypto_uuid = { .uuid = TS_PSA_CRYPTO_PROTOBUF_SERVICE_UUID };
- rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
-
- if (!is_fault_injected(FAILED_TO_DISCOVER_SECURE_STORAGE)) {
-
- /* Establish rpc session with storage provider */
- struct storage_backend *storage_backend = sfs_init(sfs_flash_ram_instance());
- struct rpc_service_interface *storage_service =
- secure_storage_provider_init(&m_storage_provider, storage_backend, &storage_uuid);
- rpc_status = direct_caller_init(&m_storage_caller, storage_service);
- } else {
-
- /*
- * Missing storage service fault injected. To allow a somewhat viable
- * crypto service to be started, use a dummy _caller that will safely
- * terminate storage calls with an appropriate error.
- */
- rpc_status = dummy_caller_init(&m_storage_caller, RPC_SUCCESS, PSA_ERROR_STORAGE_FAILURE);
- }
-
- if (rpc_status != RPC_SUCCESS)
- return false;
-
- rpc_status = rpc_caller_session_find_and_open(&m_storage_session, &m_storage_caller,
- &storage_uuid, 4096);
- if (rpc_status != RPC_SUCCESS)
- return false;
-
- struct rpc_service_interface *crypto_iface = NULL;
- struct storage_backend *client_storage_backend =
- secure_storage_client_init(&m_storage_client, &m_storage_session);
-
- if (mbedcrypto_backend_init(client_storage_backend, 0) == PSA_SUCCESS) {
-
- m_crypto_provider = crypto_protobuf_provider_factory_create();
- crypto_iface = service_provider_get_rpc_interface(&m_crypto_provider->base_provider);
- }
-
- rpc_status = direct_caller_init(&m_crypto_caller, crypto_iface);
- if (rpc_status != RPC_SUCCESS)
- return false;
-
- rpc_status = rpc_caller_session_find_and_open(&m_crypto_session, &m_crypto_caller,
- &crypto_uuid, 4096);
- if (rpc_status != RPC_SUCCESS)
- return false;
-
- crypto_client::set_caller(&m_crypto_session);
- }
-
- return should_do;
-}
-
-bool standalone_crypto_client::deinit()
-{
- bool should_do = test_crypto_client::deinit();
-
- if (should_do) {
-
- crypto_provider_factory_destroy(m_crypto_provider);
- secure_storage_provider_deinit(&m_storage_provider);
- secure_storage_client_deinit(&m_storage_client);
-
- rpc_caller_session_close(&m_storage_session);
- rpc_caller_session_close(&m_crypto_session);
-
- direct_caller_deinit(&m_storage_caller);
- direct_caller_deinit(&m_crypto_caller);
- }
-
- return should_do;
-}
-
-/* Fault injection */
-bool standalone_crypto_client::is_fault_supported(enum fault_code code) const
-{
- return (code == test_crypto_client::FAILED_TO_DISCOVER_SECURE_STORAGE);
-}
-
-/* Test Methods */
-bool standalone_crypto_client::keystore_reset_is_supported() const
-{
- return test_crypto_client::keystore_reset_is_supported();
-}
-
-void standalone_crypto_client::keystore_reset()
-{
- test_crypto_client::keystore_reset();
-}
-
-bool standalone_crypto_client::keystore_key_exists_is_supported() const
-{
- return test_crypto_client::keystore_key_exists_is_supported() ;
-}
-
-bool standalone_crypto_client::keystore_key_exists(uint32_t id) const
-{
- return test_crypto_client::keystore_key_exists(id);
-}
-
-bool standalone_crypto_client::keystore_keys_held_is_supported() const
-{
- return test_crypto_client::keystore_keys_held_is_supported();
-}
-
-size_t standalone_crypto_client::keystore_keys_held() const
-{
- return test_crypto_client::keystore_keys_held();
-}
-
-/* Factory for creating standalone_crypto_client objects */
-class standalone_crypto_client_factory : public test_crypto_client::factory
-{
-public:
- standalone_crypto_client_factory() :
- test_crypto_client::factory()
- {
- test_crypto_client::register_factory(this);
- }
-
- ~standalone_crypto_client_factory()
- {
- test_crypto_client::deregister_factory(this);
- }
-
- test_crypto_client *create()
- {
- return new standalone_crypto_client;
- };
-};
-
-/*
- * Static construction causes this to be registered
- * as the default factory for constructing test_crypto_client objects.
- */
-static standalone_crypto_client_factory default_factory;
diff --git a/components/service/crypto/client/test/standalone/standalone_crypto_client.h b/components/service/crypto/client/test/standalone/standalone_crypto_client.h
deleted file mode 100644
index c6d9ace..0000000
--- a/components/service/crypto/client/test/standalone/standalone_crypto_client.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STANDALONE_CRYPTO_CLIENT_H
-#define STANDALONE_CRYPTO_CLIENT_H
-
-#include <service/crypto/client/test/test_crypto_client.h>
-#include <rpc/direct/direct_caller.h>
-#include <rpc/dummy/dummy_caller.h>
-#include <service/crypto/provider/crypto_provider.h>
-#include <service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h>
-#include <service/secure_storage/backend/secure_storage_client/secure_storage_client.h>
-
-/*
- * A specialization of the crypto_client class that extends it to add crypto
- * and storage providers to offer a viable crypto service from a single object.
- * This is only used for test purposes and should not be used for production
- * deployments. Provides methods used for inspecting service state that
- * support test.
- */
-class standalone_crypto_client : public test_crypto_client
-{
-public:
- standalone_crypto_client();
- virtual ~standalone_crypto_client();
-
- bool init();
- bool deinit();
-
- /* Test support methods */
- bool keystore_reset_is_supported() const;
- void keystore_reset();
-
- bool keystore_key_exists_is_supported() const;
- bool keystore_key_exists(uint32_t id) const;
-
- bool keystore_keys_held_is_supported() const;
- size_t keystore_keys_held() const;
-
-private:
- bool is_fault_supported(enum fault_code code) const;
-
- struct crypto_provider *m_crypto_provider;
- struct secure_storage_provider m_storage_provider;
- struct secure_storage_client m_storage_client;
- struct rpc_caller_interface m_crypto_caller;
- struct rpc_caller_interface m_storage_caller;
- struct rpc_caller_session m_crypto_session;
- struct rpc_caller_session m_storage_session;
-};
-
-#endif /* STANDALONE_CRYPTO_CLIENT_H */
diff --git a/components/service/crypto/client/test/test_crypto_client.cpp b/components/service/crypto/client/test/test_crypto_client.cpp
deleted file mode 100644
index 3217c61..0000000
--- a/components/service/crypto/client/test/test_crypto_client.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <cassert>
-#include "test_crypto_client.h"
-
-test_crypto_client::factory *test_crypto_client::m_default_factory = NULL;
-
-test_crypto_client::test_crypto_client() :
- protobuf_crypto_client(),
- m_is_initialized(false),
- m_injected_faults()
-{
-
-}
-
-test_crypto_client::~test_crypto_client()
-{
- deinit();
-}
-
-bool test_crypto_client::init()
-{
- bool success = !m_is_initialized;
- m_is_initialized = true;
- return success;
-}
-
-bool test_crypto_client::deinit()
-{
- bool success = m_is_initialized;
- m_is_initialized = false;
- return success;
-}
-
-test_crypto_client *test_crypto_client::create_default()
-{
- /*
- * It's mandatory to include a concrete test_crypto_client
- * that registers its own factory in a deployment if you
- * want to use this factory method.
- */
- assert(m_default_factory);
- return m_default_factory->create();
-}
-
-void test_crypto_client::register_factory(factory *factory)
-{
- /*
- * Don't allow overriding of an existing default. This
- * will happen if two test_crypto_client components have
- * been included in a deployment.
- */
- assert(!m_default_factory);
- m_default_factory = factory;
-}
-
-void test_crypto_client::deregister_factory(factory *factory)
-{
- if (m_default_factory == factory) m_default_factory = NULL;
-}
-
-bool test_crypto_client::inject_fault(enum fault_code code)
-{
- assert(!m_is_initialized);
-
- bool is_supported = is_fault_supported(code);
- if (is_supported) m_injected_faults.push_back(code);
- return is_supported;
-}
-
-bool test_crypto_client::is_fault_supported(enum fault_code code) const
-{
- /* Derived classes may override this if fault simualtion is supported */
- (void)code;
- return false;
-}
-
-bool test_crypto_client::is_fault_injected(enum fault_code code) const
-{
- bool is_injected = false;
-
- for (size_t i = 0; !is_injected && i < m_injected_faults.size(); ++i) {
- is_injected = (m_injected_faults[i] == code);
- }
-
- return is_injected;
-}
-
-/*
- * Test methods by default are not supported. Calling a non-supported
- * method will trigger an assert. A class derived from this one may
- * pick and choose which test methods it supports.
- */
-bool test_crypto_client::keystore_reset_is_supported() const { return false; }
-void test_crypto_client::keystore_reset() { assert(false); }
-
-bool test_crypto_client::keystore_key_exists_is_supported() const { return false; }
-bool test_crypto_client::keystore_key_exists(uint32_t id) const { (void)id; assert(false); return false; }
-
-bool test_crypto_client::keystore_keys_held_is_supported() const { return false; }
-size_t test_crypto_client::keystore_keys_held() const { assert(false); return 0; }
\ No newline at end of file
diff --git a/components/service/crypto/client/test/test_crypto_client.h b/components/service/crypto/client/test/test_crypto_client.h
deleted file mode 100644
index 7e10eaa..0000000
--- a/components/service/crypto/client/test/test_crypto_client.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TEST_CRYPTO_CLIENT_H
-#define TEST_CRYPTO_CLIENT_H
-
-#include <service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h>
-#include <vector>
-
-/*
- * A specialization of the crypto_client class that extends it to add
- * virtial methods to support test. Depending on the deployment,
- * real implementations of test methods may or may not exist. For example,
- * for a real distributed deployment where the key store is located in
- * a secure processing environment, back door test methods that peak
- * into the keystore are clearly not possible (or at least desirable!).
- * Each virtual test method is paired with a is_supported() method to
- * allow test cases to adapt to circumstances.
- */
-class test_crypto_client : public protobuf_crypto_client
-{
-public:
- virtual ~test_crypto_client();
-
- virtual bool init();
- virtual bool deinit();
-
- /*
- * A factory method for contsructing the default class
- * of test_crypto_client for the deployment.
- */
- static test_crypto_client *create_default();
-
- /*
- * Fault conditions that may be injected to allow error
- * handling to be tested.
- */
- enum fault_code
- {
- FAILED_TO_DISCOVER_SECURE_STORAGE
- };
-
- /*
- * Injects the specified fault. May be called multiple
- * times to inject different fault conditions. Faults
- * should be injected prior to calling the init() method
- * to allow startup faults to be simulated. Returns true
- * if the fault condition can be simulated.
- */
- bool inject_fault(enum fault_code code);
-
- /* Wipe all keys held in the keystore */
- virtual bool keystore_reset_is_supported() const;
- virtual void keystore_reset();
-
- /* Check if a key is held in the keystore */
- virtual bool keystore_key_exists_is_supported() const;
- virtual bool keystore_key_exists(uint32_t id) const;
-
- /* Return the number of keys in the keystore */
- virtual bool keystore_keys_held_is_supported() const;
- virtual size_t keystore_keys_held() const;
-
- /* An abstract factory for constructing concrete test_crypto_client objects */
- class factory
- {
- public:
- virtual test_crypto_client *create() = 0;
- };
-
- static void register_factory(factory *factory);
- static void deregister_factory(factory *factory);
-
-protected:
- test_crypto_client();
- virtual bool is_fault_supported(enum fault_code code) const;
- bool is_fault_injected(enum fault_code code) const;
-
-private:
- bool m_is_initialized;
- std::vector<fault_code> m_injected_faults;
- static factory *m_default_factory;
-};
-
-#endif /* STANDALONE_CRYPTO_CLIENT_H */
diff --git a/components/service/crypto/test/unit/component.cmake b/components/service/crypto/test/unit/component.cmake
index bdb38bc..77d5c2e 100644
--- a/components/service/crypto/test/unit/component.cmake
+++ b/components/service/crypto/test/unit/component.cmake
@@ -10,7 +10,4 @@
target_sources(${TGT} PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/crypto_msg_encode_decode.cpp"
- "${CMAKE_CURRENT_LIST_DIR}/poc_crypto_ops.cpp"
- "${CMAKE_CURRENT_LIST_DIR}/crypto_fault_tests.cpp"
)
-
diff --git a/components/service/crypto/test/unit/crypto_fault_tests.cpp b/components/service/crypto/test/unit/crypto_fault_tests.cpp
deleted file mode 100644
index 2f7615e..0000000
--- a/components/service/crypto/test/unit/crypto_fault_tests.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <string>
-#include <cstring>
-#include <cstdint>
-#include <service/crypto/client/test/standalone/standalone_crypto_client.h>
-#include <CppUTest/TestHarness.h>
-
-TEST_GROUP(CryptoFaultTests)
-{
- void setup()
- {
- m_crypto_client = new standalone_crypto_client;
- }
-
- void teardown()
- {
- m_crypto_client->deinit();
- delete m_crypto_client;
- m_crypto_client = NULL;
- }
-
- test_crypto_client *m_crypto_client;
-};
-
-TEST(CryptoFaultTests, volatileKeyWithBrokenStorage)
-{
- /* Inject broken secure storage fault */
- m_crypto_client->inject_fault(test_crypto_client::FAILED_TO_DISCOVER_SECURE_STORAGE);
- m_crypto_client->init();
-
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-
- psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
- psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
- psa_set_key_bits(&attributes, 256);
-
- /* Expect generation of volatile key to still work with fault */
- psa_key_id_t key_id;
- status = m_crypto_client->generate_key(&attributes, &key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
- CHECK(0 != key_id);
-
- psa_reset_key_attributes(&attributes);
-}
-
-TEST(CryptoFaultTests, persistentKeysWithBrokenStorage)
-{
- /* Inject broken secure storage fault */
- m_crypto_client->inject_fault(test_crypto_client::FAILED_TO_DISCOVER_SECURE_STORAGE);
- m_crypto_client->init();
-
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
- psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
- psa_set_key_bits(&attributes, 256);
-
- /* Expect persist key generation to fail */
- psa_key_id_t key_id;
- psa_set_key_id(&attributes, 1);
- status = m_crypto_client->generate_key(&attributes, &key_id);
- CHECK(PSA_SUCCESS != status);
-
- psa_reset_key_attributes(&attributes);
-}
-
-TEST(CryptoFaultTests, randomNumbersWithBrokenStorage)
-{
- /* Inject broken secure storage fault */
- m_crypto_client->inject_fault(test_crypto_client::FAILED_TO_DISCOVER_SECURE_STORAGE);
- m_crypto_client->init();
-
- psa_status_t status;
- uint8_t num12_128bit[16];
-
- memset(num12_128bit, 0, sizeof(num12_128bit));
-
- /* Expect random number generation to work, despite the broken storage */
- status = m_crypto_client->generate_random(num12_128bit, sizeof(num12_128bit));
- CHECK_EQUAL(PSA_SUCCESS, status);
-}
diff --git a/components/service/crypto/test/unit/poc_crypto_ops.cpp b/components/service/crypto/test/unit/poc_crypto_ops.cpp
deleted file mode 100644
index 19bd448..0000000
--- a/components/service/crypto/test/unit/poc_crypto_ops.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#include <cstdio>
-#include <cstring>
-#include <psa/crypto.h>
-#include <CppUTest/TestHarness.h>
-
-/* Tests to prototype each of the Crypto operations used for the PoC Crypto SP
- * demonstrator.
- */
-TEST_GROUP(PocCryptoOpTests) {
-
- void setup() {
- print_info = false;
- (void)psa_crypto_init();
- }
-
- void generateEcdsaKeyPair() {
- psa_status_t status;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-
- psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
- psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
- psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
- psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
- psa_set_key_bits(&attributes, 256);
-
- status = psa_generate_key(&attributes, &ecdsa_key_id);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- psa_reset_key_attributes(&attributes);
-
- if (print_info) {
- printf("Generated ECDSA key pair\n");
- printf(" Inputs: attributes: %ld\n", sizeof(attributes));
- printf(" Outputs: id: %ld status: %ld\n", sizeof(ecdsa_key_id), sizeof(status));
- }
- }
-
- void exportPublicKey() {
- psa_status_t status;
- exported_key_len = 0;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-
- status = psa_get_key_attributes(ecdsa_key_id, &attributes);
-
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)),
- psa_get_key_bits(&attributes));
-
- status = psa_export_public_key(ecdsa_key_id, exported_key, sizeof(exported_key),
- &exported_key_len);
-
- CHECK_EQUAL(PSA_SUCCESS, status);
- CHECK_EQUAL(max_export_size, exported_key_len);
-
- psa_reset_key_attributes(&attributes);
-
- if (print_info) {
- printf("Exported a public key\n");
- printf(" Inputs: id: %ld\n", sizeof(ecdsa_key_id));
- printf(" Outputs: exported_length: %ld status: %ld\n", sizeof(exported_key_len), sizeof(status));
- printf(" Outputs: space of key value: %ld bytes\n", exported_key_len);
- }
- }
-
- void signMessage() {
- psa_status_t status;
- uint8_t hash[20];
- uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
- size_t signature_length;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-
- memset(hash, 0x55, sizeof(hash));
-
- status = psa_get_key_attributes(ecdsa_key_id, &attributes);
-
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- status = psa_sign_hash(ecdsa_key_id, psa_get_key_algorithm(&attributes),
- hash, sizeof(hash),
- signature, sizeof(signature),
- &signature_length);
- CHECK_EQUAL(PSA_SUCCESS, status);
-
- psa_reset_key_attributes(&attributes);
-
- if (print_info) {
- printf("Signed a message\n");
- printf(" Inputs: id: %ld algo 1 message %ld\n", sizeof(ecdsa_key_id), sizeof(hash));
- printf(" Outputs: signature: %ld\n", signature_length);
- }
- }
-
- bool print_info;
- psa_key_id_t ecdsa_key_id;
- uint8_t exported_key[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
- size_t exported_key_len;
-};
-
-TEST(PocCryptoOpTests, checkOpSequence) {
-
- generateEcdsaKeyPair();
- exportPublicKey();
- signMessage();
-}
\ No newline at end of file
diff --git a/components/service/locator/standalone/services/attestation/attestation_service_context.cpp b/components/service/locator/standalone/services/attestation/attestation_service_context.cpp
index 24778e6..66a7004 100644
--- a/components/service/locator/standalone/services/attestation/attestation_service_context.cpp
+++ b/components/service/locator/standalone/services/attestation/attestation_service_context.cpp
@@ -13,6 +13,7 @@
#include <config/ramstore/config_ramstore.h>
#include <config/interface/config_store.h>
#include <config/interface/config_blob.h>
+#include <service/crypto/client/psa/psa_crypto_client.h>
#include <psa/crypto.h>
attestation_service_context::attestation_service_context(const char *sn) :
@@ -22,7 +23,9 @@
m_boot_seed_claim_source(),
m_lifecycle_claim_source(),
m_instance_id_claim_source(),
- m_implementation_id_claim_source()
+ m_implementation_id_claim_source(),
+ m_crypto_service_context(NULL),
+ m_crypto_session(NULL)
{
}
@@ -37,11 +40,8 @@
struct claim_source *claim_source;
struct config_blob event_log_blob;
- /* For the standalone attestation service deployment, the
- * mbedcrypto library is used directly. Note that psa_crypto_init()
- * is allowed to be called multiple times.
- */
- psa_crypto_init();
+ /* The crypto service is used for token signing */
+ open_crypto_session();
/**
* Initialize the config_store and load dynamic parameters. For
@@ -101,4 +101,30 @@
claims_register_deinit();
config_ramstore_deinit();
local_attest_key_mngr_deinit();
+ close_crypto_session();
+}
+
+void attestation_service_context::open_crypto_session()
+{
+ m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
+ if (m_crypto_service_context) {
+ m_crypto_session = service_context_open(m_crypto_service_context);
+ if (m_crypto_session) {
+ psa_crypto_client_init(m_crypto_session);
+ psa_crypto_init();
+ }
+ }
+}
+
+void attestation_service_context::close_crypto_session()
+{
+ psa_crypto_client_deinit();
+
+ if (m_crypto_service_context && m_crypto_session) {
+ service_context_close(m_crypto_service_context, m_crypto_session);
+ m_crypto_session = NULL;
+
+ service_context_relinquish(m_crypto_service_context);
+ m_crypto_service_context = NULL;
+ }
}
diff --git a/components/service/locator/standalone/services/attestation/attestation_service_context.h b/components/service/locator/standalone/services/attestation/attestation_service_context.h
index cf6b5b7..28755a9 100644
--- a/components/service/locator/standalone/services/attestation/attestation_service_context.h
+++ b/components/service/locator/standalone/services/attestation/attestation_service_context.h
@@ -27,12 +27,18 @@
void do_init();
void do_deinit();
+ void open_crypto_session();
+ void close_crypto_session();
+
+
struct attest_provider m_attest_provider;
struct event_log_claim_source m_event_log_claim_source;
struct boot_seed_generator m_boot_seed_claim_source;
struct null_lifecycle_claim_source m_lifecycle_claim_source;
struct instance_id_claim_source m_instance_id_claim_source;
struct implementation_id_claim_source m_implementation_id_claim_source;
+ struct service_context *m_crypto_service_context;
+ struct rpc_caller_session *m_crypto_session;
};
#endif /* STANDALONE_ATTESTATION_SERVICE_CONTEXT_H */
diff --git a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp
index ae4698f..944841e 100644
--- a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp
+++ b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp
@@ -6,6 +6,8 @@
#include "smm_variable_service_context.h"
#include <protocols/rpc/common/packed-c/encoding.h>
+#include <service/crypto/client/psa/psa_crypto_client.h>
+#include <psa/crypto.h>
smm_variable_service_context::smm_variable_service_context(const char *sn) :
standalone_service_context(sn, RPC_BUFFER_SIZE),
@@ -13,7 +15,9 @@
m_persistent_store_client(),
m_volatile_store(),
m_storage_service_context(NULL),
- m_storage_session(NULL)
+ m_crypto_service_context(NULL),
+ m_storage_session(NULL),
+ m_crypto_session(NULL)
{
}
@@ -25,6 +29,16 @@
void smm_variable_service_context::do_init()
{
+ /* Initialize crypto backend session */
+ m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
+ if (m_crypto_service_context) {
+ m_crypto_session = service_context_open(m_crypto_service_context);
+ if (m_crypto_session) {
+ psa_crypto_client_init(m_crypto_session);
+ psa_crypto_init();
+ }
+ }
+
/* Initialize the persistent storage backend - uses protected storage service */
struct storage_backend *peristent_backend = NULL;
@@ -72,4 +86,14 @@
smm_variable_provider_deinit(&m_smm_variable_provider);
secure_storage_client_deinit(&m_persistent_store_client);
mock_store_deinit(&m_volatile_store);
+
+ psa_crypto_client_deinit();
+
+ if (m_crypto_service_context && m_crypto_session) {
+ service_context_close(m_crypto_service_context, m_crypto_session);
+ m_crypto_session = NULL;
+
+ service_context_relinquish(m_crypto_service_context);
+ m_crypto_service_context = NULL;
+ }
}
diff --git a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h
index 4420614..21594f9 100644
--- a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h
+++ b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h
@@ -34,7 +34,9 @@
struct secure_storage_client m_persistent_store_client;
struct mock_store m_volatile_store;
struct service_context *m_storage_service_context;
+ struct service_context *m_crypto_service_context;
struct rpc_caller_session *m_storage_session;
+ struct rpc_caller_session *m_crypto_session;
};
#endif /* STANDALONE_SMM_VARIABLE_SERVICE_CONTEXT_H */
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index a8718f0..03f7c8c 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -125,11 +125,11 @@
"components/service/fwu/test/metadata_fetcher/volume"
"components/service/fwu/test/image_directory_checker"
"components/service/fwu/test/ref_scenarios"
+ "components/service/crypto/include"
+ "components/service/crypto/client/psa"
"components/service/crypto/client/cpp"
"components/service/crypto/client/cpp/protocol/protobuf"
"components/service/crypto/client/cpp/protocol/packed-c"
- "components/service/crypto/client/test"
- "components/service/crypto/client/test/standalone"
"components/service/crypto/provider"
"components/service/crypto/provider/serializer/protobuf"
"components/service/crypto/provider/serializer/packed-c"
diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt
index 60d0995..9f8a319 100644
--- a/deployments/libts/linux-pc/CMakeLists.txt
+++ b/deployments/libts/linux-pc/CMakeLists.txt
@@ -89,6 +89,8 @@
"components/service/attestation/key_mngr/local"
"components/service/attestation/provider"
"components/service/attestation/provider/serializer/packed-c"
+ "components/service/crypto/include"
+ "components/service/crypto/client/psa"
"components/service/block_storage/block_store"
"components/service/block_storage/block_store/device"
"components/service/block_storage/block_store/device/ram"
@@ -131,7 +133,6 @@
"components/service/test_runner/provider/backend/mock"
"components/service/test_runner/provider/backend/simple_c"
"components/service/uefi/smm_variable/backend"
- "components/service/uefi/smm_variable/backend/direct"
"components/service/uefi/smm_variable/provider"
"components/media/disk"
"components/media/disk/disk_images"
@@ -219,6 +220,8 @@
"components/service/crypto/test/service"
"components/service/crypto/test/service/protobuf"
"components/service/crypto/test/service/packed-c"
+ "components/service/crypto/include"
+ "components/service/crypto/client/psa"
"components/service/crypto/client/cpp"
"components/service/crypto/client/cpp/protocol/protobuf"
"components/service/crypto/client/cpp/protocol/packed-c"
diff --git a/deployments/platform-inspect/platform-inspect.cmake b/deployments/platform-inspect/platform-inspect.cmake
index dc65184..aa3c523 100644
--- a/deployments/platform-inspect/platform-inspect.cmake
+++ b/deployments/platform-inspect/platform-inspect.cmake
@@ -49,6 +49,9 @@
include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
target_link_libraries(platform-inspect PRIVATE MbedTLS::mbedcrypto)
+# Use Mbed TLS to provide the psa crypto api interface files
+set(PSA_CRYPTO_API_INCLUDE "${MBEDTLS_PUBLIC_INCLUDE_PATH}")
+
# Qcbor
include(${TS_ROOT}/external/qcbor/qcbor.cmake)
diff --git a/deployments/psa-api-test/initial_attestation/iat-api-test.cmake b/deployments/psa-api-test/initial_attestation/iat-api-test.cmake
index 88b5fb9..4d1d2b1 100644
--- a/deployments/psa-api-test/initial_attestation/iat-api-test.cmake
+++ b/deployments/psa-api-test/initial_attestation/iat-api-test.cmake
@@ -52,6 +52,9 @@
include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
target_link_libraries(${PROJECT_NAME} PRIVATE MbedTLS::mbedcrypto)
+# Use Mbed TLS to provide the psa crypto api interface files
+set(PSA_CRYPTO_API_INCLUDE ${MBEDTLS_PUBLIC_INCLUDE_PATH})
+
#-------------------------------------------------------------------------------
# Advertise PSA API include paths to PSA Arch tests
#
diff --git a/external/MbedTLS/MbedTLS.cmake b/external/MbedTLS/MbedTLS.cmake
index fd83d01..f759e19 100644
--- a/external/MbedTLS/MbedTLS.cmake
+++ b/external/MbedTLS/MbedTLS.cmake
@@ -66,6 +66,9 @@
unset(_mbedtls_tgt)
endif()
-# Advertise Mbed TLS as the provider of the PSA Crypto API
-set(PSA_CRYPTO_API_INCLUDE "${MBEDTLS_INSTALL_DIR}/include"
- CACHE STRING "PSA Crypto API include path")
+# Advertise Mbed TLS provided psa crypto api header file. Can be used with #include MBEDTLS_PSA_CRYPTO_H
+# when it is necessary to explicitly include the mbedtls provided version of psa/crypto.h.
+add_compile_definitions(MBEDTLS_PSA_CRYPTO_H="${MBEDTLS_INSTALL_DIR}/include/psa/crypto.h")
+
+# Advertise the public interface path to allow a deployment to determine what scope to give it
+set(MBEDTLS_PUBLIC_INCLUDE_PATH "${MBEDTLS_INSTALL_DIR}/include" CACHE STRING "Mbedtls public include path")
diff --git a/external/MbedTLS/config/libmbedx509.h b/external/MbedTLS/config/libmbedx509.h
index b369d2b..0039d3c 100644
--- a/external/MbedTLS/config/libmbedx509.h
+++ b/external/MbedTLS/config/libmbedx509.h
@@ -35,4 +35,8 @@
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_PKCS7_C
+#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+#define BACKEND_CRYPTO_API_ADD_PREFIX(f) __mbedtls_backend_##f
+#include "../../../components/service/crypto/backend/prefixed_crypto_api.h"
+
#endif /* CONFIG_LIBMBEDX509_H */
diff --git a/tools/cmake/compiler/shared_lib_toolchain_file.cmake b/tools/cmake/compiler/shared_lib_toolchain_file.cmake
index 2151ffc..7c44382 100644
--- a/tools/cmake/compiler/shared_lib_toolchain_file.cmake
+++ b/tools/cmake/compiler/shared_lib_toolchain_file.cmake
@@ -9,3 +9,6 @@
set(CMAKE_POSITION_INDEPENDENT_CODE True)
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+
+# Hide symbols from libraries statically linked to the shared library
+add_link_options(-Wl,--exclude-libs,ALL)