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