1 /*
2  * Copyright (c) 2021-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 
12 #include "config_tfm.h"
13 #include "tfm_mbedcrypto_include.h"
14 #include "tfm_crypto_api.h"
15 #include "tfm_crypto_key.h"
16 #include "tfm_crypto_defs.h"
17 
18 #include "crypto_library.h"
19 
20 /*!
21  * \addtogroup tfm_crypto_api_shim_layer
22  *
23  */
24 
25 /*!@{*/
26 #if CRYPTO_KEY_MODULE_ENABLED
tfm_crypto_key_management_interface(psa_invec in_vec[],psa_outvec out_vec[],struct tfm_crypto_key_id_s * encoded_key)27 psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
28                                                  psa_outvec out_vec[],
29                                                  struct tfm_crypto_key_id_s *encoded_key)
30 {
31     const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
32     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
33     /* Build a key_id in the library key format, i.e. (owner, key_id) */
34     tfm_crypto_library_key_id_t library_key = tfm_crypto_library_key_id_init(
35                                                   encoded_key->owner, encoded_key->key_id);
36     psa_key_attributes_t srv_key_attr;
37 
38     switch (iov->function_id) {
39     case TFM_CRYPTO_IMPORT_KEY_SID:
40     case TFM_CRYPTO_COPY_KEY_SID:
41     case TFM_CRYPTO_GENERATE_KEY_SID:
42         memcpy(&srv_key_attr, in_vec[1].base, in_vec[1].len);
43         tfm_crypto_library_get_library_key_id_set_owner(encoded_key->owner, &srv_key_attr);
44         break;
45     default:
46         break;
47     }
48 
49     switch (iov->function_id) {
50     case TFM_CRYPTO_IMPORT_KEY_SID:
51     {
52         const uint8_t *data = in_vec[2].base;
53         size_t data_length = in_vec[2].len;
54         psa_key_id_t *key_id = out_vec[0].base;
55 
56         status = psa_import_key(&srv_key_attr,
57                                 data, data_length, &library_key);
58         /* Update the imported key id */
59         *key_id = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
60     }
61     break;
62     case TFM_CRYPTO_OPEN_KEY_SID:
63     {
64         psa_key_id_t *key_id = out_vec[0].base;
65 
66         status = psa_open_key(library_key, &library_key);
67         *key_id = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
68     }
69     break;
70     case TFM_CRYPTO_CLOSE_KEY_SID:
71     {
72         status = psa_close_key(library_key);
73     }
74     break;
75     case TFM_CRYPTO_DESTROY_KEY_SID:
76     {
77         status = psa_destroy_key(library_key);
78     }
79     break;
80     case TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID:
81     {
82         psa_key_attributes_t *key_attributes = out_vec[0].base;
83 
84         status = psa_get_key_attributes(library_key, &srv_key_attr);
85 
86         /* Note that we just copy out_vec[0].len, because in this context
87          * sizeof(psa_key_attributes_t) would return the size of the service
88          * view of the attributes, while we are passing back to the caller
89          * only the client view of it, i.e. without the owner field at the
90          * end of the structure
91          */
92         memcpy(key_attributes, &srv_key_attr, out_vec[0].len);
93     }
94     break;
95     case TFM_CRYPTO_EXPORT_KEY_SID:
96     {
97         uint8_t *data = out_vec[0].base;
98         size_t data_size = out_vec[0].len;
99 
100         status = psa_export_key(library_key, data, data_size,
101                                 &(out_vec[0].len));
102         if (status != PSA_SUCCESS) {
103             out_vec[0].len = 0;
104         }
105     }
106     break;
107     case TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID:
108     {
109         uint8_t *data = out_vec[0].base;
110         size_t data_size = out_vec[0].len;
111 
112         status = psa_export_public_key(library_key, data, data_size,
113                                        &(out_vec[0].len));
114         if (status != PSA_SUCCESS) {
115             out_vec[0].len = 0;
116         }
117     }
118     break;
119     case TFM_CRYPTO_PURGE_KEY_SID:
120     {
121         status = psa_purge_key(library_key);
122     }
123     break;
124     case TFM_CRYPTO_COPY_KEY_SID:
125     {
126         psa_key_id_t *target_key_id = out_vec[0].base;
127         tfm_crypto_library_key_id_t target_key = tfm_crypto_library_key_id_init_default();
128 
129         status = psa_copy_key(library_key,
130                               &srv_key_attr,
131                               &target_key);
132         if (status != PSA_SUCCESS) {
133             return status;
134         }
135 
136         *target_key_id = CRYPTO_LIBRARY_GET_KEY_ID(target_key);
137     }
138     break;
139     case TFM_CRYPTO_GENERATE_KEY_SID:
140     {
141         psa_key_id_t *key_handle = out_vec[0].base;
142 
143         status = psa_generate_key(&srv_key_attr, &library_key);
144         if (status != PSA_SUCCESS) {
145             return status;
146         }
147 
148         *key_handle = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
149     }
150     break;
151     default:
152         return PSA_ERROR_NOT_SUPPORTED;
153     }
154 
155     return status;
156 }
157 #else /* CRYPTO_KEY_MODULE_ENABLED  */
tfm_crypto_key_management_interface(psa_invec in_vec[],psa_outvec out_vec[],struct tfm_crypto_key_id_s * encoded_key)158 psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
159                                                  psa_outvec out_vec[],
160                                                  struct tfm_crypto_key_id_s *encoded_key)
161 {
162     (void)in_vec;
163     (void)out_vec;
164     (void)encoded_key;
165 
166     return PSA_ERROR_NOT_SUPPORTED;
167 }
168 #endif /* CRYPTO_KEY_MODULE_ENABLED  */
169 /*!@}*/
170