1 /***************************************************************************//**
2 * \file cy_cryptolite_trng.c
3 * \version 2.50
4 *
5 * \brief
6 * Provides API implementation of the Cryptolite TRNG PDL driver.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright (c) 2022, Cypress Semiconductor Corporation (an Infineon company) or
11 * an affiliate of Cypress Semiconductor Corporation.
12 * SPDX-License-Identifier: Apache-2.0
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 *******************************************************************************/
26
27
28 #include "cy_device.h"
29
30 #if defined (CY_IP_MXCRYPTOLITE)
31
32 #include "cy_cryptolite_trng.h"
33 #include "cy_cryptolite_trng_config.h"
34
35 #if defined(__cplusplus)
36 extern "C" {
37 #endif
38
39 #if (CRYPTOLITE_TRNG_PRESENT == 1)
40 #if defined(CY_CRYPTOLITE_CFG_TRNG_C)
41
42 const cy_stc_cryptolite_trng_config_t cy_cryptolite_trngDefaultConfig =
43 {
44 (uint8_t)CY_CRYPTOLITE_DEF_TRNG_SAMPLE_CLOCK_DIV, /* sampleClockDiv */
45 (uint8_t)CY_CRYPTOLITE_DEF_TRNG_RED_CLOCK_DIV, /* reducedClockDiv */
46 (uint8_t)CY_CRYPTOLITE_DEF_TRNG_INIT_DELAY, /* initDelay */
47 CY_CRYPTOLITE_DEF_TRNG_VON_NEUMANN_CORR, /* vnCorrectorEnable */
48 CY_CRYPTOLITE_DEF_TRNG_AP_ENABLE, /* AP test enable */
49 CY_CRYPTOLITE_DEF_TRNG_RC_ENABLE, /* RC test enable */
50 CY_CRYPTOLITE_DEF_TRNG_STOP_ON_AP_DETECT, /* stopOnAPDetect */
51 CY_CRYPTOLITE_DEF_TRNG_STOP_ON_RC_DETECT, /* stopOnRCDetect */
52 CY_CRYPTOLITE_DEF_TRNG_GARO, /* garo31Poly */
53 CY_CRYPTOLITE_DEF_TRNG_FIRO, /* firo31Poly */
54 CY_CRYPTOLITE_DEF_TRNG_BITSTREAM_SEL, /* monBitStreamSelect */
55 (uint8_t)CY_CRYPTOLITE_DEF_TRNG_CUTOFF_COUNT8, /* monCutoffCount8 */
56 (uint16_t)CY_CRYPTOLITE_DEF_TRNG_CUTOFF_COUNT16, /* monCutoffCount16 */
57 (uint16_t)CY_CRYPTOLITE_DEF_TRNG_WINDOW_SIZE /* monWindowSize */
58 };
59
60 /*******************************************************************************
61 * Function Name: Cy_Cryptolite_Trng_Init
62 ****************************************************************************//*
63 *
64 * Initialize the TRNG hardware submodule
65 *
66 * \param base
67 * The pointer to the CRYPTOLITE instance.
68 *
69 * \param config
70 * The pointer to the configuration structure. If NULL default config is used.
71 *
72 * \return
73 * \ref cy_en_cryptolite_status_t
74 *
75 *******************************************************************************/
Cy_Cryptolite_Trng_Init(CRYPTOLITE_Type * base,cy_stc_cryptolite_trng_config_t * config)76 cy_en_cryptolite_status_t Cy_Cryptolite_Trng_Init(CRYPTOLITE_Type *base, cy_stc_cryptolite_trng_config_t *config)
77 {
78 if(NULL != base)
79 {
80 if (NULL == config)
81 {
82 config = (cy_stc_cryptolite_trng_config_t *)&cy_cryptolite_trngDefaultConfig;
83 }
84 if(!(CY_CRYPTOLITE_IS_BS_SELECT_VALID(config->monBitStreamSelect)))
85 {
86 return CY_CRYPTOLITE_BAD_PARAMS;
87 }
88
89 Cy_Cryptolite_Trng_ClearInterrupt(base, CRYPTOLITE_INTR_TRNG_DATA_AVAILABLE_Msk | CRYPTOLITE_INTR_TRNG_INITIALIZED_Msk);
90 Cy_Cryptolite_Trng_MonClearHealthStatus(base);
91
92 REG_CRYPTOLITE_TRNG_GARO_CTL(base) = config->garo31Poly;
93 REG_CRYPTOLITE_TRNG_FIRO_CTL(base) = config->firo31Poly;
94
95 REG_CRYPTOLITE_TRNG_CTL0(base) = (uint32_t)(_VAL2FLD(CRYPTOLITE_TRNG_CTL0_SAMPLE_CLOCK_DIV, config->sampleClockDiv)
96 | _VAL2FLD(CRYPTOLITE_TRNG_CTL0_RED_CLOCK_DIV, config->reducedClockDiv)
97 | _VAL2FLD(CRYPTOLITE_TRNG_CTL0_INIT_DELAY, config->initDelay)
98 | _VAL2FLD(CRYPTOLITE_TRNG_CTL0_VON_NEUMANN_CORR, config->vnCorrectorEnable)
99 | _VAL2FLD(CRYPTOLITE_TRNG_CTL0_FEEDBACK_EN, 0U)
100 | _VAL2FLD(CRYPTOLITE_TRNG_CTL0_STOP_ON_AP_DETECT, config->stopOnAPDetect)
101 | _VAL2FLD(CRYPTOLITE_TRNG_CTL0_STOP_ON_RC_DETECT, config->stopOnRCDetect));
102
103 REG_CRYPTOLITE_TRNG_MON_CTL(base) = (uint32_t)_VAL2FLD(CRYPTOLITE_TRNG_MON_CTL_BITSTREAM_SEL, config->monBitStreamSelect);
104
105 /*Enable Health Monitor tests*/
106 if (config->EnableAPTest)
107 {
108 Cy_Cryptolite_Trng_MonEnableApTest(base);
109 }
110 if (config->EnableRCTest)
111 {
112 Cy_Cryptolite_Trng_MonEnableRcTest(base);
113 }
114
115 REG_CRYPTOLITE_TRNG_MON_RC_CTL(base) = (uint32_t)_VAL2FLD(CRYPTOLITE_TRNG_MON_RC_CTL_CUTOFF_COUNT8, config->monCutoffCount8);
116
117 REG_CRYPTOLITE_TRNG_MON_AP_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTOLITE_TRNG_MON_AP_CTL_CUTOFF_COUNT16, config->monCutoffCount16)
118 | _VAL2FLD(CRYPTOLITE_TRNG_MON_AP_CTL_WINDOW_SIZE, config->monWindowSize));
119
120 return (CY_CRYPTOLITE_SUCCESS);
121 }
122 return (CY_CRYPTOLITE_BAD_PARAMS);
123 }
124
125 /*******************************************************************************
126 * Function Name: Cy_Cryptolite_Trng_DeInit
127 ****************************************************************************//*
128 *
129 * Clears all TRNG registers by set to hardware default values.
130 *
131 * \param base
132 * The pointer to the CRYPTOLITE instance.
133 *
134 * \return
135 * The error / status code. See \ref cy_en_cryptolite_status_t.
136 *
137 *******************************************************************************/
Cy_Cryptolite_Trng_DeInit(CRYPTOLITE_Type * base)138 cy_en_cryptolite_status_t Cy_Cryptolite_Trng_DeInit(CRYPTOLITE_Type *base)
139 {
140 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_BAD_PARAMS;
141
142 if( NULL != base)
143 {
144 REG_CRYPTOLITE_TRNG_CTL0(base) = (uint32_t)_VAL2FLD(CRYPTOLITE_TRNG_CTL0_INIT_DELAY, 3U);
145 REG_CRYPTOLITE_TRNG_CTL1(base) = 0UL;
146
147 REG_CRYPTOLITE_TRNG_GARO_CTL(base) = 0UL;
148 REG_CRYPTOLITE_TRNG_FIRO_CTL(base) = 0UL;
149
150 REG_CRYPTOLITE_TRNG_MON_CTL(base) = 2UL;
151
152 REG_CRYPTOLITE_TRNG_MON_RC_CTL(base) = 0UL;
153 REG_CRYPTOLITE_TRNG_MON_AP_CTL(base) = 0UL;
154
155 Cy_Cryptolite_Trng_ClearInterrupt(base, CRYPTOLITE_INTR_TRNG_DATA_AVAILABLE_Msk | CRYPTOLITE_INTR_TRNG_INITIALIZED_Msk);
156 Cy_Cryptolite_Trng_MonClearHealthStatus(base);
157
158 status = CY_CRYPTOLITE_SUCCESS;
159 }
160
161 return status;
162 }
163
164 /*******************************************************************************
165 * Function Name: Cy_Cryptolite_Trng_Enable
166 ****************************************************************************//*
167 *
168 * Starts a random number generation.
169 *
170 * \param base
171 * The pointer to the CRYPTOLITE instance.
172 *
173 * \return
174 * The error / status code. See \ref cy_en_cryptolite_status_t.
175 *
176 *******************************************************************************/
Cy_Cryptolite_Trng_Enable(CRYPTOLITE_Type * base)177 cy_en_cryptolite_status_t Cy_Cryptolite_Trng_Enable(CRYPTOLITE_Type *base)
178 {
179 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_BAD_PARAMS;
180
181 if( NULL != base)
182 {
183 status = CY_CRYPTOLITE_SUCCESS;
184 if (!Cy_Cryptolite_Trng_IsEnabled(base))
185 {
186 Cy_Cryptolite_Trng_ClearInterrupt(base, CRYPTOLITE_INTR_TRNG_DATA_AVAILABLE_Msk | CRYPTOLITE_INTR_TRNG_INITIALIZED_Msk);
187
188 REG_CRYPTOLITE_TRNG_CTL1(base) = (uint32_t)(_VAL2FLD(CRYPTOLITE_TRNG_CTL1_RO11_EN, CY_CRYPTOLITE_TRNG_RO_ENABLE)
189 | _VAL2FLD(CRYPTOLITE_TRNG_CTL1_RO15_EN, CY_CRYPTOLITE_TRNG_RO_ENABLE)
190 | _VAL2FLD(CRYPTOLITE_TRNG_CTL1_GARO15_EN, CY_CRYPTOLITE_TRNG_RO_ENABLE)
191 | _VAL2FLD(CRYPTOLITE_TRNG_CTL1_GARO31_EN, CY_CRYPTOLITE_TRNG_RO_ENABLE)
192 | _VAL2FLD(CRYPTOLITE_TRNG_CTL1_FIRO15_EN, CY_CRYPTOLITE_TRNG_RO_ENABLE)
193 | _VAL2FLD(CRYPTOLITE_TRNG_CTL1_FIRO31_EN, CY_CRYPTOLITE_TRNG_RO_ENABLE));
194 /*wait for TRNG Init*/
195 Cy_Cryptolite_Trng_WaitForInit(base);
196 }
197 }
198
199 return status;
200 }
201
202 /*******************************************************************************
203 * Function Name: Cy_Cryptolite_Trng_IsEnabled
204 ****************************************************************************//*
205 *
206 * Checks if Trng is enabled.
207 *
208 * \param base
209 * The pointer to the CRYPTOLITE instance.
210 *
211 * \return
212 * The 'true' if Trng enabled 'false' otherwise.
213 *
214 *******************************************************************************/
Cy_Cryptolite_Trng_IsEnabled(CRYPTOLITE_Type * base)215 bool Cy_Cryptolite_Trng_IsEnabled(CRYPTOLITE_Type *base)
216 {
217 if( NULL != base)
218 {
219 return ((REG_CRYPTOLITE_TRNG_CTL1(base) & CY_CRYPTOLITE_TRNG_RO_ALL_MASK) != 0U);
220 }
221
222 return false;
223 }
224
225 /*******************************************************************************
226 * Function Name: Cy_Cryptolite_Trng_Disable
227 ****************************************************************************//*
228 *
229 * Stops the random number generation.
230 *
231 * \param base
232 * The pointer to the CRYPTOLITE instance.
233 *
234 * \return
235 * The error / status code. See \ref cy_en_cryptolite_status_t.
236 *
237 *******************************************************************************/
Cy_Cryptolite_Trng_Disable(CRYPTOLITE_Type * base)238 cy_en_cryptolite_status_t Cy_Cryptolite_Trng_Disable(CRYPTOLITE_Type *base)
239 {
240 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_BAD_PARAMS;
241
242 if( NULL != base)
243 {
244 status = CY_CRYPTOLITE_SUCCESS;
245 if (Cy_Cryptolite_Trng_IsEnabled(base))
246 {
247 Cy_Cryptolite_Trng_ClearInterrupt(base, CRYPTOLITE_INTR_TRNG_DATA_AVAILABLE_Msk | CRYPTOLITE_INTR_TRNG_INITIALIZED_Msk);
248 REG_CRYPTOLITE_TRNG_CTL1(base) = (uint32_t)0x0;
249 }
250 }
251
252 return status;
253 }
254
255 /*******************************************************************************
256 * Function Name: Cy_Cryptolite_Trng_ReadData
257 ****************************************************************************//*
258 *
259 * Reads in blocking mode a generated random number.
260 *
261 * \note
262 * Call this API only after Cy_Cryptolite_Trng_Enable() is successful.
263 *
264 * \param base
265 * The pointer to the CRYPTO instance.
266 *
267 * \param randomData
268 * The pointer to a generated true random number.
269 *
270 * \return
271 * The error / status code. See \ref cy_en_cryptolite_status_t.
272 *
273 *******************************************************************************/
Cy_Cryptolite_Trng_ReadData(CRYPTOLITE_Type * base,uint32_t * randomData)274 cy_en_cryptolite_status_t Cy_Cryptolite_Trng_ReadData(CRYPTOLITE_Type *base, uint32_t *randomData)
275 {
276 cy_en_cryptolite_status_t status = CY_CRYPTOLITE_BAD_PARAMS;
277 uint8_t stateHealthMon;
278
279 if(NULL != base && NULL != randomData)
280 {
281 if (Cy_Cryptolite_Trng_IsEnabled(base))
282 {
283 status = CY_CRYPTOLITE_SUCCESS;
284
285 Cy_Cryptolite_Trng_WaitForComplete(base);
286
287 *randomData = Cy_Cryptolite_Trng_GetData(base);
288
289 stateHealthMon = Cy_Cryptolite_Trng_MonGetHealthStatus(base);
290 if (0x0u != stateHealthMon)
291 {
292 status = CY_CRYPTOLITE_TRNG_UNHEALTHY;
293 }
294 }
295 else
296 {
297 status = CY_CRYPTOLITE_TRNG_NOT_ENABLED;
298 }
299 }
300 return status;
301 }
302
303 /*******************************************************************************
304 * Function Name: Cy_Cryptolite_Trng
305 ****************************************************************************//*
306 *
307 * Generates a True Random Number.
308 *
309 * \param base
310 * The pointer to the CRYPTOLITE instance.
311 *
312 * \param randomNum
313 * The pointer to a generated true random number.
314 *
315 * \return
316 * \ref cy_en_cryptolite_status_t
317 *
318 *******************************************************************************/
Cy_Cryptolite_Trng(CRYPTOLITE_Type * base,uint32_t * randomNum)319 cy_en_cryptolite_status_t Cy_Cryptolite_Trng(CRYPTOLITE_Type *base, uint32_t *randomNum)
320 {
321 cy_en_cryptolite_status_t status;
322
323 status = Cy_Cryptolite_Trng_Enable(base);
324
325 if (CY_CRYPTOLITE_SUCCESS == status)
326 {
327 status = Cy_Cryptolite_Trng_ReadData(base, randomNum);
328 }
329
330 (void)Cy_Cryptolite_Trng_Disable(base);
331
332 return (status);
333 }
334
335 #endif
336 #endif
337
338 #if defined(__cplusplus)
339 }
340 #endif
341
342
343 #endif /* CY_IP_MXCRYPTOLITE */
344
345
346 /* [] END OF FILE */
347