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:
Mon Sep 09 16:16:24 2013 +0000
Revision:
2:473bac39ae7c
Parent:
0:7a1237bd2d13
improved performance of MD2

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 0:7a1237bd2d13 55 state()
feb11 0:7a1237bd2d13 56 {
feb11 0:7a1237bd2d13 57 switch(t)
feb11 0:7a1237bd2d13 58 {
feb11 0:7a1237bd2d13 59 case AES_128:
feb11 0:7a1237bd2d13 60 nr = 10;
feb11 0:7a1237bd2d13 61 nk = 4;
feb11 0:7a1237bd2d13 62 break;
feb11 0:7a1237bd2d13 63
feb11 0:7a1237bd2d13 64 case AES_192:
feb11 0:7a1237bd2d13 65 nr = 12;
feb11 0:7a1237bd2d13 66 nk = 6;
feb11 0:7a1237bd2d13 67 break;
feb11 0:7a1237bd2d13 68
feb11 0:7a1237bd2d13 69 case AES_256:
feb11 0:7a1237bd2d13 70 nr = 14;
feb11 0:7a1237bd2d13 71 nk = 8;
feb11 0:7a1237bd2d13 72 break;
feb11 0:7a1237bd2d13 73 }
feb11 0:7a1237bd2d13 74
feb11 0:7a1237bd2d13 75 keyExpansion(key);
feb11 0:7a1237bd2d13 76 }
feb11 0:7a1237bd2d13 77
feb11 0:7a1237bd2d13 78 void AES::keyExpansion(uint8_t *key)
feb11 0:7a1237bd2d13 79 {
feb11 0:7a1237bd2d13 80 uint32_t temp;
feb11 0:7a1237bd2d13 81 int i = 0;
feb11 0:7a1237bd2d13 82
feb11 0:7a1237bd2d13 83 while(i < nk)
feb11 0:7a1237bd2d13 84 {
feb11 0:7a1237bd2d13 85 w[i] = (key[4*i] << 24) + (key[4*i+1] << 16) + (key[4*i+2] << 8) + key[4*i+3];
feb11 0:7a1237bd2d13 86 i++;
feb11 0:7a1237bd2d13 87 }
feb11 0:7a1237bd2d13 88 i = nk;
feb11 0:7a1237bd2d13 89 while(i < 4*(nr+1))
feb11 0:7a1237bd2d13 90 {
feb11 0:7a1237bd2d13 91 temp = w[i-1];
feb11 0:7a1237bd2d13 92 if(i % nk == 0)
feb11 0:7a1237bd2d13 93 {
feb11 0:7a1237bd2d13 94 temp = rotWord(temp);
feb11 0:7a1237bd2d13 95 temp = subWord(temp);
feb11 0:7a1237bd2d13 96 temp ^= rcon[i/nk-1];
feb11 0:7a1237bd2d13 97 }
feb11 0:7a1237bd2d13 98 else if(nk > 6 && i % nk == 4)
feb11 0:7a1237bd2d13 99 temp = subWord(temp);
feb11 0:7a1237bd2d13 100 w[i] = w[i-nk] ^ temp;
feb11 0:7a1237bd2d13 101 i++;
feb11 0:7a1237bd2d13 102 }
feb11 0:7a1237bd2d13 103 }
feb11 0:7a1237bd2d13 104
feb11 0:7a1237bd2d13 105 uint32_t AES::rotWord(uint32_t w)
feb11 0:7a1237bd2d13 106 {
feb11 0:7a1237bd2d13 107 return (w << 8) + (w >> 24);
feb11 0:7a1237bd2d13 108 }
feb11 0:7a1237bd2d13 109
feb11 0:7a1237bd2d13 110 uint32_t AES::invRotWord(uint32_t w)
feb11 0:7a1237bd2d13 111 {
feb11 0:7a1237bd2d13 112 return (w >> 8) + (w << 24);
feb11 0:7a1237bd2d13 113 }
feb11 0:7a1237bd2d13 114
feb11 0:7a1237bd2d13 115 uint32_t AES::subWord(uint32_t w)
feb11 0:7a1237bd2d13 116 {
feb11 0:7a1237bd2d13 117 uint32_t out = 0;
feb11 0:7a1237bd2d13 118 for(int i = 0; i < 4; ++i)
feb11 0:7a1237bd2d13 119 {
feb11 0:7a1237bd2d13 120 uint8_t temp = (w & 0xFF);
feb11 0:7a1237bd2d13 121 out |= (sbox[temp] << (8*i));
feb11 0:7a1237bd2d13 122 w = (w >> 8);
feb11 0:7a1237bd2d13 123 }
feb11 0:7a1237bd2d13 124 return out;
feb11 0:7a1237bd2d13 125 }
feb11 0:7a1237bd2d13 126
feb11 0:7a1237bd2d13 127 void AES::subBytes()
feb11 0:7a1237bd2d13 128 {
feb11 0:7a1237bd2d13 129 for(int i = 0; i < 16; ++i)
feb11 0:7a1237bd2d13 130 state[i] = sbox[state[i]];
feb11 0:7a1237bd2d13 131 }
feb11 0:7a1237bd2d13 132
feb11 0:7a1237bd2d13 133 void AES::invSubBytes()
feb11 0:7a1237bd2d13 134 {
feb11 0:7a1237bd2d13 135 for(int i = 0; i < 16; ++i)
feb11 0:7a1237bd2d13 136 state[i] = inv_s[state[i]];
feb11 0:7a1237bd2d13 137 }
feb11 0:7a1237bd2d13 138
feb11 0:7a1237bd2d13 139 void AES::shiftRows()
feb11 0:7a1237bd2d13 140 {
feb11 0:7a1237bd2d13 141 for(int r = 0; r < 4; ++r)
feb11 0:7a1237bd2d13 142 {
feb11 0:7a1237bd2d13 143 uint32_t temp = (state[r] << 24) + (state[r+4] << 16) + (state[r+8] << 8) + state[r+12];
feb11 0:7a1237bd2d13 144 int i = r;
feb11 0:7a1237bd2d13 145 while(i > 0)
feb11 0:7a1237bd2d13 146 {
feb11 0:7a1237bd2d13 147 temp = rotWord(temp);
feb11 0:7a1237bd2d13 148 --i;
feb11 0:7a1237bd2d13 149 }
feb11 0:7a1237bd2d13 150 state[r] = temp >> 24;
feb11 2:473bac39ae7c 151 state[r+4] = temp >> 16;
feb11 2:473bac39ae7c 152 state[r+8] = temp >> 8;
feb11 2:473bac39ae7c 153 state[r+12] = temp;
feb11 0:7a1237bd2d13 154 }
feb11 0:7a1237bd2d13 155 }
feb11 0:7a1237bd2d13 156
feb11 0:7a1237bd2d13 157 void AES::invShiftRows()
feb11 0:7a1237bd2d13 158 {
feb11 0:7a1237bd2d13 159 for(int r = 0; r < 4; ++r)
feb11 0:7a1237bd2d13 160 {
feb11 0:7a1237bd2d13 161 uint32_t temp = (state[r] << 24) + (state[r+4] << 16) + (state[r+8] << 8) + state[r+12];
feb11 0:7a1237bd2d13 162 int i = r;
feb11 0:7a1237bd2d13 163 while(i > 0)
feb11 0:7a1237bd2d13 164 {
feb11 0:7a1237bd2d13 165 temp = invRotWord(temp);
feb11 0:7a1237bd2d13 166 --i;
feb11 0:7a1237bd2d13 167 }
feb11 0:7a1237bd2d13 168 state[r] = temp >> 24;
feb11 2:473bac39ae7c 169 state[r+4] = temp >> 16;
feb11 2:473bac39ae7c 170 state[r+8] = temp >> 8;
feb11 2:473bac39ae7c 171 state[r+12] = temp;
feb11 0:7a1237bd2d13 172 }
feb11 0:7a1237bd2d13 173 }
feb11 0:7a1237bd2d13 174
feb11 0:7a1237bd2d13 175 /* Multiply two numbers in the GF(2^8) finite field defined
feb11 0:7a1237bd2d13 176 * by the polynomial x^8 + x^4 + x^3 + x + 1 */
feb11 0:7a1237bd2d13 177 uint8_t gmul(uint8_t a, uint8_t b)
feb11 0:7a1237bd2d13 178 {
feb11 0:7a1237bd2d13 179 uint8_t p = 0;
feb11 0:7a1237bd2d13 180 uint8_t counter;
feb11 0:7a1237bd2d13 181 uint8_t carry;
feb11 0:7a1237bd2d13 182 for (counter = 0; counter < 8; counter++) {
feb11 0:7a1237bd2d13 183 if (b & 1)
feb11 0:7a1237bd2d13 184 p ^= a;
feb11 0:7a1237bd2d13 185 carry = (a & 0x80);
feb11 0:7a1237bd2d13 186 a <<= 1;
feb11 0:7a1237bd2d13 187 if (carry)
feb11 0:7a1237bd2d13 188 a ^= 0x001B; /* what x^8 is modulo x^8 + x^4 + x^3 + x^2 + 1 */
feb11 0:7a1237bd2d13 189 b >>= 1;
feb11 0:7a1237bd2d13 190 }
feb11 0:7a1237bd2d13 191 return p;
feb11 0:7a1237bd2d13 192 }
feb11 0:7a1237bd2d13 193
feb11 0:7a1237bd2d13 194 void AES::mul(uint8_t *r)
feb11 0:7a1237bd2d13 195 {
feb11 0:7a1237bd2d13 196 uint8_t tmp[4];
feb11 0:7a1237bd2d13 197 memcpy(tmp, r, 4);
feb11 0:7a1237bd2d13 198 r[0] = gmul(tmp[0],2) ^ gmul(tmp[1],3) ^ tmp[2] ^ tmp[3];
feb11 0:7a1237bd2d13 199 r[1] = tmp[0] ^ gmul(tmp[1],2) ^ gmul(tmp[2],3) ^ tmp[3];
feb11 0:7a1237bd2d13 200 r[2] = tmp[0] ^ tmp[1] ^ gmul(tmp[2],2) ^ gmul(tmp[3],3);
feb11 0:7a1237bd2d13 201 r[3] = gmul(tmp[0],3) ^ tmp[1] ^ tmp[2] ^ gmul(tmp[3],2);
feb11 0:7a1237bd2d13 202 }
feb11 0:7a1237bd2d13 203
feb11 0:7a1237bd2d13 204 void AES::invMul(uint8_t *r)
feb11 0:7a1237bd2d13 205 {
feb11 0:7a1237bd2d13 206 uint8_t tmp[4];
feb11 0:7a1237bd2d13 207 memcpy(tmp, r, 4);
feb11 0:7a1237bd2d13 208 r[0] = gmul(tmp[0],0x0e) ^ gmul(tmp[1],0x0b) ^ gmul(tmp[2],0x0d) ^ gmul(tmp[3],9);
feb11 0:7a1237bd2d13 209 r[1] = gmul(tmp[0],9) ^ gmul(tmp[1],0x0e) ^ gmul(tmp[2],0x0b) ^ gmul(tmp[3],0x0d);
feb11 0:7a1237bd2d13 210 r[2] = gmul(tmp[0],0x0d) ^ gmul(tmp[1],9) ^ gmul(tmp[2],0x0e) ^ gmul(tmp[3],0x0b);
feb11 0:7a1237bd2d13 211 r[3] = gmul(tmp[0],0x0b) ^ gmul(tmp[1],0x0d) ^ gmul(tmp[2],9) ^ gmul(tmp[3],0x0e);
feb11 0:7a1237bd2d13 212 }
feb11 0:7a1237bd2d13 213
feb11 0:7a1237bd2d13 214 void AES::mixColumns()
feb11 0:7a1237bd2d13 215 {
feb11 0:7a1237bd2d13 216 for(int c = 0; c < 4; ++c)
feb11 0:7a1237bd2d13 217 mul(&state[4*c]);
feb11 0:7a1237bd2d13 218 }
feb11 0:7a1237bd2d13 219
feb11 0:7a1237bd2d13 220 void AES::invMixColumns()
feb11 0:7a1237bd2d13 221 {
feb11 0:7a1237bd2d13 222 for(int c = 0; c < 4; ++c)
feb11 0:7a1237bd2d13 223 invMul(&state[4*c]);
feb11 0:7a1237bd2d13 224 }
feb11 0:7a1237bd2d13 225
feb11 0:7a1237bd2d13 226 void AES::addRoundKey(int round)
feb11 0:7a1237bd2d13 227 {
feb11 0:7a1237bd2d13 228 for(int c = 0; c < 4; ++c)
feb11 0:7a1237bd2d13 229 {
feb11 0:7a1237bd2d13 230 uint32_t temp = (state[4*c] << 24) + (state[4*c+1] << 16) + (state[4*c+2] << 8) + state[4*c+3];
feb11 0:7a1237bd2d13 231 temp ^= w[round*4+c];
feb11 2:473bac39ae7c 232 state[4*c] = temp >> 24;
feb11 2:473bac39ae7c 233 state[4*c+1] = temp >> 16;
feb11 2:473bac39ae7c 234 state[4*c+2] = temp >> 8;
feb11 2:473bac39ae7c 235 state[4*c+3] = temp;
feb11 0:7a1237bd2d13 236 }
feb11 0:7a1237bd2d13 237 }
feb11 0:7a1237bd2d13 238
feb11 0:7a1237bd2d13 239 void AES::decryptBlock(uint8_t *out, uint8_t *in)
feb11 0:7a1237bd2d13 240 {
feb11 0:7a1237bd2d13 241 memcpy(state,in,16);
feb11 0:7a1237bd2d13 242
feb11 0:7a1237bd2d13 243 addRoundKey(nr);
feb11 0:7a1237bd2d13 244
feb11 0:7a1237bd2d13 245 for(int round = nr-1; round > 0; --round)
feb11 0:7a1237bd2d13 246 {
feb11 0:7a1237bd2d13 247 invShiftRows();
feb11 0:7a1237bd2d13 248 invSubBytes();
feb11 0:7a1237bd2d13 249 addRoundKey(round);
feb11 0:7a1237bd2d13 250 invMixColumns();
feb11 0:7a1237bd2d13 251 }
feb11 0:7a1237bd2d13 252 invShiftRows();
feb11 0:7a1237bd2d13 253 invSubBytes();
feb11 0:7a1237bd2d13 254 addRoundKey(0);
feb11 0:7a1237bd2d13 255
feb11 0:7a1237bd2d13 256 memcpy(out, state, 16);
feb11 0:7a1237bd2d13 257 }
feb11 0:7a1237bd2d13 258
feb11 0:7a1237bd2d13 259 void AES::encryptBlock(uint8_t *out, uint8_t *in)
feb11 0:7a1237bd2d13 260 {
feb11 0:7a1237bd2d13 261 memcpy(state,in,16);
feb11 0:7a1237bd2d13 262
feb11 0:7a1237bd2d13 263 addRoundKey(0);
feb11 0:7a1237bd2d13 264
feb11 0:7a1237bd2d13 265 for(int round = 1; round < nr; ++round)
feb11 0:7a1237bd2d13 266 {
feb11 0:7a1237bd2d13 267 subBytes();
feb11 0:7a1237bd2d13 268 shiftRows();
feb11 0:7a1237bd2d13 269 mixColumns();
feb11 0:7a1237bd2d13 270 addRoundKey(round);
feb11 0:7a1237bd2d13 271 }
feb11 0:7a1237bd2d13 272 subBytes();
feb11 0:7a1237bd2d13 273 shiftRows();
feb11 0:7a1237bd2d13 274 addRoundKey(nr);
feb11 0:7a1237bd2d13 275
feb11 0:7a1237bd2d13 276 memcpy(out, state, 16);
feb11 0:7a1237bd2d13 277 }
feb11 0:7a1237bd2d13 278
feb11 0:7a1237bd2d13 279 void AES::encrypt(uint8_t *out, uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 280 {
feb11 0:7a1237bd2d13 281 for(uint32_t i = 0; i < length; i+=16)
feb11 0:7a1237bd2d13 282 encryptBlock(&out[i], &in[i]);
feb11 0:7a1237bd2d13 283 }
feb11 0:7a1237bd2d13 284
feb11 0:7a1237bd2d13 285 void AES::decrypt(uint8_t *out, uint8_t *in, uint32_t length)
feb11 0:7a1237bd2d13 286 {
feb11 0:7a1237bd2d13 287 for(uint32_t i = 0; i < length; i+=16)
feb11 0:7a1237bd2d13 288 decryptBlock(&out[i], &in[i]);
feb11 0:7a1237bd2d13 289 }
feb11 0:7a1237bd2d13 290
feb11 0:7a1237bd2d13 291 uint32_t AES::getBlockSize() const
feb11 0:7a1237bd2d13 292 {
feb11 0:7a1237bd2d13 293 return 16;
feb11 0:7a1237bd2d13 294 }