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