1 /***************************************************************************//**
2 * \file cy_crypto_core_trng.c
3 * \version 2.120
4 *
5 * \brief
6 *  This file provides the source code to the API for the TRNG
7 *  in the Crypto block driver.
8 *
9 ********************************************************************************
10 * Copyright 2016-2019 Cypress Semiconductor Corporation
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 *    http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25 
26 
27 #include "cy_crypto_core_trng.h"
28 
29 #if defined(CY_IP_MXCRYPTO)
30 
31 #if defined(__cplusplus)
32 extern "C" {
33 #endif
34 
35 #if (CPUSS_CRYPTO_TR == 1) && defined(CY_CRYPTO_CFG_TRNG_C)
36 
37 #if defined(CY_CRYPTO_CFG_HW_V1_ENABLE)
38 #include "cy_crypto_core_hw_v1.h"
39 #endif
40 
41 const cy_stc_crypto_trng_config_t cy_trngDefaultConfig =
42 {
43     (uint8_t)CY_CRYPTO_DEF_TR_SAMPLE_CLOCK_DIV,            /* sampleClockDiv */
44     (uint8_t)CY_CRYPTO_DEF_TR_RED_CLOCK_DIV,               /* reducedClockDiv */
45     (uint8_t)CY_CRYPTO_DEF_TR_INIT_DELAY,                  /* initDelay */
46     CY_CRYPTO_DEF_TR_VON_NEUMANN_CORR,            /* vnCorrectorEnable */
47     CY_CRYPTO_DEF_TR_STOP_ON_AP_DETECT,           /* stopOnAPDetect */
48     CY_CRYPTO_DEF_TR_STOP_ON_RC_DETECT,           /* stopOnRCDetect */
49     CY_CRYPTO_DEF_TR_RO11_EN,                     /* ro11Enable */
50     CY_CRYPTO_DEF_TR_RO15_EN,                     /* ro15Enable */
51     CY_CRYPTO_DEF_TR_GARO15_EN,                   /* garo15Enable */
52     CY_CRYPTO_DEF_TR_GARO31_EN,                   /* garo31Enable */
53     CY_CRYPTO_DEF_TR_FIRO15_EN,                   /* firo15Enable */
54     CY_CRYPTO_DEF_TR_FIRO31_EN,                   /* firo31Enable */
55     CY_CRYPTO_DEF_TR_GARO,                        /* garo31Poly */
56     CY_CRYPTO_DEF_TR_FIRO,                        /* firo31Poly */
57     CY_CRYPTO_DEF_TR_BITSTREAM_SEL,               /* monBitStreamSelect */
58     (uint8_t)CY_CRYPTO_DEF_TR_CUTOFF_COUNT8,               /* monCutoffCount8 */
59     (uint16_t)CY_CRYPTO_DEF_TR_CUTOFF_COUNT16,              /* monCutoffCount16 */
60     (uint16_t)CY_CRYPTO_DEF_TR_WINDOW_SIZE                  /* monWindowSize */
61 };
62 
63 /*******************************************************************************
64 * Function Name: Cy_Crypto_Core_Trng_Init
65 ****************************************************************************//**
66 *
67 * Initialize the TRNG hardware submodule
68 *
69 * \pre If the TRNG submodule is initialized previously, the
70 * \ref Cy_Crypto_Core_Trng_DeInit() must be called before calling this function.
71 *
72 * \param base
73 * The pointer to the CRYPTO instance.
74 *
75 * \param config
76 * The pointer to the configuration structure.
77 *
78 *******************************************************************************/
Cy_Crypto_Core_Trng_Init(CRYPTO_Type * base,cy_stc_crypto_trng_config_t * config)79 void Cy_Crypto_Core_Trng_Init(CRYPTO_Type *base, cy_stc_crypto_trng_config_t *config)
80 {
81     if(NULL != base)
82     {
83         if (NULL == config)
84         {
85             config = (cy_stc_crypto_trng_config_t *)&cy_trngDefaultConfig;
86         }
87         else
88         {
89             CY_ASSERT_L3(CY_CRYPTO_IS_BS_SELECT_VALID(config->monBitStreamSelect));
90         }
91 
92         REG_CRYPTO_TR_MON_CMD(base) = 0UL;
93         REG_CRYPTO_TR_CTL1(base) = 0UL;
94 
95         Cy_Crypto_Core_ClearInterrupt(base, CRYPTO_INTR_TR_DATA_AVAILABLE_Msk | CRYPTO_INTR_TR_INITIALIZED_Msk);
96         Cy_Crypto_Core_Trng_MonClearHealthStatus(base);
97 
98         REG_CRYPTO_TR_GARO_CTL(base) = config->garo31Poly;
99         REG_CRYPTO_TR_FIRO_CTL(base) = config->firo31Poly;
100 
101         REG_CRYPTO_TR_CTL0(base) = (uint32_t)(_VAL2FLD(CRYPTO_TR_CTL0_SAMPLE_CLOCK_DIV, config->sampleClockDiv)
102                                             | _VAL2FLD(CRYPTO_TR_CTL0_RED_CLOCK_DIV, config->reducedClockDiv)
103                                             | _VAL2FLD(CRYPTO_TR_CTL0_INIT_DELAY, config->initDelay)
104                                             | _VAL2FLD(CRYPTO_TR_CTL0_VON_NEUMANN_CORR, config->vnCorrectorEnable)
105                                             | _VAL2FLD(CRYPTO_TR_CTL0_STOP_ON_AP_DETECT, config->stopOnAPDetect)
106                                             | _VAL2FLD(CRYPTO_TR_CTL0_STOP_ON_RC_DETECT, config->stopOnRCDetect));
107 
108         REG_CRYPTO_TR_CTL1(base) = (uint32_t)(_VAL2FLD(CRYPTO_TR_CTL1_RO11_EN, config->ro11Enable)
109                                             | _VAL2FLD(CRYPTO_TR_CTL1_RO15_EN, config->ro15Enable)
110                                             | _VAL2FLD(CRYPTO_TR_CTL1_GARO15_EN, config->garo15Enable)
111                                             | _VAL2FLD(CRYPTO_TR_CTL1_GARO31_EN, config->garo31Enable)
112                                             | _VAL2FLD(CRYPTO_TR_CTL1_FIRO15_EN, config->firo15Enable)
113                                             | _VAL2FLD(CRYPTO_TR_CTL1_FIRO31_EN, config->firo31Enable));
114 
115         REG_CRYPTO_TR_MON_CTL(base) = (uint32_t)_VAL2FLD(CRYPTO_TR_MON_CTL_BITSTREAM_SEL, config->monBitStreamSelect);
116 
117         REG_CRYPTO_TR_MON_RC_CTL(base) = (uint32_t)_VAL2FLD(CRYPTO_TR_MON_RC_CTL_CUTOFF_COUNT8, config->monCutoffCount8);
118 
119         REG_CRYPTO_TR_MON_AP_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_TR_MON_AP_CTL_CUTOFF_COUNT16, config->monCutoffCount16)
120                                                   | _VAL2FLD(CRYPTO_TR_MON_AP_CTL_WINDOW_SIZE, config->monWindowSize));
121     }
122 }
123 
124 /*******************************************************************************
125 * Function Name: Cy_Crypto_Core_Trng_DeInit
126 ****************************************************************************//**
127 *
128 * Clears all TRNG registers by set to hardware default values.
129 *
130 * \param base
131 * The pointer to the CRYPTO instance.
132 *
133 *******************************************************************************/
Cy_Crypto_Core_Trng_DeInit(CRYPTO_Type * base)134 void Cy_Crypto_Core_Trng_DeInit(CRYPTO_Type *base)
135 {
136     REG_CRYPTO_TR_CTL0(base) = (uint32_t)_VAL2FLD(CRYPTO_TR_CTL0_INIT_DELAY, 3U);
137     REG_CRYPTO_TR_CTL1(base) = 0UL;
138 
139     #if defined(CY_CRYPTO_CFG_HW_V2_ENABLE)
140     REG_CRYPTO_TR_CTL2(base) = 0UL;
141     REG_CRYPTO_TR_CMD(base) = 0UL;
142     #endif
143 
144     REG_CRYPTO_TR_GARO_CTL(base) = 0UL;
145     REG_CRYPTO_TR_FIRO_CTL(base) = 0UL;
146 
147     REG_CRYPTO_TR_MON_CTL(base) = 2UL;
148 
149     REG_CRYPTO_TR_MON_RC_CTL(base) = 0UL;
150     REG_CRYPTO_TR_MON_AP_CTL(base) = 0UL;
151 
152     REG_CRYPTO_TR_MON_CMD(base) = 0UL;
153 }
154 
155 /*******************************************************************************
156 * Function Name: Cy_Crypto_Core_Trng_Start
157 ****************************************************************************//**
158 *
159 * Starts a random number generation.
160 *
161 * \param base
162 * The pointer to the CRYPTO instance.
163 *
164 * \param dataSize
165 * The maximum length of a random number, in the range [0, 32] bits.
166 *
167 * \return
168 * The error / status code. See \ref cy_en_crypto_status_t.
169 *
170 *******************************************************************************/
Cy_Crypto_Core_Trng_Start(CRYPTO_Type * base,uint32_t dataSize)171 cy_en_crypto_status_t Cy_Crypto_Core_Trng_Start(CRYPTO_Type *base, uint32_t dataSize)
172 {
173     cy_en_crypto_status_t status = CY_CRYPTO_NOT_INITIALIZED;
174 
175     if (Cy_Crypto_Core_IsEnabled(base))
176     {
177         Cy_Crypto_Core_Trng_WaitForReady(base);
178 
179         if (Cy_Crypto_Core_Trng_AnyRoEnabled(base))
180         {
181             if (Cy_Crypto_Core_Trng_IsInitialized(base))
182             {
183                 status = CY_CRYPTO_BAD_PARAMS;
184 
185                 Cy_Crypto_Core_ClearInterrupt(base, CRYPTO_INTR_TR_DATA_AVAILABLE_Msk);
186 
187                 if (dataSize <= 32U)
188                 {
189                     status = CY_CRYPTO_SUCCESS;
190                     if (CY_CRYPTO_V1)
191                     {
192                         #if defined(CY_CRYPTO_CFG_HW_V1_ENABLE)
193                         Cy_Crypto_SetReg1Instr(base, dataSize);
194                         Cy_Crypto_Run1ParamInstr(base, CY_CRYPTO_V1_TRNG_OPC, CY_CRYPTO_RSRC0_SHIFT);
195                         #endif
196                     }
197                     else
198                     {
199                         #if defined(CY_CRYPTO_CFG_HW_V2_ENABLE)
200                         REG_CRYPTO_TR_CTL2(base) = dataSize;
201                         REG_CRYPTO_TR_CMD(base) = 1UL;
202                         #endif
203                     }
204                 }
205             }
206         }
207     }
208     return status;
209 }
210 
211 /*******************************************************************************
212 * Function Name: Cy_Crypto_Core_Trng_ReadData
213 ****************************************************************************//**
214 *
215 * Reads in blocking mode a generated random number.
216 *
217 * \note
218 * Call this API only after Cy_Crypto_Core_Trng_Start() is successful.
219 *
220 * \param base
221 * The pointer to the CRYPTO instance.
222 *
223 * \param randomData
224 * The pointer to a generated true random number. Must be 4-byte aligned.
225 *
226 * \return
227 * The error / status code. See \ref cy_en_crypto_status_t.
228 *
229 *******************************************************************************/
Cy_Crypto_Core_Trng_ReadData(CRYPTO_Type * base,uint32_t * randomData)230 cy_en_crypto_status_t Cy_Crypto_Core_Trng_ReadData(CRYPTO_Type *base, uint32_t *randomData)
231 {
232     cy_en_crypto_status_t status = CY_CRYPTO_NOT_INITIALIZED;
233     uint8_t stateHealthMon;
234 
235     if (Cy_Crypto_Core_IsEnabled(base))
236     {
237         if (false != Cy_Crypto_Core_Trng_AnyRoEnabled(base))
238         {
239             status = CY_CRYPTO_SUCCESS;
240 
241             Cy_Crypto_Core_Trng_WaitForComplete(base);
242 
243             *randomData = Cy_Crypto_Core_Trng_GetData(base);
244 
245             stateHealthMon = Cy_Crypto_Core_Trng_MonGetHealthStatus(base);
246             if (0u != stateHealthMon)
247             {
248                 status = CY_CRYPTO_TRNG_UNHEALTHY;
249             }
250         }
251     }
252     return status;
253 }
254 
255 /*******************************************************************************
256 * Function Name: Cy_Crypto_Core_Trng
257 ****************************************************************************//**
258 *
259 * Generates a True Random Number.
260 *
261 * \param base
262 * The pointer to the CRYPTO instance.
263 *
264 * \param GAROPol
265 * The polynomial for the programmable Galois ring oscillator.
266 *
267 * \param FIROPol
268 * The polynomial for the programmable Fibonacci ring oscillator.
269 *
270 * \param max
271 * The maximum length of a random number, in the range of [0, 32] bits.
272 *
273 * \param randomNum
274 * The pointer to a generated true random number. Must be 4-byte aligned.
275 *
276 * \return
277 * \ref cy_en_crypto_status_t
278 *
279 * \funcusage
280 * \snippet crypto/snippet/main.c snippet_myCryptoCoreTrngUse
281 *
282 *******************************************************************************/
Cy_Crypto_Core_Trng(CRYPTO_Type * base,uint32_t GAROPol,uint32_t FIROPol,uint32_t max,uint32_t * randomNum)283 cy_en_crypto_status_t Cy_Crypto_Core_Trng(CRYPTO_Type *base,
284                                              uint32_t  GAROPol,
285                                              uint32_t  FIROPol,
286                                              uint32_t  max,
287                                              uint32_t *randomNum)
288 {
289     cy_en_crypto_status_t status;
290 
291     Cy_Crypto_Core_Trng_Init(base, (cy_stc_crypto_trng_config_t *)&cy_trngDefaultConfig);
292 
293     Cy_Crypto_Core_Trng_SetGaroPoly(base, GAROPol);
294     Cy_Crypto_Core_Trng_SetFiroPoly(base, FIROPol);
295 
296     status = Cy_Crypto_Core_Trng_Start(base, max);
297 
298     if (CY_CRYPTO_SUCCESS == status)
299     {
300         status = Cy_Crypto_Core_Trng_ReadData(base, randomNum);
301     }
302 
303     return (status);
304 }
305 
306 #endif /* (CPUSS_CRYPTO_TR == 1) && defined(CY_CRYPTO_CFG_TRNG_C) */
307 
308 #if defined(__cplusplus)
309 }
310 #endif
311 
312 #endif /* defined(CY_IP_MXCRYPTO) */
313 
314 
315 /* [] END OF FILE */
316