1 /**
2   ******************************************************************************
3   * @file    stm32f2xx_cryp_tdes.c
4   * @author  MCD Application Team
5   * @version V1.1.2
6   * @date    05-March-2012
7   * @brief   This file provides high level functions to encrypt and decrypt an
8   *          input message using TDES in ECB/CBC modes .
9   *          It uses the stm32f2xx_cryp.c/.h drivers to access the STM32F2xx CRYP
10   *          peripheral.
11   *
12   *  @verbatim
13   *
14   *          ===================================================================
15   *                                   How to use this driver
16   *          ===================================================================
17   *          1. Enable The CRYP controller clock using
18   *            RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); function.
19   *
20   *          2. Encrypt and decrypt using TDES in ECB Mode using CRYP_TDES_ECB()
21   *             function.
22   *
23   *          3. Encrypt and decrypt using TDES in CBC Mode using CRYP_TDES_CBC()
24   *             function.
25   *
26   *  @endverbatim
27   *
28   ******************************************************************************
29   * @attention
30   *
31   * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
32   *
33   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
34   * You may not use this file except in compliance with the License.
35   * You may obtain a copy of the License at:
36   *
37   *        http://www.st.com/software_license_agreement_liberty_v2
38   *
39   * Unless required by applicable law or agreed to in writing, software
40   * distributed under the License is distributed on an "AS IS" BASIS,
41   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42   * See the License for the specific language governing permissions and
43   * limitations under the License.
44   *
45   ******************************************************************************
46   */
47 
48 /* Includes ------------------------------------------------------------------*/
49 #include "stm32f2xx_cryp.h"
50 
51 
52 /** @addtogroup STM32F2xx_StdPeriph_Driver
53   * @{
54   */
55 
56 /** @defgroup CRYP
57   * @brief CRYP driver modules
58   * @{
59   */
60 
61 /* Private typedef -----------------------------------------------------------*/
62 /* Private define ------------------------------------------------------------*/
63 #define TDESBUSY_TIMEOUT    ((uint32_t) 0x00010000)
64 
65 /* Private macro -------------------------------------------------------------*/
66 /* Private variables ---------------------------------------------------------*/
67 /* Private function prototypes -----------------------------------------------*/
68 /* Private functions ---------------------------------------------------------*/
69 
70 
71 /** @defgroup CRYP_Private_Functions
72   * @{
73   */
74 
75 /** @defgroup CRYP_Group7 High Level TDES functions
76  *  @brief   High Level TDES functions
77  *
78 @verbatim
79  ===============================================================================
80                           High Level TDES functions
81  ===============================================================================
82 
83 
84 @endverbatim
85   * @{
86   */
87 
88 /**
89   * @brief  Encrypt and decrypt using TDES in ECB Mode
90   * @param  Mode: encryption or decryption Mode.
91   *           This parameter can be one of the following values:
92   *            @arg MODE_ENCRYPT: Encryption
93   *            @arg MODE_DECRYPT: Decryption
94   * @param  Key: Key used for TDES algorithm.
95   * @param  Ilength: length of the Input buffer, must be a multiple of 8.
96   * @param  Input: pointer to the Input buffer.
97   * @param  Output: pointer to the returned buffer.
98   * @retval An ErrorStatus enumeration value:
99   *          - SUCCESS: Operation done
100   *          - ERROR: Operation failed
101   */
CRYP_TDES_ECB(uint8_t Mode,uint8_t Key[24],uint8_t * Input,uint32_t Ilength,uint8_t * Output)102 ErrorStatus CRYP_TDES_ECB(uint8_t Mode, uint8_t Key[24], uint8_t *Input,
103                           uint32_t Ilength, uint8_t *Output)
104 {
105   CRYP_InitTypeDef TDES_CRYP_InitStructure;
106   CRYP_KeyInitTypeDef TDES_CRYP_KeyInitStructure;
107   __IO uint32_t counter = 0;
108   uint32_t busystatus = 0;
109   ErrorStatus status = SUCCESS;
110   uint32_t keyaddr    = (uint32_t)Key;
111   uint32_t inputaddr  = (uint32_t)Input;
112   uint32_t outputaddr = (uint32_t)Output;
113   uint32_t i = 0;
114 
115   /* Crypto structures initialisation*/
116   CRYP_KeyStructInit(&TDES_CRYP_KeyInitStructure);
117 
118   /* Crypto Init for Encryption process */
119   if(Mode == MODE_ENCRYPT) /* TDES encryption */
120   {
121      TDES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
122   }
123   else /*if(Mode == MODE_DECRYPT)*/ /* TDES decryption */
124   {
125      TDES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
126   }
127 
128   TDES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_ECB;
129   TDES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
130   CRYP_Init(&TDES_CRYP_InitStructure);
131 
132   /* Key Initialisation */
133   TDES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
134   keyaddr+=4;
135   TDES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
136   keyaddr+=4;
137   TDES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
138   keyaddr+=4;
139   TDES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
140   keyaddr+=4;
141   TDES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
142   keyaddr+=4;
143   TDES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
144   CRYP_KeyInit(& TDES_CRYP_KeyInitStructure);
145 
146   /* Flush IN/OUT FIFO */
147   CRYP_FIFOFlush();
148 
149   /* Enable Crypto processor */
150   CRYP_Cmd(ENABLE);
151 
152   for(i=0; ((i<Ilength) && (status != ERROR)); i+=8)
153   {
154     /* Write the Input block in the Input FIFO */
155     CRYP_DataIn(*(uint32_t*)(inputaddr));
156     inputaddr+=4;
157     CRYP_DataIn(*(uint32_t*)(inputaddr));
158     inputaddr+=4;
159 
160     /* Wait until the complete message has been processed */
161     counter = 0;
162     do
163     {
164       busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
165       counter++;
166     }while ((counter != TDESBUSY_TIMEOUT) && (busystatus != RESET));
167 
168     if (busystatus != RESET)
169     {
170        status = ERROR;
171     }
172     else
173     {
174 
175       /* Read the Output block from the Output FIFO */
176       *(uint32_t*)(outputaddr) = CRYP_DataOut();
177       outputaddr+=4;
178       *(uint32_t*)(outputaddr) = CRYP_DataOut();
179       outputaddr+=4;
180     }
181   }
182 
183   /* Disable Crypto */
184   CRYP_Cmd(DISABLE);
185 
186   return status;
187 }
188 
189 /**
190   * @brief  Encrypt and decrypt using TDES in CBC Mode
191   * @param  Mode: encryption or decryption Mode.
192   *           This parameter can be one of the following values:
193   *            @arg MODE_ENCRYPT: Encryption
194   *            @arg MODE_DECRYPT: Decryption
195   * @param  Key: Key used for TDES algorithm.
196   * @param  InitVectors: Initialisation Vectors used for TDES algorithm.
197   * @param  Input: pointer to the Input buffer.
198   * @param  Ilength: length of the Input buffer, must be a multiple of 8.
199   * @param  Output: pointer to the returned buffer.
200   * @retval An ErrorStatus enumeration value:
201   *          - SUCCESS: Operation done
202   *          - ERROR: Operation failed
203   */
CRYP_TDES_CBC(uint8_t Mode,uint8_t Key[24],uint8_t InitVectors[8],uint8_t * Input,uint32_t Ilength,uint8_t * Output)204 ErrorStatus CRYP_TDES_CBC(uint8_t Mode, uint8_t Key[24], uint8_t InitVectors[8],
205                           uint8_t *Input, uint32_t Ilength, uint8_t *Output)
206 {
207   CRYP_InitTypeDef TDES_CRYP_InitStructure;
208   CRYP_KeyInitTypeDef TDES_CRYP_KeyInitStructure;
209   CRYP_IVInitTypeDef TDES_CRYP_IVInitStructure;
210   __IO uint32_t counter = 0;
211   uint32_t busystatus = 0;
212   ErrorStatus status = SUCCESS;
213   uint32_t keyaddr    = (uint32_t)Key;
214   uint32_t inputaddr  = (uint32_t)Input;
215   uint32_t outputaddr = (uint32_t)Output;
216   uint32_t ivaddr     = (uint32_t)InitVectors;
217   uint32_t i = 0;
218 
219   /* Crypto structures initialisation*/
220   CRYP_KeyStructInit(&TDES_CRYP_KeyInitStructure);
221 
222   /* Crypto Init for Encryption process */
223   if(Mode == MODE_ENCRYPT) /* TDES encryption */
224   {
225     TDES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
226   }
227   else
228   {
229     TDES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
230   }
231   TDES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_CBC;
232   TDES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
233 
234   CRYP_Init(&TDES_CRYP_InitStructure);
235 
236   /* Key Initialisation */
237   TDES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
238   keyaddr+=4;
239   TDES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
240   keyaddr+=4;
241   TDES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
242   keyaddr+=4;
243   TDES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
244   keyaddr+=4;
245   TDES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
246   keyaddr+=4;
247   TDES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
248   CRYP_KeyInit(& TDES_CRYP_KeyInitStructure);
249 
250   /* Initialization Vectors */
251   TDES_CRYP_IVInitStructure.CRYP_IV0Left = __REV(*(uint32_t*)(ivaddr));
252   ivaddr+=4;
253   TDES_CRYP_IVInitStructure.CRYP_IV0Right= __REV(*(uint32_t*)(ivaddr));
254   CRYP_IVInit(&TDES_CRYP_IVInitStructure);
255 
256   /* Flush IN/OUT FIFO */
257   CRYP_FIFOFlush();
258 
259   /* Enable Crypto processor */
260   CRYP_Cmd(ENABLE);
261 
262   for(i=0; ((i<Ilength) && (status != ERROR)); i+=8)
263   {
264     /* Write the Input block in the Input FIFO */
265     CRYP_DataIn(*(uint32_t*)(inputaddr));
266     inputaddr+=4;
267     CRYP_DataIn(*(uint32_t*)(inputaddr));
268     inputaddr+=4;
269 
270     /* Wait until the complete message has been processed */
271     counter = 0;
272     do
273     {
274       busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
275       counter++;
276     }while ((counter != TDESBUSY_TIMEOUT) && (busystatus != RESET));
277 
278     if (busystatus != RESET)
279    {
280        status = ERROR;
281     }
282     else
283     {
284 
285       /* Read the Output block from the Output FIFO */
286       *(uint32_t*)(outputaddr) = CRYP_DataOut();
287       outputaddr+=4;
288       *(uint32_t*)(outputaddr) = CRYP_DataOut();
289       outputaddr+=4;
290     }
291   }
292 
293   /* Disable Crypto */
294   CRYP_Cmd(DISABLE);
295 
296   return status;
297 }
298 /**
299   * @}
300   */
301 
302 /**
303   * @}
304   */
305 
306 /**
307   * @}
308   */
309 
310 /**
311   * @}
312   */
313 
314 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
315