blob: 386ac2098be5cba5c6b5649d3902a4a4861f2280 [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>
11#include "tfm_crypto_defs.h"
12#include "psa_crypto.h"
13#include "psa_crypto_platform.h"
14#include "psa_initial_attestation_api.h"
15#include "platform/include/tfm_plat_defs.h"
16#include "platform/include/tfm_plat_crypto_keys.h"
17
18/*!
19 * \var private_key_registered
20 *
21 * \brief Indicates whether the private part of the attestation key pair was
22 * registered to crypto service or not.
23 */
24static uint32_t private_key_registered = 0;
25
26/*!
27 * \var public_key_registered
28 *
29 * \brief Indicates whether the public part of the attestation key pair was
30 * registered to crypto service or not.
31 */
32static uint32_t public_key_registered = 0;
33
34/**
35 * \brief Map the curve type definition by RFC8152 (COSE) to PSA curve types
36 *
37 * \param[in] cose_curve COSE curve type definition \ref ecc_curve_t.
38 *
39 * \return Return PSA curve type according to \ref psa_ecc_curve_t. If
40 * mapping is not possible then return with USHRT_MAX.
41 */
42static inline psa_ecc_curve_t
43attest_map_elliptic_curve_type(enum ecc_curve_t cose_curve)
44{
45 psa_ecc_curve_t psa_curve;
46
47 /*FixMe: Mapping is not complete, missing ones: ED25519, ED448 */
48 switch (cose_curve) {
49 case P_256:
50 psa_curve = PSA_ECC_CURVE_SECP256R1;
51 break;
52 case P_384:
53 psa_curve = PSA_ECC_CURVE_SECP384R1;
54 break;
55 case P_521:
56 psa_curve = PSA_ECC_CURVE_SECP521R1;
57 break;
58 case X25519:
59 psa_curve = PSA_ECC_CURVE_CURVE25519;
60 break;
61 case X448:
62 psa_curve = PSA_ECC_CURVE_CURVE448;
63 break;
64 default:
65 psa_curve = USHRT_MAX;
66 }
67
68 return psa_curve;
69}
70
71enum psa_attest_err_t
72attest_register_initial_attestation_key(void)
73{
74 enum tfm_plat_err_t plat_res;
75 psa_ecc_curve_t psa_curve;
76 enum ecc_curve_t cose_curve;
77 struct ecc_key_t attest_key = {0};
78 uint8_t key_buf[ECC_P_256_KEY_SIZE];
79 psa_key_type_t attest_key_type;
80 size_t public_key_size;
81 psa_status_t crypto_res;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010082 psa_key_policy_t policy = psa_key_policy_init();
Tamas Ban28aeec32019-01-09 16:53:26 +000083
84 /* Key(s) should be unregistered at this point */
85 if (private_key_registered != 0 || public_key_registered != 0) {
86 return PSA_ATTEST_ERR_GENERAL;
87 }
88
89 /* Get the initial attestation key */
90 plat_res = tfm_plat_get_initial_attest_key(key_buf, sizeof(key_buf),
91 &attest_key, &cose_curve);
92
93 /* Check the availability of the private key */
94 if (plat_res != TFM_PLAT_ERR_SUCCESS || attest_key.priv_key == NULL) {
95 return PSA_ATTEST_ERR_GENERAL;
96 }
97
98 /* Mapping of COSE curve type to PSA curve types */
99 psa_curve = attest_map_elliptic_curve_type(cose_curve);
100 if (psa_curve == USHRT_MAX) {
101 return PSA_ATTEST_ERR_GENERAL;
102 }
103
104 /* Setup the key policy for private key */
Tamas Ban28aeec32019-01-09 16:53:26 +0000105 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_SIGN, 0); /* FixMe: alg */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100106 crypto_res = psa_set_key_policy((psa_key_handle_t)ATTEST_PRIVATE_KEY_SLOT,
Tamas Ban28aeec32019-01-09 16:53:26 +0000107 &policy);
108 if (crypto_res != PSA_SUCCESS) {
109 return PSA_ATTEST_ERR_GENERAL;
110 }
111
112 /* Set key type for private key */
113 /* FixMe: Use PSA_KEY_TYPE_ECC_KEYPAIR(psa_curve) when ECC key type will be
114 * supported in Crypto service
115 */
116 attest_key_type = PSA_KEY_TYPE_RAW_DATA;
117
118 /* Register private key to crypto service */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100119 crypto_res = psa_import_key((psa_key_handle_t)ATTEST_PRIVATE_KEY_SLOT,
Tamas Ban28aeec32019-01-09 16:53:26 +0000120 attest_key_type,
121 attest_key.priv_key,
122 attest_key.priv_key_size);
123
124 if (crypto_res != PSA_SUCCESS) {
125 return PSA_ATTEST_ERR_GENERAL;
126 }
127 private_key_registered = 1;
128
129 /* Check whether public key is available, not mandatory */
130 if (attest_key.pubx_key == NULL) {
131 return PSA_ATTEST_ERR_SUCCESS;
132 }
133
134 /* Setup the key policy for public key */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100135 policy = psa_key_policy_init();
Tamas Ban28aeec32019-01-09 16:53:26 +0000136 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_VERIFY, 0); /* FixMe: alg */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100137 crypto_res = psa_set_key_policy((psa_key_handle_t)ATTEST_PUBLIC_KEY_SLOT,
Tamas Ban28aeec32019-01-09 16:53:26 +0000138 &policy);
139 if (crypto_res != PSA_SUCCESS) {
140 return PSA_ATTEST_ERR_GENERAL;
141 }
142
143 /* Set key type for public key */
144 /* FixMe: Use PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_curve) when ECC key type will
145 * be supported in Crypto service
146 */
147 attest_key_type = PSA_KEY_TYPE_RAW_DATA;
148
149 /* Register public key to crypto service */
150 public_key_size = attest_key.pubx_key_size + attest_key.puby_key_size;
151
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100152 crypto_res = psa_import_key((psa_key_handle_t)ATTEST_PUBLIC_KEY_SLOT,
Tamas Ban28aeec32019-01-09 16:53:26 +0000153 attest_key_type,
154 attest_key.pubx_key,
155 public_key_size);
156
157 if (crypto_res != PSA_SUCCESS) {
158 return PSA_ATTEST_ERR_GENERAL;
159 }
160 public_key_registered = 1;
161
162 return PSA_ATTEST_ERR_SUCCESS;
163}
164
165enum psa_attest_err_t
166attest_unregister_initial_attestation_key(void)
167{
168 psa_status_t crypto_res;
169
170 /* Only private key is mandatory */
171 if (private_key_registered != 1) {
172 return PSA_ATTEST_ERR_GENERAL;
173 }
174
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100175 crypto_res = psa_destroy_key((psa_key_handle_t)ATTEST_PRIVATE_KEY_SLOT);
Tamas Ban28aeec32019-01-09 16:53:26 +0000176 if (crypto_res != PSA_SUCCESS) {
177 return PSA_ATTEST_ERR_GENERAL;
178 }
179 private_key_registered = 0;
180
181 if (public_key_registered) {
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100182 crypto_res = psa_destroy_key((psa_key_handle_t)ATTEST_PUBLIC_KEY_SLOT);
Tamas Ban28aeec32019-01-09 16:53:26 +0000183 if (crypto_res != PSA_SUCCESS) {
184 return PSA_ATTEST_ERR_GENERAL;
185 }
186 public_key_registered = 0;
187 }
188
189 return PSA_ATTEST_ERR_SUCCESS;
190}