1 /***************************************************************************//**
2 * \file cy_crypto_core_crc_v2.c
3 * \version 2.120
4 *
5 * \brief
6 *  This file provides the source code for CRC API
7 *  in the Crypto driver.
8 *
9 ********************************************************************************
10 * \copyright
11 * Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or
12 * an affiliate of Cypress Semiconductor Corporation.
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 *    http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27 
28 #include "cy_device.h"
29 
30 #if defined(CY_IP_MXCRYPTO)
31 
32 #include "cy_crypto_core_crc_v2.h"
33 
34 #if defined(CY_CRYPTO_CFG_HW_V2_ENABLE)
35 
36 #if defined(__cplusplus)
37 extern "C" {
38 #endif
39 
40 #if (CPUSS_CRYPTO_CRC == 1) && defined(CY_CRYPTO_CFG_CRC_C)
41 
42 #include "cy_crypto_core_hw_v2.h"
43 #include "cy_syslib.h"
44 
45 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 11.3', 3, \
46 'CRYPTO_Type will typecast to either CRYPTO_V1_Type or CRYPTO_V2_Type but not both on PDL initialization based on the target device at compile time.')
47 
48 /*******************************************************************************
49 * Function Name: Cy_Crypto_Core_V2_Crc_Init
50 ****************************************************************************//**
51 *
52 * Initializes CRC calculation.
53 *
54 * \param base
55 * The pointer to the CRYPTO instance.
56 *
57 * \param polynomial
58 * The polynomial (specified using 32 bits) used in the computing CRC.
59 *
60 * \param dataReverse
61 * The order in which data bytes are processed. 0 - MSB first; 1- LSB first.
62 *
63 * \param dataXor
64 * The byte mask for XORing data
65 *
66 * \param remReverse
67 * A remainder reverse: 0 means the remainder is not reversed. 1 means reversed.
68 *
69 * \param remXor
70 * Specifies a mask with which the LFSR32 register is XORed to produce a remainder.
71 *
72 * \return
73 * \ref cy_en_crypto_status_t
74 *
75 *******************************************************************************/
Cy_Crypto_Core_V2_Crc_Init(CRYPTO_Type * base,uint32_t polynomial,uint32_t dataReverse,uint32_t dataXor,uint32_t remReverse,uint32_t remXor)76 cy_en_crypto_status_t Cy_Crypto_Core_V2_Crc_Init(CRYPTO_Type *base,
77                                         uint32_t polynomial,
78                                         uint32_t dataReverse,
79                                         uint32_t dataXor,
80                                         uint32_t remReverse,
81                                         uint32_t remXor)
82 {
83 
84     /* Specifies the bit order in which a data Byte is processed
85      * (reversal is performed after XORing):
86      *                                       '0': Most significant bit (bit 1) first.
87      *                                       '1': Least significant bit (bit 0) first. */
88     REG_CRYPTO_CRC_CTL(base) = (uint32_t)( (_VAL2FLD(CRYPTO_V2_CRC_CTL_DATA_REVERSE, dataReverse)) |
89                                            (_VAL2FLD(CRYPTO_V2_CRC_CTL_REM_REVERSE,  remReverse)) );
90 
91     /* Specifies a byte mask with which each data byte is XORed.
92      * The XOR is performed before data reversal. */
93     REG_CRYPTO_CRC_DATA_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_V2_CRC_DATA_CTL_DATA_XOR, dataXor));
94 
95     /* CRC polynomial. The polynomial is represented WITHOUT the high order bit
96      * (this bit is always assumed '1'). */
97     REG_CRYPTO_CRC_POL_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_V2_CRC_POL_CTL_POLYNOMIAL, polynomial));
98 
99     /*Specifies a mask with which the CRC_LFSR_CTL.LFSR32 register is XORed to produce a remainder.
100      * The XOR is performed before remainder reversal. */
101     REG_CRYPTO_CRC_REM_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_V2_CRC_REM_CTL_REM_XOR, remXor));
102 
103     return (CY_CRYPTO_SUCCESS);
104 }
105 
106 /*******************************************************************************
107 * Function Name: Cy_Crypto_Core_V2_Crc
108 ****************************************************************************//**
109 *
110 * Performs CRC calculation on a message.
111 *
112 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameter data must align and end in 32 byte boundary.
113 * For CAT1A and CAT1C devices with DCache disabled, crc must be 4-Byte aligned.
114 *
115 * \param base
116 * The pointer to the CRYPTO instance.
117 *
118 * \param crc
119 * The pointer to a computed CRC value.
120 *
121 * \param data
122 * The pointer to the message whose CRC is being computed.
123 *
124 * \param dataSize
125 * The size of a message in bytes.
126 *
127 * \param lfsrInitState
128 * The initial state of the LFSR.
129 *
130 * \return
131 * \ref cy_en_crypto_status_t
132 *
133 *******************************************************************************/
Cy_Crypto_Core_V2_Crc(CRYPTO_Type * base,uint32_t * crc,void const * data,uint32_t dataSize,uint32_t lfsrInitState)134 cy_en_crypto_status_t Cy_Crypto_Core_V2_Crc(CRYPTO_Type *base,
135                                         uint32_t *crc,
136                                         void const  *data,
137                                         uint32_t  dataSize,
138                                         uint32_t  lfsrInitState)
139 {
140 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
141     /* Flush the cache */
142     SCB_CleanDCache_by_Addr((volatile void *)data,(int32_t)dataSize);
143 #endif
144     uint8_t *dataRemap;
145     dataRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(data);
146 
147     /* Fill the FIFO with the instruction parameters */
148     Cy_Crypto_Core_V2_FFStart(base, CY_CRYPTO_V2_RB_FF_LOAD0, (uint8_t const *)dataRemap, dataSize);
149 
150     /* A state of 32-bit Linear Feedback Shift Registers (LFSR) used to implement CRC. */
151     REG_CRYPTO_RESULT(base) = (uint32_t)(_VAL2FLD(CRYPTO_V2_RESULT_DATA, lfsrInitState));
152 
153     /* Issue the CRC instruction */
154     Cy_Crypto_Core_V2_Run(base, CY_CRYPTO_V2_CRC_OPC);
155 
156     /* Wait until CRC instruction is complete */
157     Cy_Crypto_Core_V2_Sync(base);
158 
159     /* Copy the result from the CRC_REM_RESULT register */
160     *crc = (uint32_t)_FLD2VAL(CRYPTO_V2_CRC_REM_RESULT_REM, REG_CRYPTO_CRC_REM_RESULT(base));
161 
162     return (CY_CRYPTO_SUCCESS);
163 }
164 
165 /*******************************************************************************
166 * Function Name: Cy_Crypto_Core_V2_Crc_CalcInit
167 ****************************************************************************//**
168 *
169 * Initializes the CRC calculation.
170 *
171 * \param base
172 * The pointer to the CRYPTO instance.
173 *
174 * \param width
175 * The CRC width in bits.
176 *
177 * \param polynomial
178 * The polynomial (specified using 32 bits) used in the computing CRC.
179 *
180 * \param dataReverse
181 * The order in which data bytes are processed. 0 - MSB first; 1- LSB first.
182 *
183 * \param dataXor
184 * The byte mask for XORing data.
185 *
186 * \param remReverse
187 * The remainder reverse: 0 means the remainder is not reversed; 1 means it is reversed.
188 *
189 * \param remXor
190 * Specifies the mask with which the LFSR32 register is XORed to produce a remainder.
191 *
192 * \param lfsrInitState
193 * The initial state of the LFSR.
194 *
195 * \return
196 * \ref cy_en_crypto_status_t
197 *
198 *******************************************************************************/
Cy_Crypto_Core_V2_Crc_CalcInit(CRYPTO_Type * base,uint32_t width,uint32_t polynomial,uint32_t dataReverse,uint32_t dataXor,uint32_t remReverse,uint32_t remXor,uint32_t lfsrInitState)199 cy_en_crypto_status_t Cy_Crypto_Core_V2_Crc_CalcInit(CRYPTO_Type *base,
200                                         uint32_t width,
201                                         uint32_t polynomial,
202                                         uint32_t dataReverse,
203                                         uint32_t dataXor,
204                                         uint32_t remReverse,
205                                         uint32_t remXor,
206                                         uint32_t lfsrInitState)
207 {
208     CY_ASSERT_L1((width >= 1U) && (width <= CY_CRYPTO_HW_REGS_WIDTH));
209 
210     /* Specifies the bit order in which a data byte is processed
211      * (reversal is performed after XORing):
212      *                                       '0': Most significant bit (bit 1) first.
213      *                                       '1': Least significant bit (bit 0) first. */
214     REG_CRYPTO_CRC_CTL(base) = (uint32_t)( (_VAL2FLD(CRYPTO_V2_CRC_CTL_DATA_REVERSE, dataReverse)) |
215                                            (_VAL2FLD(CRYPTO_V2_CRC_CTL_REM_REVERSE,  remReverse)) );
216 
217     /* Specifies the byte mask with which each data byte is XORed.
218      * The XOR is performed before data reversal. */
219     REG_CRYPTO_CRC_DATA_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_V2_CRC_DATA_CTL_DATA_XOR, dataXor));
220 
221     /* The CRC polynomial. The polynomial is represented WITHOUT the high-order bit
222      * (this bit is always assumed '1'). */
223     REG_CRYPTO_CRC_POL_CTL(base) =
224         (uint32_t)(_VAL2FLD(CRYPTO_V2_CRC_POL_CTL_POLYNOMIAL, polynomial << (CY_CRYPTO_HW_REGS_WIDTH - width)));
225 
226     /*Specifies the mask with which the CRC_LFSR_CTL.LFSR32 register is XORed to produce a remainder.
227      * The XOR is performed before remainder reversal. */
228     REG_CRYPTO_CRC_REM_CTL(base) =
229         (uint32_t)(_VAL2FLD(CRYPTO_V2_CRC_REM_CTL_REM_XOR, remXor << (CY_CRYPTO_HW_REGS_WIDTH - width)));
230 
231     /* The state of 32-bit Linear Feedback Shift Registers (LFSR) used to implement the CRC. */
232     REG_CRYPTO_RESULT(base) =
233         (uint32_t)(_VAL2FLD(CRYPTO_V2_RESULT_DATA, lfsrInitState << (CY_CRYPTO_HW_REGS_WIDTH - width)));
234 
235     return (CY_CRYPTO_SUCCESS);
236 }
237 
238 /*******************************************************************************
239 * Function Name: Cy_Crypto_Core_V2_Crc_CalcStart
240 ****************************************************************************//**
241 *
242 * Prepares the CRC calculation by setting an initial seed value.
243 *
244 * \param base
245 * The pointer to the CRYPTO instance.
246 *
247 * \param width
248 * The CRC width in bits.
249 *
250 * \param lfsrInitState
251 * The initial state of the LFSR.
252 *
253 * \return
254 * \ref cy_en_crypto_status_t
255 *
256 *******************************************************************************/
Cy_Crypto_Core_V2_Crc_CalcStart(CRYPTO_Type * base,uint32_t width,uint32_t lfsrInitState)257 cy_en_crypto_status_t Cy_Crypto_Core_V2_Crc_CalcStart(CRYPTO_Type *base, uint32_t width, uint32_t  lfsrInitState)
258 {
259     CY_ASSERT_L1((width >= 1U) && (width <= CY_CRYPTO_HW_REGS_WIDTH));
260 
261     /* The state of 32-bit Linear Feedback Shift Registers (LFSR) used to implement the CRC. */
262     REG_CRYPTO_RESULT(base) = (uint32_t)(_VAL2FLD(CRYPTO_V2_RESULT_DATA, lfsrInitState << (CY_CRYPTO_HW_REGS_WIDTH - width)));
263 
264     return (CY_CRYPTO_SUCCESS);
265 }
266 
267 /*******************************************************************************
268 * Function Name: Cy_Crypto_Core_V2_Crc_CalcPartial
269 ****************************************************************************//**
270 *
271 * Performs the CRC calculation of a message part.
272 *
273 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameter data must align and end in 32 byte boundary.
274 *
275 * \param base
276 * The pointer to the CRYPTO instance.
277 *
278 * \param data
279 * The pointer to the message whose CRC is being computed.
280 *
281 * \param dataSize
282 * The size of a message in bytes.
283 *
284 * \return
285 * \ref cy_en_crypto_status_t
286 *
287 *******************************************************************************/
Cy_Crypto_Core_V2_Crc_CalcPartial(CRYPTO_Type * base,void const * data,uint32_t dataSize)288 cy_en_crypto_status_t Cy_Crypto_Core_V2_Crc_CalcPartial(CRYPTO_Type *base,
289                                         void const  *data, uint32_t  dataSize)
290 {
291 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
292     /* Flush the cache */
293     SCB_CleanDCache_by_Addr((volatile void *)data,(int32_t)dataSize);
294 #endif
295 
296     uint8_t *dataRemap;
297     dataRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(data);
298 
299     /* Fills the FIFO with the instruction parameters. */
300     Cy_Crypto_Core_V2_FFStart(base, CY_CRYPTO_V2_RB_FF_LOAD0, (uint8_t const *)dataRemap, dataSize);
301 
302     /* Issues the CRC instruction. */
303     Cy_Crypto_Core_V2_Run(base, CY_CRYPTO_V2_CRC_OPC);
304 
305     /* Waits until the CRC instruction is complete. */
306     Cy_Crypto_Core_V2_Sync(base);
307 
308     return (CY_CRYPTO_SUCCESS);
309 }
310 
311 /*******************************************************************************
312 * Function Name: Cy_Crypto_Core_V2_Crc_CalcFinish
313 ****************************************************************************//**
314 *
315 * Finalizes the CRC calculation.
316 *
317 * For CAT1A and CAT1C devices with DCache disabled, crc must be 4-Byte aligned.
318 *
319 * \param base
320 * The pointer to the CRYPTO instance.
321 *
322 * \param width
323 * The CRC width in bits.
324 *
325 * \param crc
326 * The pointer to a computed CRC value.
327 *
328 * \return
329 * \ref cy_en_crypto_status_t
330 *
331 *******************************************************************************/
Cy_Crypto_Core_V2_Crc_CalcFinish(CRYPTO_Type * base,uint32_t width,uint32_t * crc)332 cy_en_crypto_status_t Cy_Crypto_Core_V2_Crc_CalcFinish(CRYPTO_Type *base, uint32_t width, uint32_t *crc)
333 {
334     CY_ASSERT_L1((width >= 1U) && (width <= CY_CRYPTO_HW_REGS_WIDTH));
335 
336     uint32_t calculatedCrc;
337 
338     /* Copies the result from the CRC_REM_RESULT register. */
339     calculatedCrc = (uint32_t)_FLD2VAL(CRYPTO_V2_CRC_REM_RESULT_REM, REG_CRYPTO_CRC_REM_RESULT(base));
340 
341     /* NOTE The calculated CRC value is MSB-aligned and should be shifted WHEN CRC_DATA_REVERSE is zero. */
342     if (_FLD2VAL(CRYPTO_V2_CRC_CTL_REM_REVERSE, REG_CRYPTO_CRC_CTL(base)) == 0U)
343     {
344         calculatedCrc = calculatedCrc >> (CY_CRYPTO_HW_REGS_WIDTH - width);
345     }
346 
347     *crc = calculatedCrc;
348 
349     return (CY_CRYPTO_SUCCESS);
350 }
351 
352 /*******************************************************************************
353 * Function Name: Cy_Crypto_Core_V2_Crc_Calc
354 ****************************************************************************//**
355 *
356 * Performs the CRC calculation on a message.
357 *
358 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameter data must align and end in 32 byte boundary.
359 * For CAT1A and CAT1C devices with DCache disabled, crc must be 4-Byte aligned.
360 *
361 *
362 * \param base
363 * The pointer to the CRYPTO instance.
364 *
365 * \param width
366 * The CRC width in bits.
367 *
368 * \param crc
369 * The pointer to a computed CRC value.
370 *
371 * \param data
372 * The pointer to the message whose CRC is being computed.
373 *
374 * \param dataSize
375 * The size of a message in bytes.
376 *
377 * \return
378 * \ref cy_en_crypto_status_t
379 *
380 *******************************************************************************/
Cy_Crypto_Core_V2_Crc_Calc(CRYPTO_Type * base,uint32_t width,uint32_t * crc,void const * data,uint32_t dataSize)381 cy_en_crypto_status_t Cy_Crypto_Core_V2_Crc_Calc(CRYPTO_Type *base,
382                                         uint32_t  width,
383                                         uint32_t *crc,
384                                         void  const *data,
385                                         uint32_t  dataSize)
386 {
387     CY_ASSERT_L1((width >= 1U) && (width <= CY_CRYPTO_HW_REGS_WIDTH));
388 
389     uint32_t calculatedCrc;
390 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
391         /* Flush the cache */
392         SCB_CleanDCache_by_Addr((volatile void *)data,(int32_t)dataSize);
393 #endif
394 
395     uint8_t *dataRemap;
396     dataRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(data);
397 
398     /* Fills the FIFO with the instruction parameters. */
399     Cy_Crypto_Core_V2_FFStart(base, CY_CRYPTO_V2_RB_FF_LOAD0, (uint8_t const *)dataRemap, dataSize);
400 
401     /* Issues the CRC instruction. */
402     Cy_Crypto_Core_V2_Run(base, CY_CRYPTO_V2_CRC_OPC);
403 
404     /* Waits until the CRC instruction is complete. */
405     Cy_Crypto_Core_V2_Sync(base);
406 
407     /* Copies the result from the CRC_REM_RESULT register. */
408     calculatedCrc = (uint32_t)_FLD2VAL(CRYPTO_V2_CRC_REM_RESULT_REM, REG_CRYPTO_CRC_REM_RESULT(base));
409 
410     /* NOTE The calculated CRC value is MSB-aligned and should be shifted WHEN CRC_DATA_REVERSE is zero. */
411     if (_FLD2VAL(CRYPTO_V2_CRC_CTL_REM_REVERSE, REG_CRYPTO_CRC_CTL(base)) == 0U)
412     {
413         calculatedCrc = calculatedCrc >> (CY_CRYPTO_HW_REGS_WIDTH - width);
414     }
415 
416     *crc = calculatedCrc;
417 
418     return (CY_CRYPTO_SUCCESS);
419 }
420 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 11.3')
421 
422 #endif /* (CPUSS_CRYPTO_CRC == 1) && defined(CY_CRYPTO_CFG_CRC_C) */
423 
424 #if defined(__cplusplus)
425 }
426 #endif
427 
428 #endif /* defined(CY_CRYPTO_CFG_HW_V2_ENABLE) */
429 
430 #endif /* defined(CY_IP_MXCRYPTO) */
431 
432 
433 /* [] END OF FILE */
434