1 /***************************************************************************//**
2  * @file
3  * @brief Silicon Labs Secure Engine Manager 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 #include "em_device.h"
31 
32 #if defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
33 
34 #include "sl_se_manager_util.h"
35 #include "sli_se_manager_internal.h"
36 #include "em_se.h"
37 #include "sl_assert.h"
38 #include "em_system.h"
39 
40 /// @addtogroup sl_se_manager
41 /// @{
42 
43 // -----------------------------------------------------------------------------
44 // Defines
45 
46 // OTP initialization structure defines.
47 #define SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_ENABLE (1 << 16)
48 #define SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_VERIFY_CERTIFICATE (1 << 17)
49 #define SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_ANTI_ROLLBACK (1 << 18)
50 #define SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_PAGE_LOCK_NARROW (1 << 19)
51 #define SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_PAGE_LOCK_FULL (1 << 20)
52 
53 // -----------------------------------------------------------------------------
54 // Local Functions
55 
56 /***************************************************************************//**
57  * @brief
58  *   Decode debug status word (as received from the SE).
59  *
60  * @return N/A
61  ******************************************************************************/
62 #if defined(SEMAILBOX_PRESENT)
decode_debug_status(sl_se_debug_status_t * debug_status,uint32_t status_word)63 static void decode_debug_status(sl_se_debug_status_t *debug_status,
64                                 uint32_t status_word)
65 {
66   debug_status->debug_port_lock_applied = status_word & (1 << 0);
67   debug_status->device_erase_enabled = status_word & (1 << 1);
68   debug_status->secure_debug_enabled = status_word & (1 << 2);
69   debug_status->debug_port_lock_state = status_word & (1 << 5);
70   debug_status->options_state.non_secure_invasive_debug =
71     (status_word & (1 << 6)) == 0;
72   debug_status->options_state.non_secure_non_invasive_debug =
73     (status_word & (1 << 7)) == 0;
74   debug_status->options_state.secure_invasive_debug =
75     (status_word & (1 << 8)) == 0;
76   debug_status->options_state.secure_non_invasive_debug =
77     (status_word & (1 << 9)) == 0;
78   debug_status->options_config.non_secure_invasive_debug =
79     (status_word & (1 << 10)) == 0;
80   debug_status->options_config.non_secure_non_invasive_debug =
81     (status_word & (1 << 11)) == 0;
82   debug_status->options_config.secure_invasive_debug =
83     (status_word & (1 << 12)) == 0;
84   debug_status->options_config.secure_non_invasive_debug =
85     (status_word & (1 << 13)) == 0;
86 }
87 #elif defined(CRYPTOACC_PRESENT)
decode_debug_status(sl_se_debug_status_t * debug_status,uint32_t status_word)88 static void decode_debug_status(sl_se_debug_status_t *debug_status,
89                                 uint32_t status_word)
90 {
91   debug_status->debug_port_lock_applied = status_word & (1 << 10);
92   debug_status->device_erase_enabled = status_word & (1 << 11);
93   debug_status->secure_debug_enabled = status_word & (1 << 12);
94   debug_status->debug_port_lock_state = status_word & (1 << 15);
95 }
96 #endif // defined(SEMAILBOX_PRESENT)
97 
98 // -----------------------------------------------------------------------------
99 // Global Functions
100 
101 /***************************************************************************//**
102  * Validate SE firmware image.
103  ******************************************************************************/
sl_se_check_se_image(sl_se_command_context_t * cmd_ctx,void * image_addr)104 sl_status_t sl_se_check_se_image(sl_se_command_context_t *cmd_ctx,
105                                  void *image_addr)
106 {
107   if (cmd_ctx == NULL || image_addr == NULL) {
108     return SL_STATUS_INVALID_PARAMETER;
109   }
110 
111   SE_Command_t *se_cmd = &cmd_ctx->command;
112   // SE command structures
113   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_CHECK_SE_IMAGE);
114 
115   SE_addParameter(se_cmd, (uint32_t)image_addr);
116 
117   return sli_se_execute_and_wait(cmd_ctx);
118 }
119 
120 /***************************************************************************//**
121  * Apply SE firmware image.
122  ******************************************************************************/
sl_se_apply_se_image(sl_se_command_context_t * cmd_ctx,void * image_addr)123 sl_status_t sl_se_apply_se_image(sl_se_command_context_t *cmd_ctx,
124                                  void *image_addr)
125 {
126   if (cmd_ctx == NULL || image_addr == NULL) {
127     return SL_STATUS_INVALID_PARAMETER;
128   }
129 
130   SE_Command_t *se_cmd = &cmd_ctx->command;
131   // SE command structures
132   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_APPLY_SE_IMAGE);
133 
134   SE_addParameter(se_cmd, (uint32_t)image_addr);
135 
136   return sli_se_execute_and_wait(cmd_ctx);
137 }
138 
139 /***************************************************************************//**
140  * Get upgrade status of SE firmware image.
141  ******************************************************************************/
sl_se_get_upgrade_status_se_image(sl_se_command_context_t * cmd_ctx,uint32_t * status,uint32_t * prev_version)142 sl_status_t sl_se_get_upgrade_status_se_image(sl_se_command_context_t *cmd_ctx,
143                                               uint32_t *status,
144                                               uint32_t *prev_version)
145 {
146   if (cmd_ctx == NULL || status == NULL || prev_version == NULL) {
147     return SL_STATUS_INVALID_PARAMETER;
148   }
149 
150   SE_Command_t *se_cmd = &cmd_ctx->command;
151   // SE command structures
152   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_STATUS_SE_IMAGE);
153 
154   volatile uint32_t out_buf[2];
155   SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(out_buf,
156                                                        sizeof(out_buf));
157   SE_addDataOutput(se_cmd, &out_data);
158 
159   sl_status_t ret = sli_se_execute_and_wait(cmd_ctx);
160 
161   if (ret == SL_STATUS_OK) {
162     *status = out_buf[0];
163     *prev_version = out_buf[1];
164   }
165 
166   return ret;
167 }
168 
169 /***************************************************************************//**
170  * Validate Host firmware image.
171  ******************************************************************************/
sl_se_check_host_image(sl_se_command_context_t * cmd_ctx,void * image_addr,uint32_t size)172 sl_status_t sl_se_check_host_image(sl_se_command_context_t *cmd_ctx,
173                                    void *image_addr,
174                                    uint32_t size)
175 {
176   if (cmd_ctx == NULL || image_addr == NULL || size == 0UL) {
177     return SL_STATUS_INVALID_PARAMETER;
178   }
179 
180   SE_Command_t *se_cmd = &cmd_ctx->command;
181   // SE command structures
182   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_CHECK_HOST_IMAGE);
183 
184   SE_addParameter(se_cmd, (uint32_t)image_addr);
185   SE_addParameter(se_cmd, size);
186 
187   return sli_se_execute_and_wait(cmd_ctx);
188 }
189 
190 /***************************************************************************//**
191  * Apply Host firmware image.
192  ******************************************************************************/
sl_se_apply_host_image(sl_se_command_context_t * cmd_ctx,void * image_addr,uint32_t size)193 sl_status_t sl_se_apply_host_image(sl_se_command_context_t *cmd_ctx,
194                                    void *image_addr,
195                                    uint32_t size)
196 {
197   if (cmd_ctx == NULL || image_addr == NULL || size == 0UL) {
198     return SL_STATUS_INVALID_PARAMETER;
199   }
200 
201   SE_Command_t *se_cmd = &cmd_ctx->command;
202   // SE command structures
203   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_APPLY_HOST_IMAGE);
204 
205   SE_addParameter(se_cmd, (uint32_t)image_addr);
206   SE_addParameter(se_cmd, size);
207 
208   return sli_se_execute_and_wait(cmd_ctx);
209 }
210 
211 /***************************************************************************//**
212  * Get upgrade status of Host firmware image.
213  ******************************************************************************/
214 sl_status_t
sl_se_get_upgrade_status_host_image(sl_se_command_context_t * cmd_ctx,uint32_t * status,uint32_t * prev_version)215 sl_se_get_upgrade_status_host_image(sl_se_command_context_t *cmd_ctx,
216                                     uint32_t *status,
217                                     uint32_t *prev_version)
218 {
219   if (cmd_ctx == NULL || status == NULL || prev_version == NULL) {
220     return SL_STATUS_INVALID_PARAMETER;
221   }
222 
223   SE_Command_t *se_cmd = &cmd_ctx->command;
224   // SE command structures
225   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_STATUS_HOST_IMAGE);
226 
227   volatile uint32_t out_buf[2];
228   SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(out_buf,
229                                                        sizeof(out_buf));
230   SE_addDataOutput(se_cmd, &out_data);
231 
232   sl_status_t ret = sli_se_execute_and_wait(cmd_ctx);
233 
234   if (ret == SL_STATUS_OK) {
235     *status = out_buf[0];
236     *prev_version = out_buf[1];
237   }
238 
239   return ret;
240 }
241 
242 /***************************************************************************//**
243  * Initialize key to be stored in the SE OTP flash.
244  ******************************************************************************/
sl_se_init_otp_key(sl_se_command_context_t * cmd_ctx,sl_se_device_key_type_t key_type,void * key,uint32_t num_bytes)245 sl_status_t sl_se_init_otp_key(sl_se_command_context_t *cmd_ctx,
246                                sl_se_device_key_type_t key_type,
247                                void *key,
248                                uint32_t num_bytes)
249 {
250   if (cmd_ctx == NULL || key == NULL || num_bytes == 0UL || (size_t)key & 3U) {
251     return SL_STATUS_INVALID_PARAMETER;
252   }
253 
254   #if defined(SEMAILBOX_PRESENT)
255   if (key_type == SL_SE_KEY_TYPE_IMMUTABLE_AES_128) {
256     if (num_bytes != 16UL) {
257       return SL_STATUS_INVALID_PARAMETER;
258     }
259   } else {
260     if (num_bytes != 64UL) {
261       return SL_STATUS_INVALID_PARAMETER;
262     }
263   }
264   #elif defined(CRYPTOACC_PRESENT)
265   if (num_bytes != 64UL) {
266     return SL_STATUS_INVALID_PARAMETER;
267   }
268   #endif
269 
270   uint32_t command_word;
271   SE_Command_t *se_cmd = &cmd_ctx->command;
272 
273   uint32_t se_key_type;
274   switch (key_type) {
275     case SL_SE_KEY_TYPE_IMMUTABLE_BOOT:
276       se_key_type = SLI_SE_KEY_TYPE_BOOT;
277       break;
278 
279     case SL_SE_KEY_TYPE_IMMUTABLE_AUTH:
280       se_key_type = SLI_SE_KEY_TYPE_AUTH;
281       break;
282 
283     #if defined(SEMAILBOX_PRESENT)
284     case SL_SE_KEY_TYPE_IMMUTABLE_AES_128:
285       se_key_type = SLI_SE_IMMUTABLE_KEY_TYPE_AES_128;
286       break;
287     #endif // SEMAILBOX_PRESENT
288 
289     default:
290       return SL_STATUS_INVALID_PARAMETER;
291       break;
292   }
293 
294   // Find parity word
295   volatile uint32_t parity = 0;
296   for (size_t i = 0; i < num_bytes / 4; i++) {
297     parity = parity ^ ((uint32_t *)key)[i];
298   }
299 
300   // SE command structures
301   #if defined(SEMAILBOX_PRESENT)
302   command_word = key_type == SL_SE_KEY_TYPE_IMMUTABLE_AES_128
303                  ? SLI_SE_COMMAND_INIT_AES_128_KEY : SLI_SE_COMMAND_INIT_PUBKEY;
304   #elif defined(CRYPTOACC_PRESENT)
305   command_word = SLI_SE_COMMAND_INIT_PUBKEY;
306   #endif
307 
308   sli_se_command_init(cmd_ctx, (command_word | se_key_type));
309 
310   SE_DataTransfer_t parity_data = SE_DATATRANSFER_DEFAULT(&parity, 4);
311   SE_addDataInput(se_cmd, &parity_data);
312 
313   SE_DataTransfer_t key_data = SE_DATATRANSFER_DEFAULT(key, num_bytes);
314   SE_addDataInput(se_cmd, &key_data);
315 
316   return sli_se_execute_and_wait(cmd_ctx);
317 }
318 
319 /***************************************************************************//**
320  * Read a public key stored in the SE.
321  ******************************************************************************/
sl_se_read_pubkey(sl_se_command_context_t * cmd_ctx,sl_se_device_key_type_t key_type,void * key,uint32_t num_bytes)322 sl_status_t sl_se_read_pubkey(sl_se_command_context_t *cmd_ctx,
323                               sl_se_device_key_type_t key_type,
324                               void *key,
325                               uint32_t num_bytes)
326 {
327   if (cmd_ctx == NULL || key == NULL || num_bytes != 64UL || (size_t)key & 3U) {
328     return SL_STATUS_INVALID_PARAMETER;
329   }
330 
331   SE_Command_t *se_cmd = &cmd_ctx->command;
332   uint32_t se_key_type;
333   uint32_t command_word = SLI_SE_COMMAND_READ_PUBKEY;
334   switch (key_type) {
335     case SL_SE_KEY_TYPE_IMMUTABLE_BOOT:
336       se_key_type = SLI_SE_KEY_TYPE_BOOT;
337       break;
338 
339     case SL_SE_KEY_TYPE_IMMUTABLE_AUTH:
340       se_key_type = SLI_SE_KEY_TYPE_AUTH;
341       break;
342     #if defined(SEMAILBOX_PRESENT) && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
343     case SL_SE_KEY_TYPE_IMMUTABLE_SE_ATTESTATION:
344       command_word = command_word & ~0x1;
345     // Intentional fallthrough
346     case SL_SE_KEY_TYPE_IMMUTABLE_ATTESTATION:
347       se_key_type = SLI_SE_KEY_TYPE_ATTEST;
348       break;
349     #endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
350 
351     default:
352       return SL_STATUS_INVALID_PARAMETER;
353       break;
354   }
355 
356   // SE command structures
357   sli_se_command_init(cmd_ctx, command_word | se_key_type);
358 
359   SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(key, num_bytes);
360   SE_addDataOutput(se_cmd, &out_data);
361 
362   return sli_se_execute_and_wait(cmd_ctx);
363 }
364 
365 /***************************************************************************//**
366  * Read the SE firmware version.
367  ******************************************************************************/
sl_se_get_se_version(sl_se_command_context_t * cmd_ctx,uint32_t * version)368 sl_status_t sl_se_get_se_version(sl_se_command_context_t *cmd_ctx,
369                                  uint32_t *version)
370 {
371   if (cmd_ctx == NULL || version == NULL) {
372     return SL_STATUS_INVALID_PARAMETER;
373   }
374 
375   #if defined(SEMAILBOX_PRESENT)
376 
377   // SE command structures
378   SE_Command_t *se_cmd = &cmd_ctx->command;
379   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_STATUS_SE_VERSION);
380   SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(version, sizeof(uint32_t));
381 
382   SE_addDataOutput(se_cmd, &out_data);
383 
384   return sli_se_execute_and_wait(cmd_ctx);
385 
386   #elif defined(CRYPTOACC_PRESENT)
387 
388   sl_status_t status = SL_STATUS_OK;
389   SE_Response_t command_response;
390 
391   // Try to acquire SE lock.
392   // Need to protect VSE mailbox from being written by e.g. SE_ackCommand()
393   status = sli_se_lock_acquire();
394   if (status != SL_STATUS_OK) {
395     return status;
396   }
397 
398   // Read SE version from VSE mailbox.
399   command_response = SE_getVersion(version);
400 
401   // Release SE lock
402   status = sli_se_lock_release();
403 
404   // Return sl_status_t code.
405   if (command_response == SLI_SE_RESPONSE_OK) {
406     return status;
407   } else {
408     // Convert from SE_Response_t to sl_status_t code and return.
409     return sli_se_to_sl_status(command_response);
410   }
411 
412   #endif
413 }
414 
415 /***************************************************************************//**
416  * Enables the debug lock for the part.
417  ******************************************************************************/
sl_se_apply_debug_lock(sl_se_command_context_t * cmd_ctx)418 sl_status_t sl_se_apply_debug_lock(sl_se_command_context_t *cmd_ctx)
419 {
420   if (cmd_ctx == NULL) {
421     return SL_STATUS_INVALID_PARAMETER;
422   }
423 
424   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_DBG_LOCK_APPLY);
425 
426   return sli_se_execute_and_wait(cmd_ctx);
427 }
428 
429 /***************************************************************************//**
430  * Returns the current debug lock configuration.
431  ******************************************************************************/
sl_se_get_debug_lock_status(sl_se_command_context_t * cmd_ctx,sl_se_debug_status_t * debug_status)432 sl_status_t sl_se_get_debug_lock_status(sl_se_command_context_t *cmd_ctx,
433                                         sl_se_debug_status_t *debug_status)
434 {
435   if (cmd_ctx == NULL || debug_status == NULL) {
436     return SL_STATUS_INVALID_PARAMETER;
437   }
438   #if defined(SEMAILBOX_PRESENT)
439   SE_Command_t *se_cmd = &cmd_ctx->command;
440   volatile uint32_t status_word = 0;
441   SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(&status_word, 4);
442 
443   // Initialize SE command structures
444   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_DBG_LOCK_STATUS);
445   SE_addDataOutput(se_cmd, &out_data);
446 
447   sl_status_t ret = sli_se_execute_and_wait(cmd_ctx);
448 
449   if (ret == SL_STATUS_OK) {
450     decode_debug_status(debug_status, status_word);
451   }
452 
453   return ret;
454   #elif defined(CRYPTOACC_PRESENT)
455   uint32_t vse_version = 0;
456   uint32_t debug_lock_flags = 0;
457 
458   // Try to acquire SE lock
459   sl_status_t status = sli_se_lock_acquire();
460   if (status != SL_STATUS_OK) {
461     return status;
462   }
463 
464   // Read SE version from VSE mailbox.
465   SE_Response_t vse_mbx_status = SE_getVersion(&vse_version);
466 
467   // Reading debug lock status is not supported on VSE with versions <= 1.2.2.
468   if ((vse_version <= 0x1010202UL) || (vse_mbx_status != SE_RESPONSE_OK)) {
469     sli_se_lock_release();
470     return SL_STATUS_COMMAND_IS_INVALID;
471   }
472 
473   vse_mbx_status = SE_getConfigStatusBits(&debug_lock_flags);
474   // Release SE lock
475   status = sli_se_lock_release();
476 
477   if (vse_mbx_status != SE_RESPONSE_OK) {
478     return sli_se_to_sl_status(vse_mbx_status);
479   } else if (status != SL_STATUS_OK) {
480     return status;
481   }
482 
483   decode_debug_status(debug_status, debug_lock_flags);
484 
485   return SL_STATUS_OK;
486   #endif
487 }
488 
489 #if defined(SEMAILBOX_PRESENT)
490 
491 /***************************************************************************//**
492  * Initialize SE OTP configuration.
493  ******************************************************************************/
sl_se_init_otp(sl_se_command_context_t * cmd_ctx,sl_se_otp_init_t * otp_init)494 sl_status_t sl_se_init_otp(sl_se_command_context_t *cmd_ctx,
495                            sl_se_otp_init_t *otp_init)
496 {
497   if (cmd_ctx == NULL || otp_init == NULL) {
498     return SL_STATUS_INVALID_PARAMETER;
499   }
500 
501   SE_Command_t *se_cmd = &cmd_ctx->command;
502   uint32_t mcu_settings_flags = 0;
503 
504   sl_status_t status;
505 
506   if (otp_init->enable_secure_boot) {
507     mcu_settings_flags |= SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_ENABLE;
508 
509     // Check for installed boot pubkey before OTP initialization
510     uint8_t pubkey[64];
511     status =
512       sl_se_read_pubkey(cmd_ctx, SL_SE_KEY_TYPE_IMMUTABLE_BOOT, &pubkey, 64);
513     if (status != SL_STATUS_OK) {
514       return SL_STATUS_ABORT;
515     }
516   }
517   if (otp_init->verify_secure_boot_certificate) {
518     mcu_settings_flags |=
519       SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_VERIFY_CERTIFICATE;
520   }
521   if (otp_init->enable_anti_rollback) {
522     // Verify firmware compatibility before enabling anti-rollback
523     #if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
524     uint16_t part_number = SYSTEM_GetPartNumber();
525     if (part_number == 1010 || part_number == 1020) {
526       if (SYSTEM_GetProdRev() < 16) {
527         sl_se_status_t se_status;
528         status = sl_se_get_status(cmd_ctx, &se_status);
529         if ((status != SL_STATUS_OK)
530             || (se_status.se_fw_version < 0x00010201)) {
531           // If the following error is returned, the SE firmware version
532           // needs to be upgraded to v1.2.1 or higher before enabling
533           // anti-rollback.
534           EFM_ASSERT(false);
535           return SL_STATUS_ABORT;
536         }
537       }
538     }
539     #endif
540 
541     mcu_settings_flags |= SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_ANTI_ROLLBACK;
542   }
543   if (otp_init->secure_boot_page_lock_narrow) {
544     mcu_settings_flags |= SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_PAGE_LOCK_NARROW;
545   }
546   if (otp_init->secure_boot_page_lock_full) {
547     mcu_settings_flags |= SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_PAGE_LOCK_FULL;
548   }
549 
550   #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
551   static struct {
552     uint8_t levels[SL_SE_TAMPER_SIGNAL_NUM_SIGNALS / 2];
553     uint8_t period;
554     uint8_t threshold;
555     uint8_t flags;
556     uint8_t reset_threshold;
557   } otp_tamper_settings;
558 
559   // Check for reserved sources
560   if ((otp_init->tamper_levels[SL_SE_TAMPER_SIGNAL_RESERVED_1] != SL_SE_TAMPER_LEVEL_IGNORE)
561       || (otp_init->tamper_levels[SL_SE_TAMPER_SIGNAL_RESERVED_2] != SL_SE_TAMPER_LEVEL_IGNORE)
562       || (otp_init->tamper_levels[SL_SE_TAMPER_SIGNAL_RESERVED_3] != SL_SE_TAMPER_LEVEL_IGNORE)
563       || (otp_init->tamper_levels[SL_SE_TAMPER_SIGNAL_RESERVED_4] != SL_SE_TAMPER_LEVEL_IGNORE)) {
564     return SL_STATUS_INVALID_PARAMETER;
565   }
566 
567   // Combine tamper levels, two per byte
568   for (size_t i = 0; i < SL_SE_TAMPER_SIGNAL_NUM_SIGNALS; i += 2) {
569     // Check for reserved levels
570     for (size_t offset = 0; offset < 2; ++offset) {
571       switch (otp_init->tamper_levels[i + offset]) {
572         case SL_SE_TAMPER_LEVEL_IGNORE:
573         case SL_SE_TAMPER_LEVEL_INTERRUPT:
574         case SL_SE_TAMPER_LEVEL_FILTER:
575         case SL_SE_TAMPER_LEVEL_RESET:
576         case SL_SE_TAMPER_LEVEL_PERMANENTLY_ERASE_OTP:
577           break;
578         default:
579           return SL_STATUS_INVALID_PARAMETER;
580       }
581     }
582 
583     otp_tamper_settings.levels[i / 2] = (otp_init->tamper_levels[i] & 0x7)
584                                         | ((otp_init->tamper_levels[i + 1] & 0x7) << 4);
585   }
586   // Limit period and threshold input
587   otp_tamper_settings.period = otp_init->tamper_filter_period & 0x1f;
588   otp_tamper_settings.threshold = otp_init->tamper_filter_threshold & 0x7;
589 
590   otp_tamper_settings.flags = otp_init->tamper_flags;
591   otp_tamper_settings.reset_threshold = otp_init->tamper_reset_threshold;
592   #else
593   static struct otp_tamper_settings {
594     uint8_t reserved1[16];
595     uint8_t reserved2[2];
596     uint8_t reserved3[2];
597   } otp_tamper_settings = {
598     { 0x00 },
599     { 0xFF, 0xFF },
600     { 0x00 }
601   };
602   #endif
603 
604   // Find parity word
605   volatile uint32_t parity = 0;
606   parity = parity ^ mcu_settings_flags;
607   for (size_t i = 0; i < 5; i++) {
608     parity = parity ^ ((uint32_t*)(&otp_tamper_settings))[i];
609   }
610 
611   // SE command structures
612   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_INIT_OTP);
613 
614   volatile uint32_t parameters[2] = {
615     parity,
616     sizeof(mcu_settings_flags)
617     + sizeof(otp_tamper_settings)
618   };
619   SE_DataTransfer_t parameters_data = SE_DATATRANSFER_DEFAULT(&parameters, 8);
620   SE_addDataInput(se_cmd, &parameters_data);
621 
622   SE_DataTransfer_t mcu_settings_flags_data =
623     SE_DATATRANSFER_DEFAULT((volatile void *)&mcu_settings_flags, sizeof(mcu_settings_flags));
624   SE_addDataInput(se_cmd, &mcu_settings_flags_data);
625 
626   SE_DataTransfer_t tamper_settings_data =
627     SE_DATATRANSFER_DEFAULT((volatile void *)&otp_tamper_settings, sizeof(otp_tamper_settings));
628   SE_addDataInput(se_cmd, &tamper_settings_data);
629 
630   return sli_se_execute_and_wait(cmd_ctx);
631 }
632 
633 /***************************************************************************//**
634  * Read SE OTP configuration.
635  ******************************************************************************/
sl_se_read_otp(sl_se_command_context_t * cmd_ctx,sl_se_otp_init_t * otp_settings)636 sl_status_t sl_se_read_otp(sl_se_command_context_t *cmd_ctx,
637                            sl_se_otp_init_t *otp_settings)
638 {
639   if (cmd_ctx == NULL || otp_settings == NULL) {
640     return SL_STATUS_INVALID_PARAMETER;
641   }
642 
643   SE_Command_t *se_cmd = &cmd_ctx->command;
644   sl_status_t status;
645 
646   #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
647   volatile struct {
648     uint32_t mcu_settings_flags;
649     uint8_t levels[SL_SE_TAMPER_SIGNAL_NUM_SIGNALS / 2];
650     uint8_t period;
651     uint8_t threshold;
652     uint8_t flags;
653     uint8_t reset_threshold;
654   } otp_raw;
655   #else
656   volatile struct {
657     uint32_t mcu_settings_flags;
658     uint8_t reserved1[16];
659     uint8_t reserved2[2];
660     uint8_t reserved3[2];
661   } otp_raw;
662   #endif
663 
664   // SE command structures
665   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_READ_OTP);
666 
667   SE_DataTransfer_t otp_raw_data =
668     SE_DATATRANSFER_DEFAULT(&otp_raw, sizeof(otp_raw));
669   SE_addDataOutput(se_cmd, &otp_raw_data);
670 
671   status = sli_se_execute_and_wait(cmd_ctx);
672 
673   if (status != SL_STATUS_OK) {
674     return status;
675   }
676 
677   otp_settings->enable_secure_boot =
678     (otp_raw.mcu_settings_flags
679      & SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_ENABLE);
680   otp_settings->verify_secure_boot_certificate =
681     (otp_raw.mcu_settings_flags
682      & SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_VERIFY_CERTIFICATE);
683   otp_settings->enable_anti_rollback =
684     (otp_raw.mcu_settings_flags
685      & SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_ANTI_ROLLBACK);
686   otp_settings->secure_boot_page_lock_narrow =
687     (otp_raw.mcu_settings_flags
688      & SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_PAGE_LOCK_NARROW);
689   otp_settings->secure_boot_page_lock_full =
690     (otp_raw.mcu_settings_flags
691      & SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_PAGE_LOCK_FULL);
692 
693   #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
694   // Split levels
695   for (size_t i = 0; i < sizeof(otp_raw.levels); i++) {
696     otp_settings->tamper_levels[2 * i] = (otp_raw.levels[i]) & 0x7;
697     otp_settings->tamper_levels[2 * i + 1] = (otp_raw.levels[i] >> 4) & 0x7;
698   }
699 
700   otp_settings->tamper_filter_period = otp_raw.period;
701   otp_settings->tamper_filter_threshold = otp_raw.threshold;
702 
703   otp_settings->tamper_flags = otp_raw.flags;
704   otp_settings->tamper_reset_threshold = otp_raw.reset_threshold;
705   #endif
706 
707   return SL_STATUS_OK;
708 }
709 
710 #elif defined(CRYPTOACC_PRESENT)
711 
sl_se_init_otp(sl_se_command_context_t * cmd_ctx,sl_se_otp_init_t * otp_init)712 sl_status_t sl_se_init_otp(sl_se_command_context_t *cmd_ctx,
713                            sl_se_otp_init_t *otp_init)
714 {
715   if (cmd_ctx == NULL || otp_init == NULL) {
716     return SL_STATUS_INVALID_PARAMETER;
717   }
718 
719   SE_Command_t *se_cmd = &cmd_ctx->command;
720   volatile uint32_t mcu_settings_flags = 0;
721 
722   if (otp_init->enable_secure_boot) {
723     mcu_settings_flags |= SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_ENABLE;
724   }
725   if (otp_init->verify_secure_boot_certificate) {
726     mcu_settings_flags |=
727       SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_VERIFY_CERTIFICATE;
728   }
729   if (otp_init->enable_anti_rollback) {
730     mcu_settings_flags |= SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_ANTI_ROLLBACK;
731   }
732   if (otp_init->secure_boot_page_lock_narrow) {
733     mcu_settings_flags |= SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_PAGE_LOCK_NARROW;
734   }
735   if (otp_init->secure_boot_page_lock_full) {
736     mcu_settings_flags |= SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_PAGE_LOCK_FULL;
737   }
738 
739   // Find parity word
740   uint32_t parity = 0;
741   parity = parity ^ mcu_settings_flags;
742 
743   // SE command structures
744   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_INIT_OTP);
745 
746   volatile uint32_t parameters[2] = {
747     parity,
748     sizeof(mcu_settings_flags)
749   };
750   SE_DataTransfer_t parameters_data = SE_DATATRANSFER_DEFAULT(&parameters, 8);
751   SE_addDataInput(se_cmd, &parameters_data);
752 
753   SE_DataTransfer_t mcu_settings_flags_data =
754     SE_DATATRANSFER_DEFAULT(&mcu_settings_flags, sizeof(mcu_settings_flags));
755   SE_addDataInput(se_cmd, &mcu_settings_flags_data);
756 
757   SE_executeCommand(se_cmd);
758   return SL_STATUS_FAIL; // Should never get to this point
759 }
760 
sl_se_read_otp(sl_se_command_context_t * cmd_ctx,sl_se_otp_init_t * otp_settings)761 sl_status_t sl_se_read_otp(sl_se_command_context_t *cmd_ctx,
762                            sl_se_otp_init_t *otp_settings)
763 {
764   if (cmd_ctx == NULL || otp_settings == NULL) {
765     return SL_STATUS_INVALID_PARAMETER;
766   }
767 
768   // Try to acquire SE lock
769   sl_status_t status = sli_se_lock_acquire();
770   if (status != SL_STATUS_OK) {
771     return status;
772   }
773 
774   uint32_t mcu_settings_flags = 0;
775   SE_Response_t vse_mbx_status = SE_getConfigStatusBits(&mcu_settings_flags);
776 
777   // Release SE lock
778   status = sli_se_lock_release();
779 
780   if (vse_mbx_status != SE_RESPONSE_OK) {
781     return sli_se_to_sl_status(vse_mbx_status);
782   } else if (status != SL_STATUS_OK) {
783     return status;
784   }
785 
786   otp_settings->enable_secure_boot =
787     (mcu_settings_flags
788      & (SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_ENABLE >> SL_SE_ROOT_CONFIG_MCU_SETTINGS_SHIFT));
789   otp_settings->verify_secure_boot_certificate =
790     (mcu_settings_flags
791      & (SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_VERIFY_CERTIFICATE >> SL_SE_ROOT_CONFIG_MCU_SETTINGS_SHIFT));
792   otp_settings->enable_anti_rollback =
793     (mcu_settings_flags
794      & (SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_ANTI_ROLLBACK >> SL_SE_ROOT_CONFIG_MCU_SETTINGS_SHIFT));
795   otp_settings->secure_boot_page_lock_narrow =
796     (mcu_settings_flags
797      & (SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_PAGE_LOCK_NARROW >> SL_SE_ROOT_CONFIG_MCU_SETTINGS_SHIFT));
798   otp_settings->secure_boot_page_lock_full =
799     (mcu_settings_flags
800      & (SE_OTP_MCU_SETTINGS_FLAG_SECURE_BOOT_PAGE_LOCK_FULL >> SL_SE_ROOT_CONFIG_MCU_SETTINGS_SHIFT));
801 
802   return SL_STATUS_OK;
803 }
804 #endif
805 
806 #if defined(SEMAILBOX_PRESENT)
807 
808 /***************************************************************************//**
809  * Writes data to User Data section in MTP. Write data must be aligned to
810  * word size and contain a number of bytes that is divisable by four.
811  ******************************************************************************/
sl_se_write_user_data(sl_se_command_context_t * cmd_ctx,uint32_t offset,void * data,uint32_t num_bytes)812 sl_status_t sl_se_write_user_data(sl_se_command_context_t *cmd_ctx,
813                                   uint32_t offset,
814                                   void *data,
815                                   uint32_t num_bytes)
816 {
817   if (cmd_ctx == NULL) {
818     return SL_STATUS_INVALID_PARAMETER;
819   }
820 
821   if (data == NULL && num_bytes > 0UL) {
822     return SL_STATUS_INVALID_PARAMETER;
823   }
824 
825   // Setup SE command structures
826   SE_Command_t *se_cmd = &cmd_ctx->command;
827   SE_DataTransfer_t in_data = SE_DATATRANSFER_DEFAULT(data, num_bytes);
828 
829   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_WRITE_USER_DATA);
830   SE_addDataInput(se_cmd, &in_data);
831 
832   SE_addParameter(se_cmd, offset);
833   SE_addParameter(se_cmd, num_bytes);
834 
835   // Execute and wait
836   return sli_se_execute_and_wait(cmd_ctx);
837 }
838 
839 /***************************************************************************//**
840  * Erases User Data section in MTP.
841  ******************************************************************************/
sl_se_erase_user_data(sl_se_command_context_t * cmd_ctx)842 sl_status_t sl_se_erase_user_data(sl_se_command_context_t *cmd_ctx)
843 {
844   if (cmd_ctx == NULL) {
845     return SL_STATUS_INVALID_PARAMETER;
846   }
847 
848   // SE command structures
849   SE_Command_t *se_cmd = &cmd_ctx->command;
850   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_ERASE_USER_DATA);
851 
852   SE_addParameter(se_cmd, SLI_SE_COMMAND_OPTION_ERASE_UD);
853 
854   // Execute and wait.
855   return sli_se_execute_and_wait(cmd_ctx);
856 }
857 
858 /***************************************************************************//**
859  * Returns the current boot status, versions and system configuration.
860  ******************************************************************************/
sl_se_get_status(sl_se_command_context_t * cmd_ctx,sl_se_status_t * status)861 sl_status_t sl_se_get_status(sl_se_command_context_t *cmd_ctx,
862                              sl_se_status_t *status)
863 {
864   if (cmd_ctx == NULL || status == NULL) {
865     return SL_STATUS_INVALID_PARAMETER;
866   }
867 
868   volatile uint32_t output[9] = { 0 };
869   SE_Command_t *se_cmd = &cmd_ctx->command;
870 
871   // SE command structures
872   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_GET_STATUS);
873   SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(output, 4 * 9);
874 
875   SE_addDataOutput(se_cmd, &out_data);
876 
877   sl_status_t ret = sli_se_execute_and_wait(cmd_ctx);
878 
879   if (ret == SL_STATUS_OK) {
880     // Tamper status
881     status->tamper_status = output[0];
882     status->tamper_status_raw = output[2];
883 
884     // Update status object
885     status->boot_status = output[4];
886     status->se_fw_version = output[5];
887     status->host_fw_version = output[6];
888 
889     // Decode debug status
890     decode_debug_status(&status->debug_status, output[7]);
891 
892     // Decode secure boot mode
893     status->secure_boot_enabled =
894       ((output[8] & 0x1U) && ((output[8] & ~0x1U) == 0));
895   }
896 
897   return ret;
898 }
899 
900 /***************************************************************************//**
901  * Read the serial number of the SE module.
902  ******************************************************************************/
sl_se_get_serialnumber(sl_se_command_context_t * cmd_ctx,void * serial)903 sl_status_t sl_se_get_serialnumber(sl_se_command_context_t *cmd_ctx,
904                                    void *serial)
905 {
906   if (cmd_ctx == NULL || serial == NULL) {
907     return SL_STATUS_INVALID_PARAMETER;
908   }
909 
910   // SE command structures
911   SE_Command_t *se_cmd = &cmd_ctx->command;
912   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_READ_SERIAL);
913   SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(serial, 16);
914 
915   SE_addDataOutput(se_cmd, &out_data);
916 
917   return sli_se_execute_and_wait(cmd_ctx);
918 }
919 
920 /***************************************************************************//**
921  * Read the OTP firmware version of the SE module.
922  ******************************************************************************/
sl_se_get_otp_version(sl_se_command_context_t * cmd_ctx,uint32_t * version)923 sl_status_t sl_se_get_otp_version(sl_se_command_context_t *cmd_ctx,
924                                   uint32_t *version)
925 {
926   if (cmd_ctx == NULL || version == NULL) {
927     return SL_STATUS_INVALID_PARAMETER;
928   }
929 
930   // SE command structures
931   SE_Command_t *se_cmd = &cmd_ctx->command;
932   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_STATUS_OTP_VERSION);
933   SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(version, sizeof(uint32_t));
934 
935   SE_addDataOutput(se_cmd, &out_data);
936 
937   return sli_se_execute_and_wait(cmd_ctx);
938 }
939 
940 #if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
941 /***************************************************************************//**
942  * Read the EMU->RSTCAUSE after a tamper reset. This function should be called
943  * if EMU->RSTCAUSE has been cleared upon boot.
944  ******************************************************************************/
sl_se_get_reset_cause(sl_se_command_context_t * cmd_ctx,uint32_t * reset_cause)945 sl_status_t sl_se_get_reset_cause(sl_se_command_context_t *cmd_ctx,
946                                   uint32_t* reset_cause)
947 {
948   if (cmd_ctx == NULL || reset_cause == NULL) {
949     return SL_STATUS_INVALID_PARAMETER;
950   }
951 
952   // SE command structures
953   SE_Command_t *se_cmd = &cmd_ctx->command;
954   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_STATUS_READ_RSTCAUSE);
955   SE_DataTransfer_t out_data =
956     SE_DATATRANSFER_DEFAULT(reset_cause, sizeof(uint32_t));
957   SE_addDataOutput(se_cmd, &out_data);
958   return sli_se_execute_and_wait(cmd_ctx);
959 }
960 #endif // _SILICON_LABS_32B_SERIES_2_CONFIG_1
961 
962 /***************************************************************************//**
963  * Enables the secure debug functionality.
964  ******************************************************************************/
sl_se_enable_secure_debug(sl_se_command_context_t * cmd_ctx)965 sl_status_t sl_se_enable_secure_debug(sl_se_command_context_t *cmd_ctx)
966 {
967   if (cmd_ctx == NULL) {
968     return SL_STATUS_INVALID_PARAMETER;
969   }
970 
971   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_DBG_LOCK_ENABLE_SECURE);
972 
973   return sli_se_execute_and_wait(cmd_ctx);
974 }
975 
976 /***************************************************************************//**
977  * Disables the secure debug functionality.
978  ******************************************************************************/
sl_se_disable_secure_debug(sl_se_command_context_t * cmd_ctx)979 sl_status_t sl_se_disable_secure_debug(sl_se_command_context_t *cmd_ctx)
980 {
981   if (cmd_ctx == NULL) {
982     return SL_STATUS_INVALID_PARAMETER;
983   }
984 
985   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_DBG_LOCK_DISABLE_SECURE);
986 
987   return sli_se_execute_and_wait(cmd_ctx);
988 }
989 
990 /***************************************************************************//**
991  * Set options on the debug interface.
992  ******************************************************************************/
sl_se_set_debug_options(sl_se_command_context_t * cmd_ctx,const sl_se_debug_options_t * debug_options)993 sl_status_t sl_se_set_debug_options(sl_se_command_context_t *cmd_ctx,
994                                     const sl_se_debug_options_t *debug_options)
995 {
996   if (cmd_ctx == NULL || debug_options == NULL) {
997     return SL_STATUS_INVALID_PARAMETER;
998   }
999 
1000   SE_Command_t *se_cmd = &cmd_ctx->command;
1001   uint32_t restriction_bits = 0x0;
1002 
1003   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_DBG_SET_RESTRICTIONS);
1004 
1005   /// Encode restricted debug options parameter.
1006   restriction_bits |= debug_options->non_secure_invasive_debug ? 0 : 1UL << 0;
1007   restriction_bits |= debug_options->non_secure_non_invasive_debug ? 0 : 1UL << 1;
1008   restriction_bits |= debug_options->secure_invasive_debug ? 0 : 1UL << 2;
1009   restriction_bits |= debug_options->secure_non_invasive_debug ? 0 : 1UL << 3;
1010 
1011   SE_addParameter(se_cmd, restriction_bits);
1012 
1013   return sli_se_execute_and_wait(cmd_ctx);
1014 }
1015 
1016 /***************************************************************************//**
1017  * Performs a device mass erase and debug unlock.
1018  ******************************************************************************/
sl_se_erase_device(sl_se_command_context_t * cmd_ctx)1019 sl_status_t sl_se_erase_device(sl_se_command_context_t *cmd_ctx)
1020 {
1021   if (cmd_ctx == NULL) {
1022     return SL_STATUS_INVALID_PARAMETER;
1023   }
1024 
1025   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_DEVICE_ERASE);
1026 
1027   return sli_se_execute_and_wait(cmd_ctx);
1028 }
1029 
1030 /***************************************************************************//**
1031  * Disabled device erase functionality.
1032  ******************************************************************************/
sl_se_disable_device_erase(sl_se_command_context_t * cmd_ctx)1033 sl_status_t sl_se_disable_device_erase(sl_se_command_context_t *cmd_ctx)
1034 {
1035   if (cmd_ctx == NULL) {
1036     return SL_STATUS_INVALID_PARAMETER;
1037   }
1038 
1039   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_DEVICE_ERASE_DISABLE);
1040 
1041   return sli_se_execute_and_wait(cmd_ctx);
1042 }
1043 
1044 /***************************************************************************//**
1045  * Request challenge from SE which can be used to open debug access.
1046  ******************************************************************************/
sl_se_get_challenge(sl_se_command_context_t * cmd_ctx,sl_se_challenge_t challenge)1047 sl_status_t sl_se_get_challenge(sl_se_command_context_t *cmd_ctx,
1048                                 sl_se_challenge_t challenge)
1049 {
1050   if (cmd_ctx == NULL || challenge == NULL) {
1051     return SL_STATUS_INVALID_PARAMETER;
1052   }
1053 
1054   SE_Command_t *se_cmd = &cmd_ctx->command;
1055   SE_DataTransfer_t out_data =
1056     SE_DATATRANSFER_DEFAULT(challenge, sizeof(sl_se_challenge_t));
1057 
1058   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_GET_CHALLENGE);
1059 
1060   SE_addDataOutput(se_cmd, &out_data);
1061 
1062   return sli_se_execute_and_wait(cmd_ctx);
1063 }
1064 
1065 /***************************************************************************//**
1066  * Invalidate current challenge and make a new challenge.
1067  ******************************************************************************/
sl_se_roll_challenge(sl_se_command_context_t * cmd_ctx)1068 sl_status_t sl_se_roll_challenge(sl_se_command_context_t *cmd_ctx)
1069 {
1070   sl_se_challenge_t new_challenge;
1071   if (cmd_ctx == NULL) {
1072     return SL_STATUS_INVALID_PARAMETER;
1073   }
1074 
1075   SE_DataTransfer_t out_data =
1076     SE_DATATRANSFER_DEFAULT(new_challenge, sizeof(sl_se_challenge_t));
1077 
1078   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_ROLL_CHALLENGE);
1079   SE_addDataOutput(&cmd_ctx->command, &out_data);
1080 
1081   return sli_se_execute_and_wait(cmd_ctx);
1082 }
1083 
1084 /***************************************************************************//**
1085  * Unlock debug access using certificate signed with challenge.
1086  ******************************************************************************/
sl_se_open_debug(sl_se_command_context_t * cmd_ctx,void * cert,uint32_t len,const sl_se_debug_options_t * debug_options)1087 sl_status_t sl_se_open_debug(sl_se_command_context_t *cmd_ctx,
1088                              void *cert, uint32_t len,
1089                              const sl_se_debug_options_t *debug_options)
1090 {
1091   if (cmd_ctx == NULL || cert == NULL || debug_options == NULL) {
1092     return SL_STATUS_INVALID_PARAMETER;
1093   }
1094 
1095   SE_Command_t *se_cmd = &cmd_ctx->command;
1096   SE_DataTransfer_t in_data = SE_DATATRANSFER_DEFAULT(cert, len);
1097   uint32_t unlock_bits = 1UL << 1;  // Always request to unlock debug access port
1098 
1099   // SE command structures
1100   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_OPEN_DEBUG);
1101 
1102   SE_addDataInput(se_cmd, &in_data);
1103 
1104   /** Encode parameter that holds debug options to unlock. */
1105   unlock_bits |= debug_options->non_secure_invasive_debug     ? 1UL << 2 : 0;
1106   unlock_bits |= debug_options->non_secure_non_invasive_debug ? 1UL << 3 : 0;
1107   unlock_bits |= debug_options->secure_invasive_debug         ? 1UL << 4 : 0;
1108   unlock_bits |= debug_options->secure_non_invasive_debug     ? 1UL << 5 : 0;
1109 
1110   SE_addParameter(se_cmd, unlock_bits);
1111 
1112   return sli_se_execute_and_wait(cmd_ctx);
1113 }
1114 
1115 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
1116 /***************************************************************************//**
1117  * Temporarily disable tamper configuration using certificate signed with
1118  * challenge.
1119  ******************************************************************************/
sl_se_disable_tamper(sl_se_command_context_t * cmd_ctx,void * cert,uint32_t len,sl_se_tamper_signals_t tamper_signals)1120 sl_status_t sl_se_disable_tamper(sl_se_command_context_t *cmd_ctx,
1121                                  void *cert,
1122                                  uint32_t len,
1123                                  sl_se_tamper_signals_t tamper_signals)
1124 {
1125   if (cmd_ctx == NULL || cert == NULL) {
1126     return SL_STATUS_INVALID_PARAMETER;
1127   }
1128 
1129   SE_Command_t *se_cmd = &cmd_ctx->command;
1130   SE_DataTransfer_t in_data = SE_DATATRANSFER_DEFAULT(cert, len);
1131 
1132   // SE command structures
1133   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_DISABLE_TAMPER);
1134 
1135   SE_addDataInput(se_cmd, &in_data);
1136 
1137   SE_addParameter(se_cmd, tamper_signals);
1138 
1139   return sli_se_execute_and_wait(cmd_ctx);
1140 }
1141 
1142 #endif
1143 
1144 /***************************************************************************//**
1145  * Read size of stored certificates in SE.
1146  ******************************************************************************/
sl_se_read_cert_size(sl_se_command_context_t * cmd_ctx,sl_se_cert_size_type_t * cert_size)1147 sl_status_t sl_se_read_cert_size(sl_se_command_context_t *cmd_ctx,
1148                                  sl_se_cert_size_type_t *cert_size)
1149 {
1150   if (cmd_ctx == NULL || cert_size == NULL) {
1151     return SL_STATUS_INVALID_PARAMETER;
1152   }
1153   SE_Command_t *se_cmd = &cmd_ctx->command;
1154 
1155   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_READ_USER_CERT_SIZE);
1156 
1157   SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(cert_size, 12UL);
1158   SE_addDataOutput(se_cmd, &out_data);
1159 
1160   return sli_se_execute_and_wait(cmd_ctx);
1161 }
1162 
1163 /***************************************************************************//**
1164  * Read stored certificates in SE.
1165  ******************************************************************************/
sl_se_read_cert(sl_se_command_context_t * cmd_ctx,sl_se_cert_type_t cert_type,void * cert,uint32_t num_bytes)1166 sl_status_t sl_se_read_cert(sl_se_command_context_t *cmd_ctx,
1167                             sl_se_cert_type_t cert_type,
1168                             void *cert,
1169                             uint32_t num_bytes)
1170 {
1171   if (cmd_ctx == NULL || cert == NULL || num_bytes == 0UL) {
1172     return SL_STATUS_INVALID_PARAMETER;
1173   }
1174   SE_Command_t *se_cmd = &cmd_ctx->command;
1175   uint32_t se_cert_type;
1176 
1177   switch (cert_type) {
1178     case SL_SE_CERT_BATCH:
1179       se_cert_type = SLI_SE_COMMAND_CERT_BATCH;
1180       break;
1181 
1182     case SL_SE_CERT_DEVICE_SE:
1183       se_cert_type = SLI_SE_COMMAND_CERT_SE;
1184       break;
1185 
1186     case SL_SE_CERT_DEVICE_HOST:
1187       se_cert_type = SLI_SE_COMMAND_CERT_HOST;
1188       break;
1189 
1190     default:
1191       return SL_STATUS_INVALID_PARAMETER;
1192       break;
1193   }
1194 
1195   // SE command structures
1196   sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_READ_USER_CERT | se_cert_type);
1197 
1198 #if  _SILICON_LABS_32B_SERIES_2_CONFIG > 2
1199   // One parameter is required, but has no effect
1200   SE_addParameter(se_cmd, 0);
1201 #endif //
1202 
1203   SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(cert, num_bytes);
1204   SE_addDataOutput(se_cmd, &out_data);
1205 
1206   return sli_se_execute_and_wait(cmd_ctx);
1207 }
1208 
1209 #endif // defined(SEMAILBOX_PRESENT)
1210 
1211 /// @} (end addtogroup sl_se)
1212 
1213 #endif // defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
1214