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