blob: a2ad1de24dad60ac5c8d5ee6fd3038fdc10c097b [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
19 * registered to crypto service or not.
20 */
21static uint32_t private_key_registered = 0;
22
23/*!
24 * \var public_key_registered
25 *
26 * \brief Indicates whether the public part of the attestation key pair was
27 * registered to crypto service or not.
28 */
29static uint32_t public_key_registered = 0;
30
31/**
32 * \brief Map the curve type definition by RFC8152 (COSE) to PSA curve types
33 *
34 * \param[in] cose_curve COSE curve type definition \ref ecc_curve_t.
35 *
36 * \return Return PSA curve type according to \ref psa_ecc_curve_t. If
37 * mapping is not possible then return with USHRT_MAX.
38 */
39static inline psa_ecc_curve_t
40attest_map_elliptic_curve_type(enum ecc_curve_t cose_curve)
41{
42 psa_ecc_curve_t psa_curve;
43
44 /*FixMe: Mapping is not complete, missing ones: ED25519, ED448 */
45 switch (cose_curve) {
46 case P_256:
47 psa_curve = PSA_ECC_CURVE_SECP256R1;
48 break;
49 case P_384:
50 psa_curve = PSA_ECC_CURVE_SECP384R1;
51 break;
52 case P_521:
53 psa_curve = PSA_ECC_CURVE_SECP521R1;
54 break;
55 case X25519:
56 psa_curve = PSA_ECC_CURVE_CURVE25519;
57 break;
58 case X448:
59 psa_curve = PSA_ECC_CURVE_CURVE448;
60 break;
61 default:
62 psa_curve = USHRT_MAX;
63 }
64
65 return psa_curve;
66}
67
68enum psa_attest_err_t
Antonio de Angelis3a97d862019-04-25 10:46:05 +010069attest_register_initial_attestation_key(psa_key_handle_t *key_handle_private,
70 psa_key_handle_t *key_handle_public)
Tamas Ban28aeec32019-01-09 16:53:26 +000071{
72 enum tfm_plat_err_t plat_res;
73 psa_ecc_curve_t psa_curve;
74 enum ecc_curve_t cose_curve;
75 struct ecc_key_t attest_key = {0};
76 uint8_t key_buf[ECC_P_256_KEY_SIZE];
77 psa_key_type_t attest_key_type;
78 size_t public_key_size;
79 psa_status_t crypto_res;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010080 psa_key_policy_t policy = psa_key_policy_init();
Tamas Ban28aeec32019-01-09 16:53:26 +000081
82 /* Key(s) should be unregistered at this point */
83 if (private_key_registered != 0 || public_key_registered != 0) {
84 return PSA_ATTEST_ERR_GENERAL;
85 }
86
Antonio de Angelis3a97d862019-04-25 10:46:05 +010087 /* Allocate a transient key for the private key in the Crypto service */
88 crypto_res = psa_allocate_key(key_handle_private);
89 if (crypto_res != PSA_SUCCESS) {
90 return PSA_ATTEST_ERR_GENERAL;
91 }
92
Tamas Ban28aeec32019-01-09 16:53:26 +000093 /* Get the initial attestation key */
94 plat_res = tfm_plat_get_initial_attest_key(key_buf, sizeof(key_buf),
95 &attest_key, &cose_curve);
96
97 /* Check the availability of the private key */
98 if (plat_res != TFM_PLAT_ERR_SUCCESS || attest_key.priv_key == NULL) {
99 return PSA_ATTEST_ERR_GENERAL;
100 }
101
102 /* Mapping of COSE curve type to PSA curve types */
103 psa_curve = attest_map_elliptic_curve_type(cose_curve);
104 if (psa_curve == USHRT_MAX) {
105 return PSA_ATTEST_ERR_GENERAL;
106 }
107
108 /* Setup the key policy for private key */
Tamas Ban28aeec32019-01-09 16:53:26 +0000109 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_SIGN, 0); /* FixMe: alg */
Antonio de Angelis3a97d862019-04-25 10:46:05 +0100110 crypto_res = psa_set_key_policy(*key_handle_private, &policy);
Tamas Ban28aeec32019-01-09 16:53:26 +0000111 if (crypto_res != PSA_SUCCESS) {
112 return PSA_ATTEST_ERR_GENERAL;
113 }
114
115 /* Set key type for private key */
116 /* FixMe: Use PSA_KEY_TYPE_ECC_KEYPAIR(psa_curve) when ECC key type will be
117 * supported in Crypto service
118 */
119 attest_key_type = PSA_KEY_TYPE_RAW_DATA;
120
121 /* Register private key to crypto service */
Antonio de Angelis3a97d862019-04-25 10:46:05 +0100122 crypto_res = psa_import_key(*key_handle_private,
Tamas Ban28aeec32019-01-09 16:53:26 +0000123 attest_key_type,
124 attest_key.priv_key,
125 attest_key.priv_key_size);
126
127 if (crypto_res != PSA_SUCCESS) {
128 return PSA_ATTEST_ERR_GENERAL;
129 }
130 private_key_registered = 1;
131
Antonio de Angelis3a97d862019-04-25 10:46:05 +0100132 /* Allocate a transient key for the public key in the Crypto service */
133 crypto_res = psa_allocate_key(key_handle_public);
134 if (crypto_res != PSA_SUCCESS) {
135 return PSA_ATTEST_ERR_GENERAL;
136 }
137
Tamas Ban28aeec32019-01-09 16:53:26 +0000138 /* Check whether public key is available, not mandatory */
139 if (attest_key.pubx_key == NULL) {
140 return PSA_ATTEST_ERR_SUCCESS;
141 }
142
143 /* Setup the key policy for public key */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100144 policy = psa_key_policy_init();
Tamas Ban28aeec32019-01-09 16:53:26 +0000145 psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_VERIFY, 0); /* FixMe: alg */
Antonio de Angelis3a97d862019-04-25 10:46:05 +0100146 crypto_res = psa_set_key_policy(*key_handle_public, &policy);
Tamas Ban28aeec32019-01-09 16:53:26 +0000147 if (crypto_res != PSA_SUCCESS) {
148 return PSA_ATTEST_ERR_GENERAL;
149 }
150
151 /* Set key type for public key */
152 /* FixMe: Use PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_curve) when ECC key type will
153 * be supported in Crypto service
154 */
155 attest_key_type = PSA_KEY_TYPE_RAW_DATA;
156
157 /* Register public key to crypto service */
158 public_key_size = attest_key.pubx_key_size + attest_key.puby_key_size;
159
Antonio de Angelis3a97d862019-04-25 10:46:05 +0100160 crypto_res = psa_import_key(*key_handle_public,
Tamas Ban28aeec32019-01-09 16:53:26 +0000161 attest_key_type,
162 attest_key.pubx_key,
163 public_key_size);
164
165 if (crypto_res != PSA_SUCCESS) {
166 return PSA_ATTEST_ERR_GENERAL;
167 }
168 public_key_registered = 1;
169
170 return PSA_ATTEST_ERR_SUCCESS;
171}
172
173enum psa_attest_err_t
Antonio de Angelis3a97d862019-04-25 10:46:05 +0100174attest_unregister_initial_attestation_key(psa_key_handle_t key_handle_private,
175 psa_key_handle_t key_handle_public)
Tamas Ban28aeec32019-01-09 16:53:26 +0000176{
177 psa_status_t crypto_res;
178
179 /* Only private key is mandatory */
180 if (private_key_registered != 1) {
181 return PSA_ATTEST_ERR_GENERAL;
182 }
183
Antonio de Angelis3a97d862019-04-25 10:46:05 +0100184 crypto_res = psa_destroy_key(key_handle_private);
Tamas Ban28aeec32019-01-09 16:53:26 +0000185 if (crypto_res != PSA_SUCCESS) {
186 return PSA_ATTEST_ERR_GENERAL;
187 }
188 private_key_registered = 0;
189
190 if (public_key_registered) {
Antonio de Angelis3a97d862019-04-25 10:46:05 +0100191 crypto_res = psa_destroy_key(key_handle_public);
Tamas Ban28aeec32019-01-09 16:53:26 +0000192 if (crypto_res != PSA_SUCCESS) {
193 return PSA_ATTEST_ERR_GENERAL;
194 }
195 public_key_registered = 0;
196 }
197
198 return PSA_ATTEST_ERR_SUCCESS;
199}