Demonstration of Class-A LoRaWAN device using NAMote-72

Dependencies:   LoRaWAN-lib mbed lib_mpl3115a2 lib_mma8451q lib_gps SX1272Lib

Dependents:   LoRaWAN-NAMote72-BVS-confirmed-tester-0-7v1_copy

LoRaWAN-NAMote72 Application Demo is a Class-A device example project using LoRaWAN-lib and SX1272Lib libraries.

This project is compliant with LoRaWAN V1.0.1 specification.

Comissioning.h (LoRaWAN Network Configuration)

The end-device can be activated in one of the two ways:

Over the Air (OTA) activation can be enabled as shown in the figure below. /media/uploads/ubhat/ota_enable.png

The end-device must be configured with the following parameters:

  • LORAWAN_DEVICE_EUI (8 Bytes) : Fist 3 Bytes is the Organizationally Unique Identifier (OUI) followed by 5 bytes of unique ID. If not defined by user, then the firmware automatically assigns one to the end-device
  • LORAWAN_APPLICATION_EUI (8 Bytes)
  • LORAWAN_APPLICATION_KEY (or DEVKEY) (16 Bytes)

/media/uploads/ubhat/ota_eui.png

Activation by Personalization (ABP) can be enabled as shown in the figure below. /media/uploads/ubhat/abp_enable.png

The end-device must be configured with the following parameters:

  • LORAWAN_DEVICE_ADDRESS (4 Bytes) : If not defined by user, then the firmware automatically assigns one to the end-device
  • LORAWAN_NWKSKEY (16 Bytes)
  • LORAWAN_APPSKEY (16 Bytes)

/media/uploads/ubhat/abp_key.png

Config.h (LoRaWAN Communication Parameters)

  • Mode of Operation : Hybrid If the end-device needs to be configured to operate over 8-channels, then Hybrid Mode needs to be enabled /media/uploads/ubhat/hybridenable.png
  • Mode of Operation : Frequency Hop If the end-device needs to be configured to operate over 64-channels, then Hybrid Mode needs to be disabled
  • Delay between successive JOIN REQUESTs : The delay between successive Join Requests (until the end-device joins the network) can be configured using the parameter OVER_THE_AIR_ACTIVATION_DUTYCYCLE
  • Inter-Frame Delay : One can change the delay between each frame transmission using APP_TX_DUTYCYCLE It is advisable that APP_TX_DUTYCYCLE is greater than or equal to 3sec.
  • Data Rate : The data rate can be configured as per LoRaWAN specification using the paramter LORAWAN_DEFAULT_DATARATE. The range of values are DR_0, DR_1, DR_2, DR_3 and DR_4
  • Confirmed/Unconfirmed Messages : The uplink message or payload can be chosen to be confirmed or unconfirmed using the parameter LORAWAN_CONFIRMED_MSG_ON. When set to 1, the transmitted messages need to be confirmed with an ACK by the network server in the subsequent RX window. When set to 0, no ACK is requested.
  • ADR ON/OFF : The ADR can be enabled or disabled using the parameter LORAWAN_ADR_ON. When set to 1, ADR is enabled and disabled when set to 0.
  • Application Port : The application port can be set using parameter LORAWAN_APP_PORT.
  • Payload Length : The lenght of the payload (in bytes) to be transmitted can be configured using LORAWAN_APP_DATA_SIZE
  • Transmit Power : The transmit power can be configured using LORAWAN_TX_POWER (LoRaMAC verifies if the set power is compliant with the LoRaWAN spec and FCC guidelines)

/media/uploads/ubhat/loraconfig.png

Main.cpp (Device State Machine)

The end-device state machine is defined.

  • Initial State : Device is initialized.
  • Join State : For OTA, Join Request is transmitted to the network until Join Accept is received by the end-device. Join event function is called that sets Red LED ON.
  • Send State : Transmit payload frame is prepared. Tx event is called that blinks the Red LED indicating uplink transmission.
  • Cycle State : Next packet transmission is scheduled

LoRaEventProc.cpp (Events and On-board Application)

Define events during Join, Tx & Rx. Prepare TX packet by appending with appropriate application data.

/media/uploads/ubhat/lora_events.png

  • PrepareLoRaFrame(uint8_t port ) : Prepare LoRa payload frame with on-board application data such as GPS, Temperature, Battery, etc. LoRa.ApplicationCall(AppType ) calls application AppType defined in LoRaApp.cpp. AppType is defined in LoRaApp.h

/media/uploads/ubhat/lora_app.png

LoRaApp.cpp

User-defined applications such as GPS, Temp, Accelerometer, LED indications etc. Event based actions such as LED blink on Tx, LED toggle on downlink etc /media/uploads/ubhat/apptype.png

LoRaDeviceStateProc.cpp

Process function calls corresponding to different Device states /media/uploads/ubhat/device_state.png

LoRaMacLayerService.cpp

Define MAC Layer Services: MLME & MCPS

Serial Terminal Display

By using a serial port connection using applications such as teraterm or putty, one can view the status of the End-Device. Once the End-Device Joins the network, transmission parameters such as payload data, application port, message type etc. are displayed on the terminal.

/media/uploads/ubhat/serial.png

Default Application Payload

This application defaults to sending uplink data to logical port 5. The application payload consists of: /media/uploads/jknapp_smtc/payload.png

Sample Application Payload Calculation for Longitude/Latitude

Payload => 00 19 F6 352BBA A94C20 FFFF

Temperature Calculation

19H => 2510

Temp = 25/2 = 12.5 oC

Battery Level

FFH => 100 %

F6H => 96.5 %

Longitude Calculation

longitude = A94C20H => 1109507210

longitudinal coordinate = -360 + (longitude10 x 180/(223))

longitudinal coordinate = -121.93

Latitude Calculation

latitude = 352BBAH = 348460210

latitude coordinate = (latitude10 x 90/(223-1))

latitude coordinate = 37.39

