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