mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
Parent:
50:a417edff4437
This updates the lib to the mbed lib v125

Who changed what in which revision?

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