1 /***************************************************************************//**
2  * @file
3  * @brief Silicon Labs Secure Engine Manager internal API.
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 #ifndef SE_MANAGER_INTERNAL_H
31 #define SE_MANAGER_INTERNAL_H
32 
33 #include "sli_se_manager_features.h"
34 
35 #if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
36 
37 #include "sl_status.h"
38 #include "sli_se_manager_mailbox.h"
39 #include "sl_se_manager.h"
40 #include "sl_se_manager_key_handling.h"
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 // -----------------------------------------------------------------------------
47 // Defines
48 
49 #if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
50 // Due to a problem with the countermeasures applied to
51 // accelerated point multiplication over elliptic curves,
52 // it is possible that random errors are encountered (this
53 // is extremely unilkely for truly random keys).
54 // As a workaround for this, the affected commands will
55 // retry the operation in order to reduce the probability
56 // that the error code was returned incorrectly. This helps
57 // lower the error probability further when using purposely
58 // small or large scalars, for example during testing.
59 #define SLI_SE_MAX_POINT_MULT_RETRIES   3U
60 #endif
61 
62 // -------------------------------
63 // Function-like macros
64 
65 /***************************************************************************//**
66  * @brief
67  *   Helper macro to init/reset the SE command struct of an SE command context
68  *
69  * @param[in] cmd_ctx
70  *   Pointer to SE context containing the command to initialize/reset
71  *
72  * @param[out] command_word
73  *   Command word to set in the SE command.
74  *
75  ******************************************************************************/
76 #define sli_se_command_init(cmd_ctx, command_word) \
77   cmd_ctx->command.command = command_word;         \
78   cmd_ctx->command.data_in = NULL;                 \
79   cmd_ctx->command.data_out = NULL;                \
80   cmd_ctx->command.num_parameters = 0;
81 
82 #if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
83 /***************************************************************************//**
84  * @brief
85  *   Helper macros to add key parameters and input/output blocks to SE commands
86  *
87  * @param[in] cmd_ctx
88  *   Pointer to SE context
89  * @param[in] key
90  *   Pointer to sl_se_key_descriptor_t structure
91  * @param[out] status
92  *   SL_Status_T
93  *
94  ******************************************************************************/
95 
96 // Add keyspec to command for given key
97 #define sli_add_key_parameters(cmd_ctx, key, status) {                \
98     uint32_t keyspec;                                                 \
99     (status) = sli_se_key_to_keyspec((key), &keyspec);                \
100     if ((status) != SL_STATUS_OK) {                                   \
101       return (status);                                                \
102     }                                                                 \
103     sli_se_mailbox_command_add_parameter(&cmd_ctx->command, keyspec); \
104 }
105 
106 // Add key metadata buffers to command for given key
107 #define sli_add_key_metadata(cmd_ctx, key, status)        \
108   /* Auth data */                                         \
109   sli_se_datatransfer_t auth_buffer;                      \
110   (status) = sli_se_get_auth_buffer((key), &auth_buffer); \
111   if ((status) != SL_STATUS_OK) {                         \
112     return (status);                                      \
113   }                                                       \
114   sli_se_mailbox_command_add_input(&cmd_ctx->command, &auth_buffer);
115 
116 // Add key metadata buffers with custom auth buffer to command for given key
117 #define sli_add_key_metadata_custom(cmd_ctx, auth_data_buf, key, status) \
118   /* Auth data */                                                        \
119   sli_se_datatransfer_t auth_data_buf;                                   \
120   (status) = sli_se_get_auth_buffer((key), &auth_data_buf);              \
121   if ((status) != SL_STATUS_OK) {                                        \
122     return (status);                                                     \
123   }                                                                      \
124   sli_se_mailbox_command_add_input(&cmd_ctx->command, &auth_data_buf);
125 
126 // Add key input buffer to given command
127 #define sli_add_key_input(cmd_ctx, key, status)                     \
128   sli_se_datatransfer_t key_input_buffer;                           \
129   (status) = sli_se_get_key_input_output((key), &key_input_buffer); \
130   if ((status) != SL_STATUS_OK) {                                   \
131     return (status);                                                \
132   }                                                                 \
133   sli_se_mailbox_command_add_input(&cmd_ctx->command, &key_input_buffer);
134 
135 // Add Key output buffer to given command
136 #define sli_add_key_output(cmd_ctx, key, status)                     \
137   sli_se_datatransfer_t key_output_buffer;                           \
138   (status) = sli_se_get_key_input_output((key), &key_output_buffer); \
139   if ((status) != SL_STATUS_OK) {                                    \
140     return (status);                                                 \
141   }                                                                  \
142   sli_se_mailbox_command_add_output(&cmd_ctx->command, &key_output_buffer);
143 #endif // SLI_MAILBOX_COMMAND_SUPPORTED
144 
145 /*******************************************************************************
146  *****************************   PROTOTYPES   **********************************
147  ******************************************************************************/
148 
149 sl_status_t sli_se_to_sl_status(sli_se_mailbox_response_t res);
150 
151 /***************************************************************************//**
152  * @brief
153  *   Take the SE lock in order to synchronize multiple threads calling into
154  *   the SE Manager API concurrently.
155  *
156  * @return
157  *   SL_STATUS_OK when successful, or else error code.
158  ******************************************************************************/
159 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
160 sl_status_t sli_se_lock_acquire(void);
161 
162 /***************************************************************************//**
163  * @brief
164  *   Give the SE lock in order to synchronize multiple threads calling into
165  *   the SE Manager API concurrently.
166  *
167  * @return
168  *   SL_STATUS_OK when successful, or else error code.
169  ******************************************************************************/
170 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
171 sl_status_t sli_se_lock_release(void);
172 
173 /***************************************************************************//**
174  * @brief
175  *   Execute and wait for mailbox command to complete.
176  *
177  * @param[in] cmd_ctx
178  *   Pointer to an SE command context object.
179  *
180  * @return
181  *   Status code, @ref sl_status.h.
182  ******************************************************************************/
183 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
184 sl_status_t sli_se_execute_and_wait(sl_se_command_context_t *cmd_ctx);
185 
186 #if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
187 // Key handling helper functions
188 sl_status_t sli_key_get_storage_size(const sl_se_key_descriptor_t* key,
189                                      uint32_t *storage_size);
190 sl_status_t sli_key_get_size(const sl_se_key_descriptor_t* key, uint32_t* size);
191 sl_status_t sli_key_check_equivalent(const sl_se_key_descriptor_t* key_1,
192                                      const sl_se_key_descriptor_t* key_2,
193                                      bool check_key_flag,
194                                      bool public_export);
195 
196 sl_status_t sli_se_key_to_keyspec(const sl_se_key_descriptor_t* key,
197                                   uint32_t* keyspec);
198 sl_status_t sli_se_keyspec_to_key(const uint32_t keyspec,
199                                   sl_se_key_descriptor_t* key);
200 sl_status_t sli_se_get_auth_buffer(const sl_se_key_descriptor_t* key,
201                                    sli_se_datatransfer_t* auth_buffer);
202 sl_status_t sli_se_get_key_input_output(const sl_se_key_descriptor_t* key,
203                                         sli_se_datatransfer_t* buffer);
204 #endif // SLI_MAILBOX_COMMAND_SUPPORTED
205 
206 #ifdef __cplusplus
207 }
208 #endif
209 
210 #endif /* defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) */
211 
212 #endif /* SE_MANAGER_INTERNAL_H */
213