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(¶meters, 8);
620 SE_addDataInput(se_cmd, ¶meters_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(¶meters, 8);
751 SE_addDataInput(se_cmd, ¶meters_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