1 /***************************************************************************//**
2 * \file cy_crypto_core_des_v1.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_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_DES == 1) && defined(CY_CRYPTO_CFG_DES_C)
41
42 #include "cy_crypto_core_mem_v1.h"
43 #include "cy_crypto_core_hw_v1.h"
44 #include "cy_syslib.h"
45
46 #define CY_CRYPTO_DES_WEAK_KEY_COUNT (16u)
47 #define CY_CRYPTO_DES_KEY_BYTE_LENGTH (8u)
48
49 typedef struct
50 {
51 uint32_t block0[CY_CRYPTO_DES_KEY_BYTE_LENGTH / 4u];
52 uint32_t block1[CY_CRYPTO_DES_KEY_BYTE_LENGTH / 4u];
53 uint32_t key[(CY_CRYPTO_DES_KEY_BYTE_LENGTH / 4u) * 3u ];
54 } cy_stc_crypto_des_buffers_t;
55
56 typedef enum
57 {
58 CY_CRYPTO_DES_MODE_SINGLE = 0,
59 CY_CRYPTO_DES_MODE_TRIPLE = 1
60 } cy_en_crypto_des_mode_t;
61
62 /* Table with DES weak keys */
63 CY_ALIGN(4)
64 static uint8_t const cy_desWeakKeys[CY_CRYPTO_DES_WEAK_KEY_COUNT][CY_CRYPTO_DES_KEY_BYTE_LENGTH] =
65 {
66 { 0x01u, 0x01u, 0x01u, 0x01u, 0x01u, 0x01u, 0x01u, 0x01u },
67 { 0xFEu, 0xFEu, 0xFEu, 0xFEu, 0xFEu, 0xFEu, 0xFEu, 0xFEu },
68 { 0x1Fu, 0x1Fu, 0x1Fu, 0x1Fu, 0x0Eu, 0x0Eu, 0x0Eu, 0x0Eu },
69 { 0xE0u, 0xE0u, 0xE0u, 0xE0u, 0xF1u, 0xF1u, 0xF1u, 0xF1u },
70
71 { 0x01u, 0x1Fu, 0x01u, 0x1Fu, 0x01u, 0x0Eu, 0x01u, 0x0Eu },
72 { 0x1Fu, 0x01u, 0x1Fu, 0x01u, 0x0Eu, 0x01u, 0x0Eu, 0x01u },
73 { 0x01u, 0xE0u, 0x01u, 0xE0u, 0x01u, 0xF1u, 0x01u, 0xF1u },
74 { 0xE0u, 0x01u, 0xE0u, 0x01u, 0xF1u, 0x01u, 0xF1u, 0x01u },
75 { 0x01u, 0xFEu, 0x01u, 0xFEu, 0x01u, 0xFEu, 0x01u, 0xFEu },
76 { 0xFEu, 0x01u, 0xFEu, 0x01u, 0xFEu, 0x01u, 0xFEu, 0x01u },
77 { 0x1Fu, 0xE0u, 0x1Fu, 0xE0u, 0x0Eu, 0xF1u, 0x0Eu, 0xF1u },
78 { 0xE0u, 0x1Fu, 0xE0u, 0x1Fu, 0xF1u, 0x0Eu, 0xF1u, 0x0Eu },
79 { 0x1Fu, 0xFEu, 0x1Fu, 0xFEu, 0x0Eu, 0xFEu, 0x0Eu, 0xFEu },
80 { 0xFEu, 0x1Fu, 0xFEu, 0x1Fu, 0xFEu, 0x0Eu, 0xFEu, 0x0Eu },
81 { 0xE0u, 0xFEu, 0xE0u, 0xFEu, 0xF1u, 0xFEu, 0xF1u, 0xFEu },
82 { 0xFEu, 0xE0u, 0xFEu, 0xE0u, 0xFEu, 0xF1u, 0xFEu, 0xF1u }
83
84 };
85
86 static void Cy_Crypto_Core_V1_Des_ProcessBlock(CRYPTO_Type *base,
87 cy_en_crypto_des_mode_t desMode,
88 cy_en_crypto_dir_mode_t dirMode,
89 uint32_t const *key,
90 uint32_t const *dstBlock,
91 uint32_t const *srcBlock);
92
93 /*******************************************************************************
94 * Function Name: Cy_Crypto_Core_V1_Des_ProcessBlock
95 ****************************************************************************//**
96 *
97 * Performs the DES or TDES block cipher.
98 * All addresses must be 4Byte aligned,
99 * srcBlock could overlap dstBlock.
100 *
101 * \param base
102 * The pointer to the CRYPTO instance.
103 *
104 * \param desMode
105 * DES cipher operation mode.
106 *
107 * \param dirMode
108 * One of CRYPTO_ENCRYPT or CRYPTO_DECRYPT.
109 *
110 * \param key
111 * The pointer to the encryption/decryption key.
112 *
113 * \param dstBlock
114 * The pointer to the cipher text.
115 *
116 * \param srcBlock
117 * The pointer to the plain text. Must be 4-Byte aligned!
118 *
119 *******************************************************************************/
Cy_Crypto_Core_V1_Des_ProcessBlock(CRYPTO_Type * base,cy_en_crypto_des_mode_t desMode,cy_en_crypto_dir_mode_t dirMode,uint32_t const * key,uint32_t const * dstBlock,uint32_t const * srcBlock)120 static void Cy_Crypto_Core_V1_Des_ProcessBlock(CRYPTO_Type *base,
121 cy_en_crypto_des_mode_t desMode,
122 cy_en_crypto_dir_mode_t dirMode,
123 uint32_t const *key,
124 uint32_t const *dstBlock,
125 uint32_t const *srcBlock)
126 {
127 uint8_t const cy_desCommands[2][2] = {
128 { CY_CRYPTO_V1_DES_BLOCK_OPC, CY_CRYPTO_V1_DES_BLOCK_INV_OPC }, /* DES mode */
129 { CY_CRYPTO_V1_TDES_BLOCK_OPC, CY_CRYPTO_V1_TDES_BLOCK_INV_OPC } /* TDES mode */
130 };
131
132 Cy_Crypto_SetReg3Instr(base,
133 (uint32_t)key,
134 (uint32_t)srcBlock,
135 (uint32_t)dstBlock);
136
137 /* Issue the DES_BLOCK instruction */
138 Cy_Crypto_Run3ParamInstr(base,
139 cy_desCommands[(uint8_t)desMode][(uint8_t)dirMode],
140 CY_CRYPTO_RSRC0_SHIFT,
141 CY_CRYPTO_RSRC4_SHIFT,
142 CY_CRYPTO_RSRC8_SHIFT);
143
144 /* Wait until the AES instruction is complete */
145 while (0uL != _FLD2VAL(CRYPTO_STATUS_DES_BUSY, REG_CRYPTO_STATUS(base)))
146 {
147 }
148 }
149
150 /*******************************************************************************
151 * Function Name: Cy_Crypto_Core_V1_Des
152 ****************************************************************************//**
153 *
154 * Performs DES operation on a Single Block. All addresses must be 4-Byte aligned.
155 * Ciphertext (dstBlock) may overlap with plaintext (srcBlock)
156 * This function is independent from the previous Crypto state.
157 *
158 * \param base
159 * The pointer to the CRYPTO instance.
160 *
161 * \param dirMode
162 * Can be \ref CY_CRYPTO_ENCRYPT or \ref CY_CRYPTO_DECRYPT
163 * (\ref cy_en_crypto_dir_mode_t)
164 *
165 * \param key
166 * The pointer to the encryption/decryption key.
167 *
168 * \param dst
169 * The pointer to a destination cipher block.
170 *
171 * \param src
172 * The pointer to a source block.
173 *
174 * \return
175 * \ref cy_en_crypto_status_t
176 *
177 *******************************************************************************/
Cy_Crypto_Core_V1_Des(CRYPTO_Type * base,cy_en_crypto_dir_mode_t dirMode,uint8_t const * key,uint8_t * dst,uint8_t const * src)178 cy_en_crypto_status_t Cy_Crypto_Core_V1_Des(CRYPTO_Type *base,
179 cy_en_crypto_dir_mode_t dirMode,
180 uint8_t const *key,
181 uint8_t *dst,
182 uint8_t const *src)
183 {
184 uint32_t i;
185 cy_en_crypto_status_t status = CY_CRYPTO_SUCCESS;
186
187 cy_stc_crypto_des_buffers_t *desBuffers = (cy_stc_crypto_des_buffers_t *)((void *)Cy_Crypto_Core_GetVuMemoryAddress(base));
188
189 /* Check weak keys */
190 for (i = 0U; i < CY_CRYPTO_DES_WEAK_KEY_COUNT; i++)
191 {
192 if (Cy_Crypto_Core_V1_MemCmp(base, key, (uint8_t const *)cy_desWeakKeys[i], CY_CRYPTO_DES_KEY_BYTE_LENGTH) == 0U)
193 {
194 status = CY_CRYPTO_DES_WEAK_KEY;
195 break;
196 }
197 }
198
199 Cy_Crypto_Core_V1_MemCpy(base, desBuffers->key, key, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
200 Cy_Crypto_Core_V1_MemCpy(base, desBuffers->block0, src, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
201
202 Cy_Crypto_Core_V1_Des_ProcessBlock(base, CY_CRYPTO_DES_MODE_SINGLE, dirMode,
203 (uint32_t const *)desBuffers->key, (uint32_t const *)desBuffers->block1, (uint32_t const *)desBuffers->block0);
204
205 Cy_Crypto_Core_V1_MemCpy(base, dst, desBuffers->block1, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
206
207 return (status);
208 }
209
210 /*******************************************************************************
211 * Function Name: Cy_Crypto_Core_V1_Tdes
212 ****************************************************************************//**
213 *
214 * Performs TDES operation on a Single Block. All addresses must be 4-Byte aligned.
215 * Ciphertext (dstBlock) may overlap with plaintext (srcBlock)
216 * This function is independent from the previous Crypto state.
217 *
218 * \param base
219 * The pointer to the CRYPTO instance.
220 *
221 * \param dirMode
222 * Can be \ref CY_CRYPTO_ENCRYPT or \ref CY_CRYPTO_DECRYPT
223 * (\ref cy_en_crypto_dir_mode_t)
224 *
225 * \param key
226 * The pointer to the encryption/decryption keys.
227 *
228 * \param dst
229 * The pointer to a destination cipher block.
230 *
231 * \param src
232 * The pointer to a source data block.
233 *
234 * \return
235 * \ref cy_en_crypto_status_t
236 *
237 *******************************************************************************/
Cy_Crypto_Core_V1_Tdes(CRYPTO_Type * base,cy_en_crypto_dir_mode_t dirMode,uint8_t const * key,uint8_t * dst,uint8_t const * src)238 cy_en_crypto_status_t Cy_Crypto_Core_V1_Tdes(CRYPTO_Type *base,
239 cy_en_crypto_dir_mode_t dirMode,
240 uint8_t const *key,
241 uint8_t *dst,
242 uint8_t const *src)
243 {
244 uint32_t i;
245 cy_en_crypto_status_t status = CY_CRYPTO_SUCCESS;
246
247 cy_stc_crypto_des_buffers_t *desBuffers = (cy_stc_crypto_des_buffers_t *)((void *)Cy_Crypto_Core_GetVuMemoryAddress(base));
248
249 /* Check weak keys */
250 for (i = 0U; i < CY_CRYPTO_DES_WEAK_KEY_COUNT; i++)
251 {
252 for (uint32_t keynum=0U; keynum < (CY_CRYPTO_TDES_KEY_SIZE / CY_CRYPTO_DES_KEY_SIZE); keynum++)
253 {
254 if (Cy_Crypto_Core_V1_MemCmp(base, &(key[keynum * CY_CRYPTO_DES_KEY_BYTE_LENGTH]), (uint8_t const *)cy_desWeakKeys[i], CY_CRYPTO_DES_KEY_BYTE_LENGTH) == 0U)
255 {
256 status = CY_CRYPTO_DES_WEAK_KEY;
257 break;
258 }
259 }
260 if (status == CY_CRYPTO_DES_WEAK_KEY)
261 {
262 break;
263 }
264 }
265
266 Cy_Crypto_Core_V1_MemCpy(base, desBuffers->key, key, CY_CRYPTO_DES_KEY_BYTE_LENGTH * 3U);
267 Cy_Crypto_Core_V1_MemCpy(base, desBuffers->block0, src, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
268
269 Cy_Crypto_Core_V1_Des_ProcessBlock(base, CY_CRYPTO_DES_MODE_TRIPLE, dirMode,
270 (uint32_t const *)desBuffers->key, (uint32_t const *)desBuffers->block1, (uint32_t const *)desBuffers->block0);
271
272 Cy_Crypto_Core_V1_MemCpy(base, dst, desBuffers->block1, CY_CRYPTO_DES_KEY_BYTE_LENGTH);
273
274 return (status);
275 }
276
277 #endif /* (CPUSS_CRYPTO_DES == 1) && defined(CY_CRYPTO_CFG_DES_C) */
278
279 #if defined(__cplusplus)
280 }
281 #endif
282
283 #endif /* defined(CY_CRYPTO_CFG_HW_V1_ENABLE) */
284
285 #endif /* defined(CY_IP_MXCRYPTO) */
286
287
288 /* [] END OF FILE */
289