1 /*
2  * Copyright (c) 2022, Arm Limited. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 /**
19  * \file sic_drv.h
20  * \brief Driver for Arm Secure Instruction Cache (SIC).
21  */
22 
23 #ifndef __SIC_DRV_H__
24 #define __SIC_DRV_H__
25 
26 #include <stdint.h>
27 #include <stddef.h>
28 #include <stdbool.h>
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /**
35  * \brief Arm SIC error enumeration types
36  */
37 enum sic_error_t {
38     SIC_ERROR_NONE,
39     SIC_ERROR_INVALID_REGION,
40     SIC_ERROR_INVALID_ADDRESS,
41     SIC_ERROR_INVALID_SIZE,
42     SIC_ERROR_INVALID_ALIGNMENT,
43     SIC_ERROR_NO_HW_SUPPORT,
44     SIC_ERROR_INVALID_OP_WHILE_ENABLED,
45     SIC_ERROR_RBG_SEED_ALREADY_SET,
46 };
47 
48 /**
49  * \brief Arm SIC Authentication AXI manager Priviliged/Unpriviliged config types
50  */
51 enum sic_axim_priv_t {
52     SIC_AXIM_PRIV_FORWARD = 0b00,
53     SIC_AXIM_PRIV_UNPRIV  = 0b10,
54     SIC_AXIM_PRIV_PRIV    = 0b11,
55 };
56 
57 /**
58  * \brief Arm SIC Authentication AXI manager Secure/Non-Secure config types
59  */
60 enum sic_axim_secure_t {
61     SIC_AXIM_SECURE_FORWARD = 0b00,
62     SIC_AXIM_SECURE_SEC     = 0b10,
63     SIC_AXIM_SECURE_NONSEC  = 0b11,
64 };
65 
66 /**
67  * \brief Arm SIC Authentication AXI manager Data/Instruction config types
68  */
69 enum sic_axim_dinst_t {
70     SIC_AXIM_DINST_FORWARD     = 0b00,
71     SIC_AXIM_DINST_DATA        = 0b10,
72     SIC_AXIM_DINST_INSTRUCTION = 0b11,
73 };
74 
75 /**
76  * \brief Arm SIC Authentication AXI manager Cacheability config types
77  */
78 enum sic_axim_cache_t {
79     SIC_AXIM_CACHE_FORWARD = 0b00,
80     SIC_AXIM_CACHE_FALSE   = 0b10,
81     SIC_AXIM_CACHE_TRUE    = 0b11,
82 };
83 
84 /**
85  * \brief Arm SIC Authentication AXI manager configuration struct
86  */
87 struct sic_auth_axim_config_t {
88     enum sic_axim_priv_t   priv;
89     enum sic_axim_secure_t secure;
90     enum sic_axim_dinst_t  dinst;
91     enum sic_axim_cache_t  bufferable;
92     enum sic_axim_cache_t  modifiable;
93     enum sic_axim_cache_t  allocate;
94     enum sic_axim_cache_t  other_allocate;
95 };
96 
97 /**
98  * \brief Arm SIC digest size configuration types
99  */
100 enum sic_digest_size_t {
101     SIC_DIGEST_SIZE_128 = 0x1,
102     SIC_DIGEST_SIZE_256 = 0x2,
103 };
104 
105 /**
106  * \brief Arm SIC digest size configuration types
107  */
108 enum sic_digest_config_t {
109     SIC_DIGEST_COMPARE_FIRST_QWORD = 0x0,
110     SIC_DIGEST_COMPARE_LAST_QWORD = 0x1,
111     SIC_DIGEST_COMPARE_ALL,
112 };
113 
114 /**
115  * \brief Arm SIC Decryption keysize configuration types
116  */
117 enum sic_decrypt_keysize_t {
118     SIC_DECRYPT_KEYSIZE_128 = 0x0,
119     SIC_DECRYPT_KEYSIZE_256 = 0x1
120 };
121 
122 /**
123  * \brief Arm SIC Decryption mitigation config struct
124  */
125 struct sic_decrypt_mitigations_config_t {
126     bool aes_dfa_enable;
127     bool aes_dummy_enable;
128     bool aes_dummy_valid_phase_enable;
129     bool aes_dummy_valid_key_enable;
130     uint8_t aes_dr_pre_rounds_max;
131     uint8_t aes_dr_post_rounds_max;
132     uint8_t aes_dr_valid_rounds_max;
133 };
134 
135 /**
136  * \brief Arm SIC PMON mode configuration types
137  */
138 enum sic_pmon_counting_mode_t {
139     SIC_PMON_COUNT_EVENTS = 0x0,
140     SIC_PMON_COUNT_WORDS  = 0x1
141 };
142 
143 
144 /**
145  * \brief Arm SIC PMON counters struct
146  */
147 struct sic_pmon_counters_t {
148     uint32_t page_hit_counter;
149     uint32_t page_miss_counter;
150     uint32_t bypass_counter;
151 };
152 
153 /**
154  * \brief Arm SIC device configuration structure
155  */
156 struct sic_dev_cfg_t {
157     const uint32_t base;                         /*!< SIC base address */
158 };
159 
160 /**
161  * \brief Arm SIC device structure
162  */
163 struct sic_dev_t {
164     const struct sic_dev_cfg_t* const cfg;       /*!< SIC configuration */
165 };
166 
167 #define SIC_DECRYPT_DR_NONCE_BYTE_LEN (8)
168 #define SIC_DECRYPT_RBG_SEED_LEN      (16)
169 
170 /**
171  * \brief                  Enable the SIC. Setup should have been performed
172  *                         prior to this, as many registers cannot be written
173  *                         when the SIC is enabled.
174  *
175  * \param[in]  dev         The SIC device.
176  *
177  * \return                 SIC_ERROR_NONE on success, otherwise a different
178  *                         sic_error_t.
179  */
180 enum sic_error_t sic_enable(struct sic_dev_t *dev);
181 /**
182  * \brief                  Disable the SIC. Does not alter device configuration.
183  *
184  * \param[in]  dev         The SIC device.
185  *
186  * \return                 SIC_ERROR_NONE on success, otherwise a different
187  *                         sic_error_t.
188  */
189 enum sic_error_t sic_disable(struct sic_dev_t *dev);
190 
191 /**
192  * \brief                  Get the page size of the SIC in bytes.
193  *
194  * \param[in]  dev         The SIC device.
195  *
196  * \return                 The page size of the SIC in bytes.
197  */
198 size_t sic_page_size_get(struct sic_dev_t *dev);
199 /**
200  * \brief                  Get the page count of the SIC in bytes.
201  *
202  * \param[in]  dev         The SIC device.
203  *
204  * \return                 The page count of the SIC in bytes.
205  */
206 uint32_t sic_page_count_get(struct sic_dev_t *dev);
207 
208 /**
209  * \brief                    Setup the SIC authentication engine.
210  *
211  * \param[in]  dev           The SIC device.
212  *
213  * \param[in]  digest_size   The size of the hash digest the SIC should use, as
214  *                           a sic_digest_size_t.
215  *
216  * \param[in]  digest_config The configuration value for the hash digest the SIC
217  *                           should use, as a sic_digest_config_t.
218  *
219  * \param[in]  base          The RSE address which should be the start of the
220  *                           authentication region.
221  *
222  * \param[in]  size          The size in bytes of the authentication region.
223  *
224  * \return                   SIC_ERROR_NONE on success, otherwise a different
225  *                           sic_error_t.
226  */
227 enum sic_error_t sic_auth_init(struct sic_dev_t *dev,
228                                enum sic_digest_size_t digest_size,
229                                enum sic_digest_config_t digest_config,
230                                uintptr_t base, size_t size);
231 
232 /**
233  * \brief                    Enable the SIC authentication engine. This must be
234  *                           done while the SIC is disabled.
235  *
236  * \param[in]  dev           The SIC device.
237  *
238  * \return                   SIC_ERROR_NONE on success, otherwise a different
239  *                           sic_error_t.
240  */
241 enum sic_error_t sic_auth_enable(struct sic_dev_t *dev);
242 
243 /**
244  * \brief                    Disable the SIC authentication engine. This must be
245  *                           done while the SIC is disabled.
246  *
247  * \param[in]  dev           The SIC device.
248  *
249  * \return                   SIC_ERROR_NONE on success, otherwise a different
250  *                           sic_error_t.
251  */
252 enum sic_error_t sic_auth_disable(struct sic_dev_t *dev);
253 
254 /**
255  * \brief                    Invalidate any pages in the authenticated page
256  *                           cache. This is done when the authentication engine
257  *                           is disabled, and must be done before any part of
258  *                           the HTR is updated (but while the SIC is disabled).
259  *
260  * \param[in]  dev           The SIC device.
261  *
262  * \return                   SIC_ERROR_NONE on success, otherwise a different
263  *                           sic_error_t.
264  */
265 enum sic_error_t sic_auth_invalidate_pages(struct sic_dev_t *dev);
266 
267 /**
268  * \brief                    Set the configuration of the SIC AXI manager.
269  *
270  * \param[in]  dev           The SIC device.
271  *
272  * \param[in]  cfg           The configuration of the AXI manager, as a
273  *                           sic_auth_axim_config_t.
274  *
275  * \return                   SIC_ERROR_NONE on success, otherwise a different
276  *                           sic_error_t.
277  */
278 enum sic_error_t sic_auth_axim_cfg_set(struct sic_dev_t *dev,
279                                        const struct sic_auth_axim_config_t *cfg);
280 
281 /**
282  * \brief                    Get the configuration of the SIC AXI manager.
283  *
284  * \param[in]  dev           The SIC device.
285  *
286  * \param[out] cfg           The configuration of the AXI manager, as a
287  *                           sic_auth_axim_config_t.
288  *
289  * \return                   SIC_ERROR_NONE on success, otherwise a different
290  *                           sic_error_t.
291  */
292 enum sic_error_t sic_auth_axim_cfg_get(struct sic_dev_t *dev,
293                                        struct sic_auth_axim_config_t *cfg);
294 
295 /**
296  * \brief                    Set part of the SIC HTR that is used to
297  *                           authenticate pages.
298  *
299  * \param[in]  dev           The SIC device.
300  *
301  * \param[in] data           The data that should be loaded into the HTR.
302  * \param[in] data_len       The size of the data that should be loaded into the
303  *                           HTR in bytes.
304  * \param[in] table_offset   The offset (in bytes) into the HTR that the data
305  *                           should be loaded to.
306  *
307  * \return                   SIC_ERROR_NONE on success, otherwise a different
308  *                           sic_error_t.
309  */
310 enum sic_error_t sic_auth_table_set(struct sic_dev_t *dev, uint32_t *data,
311                                     size_t data_len_bytes, size_t table_offset);
312 
313 /**
314  * \brief                             Setup the SIC decryption engine.
315  *
316  * \param[in]  dev                    The SIC device.
317  *
318  * \param[in]  decrypt_keysize        The size of the key the decryption engine
319  *                                    will use, as a sic_decrypt_keysize_t.
320  *
321  * \param[in]  decrypt_padding_enable Whether decryption padding is enabled.
322  *
323  * \return                            SIC_ERROR_NONE on success, otherwise a
324  *                                    different sic_error_t.
325  */
326 enum sic_error_t sic_decrypt_init(struct sic_dev_t *dev,
327                                   enum sic_decrypt_keysize_t decrypt_keysize,
328                                   bool decrypt_padding_enable);
329 
330 /**
331  * \brief                  Setup a SIC decryption region.
332  *
333  * \param[in]  dev         The SIC device.
334  *
335  * \param[in]  region_idx  Which decryption region should be enabled.
336  *
337  * \param[in]  base        The RSE address of the start of the decryption
338  *                         region.
339  * \param[in]  size        The size in bytes of the decryption region.
340  * \param[in]  fw_revision The firmware revision of the image pointed to by the
341  *                         decryption region. This is used as part of the CTR
342  *                         mode IV.
343  * \param[in]  nonce       The remainder of the the CTR mode IV for this
344  *                         decryption region. This must be
345  *                         SIC_DECRYPT_DR_NONCE_BYTE_LEN bytes in length.
346  *
347  * \param[in]  key         The key for the decrypt region. This must be 16
348  *                         bytes in length if the decryption engine was set up
349  *                         with SIC_DECRYPT_KEYSIZE_128, or 32 bytes in length
350  *                         if using SIC_DECRYPT_KEYSIZE_256.
351  *
352  * \return                 SIC_ERROR_NONE on success, otherwise a different
353  *                         sic_error_t.
354  */
355 enum sic_error_t sic_decrypt_region_enable(struct sic_dev_t *dev,
356                                            uint8_t region_idx,
357                                            uintptr_t base, size_t size,
358                                            uint32_t fw_revision,
359                                            uint32_t *nonce, uint32_t *key);
360 
361 /**
362  * \brief                  disable a SIC decryption region.
363  *
364  * \param[in]  dev         The SIC device.
365  *
366  * \param[in]  region_idx  Which decryption region should be disabled.
367  *
368  * \return                 SIC_ERROR_NONE on success, otherwise a different
369  *                         sic_error_t.
370  */
371 enum sic_error_t sic_decrypt_region_disable(struct sic_dev_t *dev,
372                                             uint8_t region_idx);
373 
374 
375 /**
376  * \brief                    Set the side-channel mitigation configuration of
377  *                           the SIC decryption engine.
378  *
379  * \param[in]  dev           The SIC device.
380  *
381  * \param[in] cfg            The configuration of the SIC decryption engine
382  *                           side-channel mitigations, as a
383  *                           sic_decrypt_mitigations_config_t.
384  *
385  * \return                   SIC_ERROR_NONE on success, otherwise a different
386  *                           sic_error_t.
387  */
388 enum sic_error_t sic_decrypt_mitigations_set(struct sic_dev_t *dev,
389                                              const struct sic_decrypt_mitigations_config_t *cfg);
390 /**
391  * \brief                    Get the side-channel mitigation configuration of
392  *                           the SIC decryption engine.
393  *
394  * \param[in]  dev           The SIC device.
395  *
396  * \param[out] cfg           The configuration of the SIC decryption engine
397  *                           side-channel mitigations, as a
398  *                           sic_decrypt_mitigations_config_t.
399  *
400  * \return                   SIC_ERROR_NONE on success, otherwise a different
401  *                           sic_error_t.
402  */
403 enum sic_error_t sic_decrypt_mitigations_get(struct sic_dev_t *dev,
404                                              struct sic_decrypt_mitigations_config_t *cfg);
405 
406 /**
407  * \brief                    Set the seed from which the SIC decryption engine
408  *                           DRBG will be instanciated. This must be provided
409  *                           from a hardware TRNG.
410  *
411  * \param[in]  dev           The SIC device.
412  *
413  * \param[in]  seed          The seed value.
414  *
415  * \param[in]  seed_len      The seed length. In total, the seed must recieve
416  *                           SIC_DECRYPT_RBG_SEED_LEN bytes of seed input.
417  *
418  * \return                   SIC_ERROR_NONE on success, otherwise a different
419  *                           sic_error_t.
420  */
421 enum sic_error_t sic_decrypt_rbg_seed_set(struct sic_dev_t *dev,
422                                           const uint8_t *seed,
423                                           size_t seed_len);
424 
425 /**
426  * \brief                    Enable the SIC performance monitoring unit.
427  *
428  * \param[in]  dev           The SIC device.
429  *
430  * \param[in]  counting_mode Which mode the PMON should count in, as a
431  *                           sic_pmon_counting_mode_t.
432  *
433  * \param[in]  timer_enable  Whether the PMON should count forever, or for a set
434  *                           interval.
435  *
436  * \param[in]  timer_val     How long the PMON should count for (must be 0
437  *                           when timer_enable is not set).
438  *
439  * \return                   SIC_ERROR_NONE on success, otherwise a different
440  *                           sic_error_t.
441  */
442 enum sic_error_t sic_pmon_enable(struct sic_dev_t *dev,
443                                  enum sic_pmon_counting_mode_t counting_mode,
444                                  bool timer_enable, uint32_t timer_val);
445 
446 /**
447  * \brief                    Disable the SIC performance monitoring unit.
448  *
449  * \param[in]  dev           The SIC device.
450  *
451  * \return                   SIC_ERROR_NONE on success, otherwise a different
452  *                           sic_error_t.
453  */
454 enum sic_error_t sic_pmon_disable(struct sic_dev_t *dev);
455 
456 /**
457  * \brief                    Fetch the counter values from the SIC PMON.
458  *
459  * \param[in]  dev           The SIC device.
460  *
461  * \param[out] dev           The combined counter values as a
462  *                           sic_pmon_counters_t.
463  *
464  * \return                   SIC_ERROR_NONE on success, otherwise a different
465  *                           sic_error_t.
466  */
467 enum sic_error_t sic_pmon_get_stats(struct sic_dev_t *dev,
468                                     struct sic_pmon_counters_t *counters);
469 
470 #ifdef __cplusplus
471 }
472 #endif
473 
474 #endif /* __SIC_DRV_H__ */
475