added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Fri Jan 15 07:45:16 2016 +0000
Revision:
50:a417edff4437
Parent:
0:9b334a45a8ff
Child:
144:ef7eb2e8f9f7
Synchronized with git revision 6010f32619bfcbb01cc73747d4ff9040863482d9

Full URL: https://github.com/mbedmicro/mbed/commit/6010f32619bfcbb01cc73747d4ff9040863482d9/

Remove doubling of buffer size in realiseEndpoint()

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 0:9b334a45a8ff 1 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2 * @file em_aes.c
mbed_official 50:a417edff4437 3 * @brief Advanced Encryption Standard (AES) accelerator peripheral API.
mbed_official 50:a417edff4437 4 * @version 4.2.1
bogdanm 0:9b334a45a8ff 5 *******************************************************************************
bogdanm 0:9b334a45a8ff 6 * @section License
mbed_official 50:a417edff4437 7 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
bogdanm 0:9b334a45a8ff 8 *******************************************************************************
bogdanm 0:9b334a45a8ff 9 *
bogdanm 0:9b334a45a8ff 10 * Permission is granted to anyone to use this software for any purpose,
bogdanm 0:9b334a45a8ff 11 * including commercial applications, and to alter it and redistribute it
bogdanm 0:9b334a45a8ff 12 * freely, subject to the following restrictions:
bogdanm 0:9b334a45a8ff 13 *
bogdanm 0:9b334a45a8ff 14 * 1. The origin of this software must not be misrepresented; you must not
bogdanm 0:9b334a45a8ff 15 * claim that you wrote the original software.
bogdanm 0:9b334a45a8ff 16 * 2. Altered source versions must be plainly marked as such, and must not be
bogdanm 0:9b334a45a8ff 17 * misrepresented as being the original software.
bogdanm 0:9b334a45a8ff 18 * 3. This notice may not be removed or altered from any source distribution.
bogdanm 0:9b334a45a8ff 19 *
bogdanm 0:9b334a45a8ff 20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
bogdanm 0:9b334a45a8ff 21 * obligation to support this Software. Silicon Labs is providing the
bogdanm 0:9b334a45a8ff 22 * Software "AS IS", with no express or implied warranties of any kind,
bogdanm 0:9b334a45a8ff 23 * including, but not limited to, any implied warranties of merchantability
bogdanm 0:9b334a45a8ff 24 * or fitness for any particular purpose or warranties against infringement
bogdanm 0:9b334a45a8ff 25 * of any proprietary rights of a third party.
bogdanm 0:9b334a45a8ff 26 *
bogdanm 0:9b334a45a8ff 27 * Silicon Labs will not be liable for any consequential, incidental, or
bogdanm 0:9b334a45a8ff 28 * special damages, or any other relief, or for any claim by any third party,
bogdanm 0:9b334a45a8ff 29 * arising from your use of this Software.
bogdanm 0:9b334a45a8ff 30 *
bogdanm 0:9b334a45a8ff 31 ******************************************************************************/
bogdanm 0:9b334a45a8ff 32
bogdanm 0:9b334a45a8ff 33 #include "em_aes.h"
bogdanm 0:9b334a45a8ff 34 #if defined(AES_COUNT) && (AES_COUNT > 0)
bogdanm 0:9b334a45a8ff 35
bogdanm 0:9b334a45a8ff 36 #include "em_assert.h"
bogdanm 0:9b334a45a8ff 37 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 38 * @addtogroup EM_Library
bogdanm 0:9b334a45a8ff 39 * @{
bogdanm 0:9b334a45a8ff 40 ******************************************************************************/
bogdanm 0:9b334a45a8ff 41
bogdanm 0:9b334a45a8ff 42 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 43 * @addtogroup AES
mbed_official 50:a417edff4437 44 * @brief Advanced Encryption Standard Accelerator (AES) Peripheral API.
bogdanm 0:9b334a45a8ff 45 * @details
mbed_official 50:a417edff4437 46 * This API is intended for use on Silicon Labs target devices, and the
mbed_official 50:a417edff4437 47 * following input/output notations should be noted:
bogdanm 0:9b334a45a8ff 48 *
bogdanm 0:9b334a45a8ff 49 * @li Input/output data (plaintext, ciphertext, key etc) are treated as
bogdanm 0:9b334a45a8ff 50 * byte arrays, starting with most significant byte. Ie, 32 bytes of
bogdanm 0:9b334a45a8ff 51 * plaintext (B0...B31) is located in memory in the same order, with B0 at
bogdanm 0:9b334a45a8ff 52 * the lower address and B31 at the higher address.
bogdanm 0:9b334a45a8ff 53 *
bogdanm 0:9b334a45a8ff 54 * @li Byte arrays must always be a multiple of AES block size, ie a multiple
bogdanm 0:9b334a45a8ff 55 * of 16. Padding, if required, is done at the end of the byte array.
bogdanm 0:9b334a45a8ff 56 *
bogdanm 0:9b334a45a8ff 57 * @li Byte arrays should be word (32 bit) aligned for performance
bogdanm 0:9b334a45a8ff 58 * considerations, since the array is accessed with 32 bit access type.
mbed_official 50:a417edff4437 59 * The Cortex-M supports unaligned accesses, but with a performance penalty.
bogdanm 0:9b334a45a8ff 60 *
bogdanm 0:9b334a45a8ff 61 * @li It is possible to specify the same output buffer as input buffer
bogdanm 0:9b334a45a8ff 62 * as long as they point to the same address. In that case the provided input
bogdanm 0:9b334a45a8ff 63 * buffer is replaced with the encrypted/decrypted output. Notice that the
bogdanm 0:9b334a45a8ff 64 * buffers must be exactly overlapping. If partly overlapping, the
bogdanm 0:9b334a45a8ff 65 * behaviour is undefined.
bogdanm 0:9b334a45a8ff 66 *
bogdanm 0:9b334a45a8ff 67 * It is up to the user to use a cipher mode according to its requirements
bogdanm 0:9b334a45a8ff 68 * in order to not break security. Please refer to specific cipher mode
bogdanm 0:9b334a45a8ff 69 * theory for details.
bogdanm 0:9b334a45a8ff 70 *
bogdanm 0:9b334a45a8ff 71 * References:
bogdanm 0:9b334a45a8ff 72 * @li Wikipedia - Cipher modes, http://en.wikipedia.org/wiki/Cipher_modes
bogdanm 0:9b334a45a8ff 73 *
bogdanm 0:9b334a45a8ff 74 * @li Recommendation for Block Cipher Modes of Operation,
bogdanm 0:9b334a45a8ff 75 * NIST Special Publication 800-38A, 2001 Edition,
bogdanm 0:9b334a45a8ff 76 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
bogdanm 0:9b334a45a8ff 77 * @{
bogdanm 0:9b334a45a8ff 78 ******************************************************************************/
bogdanm 0:9b334a45a8ff 79
bogdanm 0:9b334a45a8ff 80 /*******************************************************************************
bogdanm 0:9b334a45a8ff 81 ******************************* DEFINES ***********************************
bogdanm 0:9b334a45a8ff 82 ******************************************************************************/
bogdanm 0:9b334a45a8ff 83
bogdanm 0:9b334a45a8ff 84 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
bogdanm 0:9b334a45a8ff 85
bogdanm 0:9b334a45a8ff 86 #define AES_BLOCKSIZE 16
bogdanm 0:9b334a45a8ff 87
bogdanm 0:9b334a45a8ff 88 /** @endcond */
bogdanm 0:9b334a45a8ff 89
bogdanm 0:9b334a45a8ff 90 /*******************************************************************************
bogdanm 0:9b334a45a8ff 91 ************************** GLOBAL FUNCTIONS *******************************
bogdanm 0:9b334a45a8ff 92 ******************************************************************************/
bogdanm 0:9b334a45a8ff 93
bogdanm 0:9b334a45a8ff 94 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 95 * @brief
bogdanm 0:9b334a45a8ff 96 * Cipher-block chaining (CBC) cipher mode encryption/decryption, 128 bit key.
bogdanm 0:9b334a45a8ff 97 *
bogdanm 0:9b334a45a8ff 98 * @details
bogdanm 0:9b334a45a8ff 99 * Encryption:
bogdanm 0:9b334a45a8ff 100 * @verbatim
bogdanm 0:9b334a45a8ff 101 * Plaintext Plaintext
bogdanm 0:9b334a45a8ff 102 * | |
bogdanm 0:9b334a45a8ff 103 * V V
bogdanm 0:9b334a45a8ff 104 * InitVector ->XOR +-------------->XOR
bogdanm 0:9b334a45a8ff 105 * | | |
bogdanm 0:9b334a45a8ff 106 * V | V
bogdanm 0:9b334a45a8ff 107 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 108 * Key ->| Block cipher | | Key ->| Block cipher |
bogdanm 0:9b334a45a8ff 109 * | encryption | | | encryption |
bogdanm 0:9b334a45a8ff 110 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 111 * |---------+ |
bogdanm 0:9b334a45a8ff 112 * V V
bogdanm 0:9b334a45a8ff 113 * Ciphertext Ciphertext
bogdanm 0:9b334a45a8ff 114 * @endverbatim
bogdanm 0:9b334a45a8ff 115 * Decryption:
bogdanm 0:9b334a45a8ff 116 * @verbatim
bogdanm 0:9b334a45a8ff 117 * Ciphertext Ciphertext
bogdanm 0:9b334a45a8ff 118 * |----------+ |
bogdanm 0:9b334a45a8ff 119 * V | V
bogdanm 0:9b334a45a8ff 120 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 121 * Key ->| Block cipher | | Key ->| Block cipher |
bogdanm 0:9b334a45a8ff 122 * | decryption | | | decryption |
bogdanm 0:9b334a45a8ff 123 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 124 * | | |
bogdanm 0:9b334a45a8ff 125 * V | V
bogdanm 0:9b334a45a8ff 126 * InitVector ->XOR +-------------->XOR
bogdanm 0:9b334a45a8ff 127 * | |
bogdanm 0:9b334a45a8ff 128 * V V
bogdanm 0:9b334a45a8ff 129 * Plaintext Plaintext
bogdanm 0:9b334a45a8ff 130 * @endverbatim
bogdanm 0:9b334a45a8ff 131 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 132 *
bogdanm 0:9b334a45a8ff 133 * @param[out] out
bogdanm 0:9b334a45a8ff 134 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
bogdanm 0:9b334a45a8ff 135 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 136 *
bogdanm 0:9b334a45a8ff 137 * @param[in] in
bogdanm 0:9b334a45a8ff 138 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
bogdanm 0:9b334a45a8ff 139 *
bogdanm 0:9b334a45a8ff 140 * @param[in] len
bogdanm 0:9b334a45a8ff 141 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
bogdanm 0:9b334a45a8ff 142 *
bogdanm 0:9b334a45a8ff 143 * @param[in] key
bogdanm 0:9b334a45a8ff 144 * When doing encryption, this is the 128 bit encryption key. When doing
bogdanm 0:9b334a45a8ff 145 * decryption, this is the 128 bit decryption key. The decryption key may
bogdanm 0:9b334a45a8ff 146 * be generated from the encryption key with AES_DecryptKey128().
bogdanm 0:9b334a45a8ff 147 * On devices supporting key buffering this argument can be null, if so, the
bogdanm 0:9b334a45a8ff 148 * key will not be loaded, as it is assumed the key has been loaded
bogdanm 0:9b334a45a8ff 149 * into KEYHA previously.
bogdanm 0:9b334a45a8ff 150 *
bogdanm 0:9b334a45a8ff 151 * @param[in] iv
bogdanm 0:9b334a45a8ff 152 * 128 bit initalization vector to use.
bogdanm 0:9b334a45a8ff 153 *
bogdanm 0:9b334a45a8ff 154 * @param[in] encrypt
bogdanm 0:9b334a45a8ff 155 * Set to true to encrypt, false to decrypt.
bogdanm 0:9b334a45a8ff 156 ******************************************************************************/
bogdanm 0:9b334a45a8ff 157 void AES_CBC128(uint8_t *out,
bogdanm 0:9b334a45a8ff 158 const uint8_t *in,
bogdanm 0:9b334a45a8ff 159 unsigned int len,
bogdanm 0:9b334a45a8ff 160 const uint8_t *key,
bogdanm 0:9b334a45a8ff 161 const uint8_t *iv,
bogdanm 0:9b334a45a8ff 162 bool encrypt)
bogdanm 0:9b334a45a8ff 163 {
bogdanm 0:9b334a45a8ff 164 int i;
bogdanm 0:9b334a45a8ff 165 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 166 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 167 const uint32_t *_key = (const uint32_t *)key;
bogdanm 0:9b334a45a8ff 168 const uint32_t *_iv = (const uint32_t *)iv;
bogdanm 0:9b334a45a8ff 169 /* Need to buffer one block when decrypting in case 'out' replaces 'in' */
bogdanm 0:9b334a45a8ff 170 uint32_t prev[4];
bogdanm 0:9b334a45a8ff 171
bogdanm 0:9b334a45a8ff 172 EFM_ASSERT(!(len % AES_BLOCKSIZE));
bogdanm 0:9b334a45a8ff 173
bogdanm 0:9b334a45a8ff 174 /* Number of blocks to process */
bogdanm 0:9b334a45a8ff 175 len /= AES_BLOCKSIZE;
bogdanm 0:9b334a45a8ff 176
bogdanm 0:9b334a45a8ff 177 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 178 if (key)
bogdanm 0:9b334a45a8ff 179 {
bogdanm 0:9b334a45a8ff 180 /* Load key into high key for key buffer usage */
bogdanm 0:9b334a45a8ff 181 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 182 {
bogdanm 0:9b334a45a8ff 183 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 184 }
bogdanm 0:9b334a45a8ff 185 }
bogdanm 0:9b334a45a8ff 186 #endif
bogdanm 0:9b334a45a8ff 187
bogdanm 0:9b334a45a8ff 188 if (encrypt)
bogdanm 0:9b334a45a8ff 189 {
bogdanm 0:9b334a45a8ff 190 /* Enable encryption with auto start using XOR */
bogdanm 0:9b334a45a8ff 191 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 192 AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_XORSTART;
bogdanm 0:9b334a45a8ff 193 #else
bogdanm 0:9b334a45a8ff 194 AES->CTRL = AES_CTRL_XORSTART;
bogdanm 0:9b334a45a8ff 195 #endif
bogdanm 0:9b334a45a8ff 196
bogdanm 0:9b334a45a8ff 197 /* Load initialization vector, since writing to DATA, it will */
bogdanm 0:9b334a45a8ff 198 /* not trigger encryption. */
bogdanm 0:9b334a45a8ff 199 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 200 {
bogdanm 0:9b334a45a8ff 201 AES->DATA = __REV(_iv[i]);
bogdanm 0:9b334a45a8ff 202 }
bogdanm 0:9b334a45a8ff 203
bogdanm 0:9b334a45a8ff 204 /* Encrypt data */
bogdanm 0:9b334a45a8ff 205 while (len--)
bogdanm 0:9b334a45a8ff 206 {
bogdanm 0:9b334a45a8ff 207 #if !defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 208 /* Load key */
bogdanm 0:9b334a45a8ff 209 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 210 {
bogdanm 0:9b334a45a8ff 211 AES->KEYLA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 212 }
bogdanm 0:9b334a45a8ff 213 #endif
bogdanm 0:9b334a45a8ff 214
bogdanm 0:9b334a45a8ff 215 /* Load data and trigger encryption */
bogdanm 0:9b334a45a8ff 216 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 217 {
bogdanm 0:9b334a45a8ff 218 AES->XORDATA = __REV(_in[i]);
bogdanm 0:9b334a45a8ff 219 }
bogdanm 0:9b334a45a8ff 220 _in += 4;
bogdanm 0:9b334a45a8ff 221
bogdanm 0:9b334a45a8ff 222 /* Wait for completion */
bogdanm 0:9b334a45a8ff 223 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 224 ;
bogdanm 0:9b334a45a8ff 225
bogdanm 0:9b334a45a8ff 226 /* Save encrypted data */
bogdanm 0:9b334a45a8ff 227 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 228 {
bogdanm 0:9b334a45a8ff 229 _out[i] = __REV(AES->DATA);
bogdanm 0:9b334a45a8ff 230 }
bogdanm 0:9b334a45a8ff 231 _out += 4;
bogdanm 0:9b334a45a8ff 232 }
bogdanm 0:9b334a45a8ff 233 }
bogdanm 0:9b334a45a8ff 234 else
bogdanm 0:9b334a45a8ff 235 {
bogdanm 0:9b334a45a8ff 236 /* Select decryption mode */
bogdanm 0:9b334a45a8ff 237 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 238 AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 239 #else
bogdanm 0:9b334a45a8ff 240 AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 241 #endif
bogdanm 0:9b334a45a8ff 242
bogdanm 0:9b334a45a8ff 243 /* Copy init vector to previous buffer to avoid special handling */
bogdanm 0:9b334a45a8ff 244 for (i = 0; i < 4; i++)
bogdanm 0:9b334a45a8ff 245 {
bogdanm 0:9b334a45a8ff 246 prev[i] = _iv[i];
bogdanm 0:9b334a45a8ff 247 }
bogdanm 0:9b334a45a8ff 248
bogdanm 0:9b334a45a8ff 249 /* Decrypt data */
bogdanm 0:9b334a45a8ff 250 while (len--)
bogdanm 0:9b334a45a8ff 251 {
bogdanm 0:9b334a45a8ff 252 #if !defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 253 /* Load key */
bogdanm 0:9b334a45a8ff 254 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 255 {
bogdanm 0:9b334a45a8ff 256 AES->KEYLA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 257 }
bogdanm 0:9b334a45a8ff 258 #endif
bogdanm 0:9b334a45a8ff 259
bogdanm 0:9b334a45a8ff 260 /* Load data and trigger decryption */
bogdanm 0:9b334a45a8ff 261 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 262 {
bogdanm 0:9b334a45a8ff 263 AES->DATA = __REV(_in[i]);
bogdanm 0:9b334a45a8ff 264 }
bogdanm 0:9b334a45a8ff 265
bogdanm 0:9b334a45a8ff 266 /* Wait for completion */
bogdanm 0:9b334a45a8ff 267 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 268 ;
bogdanm 0:9b334a45a8ff 269
bogdanm 0:9b334a45a8ff 270 /* In order to avoid additional buffer, we use HW directly for XOR and buffer */
bogdanm 0:9b334a45a8ff 271 /* (Writing to XORDATA will not trigger encoding, triggering enabled on DATA.) */
bogdanm 0:9b334a45a8ff 272 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 273 {
bogdanm 0:9b334a45a8ff 274 AES->XORDATA = __REV(prev[i]);
bogdanm 0:9b334a45a8ff 275 prev[i] = _in[i];
bogdanm 0:9b334a45a8ff 276 }
bogdanm 0:9b334a45a8ff 277 _in += 4;
bogdanm 0:9b334a45a8ff 278
bogdanm 0:9b334a45a8ff 279 /* Then fetch decrypted data, we have to do it in a separate loop */
bogdanm 0:9b334a45a8ff 280 /* due to internal auto-shifting of words */
bogdanm 0:9b334a45a8ff 281 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 282 {
bogdanm 0:9b334a45a8ff 283 _out[i] = __REV(AES->DATA);
bogdanm 0:9b334a45a8ff 284 }
bogdanm 0:9b334a45a8ff 285 _out += 4;
bogdanm 0:9b334a45a8ff 286 }
bogdanm 0:9b334a45a8ff 287 }
bogdanm 0:9b334a45a8ff 288 }
bogdanm 0:9b334a45a8ff 289
bogdanm 0:9b334a45a8ff 290
bogdanm 0:9b334a45a8ff 291 #if defined( AES_CTRL_AES256 )
bogdanm 0:9b334a45a8ff 292 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 293 * @brief
bogdanm 0:9b334a45a8ff 294 * Cipher-block chaining (CBC) cipher mode encryption/decryption, 256 bit key.
bogdanm 0:9b334a45a8ff 295 *
bogdanm 0:9b334a45a8ff 296 * @details
bogdanm 0:9b334a45a8ff 297 * Please see AES_CBC128() for CBC figure.
bogdanm 0:9b334a45a8ff 298 *
bogdanm 0:9b334a45a8ff 299 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 300 *
bogdanm 0:9b334a45a8ff 301 * @param[out] out
bogdanm 0:9b334a45a8ff 302 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
bogdanm 0:9b334a45a8ff 303 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 304 *
bogdanm 0:9b334a45a8ff 305 * @param[in] in
bogdanm 0:9b334a45a8ff 306 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
bogdanm 0:9b334a45a8ff 307 *
bogdanm 0:9b334a45a8ff 308 * @param[in] len
bogdanm 0:9b334a45a8ff 309 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
bogdanm 0:9b334a45a8ff 310 *
bogdanm 0:9b334a45a8ff 311 * @param[in] key
bogdanm 0:9b334a45a8ff 312 * When doing encryption, this is the 256 bit encryption key. When doing
bogdanm 0:9b334a45a8ff 313 * decryption, this is the 256 bit decryption key. The decryption key may
bogdanm 0:9b334a45a8ff 314 * be generated from the encryption key with AES_DecryptKey256().
bogdanm 0:9b334a45a8ff 315 *
bogdanm 0:9b334a45a8ff 316 * @param[in] iv
bogdanm 0:9b334a45a8ff 317 * 128 bit initalization vector to use.
bogdanm 0:9b334a45a8ff 318 *
bogdanm 0:9b334a45a8ff 319 * @param[in] encrypt
bogdanm 0:9b334a45a8ff 320 * Set to true to encrypt, false to decrypt.
bogdanm 0:9b334a45a8ff 321 ******************************************************************************/
bogdanm 0:9b334a45a8ff 322 void AES_CBC256(uint8_t *out,
bogdanm 0:9b334a45a8ff 323 const uint8_t *in,
bogdanm 0:9b334a45a8ff 324 unsigned int len,
bogdanm 0:9b334a45a8ff 325 const uint8_t *key,
bogdanm 0:9b334a45a8ff 326 const uint8_t *iv,
bogdanm 0:9b334a45a8ff 327 bool encrypt)
bogdanm 0:9b334a45a8ff 328 {
bogdanm 0:9b334a45a8ff 329 int i;
bogdanm 0:9b334a45a8ff 330 int j;
bogdanm 0:9b334a45a8ff 331 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 332 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 333 const uint32_t *_key = (const uint32_t *)key;
bogdanm 0:9b334a45a8ff 334 const uint32_t *_iv = (const uint32_t *)iv;
bogdanm 0:9b334a45a8ff 335 /* Need to buffer one block when decrypting in case output replaces input */
bogdanm 0:9b334a45a8ff 336 uint32_t prev[4];
bogdanm 0:9b334a45a8ff 337
bogdanm 0:9b334a45a8ff 338 EFM_ASSERT(!(len % AES_BLOCKSIZE));
bogdanm 0:9b334a45a8ff 339
bogdanm 0:9b334a45a8ff 340 /* Number of blocks to process */
bogdanm 0:9b334a45a8ff 341 len /= AES_BLOCKSIZE;
bogdanm 0:9b334a45a8ff 342
bogdanm 0:9b334a45a8ff 343 if (encrypt)
bogdanm 0:9b334a45a8ff 344 {
bogdanm 0:9b334a45a8ff 345 /* Enable encryption with auto start using XOR */
bogdanm 0:9b334a45a8ff 346 AES->CTRL = AES_CTRL_AES256 | AES_CTRL_XORSTART;
bogdanm 0:9b334a45a8ff 347
bogdanm 0:9b334a45a8ff 348 /* Load initialization vector, since writing to DATA, it will */
bogdanm 0:9b334a45a8ff 349 /* not trigger encryption. */
bogdanm 0:9b334a45a8ff 350 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 351 {
bogdanm 0:9b334a45a8ff 352 AES->DATA = __REV(_iv[i]);
bogdanm 0:9b334a45a8ff 353 }
bogdanm 0:9b334a45a8ff 354
bogdanm 0:9b334a45a8ff 355 /* Encrypt data */
bogdanm 0:9b334a45a8ff 356 while (len--)
bogdanm 0:9b334a45a8ff 357 {
bogdanm 0:9b334a45a8ff 358 /* Load key and data and trigger encryption */
bogdanm 0:9b334a45a8ff 359 for (i = 3, j = 7; i >= 0; i--, j--)
bogdanm 0:9b334a45a8ff 360 {
bogdanm 0:9b334a45a8ff 361 AES->KEYLA = __REV(_key[j]);
bogdanm 0:9b334a45a8ff 362 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 363 /* Write data last, since will trigger encryption on last iteration */
bogdanm 0:9b334a45a8ff 364 AES->XORDATA = __REV(_in[i]);
bogdanm 0:9b334a45a8ff 365 }
bogdanm 0:9b334a45a8ff 366 _in += 4;
bogdanm 0:9b334a45a8ff 367
bogdanm 0:9b334a45a8ff 368 /* Wait for completion */
bogdanm 0:9b334a45a8ff 369 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 370 ;
bogdanm 0:9b334a45a8ff 371
bogdanm 0:9b334a45a8ff 372 /* Save encrypted data */
bogdanm 0:9b334a45a8ff 373 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 374 {
bogdanm 0:9b334a45a8ff 375 _out[i] = __REV(AES->DATA);
bogdanm 0:9b334a45a8ff 376 }
bogdanm 0:9b334a45a8ff 377 _out += 4;
bogdanm 0:9b334a45a8ff 378 }
bogdanm 0:9b334a45a8ff 379 }
bogdanm 0:9b334a45a8ff 380 else
bogdanm 0:9b334a45a8ff 381 {
bogdanm 0:9b334a45a8ff 382 /* Select decryption mode */
bogdanm 0:9b334a45a8ff 383 AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DECRYPT | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 384
bogdanm 0:9b334a45a8ff 385 /* Copy init vector to previous buffer to avoid special handling */
bogdanm 0:9b334a45a8ff 386 for (i = 0; i < 4; i++)
bogdanm 0:9b334a45a8ff 387 {
bogdanm 0:9b334a45a8ff 388 prev[i] = _iv[i];
bogdanm 0:9b334a45a8ff 389 }
bogdanm 0:9b334a45a8ff 390
bogdanm 0:9b334a45a8ff 391 /* Decrypt data */
bogdanm 0:9b334a45a8ff 392 while (len--)
bogdanm 0:9b334a45a8ff 393 {
bogdanm 0:9b334a45a8ff 394 /* Load key and data and trigger decryption */
bogdanm 0:9b334a45a8ff 395 for (i = 3, j = 7; i >= 0; i--, j--)
bogdanm 0:9b334a45a8ff 396 {
bogdanm 0:9b334a45a8ff 397 AES->KEYLA = __REV(_key[j]);
bogdanm 0:9b334a45a8ff 398 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 399 /* Write data last, since will trigger encryption on last iteration */
bogdanm 0:9b334a45a8ff 400 AES->DATA = __REV(_in[i]);
bogdanm 0:9b334a45a8ff 401 }
bogdanm 0:9b334a45a8ff 402
bogdanm 0:9b334a45a8ff 403 /* Wait for completion */
bogdanm 0:9b334a45a8ff 404 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 405 ;
bogdanm 0:9b334a45a8ff 406
bogdanm 0:9b334a45a8ff 407 /* In order to avoid additional buffer, we use HW directly for XOR and buffer */
bogdanm 0:9b334a45a8ff 408 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 409 {
bogdanm 0:9b334a45a8ff 410 AES->XORDATA = __REV(prev[i]);
bogdanm 0:9b334a45a8ff 411 prev[i] = _in[i];
bogdanm 0:9b334a45a8ff 412 }
bogdanm 0:9b334a45a8ff 413 _in += 4;
bogdanm 0:9b334a45a8ff 414
bogdanm 0:9b334a45a8ff 415 /* Then fetch decrypted data, we have to do it in a separate loop */
bogdanm 0:9b334a45a8ff 416 /* due to internal auto-shifting of words */
bogdanm 0:9b334a45a8ff 417 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 418 {
bogdanm 0:9b334a45a8ff 419 _out[i] = __REV(AES->DATA);
bogdanm 0:9b334a45a8ff 420 }
bogdanm 0:9b334a45a8ff 421 _out += 4;
bogdanm 0:9b334a45a8ff 422 }
bogdanm 0:9b334a45a8ff 423 }
bogdanm 0:9b334a45a8ff 424 }
bogdanm 0:9b334a45a8ff 425 #endif
bogdanm 0:9b334a45a8ff 426
bogdanm 0:9b334a45a8ff 427
bogdanm 0:9b334a45a8ff 428 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 429 * @brief
bogdanm 0:9b334a45a8ff 430 * Cipher feedback (CFB) cipher mode encryption/decryption, 128 bit key.
bogdanm 0:9b334a45a8ff 431 *
bogdanm 0:9b334a45a8ff 432 * @details
bogdanm 0:9b334a45a8ff 433 * Encryption:
bogdanm 0:9b334a45a8ff 434 * @verbatim
bogdanm 0:9b334a45a8ff 435 * InitVector +----------------+
bogdanm 0:9b334a45a8ff 436 * | | |
bogdanm 0:9b334a45a8ff 437 * V | V
bogdanm 0:9b334a45a8ff 438 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 439 * Key ->| Block cipher | | Key ->| Block cipher |
bogdanm 0:9b334a45a8ff 440 * | encryption | | | encryption |
bogdanm 0:9b334a45a8ff 441 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 442 * | | |
bogdanm 0:9b334a45a8ff 443 * V | V
bogdanm 0:9b334a45a8ff 444 * Plaintext ->XOR | Plaintext ->XOR
bogdanm 0:9b334a45a8ff 445 * |---------+ |
bogdanm 0:9b334a45a8ff 446 * V V
bogdanm 0:9b334a45a8ff 447 * Ciphertext Ciphertext
bogdanm 0:9b334a45a8ff 448 * @endverbatim
bogdanm 0:9b334a45a8ff 449 * Decryption:
bogdanm 0:9b334a45a8ff 450 * @verbatim
bogdanm 0:9b334a45a8ff 451 * InitVector +----------------+
bogdanm 0:9b334a45a8ff 452 * | | |
bogdanm 0:9b334a45a8ff 453 * V | V
bogdanm 0:9b334a45a8ff 454 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 455 * Key ->| Block cipher | | Key ->| Block cipher |
bogdanm 0:9b334a45a8ff 456 * | encryption | | | encryption |
bogdanm 0:9b334a45a8ff 457 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 458 * | | |
bogdanm 0:9b334a45a8ff 459 * V | V
bogdanm 0:9b334a45a8ff 460 * XOR<- Ciphertext XOR<- Ciphertext
bogdanm 0:9b334a45a8ff 461 * | |
bogdanm 0:9b334a45a8ff 462 * V V
bogdanm 0:9b334a45a8ff 463 * Plaintext Plaintext
bogdanm 0:9b334a45a8ff 464 * @endverbatim
bogdanm 0:9b334a45a8ff 465 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 466 *
bogdanm 0:9b334a45a8ff 467 * @param[out] out
bogdanm 0:9b334a45a8ff 468 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
bogdanm 0:9b334a45a8ff 469 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 470 *
bogdanm 0:9b334a45a8ff 471 * @param[in] in
bogdanm 0:9b334a45a8ff 472 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
bogdanm 0:9b334a45a8ff 473 *
bogdanm 0:9b334a45a8ff 474 * @param[in] len
bogdanm 0:9b334a45a8ff 475 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
bogdanm 0:9b334a45a8ff 476 *
bogdanm 0:9b334a45a8ff 477 * @param[in] key
bogdanm 0:9b334a45a8ff 478 * 128 bit encryption key is used for both encryption and decryption modes.
bogdanm 0:9b334a45a8ff 479 *
bogdanm 0:9b334a45a8ff 480 * @param[in] iv
bogdanm 0:9b334a45a8ff 481 * 128 bit initalization vector to use.
bogdanm 0:9b334a45a8ff 482 *
bogdanm 0:9b334a45a8ff 483 * @param[in] encrypt
bogdanm 0:9b334a45a8ff 484 * Set to true to encrypt, false to decrypt.
bogdanm 0:9b334a45a8ff 485 ******************************************************************************/
bogdanm 0:9b334a45a8ff 486 void AES_CFB128(uint8_t *out,
bogdanm 0:9b334a45a8ff 487 const uint8_t *in,
bogdanm 0:9b334a45a8ff 488 unsigned int len,
bogdanm 0:9b334a45a8ff 489 const uint8_t *key,
bogdanm 0:9b334a45a8ff 490 const uint8_t *iv,
bogdanm 0:9b334a45a8ff 491 bool encrypt)
bogdanm 0:9b334a45a8ff 492 {
bogdanm 0:9b334a45a8ff 493 int i;
bogdanm 0:9b334a45a8ff 494 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 495 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 496 const uint32_t *_key = (const uint32_t *)key;
bogdanm 0:9b334a45a8ff 497 const uint32_t *_iv = (const uint32_t *)iv;
bogdanm 0:9b334a45a8ff 498 const uint32_t *data;
bogdanm 0:9b334a45a8ff 499 uint32_t tmp[4];
bogdanm 0:9b334a45a8ff 500
bogdanm 0:9b334a45a8ff 501 EFM_ASSERT(!(len % AES_BLOCKSIZE));
bogdanm 0:9b334a45a8ff 502
bogdanm 0:9b334a45a8ff 503 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 504 AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 505 #else
bogdanm 0:9b334a45a8ff 506 AES->CTRL = AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 507 #endif
bogdanm 0:9b334a45a8ff 508
bogdanm 0:9b334a45a8ff 509 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 510 /* Load key into high key for key buffer usage */
bogdanm 0:9b334a45a8ff 511 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 512 {
bogdanm 0:9b334a45a8ff 513 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 514 }
bogdanm 0:9b334a45a8ff 515 #endif
bogdanm 0:9b334a45a8ff 516
bogdanm 0:9b334a45a8ff 517 /* Encrypt/decrypt data */
bogdanm 0:9b334a45a8ff 518 data = _iv;
bogdanm 0:9b334a45a8ff 519 len /= AES_BLOCKSIZE;
bogdanm 0:9b334a45a8ff 520 while (len--)
bogdanm 0:9b334a45a8ff 521 {
bogdanm 0:9b334a45a8ff 522 #if !defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 523 /* Load key */
bogdanm 0:9b334a45a8ff 524 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 525 {
bogdanm 0:9b334a45a8ff 526 AES->KEYLA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 527 }
bogdanm 0:9b334a45a8ff 528 #endif
bogdanm 0:9b334a45a8ff 529
bogdanm 0:9b334a45a8ff 530 /* Load data and trigger encryption */
bogdanm 0:9b334a45a8ff 531 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 532 {
bogdanm 0:9b334a45a8ff 533 AES->DATA = __REV(data[i]);
bogdanm 0:9b334a45a8ff 534 }
bogdanm 0:9b334a45a8ff 535
bogdanm 0:9b334a45a8ff 536 /* Do some required processing before waiting for completion */
bogdanm 0:9b334a45a8ff 537 if (encrypt)
bogdanm 0:9b334a45a8ff 538 {
bogdanm 0:9b334a45a8ff 539 data = _out;
bogdanm 0:9b334a45a8ff 540 }
bogdanm 0:9b334a45a8ff 541 else
bogdanm 0:9b334a45a8ff 542 {
bogdanm 0:9b334a45a8ff 543 /* Must copy current ciphertext block since it may be overwritten */
bogdanm 0:9b334a45a8ff 544 for (i = 0; i < 4; i++)
bogdanm 0:9b334a45a8ff 545 {
bogdanm 0:9b334a45a8ff 546 tmp[i] = _in[i];
bogdanm 0:9b334a45a8ff 547 }
bogdanm 0:9b334a45a8ff 548 data = tmp;
bogdanm 0:9b334a45a8ff 549 }
bogdanm 0:9b334a45a8ff 550
bogdanm 0:9b334a45a8ff 551 /* Wait for completion */
bogdanm 0:9b334a45a8ff 552 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 553 ;
bogdanm 0:9b334a45a8ff 554
bogdanm 0:9b334a45a8ff 555 /* Save encrypted/decrypted data */
bogdanm 0:9b334a45a8ff 556 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 557 {
bogdanm 0:9b334a45a8ff 558 _out[i] = __REV(AES->DATA) ^ _in[i];
bogdanm 0:9b334a45a8ff 559 }
bogdanm 0:9b334a45a8ff 560 _out += 4;
bogdanm 0:9b334a45a8ff 561 _in += 4;
bogdanm 0:9b334a45a8ff 562 }
bogdanm 0:9b334a45a8ff 563 }
bogdanm 0:9b334a45a8ff 564
bogdanm 0:9b334a45a8ff 565
bogdanm 0:9b334a45a8ff 566 #if defined( AES_CTRL_AES256 )
bogdanm 0:9b334a45a8ff 567 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 568 * @brief
bogdanm 0:9b334a45a8ff 569 * Cipher feedback (CFB) cipher mode encryption/decryption, 256 bit key.
bogdanm 0:9b334a45a8ff 570 *
bogdanm 0:9b334a45a8ff 571 * @details
bogdanm 0:9b334a45a8ff 572 * Please see AES_CFB128() for CFB figure.
bogdanm 0:9b334a45a8ff 573 *
bogdanm 0:9b334a45a8ff 574 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 575 *
bogdanm 0:9b334a45a8ff 576 * @param[out] out
bogdanm 0:9b334a45a8ff 577 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
bogdanm 0:9b334a45a8ff 578 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 579 *
bogdanm 0:9b334a45a8ff 580 * @param[in] in
bogdanm 0:9b334a45a8ff 581 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
bogdanm 0:9b334a45a8ff 582 *
bogdanm 0:9b334a45a8ff 583 * @param[in] len
bogdanm 0:9b334a45a8ff 584 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
bogdanm 0:9b334a45a8ff 585 *
bogdanm 0:9b334a45a8ff 586 * @param[in] key
bogdanm 0:9b334a45a8ff 587 * 256 bit encryption key is used for both encryption and decryption modes.
bogdanm 0:9b334a45a8ff 588 *
bogdanm 0:9b334a45a8ff 589 * @param[in] iv
bogdanm 0:9b334a45a8ff 590 * 128 bit initalization vector to use.
bogdanm 0:9b334a45a8ff 591 *
bogdanm 0:9b334a45a8ff 592 * @param[in] encrypt
bogdanm 0:9b334a45a8ff 593 * Set to true to encrypt, false to decrypt.
bogdanm 0:9b334a45a8ff 594 ******************************************************************************/
bogdanm 0:9b334a45a8ff 595 void AES_CFB256(uint8_t *out,
bogdanm 0:9b334a45a8ff 596 const uint8_t *in,
bogdanm 0:9b334a45a8ff 597 unsigned int len,
bogdanm 0:9b334a45a8ff 598 const uint8_t *key,
bogdanm 0:9b334a45a8ff 599 const uint8_t *iv,
bogdanm 0:9b334a45a8ff 600 bool encrypt)
bogdanm 0:9b334a45a8ff 601 {
bogdanm 0:9b334a45a8ff 602 int i;
bogdanm 0:9b334a45a8ff 603 int j;
bogdanm 0:9b334a45a8ff 604 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 605 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 606 const uint32_t *_key = (const uint32_t *)key;
bogdanm 0:9b334a45a8ff 607 const uint32_t *_iv = (const uint32_t *)iv;
bogdanm 0:9b334a45a8ff 608 const uint32_t *data;
bogdanm 0:9b334a45a8ff 609 uint32_t tmp[4];
bogdanm 0:9b334a45a8ff 610
bogdanm 0:9b334a45a8ff 611 EFM_ASSERT(!(len % AES_BLOCKSIZE));
bogdanm 0:9b334a45a8ff 612
bogdanm 0:9b334a45a8ff 613 /* Select encryption mode */
bogdanm 0:9b334a45a8ff 614 AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 615
bogdanm 0:9b334a45a8ff 616 /* Encrypt/decrypt data */
bogdanm 0:9b334a45a8ff 617 data = _iv;
bogdanm 0:9b334a45a8ff 618 len /= AES_BLOCKSIZE;
bogdanm 0:9b334a45a8ff 619 while (len--)
bogdanm 0:9b334a45a8ff 620 {
bogdanm 0:9b334a45a8ff 621 /* Load key and block to be encrypted/decrypted */
bogdanm 0:9b334a45a8ff 622 for (i = 3, j = 7; i >= 0; i--, j--)
bogdanm 0:9b334a45a8ff 623 {
bogdanm 0:9b334a45a8ff 624 AES->KEYLA = __REV(_key[j]);
bogdanm 0:9b334a45a8ff 625 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 626 /* Write data last, since will trigger encryption on last iteration */
bogdanm 0:9b334a45a8ff 627 AES->DATA = __REV(data[i]);
bogdanm 0:9b334a45a8ff 628 }
bogdanm 0:9b334a45a8ff 629
bogdanm 0:9b334a45a8ff 630 /* Do some required processing before waiting for completion */
bogdanm 0:9b334a45a8ff 631 if (encrypt)
bogdanm 0:9b334a45a8ff 632 {
bogdanm 0:9b334a45a8ff 633 data = _out;
bogdanm 0:9b334a45a8ff 634 }
bogdanm 0:9b334a45a8ff 635 else
bogdanm 0:9b334a45a8ff 636 {
bogdanm 0:9b334a45a8ff 637 /* Must copy current ciphertext block since it may be overwritten */
bogdanm 0:9b334a45a8ff 638 for (i = 0; i < 4; i++)
bogdanm 0:9b334a45a8ff 639 {
bogdanm 0:9b334a45a8ff 640 tmp[i] = _in[i];
bogdanm 0:9b334a45a8ff 641 }
bogdanm 0:9b334a45a8ff 642 data = tmp;
bogdanm 0:9b334a45a8ff 643 }
bogdanm 0:9b334a45a8ff 644
bogdanm 0:9b334a45a8ff 645 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 646 ;
bogdanm 0:9b334a45a8ff 647
bogdanm 0:9b334a45a8ff 648 /* Save encrypted/decrypted data */
bogdanm 0:9b334a45a8ff 649 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 650 {
bogdanm 0:9b334a45a8ff 651 _out[i] = __REV(AES->DATA) ^ _in[i];
bogdanm 0:9b334a45a8ff 652 }
bogdanm 0:9b334a45a8ff 653 _out += 4;
bogdanm 0:9b334a45a8ff 654 _in += 4;
bogdanm 0:9b334a45a8ff 655 }
bogdanm 0:9b334a45a8ff 656 }
bogdanm 0:9b334a45a8ff 657 #endif
bogdanm 0:9b334a45a8ff 658
bogdanm 0:9b334a45a8ff 659
bogdanm 0:9b334a45a8ff 660 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 661 * @brief
bogdanm 0:9b334a45a8ff 662 * Counter (CTR) cipher mode encryption/decryption, 128 bit key.
bogdanm 0:9b334a45a8ff 663 *
bogdanm 0:9b334a45a8ff 664 * @details
bogdanm 0:9b334a45a8ff 665 * Encryption:
bogdanm 0:9b334a45a8ff 666 * @verbatim
bogdanm 0:9b334a45a8ff 667 * Counter Counter
bogdanm 0:9b334a45a8ff 668 * | |
bogdanm 0:9b334a45a8ff 669 * V V
bogdanm 0:9b334a45a8ff 670 * +--------------+ +--------------+
bogdanm 0:9b334a45a8ff 671 * Key ->| Block cipher | Key ->| Block cipher |
bogdanm 0:9b334a45a8ff 672 * | encryption | | encryption |
bogdanm 0:9b334a45a8ff 673 * +--------------+ +--------------+
bogdanm 0:9b334a45a8ff 674 * | |
bogdanm 0:9b334a45a8ff 675 * Plaintext ->XOR Plaintext ->XOR
bogdanm 0:9b334a45a8ff 676 * | |
bogdanm 0:9b334a45a8ff 677 * V V
bogdanm 0:9b334a45a8ff 678 * Ciphertext Ciphertext
bogdanm 0:9b334a45a8ff 679 * @endverbatim
bogdanm 0:9b334a45a8ff 680 * Decryption:
bogdanm 0:9b334a45a8ff 681 * @verbatim
bogdanm 0:9b334a45a8ff 682 * Counter Counter
bogdanm 0:9b334a45a8ff 683 * | |
bogdanm 0:9b334a45a8ff 684 * V V
bogdanm 0:9b334a45a8ff 685 * +--------------+ +--------------+
bogdanm 0:9b334a45a8ff 686 * Key ->| Block cipher | Key ->| Block cipher |
bogdanm 0:9b334a45a8ff 687 * | encryption | | encryption |
bogdanm 0:9b334a45a8ff 688 * +--------------+ +--------------+
bogdanm 0:9b334a45a8ff 689 * | |
bogdanm 0:9b334a45a8ff 690 * Ciphertext ->XOR Ciphertext ->XOR
bogdanm 0:9b334a45a8ff 691 * | |
bogdanm 0:9b334a45a8ff 692 * V V
bogdanm 0:9b334a45a8ff 693 * Plaintext Plaintext
bogdanm 0:9b334a45a8ff 694 * @endverbatim
bogdanm 0:9b334a45a8ff 695 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 696 *
bogdanm 0:9b334a45a8ff 697 * @param[out] out
bogdanm 0:9b334a45a8ff 698 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
bogdanm 0:9b334a45a8ff 699 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 700 *
bogdanm 0:9b334a45a8ff 701 * @param[in] in
bogdanm 0:9b334a45a8ff 702 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
bogdanm 0:9b334a45a8ff 703 *
bogdanm 0:9b334a45a8ff 704 * @param[in] len
bogdanm 0:9b334a45a8ff 705 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
bogdanm 0:9b334a45a8ff 706 *
bogdanm 0:9b334a45a8ff 707 * @param[in] key
bogdanm 0:9b334a45a8ff 708 * 128 bit encryption key.
bogdanm 0:9b334a45a8ff 709 * On devices supporting key buffering this argument can be null, if so, the
bogdanm 0:9b334a45a8ff 710 * key will not be loaded, as it is assumed the key has been loaded
bogdanm 0:9b334a45a8ff 711 * into KEYHA previously.
bogdanm 0:9b334a45a8ff 712 *
bogdanm 0:9b334a45a8ff 713 * @param[in,out] ctr
bogdanm 0:9b334a45a8ff 714 * 128 bit initial counter value. The counter is updated after each AES
bogdanm 0:9b334a45a8ff 715 * block encoding through use of @p ctrFunc.
bogdanm 0:9b334a45a8ff 716 *
bogdanm 0:9b334a45a8ff 717 * @param[in] ctrFunc
bogdanm 0:9b334a45a8ff 718 * Function used to update counter value.
bogdanm 0:9b334a45a8ff 719 ******************************************************************************/
bogdanm 0:9b334a45a8ff 720 void AES_CTR128(uint8_t *out,
bogdanm 0:9b334a45a8ff 721 const uint8_t *in,
bogdanm 0:9b334a45a8ff 722 unsigned int len,
bogdanm 0:9b334a45a8ff 723 const uint8_t *key,
bogdanm 0:9b334a45a8ff 724 uint8_t *ctr,
bogdanm 0:9b334a45a8ff 725 AES_CtrFuncPtr_TypeDef ctrFunc)
bogdanm 0:9b334a45a8ff 726 {
bogdanm 0:9b334a45a8ff 727 int i;
bogdanm 0:9b334a45a8ff 728 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 729 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 730 const uint32_t *_key = (const uint32_t *)key;
bogdanm 0:9b334a45a8ff 731 uint32_t *_ctr = (uint32_t *)ctr;
bogdanm 0:9b334a45a8ff 732
bogdanm 0:9b334a45a8ff 733 EFM_ASSERT(!(len % AES_BLOCKSIZE));
bogdanm 0:9b334a45a8ff 734 EFM_ASSERT(ctrFunc);
bogdanm 0:9b334a45a8ff 735
bogdanm 0:9b334a45a8ff 736 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 737 AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 738 #else
bogdanm 0:9b334a45a8ff 739 AES->CTRL = AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 740 #endif
bogdanm 0:9b334a45a8ff 741
bogdanm 0:9b334a45a8ff 742 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 743 if (key)
bogdanm 0:9b334a45a8ff 744 {
bogdanm 0:9b334a45a8ff 745 /* Load key into high key for key buffer usage */
bogdanm 0:9b334a45a8ff 746 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 747 {
bogdanm 0:9b334a45a8ff 748 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 749 }
bogdanm 0:9b334a45a8ff 750 }
bogdanm 0:9b334a45a8ff 751 #endif
bogdanm 0:9b334a45a8ff 752
bogdanm 0:9b334a45a8ff 753 /* Encrypt/decrypt data */
bogdanm 0:9b334a45a8ff 754 len /= AES_BLOCKSIZE;
bogdanm 0:9b334a45a8ff 755 while (len--)
bogdanm 0:9b334a45a8ff 756 {
bogdanm 0:9b334a45a8ff 757 #if !defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 758 /* Load key */
bogdanm 0:9b334a45a8ff 759 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 760 {
bogdanm 0:9b334a45a8ff 761 AES->KEYLA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 762 }
bogdanm 0:9b334a45a8ff 763 #endif
bogdanm 0:9b334a45a8ff 764
bogdanm 0:9b334a45a8ff 765 /* Load ctr to be encrypted/decrypted */
bogdanm 0:9b334a45a8ff 766 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 767 {
bogdanm 0:9b334a45a8ff 768 AES->DATA = __REV(_ctr[i]);
bogdanm 0:9b334a45a8ff 769 }
bogdanm 0:9b334a45a8ff 770 /* Increment ctr for next use */
bogdanm 0:9b334a45a8ff 771 ctrFunc(ctr);
bogdanm 0:9b334a45a8ff 772
bogdanm 0:9b334a45a8ff 773 /* Wait for completion */
bogdanm 0:9b334a45a8ff 774 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 775 ;
bogdanm 0:9b334a45a8ff 776
bogdanm 0:9b334a45a8ff 777 /* Save encrypted/decrypted data */
bogdanm 0:9b334a45a8ff 778 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 779 {
bogdanm 0:9b334a45a8ff 780 _out[i] = __REV(AES->DATA) ^ _in[i];
bogdanm 0:9b334a45a8ff 781 }
bogdanm 0:9b334a45a8ff 782 _out += 4;
bogdanm 0:9b334a45a8ff 783 _in += 4;
bogdanm 0:9b334a45a8ff 784 }
bogdanm 0:9b334a45a8ff 785 }
bogdanm 0:9b334a45a8ff 786
bogdanm 0:9b334a45a8ff 787
bogdanm 0:9b334a45a8ff 788 #if defined( AES_CTRL_AES256 )
bogdanm 0:9b334a45a8ff 789 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 790 * @brief
bogdanm 0:9b334a45a8ff 791 * Counter (CTR) cipher mode encryption/decryption, 256 bit key.
bogdanm 0:9b334a45a8ff 792 *
bogdanm 0:9b334a45a8ff 793 * @details
bogdanm 0:9b334a45a8ff 794 * Please see AES_CTR128() for CTR figure.
bogdanm 0:9b334a45a8ff 795 *
bogdanm 0:9b334a45a8ff 796 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 797 *
bogdanm 0:9b334a45a8ff 798 * @param[out] out
bogdanm 0:9b334a45a8ff 799 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
bogdanm 0:9b334a45a8ff 800 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 801 *
bogdanm 0:9b334a45a8ff 802 * @param[in] in
bogdanm 0:9b334a45a8ff 803 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
bogdanm 0:9b334a45a8ff 804 *
bogdanm 0:9b334a45a8ff 805 * @param[in] len
bogdanm 0:9b334a45a8ff 806 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
bogdanm 0:9b334a45a8ff 807 *
bogdanm 0:9b334a45a8ff 808 * @param[in] key
bogdanm 0:9b334a45a8ff 809 * 256 bit encryption key.
bogdanm 0:9b334a45a8ff 810 *
bogdanm 0:9b334a45a8ff 811 * @param[in,out] ctr
bogdanm 0:9b334a45a8ff 812 * 128 bit initial counter value. The counter is updated after each AES
bogdanm 0:9b334a45a8ff 813 * block encoding through use of @p ctrFunc.
bogdanm 0:9b334a45a8ff 814 *
bogdanm 0:9b334a45a8ff 815 * @param[in] ctrFunc
bogdanm 0:9b334a45a8ff 816 * Function used to update counter value.
bogdanm 0:9b334a45a8ff 817 ******************************************************************************/
bogdanm 0:9b334a45a8ff 818 void AES_CTR256(uint8_t *out,
bogdanm 0:9b334a45a8ff 819 const uint8_t *in,
bogdanm 0:9b334a45a8ff 820 unsigned int len,
bogdanm 0:9b334a45a8ff 821 const uint8_t *key,
bogdanm 0:9b334a45a8ff 822 uint8_t *ctr,
bogdanm 0:9b334a45a8ff 823 AES_CtrFuncPtr_TypeDef ctrFunc)
bogdanm 0:9b334a45a8ff 824 {
bogdanm 0:9b334a45a8ff 825 int i;
bogdanm 0:9b334a45a8ff 826 int j;
bogdanm 0:9b334a45a8ff 827 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 828 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 829 const uint32_t *_key = (const uint32_t *)key;
bogdanm 0:9b334a45a8ff 830 uint32_t *_ctr = (uint32_t *)ctr;
bogdanm 0:9b334a45a8ff 831
bogdanm 0:9b334a45a8ff 832 EFM_ASSERT(!(len % AES_BLOCKSIZE));
bogdanm 0:9b334a45a8ff 833 EFM_ASSERT(ctrFunc);
bogdanm 0:9b334a45a8ff 834
bogdanm 0:9b334a45a8ff 835 /* Select encryption mode, with auto trigger */
bogdanm 0:9b334a45a8ff 836 AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 837
bogdanm 0:9b334a45a8ff 838 /* Encrypt/decrypt data */
bogdanm 0:9b334a45a8ff 839 len /= AES_BLOCKSIZE;
bogdanm 0:9b334a45a8ff 840 while (len--)
bogdanm 0:9b334a45a8ff 841 {
bogdanm 0:9b334a45a8ff 842 /* Load key and block to be encrypted/decrypted */
bogdanm 0:9b334a45a8ff 843 for (i = 3, j = 7; i >= 0; i--, j--)
bogdanm 0:9b334a45a8ff 844 {
bogdanm 0:9b334a45a8ff 845 AES->KEYLA = __REV(_key[j]);
bogdanm 0:9b334a45a8ff 846 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 847 /* Write data last, since will trigger encryption on last iteration */
bogdanm 0:9b334a45a8ff 848 AES->DATA = __REV(_ctr[i]);
bogdanm 0:9b334a45a8ff 849 }
bogdanm 0:9b334a45a8ff 850 /* Increment ctr for next use */
bogdanm 0:9b334a45a8ff 851 ctrFunc(ctr);
bogdanm 0:9b334a45a8ff 852
bogdanm 0:9b334a45a8ff 853 /* Wait for completion */
bogdanm 0:9b334a45a8ff 854 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 855 ;
bogdanm 0:9b334a45a8ff 856
bogdanm 0:9b334a45a8ff 857 /* Save encrypted/decrypted data */
bogdanm 0:9b334a45a8ff 858 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 859 {
bogdanm 0:9b334a45a8ff 860 _out[i] = __REV(AES->DATA) ^ _in[i];
bogdanm 0:9b334a45a8ff 861 }
bogdanm 0:9b334a45a8ff 862 _out += 4;
bogdanm 0:9b334a45a8ff 863 _in += 4;
bogdanm 0:9b334a45a8ff 864 }
bogdanm 0:9b334a45a8ff 865 }
bogdanm 0:9b334a45a8ff 866 #endif
bogdanm 0:9b334a45a8ff 867
bogdanm 0:9b334a45a8ff 868
bogdanm 0:9b334a45a8ff 869 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 870 * @brief
bogdanm 0:9b334a45a8ff 871 * Update last 32 bits of 128 bit counter, by incrementing with 1.
bogdanm 0:9b334a45a8ff 872 *
bogdanm 0:9b334a45a8ff 873 * @details
bogdanm 0:9b334a45a8ff 874 * Notice that no special consideration is given to possible wrap around. If
bogdanm 0:9b334a45a8ff 875 * 32 least significant bits are 0xFFFFFFFF, they will be updated to 0x00000000,
bogdanm 0:9b334a45a8ff 876 * ignoring overflow.
bogdanm 0:9b334a45a8ff 877 *
bogdanm 0:9b334a45a8ff 878 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 879 *
bogdanm 0:9b334a45a8ff 880 * @param[in,out] ctr
bogdanm 0:9b334a45a8ff 881 * Buffer holding 128 bit counter to be updated.
bogdanm 0:9b334a45a8ff 882 ******************************************************************************/
bogdanm 0:9b334a45a8ff 883 void AES_CTRUpdate32Bit(uint8_t *ctr)
bogdanm 0:9b334a45a8ff 884 {
bogdanm 0:9b334a45a8ff 885 uint32_t *_ctr = (uint32_t *)ctr;
bogdanm 0:9b334a45a8ff 886
bogdanm 0:9b334a45a8ff 887 _ctr[3] = __REV(__REV(_ctr[3]) + 1);
bogdanm 0:9b334a45a8ff 888 }
bogdanm 0:9b334a45a8ff 889
bogdanm 0:9b334a45a8ff 890
bogdanm 0:9b334a45a8ff 891 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 892 * @brief
bogdanm 0:9b334a45a8ff 893 * Generate 128 bit decryption key from 128 bit encryption key. The decryption
bogdanm 0:9b334a45a8ff 894 * key is used for some cipher modes when decrypting.
bogdanm 0:9b334a45a8ff 895 *
bogdanm 0:9b334a45a8ff 896 * @details
bogdanm 0:9b334a45a8ff 897 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 898 *
bogdanm 0:9b334a45a8ff 899 * @param[out] out
bogdanm 0:9b334a45a8ff 900 * Buffer to place 128 bit decryption key. Must be at least 16 bytes long. It
bogdanm 0:9b334a45a8ff 901 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 902 *
bogdanm 0:9b334a45a8ff 903 * @param[in] in
bogdanm 0:9b334a45a8ff 904 * Buffer holding 128 bit encryption key. Must be at least 16 bytes long.
bogdanm 0:9b334a45a8ff 905 ******************************************************************************/
bogdanm 0:9b334a45a8ff 906 void AES_DecryptKey128(uint8_t *out, const uint8_t *in)
bogdanm 0:9b334a45a8ff 907 {
bogdanm 0:9b334a45a8ff 908 int i;
bogdanm 0:9b334a45a8ff 909 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 910 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 911
bogdanm 0:9b334a45a8ff 912 /* Load key */
bogdanm 0:9b334a45a8ff 913 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 914 {
bogdanm 0:9b334a45a8ff 915 AES->KEYLA = __REV(_in[i]);
bogdanm 0:9b334a45a8ff 916 }
bogdanm 0:9b334a45a8ff 917
bogdanm 0:9b334a45a8ff 918 /* Do dummy encryption to generate decrypt key */
bogdanm 0:9b334a45a8ff 919 AES->CTRL = 0;
bogdanm 0:9b334a45a8ff 920 AES_IntClear(AES_IF_DONE);
bogdanm 0:9b334a45a8ff 921 AES->CMD = AES_CMD_START;
bogdanm 0:9b334a45a8ff 922
bogdanm 0:9b334a45a8ff 923 /* Wait for completion */
bogdanm 0:9b334a45a8ff 924 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 925 ;
bogdanm 0:9b334a45a8ff 926
bogdanm 0:9b334a45a8ff 927 /* Save decryption key */
bogdanm 0:9b334a45a8ff 928 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 929 {
bogdanm 0:9b334a45a8ff 930 _out[i] = __REV(AES->KEYLA);
bogdanm 0:9b334a45a8ff 931 }
bogdanm 0:9b334a45a8ff 932 }
bogdanm 0:9b334a45a8ff 933
bogdanm 0:9b334a45a8ff 934
bogdanm 0:9b334a45a8ff 935 #if defined( AES_CTRL_AES256 )
bogdanm 0:9b334a45a8ff 936 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 937 * @brief
bogdanm 0:9b334a45a8ff 938 * Generate 256 bit decryption key from 256 bit encryption key. The decryption
bogdanm 0:9b334a45a8ff 939 * key is used for some cipher modes when decrypting.
bogdanm 0:9b334a45a8ff 940 *
bogdanm 0:9b334a45a8ff 941 * @details
bogdanm 0:9b334a45a8ff 942 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 943 *
bogdanm 0:9b334a45a8ff 944 * @param[out] out
bogdanm 0:9b334a45a8ff 945 * Buffer to place 256 bit decryption key. Must be at least 32 bytes long. It
bogdanm 0:9b334a45a8ff 946 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 947 *
bogdanm 0:9b334a45a8ff 948 * @param[in] in
bogdanm 0:9b334a45a8ff 949 * Buffer holding 256 bit encryption key. Must be at least 32 bytes long.
bogdanm 0:9b334a45a8ff 950 ******************************************************************************/
bogdanm 0:9b334a45a8ff 951 void AES_DecryptKey256(uint8_t *out, const uint8_t *in)
bogdanm 0:9b334a45a8ff 952 {
bogdanm 0:9b334a45a8ff 953 int i;
bogdanm 0:9b334a45a8ff 954 int j;
bogdanm 0:9b334a45a8ff 955 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 956 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 957
bogdanm 0:9b334a45a8ff 958 /* Load key */
bogdanm 0:9b334a45a8ff 959 for (i = 3, j = 7; i >= 0; i--, j--)
bogdanm 0:9b334a45a8ff 960 {
bogdanm 0:9b334a45a8ff 961 AES->KEYLA = __REV(_in[j]);
bogdanm 0:9b334a45a8ff 962 AES->KEYHA = __REV(_in[i]);
bogdanm 0:9b334a45a8ff 963 }
bogdanm 0:9b334a45a8ff 964
bogdanm 0:9b334a45a8ff 965 /* Do dummy encryption to generate decrypt key */
bogdanm 0:9b334a45a8ff 966 AES->CTRL = AES_CTRL_AES256;
bogdanm 0:9b334a45a8ff 967 AES->CMD = AES_CMD_START;
bogdanm 0:9b334a45a8ff 968
bogdanm 0:9b334a45a8ff 969 /* Wait for completion */
bogdanm 0:9b334a45a8ff 970 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 971 ;
bogdanm 0:9b334a45a8ff 972
bogdanm 0:9b334a45a8ff 973 /* Save decryption key */
bogdanm 0:9b334a45a8ff 974 for (i = 3, j = 7; i >= 0; i--, j--)
bogdanm 0:9b334a45a8ff 975 {
bogdanm 0:9b334a45a8ff 976 _out[j] = __REV(AES->KEYLA);
bogdanm 0:9b334a45a8ff 977 _out[i] = __REV(AES->KEYHA);
bogdanm 0:9b334a45a8ff 978 }
bogdanm 0:9b334a45a8ff 979 }
bogdanm 0:9b334a45a8ff 980 #endif
bogdanm 0:9b334a45a8ff 981
bogdanm 0:9b334a45a8ff 982
bogdanm 0:9b334a45a8ff 983 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 984 * @brief
bogdanm 0:9b334a45a8ff 985 * Electronic Codebook (ECB) cipher mode encryption/decryption, 128 bit key.
bogdanm 0:9b334a45a8ff 986 *
bogdanm 0:9b334a45a8ff 987 * @details
bogdanm 0:9b334a45a8ff 988 * Encryption:
bogdanm 0:9b334a45a8ff 989 * @verbatim
bogdanm 0:9b334a45a8ff 990 * Plaintext Plaintext
bogdanm 0:9b334a45a8ff 991 * | |
bogdanm 0:9b334a45a8ff 992 * V V
bogdanm 0:9b334a45a8ff 993 * +--------------+ +--------------+
bogdanm 0:9b334a45a8ff 994 * Key ->| Block cipher | Key ->| Block cipher |
bogdanm 0:9b334a45a8ff 995 * | encryption | | encryption |
bogdanm 0:9b334a45a8ff 996 * +--------------+ +--------------+
bogdanm 0:9b334a45a8ff 997 * | |
bogdanm 0:9b334a45a8ff 998 * V V
bogdanm 0:9b334a45a8ff 999 * Ciphertext Ciphertext
bogdanm 0:9b334a45a8ff 1000 * @endverbatim
bogdanm 0:9b334a45a8ff 1001 * Decryption:
bogdanm 0:9b334a45a8ff 1002 * @verbatim
bogdanm 0:9b334a45a8ff 1003 * Ciphertext Ciphertext
bogdanm 0:9b334a45a8ff 1004 * | |
bogdanm 0:9b334a45a8ff 1005 * V V
bogdanm 0:9b334a45a8ff 1006 * +--------------+ +--------------+
bogdanm 0:9b334a45a8ff 1007 * Key ->| Block cipher | Key ->| Block cipher |
bogdanm 0:9b334a45a8ff 1008 * | decryption | | decryption |
bogdanm 0:9b334a45a8ff 1009 * +--------------+ +--------------+
bogdanm 0:9b334a45a8ff 1010 * | |
bogdanm 0:9b334a45a8ff 1011 * V V
bogdanm 0:9b334a45a8ff 1012 * Plaintext Plaintext
bogdanm 0:9b334a45a8ff 1013 * @endverbatim
bogdanm 0:9b334a45a8ff 1014 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 1015 *
bogdanm 0:9b334a45a8ff 1016 * @param[out] out
bogdanm 0:9b334a45a8ff 1017 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
bogdanm 0:9b334a45a8ff 1018 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 1019 *
bogdanm 0:9b334a45a8ff 1020 * @param[in] in
bogdanm 0:9b334a45a8ff 1021 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
bogdanm 0:9b334a45a8ff 1022 *
bogdanm 0:9b334a45a8ff 1023 * @param[in] len
bogdanm 0:9b334a45a8ff 1024 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
bogdanm 0:9b334a45a8ff 1025 *
bogdanm 0:9b334a45a8ff 1026 * @param[in] key
bogdanm 0:9b334a45a8ff 1027 * When doing encryption, this is the 128 bit encryption key. When doing
bogdanm 0:9b334a45a8ff 1028 * decryption, this is the 128 bit decryption key. The decryption key may
bogdanm 0:9b334a45a8ff 1029 * be generated from the encryption key with AES_DecryptKey128().
bogdanm 0:9b334a45a8ff 1030 *
bogdanm 0:9b334a45a8ff 1031 * @param[in] encrypt
bogdanm 0:9b334a45a8ff 1032 * Set to true to encrypt, false to decrypt.
bogdanm 0:9b334a45a8ff 1033 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1034 void AES_ECB128(uint8_t *out,
bogdanm 0:9b334a45a8ff 1035 const uint8_t *in,
bogdanm 0:9b334a45a8ff 1036 unsigned int len,
bogdanm 0:9b334a45a8ff 1037 const uint8_t *key,
bogdanm 0:9b334a45a8ff 1038 bool encrypt)
bogdanm 0:9b334a45a8ff 1039 {
bogdanm 0:9b334a45a8ff 1040 int i;
bogdanm 0:9b334a45a8ff 1041 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 1042 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 1043 const uint32_t *_key = (const uint32_t *)key;
bogdanm 0:9b334a45a8ff 1044
bogdanm 0:9b334a45a8ff 1045 EFM_ASSERT(!(len % AES_BLOCKSIZE));
bogdanm 0:9b334a45a8ff 1046
bogdanm 0:9b334a45a8ff 1047 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 1048 /* Load key into high key for key buffer usage */
bogdanm 0:9b334a45a8ff 1049 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 1050 {
bogdanm 0:9b334a45a8ff 1051 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 1052 }
bogdanm 0:9b334a45a8ff 1053 #endif
bogdanm 0:9b334a45a8ff 1054
bogdanm 0:9b334a45a8ff 1055 if (encrypt)
bogdanm 0:9b334a45a8ff 1056 {
bogdanm 0:9b334a45a8ff 1057 /* Select encryption mode */
bogdanm 0:9b334a45a8ff 1058 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 1059 AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 1060 #else
bogdanm 0:9b334a45a8ff 1061 AES->CTRL = AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 1062 #endif
bogdanm 0:9b334a45a8ff 1063 }
bogdanm 0:9b334a45a8ff 1064 else
bogdanm 0:9b334a45a8ff 1065 {
bogdanm 0:9b334a45a8ff 1066 /* Select decryption mode */
bogdanm 0:9b334a45a8ff 1067 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 1068 AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 1069 #else
bogdanm 0:9b334a45a8ff 1070 AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 1071 #endif
bogdanm 0:9b334a45a8ff 1072 }
bogdanm 0:9b334a45a8ff 1073
bogdanm 0:9b334a45a8ff 1074 /* Encrypt/decrypt data */
bogdanm 0:9b334a45a8ff 1075 len /= AES_BLOCKSIZE;
bogdanm 0:9b334a45a8ff 1076 while (len--)
bogdanm 0:9b334a45a8ff 1077 {
bogdanm 0:9b334a45a8ff 1078 #if !defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 1079 /* Load key */
bogdanm 0:9b334a45a8ff 1080 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 1081 {
bogdanm 0:9b334a45a8ff 1082 AES->KEYLA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 1083 }
bogdanm 0:9b334a45a8ff 1084 #endif
bogdanm 0:9b334a45a8ff 1085
bogdanm 0:9b334a45a8ff 1086 /* Load block to be encrypted/decrypted */
bogdanm 0:9b334a45a8ff 1087 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 1088 {
bogdanm 0:9b334a45a8ff 1089 AES->DATA = __REV(_in[i]);
bogdanm 0:9b334a45a8ff 1090 }
bogdanm 0:9b334a45a8ff 1091 _in += 4;
bogdanm 0:9b334a45a8ff 1092
bogdanm 0:9b334a45a8ff 1093 /* Wait for completion */
bogdanm 0:9b334a45a8ff 1094 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 1095 ;
bogdanm 0:9b334a45a8ff 1096
bogdanm 0:9b334a45a8ff 1097 /* Save encrypted/decrypted data */
bogdanm 0:9b334a45a8ff 1098 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 1099 {
bogdanm 0:9b334a45a8ff 1100 _out[i] = __REV(AES->DATA);
bogdanm 0:9b334a45a8ff 1101 }
bogdanm 0:9b334a45a8ff 1102 _out += 4;
bogdanm 0:9b334a45a8ff 1103 }
bogdanm 0:9b334a45a8ff 1104 }
bogdanm 0:9b334a45a8ff 1105
bogdanm 0:9b334a45a8ff 1106
bogdanm 0:9b334a45a8ff 1107 #if defined( AES_CTRL_AES256 )
bogdanm 0:9b334a45a8ff 1108 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 1109 * @brief
bogdanm 0:9b334a45a8ff 1110 * Electronic Codebook (ECB) cipher mode encryption/decryption, 256 bit key.
bogdanm 0:9b334a45a8ff 1111 *
bogdanm 0:9b334a45a8ff 1112 * @details
bogdanm 0:9b334a45a8ff 1113 * Please see AES_ECB128() for ECB figure.
bogdanm 0:9b334a45a8ff 1114 *
bogdanm 0:9b334a45a8ff 1115 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 1116 *
bogdanm 0:9b334a45a8ff 1117 * @param[out] out
bogdanm 0:9b334a45a8ff 1118 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
bogdanm 0:9b334a45a8ff 1119 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 1120 *
bogdanm 0:9b334a45a8ff 1121 * @param[in] in
bogdanm 0:9b334a45a8ff 1122 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
bogdanm 0:9b334a45a8ff 1123 *
bogdanm 0:9b334a45a8ff 1124 * @param[in] len
bogdanm 0:9b334a45a8ff 1125 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
bogdanm 0:9b334a45a8ff 1126 *
bogdanm 0:9b334a45a8ff 1127 * @param[in] key
bogdanm 0:9b334a45a8ff 1128 * When doing encryption, this is the 256 bit encryption key. When doing
bogdanm 0:9b334a45a8ff 1129 * decryption, this is the 256 bit decryption key. The decryption key may
bogdanm 0:9b334a45a8ff 1130 * be generated from the encryption key with AES_DecryptKey256().
bogdanm 0:9b334a45a8ff 1131 *
bogdanm 0:9b334a45a8ff 1132 * @param[in] encrypt
bogdanm 0:9b334a45a8ff 1133 * Set to true to encrypt, false to decrypt.
bogdanm 0:9b334a45a8ff 1134 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1135 void AES_ECB256(uint8_t *out,
bogdanm 0:9b334a45a8ff 1136 const uint8_t *in,
bogdanm 0:9b334a45a8ff 1137 unsigned int len,
bogdanm 0:9b334a45a8ff 1138 const uint8_t *key,
bogdanm 0:9b334a45a8ff 1139 bool encrypt)
bogdanm 0:9b334a45a8ff 1140 {
bogdanm 0:9b334a45a8ff 1141 int i;
bogdanm 0:9b334a45a8ff 1142 int j;
bogdanm 0:9b334a45a8ff 1143 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 1144 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 1145 const uint32_t *_key = (const uint32_t *)key;
bogdanm 0:9b334a45a8ff 1146
bogdanm 0:9b334a45a8ff 1147 EFM_ASSERT(!(len % AES_BLOCKSIZE));
bogdanm 0:9b334a45a8ff 1148
bogdanm 0:9b334a45a8ff 1149 if (encrypt)
bogdanm 0:9b334a45a8ff 1150 {
bogdanm 0:9b334a45a8ff 1151 /* Select encryption mode */
bogdanm 0:9b334a45a8ff 1152 AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 1153 }
bogdanm 0:9b334a45a8ff 1154 else
bogdanm 0:9b334a45a8ff 1155 {
bogdanm 0:9b334a45a8ff 1156 /* Select decryption mode */
bogdanm 0:9b334a45a8ff 1157 AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_AES256 | AES_CTRL_DATASTART;
bogdanm 0:9b334a45a8ff 1158 }
bogdanm 0:9b334a45a8ff 1159
bogdanm 0:9b334a45a8ff 1160 /* Encrypt/decrypt data */
bogdanm 0:9b334a45a8ff 1161 len /= AES_BLOCKSIZE;
bogdanm 0:9b334a45a8ff 1162 while (len--)
bogdanm 0:9b334a45a8ff 1163 {
bogdanm 0:9b334a45a8ff 1164 /* Load key and block to be encrypted/decrypted */
bogdanm 0:9b334a45a8ff 1165 for (i = 3, j = 7; i >= 0; i--, j--)
bogdanm 0:9b334a45a8ff 1166 {
bogdanm 0:9b334a45a8ff 1167 AES->KEYLA = __REV(_key[j]);
bogdanm 0:9b334a45a8ff 1168 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 1169 /* Write data last, since will trigger encryption on last iteration */
bogdanm 0:9b334a45a8ff 1170 AES->DATA = __REV(_in[i]);
bogdanm 0:9b334a45a8ff 1171 }
bogdanm 0:9b334a45a8ff 1172 _in += 4;
bogdanm 0:9b334a45a8ff 1173
bogdanm 0:9b334a45a8ff 1174 /* Wait for completion */
bogdanm 0:9b334a45a8ff 1175 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 1176 ;
bogdanm 0:9b334a45a8ff 1177
bogdanm 0:9b334a45a8ff 1178 /* Save encrypted/decrypted data */
bogdanm 0:9b334a45a8ff 1179 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 1180 {
bogdanm 0:9b334a45a8ff 1181 _out[i] = __REV(AES->DATA);
bogdanm 0:9b334a45a8ff 1182 }
bogdanm 0:9b334a45a8ff 1183 _out += 4;
bogdanm 0:9b334a45a8ff 1184 }
bogdanm 0:9b334a45a8ff 1185 }
bogdanm 0:9b334a45a8ff 1186 #endif
bogdanm 0:9b334a45a8ff 1187
bogdanm 0:9b334a45a8ff 1188
bogdanm 0:9b334a45a8ff 1189 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 1190 * @brief
bogdanm 0:9b334a45a8ff 1191 * Output feedback (OFB) cipher mode encryption/decryption, 128 bit key.
bogdanm 0:9b334a45a8ff 1192 *
bogdanm 0:9b334a45a8ff 1193 * @details
bogdanm 0:9b334a45a8ff 1194 * Encryption:
bogdanm 0:9b334a45a8ff 1195 * @verbatim
bogdanm 0:9b334a45a8ff 1196 * InitVector +----------------+
bogdanm 0:9b334a45a8ff 1197 * | | |
bogdanm 0:9b334a45a8ff 1198 * V | V
bogdanm 0:9b334a45a8ff 1199 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 1200 * Key ->| Block cipher | | Key ->| Block cipher |
bogdanm 0:9b334a45a8ff 1201 * | encryption | | | encryption |
bogdanm 0:9b334a45a8ff 1202 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 1203 * | | |
bogdanm 0:9b334a45a8ff 1204 * |---------+ |
bogdanm 0:9b334a45a8ff 1205 * V V
bogdanm 0:9b334a45a8ff 1206 * Plaintext ->XOR Plaintext ->XOR
bogdanm 0:9b334a45a8ff 1207 * | |
bogdanm 0:9b334a45a8ff 1208 * V V
bogdanm 0:9b334a45a8ff 1209 * Ciphertext Ciphertext
bogdanm 0:9b334a45a8ff 1210 * @endverbatim
bogdanm 0:9b334a45a8ff 1211 * Decryption:
bogdanm 0:9b334a45a8ff 1212 * @verbatim
bogdanm 0:9b334a45a8ff 1213 * InitVector +----------------+
bogdanm 0:9b334a45a8ff 1214 * | | |
bogdanm 0:9b334a45a8ff 1215 * V | V
bogdanm 0:9b334a45a8ff 1216 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 1217 * Key ->| Block cipher | | Key ->| Block cipher |
bogdanm 0:9b334a45a8ff 1218 * | encryption | | | encryption |
bogdanm 0:9b334a45a8ff 1219 * +--------------+ | +--------------+
bogdanm 0:9b334a45a8ff 1220 * | | |
bogdanm 0:9b334a45a8ff 1221 * |---------+ |
bogdanm 0:9b334a45a8ff 1222 * V V
bogdanm 0:9b334a45a8ff 1223 * Ciphertext ->XOR Ciphertext ->XOR
bogdanm 0:9b334a45a8ff 1224 * | |
bogdanm 0:9b334a45a8ff 1225 * V V
bogdanm 0:9b334a45a8ff 1226 * Plaintext Plaintext
bogdanm 0:9b334a45a8ff 1227 * @endverbatim
bogdanm 0:9b334a45a8ff 1228 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 1229 *
bogdanm 0:9b334a45a8ff 1230 * @param[out] out
bogdanm 0:9b334a45a8ff 1231 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
bogdanm 0:9b334a45a8ff 1232 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 1233 *
bogdanm 0:9b334a45a8ff 1234 * @param[in] in
bogdanm 0:9b334a45a8ff 1235 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
bogdanm 0:9b334a45a8ff 1236 *
bogdanm 0:9b334a45a8ff 1237 * @param[in] len
bogdanm 0:9b334a45a8ff 1238 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
bogdanm 0:9b334a45a8ff 1239 *
bogdanm 0:9b334a45a8ff 1240 * @param[in] key
bogdanm 0:9b334a45a8ff 1241 * 128 bit encryption key.
bogdanm 0:9b334a45a8ff 1242 *
bogdanm 0:9b334a45a8ff 1243 * @param[in] iv
bogdanm 0:9b334a45a8ff 1244 * 128 bit initalization vector to use.
bogdanm 0:9b334a45a8ff 1245 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1246 void AES_OFB128(uint8_t *out,
bogdanm 0:9b334a45a8ff 1247 const uint8_t *in,
bogdanm 0:9b334a45a8ff 1248 unsigned int len,
bogdanm 0:9b334a45a8ff 1249 const uint8_t *key,
bogdanm 0:9b334a45a8ff 1250 const uint8_t *iv)
bogdanm 0:9b334a45a8ff 1251 {
bogdanm 0:9b334a45a8ff 1252 int i;
bogdanm 0:9b334a45a8ff 1253 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 1254 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 1255 const uint32_t *_key = (const uint32_t *)key;
bogdanm 0:9b334a45a8ff 1256 const uint32_t *_iv = (const uint32_t *)iv;
bogdanm 0:9b334a45a8ff 1257
bogdanm 0:9b334a45a8ff 1258 EFM_ASSERT(!(len % AES_BLOCKSIZE));
bogdanm 0:9b334a45a8ff 1259
bogdanm 0:9b334a45a8ff 1260 /* Select encryption mode, trigger explicitly by command */
bogdanm 0:9b334a45a8ff 1261 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 1262 AES->CTRL = AES_CTRL_KEYBUFEN;
bogdanm 0:9b334a45a8ff 1263 #else
bogdanm 0:9b334a45a8ff 1264 AES->CTRL = 0;
bogdanm 0:9b334a45a8ff 1265 #endif
bogdanm 0:9b334a45a8ff 1266
bogdanm 0:9b334a45a8ff 1267 /* Load key into high key for key buffer usage */
bogdanm 0:9b334a45a8ff 1268 /* Load initialization vector */
bogdanm 0:9b334a45a8ff 1269 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 1270 {
bogdanm 0:9b334a45a8ff 1271 #if defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 1272 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 1273 #endif
bogdanm 0:9b334a45a8ff 1274 AES->DATA = __REV(_iv[i]);
bogdanm 0:9b334a45a8ff 1275 }
bogdanm 0:9b334a45a8ff 1276
bogdanm 0:9b334a45a8ff 1277 /* Encrypt/decrypt data */
bogdanm 0:9b334a45a8ff 1278 len /= AES_BLOCKSIZE;
bogdanm 0:9b334a45a8ff 1279 while (len--)
bogdanm 0:9b334a45a8ff 1280 {
bogdanm 0:9b334a45a8ff 1281 #if !defined( AES_CTRL_KEYBUFEN )
bogdanm 0:9b334a45a8ff 1282 /* Load key */
bogdanm 0:9b334a45a8ff 1283 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 1284 {
bogdanm 0:9b334a45a8ff 1285 AES->KEYLA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 1286 }
bogdanm 0:9b334a45a8ff 1287 #endif
bogdanm 0:9b334a45a8ff 1288
bogdanm 0:9b334a45a8ff 1289 AES->CMD = AES_CMD_START;
bogdanm 0:9b334a45a8ff 1290
bogdanm 0:9b334a45a8ff 1291 /* Wait for completion */
bogdanm 0:9b334a45a8ff 1292 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 1293 ;
bogdanm 0:9b334a45a8ff 1294
bogdanm 0:9b334a45a8ff 1295 /* Save encrypted/decrypted data */
bogdanm 0:9b334a45a8ff 1296 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 1297 {
bogdanm 0:9b334a45a8ff 1298 _out[i] = __REV(AES->DATA) ^ _in[i];
bogdanm 0:9b334a45a8ff 1299 }
bogdanm 0:9b334a45a8ff 1300 _out += 4;
bogdanm 0:9b334a45a8ff 1301 _in += 4;
bogdanm 0:9b334a45a8ff 1302 }
bogdanm 0:9b334a45a8ff 1303 }
bogdanm 0:9b334a45a8ff 1304
bogdanm 0:9b334a45a8ff 1305
bogdanm 0:9b334a45a8ff 1306 #if defined( AES_CTRL_AES256 )
bogdanm 0:9b334a45a8ff 1307 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 1308 * @brief
bogdanm 0:9b334a45a8ff 1309 * Output feedback (OFB) cipher mode encryption/decryption, 256 bit key.
bogdanm 0:9b334a45a8ff 1310 *
bogdanm 0:9b334a45a8ff 1311 * @details
bogdanm 0:9b334a45a8ff 1312 * Please see AES_OFB128() for OFB figure.
bogdanm 0:9b334a45a8ff 1313 *
bogdanm 0:9b334a45a8ff 1314 * Please refer to general comments on layout and byte ordering of parameters.
bogdanm 0:9b334a45a8ff 1315 *
bogdanm 0:9b334a45a8ff 1316 * @param[out] out
bogdanm 0:9b334a45a8ff 1317 * Buffer to place encrypted/decrypted data. Must be at least @p len long. It
bogdanm 0:9b334a45a8ff 1318 * may be set equal to @p in, in which case the input buffer is overwritten.
bogdanm 0:9b334a45a8ff 1319 *
bogdanm 0:9b334a45a8ff 1320 * @param[in] in
bogdanm 0:9b334a45a8ff 1321 * Buffer holding data to encrypt/decrypt. Must be at least @p len long.
bogdanm 0:9b334a45a8ff 1322 *
bogdanm 0:9b334a45a8ff 1323 * @param[in] len
bogdanm 0:9b334a45a8ff 1324 * Number of bytes to encrypt/decrypt. Must be a multiple of 16.
bogdanm 0:9b334a45a8ff 1325 *
bogdanm 0:9b334a45a8ff 1326 * @param[in] key
bogdanm 0:9b334a45a8ff 1327 * 256 bit encryption key.
bogdanm 0:9b334a45a8ff 1328 *
bogdanm 0:9b334a45a8ff 1329 * @param[in] iv
bogdanm 0:9b334a45a8ff 1330 * 128 bit initalization vector to use.
bogdanm 0:9b334a45a8ff 1331 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1332 void AES_OFB256(uint8_t *out,
bogdanm 0:9b334a45a8ff 1333 const uint8_t *in,
bogdanm 0:9b334a45a8ff 1334 unsigned int len,
bogdanm 0:9b334a45a8ff 1335 const uint8_t *key,
bogdanm 0:9b334a45a8ff 1336 const uint8_t *iv)
bogdanm 0:9b334a45a8ff 1337 {
bogdanm 0:9b334a45a8ff 1338 int i;
bogdanm 0:9b334a45a8ff 1339 int j;
bogdanm 0:9b334a45a8ff 1340 uint32_t *_out = (uint32_t *)out;
bogdanm 0:9b334a45a8ff 1341 const uint32_t *_in = (const uint32_t *)in;
bogdanm 0:9b334a45a8ff 1342 const uint32_t *_key = (const uint32_t *)key;
bogdanm 0:9b334a45a8ff 1343 const uint32_t *_iv = (const uint32_t *)iv;
bogdanm 0:9b334a45a8ff 1344
bogdanm 0:9b334a45a8ff 1345 EFM_ASSERT(!(len % AES_BLOCKSIZE));
bogdanm 0:9b334a45a8ff 1346
bogdanm 0:9b334a45a8ff 1347 /* Select encryption mode, trigger explicitly by command */
bogdanm 0:9b334a45a8ff 1348 AES->CTRL = AES_CTRL_AES256;
bogdanm 0:9b334a45a8ff 1349
bogdanm 0:9b334a45a8ff 1350 /* Load initialization vector */
bogdanm 0:9b334a45a8ff 1351 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 1352 {
bogdanm 0:9b334a45a8ff 1353 AES->DATA = __REV(_iv[i]);
bogdanm 0:9b334a45a8ff 1354 }
bogdanm 0:9b334a45a8ff 1355
bogdanm 0:9b334a45a8ff 1356 /* Encrypt/decrypt data */
bogdanm 0:9b334a45a8ff 1357 len /= AES_BLOCKSIZE;
bogdanm 0:9b334a45a8ff 1358 while (len--)
bogdanm 0:9b334a45a8ff 1359 {
bogdanm 0:9b334a45a8ff 1360 /* Load key */
bogdanm 0:9b334a45a8ff 1361 for (i = 3, j = 7; i >= 0; i--, j--)
bogdanm 0:9b334a45a8ff 1362 {
bogdanm 0:9b334a45a8ff 1363 AES->KEYLA = __REV(_key[j]);
bogdanm 0:9b334a45a8ff 1364 AES->KEYHA = __REV(_key[i]);
bogdanm 0:9b334a45a8ff 1365 }
bogdanm 0:9b334a45a8ff 1366
bogdanm 0:9b334a45a8ff 1367 AES->CMD = AES_CMD_START;
bogdanm 0:9b334a45a8ff 1368
bogdanm 0:9b334a45a8ff 1369 /* Wait for completion */
bogdanm 0:9b334a45a8ff 1370 while (AES->STATUS & AES_STATUS_RUNNING)
bogdanm 0:9b334a45a8ff 1371 ;
bogdanm 0:9b334a45a8ff 1372
bogdanm 0:9b334a45a8ff 1373 /* Save encrypted/decrypted data */
bogdanm 0:9b334a45a8ff 1374 for (i = 3; i >= 0; i--)
bogdanm 0:9b334a45a8ff 1375 {
bogdanm 0:9b334a45a8ff 1376 _out[i] = __REV(AES->DATA) ^ _in[i];
bogdanm 0:9b334a45a8ff 1377 }
bogdanm 0:9b334a45a8ff 1378 _out += 4;
bogdanm 0:9b334a45a8ff 1379 _in += 4;
bogdanm 0:9b334a45a8ff 1380 }
bogdanm 0:9b334a45a8ff 1381 }
bogdanm 0:9b334a45a8ff 1382 #endif
bogdanm 0:9b334a45a8ff 1383
bogdanm 0:9b334a45a8ff 1384
bogdanm 0:9b334a45a8ff 1385 /** @} (end addtogroup AES) */
bogdanm 0:9b334a45a8ff 1386 /** @} (end addtogroup EM_Library) */
bogdanm 0:9b334a45a8ff 1387 #endif /* defined(AES_COUNT) && (AES_COUNT > 0) */