blob: f12254296e10c20cf098c74675e2acf4ea861043 [file] [log] [blame]
Tamas Ban28aeec32019-01-09 16:53:26 +00001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include "attestation_key.h"
9#include <stdint.h>
10#include <stddef.h>
Tamas Ban28aeec32019-01-09 16:53:26 +000011#include "psa_initial_attestation_api.h"
12#include "platform/include/tfm_plat_defs.h"
13#include "platform/include/tfm_plat_crypto_keys.h"
14
15/*!
16 * \var private_key_registered
17 *
18 * \brief Indicates whether the private part of the attestation key pair was
Tamas Ban6c08f9d2019-05-09 08:43:29 +010019 * registered to Crypto service or not.
Tamas Ban28aeec32019-01-09 16:53:26 +000020 */
21static uint32_t private_key_registered = 0;
22
Tamas Ban28aeec32019-01-09 16:53:26 +000023/**
24 * \brief Map the curve type definition by RFC8152 (COSE) to PSA curve types
25 *
26 * \param[in] cose_curve COSE curve type definition \ref ecc_curve_t.
27 *
28 * \return Return PSA curve type according to \ref psa_ecc_curve_t. If
29 * mapping is not possible then return with USHRT_MAX.
30 */
31static inline psa_ecc_curve_t
32attest_map_elliptic_curve_type(enum ecc_curve_t cose_curve)
33{
34 psa_ecc_curve_t psa_curve;
35
36 /*FixMe: Mapping is not complete, missing ones: ED25519, ED448 */
37 switch (cose_curve) {
38 case P_256:
39 psa_curve = PSA_ECC_CURVE_SECP256R1;
40 break;
41 case P_384:
42 psa_curve = PSA_ECC_CURVE_SECP384R1;
43 break;
44 case P_521:
45 psa_curve = PSA_ECC_CURVE_SECP521R1;
46 break;
47 case X25519:
48 psa_curve = PSA_ECC_CURVE_CURVE25519;
49 break;
50 case X448:
51 psa_curve = PSA_ECC_CURVE_CURVE448;
52 break;
53 default:
54 psa_curve = USHRT_MAX;
55 }
56
57 return psa_curve;
58}
59
60enum psa_attest_err_t
Tamas Ban6c08f9d2019-05-09 08:43:29 +010061attest_register_initial_attestation_private_key(psa_key_handle_t *private_key)
Tamas Ban28aeec32019-01-09 16:53:26 +000062{
63 enum tfm_plat_err_t plat_res;
64 psa_ecc_curve_t psa_curve;
65 enum ecc_curve_t cose_curve;
66 struct ecc_key_t attest_key = {0};
67 uint8_t key_buf[ECC_P_256_KEY_SIZE];
68 psa_key_type_t attest_key_type;
Tamas Ban28aeec32019-01-09 16:53:26 +000069 psa_status_t crypto_res;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010070 psa_key_policy_t policy = psa_key_policy_init();
Tamas Ban28aeec32019-01-09 16:53:26 +000071
Tamas Ban6c08f9d2019-05-09 08:43:29 +010072 /* Private key should be unregistered at this point */
73 if (private_key_registered != 0) {
Tamas Ban28aeec32019-01-09 16:53:26 +000074 return PSA_ATTEST_ERR_GENERAL;
75 }
76
Antonio de Angelis3a97d862019-04-25 10:46:05 +010077 /* Allocate a transient key for the private key in the Crypto service */
Tamas Ban6c08f9d2019-05-09 08:43:29 +010078 crypto_res = psa_allocate_key(private_key);
Antonio de Angelis3a97d862019-04-25 10:46:05 +010079 if (crypto_res != PSA_SUCCESS) {
80 return PSA_ATTEST_ERR_GENERAL;
81 }
82
Tamas Ban28aeec32019-01-09 16:53:26 +000083 /* Get the initial attestation key */
84 plat_res = tfm_plat_get_initial_attest_key(key_buf, sizeof(key_buf),
85 &attest_key, &cose_curve);
86
87 /* Check the availability of the private key */
88 if (plat_res != TFM_PLAT_ERR_SUCCESS || attest_key.priv_key == NULL) {
89 return PSA_ATTEST_ERR_GENERAL;
90 }
91
92 /* Mapping of COSE curve type to PSA curve types */
93 psa_curve = attest_map_elliptic_curve_type(cose_curve);
94 if (psa_curve == USHRT_MAX) {
95 return PSA_ATTEST_ERR_GENERAL;
96 }
97
98 /* Setup the key policy for private key */
Tamas Ban6c08f9d2019-05-09 08:43:29 +010099 psa_key_policy_set_usage(&policy,
100 PSA_KEY_USAGE_SIGN,
101 PSA_ALG_ECDSA(PSA_ALG_SHA_256));
102 crypto_res = psa_set_key_policy(*private_key, &policy);
Tamas Ban28aeec32019-01-09 16:53:26 +0000103 if (crypto_res != PSA_SUCCESS) {
104 return PSA_ATTEST_ERR_GENERAL;
105 }
106
107 /* Set key type for private key */
Tamas Ban6c08f9d2019-05-09 08:43:29 +0100108 attest_key_type = PSA_KEY_TYPE_ECC_KEYPAIR(psa_curve);
Tamas Ban28aeec32019-01-09 16:53:26 +0000109
Tamas Ban6c08f9d2019-05-09 08:43:29 +0100110 /* Register private key to Crypto service */
111 crypto_res = psa_import_key(*private_key,
Tamas Ban28aeec32019-01-09 16:53:26 +0000112 attest_key_type,
113 attest_key.priv_key,
114 attest_key.priv_key_size);
115
116 if (crypto_res != PSA_SUCCESS) {
117 return PSA_ATTEST_ERR_GENERAL;
118 }
119 private_key_registered = 1;
120
Tamas Ban28aeec32019-01-09 16:53:26 +0000121 return PSA_ATTEST_ERR_SUCCESS;
122}
123
124enum psa_attest_err_t
Tamas Ban6c08f9d2019-05-09 08:43:29 +0100125attest_unregister_initial_attestation_private_key(psa_key_handle_t private_key)
Tamas Ban28aeec32019-01-09 16:53:26 +0000126{
127 psa_status_t crypto_res;
128
Tamas Ban6c08f9d2019-05-09 08:43:29 +0100129 /* Private key must be registered at this point */
Tamas Ban28aeec32019-01-09 16:53:26 +0000130 if (private_key_registered != 1) {
131 return PSA_ATTEST_ERR_GENERAL;
132 }
133
Tamas Ban6c08f9d2019-05-09 08:43:29 +0100134 crypto_res = psa_destroy_key(private_key);
Tamas Ban28aeec32019-01-09 16:53:26 +0000135 if (crypto_res != PSA_SUCCESS) {
136 return PSA_ATTEST_ERR_GENERAL;
137 }
138 private_key_registered = 0;
139
Tamas Ban28aeec32019-01-09 16:53:26 +0000140 return PSA_ATTEST_ERR_SUCCESS;
141}