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