1 /*!
2 * @file apm32f4xx_cryp_tdes.c
3 *
4 * @brief This file provides high level functions to encrypt and decrypt,
5 * Input message using TDES in ECB/CBC modes.
6 *
7 * @version V1.0.2
8 *
9 * @date 2022-06-23
10 *
11 * @attention
12 *
13 * Copyright (C) 2021-2022 Geehy Semiconductor
14 *
15 * You may not use this file except in compliance with the
16 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
17 *
18 * The program is only for reference, which is distributed in the hope
19 * that it will be usefull and instructional for customers to develop
20 * their software. Unless required by applicable law or agreed to in
21 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
22 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
24 * and limitations under the License.
25 */
26
27 #include "apm32f4xx_cryp.h"
28
29 /** @addtogroup APM32F4xx_StdPeriphDriver
30 @{
31 */
32
33 /** @defgroup CRYP_TDES_Driver
34 * @brief CRYP TDES driver modules
35 @{
36 */
37
38 /** @defgroup CRYP_TDES_Functions
39 @{
40 */
41
42 /*!
43 * @brief Encrypt and decrypt using TDES in EBC Mode
44 *
45 * @param mode: Pointer to a CRYP_MODE_T structure.
46 * This parameter can be one of the following values:
47 * @arg CRYP_MODE_DECRYPT: Encryption
48 * @arg CRYP_MODE_ENCRYPT: Decryption
49 *
50 * @param key: Key used for TDES algorithm.
51 * @param input: Input buffer.
52 * @param length: length of the Input buffer, must be a multiple of 8.
53 * @param output: Output buffer.
54 *
55 * @retval SUCCESS or ERROR
56 */
CRYP_TDES_ECB(CRYP_MODE_T mode,uint8_t key[24],uint8_t * input,uint32_t length,uint8_t * output)57 uint8_t CRYP_TDES_ECB(CRYP_MODE_T mode, uint8_t key[24], uint8_t *input,
58 uint32_t length, uint8_t *output)
59 {
60 CRYP_Config_T TDEC_crypConfig;
61 CRYP_KeyConfig_T TDEC_keyConfig;
62
63 uint32_t keyAddr = (uint32_t)key;
64 uint32_t inputAddr = (uint32_t)input;
65 uint32_t outputAddr = (uint32_t)output;
66
67 uint32_t i = 0;
68 uint32_t flag = 0;
69 uint32_t status = SUCCESS;
70 __IO uint32_t counter = 0;
71
72 CRYP_ConfigKeyStructInit(&TDEC_keyConfig);
73
74 if (mode == CRYP_MODE_ENCRYPT)
75 {
76 TDEC_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
77 }
78 else
79 {
80 TDEC_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
81 }
82 TDEC_crypConfig.algoMode = CRYP_ALGOMODE_TDES_ECB;
83 TDEC_crypConfig.dataType = CRYP_DATATYPE_8B;
84 CRYP_Config(&TDEC_crypConfig);
85
86 TDEC_keyConfig.key1Left = __REV(*(uint32_t *)(keyAddr));
87 keyAddr += 0x04;
88 TDEC_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
89 keyAddr += 0x04;
90 TDEC_keyConfig.key2Left = __REV(*(uint32_t *)(keyAddr));
91 keyAddr += 0x04;
92 TDEC_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
93 keyAddr += 0x04;
94 TDEC_keyConfig.key3Left = __REV(*(uint32_t *)(keyAddr));
95 keyAddr += 0x04;
96 TDEC_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
97 CRYP_ConfigKey(&TDEC_keyConfig);
98
99 CRYP_FlushFIFO();
100 CRYP_Enable();
101
102 if (CRYP_ReadCmdStatus() == DISABLE)
103 {
104 status = ERROR;
105 }
106 else
107 {
108 for (i = 0; i < length; i += 8)
109 {
110 CRYP_InData(*(uint32_t *)(inputAddr));
111 inputAddr += 0x04;
112 CRYP_InData(*(uint32_t *)(inputAddr));
113 inputAddr += 0x04;
114
115 counter = 0;
116 do
117 {
118 flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
119 counter++;
120 }
121 while ((counter != 0x00010000) && (flag != RESET));
122
123 if (flag == SET)
124 {
125 status = ERROR;
126 }
127 else
128 {
129 *(uint32_t *)(outputAddr) = CRYP_OutData();
130 outputAddr += 0x04;
131 *(uint32_t *)(outputAddr) = CRYP_OutData();
132 outputAddr += 0x04;
133 }
134 }
135 CRYP_Disable();
136 }
137 return status;
138 }
139
140 /*!
141 * @brief Encrypt and decrypt using TDES in CBC Mode
142 *
143 * @param mode: Pointer to a CRYP_MODE_T structure.
144 * This parameter can be one of the following values:
145 * @arg CRYP_MODE_DECRYPT: Encryption
146 * @arg CRYP_MODE_ENCRYPT: Decryption
147 *
148 * @param key: Key used for TDES algorithm.
149 * @param input: Input buffer.
150 * @param IV: Initialisation Vectors used for TDES algorithm.
151 * @param length: length of the Input buffer, must be a multiple of 8.
152 * @param output: Output buffer.
153 *
154 * @retval None
155 */
CRYP_TDES_CBC(CRYP_MODE_T mode,uint8_t key[24],uint8_t * input,uint8_t IV[8],uint32_t length,uint8_t * output)156 uint8_t CRYP_TDES_CBC(CRYP_MODE_T mode, uint8_t key[24], uint8_t *input,
157 uint8_t IV[8], uint32_t length, uint8_t *output)
158 {
159 CRYP_Config_T TDEC_crypConfig;
160 CRYP_KeyConfig_T TDEC_keyConfig;
161 CRYP_IVConfig_T TDEC_IVConfig;
162
163 uint32_t keyAddr = (uint32_t)key;
164 uint32_t inputAddr = (uint32_t)input;
165 uint32_t outputAddr = (uint32_t)output;
166 uint32_t IVAddr = (uint32_t)IV;
167
168 uint32_t i = 0;
169 uint32_t flag = 0;
170 uint32_t status = SUCCESS;
171 __IO uint32_t counter = 0;
172
173 CRYP_ConfigKeyStructInit(&TDEC_keyConfig);
174
175 if (mode == CRYP_MODE_ENCRYPT)
176 {
177 TDEC_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
178 }
179 else
180 {
181 TDEC_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
182 }
183 TDEC_crypConfig.algoMode = CRYP_ALGOMODE_TDES_CBC;
184 TDEC_crypConfig.dataType = CRYP_DATATYPE_8B;
185 CRYP_Config(&TDEC_crypConfig);
186
187 TDEC_keyConfig.key1Left = __REV(*(uint32_t *)(keyAddr));
188 keyAddr += 0x04;
189 TDEC_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
190 keyAddr += 0x04;
191 TDEC_keyConfig.key2Left = __REV(*(uint32_t *)(keyAddr));
192 keyAddr += 0x04;
193 TDEC_keyConfig.key2Right = __REV(*(uint32_t *)(keyAddr));
194 keyAddr += 0x04;
195 TDEC_keyConfig.key3Left = __REV(*(uint32_t *)(keyAddr));
196 keyAddr += 0x04;
197 TDEC_keyConfig.key3Right = __REV(*(uint32_t *)(keyAddr));
198 CRYP_ConfigKey(&TDEC_keyConfig);
199
200 TDEC_IVConfig.IV0Left = __REV(*(uint32_t *)(IVAddr));
201 keyAddr += 0x04;
202 TDEC_IVConfig.IV0Right = __REV(*(uint32_t *)(IVAddr));
203 CRYP_ConfigIV(&TDEC_IVConfig);
204
205 CRYP_FlushFIFO();
206 CRYP_Enable();
207
208 if (CRYP_ReadCmdStatus() == DISABLE)
209 {
210 status = ERROR;
211 }
212 else
213 {
214 for (i = 0; i < length; i += 8)
215 {
216 CRYP_InData(*(uint32_t *)(inputAddr));
217 inputAddr += 0x04;
218 CRYP_InData(*(uint32_t *)(inputAddr));
219 inputAddr += 0x04;
220
221 counter = 0;
222 do
223 {
224 flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
225 counter++;
226 }
227 while ((counter != 0x00010000) && (flag != RESET));
228
229 if (flag == SET)
230 {
231 status = ERROR;
232 }
233 else
234 {
235 *(uint32_t *)(outputAddr) = CRYP_OutData();
236 outputAddr += 0x04;
237 *(uint32_t *)(outputAddr) = CRYP_OutData();
238 outputAddr += 0x04;
239 }
240 }
241 CRYP_Disable();
242 }
243 return status;
244 }
245
246 /**@} end of group CRYP_TDES_Functions */
247 /**@} end of group CRYP_TDES_Driver */
248 /**@} end of group APM32F4xx_StdPeriphDriver */
249