1 /*
2 * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <string.h>
11 #include "config_crypto.h"
12 #include "tfm_sp_log.h"
13
14 #include "tfm_mbedcrypto_include.h"
15
16 #include "tfm_crypto_api.h"
17 #include "tfm_crypto_defs.h"
18
19 #ifndef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
20 #error "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER must be selected in Mbed TLS config file"
21 #endif
22
23 /*!
24 * \addtogroup tfm_crypto_api_shim_layer
25 *
26 */
27
28 /*!@{*/
29 #if CRYPTO_KEY_DERIVATION_MODULE_ENABLED
tfm_crypto_key_derivation_interface(psa_invec in_vec[],psa_outvec out_vec[],mbedtls_svc_key_id_t * encoded_key)30 psa_status_t tfm_crypto_key_derivation_interface(psa_invec in_vec[],
31 psa_outvec out_vec[],
32 mbedtls_svc_key_id_t *encoded_key)
33 {
34 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
35 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
36 psa_key_derivation_operation_t *operation = NULL;
37 uint32_t *p_handle = NULL;
38 uint16_t sid = iov->function_id;
39
40 if (sid == TFM_CRYPTO_RAW_KEY_AGREEMENT_SID) {
41 uint8_t *output = out_vec[0].base;
42 size_t output_size = out_vec[0].len;
43 const uint8_t *peer_key = in_vec[1].base;
44 size_t peer_key_length = in_vec[1].len;
45
46 return psa_raw_key_agreement(iov->alg, *encoded_key,
47 peer_key, peer_key_length,
48 output, output_size, &out_vec[0].len);
49 }
50
51 if (sid == TFM_CRYPTO_KEY_DERIVATION_SETUP_SID) {
52 p_handle = out_vec[0].base;
53 *p_handle = iov->op_handle;
54 status = tfm_crypto_operation_alloc(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
55 out_vec[0].base,
56 (void **)&operation);
57 } else {
58 status = tfm_crypto_operation_lookup(
59 TFM_CRYPTO_KEY_DERIVATION_OPERATION,
60 iov->op_handle,
61 (void **)&operation);
62 }
63 if ((status != PSA_SUCCESS) &&
64 (sid != TFM_CRYPTO_KEY_DERIVATION_ABORT_SID)) {
65 return status;
66 }
67
68 switch (sid) {
69 case TFM_CRYPTO_KEY_DERIVATION_SETUP_SID:
70 {
71 status = psa_key_derivation_setup(operation, iov->alg);
72
73 if (status != PSA_SUCCESS) {
74 goto release_operation_and_return;
75 }
76 }
77 break;
78 case TFM_CRYPTO_KEY_DERIVATION_GET_CAPACITY_SID:
79 {
80 size_t *capacity = out_vec[0].base;
81
82 return psa_key_derivation_get_capacity(operation, capacity);
83 }
84 case TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY_SID:
85 {
86 return psa_key_derivation_set_capacity(operation, iov->capacity);
87 }
88 case TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES_SID:
89 {
90 const uint8_t *data = in_vec[1].base;
91 size_t data_length = in_vec[1].len;
92
93 return psa_key_derivation_input_bytes(operation, iov->step, data,
94 data_length);
95 }
96 case TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES_SID:
97 {
98 uint8_t *output = out_vec[0].base;
99 size_t output_length = out_vec[0].len;
100
101 return psa_key_derivation_output_bytes(operation,
102 output, output_length);
103 }
104 case TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY_SID:
105 {
106 return psa_key_derivation_input_key(operation,
107 iov->step, *encoded_key);
108 }
109 case TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY_SID:
110 {
111 const struct psa_client_key_attributes_s *client_key_attr =
112 in_vec[1].base;
113 psa_key_id_t *key_handle = out_vec[0].base;
114 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
115 int32_t partition_id = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(*encoded_key);
116
117 status = tfm_crypto_key_attributes_from_client(client_key_attr,
118 partition_id,
119 &key_attributes);
120 if (status != PSA_SUCCESS) {
121 return status;
122 }
123
124 status = psa_key_derivation_output_key(&key_attributes, operation,
125 encoded_key);
126
127 *key_handle = encoded_key->MBEDTLS_PRIVATE(key_id);
128 }
129 break;
130 case TFM_CRYPTO_KEY_DERIVATION_ABORT_SID:
131 {
132 p_handle = out_vec[0].base;
133 *p_handle = iov->op_handle;
134 if (status != PSA_SUCCESS) {
135 /*
136 * If lookup() failed to find out a valid operation, it is not
137 * an error for _abort(), as it is allowed to be called multiple
138 * times, and it is likely the operation has just already been
139 * aborted.
140 */
141 return PSA_SUCCESS;
142 }
143
144 status = psa_key_derivation_abort(operation);
145
146 goto release_operation_and_return;
147 }
148 case TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_SID:
149 {
150 const uint8_t *peer_key = in_vec[1].base;
151 size_t peer_key_length = in_vec[1].len;
152
153 return psa_key_derivation_key_agreement(operation, iov->step,
154 *encoded_key,
155 peer_key,
156 peer_key_length);
157 }
158 break;
159 default:
160 return PSA_ERROR_NOT_SUPPORTED;
161 }
162
163 return status;
164
165 release_operation_and_return:
166 /* Release the operation context, ignore if the operation fails. */
167 (void)tfm_crypto_operation_release(p_handle);
168 return status;
169 }
170 #else /* CRYPTO_KEY_DERIVATION_MODULE_ENABLED */
tfm_crypto_key_derivation_interface(psa_invec in_vec[],psa_outvec out_vec[],mbedtls_svc_key_id_t * encoded_key)171 psa_status_t tfm_crypto_key_derivation_interface(psa_invec in_vec[],
172 psa_outvec out_vec[],
173 mbedtls_svc_key_id_t *encoded_key)
174 {
175 (void)in_vec;
176 (void)out_vec;
177 (void)encoded_key;
178
179 return PSA_ERROR_NOT_SUPPORTED;
180 }
181 #endif /* CRYPTO_KEY_DERIVATION_MODULE_ENABLED */
182 /*!@}*/
183