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)
33
34 #include "sl_se_manager.h"
35 #include "sli_se_manager_internal.h"
36 #include "em_se.h"
37 #include "em_system.h"
38 #include <string.h>
39
40 /// @addtogroup sl_se_manager
41 /// @{
42
43 // -----------------------------------------------------------------------------
44 // Global Functions
45
46 /***************************************************************************//**
47 * Get random data from hardware TRNG.
48 ******************************************************************************/
sl_se_get_random(sl_se_command_context_t * cmd_ctx,void * data,uint32_t num_bytes)49 sl_status_t sl_se_get_random(sl_se_command_context_t *cmd_ctx,
50 void * data,
51 uint32_t num_bytes)
52 {
53 SE_Command_t *se_cmd;
54 sl_status_t ret;
55 uint32_t surplus_bytes, i;
56 uint32_t surplus_word = 0;
57
58 if (cmd_ctx == NULL || (num_bytes != 0 && data == NULL)) {
59 return SL_STATUS_INVALID_PARAMETER;
60 }
61
62 se_cmd = &cmd_ctx->command;
63 surplus_bytes = num_bytes & 0x3U;
64 num_bytes &= ~0x3U;
65
66 if (num_bytes > 0U) {
67 sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_TRNG_GET_RANDOM);
68 SE_DataTransfer_t data_out = SE_DATATRANSFER_DEFAULT(data, num_bytes);
69
70 SE_addDataOutput(se_cmd, &data_out);
71 SE_addParameter(se_cmd, num_bytes);
72
73 // Execute and wait
74 if ((ret = sli_se_execute_and_wait(cmd_ctx)) != SL_STATUS_OK) {
75 memset(data, 0, num_bytes);
76 return ret;
77 }
78 }
79
80 if (surplus_bytes > 0) {
81 sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_TRNG_GET_RANDOM);
82 SE_DataTransfer_t data_out = SE_DATATRANSFER_DEFAULT(&surplus_word, 4);
83
84 SE_addDataOutput(se_cmd, &data_out);
85 SE_addParameter(se_cmd, 4);
86
87 // Execute and wait
88 if ((ret = sli_se_execute_and_wait(cmd_ctx)) != SL_STATUS_OK) {
89 memset(data, 0, num_bytes + surplus_bytes);
90 return ret;
91 }
92
93 uint8_t *output = (uint8_t*)data + num_bytes;
94 for (i = 0; i < surplus_bytes; i++) {
95 output[i] = (surplus_word >> (i * 8U)) & 0xFFU;
96 }
97 }
98
99 return SL_STATUS_OK;
100 }
101
102 /** @} (end addtogroup sl_se) */
103
104 #endif // defined(SEMAILBOX_PRESENT)
105