This library implements some hash and cryptographic algorithms.

Dependents:   mBuinoBlinky PB_Emma_Ethernet SLOTrashHTTP Garagem ... more

This library implements the following algorithms :

  • RC4
  • AES (AES-128, AES-192, AES-256)
  • DES
  • Triple DES (EDE)
  • MD2
  • MD4
  • MD5
  • SHA-1
  • SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512)

The hash algorithms have been optimized for the mbed and you should get decent performance. However, I did not optimize the ciphers. Also, I did not test extensively these algorithms : it should work but you may find some bugs. Block ciphers support two modes : ECB and CBC.

Warning

If you are using SHA-384 or SHA-512, be aware that it produces large binary files and the compilation (using the online compiler) takes much longer to execute. It may happen that the compiler stops because it timed-out. In this case, just compile again and it should work.

Computing hash

You can compute the hash of some data in two different ways. The first one is the easiest, each hash algorithm has a static method that takes some data and compute the hash from it.

Computing hash using method 1

#include "Crypto.h"
#include "mbed.h"

static const char msg[] = "mbed is great !";

int main()
{
    uint8_t hash[16];
    MD2::computeHash(hash, (uint8_t*)msg, strlen(msg));
    printf("hash: ");
    for(int i = 0; i < 16; ++i)
        printf("%02x", hash[i]);
    printf("\n");
    
    return 0;
}

The second one is slightly slower (around 2-3% slower) but it allows you to compute the hash of some data in several steps (by calling update method). This is the method you should use if you need to compute the hash from a large source and you don't have enough memory to store it in a single buffer.

Computing hash using method 2

#include "Crypto.h"
#include "mbed.h"

static const char msg[] = "mbed is great !";

int main()
{
    uint8_t hash[16];
    MD2 h;
    h.update((uint8_t*)msg, strlen(msg));
    h.finalize(hash);
    printf("hash: ");
    for(int i = 0; i < 16; ++i)
        printf("%02x", hash[i]);
    printf("\n");
    
    return 0;
}

TODO

  • optimize ciphers
  • add doc
