XMEGA_AES_driver.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. /* This file has been prepared for Doxygen automatic documentation generation.*/
  2. /*! \file *********************************************************************
  3. *
  4. * \brief
  5. * XMEGA AES driver source file.
  6. *
  7. * This file contains the function implementations the XMEGA AES driver.
  8. *
  9. * The driver is not intended for size and/or speed critical code, since
  10. * most functions are just a few lines of code, and the function call
  11. * overhead would decrease code performance. The driver is intended for
  12. * rapid prototyping and documentation purposes for getting started with
  13. * the XMEGA AES module.
  14. *
  15. * For size and/or speed critical code, it is recommended to copy the
  16. * function contents directly into your application instead of making
  17. * a function call.
  18. *
  19. * Several functions use the following construct:
  20. * "some_register = ... | (some_parameter ? SOME_BIT_bm : 0) | ..."
  21. * Although the use of the ternary operator ( if ? then : else ) is discouraged,
  22. * in some occasions the operator makes it possible to write pretty clean and
  23. * neat code. In this driver, the construct is used to set or not set a
  24. * configuration bit based on a boolean input parameter, such as
  25. * the "some_parameter" in the example above.
  26. *
  27. * \par Application note:
  28. * AVR1317 Using the XMEGA built in AES accelerator
  29. *
  30. * \par Documentation
  31. * For comprehensive code documentation, supported compilers, compiler
  32. * settings and supported devices see readme.html
  33. *
  34. * \author
  35. * Atmel Corporation: http://www.atmel.com \n
  36. * Support email: avr@atmel.com
  37. *
  38. * $Revision: 1569 $
  39. * $Date: 2008-04-22 13:03:43 +0200 (ti, 22 apr 2008) $ \n
  40. *
  41. * Copyright (c) 2008, Atmel Corporation All rights reserved.
  42. *
  43. * Redistribution and use in source and binary forms, with or without
  44. * modification, are permitted provided that the following conditions are met:
  45. *
  46. * 1. Redistributions of source code must retain the above copyright notice,
  47. * this list of conditions and the following disclaimer.
  48. *
  49. * 2. Redistributions in binary form must reproduce the above copyright notice,
  50. * this list of conditions and the following disclaimer in the documentation
  51. * and/or other materials provided with the distribution.
  52. *
  53. * 3. The name of ATMEL may not be used to endorse or promote products derived
  54. * from this software without specific prior written permission.
  55. *
  56. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  57. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  58. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
  59. * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
  60. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  61. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  62. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  63. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  64. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  65. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  66. *****************************************************************************/
  67. #if HWCRYPTO
  68. #include "XMEGA_AES_driver.h"
  69. /*! \brief Function that initialize the interrupt driver
  70. *
  71. * \param interrupt_driver Pointer to interrupt driver struct .
  72. * \param input_ptr Pointer to the input blocks (plaintext/ciphertext).
  73. * \param output_ptr Pointer to where to store the output.
  74. * \param AES_key Pointer to the key used by the AES algorithm.
  75. * \param AES_CBC_init Pointer to initialization vector needed in CBC.
  76. * \param block_count The number of block that is being encrypted/decrypted.
  77. * \param decrypt Bool that determine if encryption or decryption is done.
  78. *
  79. */
  80. void AES_interrupt_driver_init(AES_interrupt_driver_t * interrupt_driver,
  81. uint8_t * input_ptr,
  82. uint8_t * output_ptr,
  83. uint8_t * AES_key,
  84. uint8_t * AES_CBC_init,
  85. uint8_t block_count,
  86. bool decrypt)
  87. {
  88. /* Initialize interrupt driver struct. */
  89. interrupt_driver->block_count = block_count;
  90. interrupt_driver->blocks_left = block_count;
  91. interrupt_driver->output_ptr = output_ptr;
  92. interrupt_driver->input_ptr = input_ptr;
  93. interrupt_driver->key_ptr = AES_key;
  94. interrupt_driver->init_ptr = AES_CBC_init;
  95. interrupt_driver->decrypt = decrypt;
  96. }
  97. /*! \brief Function that starts the AES interrupt driver
  98. *
  99. * CBC is used if the number of blocks is more than one.
  100. *
  101. * \param interrupt_driver Pointer to interrupt driver struct.
  102. * \param int_lvl Interrupt level for the AES module.
  103. *
  104. * \retval true Starting the AES interrupt driver was successful.
  105. * \retval false Starting the AES interrupt driver was not successful.
  106. *
  107. */
  108. bool AES_interrupt_driver_start(AES_interrupt_driver_t * interrupt_driver,
  109. AES_INTLVL_t int_lvl)
  110. {
  111. bool start_ok;
  112. /* Remove pending AES interrupts. */
  113. AES.STATUS = (AES_ERROR_bm | AES_SRIF_bm);
  114. /* Set AES to the desired interrupt level.
  115. * NOTE: If interrupt level is set to off, interrupts will never execute. */
  116. AES.INTCTRL = int_lvl;
  117. /* Put AES module in right mode. */
  118. if(interrupt_driver->decrypt){
  119. AES.CTRL |= AES_DECRYPT_bm;
  120. }else{
  121. AES.CTRL = AES.CTRL & (~AES_DECRYPT_bm);
  122. }
  123. /* If encryption and there are more than one block CBC is used. In CBC
  124. * encryption the first plaintext block is xored with the initialization
  125. * vector. */
  126. if((interrupt_driver->block_count > 1) && !(interrupt_driver->decrypt)){
  127. /* Load key to AES Key memory. */
  128. uint8_t * temp_key_ptr = interrupt_driver->key_ptr;
  129. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  130. AES.KEY = *(temp_key_ptr++);
  131. }
  132. /* Load the first plaintext block to AES State memory. */
  133. uint8_t * temp_input_ptr = interrupt_driver->input_ptr;
  134. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  135. AES.STATE = *(temp_input_ptr++);
  136. }
  137. interrupt_driver->input_ptr = temp_input_ptr;
  138. /* Enable Auto mode and the XOR feature. */
  139. AES.CTRL = AES.CTRL | AES_XOR_bm | AES_AUTO_bm;
  140. /* Load the initialization vector to the AES State memory.
  141. * The initialization vector is xored with the plaintext block already
  142. * loaded into the memory and the AES module is auto started. */
  143. uint8_t * temp_init_ptr = interrupt_driver->init_ptr;
  144. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  145. AES.STATE = *(temp_init_ptr++);
  146. }
  147. /* Check if error flag is set. */
  148. start_ok = !(AES_error_flag_check());
  149. }
  150. /* If decryption or encryption of a single block the xor feature is not
  151. * used. */
  152. else{
  153. /* Load key to AES Key memory. */
  154. volatile uint8_t * temp_key_ptr = interrupt_driver->key_ptr;
  155. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  156. AES.KEY = *(temp_key_ptr++);
  157. }
  158. /* Enable Auto mode. */
  159. AES.CTRL |= AES_AUTO_bm;
  160. /* Load the first input block to AES State memory. */
  161. uint8_t * temp_input_ptr = interrupt_driver->input_ptr;
  162. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  163. AES.STATE = *(temp_input_ptr++);
  164. }
  165. /* Update input pointer. */
  166. interrupt_driver->input_ptr = temp_input_ptr;
  167. /* Check if error flag is set. */
  168. start_ok = !(AES_error_flag_check());
  169. }
  170. return start_ok;
  171. }
  172. /*! \brief Function that control the AES when State Ready Interrupts occurs.
  173. *
  174. * CBC is used if the number of blocks is more than one.
  175. *
  176. * \param interrupt_driver Pointer to interrupt driver struct.
  177. */
  178. void AES_interrupt_handler(AES_interrupt_driver_t * interrupt_driver)
  179. {
  180. /* If encryption is done, the answer can be read out directly from the
  181. * state memory. Then the output pointer is updated. */
  182. if(!(interrupt_driver->decrypt)){
  183. /* Store result to memory. */
  184. uint8_t * temp_output_ptr = interrupt_driver->output_ptr;
  185. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  186. *(temp_output_ptr++) = AES.STATE;
  187. }
  188. /* Update output pointer and the number of blocks left to
  189. * encrypt/decrypt. */
  190. interrupt_driver->output_ptr = temp_output_ptr;
  191. interrupt_driver->blocks_left -= 1;
  192. /* If there are more blocks to encrypt a new encryption is started. */
  193. if(interrupt_driver->blocks_left > 0){
  194. /* Load key to AES Key memory. */
  195. uint8_t * temp_key_ptr = interrupt_driver->key_ptr;
  196. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  197. AES.KEY = *(temp_key_ptr++);
  198. }
  199. /* Load the next plaintext to the AES State memory. The block is xored
  200. * with the previous encrypted block and the AES module is auto
  201. * started. */
  202. uint8_t * temp_input_ptr = interrupt_driver->input_ptr;
  203. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  204. AES.STATE = *(temp_input_ptr++);
  205. }
  206. /* Update input pointer. */
  207. interrupt_driver->input_ptr = temp_input_ptr;
  208. }
  209. }
  210. /* When decryption is done, the answer can only be read out directly if
  211. * there only is one block to decrypt. If there are more than one block and
  212. * CBC is used the answer must be xored with the previous cipher text or
  213. * the initialization vector to reconstruct the plaintext. */
  214. else{
  215. /* If only one block should be decrypted the plaintext can be read out
  216. * directly from the AES State memory. */
  217. if(interrupt_driver->block_count == 1){
  218. /* Store result to memory. */
  219. uint8_t * temp_output_pointer = interrupt_driver->output_ptr;
  220. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  221. *(temp_output_pointer + i) = AES.STATE;
  222. }
  223. }
  224. /* If there are more than one block to decrypt. */
  225. else{
  226. /* Disable of Auto mode and enable on the xor feature. */
  227. AES.CTRL = (AES.CTRL & (~AES_AUTO_bm)) | AES_XOR_bm;
  228. /* If it is the first block that is decrypted the answer must be
  229. * xored with initialization vector to reconstruct the first
  230. * plaintext. */
  231. uint8_t * temp_ptr;
  232. uint8_t temp_blocks_left = interrupt_driver->blocks_left;
  233. if(interrupt_driver->block_count == temp_blocks_left){
  234. temp_ptr = interrupt_driver->init_ptr;
  235. }
  236. /* Else the answer must be xored with previous ciphertext value to
  237. * reconstruct the plaintext. */
  238. else{
  239. temp_ptr = interrupt_driver->input_ptr -(AES_BLOCK_LENGTH*2);
  240. }
  241. /* Xor the initialization vector or the previous ciphertext with
  242. * the answer from the decryption. */
  243. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  244. AES.STATE = *(temp_ptr++);
  245. }
  246. /* Store the result. */
  247. uint8_t * temp_output_ptr = interrupt_driver->output_ptr;
  248. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  249. *(temp_output_ptr++) = AES.STATE;
  250. }
  251. /* Update output pointer and the number of blocks left to
  252. * encrypt/decrypt. */
  253. interrupt_driver->output_ptr = temp_output_ptr;
  254. interrupt_driver->blocks_left -= 1;
  255. /* If there are more block to decrypt a new decryption is started. */
  256. if(interrupt_driver->blocks_left > 0){
  257. /* Enable the Auto mode and disable the xor feature. */
  258. AES.CTRL = (AES.CTRL & (~AES_XOR_bm)) | AES_AUTO_bm;
  259. /* Load key to AES Key memory. */
  260. uint8_t * temp_key_ptr = interrupt_driver->key_ptr;
  261. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  262. AES.KEY = *(temp_key_ptr++);
  263. }
  264. /* Load the next ciphertext block to the AES State memory. The
  265. * AES module is auto started. */
  266. uint8_t * temp_input_ptr = interrupt_driver->input_ptr;
  267. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  268. AES.STATE = *(temp_input_ptr++);
  269. }
  270. /* Update the input pointer. */
  271. interrupt_driver->input_ptr = temp_input_ptr;
  272. }
  273. }
  274. }
  275. }
  276. /*! \brief Function that check if the interrupt driver is finished.
  277. *
  278. * \param interrupt_driver Pointer to interrupt driver struct.
  279. *
  280. * \retval true The AES interrupt driver is finished.
  281. * \retval false The AES interrupt driver is not finished.
  282. */
  283. bool AES_interrupt_driver_finished(AES_interrupt_driver_t * interrupt_driver)
  284. {
  285. bool finished = (interrupt_driver->blocks_left == 0);
  286. return finished;
  287. }
  288. /*! \brief Polled function that does an AES encryption on one 128-bit data block.
  289. *
  290. * \note This code is blocking and will dead lock if no interrupt flags are set.
  291. *
  292. * \param plaintext Pointer to the plaintext that shall be encrypted
  293. * \param ciphertext Pointer to where in memory the ciphertext (answer) shall be stored.
  294. * \param key Pointer to the AES key
  295. *
  296. * \retval true If the AES encryption was successful.
  297. * \retval false If the AES encryption was not successful.
  298. */
  299. bool AES_encrypt(uint8_t * plaintext, uint8_t * ciphertext, uint8_t * key)
  300. {
  301. bool encrypt_ok;
  302. /* Load key into AES key memory. */
  303. uint8_t * temp_key = key;
  304. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  305. AES.KEY = *(temp_key++);
  306. }
  307. /* Load data into AES state memory. */
  308. uint8_t * temp_plaintext = plaintext;
  309. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  310. AES.STATE = *(temp_plaintext++);
  311. }
  312. // PORTA.OUT = PIN0_bm;
  313. /* Set AES in encryption mode and start AES. */
  314. AES.CTRL = (AES.CTRL & (~AES_DECRYPT_bm)) | AES_START_bm;
  315. //PORTA.OUT = 0;
  316. do{
  317. /* Wait until AES is finished or an error occurs. */
  318. }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0);
  319. /* If not error. */
  320. if((AES.STATUS & AES_ERROR_bm) == 0){
  321. /* Store the result. */
  322. uint8_t * temp_ciphertext = ciphertext;
  323. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  324. *(temp_ciphertext++) = AES.STATE;
  325. }
  326. encrypt_ok = true;
  327. }else{
  328. encrypt_ok = false;
  329. }
  330. return encrypt_ok;
  331. }
  332. /*! \brief Polled function that does an AES decryption on one 128-bit data block.
  333. *
  334. * \note This code is blocking and will dead lock if no interrupt flags are set.
  335. *
  336. * \param ciphertext Pointer to the ciphertext that shall be decrypted
  337. * \param plaintext Pointer to where in memory the plaintext (answer) shall be stored.
  338. * \param key Pointer to the DES key
  339. *
  340. * \retval true If the AES decryption was successful.
  341. * \retval false If the AES decryption was not successful.
  342. */
  343. bool AES_decrypt(uint8_t * ciphertext, uint8_t * plaintext,
  344. uint8_t * key)
  345. {
  346. bool decrypt_ok;
  347. /* Load key into AES key memory. */
  348. uint8_t * temp_key = key;
  349. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  350. AES.KEY = *(temp_key++);
  351. }
  352. /* Load data into AES state memory. */
  353. uint8_t * temp_ciphertext = ciphertext;
  354. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  355. AES.STATE = *(temp_ciphertext++);
  356. }
  357. /* Set AES in decryption mode and start the AES.*/
  358. AES.CTRL |= (AES_START_bm | AES_DECRYPT_bm);
  359. do{
  360. /* Wait until AES is finished or an error occurs. */
  361. }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0);
  362. /* If not error. */
  363. if((AES.STATUS & AES_ERROR_bm) == 0){
  364. /* Store the result. */
  365. uint8_t * temp_plaintext = plaintext;
  366. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  367. *(temp_plaintext++) = AES.STATE;
  368. }
  369. decrypt_ok = true;
  370. }else{
  371. decrypt_ok = false;
  372. }
  373. return decrypt_ok;
  374. }
  375. /*! \brief Polled function that generates the last subkey of the Expanded Key
  376. * needed during decryption.
  377. *
  378. * \note This code is blocking and will dead lock if no interrupt flags are set.
  379. *
  380. * \param key Pointer to AES key.
  381. * \param last_sub_key Pointer to where the last subkey of the Expanded Key
  382. * shall be stored.
  383. *
  384. * \retval true If generating the last subkey was successful.
  385. * \retval false If generating the last subkey was not successful.
  386. */
  387. bool AES_lastsubkey_generate(uint8_t * key, uint8_t * last_sub_key)
  388. {
  389. bool keygen_ok;
  390. AES_software_reset();
  391. /* Load key into AES key memory. */
  392. uint8_t * temp_key = key;
  393. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  394. AES.KEY = *(temp_key++);
  395. }
  396. /* Load dummy data into AES state memory. */
  397. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  398. AES.STATE = 0x00;
  399. }
  400. /* Set AES in encryption mode and start AES. */
  401. AES.CTRL = (AES.CTRL & (~AES_DECRYPT_bm)) | AES_START_bm;
  402. do{
  403. /* Wait until AES is finished or an error occurs. */
  404. }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0);
  405. /* If not error. */
  406. if((AES.STATUS & AES_ERROR_bm) == 0){
  407. /* Store the last subkey. */
  408. uint8_t * temp_last_sub_key = last_sub_key;
  409. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  410. *(temp_last_sub_key++) = AES.KEY;
  411. }
  412. AES.STATUS = AES_SRIF_bm;
  413. keygen_ok = true;
  414. }else{
  415. AES.STATUS = AES_ERROR_bm;
  416. keygen_ok = false;
  417. }
  418. return keygen_ok;
  419. }
  420. /*! \brief Polled function that does AES CBC encryption on a given number of
  421. * 128-bit data block.
  422. *
  423. * \note This code is blocking and will dead lock if no interrupt flags are set.
  424. *
  425. * \param plaintext Pointer to the plaintext that shall be encrypted.
  426. * \param ciphertext Pointer to where in memory the ciphertext (answer) shall be stored.
  427. * \param key Pointer to the key.
  428. * \param init Pointer to the initialization vector used in the CBC.
  429. * \param block_count The number of blocks to encrypt.
  430. *
  431. * \retval true: The AES CBC encryption was successful.
  432. * \retval false: The AES CBC encryption was not successful.
  433. */
  434. bool AES_CBC_encrypt(uint8_t * plaintext, uint8_t * ciphertext,
  435. uint8_t * key, uint8_t * init, uint16_t block_count)
  436. {
  437. bool CBC_ok = true;
  438. /* The first encryption uses the initialization vector. */
  439. uint8_t * temp_init = init;
  440. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  441. AES.STATE = *(temp_init++);
  442. }
  443. /* Set AES in encryption mode and enables the XOR feature and the AUTO start
  444. * mode. */
  445. AES.CTRL = (AES.CTRL & (~AES_DECRYPT_bm))| AES_XOR_bm |AES_AUTO_bm;
  446. /* Temporary values used to reduce memory access. */
  447. uint8_t * temp_plaintext = plaintext;
  448. uint8_t * temp_ciphertext = ciphertext;
  449. for(uint8_t blocks_left = block_count; blocks_left > 0; blocks_left--){
  450. /* Load key into AES key memory. */
  451. uint8_t * temp_key = key;
  452. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  453. AES.KEY = *(temp_key++);
  454. }
  455. /* Load plaintext into AES state memory. Auto starts. */
  456. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  457. AES.STATE = *(temp_plaintext++);
  458. }
  459. do{
  460. /* Wait until AES is finished or an error occurs. */
  461. }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0);
  462. /* If not error. */
  463. if((AES.STATUS & AES_ERROR_bm) == 0){
  464. /* Store result. */
  465. uint8_t * temp = temp_ciphertext;
  466. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  467. *(temp++) = AES.STATE;
  468. }
  469. temp_ciphertext = temp;
  470. }else{
  471. CBC_ok = false;
  472. }
  473. }
  474. /* Turn off auto mode and xor feature. */
  475. AES.CTRL = (AES.CTRL & ~( AES_XOR_bm |AES_AUTO_bm));
  476. return CBC_ok;
  477. }
  478. /*! \brief Polled function that does AES CBC decryption on a given number of
  479. * 128-bit data block.
  480. *
  481. * \note This code is blocking and will dead lock if no interrupt flags are set.
  482. *
  483. * \param ciphertext Pointer to the ciphertext that shall be decrypted.
  484. * \param plaintext Pointer to where the plaintext (answer) shall be stored.
  485. * \param key Pointer to the last subkey of the Expanded Key.
  486. * \param init Pointer to the initialization vector used in the CBC.
  487. * \param block_count The number of blocks to decrypt.
  488. *
  489. * \retval true If the AES CBC decryption was successful.
  490. * \retval false If the AES CBC decryption was not successful.
  491. */
  492. bool AES_CBC_decrypt(uint8_t * ciphertext, uint8_t * plaintext,
  493. uint8_t * key, uint8_t * init, uint16_t block_count)
  494. {
  495. bool CBC_ok = true;
  496. /* Temporary values used to reduce memory access. */
  497. uint8_t * temp_plaintext = plaintext;
  498. uint8_t * temp_ciphertext = ciphertext;
  499. for(uint8_t blocks_left = block_count; blocks_left > 0; blocks_left--){
  500. /* Load key into AES key memory. */
  501. uint8_t * temp_key = key;
  502. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  503. AES.KEY = *(temp_key++);
  504. }
  505. /* Load ciphertext into AES state memory. */
  506. uint8_t * temp = temp_ciphertext;
  507. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  508. AES.STATE = *(temp++);
  509. }
  510. temp_ciphertext = temp;
  511. /* Set AES in decryption mode and enable xor feature and start the AES. */
  512. AES.CTRL |= (AES_DECRYPT_bm | AES_XOR_bm | AES_START_bm);
  513. do{
  514. /* Wait until AES is finished or an error occurs. */
  515. }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0);
  516. /* If not error. */
  517. if((AES.STATUS & AES_ERROR_bm) == 0){
  518. /* The first block is xored with the initialization vector. */
  519. if(blocks_left == block_count){
  520. /* Load into AES state memory. */
  521. uint8_t * temp_init = init;
  522. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  523. AES.STATE = *(temp_init++);
  524. }
  525. }
  526. /* The other blocks is xored with the previous ciphertext block. */
  527. else{
  528. /* Load into AES state memory. */
  529. uint8_t * last_ciphertext = temp_ciphertext - (AES_BLOCK_LENGTH*2);
  530. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  531. AES.STATE = *(last_ciphertext++);
  532. }
  533. }
  534. /* Disable XOR feature before next round. */
  535. AES.CTRL = AES.CTRL & (~AES_XOR_bm);
  536. /* Store the result. */
  537. uint8_t * temp = temp_plaintext;
  538. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  539. *(temp++) = AES.STATE;
  540. }
  541. temp_plaintext = temp;
  542. }else{
  543. CBC_ok = false;
  544. }
  545. }
  546. return CBC_ok;
  547. }
  548. /*! \brief Function that sets AES interrupt level
  549. *
  550. * \param int_lvl The AES interrupt level
  551. */
  552. void AES_interruptlevel_set(AES_INTLVL_t int_lvl)
  553. {
  554. AES.INTCTRL = int_lvl;
  555. }
  556. /*! \brief Polled function that does an AES encryption on one 128-bit data block.
  557. *
  558. * Function equal to the AES_encrypt function but the key is not loaded
  559. * into the key memory. The function require that the key already is in the
  560. * key memory. Used when encryption and decryption with the same key is
  561. * done every other time.
  562. *
  563. * \note This code is blocking and will dead lock if no interrupt flags are set.
  564. *
  565. * \param plaintext Pointer to the plaintext that shall be encrypted
  566. * \param ciphertext Pointer to where in memory the ciphertext (answer) shall be stored.
  567. *
  568. * \retval true If the AES encryption was successful.
  569. * \retval false If the AES encryption was not successful.
  570. */
  571. bool AES_encrypt_backtoback(uint8_t * plaintext, uint8_t * ciphertext)
  572. {
  573. bool encrypt_ok;
  574. /* Load data into AES state memory. */
  575. uint8_t * temp_plaintext = plaintext;
  576. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  577. AES.STATE = *(temp_plaintext++);
  578. }
  579. /* Set AES in encryption mode and start AES. */
  580. AES.CTRL = (AES.CTRL & (~AES_DECRYPT_bm)) | AES_START_bm;
  581. do{
  582. /* Wait until AES is finished or an error occurs. */
  583. }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0);
  584. /* If not error. */
  585. if((AES.STATUS & AES_ERROR_bm) == 0){
  586. /* Store the result. */
  587. uint8_t * temp_ciphertext = ciphertext;
  588. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  589. *(temp_ciphertext++) = AES.STATE;
  590. }
  591. encrypt_ok = true;
  592. }else{
  593. encrypt_ok = false;
  594. }
  595. return encrypt_ok;
  596. }
  597. /*! \brief Polled function that does an AES decryption on one 128-bit data block.
  598. *
  599. * Function equal to the AES_decrypt function but the key is not loaded
  600. * into the key memory. The function require that the key already is in the
  601. * key memory. Used when encryption and decryption with the same key is
  602. * done every other time.
  603. *
  604. * \note This code is blocking and will dead lock if no interrupt flags are set.
  605. *
  606. * \param ciphertext Pointer to the ciphertext that shall be decrypted
  607. * \param plaintext Pointer to where in memory the plaintext (answer) shall be stored.
  608. *
  609. * \retval true If the AES decryption was successful.
  610. * \retval false If the AES decryption was not successful.
  611. */
  612. bool AES_decrypt_backtoback(uint8_t * ciphertext, uint8_t * plaintext)
  613. {
  614. bool decrypt_ok;
  615. /* Load data into AES state memory. */
  616. uint8_t * temp_ciphertext = ciphertext;
  617. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  618. AES.STATE = *(temp_ciphertext++);
  619. }
  620. /* Set AES in decryption mode and start the AES.*/
  621. AES.CTRL |= (AES_START_bm | AES_DECRYPT_bm);
  622. do{
  623. /* Wait until AES is finished or an error occurs. */
  624. }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0);
  625. /* If not error. */
  626. if((AES.STATUS & AES_ERROR_bm) == 0){
  627. /* Store the result. */
  628. uint8_t * temp_plaintext = plaintext;
  629. for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
  630. *(temp_plaintext++) = AES.STATE;
  631. }
  632. decrypt_ok = true;
  633. }else{
  634. decrypt_ok = false;
  635. }
  636. return decrypt_ok;
  637. }
  638. #endif