1 /*!
2  * @file        apm32f4xx_cryp_des.c
3  *
4  * @brief       This file provides high level functions to encrypt and decrypt,
5  *              Input message using DES 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_DES_Driver
34   * @brief CRYP DES driver modules
35   @{
36 */
37 
38 /** @defgroup CRYP_DES_Functions
39   @{
40 */
41 
42 /*!
43  * @brief     Encrypt and decrypt using DES 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 DES 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_DES_ECB(CRYP_MODE_T mode,uint8_t key[8],uint8_t * input,uint32_t length,uint8_t * output)57 uint8_t CRYP_DES_ECB(CRYP_MODE_T mode, uint8_t key[8], uint8_t *input,
58                      uint32_t length, uint8_t *output)
59 {
60     CRYP_Config_T    DEC_crypConfig;
61     CRYP_KeyConfig_T DEC_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(&DEC_keyConfig);
73 
74     if (mode == CRYP_MODE_ENCRYPT)
75     {
76         DEC_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
77     }
78     else
79     {
80         DEC_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
81     }
82     DEC_crypConfig.algoMode = CRYP_ALGOMODE_DES_ECB;
83     DEC_crypConfig.dataType = CRYP_DATATYPE_8B;
84     CRYP_Config(&DEC_crypConfig);
85 
86     DEC_keyConfig.key1Left = __REV(*(uint32_t *)(keyAddr));
87     keyAddr += 0x04;
88     DEC_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
89     CRYP_ConfigKey(&DEC_keyConfig);
90 
91     CRYP_FlushFIFO();
92     CRYP_Enable();
93 
94     if (CRYP_ReadCmdStatus() == DISABLE)
95     {
96         status = ERROR;
97     }
98     else
99     {
100         for (i = 0; i < length; i += 8)
101         {
102             CRYP_InData(*(uint32_t *)(inputAddr));
103             inputAddr += 0x04;
104             CRYP_InData(*(uint32_t *)(inputAddr));
105             inputAddr += 0x04;
106 
107             counter = 0;
108             do
109             {
110                 flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
111                 counter++;
112             }
113             while ((counter != 0x00010000) && (flag != RESET));
114 
115             if (flag == SET)
116             {
117                 status = ERROR;
118             }
119             else
120             {
121                 *(uint32_t *)(outputAddr) = CRYP_OutData();
122                 outputAddr += 0x04;
123                 *(uint32_t *)(outputAddr) = CRYP_OutData();
124                 outputAddr += 0x04;
125             }
126         }
127         CRYP_Disable();
128     }
129     return status;
130 }
131 
132 /*!
133  * @brief     Encrypt and decrypt using DES in CBC Mode
134  *
135  * @param     mode: Pointer to a CRYP_MODE_T structure.
136  *            This parameter can be one of the following values:
137  *                @arg CRYP_MODE_DECRYPT: Encryption
138  *                @arg CRYP_MODE_ENCRYPT: Decryption
139  *
140  * @param     key:    Key used for DES algorithm.
141  * @param     input:  Input buffer.
142  * @param     IV:     Initialisation Vectors used for DES algorithm.
143  * @param     length: length of the Input buffer, must be a multiple of 8.
144  * @param     output: Output buffer.
145  *
146  * @retval    None
147  */
CRYP_DES_CBC(CRYP_MODE_T mode,uint8_t key[8],uint8_t * input,uint8_t IV[8],uint32_t length,uint8_t * output)148 uint8_t CRYP_DES_CBC(CRYP_MODE_T mode, uint8_t key[8],  uint8_t *input,
149                      uint8_t IV[8], uint32_t length, uint8_t *output)
150 {
151     CRYP_Config_T    DEC_crypConfig;
152     CRYP_KeyConfig_T DEC_keyConfig;
153     CRYP_IVConfig_T  DEC_IVConfig;
154 
155     uint32_t keyAddr    = (uint32_t)key;
156     uint32_t inputAddr  = (uint32_t)input;
157     uint32_t outputAddr = (uint32_t)output;
158     uint32_t IVAddr     = (uint32_t)IV;
159 
160     uint32_t i = 0;
161     uint32_t flag = 0;
162     uint32_t status = SUCCESS;
163     __IO uint32_t counter = 0;
164 
165     CRYP_ConfigKeyStructInit(&DEC_keyConfig);
166 
167     if (mode == CRYP_MODE_ENCRYPT)
168     {
169         DEC_crypConfig.algoDir = CRYP_ALGODIR_ENCRYPT;
170     }
171     else
172     {
173         DEC_crypConfig.algoDir = CRYP_ALGODIR_DECRYPT;
174     }
175     DEC_crypConfig.algoMode = CRYP_ALGOMODE_DES_CBC;
176     DEC_crypConfig.dataType = CRYP_DATATYPE_8B;
177     CRYP_Config(&DEC_crypConfig);
178 
179     DEC_keyConfig.key1Left = __REV(*(uint32_t *)(keyAddr));
180     keyAddr += 0x04;
181     DEC_keyConfig.key1Right = __REV(*(uint32_t *)(keyAddr));
182     CRYP_ConfigKey(&DEC_keyConfig);
183 
184     DEC_IVConfig.IV0Left  = __REV(*(uint32_t *)(IVAddr));
185     keyAddr += 0x04;
186     DEC_IVConfig.IV0Right = __REV(*(uint32_t *)(IVAddr));
187     CRYP_ConfigIV(&DEC_IVConfig);
188 
189     CRYP_FlushFIFO();
190     CRYP_Enable();
191 
192     if (CRYP_ReadCmdStatus() == DISABLE)
193     {
194         status = ERROR;
195     }
196     else
197     {
198         for (i = 0; i < length; i += 8)
199         {
200             CRYP_InData(*(uint32_t *)(inputAddr));
201             inputAddr += 0x04;
202             CRYP_InData(*(uint32_t *)(inputAddr));
203             inputAddr += 0x04;
204 
205             counter = 0;
206             do
207             {
208                 flag = CRYP_ReadStatusFlag(CRYP_FLAG_BUSY);
209                 counter++;
210             }
211             while ((counter != 0x00010000) && (flag != RESET));
212 
213             if (flag == SET)
214             {
215                 status = ERROR;
216             }
217             else
218             {
219                 *(uint32_t *)(outputAddr) = CRYP_OutData();
220                 outputAddr += 0x04;
221                 *(uint32_t *)(outputAddr) = CRYP_OutData();
222                 outputAddr += 0x04;
223             }
224         }
225         CRYP_Disable();
226     }
227     return status;
228 }
229 
230 /**@} end of group CRYP_DES_Functions */
231 /**@} end of group CRYP_DES_Driver */
232 /**@} end of group APM32F4xx_StdPeriphDriver */
233