aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurence Lundblade <lgl@securitytheory.com>2019-12-26 11:18:04 -0800
committerTamas Ban <tamas.ban@arm.com>2020-01-23 13:33:03 +0000
commit166836fdf82327cf0604c25040b6cd1e8c909bfc (patch)
treebe93641ad58bded5aa2f2dd91cd2b019c84a6158
parent0025718800cfd2fa9ddf7f129a1e0ee4a7711dae (diff)
downloadtrusted-firmware-m-166836fdf82327cf0604c25040b6cd1e8c909bfc.tar.gz
COSE: Improve PSA crypto adapter
Testing against off-target mbed-crypto 1.1 code base. Change-Id: I842ed8f11791444e65fca9370913c391e7b5a040 Signed-off-by: Laurence Lundblade <lgl@securitytheory.com>
-rw-r--r--lib/ext/t_cose/Makefile.psa_off_target74
-rw-r--r--lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c139
-rw-r--r--lib/ext/t_cose/src/t_cose_crypto.h87
-rw-r--r--lib/ext/t_cose/test/t_cose_make_psa_test_key.c126
4 files changed, 221 insertions, 205 deletions
diff --git a/lib/ext/t_cose/Makefile.psa_off_target b/lib/ext/t_cose/Makefile.psa_off_target
deleted file mode 100644
index 2e674c22d..000000000
--- a/lib/ext/t_cose/Makefile.psa_off_target
+++ /dev/null
@@ -1,74 +0,0 @@
-# Makefile -- UNIX-style make for t_cose simulating PSA crypto
-#
-# Copyright (c) 2019, Laurence Lundblade. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-# See BSD-3-Clause license in README.md
-#
-
-# ---- comment ----
-# This is for PSA Crypto. Adjust CRYPTO_INC and CRYPTO_LIB for the location of
-# the PSA libraries on your build machine.
-
-
-# ---- QCBOR location ----
-# Adjust this to the location of QCBOR in your build environment
-QCBOR_INC= -I ../../QCBOR/master/inc
-QCBOR_LIB=../../QCBOR/master/libqcbor.a
-
-
-# ---- crypto configuration -----
-# Set up for PSA + OpenSSL. This may have to be adjusted for your build environment.
-CRYPTO_INC= -I ../../TF-M/trusted-firmware-m/interface/include/
-CRYPTO_OBJ=crypto_adapters/t_cose_psa_crypto.o
-CRYPTO_LIB=
-
-
-# ---- compiler configuration -----
-C_OPTS=-Os -Wall -pedantic-errors -Wextra -Wshadow -Wparentheses -xc -std=c99
-
-
-# ---- T_COSE Config and test options ----
-CONFIG_OPTS=
-CRYPTO_TEST_OBJ=test/t_cose_make_psa_test_key.o
-TEST_OBJ=test/t_cose_test.o test/run_tests.o test/t_cose_sign_verify_test.o test/t_cose_make_test_messages.o $(CRYPTO_TEST_OBJ)
-
-
-# ---- the main body that is invariant ----
-INC=-I inc -I Test -I src
-ALL_INC=$(CRYPTO_INC) $(QCBOR_INC) $(INC)
-CFLAGS=$(ALL_INC) $(C_OPTS) $(CONFIG_OPTS)
-
-SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_util.o src/t_cose_parameters.o
-
-all: t_cose_test libt_cose.a
-
-
-libt_cose.a: $(SRC_OBJ) $(CRYPTO_OBJ)
- ar -r $@ $^
-
-
-t_cose_test: main.o $(SRC_OBJ) $(CRYPTO_OBJ) $(TEST_OBJ)
- cc -o $@ $^ $(QCBOR_LIB) $(CRYPTO_LIB)
-
-
-clean:
- rm -f $(SRC_OBJ) $(TEST_OBJ) $(CRYPTO_OBJ) t_cose_test libt_cose.a main.o
-
-
-# ---- source dependecies -----
-src/t_cose_util.o: src/t_cose_util.h src/t_cose_standard_constants.h inc/t_cose_common.h src/t_cose_crypto.h
-src/t_cose_sign1_verify.o: inc/t_cose_sign1_verify.h src/t_cose_crypto.h src/t_cose_util.h src/t_cose_parameters.h inc/t_cose_common.h src/t_cose_standard_constants.h
-src/t_cose_parameters.o: src/t_cose_parameters.h src/t_cose_standard_constants.h inc/t_cose_sign1_verify.h inc/t_cose_common.h
-src/t_cose_sign1_sign.o: inc/t_cose_sign1_sign.h src/t_cose_standard_constants.h src/t_cose_crypto.h src/t_cose_util.h inc/t_cose_common.h
-
-
-# ---- test dependencies -----
-test/t_cose_test.o: test/t_cose_test.h inc/t_cose_sign1_sign.h inc/t_cose_sign1_verify.h inc/t_cose_common.h test/t_cose_make_test_messages.h src/t_cose_crypto.h
-test/t_cose_make_test_messages.o: test/t_cose_make_test_messages.h inc/t_cose_sign1_sign.h inc/t_cose_common.h src/t_cose_standard_constants.h src/t_cose_crypto.h src/t_cose_util.h
-test/run_test.o: test/run_test.h test/t_cose_test.h test/t_cose_hash_fail_test.h
-test/t_cose_make_psa_test_key.o: test/t_cose_make_test_pub_key.h src/t_cose_standard_constants.h
-
-# ---- crypto dependencies ----
-crypto_adapters/t_cose_psa_crypto.o: src/t_cose_crypto.h inc/t_cose_common.h src/t_cose_standard_constants.h inc/q_useful_buf.h
diff --git a/lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c b/lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c
index 5fc8fba87..cdbb254d8 100644
--- a/lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c
+++ b/lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c
@@ -5,7 +5,7 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*
- * See BSD-3-Clause license in README.mdE.
+ * See BSD-3-Clause license in README.md
*/
@@ -35,7 +35,26 @@
#include "t_cose_crypto.h" /* The interface this implements */
-#include "psa/crypto.h" /* PSA / TF_M crypto */
+#include "psa/crypto.h" /* PSA Crypto Interface to mbed crypto or such */
+
+
+/* Here's the auto-detect and manual override logic for managing PSA
+ * Crypto API compatibility.
+ *
+ * PSA_GENERATOR_UNBRIDLED_CAPACITY happens to be defined in MBed
+ * Crypto 1.1 and not in MBed Crypto 2.0 so it is what auto-detect
+ * hinges off of.
+ *
+ * T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO20 can be defined to force
+ * setting to MBed Crypto 2.0
+ *
+ * T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11 can be defined to force
+ * setting to MBed Crypt 1.1. It is also what the code below hinges
+ * on.
+ */
+#if defined(PSA_GENERATOR_UNBRIDLED_CAPACITY) && !defined(T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO20)
+#define T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11
+#endif
/* Avoid compiler warning due to unused argument */
@@ -81,7 +100,7 @@ static enum t_cose_err_t psa_status_to_t_cose_error_signing(psa_status_t err)
err == PSA_ERROR_NOT_SUPPORTED ? T_COSE_ERR_UNSUPPORTED_SIGNING_ALG:
err == PSA_ERROR_INSUFFICIENT_MEMORY ? T_COSE_ERR_INSUFFICIENT_MEMORY :
err == PSA_ERROR_TAMPERING_DETECTED ? T_COSE_ERR_TAMPERING_DETECTED :
- T_COSE_ERR_FAIL;
+ T_COSE_ERR_SIG_FAIL;
}
@@ -124,6 +143,15 @@ t_cose_crypto_pub_key_verify(int32_t cose_algorithm_id,
verification_key_psa = (psa_key_handle_t)verification_key.k.key_handle;
+
+ /* The official PSA Crypto API expected to be formally set in 2020
+ * uses psa_verify_hash() instead of psa_asymmetric_verify().
+ * This older API is used because Mbed Crypto 2.0 provides
+ * backwards compatibility to this with crypto_compat.h and there
+ * is no forward compatibility in the other direction. If Mbed
+ * Crypto ceases providing backwards compatibility then this code
+ * has to be changed to use psa_verify_hash().
+ */
psa_result = psa_asymmetric_verify(verification_key_psa,
psa_alg_id,
hash_to_verify.ptr,
@@ -173,8 +201,16 @@ t_cose_crypto_pub_key_sign(int32_t cose_algorithm_id,
signing_key_psa = (psa_key_handle_t)signing_key.k.key_handle;
- /* It is assumed that psa_asymmetric_sign() is checking
- * signature_buffer length and won't write off the end of it.
+ /* It is assumed that this call is checking the signature_buffer
+ * length and won't write off the end of it.
+ */
+ /* The official PSA Crypto API expected to be formally set in 2020
+ * uses psa_sign_hash() instead of psa_asymmetric_sign(). This
+ * older API is used because Mbed Crypto 2.0 provides backwards
+ * compatibility to this crypto_compat.h and there is no forward
+ * compatibility in the other direction. If Mbed Crypto ceases
+ * providing backwards compatibility then this code has to be
+ * changed to use psa_sign_hash().
*/
psa_result = psa_asymmetric_sign(signing_key_psa,
psa_alg_id,
@@ -206,7 +242,6 @@ enum t_cose_err_t t_cose_crypto_sig_size(int32_t cose_algorithm_id,
{
enum t_cose_err_t return_value;
psa_key_handle_t signing_key_psa;
- psa_key_type_t key_type;
size_t key_len_bits;
size_t key_len_bytes;
@@ -225,12 +260,36 @@ enum t_cose_err_t t_cose_crypto_sig_size(int32_t cose_algorithm_id,
signing_key_psa = (psa_key_handle_t)signing_key.k.key_handle;
+#ifdef T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11
+ /* This code is for MBed Crypto 1.1. It uses an older version of
+ * the PSA Crypto API that is not compatible with the new
+ * versions. When all environments (particularly TF-M) are on the
+ * latest API, this code will no longer be necessary.
+ */
+
+ psa_key_type_t key_type;
+
psa_status_t status = psa_get_key_information(signing_key_psa,
&key_type,
&key_len_bits);
(void)key_type; /* Avoid unused parameter error */
+#else /* T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11 */
+ /* This code is for Mbed Crypto 2.0 circa 2019. The PSA Crypto API
+ * is supposed to be offically locked down in 2020 and should be
+ * very close to this, so this is likely the code to use with MBed
+ * Crypto going forward.
+ */
+
+ psa_key_attributes_t key_attributes = psa_key_attributes_init();
+
+ psa_status_t status = psa_get_key_attributes(signing_key_psa, &key_attributes);
+
+ key_len_bits = psa_get_key_bits(&key_attributes);
+
+#endif /* T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11 */
+
return_value = psa_status_to_t_cose_error_signing(status);
if(return_value == T_COSE_SUCCESS) {
/* Calculation of size per RFC 8152 section 8.1 -- round up to
@@ -299,40 +358,16 @@ psa_status_to_t_cose_error_hash(psa_status_t status)
enum t_cose_err_t t_cose_crypto_hash_start(struct t_cose_crypto_hash *hash_ctx,
int32_t cose_hash_alg_id)
{
- /* Here's how t_cose_crypto_hash is used with PSA hashes.
- *
- * If you look inside psa_hash.handle is just a uint32_t that is
- * used as a handle. To avoid modifying t_cose_crypto.h in a
- * PSA-specific way, this implementation just copies the PSA
- * handle from the generic t_cose_crypto_hash on entry to a hash
- * function, and back on exit.
- *
- * This could have been implemented by modifying t_cose_crypto.h
- * so that psa_hash_operation_t is a member of t_cose_crypto_hash.
- * It's nice to not have to modify t_cose_crypto.h.
- *
- * This would have been cleaner if psa_hash_operation_t didn't
- * exist and the PSA crypto just used a plain pointer or integer
- * handle. If psa_hash_operation_t is changed to be different
- * than just the single uint32_t, then this code has to change.
- *
- * The status member of t_cose_crypto_hash is used to hold a
- * psa_status_t error code.
- */
- psa_hash_operation_t psa_hash;
psa_algorithm_t psa_alg;
/* Map the algorithm ID */
psa_alg = cose_hash_alg_id_to_psa(cose_hash_alg_id);
/* initialize PSA hash context */
- psa_hash = (psa_hash_operation_t){0};
+ hash_ctx->ctx = psa_hash_operation_init();
/* Actually do the hash set up */
- hash_ctx->status = psa_hash_setup(&psa_hash, psa_alg);
-
- /* Copy the PSA handle back into the context */
- hash_ctx->context.handle = psa_hash.handle;
+ hash_ctx->status = psa_hash_setup(&(hash_ctx->ctx), psa_alg);
/* Map errors and return */
return psa_status_to_t_cose_error_hash((psa_status_t)hash_ctx->status);
@@ -345,12 +380,6 @@ enum t_cose_err_t t_cose_crypto_hash_start(struct t_cose_crypto_hash *hash_ctx,
void t_cose_crypto_hash_update(struct t_cose_crypto_hash *hash_ctx,
struct q_useful_buf_c data_to_hash)
{
- /* See t_cose_crypto_hash_start() for context handling details */
- psa_hash_operation_t psa_hash;
-
- /* Copy the PSA handle out of the generic context */
- psa_hash.handle = (uint32_t)hash_ctx->context.handle;
-
if(hash_ctx->status != PSA_SUCCESS) {
/* In error state. Nothing to do. */
return;
@@ -365,15 +394,9 @@ void t_cose_crypto_hash_update(struct t_cose_crypto_hash *hash_ctx,
}
/* Actually hash the data */
- hash_ctx->status = psa_hash_update(&psa_hash,
+ hash_ctx->status = psa_hash_update(&(hash_ctx->ctx),
data_to_hash.ptr,
data_to_hash.len);
-
- /* Copy the PSA handle back into the context because a non const
- * reference is passed to psa_hash_update(). If it was const, this
- * line of code could be deleted.
- */
- hash_ctx->context.handle = psa_hash.handle;
}
@@ -385,33 +408,19 @@ t_cose_crypto_hash_finish(struct t_cose_crypto_hash *hash_ctx,
struct q_useful_buf buffer_to_hold_result,
struct q_useful_buf_c *hash_result)
{
- /* See t_cose_crypto_hash_start() for context handling details */
- psa_hash_operation_t psa_hash;
- psa_status_t status;
-
- /* Copy the PSA handle out of the generic context */
- psa_hash.handle = (uint32_t)hash_ctx->context.handle;
- status = (psa_status_t)hash_ctx->status;
-
- if(status != PSA_SUCCESS) {
+ if(hash_ctx->status != PSA_SUCCESS) {
/* Error state. Nothing to do */
goto Done;
}
/* Actually finish up the hash */
- status = psa_hash_finish(&psa_hash,
- buffer_to_hold_result.ptr,
- buffer_to_hold_result.len,
- &(hash_result->len));
+ hash_ctx->status = psa_hash_finish(&(hash_ctx->ctx),
+ buffer_to_hold_result.ptr,
+ buffer_to_hold_result.len,
+ &(hash_result->len));
hash_result->ptr = buffer_to_hold_result.ptr;
- /* Copy the PSA handle back into the context because a non const
- * reference is passed to psa_hash_finish(). If it was const, this
- * line of code could be deleted.
- */
- hash_ctx->context.handle = psa_hash.handle;
-
Done:
- return psa_status_to_t_cose_error_hash(status);
+ return psa_status_to_t_cose_error_hash(hash_ctx->status);
}
diff --git a/lib/ext/t_cose/src/t_cose_crypto.h b/lib/ext/t_cose/src/t_cose_crypto.h
index 458d8dd74..ec68ae458 100644
--- a/lib/ext/t_cose/src/t_cose_crypto.h
+++ b/lib/ext/t_cose/src/t_cose_crypto.h
@@ -279,7 +279,13 @@ t_cose_crypto_pub_key_verify(int32_t cose_algorithm_id,
-#ifdef T_COSE_USE_B_CON_SHA256
+#ifdef T_COSE_USE_PSA_CRYPTO
+#include "psa/crypto.h"
+
+#elif T_COSE_USE_OPENSSL_CRYPTO
+#include "openssl/sha.h"
+
+#elif T_COSE_USE_B_CON_SHA256
/* This is code for use with Brad Conte's crypto. See
* https://github.com/B-Con/crypto-algorithms and see the description
* of t_cose_crypto_hash
@@ -287,10 +293,6 @@ t_cose_crypto_pub_key_verify(int32_t cose_algorithm_id,
#include "sha256.h"
#endif
-#ifdef T_COSE_USE_OPENSSL_CRYPTO
-#include "openssl/sha.h"
-#endif
-
/**
* The context for use with the hash adaptation layer here.
@@ -322,37 +324,50 @@ t_cose_crypto_pub_key_verify(int32_t cose_algorithm_id,
*/
struct t_cose_crypto_hash {
-#ifdef T_COSE_USE_OPENSSL_CRYPTO
- /* What is needed for a full proper integration of OpenSSL's hashes */
- /* The hash context goes on the stack. This is 224 bytes on 64-bit x86 */
- union {
- SHA256_CTX sha_256;
-#if !defined T_COSE_DISABLE_ES512 || !defined T_COSE_DISABLE_ES384
- /* SHA 384 uses the sha_512 context
- * This uses about 100 bytes above SHA-256 */
- SHA512_CTX sha_512;
-#endif
- } ctx;
-
- int update_error; /* Used to track error return by SHAXXX_Upate() */
- int32_t cose_hash_alg_id; /* COSE integer ID for the hash alg */
-
-#else
-#ifdef T_COSE_USE_B_CON_SHA256
- /* Specific context for Brad Conte's sha256.c */
- SHA256_CTX b_con_hash_context;
-#else
- /*
- * Generic pointer / handle that can work for many
- * hash implementations.
- */
- union {
- void *ptr;
- uint64_t handle;
- } context;
- int64_t status;
-#endif
-#endif
+ #ifdef T_COSE_USE_PSA_CRYPTO
+ /* --- The context for PSA Crypto (MBed Crypto) --- */
+
+ /* psa_hash_operation_t actually varied by the implementation of
+ * the crypto library. Sometimes the implementation is inline and
+ * thus the context is a few hundred bytes, sometimes it is not.
+ * This varies by what is in crypto_struct.h (which is not quite
+ * a public interface).
+ *
+ * This can be made smaller for PSA implementations that work inline
+ * by disabling the larger algorithms using PSA / MBed configuration.
+ */
+ psa_hash_operation_t ctx;
+ psa_status_t status;
+
+ #elif T_COSE_USE_OPENSSL_CRYPTO
+ /* --- The context for PSA Crypto (MBed Crypto) --- */
+
+ /* What is needed for a full proper integration of OpenSSL's hashes */
+ union {
+ SHA256_CTX sha_256;
+ #if !defined T_COSE_DISABLE_ES512 || !defined T_COSE_DISABLE_ES384
+ /* SHA 384 uses the sha_512 context
+ * This uses about 100 bytes above SHA-256 */
+ SHA512_CTX sha_512;
+ #endif
+ } ctx;
+
+ int update_error; /* Used to track error return by SHAXXX_Upate() */
+ int32_t cose_hash_alg_id; /* COSE integer ID for the hash alg */
+
+ #elif T_COSE_USE_B_CON_SHA256
+ /* --- Specific context for Brad Conte's sha256.c --- */
+ SHA256_CTX b_con_hash_context;
+
+ #else
+ /* --- Default: generic pointer / handle --- */
+
+ union {
+ void *ptr;
+ uint64_t handle;
+ } context;
+ int64_t status;
+ #endif
};
diff --git a/lib/ext/t_cose/test/t_cose_make_psa_test_key.c b/lib/ext/t_cose/test/t_cose_make_psa_test_key.c
index 51330297f..a58c6c989 100644
--- a/lib/ext/t_cose/test/t_cose_make_psa_test_key.c
+++ b/lib/ext/t_cose/test/t_cose_make_psa_test_key.c
@@ -10,13 +10,29 @@
#include "t_cose_make_test_pub_key.h" /* The interface implemented here */
-
#include "t_cose_standard_constants.h"
-
-#include "psa/crypto_types.h"
#include "psa/crypto.h"
+/* Here's the auto-detect and manual override logic for managing PSA
+ * Crypto API compatibility.
+ *
+ * PSA_GENERATOR_UNBRIDLED_CAPACITY happens to be defined in MBed
+ * Crypto 1.1 and not in MBed Crypto 2.0 so it is what auto-detect
+ * hinges off of.
+ *
+ * T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO20 can be defined to force
+ * setting to MBed Crypto 2.0
+ *
+ * T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11 can be defined to force
+ * setting to MBed Crypt 1.1. It is also what the code below hinges
+ * on.
+ */
+#if defined(PSA_GENERATOR_UNBRIDLED_CAPACITY) && !defined(T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO20)
+#define T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11
+#endif
+
+
/*
* Some hard coded keys for the test cases here.
*/
@@ -47,10 +63,9 @@ enum t_cose_err_t make_ecdsa_key_pair(int32_t cose_algorithm_id,
struct t_cose_key *key_pair)
{
psa_key_type_t key_type;
- psa_status_t crypto_res;
+ psa_status_t crypto_result;
psa_key_handle_t key_handle;
- psa_key_policy_t policy;
- psa_key_usage_t key_usage;
+ psa_algorithm_t key_alg;
const uint8_t *private_key;
size_t private_key_len;
@@ -62,59 +77,110 @@ enum t_cose_err_t make_ecdsa_key_pair(int32_t cose_algorithm_id,
* there is usually an obvious curve for an algorithm. That
* is what this does.
*/
- switch(cose_algorithm_id) {
+
+ #ifdef T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11
+ #define PSA_KEY_TYPE_ECC_KEY_PAIR PSA_KEY_TYPE_ECC_KEYPAIR
+ #endif /* T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11 */
+
+ switch(cose_algorithm_id) {
case COSE_ALGORITHM_ES256:
private_key = private_key_256;
private_key_len = sizeof(private_key_256);
- key_type = PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1);
- key_usage = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
+ key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1);
+ key_alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
break;
case COSE_ALGORITHM_ES384:
private_key = private_key_384;
private_key_len = sizeof(private_key_384);
- key_type = PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP384R1);
- key_usage = PSA_ALG_ECDSA(PSA_ALG_SHA_384);
+ key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP384R1);
+ key_alg = PSA_ALG_ECDSA(PSA_ALG_SHA_384);
break;
case COSE_ALGORITHM_ES512:
private_key = private_key_521;
private_key_len = sizeof(private_key_521);
- key_type = PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP521R1);
- key_usage = PSA_ALG_ECDSA(PSA_ALG_SHA_512);
+ key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP521R1);
+ key_alg = PSA_ALG_ECDSA(PSA_ALG_SHA_512);
break;
default:
return T_COSE_ERR_UNSUPPORTED_SIGNING_ALG;
}
+
+ psa_crypto_init(); /* OK to call this multiple times */
+
+ /* When importing a key with the PSA API there are two main
+ * things to do.
+ *
+ * First you must tell it what type of key it is as this
+ * cannot be discovered from the raw data. The variable
+ * key_type contains that information including the EC curve. This is sufficient
+ * for psa_import_key() to succeed, but you probably want
+ * actually use the key.
+ *
+ * Second, you must say what algorithm(s) and operations
+ * the key can be used as the PSA Crypto Library has
+ * policy enforcement.
+ *
+ * How this is done varies quite a lot in the newer
+ * PSA Crypto API compared to the older.
+ */
+
+#ifdef T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11
/* Allocate for the key pair in the Crypto service */
- crypto_res = psa_allocate_key(&key_handle);
- if (crypto_res != PSA_SUCCESS) {
+ crypto_result = psa_allocate_key(&key_handle);
+ if (crypto_result != PSA_SUCCESS) {
return T_COSE_ERR_FAIL;
}
- /* Setup the key policy for private key */
- policy = psa_key_policy_init();
+ /* Say what algorithm and operations the key can be used with / for */
+ psa_key_policy_t policy = psa_key_policy_init();
psa_key_policy_set_usage(&policy,
- PSA_KEY_USAGE_SIGN,
- key_usage);
- crypto_res = psa_set_key_policy(key_handle, &policy);
- if (crypto_res != PSA_SUCCESS) {
+ PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
+ key_alg);
+ crypto_result = psa_set_key_policy(key_handle, &policy);
+ if (crypto_result != PSA_SUCCESS) {
return T_COSE_ERR_FAIL;
}
- /* Import the private key. psa_import_key() automatically generates
- * the public key from the private so no need to import more than
- * the private key. (With ECDSA the public key is always
+ /* Import the private key. psa_import_key() automatically
+ * generates the public key from the private so no need to import
+ * more than the private key. (With ECDSA the public key is always
+ * deterministically derivable from the private key).
+ */
+ /* key_type has the type of key including the EC curve */
+ crypto_result = psa_import_key(key_handle,
+ key_type,
+ private_key,
+ private_key_len);
+
+#else /* T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11 */
+ psa_key_attributes_t key_attributes;
+
+ key_attributes = psa_key_attributes_init();
+
+ /* Say what algorithm and operations the key can be used with / for */
+ psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
+ psa_set_key_algorithm(&key_attributes, key_alg);
+
+ /* The type of key including the EC curve */
+ psa_set_key_type(&key_attributes, key_type);
+
+ /* Import the private key. psa_import_key() automatically
+ * generates the public key from the private so no need to import
+ * more than the private key. (With ECDSA the public key is always
* deterministically derivable from the private key).
*/
- crypto_res = psa_import_key(key_handle,
- key_type,
- private_key,
- sizeof(private_key));
+ crypto_result = psa_import_key(&key_attributes,
+ private_key,
+ private_key_len,
+ &key_handle);
+
+#endif /* T_COSE_USE_PSA_CRYPTO_FROM_MBED_CRYPTO11 */
- if (crypto_res != PSA_SUCCESS) {
+ if (crypto_result != PSA_SUCCESS) {
return T_COSE_ERR_FAIL;
}
@@ -130,6 +196,6 @@ enum t_cose_err_t make_ecdsa_key_pair(int32_t cose_algorithm_id,
*/
void free_ecdsa_key_pair(struct t_cose_key key_pair)
{
- psa_destroy_key(key_pair.k.key_handle);
+ psa_close_key(key_pair.k.key_handle);
}