Committer:
ubhat
Date:
Tue May 17 00:21:55 2016 +0000
Revision:
0:69f2e28d12c1
Project for LoRa Bootcamp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ubhat 0:69f2e28d12c1 1 /*
ubhat 0:69f2e28d12c1 2 ---------------------------------------------------------------------------
ubhat 0:69f2e28d12c1 3 Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
ubhat 0:69f2e28d12c1 4
ubhat 0:69f2e28d12c1 5 LICENSE TERMS
ubhat 0:69f2e28d12c1 6
ubhat 0:69f2e28d12c1 7 The redistribution and use of this software (with or without changes)
ubhat 0:69f2e28d12c1 8 is allowed without the payment of fees or royalties provided that:
ubhat 0:69f2e28d12c1 9
ubhat 0:69f2e28d12c1 10 1. source code distributions include the above copyright notice, this
ubhat 0:69f2e28d12c1 11 list of conditions and the following disclaimer;
ubhat 0:69f2e28d12c1 12
ubhat 0:69f2e28d12c1 13 2. binary distributions include the above copyright notice, this list
ubhat 0:69f2e28d12c1 14 of conditions and the following disclaimer in their documentation;
ubhat 0:69f2e28d12c1 15
ubhat 0:69f2e28d12c1 16 3. the name of the copyright holder is not used to endorse products
ubhat 0:69f2e28d12c1 17 built using this software without specific written permission.
ubhat 0:69f2e28d12c1 18
ubhat 0:69f2e28d12c1 19 DISCLAIMER
ubhat 0:69f2e28d12c1 20
ubhat 0:69f2e28d12c1 21 This software is provided 'as is' with no explicit or implied warranties
ubhat 0:69f2e28d12c1 22 in respect of its properties, including, but not limited to, correctness
ubhat 0:69f2e28d12c1 23 and/or fitness for purpose.
ubhat 0:69f2e28d12c1 24 ---------------------------------------------------------------------------
ubhat 0:69f2e28d12c1 25 Issue 09/09/2006
ubhat 0:69f2e28d12c1 26
ubhat 0:69f2e28d12c1 27 This is an AES implementation that uses only 8-bit byte operations on the
ubhat 0:69f2e28d12c1 28 cipher state (there are options to use 32-bit types if available).
ubhat 0:69f2e28d12c1 29
ubhat 0:69f2e28d12c1 30 The combination of mix columns and byte substitution used here is based on
ubhat 0:69f2e28d12c1 31 that developed by Karl Malbrain. His contribution is acknowledged.
ubhat 0:69f2e28d12c1 32 */
ubhat 0:69f2e28d12c1 33
ubhat 0:69f2e28d12c1 34 /* define if you have a fast memcpy function on your system */
ubhat 0:69f2e28d12c1 35 #if 0
ubhat 0:69f2e28d12c1 36 # define HAVE_MEMCPY
ubhat 0:69f2e28d12c1 37 # include <string.h>
ubhat 0:69f2e28d12c1 38 # if defined( _MSC_VER )
ubhat 0:69f2e28d12c1 39 # include <intrin.h>
ubhat 0:69f2e28d12c1 40 # pragma intrinsic( memcpy )
ubhat 0:69f2e28d12c1 41 # endif
ubhat 0:69f2e28d12c1 42 #endif
ubhat 0:69f2e28d12c1 43
ubhat 0:69f2e28d12c1 44
ubhat 0:69f2e28d12c1 45 #include <stdlib.h>
ubhat 0:69f2e28d12c1 46 #include <stdint.h>
ubhat 0:69f2e28d12c1 47
ubhat 0:69f2e28d12c1 48 /* define if you have fast 32-bit types on your system */
ubhat 0:69f2e28d12c1 49 #if 1
ubhat 0:69f2e28d12c1 50 # define HAVE_UINT_32T
ubhat 0:69f2e28d12c1 51 #endif
ubhat 0:69f2e28d12c1 52
ubhat 0:69f2e28d12c1 53 /* define if you don't want any tables */
ubhat 0:69f2e28d12c1 54 #if 1
ubhat 0:69f2e28d12c1 55 # define USE_TABLES
ubhat 0:69f2e28d12c1 56 #endif
ubhat 0:69f2e28d12c1 57
ubhat 0:69f2e28d12c1 58 /* On Intel Core 2 duo VERSION_1 is faster */
ubhat 0:69f2e28d12c1 59
ubhat 0:69f2e28d12c1 60 /* alternative versions (test for performance on your system) */
ubhat 0:69f2e28d12c1 61 #if 1
ubhat 0:69f2e28d12c1 62 # define VERSION_1
ubhat 0:69f2e28d12c1 63 #endif
ubhat 0:69f2e28d12c1 64
ubhat 0:69f2e28d12c1 65 #include "aes.h"
ubhat 0:69f2e28d12c1 66
ubhat 0:69f2e28d12c1 67 //#if defined( HAVE_UINT_32T )
ubhat 0:69f2e28d12c1 68 // typedef unsigned long uint32_t;
ubhat 0:69f2e28d12c1 69 //#endif
ubhat 0:69f2e28d12c1 70
ubhat 0:69f2e28d12c1 71 /* functions for finite field multiplication in the AES Galois field */
ubhat 0:69f2e28d12c1 72
ubhat 0:69f2e28d12c1 73 #define WPOLY 0x011b
ubhat 0:69f2e28d12c1 74 #define BPOLY 0x1b
ubhat 0:69f2e28d12c1 75 #define DPOLY 0x008d
ubhat 0:69f2e28d12c1 76
ubhat 0:69f2e28d12c1 77 #define f1(x) (x)
ubhat 0:69f2e28d12c1 78 #define f2(x) ((x << 1) ^ (((x >> 7) & 1) * WPOLY))
ubhat 0:69f2e28d12c1 79 #define f4(x) ((x << 2) ^ (((x >> 6) & 1) * WPOLY) ^ (((x >> 6) & 2) * WPOLY))
ubhat 0:69f2e28d12c1 80 #define f8(x) ((x << 3) ^ (((x >> 5) & 1) * WPOLY) ^ (((x >> 5) & 2) * WPOLY) \
ubhat 0:69f2e28d12c1 81 ^ (((x >> 5) & 4) * WPOLY))
ubhat 0:69f2e28d12c1 82 #define d2(x) (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0))
ubhat 0:69f2e28d12c1 83
ubhat 0:69f2e28d12c1 84 #define f3(x) (f2(x) ^ x)
ubhat 0:69f2e28d12c1 85 #define f9(x) (f8(x) ^ x)
ubhat 0:69f2e28d12c1 86 #define fb(x) (f8(x) ^ f2(x) ^ x)
ubhat 0:69f2e28d12c1 87 #define fd(x) (f8(x) ^ f4(x) ^ x)
ubhat 0:69f2e28d12c1 88 #define fe(x) (f8(x) ^ f4(x) ^ f2(x))
ubhat 0:69f2e28d12c1 89
ubhat 0:69f2e28d12c1 90 #if defined( USE_TABLES )
ubhat 0:69f2e28d12c1 91
ubhat 0:69f2e28d12c1 92 #define sb_data(w) { /* S Box data values */ \
ubhat 0:69f2e28d12c1 93 w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
ubhat 0:69f2e28d12c1 94 w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
ubhat 0:69f2e28d12c1 95 w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
ubhat 0:69f2e28d12c1 96 w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
ubhat 0:69f2e28d12c1 97 w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
ubhat 0:69f2e28d12c1 98 w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
ubhat 0:69f2e28d12c1 99 w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
ubhat 0:69f2e28d12c1 100 w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
ubhat 0:69f2e28d12c1 101 w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
ubhat 0:69f2e28d12c1 102 w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
ubhat 0:69f2e28d12c1 103 w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
ubhat 0:69f2e28d12c1 104 w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
ubhat 0:69f2e28d12c1 105 w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
ubhat 0:69f2e28d12c1 106 w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
ubhat 0:69f2e28d12c1 107 w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
ubhat 0:69f2e28d12c1 108 w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
ubhat 0:69f2e28d12c1 109 w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
ubhat 0:69f2e28d12c1 110 w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
ubhat 0:69f2e28d12c1 111 w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
ubhat 0:69f2e28d12c1 112 w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
ubhat 0:69f2e28d12c1 113 w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
ubhat 0:69f2e28d12c1 114 w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
ubhat 0:69f2e28d12c1 115 w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
ubhat 0:69f2e28d12c1 116 w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
ubhat 0:69f2e28d12c1 117 w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
ubhat 0:69f2e28d12c1 118 w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
ubhat 0:69f2e28d12c1 119 w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
ubhat 0:69f2e28d12c1 120 w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
ubhat 0:69f2e28d12c1 121 w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
ubhat 0:69f2e28d12c1 122 w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
ubhat 0:69f2e28d12c1 123 w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
ubhat 0:69f2e28d12c1 124 w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
ubhat 0:69f2e28d12c1 125
ubhat 0:69f2e28d12c1 126 #define isb_data(w) { /* inverse S Box data values */ \
ubhat 0:69f2e28d12c1 127 w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
ubhat 0:69f2e28d12c1 128 w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
ubhat 0:69f2e28d12c1 129 w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
ubhat 0:69f2e28d12c1 130 w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
ubhat 0:69f2e28d12c1 131 w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
ubhat 0:69f2e28d12c1 132 w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
ubhat 0:69f2e28d12c1 133 w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
ubhat 0:69f2e28d12c1 134 w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
ubhat 0:69f2e28d12c1 135 w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
ubhat 0:69f2e28d12c1 136 w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
ubhat 0:69f2e28d12c1 137 w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
ubhat 0:69f2e28d12c1 138 w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
ubhat 0:69f2e28d12c1 139 w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
ubhat 0:69f2e28d12c1 140 w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
ubhat 0:69f2e28d12c1 141 w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
ubhat 0:69f2e28d12c1 142 w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
ubhat 0:69f2e28d12c1 143 w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
ubhat 0:69f2e28d12c1 144 w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
ubhat 0:69f2e28d12c1 145 w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
ubhat 0:69f2e28d12c1 146 w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
ubhat 0:69f2e28d12c1 147 w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
ubhat 0:69f2e28d12c1 148 w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
ubhat 0:69f2e28d12c1 149 w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
ubhat 0:69f2e28d12c1 150 w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
ubhat 0:69f2e28d12c1 151 w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
ubhat 0:69f2e28d12c1 152 w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
ubhat 0:69f2e28d12c1 153 w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
ubhat 0:69f2e28d12c1 154 w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
ubhat 0:69f2e28d12c1 155 w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
ubhat 0:69f2e28d12c1 156 w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
ubhat 0:69f2e28d12c1 157 w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
ubhat 0:69f2e28d12c1 158 w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
ubhat 0:69f2e28d12c1 159
ubhat 0:69f2e28d12c1 160 #define mm_data(w) { /* basic data for forming finite field tables */ \
ubhat 0:69f2e28d12c1 161 w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
ubhat 0:69f2e28d12c1 162 w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
ubhat 0:69f2e28d12c1 163 w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
ubhat 0:69f2e28d12c1 164 w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
ubhat 0:69f2e28d12c1 165 w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
ubhat 0:69f2e28d12c1 166 w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
ubhat 0:69f2e28d12c1 167 w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
ubhat 0:69f2e28d12c1 168 w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
ubhat 0:69f2e28d12c1 169 w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
ubhat 0:69f2e28d12c1 170 w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
ubhat 0:69f2e28d12c1 171 w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
ubhat 0:69f2e28d12c1 172 w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
ubhat 0:69f2e28d12c1 173 w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
ubhat 0:69f2e28d12c1 174 w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
ubhat 0:69f2e28d12c1 175 w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
ubhat 0:69f2e28d12c1 176 w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
ubhat 0:69f2e28d12c1 177 w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
ubhat 0:69f2e28d12c1 178 w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
ubhat 0:69f2e28d12c1 179 w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
ubhat 0:69f2e28d12c1 180 w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
ubhat 0:69f2e28d12c1 181 w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
ubhat 0:69f2e28d12c1 182 w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
ubhat 0:69f2e28d12c1 183 w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
ubhat 0:69f2e28d12c1 184 w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
ubhat 0:69f2e28d12c1 185 w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
ubhat 0:69f2e28d12c1 186 w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
ubhat 0:69f2e28d12c1 187 w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
ubhat 0:69f2e28d12c1 188 w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
ubhat 0:69f2e28d12c1 189 w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
ubhat 0:69f2e28d12c1 190 w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
ubhat 0:69f2e28d12c1 191 w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
ubhat 0:69f2e28d12c1 192 w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
ubhat 0:69f2e28d12c1 193
ubhat 0:69f2e28d12c1 194 static const uint8_t sbox[256] = sb_data(f1);
ubhat 0:69f2e28d12c1 195
ubhat 0:69f2e28d12c1 196 #if defined( AES_DEC_PREKEYED )
ubhat 0:69f2e28d12c1 197 static const uint8_t isbox[256] = isb_data(f1);
ubhat 0:69f2e28d12c1 198 #endif
ubhat 0:69f2e28d12c1 199
ubhat 0:69f2e28d12c1 200 static const uint8_t gfm2_sbox[256] = sb_data(f2);
ubhat 0:69f2e28d12c1 201 static const uint8_t gfm3_sbox[256] = sb_data(f3);
ubhat 0:69f2e28d12c1 202
ubhat 0:69f2e28d12c1 203 #if defined( AES_DEC_PREKEYED )
ubhat 0:69f2e28d12c1 204 static const uint8_t gfmul_9[256] = mm_data(f9);
ubhat 0:69f2e28d12c1 205 static const uint8_t gfmul_b[256] = mm_data(fb);
ubhat 0:69f2e28d12c1 206 static const uint8_t gfmul_d[256] = mm_data(fd);
ubhat 0:69f2e28d12c1 207 static const uint8_t gfmul_e[256] = mm_data(fe);
ubhat 0:69f2e28d12c1 208 #endif
ubhat 0:69f2e28d12c1 209
ubhat 0:69f2e28d12c1 210 #define s_box(x) sbox[(x)]
ubhat 0:69f2e28d12c1 211 #if defined( AES_DEC_PREKEYED )
ubhat 0:69f2e28d12c1 212 #define is_box(x) isbox[(x)]
ubhat 0:69f2e28d12c1 213 #endif
ubhat 0:69f2e28d12c1 214 #define gfm2_sb(x) gfm2_sbox[(x)]
ubhat 0:69f2e28d12c1 215 #define gfm3_sb(x) gfm3_sbox[(x)]
ubhat 0:69f2e28d12c1 216 #if defined( AES_DEC_PREKEYED )
ubhat 0:69f2e28d12c1 217 #define gfm_9(x) gfmul_9[(x)]
ubhat 0:69f2e28d12c1 218 #define gfm_b(x) gfmul_b[(x)]
ubhat 0:69f2e28d12c1 219 #define gfm_d(x) gfmul_d[(x)]
ubhat 0:69f2e28d12c1 220 #define gfm_e(x) gfmul_e[(x)]
ubhat 0:69f2e28d12c1 221 #endif
ubhat 0:69f2e28d12c1 222 #else
ubhat 0:69f2e28d12c1 223
ubhat 0:69f2e28d12c1 224 /* this is the high bit of x right shifted by 1 */
ubhat 0:69f2e28d12c1 225 /* position. Since the starting polynomial has */
ubhat 0:69f2e28d12c1 226 /* 9 bits (0x11b), this right shift keeps the */
ubhat 0:69f2e28d12c1 227 /* values of all top bits within a byte */
ubhat 0:69f2e28d12c1 228
ubhat 0:69f2e28d12c1 229 static uint8_t hibit(const uint8_t x)
ubhat 0:69f2e28d12c1 230 { uint8_t r = (uint8_t)((x >> 1) | (x >> 2));
ubhat 0:69f2e28d12c1 231
ubhat 0:69f2e28d12c1 232 r |= (r >> 2);
ubhat 0:69f2e28d12c1 233 r |= (r >> 4);
ubhat 0:69f2e28d12c1 234 return (r + 1) >> 1;
ubhat 0:69f2e28d12c1 235 }
ubhat 0:69f2e28d12c1 236
ubhat 0:69f2e28d12c1 237 /* return the inverse of the finite field element x */
ubhat 0:69f2e28d12c1 238
ubhat 0:69f2e28d12c1 239 static uint8_t gf_inv(const uint8_t x)
ubhat 0:69f2e28d12c1 240 { uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
ubhat 0:69f2e28d12c1 241
ubhat 0:69f2e28d12c1 242 if(x < 2)
ubhat 0:69f2e28d12c1 243 return x;
ubhat 0:69f2e28d12c1 244
ubhat 0:69f2e28d12c1 245 for( ; ; )
ubhat 0:69f2e28d12c1 246 {
ubhat 0:69f2e28d12c1 247 if(n1)
ubhat 0:69f2e28d12c1 248 while(n2 >= n1) /* divide polynomial p2 by p1 */
ubhat 0:69f2e28d12c1 249 {
ubhat 0:69f2e28d12c1 250 n2 /= n1; /* shift smaller polynomial left */
ubhat 0:69f2e28d12c1 251 p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */
ubhat 0:69f2e28d12c1 252 v2 ^= (v1 * n2); /* shift accumulated value and */
ubhat 0:69f2e28d12c1 253 n2 = hibit(p2); /* add into result */
ubhat 0:69f2e28d12c1 254 }
ubhat 0:69f2e28d12c1 255 else
ubhat 0:69f2e28d12c1 256 return v1;
ubhat 0:69f2e28d12c1 257
ubhat 0:69f2e28d12c1 258 if(n2) /* repeat with values swapped */
ubhat 0:69f2e28d12c1 259 while(n1 >= n2)
ubhat 0:69f2e28d12c1 260 {
ubhat 0:69f2e28d12c1 261 n1 /= n2;
ubhat 0:69f2e28d12c1 262 p1 ^= p2 * n1;
ubhat 0:69f2e28d12c1 263 v1 ^= v2 * n1;
ubhat 0:69f2e28d12c1 264 n1 = hibit(p1);
ubhat 0:69f2e28d12c1 265 }
ubhat 0:69f2e28d12c1 266 else
ubhat 0:69f2e28d12c1 267 return v2;
ubhat 0:69f2e28d12c1 268 }
ubhat 0:69f2e28d12c1 269 }
ubhat 0:69f2e28d12c1 270
ubhat 0:69f2e28d12c1 271 /* The forward and inverse affine transformations used in the S-box */
ubhat 0:69f2e28d12c1 272 uint8_t fwd_affine(const uint8_t x)
ubhat 0:69f2e28d12c1 273 {
ubhat 0:69f2e28d12c1 274 #if defined( HAVE_UINT_32T )
ubhat 0:69f2e28d12c1 275 uint32_t w = x;
ubhat 0:69f2e28d12c1 276 w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
ubhat 0:69f2e28d12c1 277 return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
ubhat 0:69f2e28d12c1 278 #else
ubhat 0:69f2e28d12c1 279 return 0x63 ^ x ^ (x << 1) ^ (x << 2) ^ (x << 3) ^ (x << 4)
ubhat 0:69f2e28d12c1 280 ^ (x >> 7) ^ (x >> 6) ^ (x >> 5) ^ (x >> 4);
ubhat 0:69f2e28d12c1 281 #endif
ubhat 0:69f2e28d12c1 282 }
ubhat 0:69f2e28d12c1 283
ubhat 0:69f2e28d12c1 284 uint8_t inv_affine(const uint8_t x)
ubhat 0:69f2e28d12c1 285 {
ubhat 0:69f2e28d12c1 286 #if defined( HAVE_UINT_32T )
ubhat 0:69f2e28d12c1 287 uint32_t w = x;
ubhat 0:69f2e28d12c1 288 w = (w << 1) ^ (w << 3) ^ (w << 6);
ubhat 0:69f2e28d12c1 289 return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
ubhat 0:69f2e28d12c1 290 #else
ubhat 0:69f2e28d12c1 291 return 0x05 ^ (x << 1) ^ (x << 3) ^ (x << 6)
ubhat 0:69f2e28d12c1 292 ^ (x >> 7) ^ (x >> 5) ^ (x >> 2);
ubhat 0:69f2e28d12c1 293 #endif
ubhat 0:69f2e28d12c1 294 }
ubhat 0:69f2e28d12c1 295
ubhat 0:69f2e28d12c1 296 #define s_box(x) fwd_affine(gf_inv(x))
ubhat 0:69f2e28d12c1 297 #define is_box(x) gf_inv(inv_affine(x))
ubhat 0:69f2e28d12c1 298 #define gfm2_sb(x) f2(s_box(x))
ubhat 0:69f2e28d12c1 299 #define gfm3_sb(x) f3(s_box(x))
ubhat 0:69f2e28d12c1 300 #define gfm_9(x) f9(x)
ubhat 0:69f2e28d12c1 301 #define gfm_b(x) fb(x)
ubhat 0:69f2e28d12c1 302 #define gfm_d(x) fd(x)
ubhat 0:69f2e28d12c1 303 #define gfm_e(x) fe(x)
ubhat 0:69f2e28d12c1 304
ubhat 0:69f2e28d12c1 305 #endif
ubhat 0:69f2e28d12c1 306
ubhat 0:69f2e28d12c1 307 #if defined( HAVE_MEMCPY )
ubhat 0:69f2e28d12c1 308 # define block_copy_nn(d, s, l) memcpy(d, s, l)
ubhat 0:69f2e28d12c1 309 # define block_copy(d, s) memcpy(d, s, N_BLOCK)
ubhat 0:69f2e28d12c1 310 #else
ubhat 0:69f2e28d12c1 311 # define block_copy_nn(d, s, l) copy_block_nn(d, s, l)
ubhat 0:69f2e28d12c1 312 # define block_copy(d, s) copy_block(d, s)
ubhat 0:69f2e28d12c1 313 #endif
ubhat 0:69f2e28d12c1 314
ubhat 0:69f2e28d12c1 315 static void copy_block( void *d, const void *s )
ubhat 0:69f2e28d12c1 316 {
ubhat 0:69f2e28d12c1 317 #if defined( HAVE_UINT_32T )
ubhat 0:69f2e28d12c1 318 ((uint32_t*)d)[ 0] = ((uint32_t*)s)[ 0];
ubhat 0:69f2e28d12c1 319 ((uint32_t*)d)[ 1] = ((uint32_t*)s)[ 1];
ubhat 0:69f2e28d12c1 320 ((uint32_t*)d)[ 2] = ((uint32_t*)s)[ 2];
ubhat 0:69f2e28d12c1 321 ((uint32_t*)d)[ 3] = ((uint32_t*)s)[ 3];
ubhat 0:69f2e28d12c1 322 #else
ubhat 0:69f2e28d12c1 323 ((uint8_t*)d)[ 0] = ((uint8_t*)s)[ 0];
ubhat 0:69f2e28d12c1 324 ((uint8_t*)d)[ 1] = ((uint8_t*)s)[ 1];
ubhat 0:69f2e28d12c1 325 ((uint8_t*)d)[ 2] = ((uint8_t*)s)[ 2];
ubhat 0:69f2e28d12c1 326 ((uint8_t*)d)[ 3] = ((uint8_t*)s)[ 3];
ubhat 0:69f2e28d12c1 327 ((uint8_t*)d)[ 4] = ((uint8_t*)s)[ 4];
ubhat 0:69f2e28d12c1 328 ((uint8_t*)d)[ 5] = ((uint8_t*)s)[ 5];
ubhat 0:69f2e28d12c1 329 ((uint8_t*)d)[ 6] = ((uint8_t*)s)[ 6];
ubhat 0:69f2e28d12c1 330 ((uint8_t*)d)[ 7] = ((uint8_t*)s)[ 7];
ubhat 0:69f2e28d12c1 331 ((uint8_t*)d)[ 8] = ((uint8_t*)s)[ 8];
ubhat 0:69f2e28d12c1 332 ((uint8_t*)d)[ 9] = ((uint8_t*)s)[ 9];
ubhat 0:69f2e28d12c1 333 ((uint8_t*)d)[10] = ((uint8_t*)s)[10];
ubhat 0:69f2e28d12c1 334 ((uint8_t*)d)[11] = ((uint8_t*)s)[11];
ubhat 0:69f2e28d12c1 335 ((uint8_t*)d)[12] = ((uint8_t*)s)[12];
ubhat 0:69f2e28d12c1 336 ((uint8_t*)d)[13] = ((uint8_t*)s)[13];
ubhat 0:69f2e28d12c1 337 ((uint8_t*)d)[14] = ((uint8_t*)s)[14];
ubhat 0:69f2e28d12c1 338 ((uint8_t*)d)[15] = ((uint8_t*)s)[15];
ubhat 0:69f2e28d12c1 339 #endif
ubhat 0:69f2e28d12c1 340 }
ubhat 0:69f2e28d12c1 341
ubhat 0:69f2e28d12c1 342 static void copy_block_nn( uint8_t * d, const uint8_t *s, uint8_t nn )
ubhat 0:69f2e28d12c1 343 {
ubhat 0:69f2e28d12c1 344 while( nn-- )
ubhat 0:69f2e28d12c1 345 //*((uint8_t*)d)++ = *((uint8_t*)s)++;
ubhat 0:69f2e28d12c1 346 *d++ = *s++;
ubhat 0:69f2e28d12c1 347 }
ubhat 0:69f2e28d12c1 348
ubhat 0:69f2e28d12c1 349 static void xor_block( void *d, const void *s )
ubhat 0:69f2e28d12c1 350 {
ubhat 0:69f2e28d12c1 351 #if defined( HAVE_UINT_32T )
ubhat 0:69f2e28d12c1 352 ((uint32_t*)d)[ 0] ^= ((uint32_t*)s)[ 0];
ubhat 0:69f2e28d12c1 353 ((uint32_t*)d)[ 1] ^= ((uint32_t*)s)[ 1];
ubhat 0:69f2e28d12c1 354 ((uint32_t*)d)[ 2] ^= ((uint32_t*)s)[ 2];
ubhat 0:69f2e28d12c1 355 ((uint32_t*)d)[ 3] ^= ((uint32_t*)s)[ 3];
ubhat 0:69f2e28d12c1 356 #else
ubhat 0:69f2e28d12c1 357 ((uint8_t*)d)[ 0] ^= ((uint8_t*)s)[ 0];
ubhat 0:69f2e28d12c1 358 ((uint8_t*)d)[ 1] ^= ((uint8_t*)s)[ 1];
ubhat 0:69f2e28d12c1 359 ((uint8_t*)d)[ 2] ^= ((uint8_t*)s)[ 2];
ubhat 0:69f2e28d12c1 360 ((uint8_t*)d)[ 3] ^= ((uint8_t*)s)[ 3];
ubhat 0:69f2e28d12c1 361 ((uint8_t*)d)[ 4] ^= ((uint8_t*)s)[ 4];
ubhat 0:69f2e28d12c1 362 ((uint8_t*)d)[ 5] ^= ((uint8_t*)s)[ 5];
ubhat 0:69f2e28d12c1 363 ((uint8_t*)d)[ 6] ^= ((uint8_t*)s)[ 6];
ubhat 0:69f2e28d12c1 364 ((uint8_t*)d)[ 7] ^= ((uint8_t*)s)[ 7];
ubhat 0:69f2e28d12c1 365 ((uint8_t*)d)[ 8] ^= ((uint8_t*)s)[ 8];
ubhat 0:69f2e28d12c1 366 ((uint8_t*)d)[ 9] ^= ((uint8_t*)s)[ 9];
ubhat 0:69f2e28d12c1 367 ((uint8_t*)d)[10] ^= ((uint8_t*)s)[10];
ubhat 0:69f2e28d12c1 368 ((uint8_t*)d)[11] ^= ((uint8_t*)s)[11];
ubhat 0:69f2e28d12c1 369 ((uint8_t*)d)[12] ^= ((uint8_t*)s)[12];
ubhat 0:69f2e28d12c1 370 ((uint8_t*)d)[13] ^= ((uint8_t*)s)[13];
ubhat 0:69f2e28d12c1 371 ((uint8_t*)d)[14] ^= ((uint8_t*)s)[14];
ubhat 0:69f2e28d12c1 372 ((uint8_t*)d)[15] ^= ((uint8_t*)s)[15];
ubhat 0:69f2e28d12c1 373 #endif
ubhat 0:69f2e28d12c1 374 }
ubhat 0:69f2e28d12c1 375
ubhat 0:69f2e28d12c1 376 static void copy_and_key( void *d, const void *s, const void *k )
ubhat 0:69f2e28d12c1 377 {
ubhat 0:69f2e28d12c1 378 #if defined( HAVE_UINT_32T )
ubhat 0:69f2e28d12c1 379 ((uint32_t*)d)[ 0] = ((uint32_t*)s)[ 0] ^ ((uint32_t*)k)[ 0];
ubhat 0:69f2e28d12c1 380 ((uint32_t*)d)[ 1] = ((uint32_t*)s)[ 1] ^ ((uint32_t*)k)[ 1];
ubhat 0:69f2e28d12c1 381 ((uint32_t*)d)[ 2] = ((uint32_t*)s)[ 2] ^ ((uint32_t*)k)[ 2];
ubhat 0:69f2e28d12c1 382 ((uint32_t*)d)[ 3] = ((uint32_t*)s)[ 3] ^ ((uint32_t*)k)[ 3];
ubhat 0:69f2e28d12c1 383 #elif 1
ubhat 0:69f2e28d12c1 384 ((uint8_t*)d)[ 0] = ((uint8_t*)s)[ 0] ^ ((uint8_t*)k)[ 0];
ubhat 0:69f2e28d12c1 385 ((uint8_t*)d)[ 1] = ((uint8_t*)s)[ 1] ^ ((uint8_t*)k)[ 1];
ubhat 0:69f2e28d12c1 386 ((uint8_t*)d)[ 2] = ((uint8_t*)s)[ 2] ^ ((uint8_t*)k)[ 2];
ubhat 0:69f2e28d12c1 387 ((uint8_t*)d)[ 3] = ((uint8_t*)s)[ 3] ^ ((uint8_t*)k)[ 3];
ubhat 0:69f2e28d12c1 388 ((uint8_t*)d)[ 4] = ((uint8_t*)s)[ 4] ^ ((uint8_t*)k)[ 4];
ubhat 0:69f2e28d12c1 389 ((uint8_t*)d)[ 5] = ((uint8_t*)s)[ 5] ^ ((uint8_t*)k)[ 5];
ubhat 0:69f2e28d12c1 390 ((uint8_t*)d)[ 6] = ((uint8_t*)s)[ 6] ^ ((uint8_t*)k)[ 6];
ubhat 0:69f2e28d12c1 391 ((uint8_t*)d)[ 7] = ((uint8_t*)s)[ 7] ^ ((uint8_t*)k)[ 7];
ubhat 0:69f2e28d12c1 392 ((uint8_t*)d)[ 8] = ((uint8_t*)s)[ 8] ^ ((uint8_t*)k)[ 8];
ubhat 0:69f2e28d12c1 393 ((uint8_t*)d)[ 9] = ((uint8_t*)s)[ 9] ^ ((uint8_t*)k)[ 9];
ubhat 0:69f2e28d12c1 394 ((uint8_t*)d)[10] = ((uint8_t*)s)[10] ^ ((uint8_t*)k)[10];
ubhat 0:69f2e28d12c1 395 ((uint8_t*)d)[11] = ((uint8_t*)s)[11] ^ ((uint8_t*)k)[11];
ubhat 0:69f2e28d12c1 396 ((uint8_t*)d)[12] = ((uint8_t*)s)[12] ^ ((uint8_t*)k)[12];
ubhat 0:69f2e28d12c1 397 ((uint8_t*)d)[13] = ((uint8_t*)s)[13] ^ ((uint8_t*)k)[13];
ubhat 0:69f2e28d12c1 398 ((uint8_t*)d)[14] = ((uint8_t*)s)[14] ^ ((uint8_t*)k)[14];
ubhat 0:69f2e28d12c1 399 ((uint8_t*)d)[15] = ((uint8_t*)s)[15] ^ ((uint8_t*)k)[15];
ubhat 0:69f2e28d12c1 400 #else
ubhat 0:69f2e28d12c1 401 block_copy(d, s);
ubhat 0:69f2e28d12c1 402 xor_block(d, k);
ubhat 0:69f2e28d12c1 403 #endif
ubhat 0:69f2e28d12c1 404 }
ubhat 0:69f2e28d12c1 405
ubhat 0:69f2e28d12c1 406 static void add_round_key( uint8_t d[N_BLOCK], const uint8_t k[N_BLOCK] )
ubhat 0:69f2e28d12c1 407 {
ubhat 0:69f2e28d12c1 408 xor_block(d, k);
ubhat 0:69f2e28d12c1 409 }
ubhat 0:69f2e28d12c1 410
ubhat 0:69f2e28d12c1 411 static void shift_sub_rows( uint8_t st[N_BLOCK] )
ubhat 0:69f2e28d12c1 412 { uint8_t tt;
ubhat 0:69f2e28d12c1 413
ubhat 0:69f2e28d12c1 414 st[ 0] = s_box(st[ 0]); st[ 4] = s_box(st[ 4]);
ubhat 0:69f2e28d12c1 415 st[ 8] = s_box(st[ 8]); st[12] = s_box(st[12]);
ubhat 0:69f2e28d12c1 416
ubhat 0:69f2e28d12c1 417 tt = st[1]; st[ 1] = s_box(st[ 5]); st[ 5] = s_box(st[ 9]);
ubhat 0:69f2e28d12c1 418 st[ 9] = s_box(st[13]); st[13] = s_box( tt );
ubhat 0:69f2e28d12c1 419
ubhat 0:69f2e28d12c1 420 tt = st[2]; st[ 2] = s_box(st[10]); st[10] = s_box( tt );
ubhat 0:69f2e28d12c1 421 tt = st[6]; st[ 6] = s_box(st[14]); st[14] = s_box( tt );
ubhat 0:69f2e28d12c1 422
ubhat 0:69f2e28d12c1 423 tt = st[15]; st[15] = s_box(st[11]); st[11] = s_box(st[ 7]);
ubhat 0:69f2e28d12c1 424 st[ 7] = s_box(st[ 3]); st[ 3] = s_box( tt );
ubhat 0:69f2e28d12c1 425 }
ubhat 0:69f2e28d12c1 426
ubhat 0:69f2e28d12c1 427 #if defined( AES_DEC_PREKEYED )
ubhat 0:69f2e28d12c1 428
ubhat 0:69f2e28d12c1 429 static void inv_shift_sub_rows( uint8_t st[N_BLOCK] )
ubhat 0:69f2e28d12c1 430 { uint8_t tt;
ubhat 0:69f2e28d12c1 431
ubhat 0:69f2e28d12c1 432 st[ 0] = is_box(st[ 0]); st[ 4] = is_box(st[ 4]);
ubhat 0:69f2e28d12c1 433 st[ 8] = is_box(st[ 8]); st[12] = is_box(st[12]);
ubhat 0:69f2e28d12c1 434
ubhat 0:69f2e28d12c1 435 tt = st[13]; st[13] = is_box(st[9]); st[ 9] = is_box(st[5]);
ubhat 0:69f2e28d12c1 436 st[ 5] = is_box(st[1]); st[ 1] = is_box( tt );
ubhat 0:69f2e28d12c1 437
ubhat 0:69f2e28d12c1 438 tt = st[2]; st[ 2] = is_box(st[10]); st[10] = is_box( tt );
ubhat 0:69f2e28d12c1 439 tt = st[6]; st[ 6] = is_box(st[14]); st[14] = is_box( tt );
ubhat 0:69f2e28d12c1 440
ubhat 0:69f2e28d12c1 441 tt = st[3]; st[ 3] = is_box(st[ 7]); st[ 7] = is_box(st[11]);
ubhat 0:69f2e28d12c1 442 st[11] = is_box(st[15]); st[15] = is_box( tt );
ubhat 0:69f2e28d12c1 443 }
ubhat 0:69f2e28d12c1 444
ubhat 0:69f2e28d12c1 445 #endif
ubhat 0:69f2e28d12c1 446
ubhat 0:69f2e28d12c1 447 #if defined( VERSION_1 )
ubhat 0:69f2e28d12c1 448 static void mix_sub_columns( uint8_t dt[N_BLOCK] )
ubhat 0:69f2e28d12c1 449 { uint8_t st[N_BLOCK];
ubhat 0:69f2e28d12c1 450 block_copy(st, dt);
ubhat 0:69f2e28d12c1 451 #else
ubhat 0:69f2e28d12c1 452 static void mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t st[N_BLOCK] )
ubhat 0:69f2e28d12c1 453 {
ubhat 0:69f2e28d12c1 454 #endif
ubhat 0:69f2e28d12c1 455 dt[ 0] = gfm2_sb(st[0]) ^ gfm3_sb(st[5]) ^ s_box(st[10]) ^ s_box(st[15]);
ubhat 0:69f2e28d12c1 456 dt[ 1] = s_box(st[0]) ^ gfm2_sb(st[5]) ^ gfm3_sb(st[10]) ^ s_box(st[15]);
ubhat 0:69f2e28d12c1 457 dt[ 2] = s_box(st[0]) ^ s_box(st[5]) ^ gfm2_sb(st[10]) ^ gfm3_sb(st[15]);
ubhat 0:69f2e28d12c1 458 dt[ 3] = gfm3_sb(st[0]) ^ s_box(st[5]) ^ s_box(st[10]) ^ gfm2_sb(st[15]);
ubhat 0:69f2e28d12c1 459
ubhat 0:69f2e28d12c1 460 dt[ 4] = gfm2_sb(st[4]) ^ gfm3_sb(st[9]) ^ s_box(st[14]) ^ s_box(st[3]);
ubhat 0:69f2e28d12c1 461 dt[ 5] = s_box(st[4]) ^ gfm2_sb(st[9]) ^ gfm3_sb(st[14]) ^ s_box(st[3]);
ubhat 0:69f2e28d12c1 462 dt[ 6] = s_box(st[4]) ^ s_box(st[9]) ^ gfm2_sb(st[14]) ^ gfm3_sb(st[3]);
ubhat 0:69f2e28d12c1 463 dt[ 7] = gfm3_sb(st[4]) ^ s_box(st[9]) ^ s_box(st[14]) ^ gfm2_sb(st[3]);
ubhat 0:69f2e28d12c1 464
ubhat 0:69f2e28d12c1 465 dt[ 8] = gfm2_sb(st[8]) ^ gfm3_sb(st[13]) ^ s_box(st[2]) ^ s_box(st[7]);
ubhat 0:69f2e28d12c1 466 dt[ 9] = s_box(st[8]) ^ gfm2_sb(st[13]) ^ gfm3_sb(st[2]) ^ s_box(st[7]);
ubhat 0:69f2e28d12c1 467 dt[10] = s_box(st[8]) ^ s_box(st[13]) ^ gfm2_sb(st[2]) ^ gfm3_sb(st[7]);
ubhat 0:69f2e28d12c1 468 dt[11] = gfm3_sb(st[8]) ^ s_box(st[13]) ^ s_box(st[2]) ^ gfm2_sb(st[7]);
ubhat 0:69f2e28d12c1 469
ubhat 0:69f2e28d12c1 470 dt[12] = gfm2_sb(st[12]) ^ gfm3_sb(st[1]) ^ s_box(st[6]) ^ s_box(st[11]);
ubhat 0:69f2e28d12c1 471 dt[13] = s_box(st[12]) ^ gfm2_sb(st[1]) ^ gfm3_sb(st[6]) ^ s_box(st[11]);
ubhat 0:69f2e28d12c1 472 dt[14] = s_box(st[12]) ^ s_box(st[1]) ^ gfm2_sb(st[6]) ^ gfm3_sb(st[11]);
ubhat 0:69f2e28d12c1 473 dt[15] = gfm3_sb(st[12]) ^ s_box(st[1]) ^ s_box(st[6]) ^ gfm2_sb(st[11]);
ubhat 0:69f2e28d12c1 474 }
ubhat 0:69f2e28d12c1 475
ubhat 0:69f2e28d12c1 476 #if defined( AES_DEC_PREKEYED )
ubhat 0:69f2e28d12c1 477
ubhat 0:69f2e28d12c1 478 #if defined( VERSION_1 )
ubhat 0:69f2e28d12c1 479 static void inv_mix_sub_columns( uint8_t dt[N_BLOCK] )
ubhat 0:69f2e28d12c1 480 { uint8_t st[N_BLOCK];
ubhat 0:69f2e28d12c1 481 block_copy(st, dt);
ubhat 0:69f2e28d12c1 482 #else
ubhat 0:69f2e28d12c1 483 static void inv_mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t st[N_BLOCK] )
ubhat 0:69f2e28d12c1 484 {
ubhat 0:69f2e28d12c1 485 #endif
ubhat 0:69f2e28d12c1 486 dt[ 0] = is_box(gfm_e(st[ 0]) ^ gfm_b(st[ 1]) ^ gfm_d(st[ 2]) ^ gfm_9(st[ 3]));
ubhat 0:69f2e28d12c1 487 dt[ 5] = is_box(gfm_9(st[ 0]) ^ gfm_e(st[ 1]) ^ gfm_b(st[ 2]) ^ gfm_d(st[ 3]));
ubhat 0:69f2e28d12c1 488 dt[10] = is_box(gfm_d(st[ 0]) ^ gfm_9(st[ 1]) ^ gfm_e(st[ 2]) ^ gfm_b(st[ 3]));
ubhat 0:69f2e28d12c1 489 dt[15] = is_box(gfm_b(st[ 0]) ^ gfm_d(st[ 1]) ^ gfm_9(st[ 2]) ^ gfm_e(st[ 3]));
ubhat 0:69f2e28d12c1 490
ubhat 0:69f2e28d12c1 491 dt[ 4] = is_box(gfm_e(st[ 4]) ^ gfm_b(st[ 5]) ^ gfm_d(st[ 6]) ^ gfm_9(st[ 7]));
ubhat 0:69f2e28d12c1 492 dt[ 9] = is_box(gfm_9(st[ 4]) ^ gfm_e(st[ 5]) ^ gfm_b(st[ 6]) ^ gfm_d(st[ 7]));
ubhat 0:69f2e28d12c1 493 dt[14] = is_box(gfm_d(st[ 4]) ^ gfm_9(st[ 5]) ^ gfm_e(st[ 6]) ^ gfm_b(st[ 7]));
ubhat 0:69f2e28d12c1 494 dt[ 3] = is_box(gfm_b(st[ 4]) ^ gfm_d(st[ 5]) ^ gfm_9(st[ 6]) ^ gfm_e(st[ 7]));
ubhat 0:69f2e28d12c1 495
ubhat 0:69f2e28d12c1 496 dt[ 8] = is_box(gfm_e(st[ 8]) ^ gfm_b(st[ 9]) ^ gfm_d(st[10]) ^ gfm_9(st[11]));
ubhat 0:69f2e28d12c1 497 dt[13] = is_box(gfm_9(st[ 8]) ^ gfm_e(st[ 9]) ^ gfm_b(st[10]) ^ gfm_d(st[11]));
ubhat 0:69f2e28d12c1 498 dt[ 2] = is_box(gfm_d(st[ 8]) ^ gfm_9(st[ 9]) ^ gfm_e(st[10]) ^ gfm_b(st[11]));
ubhat 0:69f2e28d12c1 499 dt[ 7] = is_box(gfm_b(st[ 8]) ^ gfm_d(st[ 9]) ^ gfm_9(st[10]) ^ gfm_e(st[11]));
ubhat 0:69f2e28d12c1 500
ubhat 0:69f2e28d12c1 501 dt[12] = is_box(gfm_e(st[12]) ^ gfm_b(st[13]) ^ gfm_d(st[14]) ^ gfm_9(st[15]));
ubhat 0:69f2e28d12c1 502 dt[ 1] = is_box(gfm_9(st[12]) ^ gfm_e(st[13]) ^ gfm_b(st[14]) ^ gfm_d(st[15]));
ubhat 0:69f2e28d12c1 503 dt[ 6] = is_box(gfm_d(st[12]) ^ gfm_9(st[13]) ^ gfm_e(st[14]) ^ gfm_b(st[15]));
ubhat 0:69f2e28d12c1 504 dt[11] = is_box(gfm_b(st[12]) ^ gfm_d(st[13]) ^ gfm_9(st[14]) ^ gfm_e(st[15]));
ubhat 0:69f2e28d12c1 505 }
ubhat 0:69f2e28d12c1 506
ubhat 0:69f2e28d12c1 507 #endif
ubhat 0:69f2e28d12c1 508
ubhat 0:69f2e28d12c1 509 #if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED )
ubhat 0:69f2e28d12c1 510
ubhat 0:69f2e28d12c1 511 /* Set the cipher key for the pre-keyed version */
ubhat 0:69f2e28d12c1 512
ubhat 0:69f2e28d12c1 513 return_type aes_set_key( const uint8_t key[], length_type keylen, aes_context ctx[1] )
ubhat 0:69f2e28d12c1 514 {
ubhat 0:69f2e28d12c1 515 uint8_t cc, rc, hi;
ubhat 0:69f2e28d12c1 516
ubhat 0:69f2e28d12c1 517 switch( keylen )
ubhat 0:69f2e28d12c1 518 {
ubhat 0:69f2e28d12c1 519 case 16:
ubhat 0:69f2e28d12c1 520 case 24:
ubhat 0:69f2e28d12c1 521 case 32:
ubhat 0:69f2e28d12c1 522 break;
ubhat 0:69f2e28d12c1 523 default:
ubhat 0:69f2e28d12c1 524 ctx->rnd = 0;
ubhat 0:69f2e28d12c1 525 return ( uint8_t )-1;
ubhat 0:69f2e28d12c1 526 }
ubhat 0:69f2e28d12c1 527 block_copy_nn(ctx->ksch, key, keylen);
ubhat 0:69f2e28d12c1 528 hi = (keylen + 28) << 2;
ubhat 0:69f2e28d12c1 529 ctx->rnd = (hi >> 4) - 1;
ubhat 0:69f2e28d12c1 530 for( cc = keylen, rc = 1; cc < hi; cc += 4 )
ubhat 0:69f2e28d12c1 531 { uint8_t tt, t0, t1, t2, t3;
ubhat 0:69f2e28d12c1 532
ubhat 0:69f2e28d12c1 533 t0 = ctx->ksch[cc - 4];
ubhat 0:69f2e28d12c1 534 t1 = ctx->ksch[cc - 3];
ubhat 0:69f2e28d12c1 535 t2 = ctx->ksch[cc - 2];
ubhat 0:69f2e28d12c1 536 t3 = ctx->ksch[cc - 1];
ubhat 0:69f2e28d12c1 537 if( cc % keylen == 0 )
ubhat 0:69f2e28d12c1 538 {
ubhat 0:69f2e28d12c1 539 tt = t0;
ubhat 0:69f2e28d12c1 540 t0 = s_box(t1) ^ rc;
ubhat 0:69f2e28d12c1 541 t1 = s_box(t2);
ubhat 0:69f2e28d12c1 542 t2 = s_box(t3);
ubhat 0:69f2e28d12c1 543 t3 = s_box(tt);
ubhat 0:69f2e28d12c1 544 rc = f2(rc);
ubhat 0:69f2e28d12c1 545 }
ubhat 0:69f2e28d12c1 546 else if( keylen > 24 && cc % keylen == 16 )
ubhat 0:69f2e28d12c1 547 {
ubhat 0:69f2e28d12c1 548 t0 = s_box(t0);
ubhat 0:69f2e28d12c1 549 t1 = s_box(t1);
ubhat 0:69f2e28d12c1 550 t2 = s_box(t2);
ubhat 0:69f2e28d12c1 551 t3 = s_box(t3);
ubhat 0:69f2e28d12c1 552 }
ubhat 0:69f2e28d12c1 553 tt = cc - keylen;
ubhat 0:69f2e28d12c1 554 ctx->ksch[cc + 0] = ctx->ksch[tt + 0] ^ t0;
ubhat 0:69f2e28d12c1 555 ctx->ksch[cc + 1] = ctx->ksch[tt + 1] ^ t1;
ubhat 0:69f2e28d12c1 556 ctx->ksch[cc + 2] = ctx->ksch[tt + 2] ^ t2;
ubhat 0:69f2e28d12c1 557 ctx->ksch[cc + 3] = ctx->ksch[tt + 3] ^ t3;
ubhat 0:69f2e28d12c1 558 }
ubhat 0:69f2e28d12c1 559 return 0;
ubhat 0:69f2e28d12c1 560 }
ubhat 0:69f2e28d12c1 561
ubhat 0:69f2e28d12c1 562 #endif
ubhat 0:69f2e28d12c1 563
ubhat 0:69f2e28d12c1 564 #if defined( AES_ENC_PREKEYED )
ubhat 0:69f2e28d12c1 565
ubhat 0:69f2e28d12c1 566 /* Encrypt a single block of 16 bytes */
ubhat 0:69f2e28d12c1 567
ubhat 0:69f2e28d12c1 568 return_type aes_encrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] )
ubhat 0:69f2e28d12c1 569 {
ubhat 0:69f2e28d12c1 570 if( ctx->rnd )
ubhat 0:69f2e28d12c1 571 {
ubhat 0:69f2e28d12c1 572 uint8_t s1[N_BLOCK], r;
ubhat 0:69f2e28d12c1 573 copy_and_key( s1, in, ctx->ksch );
ubhat 0:69f2e28d12c1 574
ubhat 0:69f2e28d12c1 575 for( r = 1 ; r < ctx->rnd ; ++r )
ubhat 0:69f2e28d12c1 576 #if defined( VERSION_1 )
ubhat 0:69f2e28d12c1 577 {
ubhat 0:69f2e28d12c1 578 mix_sub_columns( s1 );
ubhat 0:69f2e28d12c1 579 add_round_key( s1, ctx->ksch + r * N_BLOCK);
ubhat 0:69f2e28d12c1 580 }
ubhat 0:69f2e28d12c1 581 #else
ubhat 0:69f2e28d12c1 582 { uint8_t s2[N_BLOCK];
ubhat 0:69f2e28d12c1 583 mix_sub_columns( s2, s1 );
ubhat 0:69f2e28d12c1 584 copy_and_key( s1, s2, ctx->ksch + r * N_BLOCK);
ubhat 0:69f2e28d12c1 585 }
ubhat 0:69f2e28d12c1 586 #endif
ubhat 0:69f2e28d12c1 587 shift_sub_rows( s1 );
ubhat 0:69f2e28d12c1 588 copy_and_key( out, s1, ctx->ksch + r * N_BLOCK );
ubhat 0:69f2e28d12c1 589 }
ubhat 0:69f2e28d12c1 590 else
ubhat 0:69f2e28d12c1 591 return ( uint8_t )-1;
ubhat 0:69f2e28d12c1 592 return 0;
ubhat 0:69f2e28d12c1 593 }
ubhat 0:69f2e28d12c1 594
ubhat 0:69f2e28d12c1 595 /* CBC encrypt a number of blocks (input and return an IV) */
ubhat 0:69f2e28d12c1 596
ubhat 0:69f2e28d12c1 597 return_type aes_cbc_encrypt( const uint8_t *in, uint8_t *out,
ubhat 0:69f2e28d12c1 598 int32_t n_block, uint8_t iv[N_BLOCK], const aes_context ctx[1] )
ubhat 0:69f2e28d12c1 599 {
ubhat 0:69f2e28d12c1 600
ubhat 0:69f2e28d12c1 601 while(n_block--)
ubhat 0:69f2e28d12c1 602 {
ubhat 0:69f2e28d12c1 603 xor_block(iv, in);
ubhat 0:69f2e28d12c1 604 if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
ubhat 0:69f2e28d12c1 605 return EXIT_FAILURE;
ubhat 0:69f2e28d12c1 606 //memcpy(out, iv, N_BLOCK);
ubhat 0:69f2e28d12c1 607 block_copy(out, iv);
ubhat 0:69f2e28d12c1 608 in += N_BLOCK;
ubhat 0:69f2e28d12c1 609 out += N_BLOCK;
ubhat 0:69f2e28d12c1 610 }
ubhat 0:69f2e28d12c1 611 return EXIT_SUCCESS;
ubhat 0:69f2e28d12c1 612 }
ubhat 0:69f2e28d12c1 613
ubhat 0:69f2e28d12c1 614 #endif
ubhat 0:69f2e28d12c1 615
ubhat 0:69f2e28d12c1 616 #if defined( AES_DEC_PREKEYED )
ubhat 0:69f2e28d12c1 617
ubhat 0:69f2e28d12c1 618 /* Decrypt a single block of 16 bytes */
ubhat 0:69f2e28d12c1 619
ubhat 0:69f2e28d12c1 620 return_type aes_decrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] )
ubhat 0:69f2e28d12c1 621 {
ubhat 0:69f2e28d12c1 622 if( ctx->rnd )
ubhat 0:69f2e28d12c1 623 {
ubhat 0:69f2e28d12c1 624 uint8_t s1[N_BLOCK], r;
ubhat 0:69f2e28d12c1 625 copy_and_key( s1, in, ctx->ksch + ctx->rnd * N_BLOCK );
ubhat 0:69f2e28d12c1 626 inv_shift_sub_rows( s1 );
ubhat 0:69f2e28d12c1 627
ubhat 0:69f2e28d12c1 628 for( r = ctx->rnd ; --r ; )
ubhat 0:69f2e28d12c1 629 #if defined( VERSION_1 )
ubhat 0:69f2e28d12c1 630 {
ubhat 0:69f2e28d12c1 631 add_round_key( s1, ctx->ksch + r * N_BLOCK );
ubhat 0:69f2e28d12c1 632 inv_mix_sub_columns( s1 );
ubhat 0:69f2e28d12c1 633 }
ubhat 0:69f2e28d12c1 634 #else
ubhat 0:69f2e28d12c1 635 { uint8_t s2[N_BLOCK];
ubhat 0:69f2e28d12c1 636 copy_and_key( s2, s1, ctx->ksch + r * N_BLOCK );
ubhat 0:69f2e28d12c1 637 inv_mix_sub_columns( s1, s2 );
ubhat 0:69f2e28d12c1 638 }
ubhat 0:69f2e28d12c1 639 #endif
ubhat 0:69f2e28d12c1 640 copy_and_key( out, s1, ctx->ksch );
ubhat 0:69f2e28d12c1 641 }
ubhat 0:69f2e28d12c1 642 else
ubhat 0:69f2e28d12c1 643 return -1;
ubhat 0:69f2e28d12c1 644 return 0;
ubhat 0:69f2e28d12c1 645 }
ubhat 0:69f2e28d12c1 646
ubhat 0:69f2e28d12c1 647 /* CBC decrypt a number of blocks (input and return an IV) */
ubhat 0:69f2e28d12c1 648
ubhat 0:69f2e28d12c1 649 return_type aes_cbc_decrypt( const uint8_t *in, uint8_t *out,
ubhat 0:69f2e28d12c1 650 int32_t n_block, uint8_t iv[N_BLOCK], const aes_context ctx[1] )
ubhat 0:69f2e28d12c1 651 {
ubhat 0:69f2e28d12c1 652 while(n_block--)
ubhat 0:69f2e28d12c1 653 { uint8_t tmp[N_BLOCK];
ubhat 0:69f2e28d12c1 654
ubhat 0:69f2e28d12c1 655 //memcpy(tmp, in, N_BLOCK);
ubhat 0:69f2e28d12c1 656 block_copy(tmp, in);
ubhat 0:69f2e28d12c1 657 if(aes_decrypt(in, out, ctx) != EXIT_SUCCESS)
ubhat 0:69f2e28d12c1 658 return EXIT_FAILURE;
ubhat 0:69f2e28d12c1 659 xor_block(out, iv);
ubhat 0:69f2e28d12c1 660 //memcpy(iv, tmp, N_BLOCK);
ubhat 0:69f2e28d12c1 661 block_copy(iv, tmp);
ubhat 0:69f2e28d12c1 662 in += N_BLOCK;
ubhat 0:69f2e28d12c1 663 out += N_BLOCK;
ubhat 0:69f2e28d12c1 664 }
ubhat 0:69f2e28d12c1 665 return EXIT_SUCCESS;
ubhat 0:69f2e28d12c1 666 }
ubhat 0:69f2e28d12c1 667
ubhat 0:69f2e28d12c1 668 #endif
ubhat 0:69f2e28d12c1 669
ubhat 0:69f2e28d12c1 670 #if defined( AES_ENC_128_OTFK )
ubhat 0:69f2e28d12c1 671
ubhat 0:69f2e28d12c1 672 /* The 'on the fly' encryption key update for for 128 bit keys */
ubhat 0:69f2e28d12c1 673
ubhat 0:69f2e28d12c1 674 static void update_encrypt_key_128( uint8_t k[N_BLOCK], uint8_t *rc )
ubhat 0:69f2e28d12c1 675 { uint8_t cc;
ubhat 0:69f2e28d12c1 676
ubhat 0:69f2e28d12c1 677 k[0] ^= s_box(k[13]) ^ *rc;
ubhat 0:69f2e28d12c1 678 k[1] ^= s_box(k[14]);
ubhat 0:69f2e28d12c1 679 k[2] ^= s_box(k[15]);
ubhat 0:69f2e28d12c1 680 k[3] ^= s_box(k[12]);
ubhat 0:69f2e28d12c1 681 *rc = f2( *rc );
ubhat 0:69f2e28d12c1 682
ubhat 0:69f2e28d12c1 683 for(cc = 4; cc < 16; cc += 4 )
ubhat 0:69f2e28d12c1 684 {
ubhat 0:69f2e28d12c1 685 k[cc + 0] ^= k[cc - 4];
ubhat 0:69f2e28d12c1 686 k[cc + 1] ^= k[cc - 3];
ubhat 0:69f2e28d12c1 687 k[cc + 2] ^= k[cc - 2];
ubhat 0:69f2e28d12c1 688 k[cc + 3] ^= k[cc - 1];
ubhat 0:69f2e28d12c1 689 }
ubhat 0:69f2e28d12c1 690 }
ubhat 0:69f2e28d12c1 691
ubhat 0:69f2e28d12c1 692 /* Encrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
ubhat 0:69f2e28d12c1 693
ubhat 0:69f2e28d12c1 694 void aes_encrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
ubhat 0:69f2e28d12c1 695 const uint8_t key[N_BLOCK], uint8_t o_key[N_BLOCK] )
ubhat 0:69f2e28d12c1 696 { uint8_t s1[N_BLOCK], r, rc = 1;
ubhat 0:69f2e28d12c1 697
ubhat 0:69f2e28d12c1 698 if(o_key != key)
ubhat 0:69f2e28d12c1 699 block_copy( o_key, key );
ubhat 0:69f2e28d12c1 700 copy_and_key( s1, in, o_key );
ubhat 0:69f2e28d12c1 701
ubhat 0:69f2e28d12c1 702 for( r = 1 ; r < 10 ; ++r )
ubhat 0:69f2e28d12c1 703 #if defined( VERSION_1 )
ubhat 0:69f2e28d12c1 704 {
ubhat 0:69f2e28d12c1 705 mix_sub_columns( s1 );
ubhat 0:69f2e28d12c1 706 update_encrypt_key_128( o_key, &rc );
ubhat 0:69f2e28d12c1 707 add_round_key( s1, o_key );
ubhat 0:69f2e28d12c1 708 }
ubhat 0:69f2e28d12c1 709 #else
ubhat 0:69f2e28d12c1 710 { uint8_t s2[N_BLOCK];
ubhat 0:69f2e28d12c1 711 mix_sub_columns( s2, s1 );
ubhat 0:69f2e28d12c1 712 update_encrypt_key_128( o_key, &rc );
ubhat 0:69f2e28d12c1 713 copy_and_key( s1, s2, o_key );
ubhat 0:69f2e28d12c1 714 }
ubhat 0:69f2e28d12c1 715 #endif
ubhat 0:69f2e28d12c1 716
ubhat 0:69f2e28d12c1 717 shift_sub_rows( s1 );
ubhat 0:69f2e28d12c1 718 update_encrypt_key_128( o_key, &rc );
ubhat 0:69f2e28d12c1 719 copy_and_key( out, s1, o_key );
ubhat 0:69f2e28d12c1 720 }
ubhat 0:69f2e28d12c1 721
ubhat 0:69f2e28d12c1 722 #endif
ubhat 0:69f2e28d12c1 723
ubhat 0:69f2e28d12c1 724 #if defined( AES_DEC_128_OTFK )
ubhat 0:69f2e28d12c1 725
ubhat 0:69f2e28d12c1 726 /* The 'on the fly' decryption key update for for 128 bit keys */
ubhat 0:69f2e28d12c1 727
ubhat 0:69f2e28d12c1 728 static void update_decrypt_key_128( uint8_t k[N_BLOCK], uint8_t *rc )
ubhat 0:69f2e28d12c1 729 { uint8_t cc;
ubhat 0:69f2e28d12c1 730
ubhat 0:69f2e28d12c1 731 for( cc = 12; cc > 0; cc -= 4 )
ubhat 0:69f2e28d12c1 732 {
ubhat 0:69f2e28d12c1 733 k[cc + 0] ^= k[cc - 4];
ubhat 0:69f2e28d12c1 734 k[cc + 1] ^= k[cc - 3];
ubhat 0:69f2e28d12c1 735 k[cc + 2] ^= k[cc - 2];
ubhat 0:69f2e28d12c1 736 k[cc + 3] ^= k[cc - 1];
ubhat 0:69f2e28d12c1 737 }
ubhat 0:69f2e28d12c1 738 *rc = d2(*rc);
ubhat 0:69f2e28d12c1 739 k[0] ^= s_box(k[13]) ^ *rc;
ubhat 0:69f2e28d12c1 740 k[1] ^= s_box(k[14]);
ubhat 0:69f2e28d12c1 741 k[2] ^= s_box(k[15]);
ubhat 0:69f2e28d12c1 742 k[3] ^= s_box(k[12]);
ubhat 0:69f2e28d12c1 743 }
ubhat 0:69f2e28d12c1 744
ubhat 0:69f2e28d12c1 745 /* Decrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
ubhat 0:69f2e28d12c1 746
ubhat 0:69f2e28d12c1 747 void aes_decrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
ubhat 0:69f2e28d12c1 748 const uint8_t key[N_BLOCK], uint8_t o_key[N_BLOCK] )
ubhat 0:69f2e28d12c1 749 {
ubhat 0:69f2e28d12c1 750 uint8_t s1[N_BLOCK], r, rc = 0x6c;
ubhat 0:69f2e28d12c1 751 if(o_key != key)
ubhat 0:69f2e28d12c1 752 block_copy( o_key, key );
ubhat 0:69f2e28d12c1 753
ubhat 0:69f2e28d12c1 754 copy_and_key( s1, in, o_key );
ubhat 0:69f2e28d12c1 755 inv_shift_sub_rows( s1 );
ubhat 0:69f2e28d12c1 756
ubhat 0:69f2e28d12c1 757 for( r = 10 ; --r ; )
ubhat 0:69f2e28d12c1 758 #if defined( VERSION_1 )
ubhat 0:69f2e28d12c1 759 {
ubhat 0:69f2e28d12c1 760 update_decrypt_key_128( o_key, &rc );
ubhat 0:69f2e28d12c1 761 add_round_key( s1, o_key );
ubhat 0:69f2e28d12c1 762 inv_mix_sub_columns( s1 );
ubhat 0:69f2e28d12c1 763 }
ubhat 0:69f2e28d12c1 764 #else
ubhat 0:69f2e28d12c1 765 { uint8_t s2[N_BLOCK];
ubhat 0:69f2e28d12c1 766 update_decrypt_key_128( o_key, &rc );
ubhat 0:69f2e28d12c1 767 copy_and_key( s2, s1, o_key );
ubhat 0:69f2e28d12c1 768 inv_mix_sub_columns( s1, s2 );
ubhat 0:69f2e28d12c1 769 }
ubhat 0:69f2e28d12c1 770 #endif
ubhat 0:69f2e28d12c1 771 update_decrypt_key_128( o_key, &rc );
ubhat 0:69f2e28d12c1 772 copy_and_key( out, s1, o_key );
ubhat 0:69f2e28d12c1 773 }
ubhat 0:69f2e28d12c1 774
ubhat 0:69f2e28d12c1 775 #endif
ubhat 0:69f2e28d12c1 776
ubhat 0:69f2e28d12c1 777 #if defined( AES_ENC_256_OTFK )
ubhat 0:69f2e28d12c1 778
ubhat 0:69f2e28d12c1 779 /* The 'on the fly' encryption key update for for 256 bit keys */
ubhat 0:69f2e28d12c1 780
ubhat 0:69f2e28d12c1 781 static void update_encrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc )
ubhat 0:69f2e28d12c1 782 { uint8_t cc;
ubhat 0:69f2e28d12c1 783
ubhat 0:69f2e28d12c1 784 k[0] ^= s_box(k[29]) ^ *rc;
ubhat 0:69f2e28d12c1 785 k[1] ^= s_box(k[30]);
ubhat 0:69f2e28d12c1 786 k[2] ^= s_box(k[31]);
ubhat 0:69f2e28d12c1 787 k[3] ^= s_box(k[28]);
ubhat 0:69f2e28d12c1 788 *rc = f2( *rc );
ubhat 0:69f2e28d12c1 789
ubhat 0:69f2e28d12c1 790 for(cc = 4; cc < 16; cc += 4)
ubhat 0:69f2e28d12c1 791 {
ubhat 0:69f2e28d12c1 792 k[cc + 0] ^= k[cc - 4];
ubhat 0:69f2e28d12c1 793 k[cc + 1] ^= k[cc - 3];
ubhat 0:69f2e28d12c1 794 k[cc + 2] ^= k[cc - 2];
ubhat 0:69f2e28d12c1 795 k[cc + 3] ^= k[cc - 1];
ubhat 0:69f2e28d12c1 796 }
ubhat 0:69f2e28d12c1 797
ubhat 0:69f2e28d12c1 798 k[16] ^= s_box(k[12]);
ubhat 0:69f2e28d12c1 799 k[17] ^= s_box(k[13]);
ubhat 0:69f2e28d12c1 800 k[18] ^= s_box(k[14]);
ubhat 0:69f2e28d12c1 801 k[19] ^= s_box(k[15]);
ubhat 0:69f2e28d12c1 802
ubhat 0:69f2e28d12c1 803 for( cc = 20; cc < 32; cc += 4 )
ubhat 0:69f2e28d12c1 804 {
ubhat 0:69f2e28d12c1 805 k[cc + 0] ^= k[cc - 4];
ubhat 0:69f2e28d12c1 806 k[cc + 1] ^= k[cc - 3];
ubhat 0:69f2e28d12c1 807 k[cc + 2] ^= k[cc - 2];
ubhat 0:69f2e28d12c1 808 k[cc + 3] ^= k[cc - 1];
ubhat 0:69f2e28d12c1 809 }
ubhat 0:69f2e28d12c1 810 }
ubhat 0:69f2e28d12c1 811
ubhat 0:69f2e28d12c1 812 /* Encrypt a single block of 16 bytes with 'on the fly' 256 bit keying */
ubhat 0:69f2e28d12c1 813
ubhat 0:69f2e28d12c1 814 void aes_encrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
ubhat 0:69f2e28d12c1 815 const uint8_t key[2 * N_BLOCK], uint8_t o_key[2 * N_BLOCK] )
ubhat 0:69f2e28d12c1 816 {
ubhat 0:69f2e28d12c1 817 uint8_t s1[N_BLOCK], r, rc = 1;
ubhat 0:69f2e28d12c1 818 if(o_key != key)
ubhat 0:69f2e28d12c1 819 {
ubhat 0:69f2e28d12c1 820 block_copy( o_key, key );
ubhat 0:69f2e28d12c1 821 block_copy( o_key + 16, key + 16 );
ubhat 0:69f2e28d12c1 822 }
ubhat 0:69f2e28d12c1 823 copy_and_key( s1, in, o_key );
ubhat 0:69f2e28d12c1 824
ubhat 0:69f2e28d12c1 825 for( r = 1 ; r < 14 ; ++r )
ubhat 0:69f2e28d12c1 826 #if defined( VERSION_1 )
ubhat 0:69f2e28d12c1 827 {
ubhat 0:69f2e28d12c1 828 mix_sub_columns(s1);
ubhat 0:69f2e28d12c1 829 if( r & 1 )
ubhat 0:69f2e28d12c1 830 add_round_key( s1, o_key + 16 );
ubhat 0:69f2e28d12c1 831 else
ubhat 0:69f2e28d12c1 832 {
ubhat 0:69f2e28d12c1 833 update_encrypt_key_256( o_key, &rc );
ubhat 0:69f2e28d12c1 834 add_round_key( s1, o_key );
ubhat 0:69f2e28d12c1 835 }
ubhat 0:69f2e28d12c1 836 }
ubhat 0:69f2e28d12c1 837 #else
ubhat 0:69f2e28d12c1 838 { uint8_t s2[N_BLOCK];
ubhat 0:69f2e28d12c1 839 mix_sub_columns( s2, s1 );
ubhat 0:69f2e28d12c1 840 if( r & 1 )
ubhat 0:69f2e28d12c1 841 copy_and_key( s1, s2, o_key + 16 );
ubhat 0:69f2e28d12c1 842 else
ubhat 0:69f2e28d12c1 843 {
ubhat 0:69f2e28d12c1 844 update_encrypt_key_256( o_key, &rc );
ubhat 0:69f2e28d12c1 845 copy_and_key( s1, s2, o_key );
ubhat 0:69f2e28d12c1 846 }
ubhat 0:69f2e28d12c1 847 }
ubhat 0:69f2e28d12c1 848 #endif
ubhat 0:69f2e28d12c1 849
ubhat 0:69f2e28d12c1 850 shift_sub_rows( s1 );
ubhat 0:69f2e28d12c1 851 update_encrypt_key_256( o_key, &rc );
ubhat 0:69f2e28d12c1 852 copy_and_key( out, s1, o_key );
ubhat 0:69f2e28d12c1 853 }
ubhat 0:69f2e28d12c1 854
ubhat 0:69f2e28d12c1 855 #endif
ubhat 0:69f2e28d12c1 856
ubhat 0:69f2e28d12c1 857 #if defined( AES_DEC_256_OTFK )
ubhat 0:69f2e28d12c1 858
ubhat 0:69f2e28d12c1 859 /* The 'on the fly' encryption key update for for 256 bit keys */
ubhat 0:69f2e28d12c1 860
ubhat 0:69f2e28d12c1 861 static void update_decrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc )
ubhat 0:69f2e28d12c1 862 { uint8_t cc;
ubhat 0:69f2e28d12c1 863
ubhat 0:69f2e28d12c1 864 for(cc = 28; cc > 16; cc -= 4)
ubhat 0:69f2e28d12c1 865 {
ubhat 0:69f2e28d12c1 866 k[cc + 0] ^= k[cc - 4];
ubhat 0:69f2e28d12c1 867 k[cc + 1] ^= k[cc - 3];
ubhat 0:69f2e28d12c1 868 k[cc + 2] ^= k[cc - 2];
ubhat 0:69f2e28d12c1 869 k[cc + 3] ^= k[cc - 1];
ubhat 0:69f2e28d12c1 870 }
ubhat 0:69f2e28d12c1 871
ubhat 0:69f2e28d12c1 872 k[16] ^= s_box(k[12]);
ubhat 0:69f2e28d12c1 873 k[17] ^= s_box(k[13]);
ubhat 0:69f2e28d12c1 874 k[18] ^= s_box(k[14]);
ubhat 0:69f2e28d12c1 875 k[19] ^= s_box(k[15]);
ubhat 0:69f2e28d12c1 876
ubhat 0:69f2e28d12c1 877 for(cc = 12; cc > 0; cc -= 4)
ubhat 0:69f2e28d12c1 878 {
ubhat 0:69f2e28d12c1 879 k[cc + 0] ^= k[cc - 4];
ubhat 0:69f2e28d12c1 880 k[cc + 1] ^= k[cc - 3];
ubhat 0:69f2e28d12c1 881 k[cc + 2] ^= k[cc - 2];
ubhat 0:69f2e28d12c1 882 k[cc + 3] ^= k[cc - 1];
ubhat 0:69f2e28d12c1 883 }
ubhat 0:69f2e28d12c1 884
ubhat 0:69f2e28d12c1 885 *rc = d2(*rc);
ubhat 0:69f2e28d12c1 886 k[0] ^= s_box(k[29]) ^ *rc;
ubhat 0:69f2e28d12c1 887 k[1] ^= s_box(k[30]);
ubhat 0:69f2e28d12c1 888 k[2] ^= s_box(k[31]);
ubhat 0:69f2e28d12c1 889 k[3] ^= s_box(k[28]);
ubhat 0:69f2e28d12c1 890 }
ubhat 0:69f2e28d12c1 891
ubhat 0:69f2e28d12c1 892 /* Decrypt a single block of 16 bytes with 'on the fly'
ubhat 0:69f2e28d12c1 893 256 bit keying
ubhat 0:69f2e28d12c1 894 */
ubhat 0:69f2e28d12c1 895 void aes_decrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
ubhat 0:69f2e28d12c1 896 const uint8_t key[2 * N_BLOCK], uint8_t o_key[2 * N_BLOCK] )
ubhat 0:69f2e28d12c1 897 {
ubhat 0:69f2e28d12c1 898 uint8_t s1[N_BLOCK], r, rc = 0x80;
ubhat 0:69f2e28d12c1 899
ubhat 0:69f2e28d12c1 900 if(o_key != key)
ubhat 0:69f2e28d12c1 901 {
ubhat 0:69f2e28d12c1 902 block_copy( o_key, key );
ubhat 0:69f2e28d12c1 903 block_copy( o_key + 16, key + 16 );
ubhat 0:69f2e28d12c1 904 }
ubhat 0:69f2e28d12c1 905
ubhat 0:69f2e28d12c1 906 copy_and_key( s1, in, o_key );
ubhat 0:69f2e28d12c1 907 inv_shift_sub_rows( s1 );
ubhat 0:69f2e28d12c1 908
ubhat 0:69f2e28d12c1 909 for( r = 14 ; --r ; )
ubhat 0:69f2e28d12c1 910 #if defined( VERSION_1 )
ubhat 0:69f2e28d12c1 911 {
ubhat 0:69f2e28d12c1 912 if( ( r & 1 ) )
ubhat 0:69f2e28d12c1 913 {
ubhat 0:69f2e28d12c1 914 update_decrypt_key_256( o_key, &rc );
ubhat 0:69f2e28d12c1 915 add_round_key( s1, o_key + 16 );
ubhat 0:69f2e28d12c1 916 }
ubhat 0:69f2e28d12c1 917 else
ubhat 0:69f2e28d12c1 918 add_round_key( s1, o_key );
ubhat 0:69f2e28d12c1 919 inv_mix_sub_columns( s1 );
ubhat 0:69f2e28d12c1 920 }
ubhat 0:69f2e28d12c1 921 #else
ubhat 0:69f2e28d12c1 922 { uint8_t s2[N_BLOCK];
ubhat 0:69f2e28d12c1 923 if( ( r & 1 ) )
ubhat 0:69f2e28d12c1 924 {
ubhat 0:69f2e28d12c1 925 update_decrypt_key_256( o_key, &rc );
ubhat 0:69f2e28d12c1 926 copy_and_key( s2, s1, o_key + 16 );
ubhat 0:69f2e28d12c1 927 }
ubhat 0:69f2e28d12c1 928 else
ubhat 0:69f2e28d12c1 929 copy_and_key( s2, s1, o_key );
ubhat 0:69f2e28d12c1 930 inv_mix_sub_columns( s1, s2 );
ubhat 0:69f2e28d12c1 931 }
ubhat 0:69f2e28d12c1 932 #endif
ubhat 0:69f2e28d12c1 933 copy_and_key( out, s1, o_key );
ubhat 0:69f2e28d12c1 934 }
ubhat 0:69f2e28d12c1 935
ubhat 0:69f2e28d12c1 936 #endif