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