1 /***************************************************************************//**
2 * \file cy_crypto_core_crc_v1.c
3 * \version 2.90
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_v1.h"
33 
34 #if defined(CY_CRYPTO_CFG_HW_V1_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_v1.h"
43 #include "cy_syslib.h"
44 
45 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 11.3', 3, \
46 'This piece of code is written for CRYPTO_V1_Type and will not execute for CRYPTO_V2_Type')
47 
48 /*******************************************************************************
49 * Function Name: Cy_Crypto_Core_V1_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_V1_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_V1_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_CRC_CTL_DATA_REVERSE, dataReverse)) |
89                                            (_VAL2FLD(CRYPTO_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_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_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_CRC_REM_CTL_REM_XOR, remXor));
102 
103     return (CY_CRYPTO_SUCCESS);
104 }
105 
106 /*******************************************************************************
107 * Function Name: Cy_Crypto_Core_V1_Crc
108 ****************************************************************************//**
109 *
110 * Performs CRC calculation on a message.
111 *
112 * \param base
113 * The pointer to the CRYPTO instance.
114 *
115 * \param crc
116 * The pointer to a computed CRC value. Must be 4-byte aligned.
117 *
118 * \param data
119 * The pointer to the message whose CRC is being computed.
120 *
121 * \param dataSize
122 * The size of a message in bytes.
123 *
124 * \param lfsrInitState
125 * The initial state of the LFSR.
126 *
127 * \return
128 * \ref cy_en_crypto_status_t
129 *
130 *******************************************************************************/
Cy_Crypto_Core_V1_Crc(CRYPTO_Type * base,uint32_t * crc,void const * data,uint32_t dataSize,uint32_t lfsrInitState)131 cy_en_crypto_status_t Cy_Crypto_Core_V1_Crc(CRYPTO_Type *base,
132                                         uint32_t *crc,
133                                         void const *data,
134                                         uint32_t  dataSize,
135                                         uint32_t  lfsrInitState)
136 {
137     uint32_t *dataStart = (uint32_t *)data;
138 
139     /* A state of 32-bit Linear Feedback Shift Registers (LFSR) used to implement CRC. */
140     REG_CRYPTO_CRC_LFSR_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_CRC_LFSR_CTL_LFSR32, lfsrInitState));
141 
142     do {
143         uint32_t partSize = (dataSize <= 0xFFFFu) ? dataSize : 0xFFFFu;
144 
145         /* Fill the FIFO with the instruction parameters */
146         Cy_Crypto_SetReg2Instr(base, (uint32_t)dataStart, partSize );
147 
148         /* Issue the CRC instruction */
149         Cy_Crypto_Run2ParamInstr(base, CY_CRYPTO_V1_CRC_OPC, CY_CRYPTO_RSRC0_SHIFT, CY_CRYPTO_RSRC4_SHIFT);
150 
151         /* Wait until CRC instruction is complete */
152         while(0uL != _FLD2VAL(CRYPTO_STATUS_CRC_BUSY, REG_CRYPTO_STATUS(base)))
153         {
154         }
155 
156         dataSize -= partSize;
157         dataStart += partSize;
158 
159     } while (dataSize > 0u);
160 
161     /* Copy the result from the CRC_REM_RESULT register */
162     *crc = (uint32_t)_FLD2VAL(CRYPTO_CRC_REM_RESULT_REM, REG_CRYPTO_CRC_REM_RESULT(base));
163 
164     return (CY_CRYPTO_SUCCESS);
165 }
166 
167 /*******************************************************************************
168 * Function Name: Cy_Crypto_Core_V1_Crc_CalcInit
169 ****************************************************************************//**
170 *
171 * Initializes the CRC calculation.
172 *
173 * \param base
174 * The pointer to the CRYPTO instance.
175 *
176 * \param width
177 * The CRC width in bits.
178 *
179 * \param polynomial
180 * The polynomial (specified using 32 bits) used in the computing CRC.
181 *
182 * \param dataReverse
183 * The order in which data bytes are processed. 0 - MSB first; 1- LSB first.
184 *
185 * \param dataXor
186 * The byte mask for XORing data.
187 *
188 * \param remReverse
189 * A remainder reverse: 0 means the remainder is not reversed. 1 means it is reversed.
190 *
191 * \param remXor
192 * Specifies the mask with which the LFSR32 register is XORed to produce a remainder.
193 *
194 * \param lfsrInitState
195 * The initial state of the LFSR.
196 *
197 * \return
198 * \ref cy_en_crypto_status_t
199 *
200 *******************************************************************************/
Cy_Crypto_Core_V1_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)201 cy_en_crypto_status_t Cy_Crypto_Core_V1_Crc_CalcInit(CRYPTO_Type *base,
202                                         uint32_t width,
203                                         uint32_t polynomial,
204                                         uint32_t dataReverse,
205                                         uint32_t dataXor,
206                                         uint32_t remReverse,
207                                         uint32_t remXor,
208                                         uint32_t lfsrInitState)
209 {
210     CY_ASSERT_L1((width >= 1U) && (width <= CY_CRYPTO_HW_REGS_WIDTH));
211 
212     /* Specifies the bit order in which a data byte is processed
213      * (reversal is performed after XORing):
214      *                                       '0': Most significant bit (bit 1) first.
215      *                                       '1': Least significant bit (bit 0) first. */
216     REG_CRYPTO_CRC_CTL(base) = (uint32_t)( (_VAL2FLD(CRYPTO_CRC_CTL_DATA_REVERSE, dataReverse)) |
217                                            (_VAL2FLD(CRYPTO_CRC_CTL_REM_REVERSE,  remReverse)) );
218 
219     /* Specifies the byte mask with which each data byte is XORed.
220      * The XOR is performed before data reversal. */
221     REG_CRYPTO_CRC_DATA_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_CRC_DATA_CTL_DATA_XOR, dataXor));
222 
223     /* The CRC polynomial. The polynomial is represented WITHOUT the high-order bit
224      * (this bit is always assumed '1').
225      * CRC_POLYNOMIAL << (32 - CRC_BITLEN) */
226     REG_CRYPTO_CRC_POL_CTL(base) =
227         (uint32_t)(_VAL2FLD(CRYPTO_CRC_POL_CTL_POLYNOMIAL, polynomial << (CY_CRYPTO_HW_REGS_WIDTH - width)));
228 
229     /*Specifies the mask with which the CRC_LFSR_CTL.LFSR32 register is XORed to produce a remainder.
230      * The XOR is performed before remainder reversal. */
231     REG_CRYPTO_CRC_REM_CTL(base) =
232         (uint32_t)(_VAL2FLD(CRYPTO_CRC_REM_CTL_REM_XOR, remXor << (CY_CRYPTO_HW_REGS_WIDTH - width)));
233 
234     /* The state of 32-bit Linear Feedback Shift Registers (LFSR) used to implement the CRC. */
235     REG_CRYPTO_CRC_LFSR_CTL(base) =
236         (uint32_t)(_VAL2FLD(CRYPTO_CRC_LFSR_CTL_LFSR32, lfsrInitState << (CY_CRYPTO_HW_REGS_WIDTH - width)));
237 
238     return (CY_CRYPTO_SUCCESS);
239 }
240 
241 /*******************************************************************************
242 * Function Name: Cy_Crypto_Core_V1_Crc_CalcStart
243 ****************************************************************************//**
244 *
245 * Prepares the CRC calculation by setting an initial seed value.
246 *
247 * \param base
248 * The pointer to the CRYPTO instance.
249 *
250 * \param width
251 * The CRC width in bits.
252 *
253 * \param lfsrInitState
254 * The initial state of the LFSR.
255 *
256 * \return
257 * \ref cy_en_crypto_status_t
258 *
259 *******************************************************************************/
Cy_Crypto_Core_V1_Crc_CalcStart(CRYPTO_Type * base,uint32_t width,uint32_t lfsrInitState)260 cy_en_crypto_status_t Cy_Crypto_Core_V1_Crc_CalcStart(CRYPTO_Type *base, uint32_t width, uint32_t  lfsrInitState)
261 {
262     CY_ASSERT_L1((width >= 1U) && (width <= CY_CRYPTO_HW_REGS_WIDTH));
263 
264     /* The state of 32-bit Linear Feedback Shift Registers (LFSR) used to implement the CRC. */
265     REG_CRYPTO_CRC_LFSR_CTL(base) =
266         (uint32_t)(_VAL2FLD(CRYPTO_CRC_LFSR_CTL_LFSR32, lfsrInitState << (CY_CRYPTO_HW_REGS_WIDTH - width)));
267 
268     return (CY_CRYPTO_SUCCESS);
269 }
270 
271 /*******************************************************************************
272 * Function Name: Cy_Crypto_Core_V1_Crc_CalcPartial
273 ****************************************************************************//**
274 *
275 * Performs the CRC calculation of a message part.
276 *
277 * \param base
278 * The pointer to the CRYPTO instance.
279 *
280 * \param data
281 * The pointer to the message whose CRC is being computed.
282 *
283 * \param dataSize
284 * The size of a message in bytes.
285 *
286 * \return
287 * \ref cy_en_crypto_status_t
288 *
289 *******************************************************************************/
Cy_Crypto_Core_V1_Crc_CalcPartial(CRYPTO_Type * base,void const * data,uint32_t dataSize)290 cy_en_crypto_status_t Cy_Crypto_Core_V1_Crc_CalcPartial(CRYPTO_Type *base,
291                                         void const *data, uint32_t  dataSize)
292 {
293     uint32_t *dataStart = (uint32_t *)data;
294 
295     do {
296         uint32_t partSize = (dataSize <= 0xFFFFu) ? dataSize : 0xFFFFu;
297 
298         /* Fills the FIFO with the instruction parameters. */
299         Cy_Crypto_SetReg2Instr(base, (uint32_t)dataStart, partSize );
300 
301         /* Issues the CRC instruction. */
302         Cy_Crypto_Run2ParamInstr(base, CY_CRYPTO_V1_CRC_OPC, CY_CRYPTO_RSRC0_SHIFT, CY_CRYPTO_RSRC4_SHIFT);
303 
304         /* Waits until the CRC instruction is complete. */
305         while(0uL != _FLD2VAL(CRYPTO_STATUS_CRC_BUSY, REG_CRYPTO_STATUS(base)))
306         {
307         }
308 
309         dataSize -= partSize;
310         dataStart += partSize;
311 
312     } while (dataSize > 0u);
313 
314     return (CY_CRYPTO_SUCCESS);
315 }
316 
317 /*******************************************************************************
318 * Function Name: Cy_Crypto_Core_V1_Crc_CalcFinish
319 ****************************************************************************//**
320 *
321 * Finalizes the CRC calculation.
322 *
323 * \param base
324 * The pointer to the CRYPTO instance.
325 *
326 * \param width
327 * The CRC width in bits.
328 *
329 * \param crc
330 * The pointer to a computed CRC value. Must be 4-byte aligned.
331 *
332 * \return
333 * \ref cy_en_crypto_status_t
334 *
335 *******************************************************************************/
Cy_Crypto_Core_V1_Crc_CalcFinish(CRYPTO_Type * base,uint32_t width,uint32_t * crc)336 cy_en_crypto_status_t Cy_Crypto_Core_V1_Crc_CalcFinish(CRYPTO_Type *base, uint32_t width, uint32_t *crc)
337 {
338     CY_ASSERT_L1((width >= 1U) && (width <= CY_CRYPTO_HW_REGS_WIDTH));
339 
340     uint32_t calculatedCrc;
341 
342     /* Copies the result from the CRC_REM_RESULT register. */
343     calculatedCrc = (uint32_t)_FLD2VAL(CRYPTO_CRC_REM_RESULT_REM, REG_CRYPTO_CRC_REM_RESULT(base));
344 
345     /* NOTE The calculated CRC value is MSB-aligned and should be shifted WHEN CRC_DATA_REVERSE is zero. */
346     if (_FLD2VAL(CRYPTO_CRC_CTL_REM_REVERSE, REG_CRYPTO_CRC_CTL(base)) == 0u)
347     {
348         calculatedCrc = calculatedCrc >> (CY_CRYPTO_HW_REGS_WIDTH - width);
349     }
350 
351     *crc = calculatedCrc;
352 
353     return (CY_CRYPTO_SUCCESS);
354 }
355 
356 /*******************************************************************************
357 * Function Name: Cy_Crypto_Core_V1_Crc_Calc
358 ****************************************************************************//**
359 *
360 * Performs the CRC calculation on a message.
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. Must be 4-byte aligned.
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_V1_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_V1_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 
391     /* Fills the FIFO with the instruction parameters. */
392     Cy_Crypto_SetReg2Instr(base, (uint32_t)data, dataSize );
393 
394     /* Issues the CRC instruction. */
395     Cy_Crypto_Run2ParamInstr(base, CY_CRYPTO_V1_CRC_OPC, CY_CRYPTO_RSRC0_SHIFT, CY_CRYPTO_RSRC4_SHIFT);
396 
397     /* Waits until the CRC instruction is complete. */
398     while(0uL != _FLD2VAL(CRYPTO_STATUS_CRC_BUSY, REG_CRYPTO_STATUS(base)))
399     {
400     }
401 
402     /* Copies the result from the CRC_REM_RESULT register. */
403     calculatedCrc = (uint32_t)_FLD2VAL(CRYPTO_CRC_REM_RESULT_REM, REG_CRYPTO_CRC_REM_RESULT(base));
404 
405     /* NOTE The calculated CRC value is MSB-aligned and should be shifted WHEN CRC_DATA_REVERSE is zero. */
406     if (_FLD2VAL(CRYPTO_CRC_CTL_REM_REVERSE, REG_CRYPTO_CRC_CTL(base)) == 0u)
407     {
408         calculatedCrc = calculatedCrc >> (CY_CRYPTO_HW_REGS_WIDTH - width);
409     }
410 
411     *crc = calculatedCrc;
412 
413     return (CY_CRYPTO_SUCCESS);
414 }
415 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 11.3')
416 #endif /* (CPUSS_CRYPTO_CRC == 1) && defined(CY_CRYPTO_CFG_CRC_C) */
417 
418 #if defined(__cplusplus)
419 }
420 #endif
421 
422 #endif /* defined(CY_CRYPTO_CFG_HW_V1_ENABLE) */
423 
424 #endif /* defined(CY_IP_MXCRYPTO) */
425 
426 
427 /* [] END OF FILE */
428