1 /***************************************************************************//**
2 * \file cy_crypto_core_des_v2.c
3 * \version 2.120
4 *
5 * \brief
6 * This file provides the source code fro the API for the DES method
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_des_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_DES == 1) && defined(CY_CRYPTO_CFG_DES_C)
41
42 #include "cy_crypto_common.h"
43 #include "cy_crypto_core_hw_v2.h"
44 #include "cy_crypto_core_mem_v2.h"
45 #include "cy_syslib.h"
46
47 #define CY_CRYPTO_DES_WEAK_KEY_COUNT (16U)
48 #define CY_CRYPTO_DES_KEY_BYTE_LENGTH (8U)
49
50 typedef enum
51 {
52 CY_CRYPTO_DES_MODE_SINGLE = 0,
53 CY_CRYPTO_DES_MODE_TRIPLE = 1
54 } cy_en_crypto_des_mode_t;
55
56 /* Table with DES weak keys */
57 CY_ALIGN(4)
58 static uint8_t const cy_desWeakKeys[CY_CRYPTO_DES_WEAK_KEY_COUNT][CY_CRYPTO_DES_KEY_BYTE_LENGTH] =
59 {
60 { 0x01u, 0x01u, 0x01u, 0x01u, 0x01u, 0x01u, 0x01u, 0x01u },
61 { 0xFEu, 0xFEu, 0xFEu, 0xFEu, 0xFEu, 0xFEu, 0xFEu, 0xFEu },
62 { 0x1Fu, 0x1Fu, 0x1Fu, 0x1Fu, 0x0Eu, 0x0Eu, 0x0Eu, 0x0Eu },
63 { 0xE0u, 0xE0u, 0xE0u, 0xE0u, 0xF1u, 0xF1u, 0xF1u, 0xF1u },
64
65 { 0x01u, 0x1Fu, 0x01u, 0x1Fu, 0x01u, 0x0Eu, 0x01u, 0x0Eu },
66 { 0x1Fu, 0x01u, 0x1Fu, 0x01u, 0x0Eu, 0x01u, 0x0Eu, 0x01u },
67 { 0x01u, 0xE0u, 0x01u, 0xE0u, 0x01u, 0xF1u, 0x01u, 0xF1u },
68 { 0xE0u, 0x01u, 0xE0u, 0x01u, 0xF1u, 0x01u, 0xF1u, 0x01u },
69 { 0x01u, 0xFEu, 0x01u, 0xFEu, 0x01u, 0xFEu, 0x01u, 0xFEu },
70 { 0xFEu, 0x01u, 0xFEu, 0x01u, 0xFEu, 0x01u, 0xFEu, 0x01u },
71 { 0x1Fu, 0xE0u, 0x1Fu, 0xE0u, 0x0Eu, 0xF1u, 0x0Eu, 0xF1u },
72 { 0xE0u, 0x1Fu, 0xE0u, 0x1Fu, 0xF1u, 0x0Eu, 0xF1u, 0x0Eu },
73 { 0x1Fu, 0xFEu, 0x1Fu, 0xFEu, 0x0Eu, 0xFEu, 0x0Eu, 0xFEu },
74 { 0xFEu, 0x1Fu, 0xFEu, 0x1Fu, 0xFEu, 0x0Eu, 0xFEu, 0x0Eu },
75 { 0xE0u, 0xFEu, 0xE0u, 0xFEu, 0xF1u, 0xFEu, 0xF1u, 0xFEu },
76 { 0xFEu, 0xE0u, 0xFEu, 0xE0u, 0xFEu, 0xF1u, 0xFEu, 0xF1u }
77 };
78
79
80 /*******************************************************************************
81 * Function Name: Cy_Crypto_Core_V2_Des
82 ****************************************************************************//**
83 *
84 * Performs DES operation on a Single Block.
85 * Ciphertext (dst) may overlap with plaintext (src)
86 * This function is independent from the previous Crypto state.
87 *
88 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameters key, dst and src must align and end in 32 byte boundary.
89 * For CAT1A and CAT1C devices with DCache disabled, all addresses must be 4-Byte aligned.
90 *
91 * \param base
92 * The pointer to the CRYPTO instance.
93 *
94 * \param dirMode
95 * Can be \ref CY_CRYPTO_ENCRYPT or \ref CY_CRYPTO_DECRYPT
96 * (\ref cy_en_crypto_dir_mode_t)
97 *
98 * \param key
99 * The pointer to the encryption/decryption key.
100 *
101 * \param dst
102 * The pointer to a destination cipher block.
103 *
104 * \param src
105 * The pointer to a source data block.
106 *
107 * \return
108 * \ref cy_en_crypto_status_t
109 *
110 *******************************************************************************/
Cy_Crypto_Core_V2_Des(CRYPTO_Type * base,cy_en_crypto_dir_mode_t dirMode,uint8_t const * key,uint8_t * dst,uint8_t const * src)111 cy_en_crypto_status_t Cy_Crypto_Core_V2_Des(CRYPTO_Type *base,
112 cy_en_crypto_dir_mode_t dirMode,
113 uint8_t const *key,
114 uint8_t *dst,
115 uint8_t const *src)
116 {
117 uint32_t i;
118 cy_en_crypto_status_t status = CY_CRYPTO_SUCCESS;
119 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
120 /* Flush the cache */
121 SCB_CleanDCache_by_Addr((volatile void *)key,(int32_t)CY_CRYPTO_DES_KEY_BYTE_LENGTH);
122 SCB_CleanDCache_by_Addr((volatile void *)src,(int32_t)CY_CRYPTO_DES_KEY_BYTE_LENGTH);
123 #endif
124 uint8_t *keyRemap;
125 uint8_t *dstRemap;
126 uint8_t *srcRemap;
127
128 keyRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key);
129 dstRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(dst);
130 srcRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(src);
131
132 /* Check weak keys */
133 for (i = 0U; i < CY_CRYPTO_DES_WEAK_KEY_COUNT; i++)
134 {
135 if (Cy_Crypto_Core_V2_MemCmp(base, keyRemap, (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cy_desWeakKeys[i]), CY_CRYPTO_DES_KEY_BYTE_LENGTH) == 0U)
136 {
137 status = CY_CRYPTO_DES_WEAK_KEY;
138 break;
139 }
140 }
141
142 /* Load key */
143 Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, keyRemap, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
144 Cy_Crypto_Core_V2_BlockMov(base, CY_CRYPTO_V2_RB_KEY0, CY_CRYPTO_V2_RB_FF_LOAD0, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
145
146 Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, srcRemap, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
147 Cy_Crypto_Core_V2_FFStart(base, CY_CRYPTO_V2_RB_FF_STORE, dstRemap, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
148
149 Cy_Crypto_Core_V2_BlockMov(base, CY_CRYPTO_V2_RB_BLOCK0, CY_CRYPTO_V2_RB_FF_LOAD0, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
150 Cy_Crypto_Core_V2_Run(base, (uint32_t)((dirMode == CY_CRYPTO_ENCRYPT) ? (CY_CRYPTO_V2_DES_OPC) : (CY_CRYPTO_V2_DES_INV_OPC)));
151 Cy_Crypto_Core_V2_BlockMov(base, CY_CRYPTO_V2_RB_FF_STORE, CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
152
153 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
154 SCB_InvalidateDCache_by_Addr(dst, (int32_t)CY_CRYPTO_DES_KEY_BYTE_LENGTH);
155 #endif
156
157 return (status);
158 }
159
160 /*******************************************************************************
161 * Function Name: Cy_Crypto_Core_V2_Tdes
162 ****************************************************************************//**
163 *
164 * Performs TDES operation on a Single Block.
165 * Ciphertext (dstBlock) may overlap with plaintext (srcBlock)
166 * This function is independent from the previous Crypto state.
167 *
168 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameters key, dst and src must align and end in 32 byte boundary.
169 * For CAT1A and CAT1C devices with DCache disabled, all addresses must be 4-Byte aligned.
170 *
171 * \param base
172 * The pointer to the CRYPTO instance.
173 *
174 * \param dirMode
175 * Can be \ref CY_CRYPTO_ENCRYPT or \ref CY_CRYPTO_DECRYPT
176 * (\ref cy_en_crypto_dir_mode_t)
177 *
178 * \param key
179 * The pointer to the encryption/decryption keys.
180 *
181 * \param dst
182 * The pointer to a destination cipher block.
183 *
184 * \param src
185 * The pointer to a source data block.
186 *
187 * \return
188 * \ref cy_en_crypto_status_t
189 *
190 *******************************************************************************/
Cy_Crypto_Core_V2_Tdes(CRYPTO_Type * base,cy_en_crypto_dir_mode_t dirMode,uint8_t const * key,uint8_t * dst,uint8_t const * src)191 cy_en_crypto_status_t Cy_Crypto_Core_V2_Tdes(CRYPTO_Type *base,
192 cy_en_crypto_dir_mode_t dirMode,
193 uint8_t const *key,
194 uint8_t *dst,
195 uint8_t const *src)
196 {
197 uint32_t i;
198 cy_en_crypto_status_t status = CY_CRYPTO_SUCCESS;
199 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
200 /* Flush the cache */
201 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to int32_t.');
202 SCB_CleanDCache_by_Addr((volatile void *)key,(int32_t)(CY_CRYPTO_DES_KEY_BYTE_LENGTH * 3U));
203 SCB_CleanDCache_by_Addr((volatile void *)src,(int32_t)CY_CRYPTO_DES_KEY_BYTE_LENGTH);
204 #endif
205 uint8_t *keyRemap;
206 uint8_t *dstRemap;
207 uint8_t *srcRemap;
208
209 keyRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key);
210 dstRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(dst);
211 srcRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(src);
212
213 /* Check weak keys */
214 for (i = 0U; i < CY_CRYPTO_DES_WEAK_KEY_COUNT; i++)
215 {
216 for (uint32_t keynum=0U; keynum < (CY_CRYPTO_TDES_KEY_SIZE / CY_CRYPTO_DES_KEY_SIZE); keynum++)
217 {
218 if (Cy_Crypto_Core_V2_MemCmp(base, &(keyRemap[keynum * CY_CRYPTO_DES_KEY_BYTE_LENGTH]), (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cy_desWeakKeys[i]), CY_CRYPTO_DES_KEY_BYTE_LENGTH) == 0U)
219 {
220 status = CY_CRYPTO_DES_WEAK_KEY;
221 break;
222 }
223 }
224 if (status == CY_CRYPTO_DES_WEAK_KEY)
225 {
226 break;
227 }
228 }
229
230 /* Load keys */
231 Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, keyRemap, CY_CRYPTO_DES_KEY_BYTE_LENGTH * 3U);
232 Cy_Crypto_Core_V2_BlockMov (base, CY_CRYPTO_V2_RB_KEY0, CY_CRYPTO_V2_RB_FF_LOAD0, CY_CRYPTO_DES_KEY_BYTE_LENGTH * 2U);
233 Cy_Crypto_Core_V2_BlockMov (base, CY_CRYPTO_V2_RB_KEY1, CY_CRYPTO_V2_RB_FF_LOAD0, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
234
235 Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, srcRemap, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
236 Cy_Crypto_Core_V2_FFStart (base, CY_CRYPTO_V2_RB_FF_STORE, dstRemap, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
237
238 Cy_Crypto_Core_V2_BlockMov(base, CY_CRYPTO_V2_RB_BLOCK0, CY_CRYPTO_V2_RB_FF_LOAD0, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
239 Cy_Crypto_Core_V2_Run(base, (uint32_t)((dirMode == CY_CRYPTO_ENCRYPT) ? (CY_CRYPTO_V2_TDES_OPC) : (CY_CRYPTO_V2_TDES_INV_OPC)));
240 Cy_Crypto_Core_V2_BlockMov(base, CY_CRYPTO_V2_RB_FF_STORE, CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
241
242 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
243 SCB_InvalidateDCache_by_Addr(dst, (int32_t)CY_CRYPTO_DES_KEY_BYTE_LENGTH);
244 #endif
245
246 return (status);
247 }
248
249 #endif /* (CPUSS_CRYPTO_DES == 1) && defined(CY_CRYPTO_CFG_DES_C) */
250
251 #if defined(__cplusplus)
252 }
253 #endif
254
255 #endif /* defined(CY_CRYPTO_CFG_HW_V2_ENABLE) */
256
257 #endif /* defined(CY_IP_MXCRYPTO) */
258
259 /* [] END OF FILE */
260