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