added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
bogdanm
Date:
Thu Oct 01 15:25:22 2015 +0300
Revision:
0:9b334a45a8ff
Child:
50:a417edff4437
Initial commit on mbed-dev

Replaces mbed-src (now inactive)

Who changed what in which revision?

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