Committer:
feb11
Date:
Sun May 11 13:36:45 2014 +0000
Revision:
14:f04410cef037
Parent:
8:a090264e9b2d
CBC mode completed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
feb11 0:7a1237bd2d13 1 #include "AES.h"
feb11 0:7a1237bd2d13 2 #include <string.h>
feb11 0:7a1237bd2d13 3 #include <stdio.h>
feb11 0:7a1237bd2d13 4 #include <stdlib.h>
feb11 0:7a1237bd2d13 5
feb11 0:7a1237bd2d13 6 static const uint8_t sbox[] =
feb11 0:7a1237bd2d13 7 {
feb11 0:7a1237bd2d13 8 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
feb11 0:7a1237bd2d13 9 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
feb11 0:7a1237bd2d13 10 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
feb11 0:7a1237bd2d13 11 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
feb11 0:7a1237bd2d13 12 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
feb11 0:7a1237bd2d13 13 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
feb11 0:7a1237bd2d13 14 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
feb11 0:7a1237bd2d13 15 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
feb11 0:7a1237bd2d13 16 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
feb11 0:7a1237bd2d13 17 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
feb11 0:7a1237bd2d13 18 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
feb11 0:7a1237bd2d13 19 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
feb11 0:7a1237bd2d13 20 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
feb11 0:7a1237bd2d13 21 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
feb11 0:7a1237bd2d13 22 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
feb11 0:7a1237bd2d13 23 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
feb11 0:7a1237bd2d13 24 };
feb11 0:7a1237bd2d13 25
feb11 0:7a1237bd2d13 26 static const uint8_t inv_s[] =
feb11 0:7a1237bd2d13 27 {
feb11 0:7a1237bd2d13 28 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
feb11 0:7a1237bd2d13 29 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
feb11 0:7a1237bd2d13 30 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
feb11 0:7a1237bd2d13 31 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
feb11 0:7a1237bd2d13 32 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
feb11 0:7a1237bd2d13 33 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
feb11 0:7a1237bd2d13 34 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
feb11 0:7a1237bd2d13 35 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
feb11 0:7a1237bd2d13 36 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
feb11 0:7a1237bd2d13 37 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
feb11 0:7a1237bd2d13 38 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
feb11 0:7a1237bd2d13 39 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
feb11 0:7a1237bd2d13 40 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
feb11 0:7a1237bd2d13 41 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
feb11 0:7a1237bd2d13 42 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
feb11 0:7a1237bd2d13 43 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
feb11 0:7a1237bd2d13 44 };
feb11 0:7a1237bd2d13 45
feb11 0:7a1237bd2d13 46
feb11 0:7a1237bd2d13 47 static const uint32_t rcon[10]=
feb11 0:7a1237bd2d13 48 {
feb11 0:7a1237bd2d13 49 0x01000000, 0x02000000, 0x04000000, 0x08000000,
feb11 0:7a1237bd2d13 50 0x10000000, 0x20000000, 0x40000000, 0x80000000,
feb11 0:7a1237bd2d13 51 0x1B000000, 0x36000000
feb11 0:7a1237bd2d13 52 };
feb11 0:7a1237bd2d13 53
feb11 0:7a1237bd2d13 54 AES::AES(const AES_TYPE t, uint8_t *key):
feb11 8:a090264e9b2d 55 BlockCipher(16,ECB_MODE),
feb11 8:a090264e9b2d 56 state()
feb11 8:a090264e9b2d 57 {
feb11 8:a090264e9b2d 58 switch(t)
feb11 8:a090264e9b2d 59 {
feb11 8:a090264e9b2d 60 case AES_128:
feb11 8:a090264e9b2d 61 nr = 10;
feb11 8:a090264e9b2d 62 nk = 4;
feb11 8:a090264e9b2d 63 break;
feb11 8:a090264e9b2d 64
feb11 8:a090264e9b2d 65 case AES_192:
feb11 8:a090264e9b2d 66 nr = 12;
feb11 8:a090264e9b2d 67 nk = 6;
feb11 8:a090264e9b2d 68 break;
feb11 8:a090264e9b2d 69
feb11 8:a090264e9b2d 70 case AES_256:
feb11 8:a090264e9b2d 71 nr = 14;
feb11 8:a090264e9b2d 72 nk = 8;
feb11 8:a090264e9b2d 73 break;
feb11 8:a090264e9b2d 74 }
feb11 8:a090264e9b2d 75
feb11 8:a090264e9b2d 76 keyExpansion(key);
feb11 8:a090264e9b2d 77 }
feb11 8:a090264e9b2d 78
feb11 8:a090264e9b2d 79 AES::AES(const AES_TYPE t, uint8_t *key, uint8_t *iv):
feb11 8:a090264e9b2d 80 BlockCipher(16,CBC_MODE, iv),
feb11 0:7a1237bd2d13 81 state()
feb11 0:7a1237bd2d13 82 {
feb11 0:7a1237bd2d13 83 switch(t)
feb11 0:7a1237bd2d13 84 {
feb11 0:7a1237bd2d13 85 case AES_128:
feb11 0:7a1237bd2d13 86 nr = 10;
feb11 0:7a1237bd2d13 87 nk = 4;
feb11 0:7a1237bd2d13 88 break;
feb11 0:7a1237bd2d13 89
feb11 0:7a1237bd2d13 90 case AES_192:
feb11 0:7a1237bd2d13 91 nr = 12;
feb11 0:7a1237bd2d13 92 nk = 6;
feb11 0:7a1237bd2d13 93 break;
feb11 0:7a1237bd2d13 94
feb11 0:7a1237bd2d13 95 case AES_256:
feb11 0:7a1237bd2d13 96 nr = 14;
feb11 0:7a1237bd2d13 97 nk = 8;
feb11 0:7a1237bd2d13 98 break;
feb11 0:7a1237bd2d13 99 }
feb11 0:7a1237bd2d13 100
feb11 0:7a1237bd2d13 101 keyExpansion(key);
feb11 0:7a1237bd2d13 102 }
feb11 0:7a1237bd2d13 103
feb11 0:7a1237bd2d13 104 void AES::keyExpansion(uint8_t *key)
feb11 0:7a1237bd2d13 105 {
feb11 0:7a1237bd2d13 106 uint32_t temp;
feb11 0:7a1237bd2d13 107 int i = 0;
feb11 0:7a1237bd2d13 108
feb11 0:7a1237bd2d13 109 while(i < nk)
feb11 0:7a1237bd2d13 110 {
feb11 0:7a1237bd2d13 111 w[i] = (key[4*i] << 24) + (key[4*i+1] << 16) + (key[4*i+2] << 8) + key[4*i+3];
feb11 0:7a1237bd2d13 112 i++;
feb11 0:7a1237bd2d13 113 }
feb11 0:7a1237bd2d13 114 i = nk;
feb11 0:7a1237bd2d13 115 while(i < 4*(nr+1))
feb11 0:7a1237bd2d13 116 {
feb11 0:7a1237bd2d13 117 temp = w[i-1];
feb11 0:7a1237bd2d13 118 if(i % nk == 0)
feb11 0:7a1237bd2d13 119 {
feb11 0:7a1237bd2d13 120 temp = rotWord(temp);
feb11 0:7a1237bd2d13 121 temp = subWord(temp);
feb11 0:7a1237bd2d13 122 temp ^= rcon[i/nk-1];
feb11 0:7a1237bd2d13 123 }
feb11 0:7a1237bd2d13 124 else if(nk > 6 && i % nk == 4)
feb11 0:7a1237bd2d13 125 temp = subWord(temp);
feb11 0:7a1237bd2d13 126 w[i] = w[i-nk] ^ temp;
feb11 0:7a1237bd2d13 127 i++;
feb11 0:7a1237bd2d13 128 }
feb11 0:7a1237bd2d13 129 }
feb11 0:7a1237bd2d13 130
feb11 0:7a1237bd2d13 131 uint32_t AES::rotWord(uint32_t w)
feb11 0:7a1237bd2d13 132 {
feb11 0:7a1237bd2d13 133 return (w << 8) + (w >> 24);
feb11 0:7a1237bd2d13 134 }
feb11 0:7a1237bd2d13 135
feb11 0:7a1237bd2d13 136 uint32_t AES::invRotWord(uint32_t w)
feb11 0:7a1237bd2d13 137 {
feb11 0:7a1237bd2d13 138 return (w >> 8) + (w << 24);
feb11 0:7a1237bd2d13 139 }
feb11 0:7a1237bd2d13 140
feb11 0:7a1237bd2d13 141 uint32_t AES::subWord(uint32_t w)
feb11 0:7a1237bd2d13 142 {
feb11 0:7a1237bd2d13 143 uint32_t out = 0;
feb11 0:7a1237bd2d13 144 for(int i = 0; i < 4; ++i)
feb11 0:7a1237bd2d13 145 {
feb11 0:7a1237bd2d13 146 uint8_t temp = (w & 0xFF);
feb11 0:7a1237bd2d13 147 out |= (sbox[temp] << (8*i));
feb11 0:7a1237bd2d13 148 w = (w >> 8);
feb11 0:7a1237bd2d13 149 }
feb11 0:7a1237bd2d13 150 return out;
feb11 0:7a1237bd2d13 151 }
feb11 0:7a1237bd2d13 152
feb11 0:7a1237bd2d13 153 void AES::subBytes()
feb11 0:7a1237bd2d13 154 {
feb11 0:7a1237bd2d13 155 for(int i = 0; i < 16; ++i)
feb11 0:7a1237bd2d13 156 state[i] = sbox[state[i]];
feb11 0:7a1237bd2d13 157 }
feb11 0:7a1237bd2d13 158
feb11 0:7a1237bd2d13 159 void AES::invSubBytes()
feb11 0:7a1237bd2d13 160 {
feb11 0:7a1237bd2d13 161 for(int i = 0; i < 16; ++i)
feb11 0:7a1237bd2d13 162 state[i] = inv_s[state[i]];
feb11 0:7a1237bd2d13 163 }
feb11 0:7a1237bd2d13 164
feb11 0:7a1237bd2d13 165 void AES::shiftRows()
feb11 0:7a1237bd2d13 166 {
feb11 0:7a1237bd2d13 167 for(int r = 0; r < 4; ++r)
feb11 0:7a1237bd2d13 168 {
feb11 0:7a1237bd2d13 169 uint32_t temp = (state[r] << 24) + (state[r+4] << 16) + (state[r+8] << 8) + state[r+12];
feb11 0:7a1237bd2d13 170 int i = r;
feb11 0:7a1237bd2d13 171 while(i > 0)
feb11 0:7a1237bd2d13 172 {
feb11 0:7a1237bd2d13 173 temp = rotWord(temp);
feb11 0:7a1237bd2d13 174 --i;
feb11 0:7a1237bd2d13 175 }
feb11 0:7a1237bd2d13 176 state[r] = temp >> 24;
feb11 2:473bac39ae7c 177 state[r+4] = temp >> 16;
feb11 2:473bac39ae7c 178 state[r+8] = temp >> 8;
feb11 2:473bac39ae7c 179 state[r+12] = temp;
feb11 0:7a1237bd2d13 180 }
feb11 0:7a1237bd2d13 181 }
feb11 0:7a1237bd2d13 182
feb11 0:7a1237bd2d13 183 void AES::invShiftRows()
feb11 0:7a1237bd2d13 184 {
feb11 0:7a1237bd2d13 185 for(int r = 0; r < 4; ++r)
feb11 0:7a1237bd2d13 186 {
feb11 0:7a1237bd2d13 187 uint32_t temp = (state[r] << 24) + (state[r+4] << 16) + (state[r+8] << 8) + state[r+12];
feb11 0:7a1237bd2d13 188 int i = r;
feb11 0:7a1237bd2d13 189 while(i > 0)
feb11 0:7a1237bd2d13 190 {
feb11 0:7a1237bd2d13 191 temp = invRotWord(temp);
feb11 0:7a1237bd2d13 192 --i;
feb11 0:7a1237bd2d13 193 }
feb11 0:7a1237bd2d13 194 state[r] = temp >> 24;
feb11 2:473bac39ae7c 195 state[r+4] = temp >> 16;
feb11 2:473bac39ae7c 196 state[r+8] = temp >> 8;
feb11 2:473bac39ae7c 197 state[r+12] = temp;
feb11 0:7a1237bd2d13 198 }
feb11 0:7a1237bd2d13 199 }
feb11 0:7a1237bd2d13 200
feb11 0:7a1237bd2d13 201 /* Multiply two numbers in the GF(2^8) finite field defined
feb11 0:7a1237bd2d13 202 * by the polynomial x^8 + x^4 + x^3 + x + 1 */
feb11 0:7a1237bd2d13 203 uint8_t gmul(uint8_t a, uint8_t b)
feb11 0:7a1237bd2d13 204 {
feb11 0:7a1237bd2d13 205 uint8_t p = 0;
feb11 0:7a1237bd2d13 206 uint8_t counter;
feb11 0:7a1237bd2d13 207 uint8_t carry;
feb11 0:7a1237bd2d13 208 for (counter = 0; counter < 8; counter++) {
feb11 0:7a1237bd2d13 209 if (b & 1)
feb11 0:7a1237bd2d13 210 p ^= a;
feb11 0:7a1237bd2d13 211 carry = (a & 0x80);
feb11 0:7a1237bd2d13 212 a <<= 1;
feb11 0:7a1237bd2d13 213 if (carry)
feb11 0:7a1237bd2d13 214 a ^= 0x001B; /* what x^8 is modulo x^8 + x^4 + x^3 + x^2 + 1 */
feb11 0:7a1237bd2d13 215 b >>= 1;
feb11 0:7a1237bd2d13 216 }
feb11 0:7a1237bd2d13 217 return p;
feb11 0:7a1237bd2d13 218 }
feb11 0:7a1237bd2d13 219
feb11 0:7a1237bd2d13 220 void AES::mul(uint8_t *r)
feb11 0:7a1237bd2d13 221 {
feb11 0:7a1237bd2d13 222 uint8_t tmp[4];
feb11 0:7a1237bd2d13 223 memcpy(tmp, r, 4);
feb11 0:7a1237bd2d13 224 r[0] = gmul(tmp[0],2) ^ gmul(tmp[1],3) ^ tmp[2] ^ tmp[3];
feb11 0:7a1237bd2d13 225 r[1] = tmp[0] ^ gmul(tmp[1],2) ^ gmul(tmp[2],3) ^ tmp[3];
feb11 0:7a1237bd2d13 226 r[2] = tmp[0] ^ tmp[1] ^ gmul(tmp[2],2) ^ gmul(tmp[3],3);
feb11 0:7a1237bd2d13 227 r[3] = gmul(tmp[0],3) ^ tmp[1] ^ tmp[2] ^ gmul(tmp[3],2);
feb11 0:7a1237bd2d13 228 }
feb11 0:7a1237bd2d13 229
feb11 0:7a1237bd2d13 230 void AES::invMul(uint8_t *r)
feb11 0:7a1237bd2d13 231 {
feb11 0:7a1237bd2d13 232 uint8_t tmp[4];
feb11 0:7a1237bd2d13 233 memcpy(tmp, r, 4);
feb11 0:7a1237bd2d13 234 r[0] = gmul(tmp[0],0x0e) ^ gmul(tmp[1],0x0b) ^ gmul(tmp[2],0x0d) ^ gmul(tmp[3],9);
feb11 0:7a1237bd2d13 235 r[1] = gmul(tmp[0],9) ^ gmul(tmp[1],0x0e) ^ gmul(tmp[2],0x0b) ^ gmul(tmp[3],0x0d);
feb11 0:7a1237bd2d13 236 r[2] = gmul(tmp[0],0x0d) ^ gmul(tmp[1],9) ^ gmul(tmp[2],0x0e) ^ gmul(tmp[3],0x0b);
feb11 0:7a1237bd2d13 237 r[3] = gmul(tmp[0],0x0b) ^ gmul(tmp[1],0x0d) ^ gmul(tmp[2],9) ^ gmul(tmp[3],0x0e);
feb11 0:7a1237bd2d13 238 }
feb11 0:7a1237bd2d13 239
feb11 0:7a1237bd2d13 240 void AES::mixColumns()
feb11 0:7a1237bd2d13 241 {
feb11 0:7a1237bd2d13 242 for(int c = 0; c < 4; ++c)
feb11 0:7a1237bd2d13 243 mul(&state[4*c]);
feb11 0:7a1237bd2d13 244 }
feb11 0:7a1237bd2d13 245
feb11 0:7a1237bd2d13 246 void AES::invMixColumns()
feb11 0:7a1237bd2d13 247 {
feb11 0:7a1237bd2d13 248 for(int c = 0; c < 4; ++c)
feb11 0:7a1237bd2d13 249 invMul(&state[4*c]);
feb11 0:7a1237bd2d13 250 }
feb11 0:7a1237bd2d13 251
feb11 0:7a1237bd2d13 252 void AES::addRoundKey(int round)
feb11 0:7a1237bd2d13 253 {
feb11 0:7a1237bd2d13 254 for(int c = 0; c < 4; ++c)
feb11 0:7a1237bd2d13 255 {
feb11 0:7a1237bd2d13 256 uint32_t temp = (state[4*c] << 24) + (state[4*c+1] << 16) + (state[4*c+2] << 8) + state[4*c+3];
feb11 0:7a1237bd2d13 257 temp ^= w[round*4+c];
feb11 2:473bac39ae7c 258 state[4*c] = temp >> 24;
feb11 2:473bac39ae7c 259 state[4*c+1] = temp >> 16;
feb11 2:473bac39ae7c 260 state[4*c+2] = temp >> 8;
feb11 2:473bac39ae7c 261 state[4*c+3] = temp;
feb11 0:7a1237bd2d13 262 }
feb11 0:7a1237bd2d13 263 }
feb11 0:7a1237bd2d13 264
feb11 0:7a1237bd2d13 265 void AES::decryptBlock(uint8_t *out, uint8_t *in)
feb11 0:7a1237bd2d13 266 {
feb11 0:7a1237bd2d13 267 memcpy(state,in,16);
feb11 0:7a1237bd2d13 268
feb11 0:7a1237bd2d13 269 addRoundKey(nr);
feb11 0:7a1237bd2d13 270
feb11 0:7a1237bd2d13 271 for(int round = nr-1; round > 0; --round)
feb11 0:7a1237bd2d13 272 {
feb11 0:7a1237bd2d13 273 invShiftRows();
feb11 0:7a1237bd2d13 274 invSubBytes();
feb11 0:7a1237bd2d13 275 addRoundKey(round);
feb11 0:7a1237bd2d13 276 invMixColumns();
feb11 0:7a1237bd2d13 277 }
feb11 0:7a1237bd2d13 278 invShiftRows();
feb11 0:7a1237bd2d13 279 invSubBytes();
feb11 0:7a1237bd2d13 280 addRoundKey(0);
feb11 0:7a1237bd2d13 281
feb11 0:7a1237bd2d13 282 memcpy(out, state, 16);
feb11 0:7a1237bd2d13 283 }
feb11 0:7a1237bd2d13 284
feb11 0:7a1237bd2d13 285 void AES::encryptBlock(uint8_t *out, uint8_t *in)
feb11 0:7a1237bd2d13 286 {
feb11 0:7a1237bd2d13 287 memcpy(state,in,16);
feb11 0:7a1237bd2d13 288
feb11 0:7a1237bd2d13 289 addRoundKey(0);
feb11 0:7a1237bd2d13 290
feb11 0:7a1237bd2d13 291 for(int round = 1; round < nr; ++round)
feb11 0:7a1237bd2d13 292 {
feb11 0:7a1237bd2d13 293 subBytes();
feb11 0:7a1237bd2d13 294 shiftRows();
feb11 0:7a1237bd2d13 295 mixColumns();
feb11 0:7a1237bd2d13 296 addRoundKey(round);
feb11 0:7a1237bd2d13 297 }
feb11 0:7a1237bd2d13 298 subBytes();
feb11 0:7a1237bd2d13 299 shiftRows();
feb11 0:7a1237bd2d13 300 addRoundKey(nr);
feb11 0:7a1237bd2d13 301
feb11 0:7a1237bd2d13 302 memcpy(out, state, 16);
feb11 0:7a1237bd2d13 303 }