mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
179:b0033dcd6934
mbed library release version 165

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