new AES library

ECB mode? How insecure do you want to be :wink:

My library uses CBC mode, and I've provided the test vectors and an example
that you can run to compare to them. But go out and find the test vectors
yourself, don't trust me.

If you don't know what block cipher modes are, its time to do some homework.

Big thanks to MarkT for his work. Tried using this library on the latest IDE 1.5.8 and there were two error messages:

Arduino: 1.5.8 (Windows 7), Board: "Arduino Yún"

In file included from AES.h:4:0,
from AES.cpp:1:
AES.cpp:64:27: error: variable 's_fwd' must be const in order to be put into read-only section by means of 'attribute((progmem))'
static byte s_fwd [0x100] PROGMEM =
^
AES.cpp:84:27: error: variable 's_inv' must be const in order to be put into read-only section by means of 'attribute((progmem))'
static byte s_inv [0x100] PROGMEM =
^
Error compiling.

Any idea what's wrong?

I don't have 1.5.8 nor the AES library, but until someone else chimes in, I think you might try inserting const in these two declarations:

    static const byte s_fwd [0x100] PROGMEM =
           ^^^^^

This might cause a link problem, in which case all the declarations with PROGMEM will need the const keyword, too.

Hope that helps!
/dev

P.S. A little googling shows that the newer version of the compiler requires the const keyword on PROGMEM. This library, and many others, are out-of-date with respect to the compiler.

/dev:
I don't have 1.5.8 nor the AES library, but until someone else chimes in, I think you might try inserting const in these two declarations:

    static const byte s_fwd [0x100] PROGMEM =

^^^^^




This might cause a link problem, in which case all the declarations with PROGMEM will need the `const` keyword, too.

Hope that helps!
/dev

P.S. A little googling shows that the newer version of the compiler requires the `const` keyword on PROGMEM. This library, and many others, are out-of-date with respect to the compiler.

That was very fast. Was not aware the new IDE has different requirements for such declarations. I will try it out in awhile. Thank you so so much!!!

I'm not sure if I missed something on how to use CBC mode with this library but in order to successfully decrypt CBC messages, I needed to pad the input.

I'm not a crypto person and it'd be awesome if someone who knows what they're doing could explain more precisely.

As far as I can tell, the openssl implementation always adds up to 16 bytes of plaintext to the input for a padded ciphertext.

so if your input is:
"0123456789abcdef"

then openssl will produce the equivalent of encrypting:
"0123456789abcdef" followed by sixteen 0x10 (byte 16)

so in order to decrypt messages encrypted from the arduino with openssl, I had to pad the input I gave to this library.

is this the right way or am I misusing it?

I hello MarkT. I've been studying this lib and was wondering what size files you tested to get your processing times.

Hi Everyone,

I'm having some strange issues with this library and I think it may be related to using the new Arduino Zero Pro (which is 32 bit) rather than an 8 bit Arduino that this library was intended for.

The problem I have is when either encrypting or decrypting certain char arrays. I'm using CBC mode and believe I have all of the padding and such done correctly. Usually everything works fine, but sometimes certain strings cause everything to break (Arduino totally stops responding).

I'll post some of my code below, but as an example:

char toEncryptOne[] = "PCCTExample 47 characters......012345678901xx4567";
char toEncrypt1Two[] = "PCCTExample 47 characters......012345678901xX4567";

toEncryptOne[] breaks everything, but toEncryptTwo[] works fine. The only difference is an 'x' vs. an 'X' -- and this is just an example. For instance, maybe if I put a lower case 'a' somewhere else the same thing happens.

If I upload the exact same sketch to an Arduino Mega 2560 (which is 8 bit) I have no problems.

Is there a way I can modify the library to be compatible with the 32 bit Arduino Zero Pro?

Here is my encryption code below. Please be gentle! I'm still trying to learn this stuff.

void encrypt (char toEncrypt[], int plainArrLength) {

  int paddingToAdd = (((plainArrLength + 15) & ~15) - plainArrLength);

  plainArrLength = plainArrLength + paddingToAdd;

  char toEncryptFullSize[plainArrLength];

  byte plain[plainArrLength];

  for (int n = 0; n < (plainArrLength - paddingToAdd); n++) {
    toEncryptFullSize[n] = toEncrypt[n];
  }

  for (int n = (plainArrLength - paddingToAdd); n <= plainArrLength; n++) {
    toEncryptFullSize[n] = '`'; //Pad the remaining space with 0x60 (`).
  }

  for (int n = 0; n < plainArrLength; n++) {
    plain[n] = toEncryptFullSize[n];
  }

  int blocks = ceil(plainArrLength / 8);
  int bits = blocks * 128;

  byte iv [N_BLOCK];
  byte succ = aes.set_key (key, 128);

  if (succ != SUCCESS && debugMode == true) {
    Serial.println("***ERROR: Encryption failure (set_key problem).***\n");
  }

  if (blocks == 1) {
    succ = aes.encrypt (plain, cipher);
    if (succ != SUCCESS) {
      Serial.println("***ERROR: Encryption failure (one block only).***\n");
    }
  }

  else
  {
    for (byte i = 0 ; i < 16 ; i++)
    {
      iv[i] = my_iv[i] ;
    }

    succ = aes.cbc_encrypt (plain, cipher, blocks, iv) ;

    //
    //
    // When a 'bad' string is put through this function, it never makes it to this point.
    //
    //
    
    if (succ != SUCCESS) {
      Serial.println("***ERROR: Encryption failure (CBC Mode).***\n");
    }
  }

  for (int x = 1; x <= plainArrLength; x++) {
    if (cipher[x - 1] < 0x10) {
      Serial.print("0");
    }
    Serial.print(cipher[x - 1], HEX);
    Serial.print(" ");
  }
}

The code is written for 8-bit microcontrollers as the comments mention.

You'll have to look for 8-bit and 16-bit assumptions if you want to port it
to a 32 bit machine.

MarkT:
The code is written for 8-bit microcontrollers as the comments mention.

You'll have to look for 8-bit and 16-bit assumptions if you want to port it
to a 32 bit machine.

Thanks for the reply!

I've found some pseudo code for AES ( http://www.cs.utsa.edu/~wagner/laws/AESintro.html ) that has helped me understand this some more -- but I'm still struggling to find where the '8 bit assumptions' are precisely.

It seems from what I can find one difference between the 8 and 32 bit micros with Arduino is the size of int variables (16 and 32 bit, respectively). Are variables such as the two below therefore the ones causing me problems in this library?

int n_block
int keylen

For instance the line:
byte next = keylen ;

byte is 8 bits regardless, but the size of keylen is different between the 8 and 32 bit systems. Is this my problem?

Any additional pointers would be greatly appreciated as I try to work through this.

Hi could you help me making this library able for the Arduino Zero

Thank you!!!

This library is intended for 8 bit CPU's. You'll probably have better performance finding a 32-bit version.

However you should be able to go through and change the data types (int) to their AVR sized fixed width equivalents (int becomes int16_t and such).

Hi MarkT,

sorry but your lib don't work correct.
I've do decode AES128 CBC, encoded from another device. Only the first block is correct, all others wrong.
Please check against

Here you find usefull info and test-vectors:

Greetings,
gprand

Hello gpra,

it would be nice from you if you could provide the proof of what you're saying, for example some code that shows incorrect blocks compared to test vectors :slight_smile:

Was this the exact same CBC mode and with the precise IV in the right endianess to match
my code? All these details matter, you have to check. Perhaps you could provide a specific
example case referenced to the documentation?

Have you run the example that runs the test vectors? Does it work for you? Seen my #2 post?

Hi,

yes, I'll evaluate an example in the next days. Test program "aes.pde" did run correct. But it does encrypt and then decrypt, this seems to compensate the difference.

Greetings,

gpra

In the "aes" example, line:

succ = aes.decrypt (cipher, plain) ;

should read:

succ = aes.decrypt (cipher, check) ;

With original aes example code, when running:

void prekey_test ()
{
  prekey (128, 4) ;
  prekey (192, 3) ;
  prekey (256, 2) ;
  prekey (128, 1) ;
  prekey (192, 1) ;
  prekey (256, 1) ;
}

check variable is untouched after prekey(256,2), that is why if you comment statements before prekey(128, 1), right decryption won't be shown. In order to see it, you also should change plain to something like:

byte plain[] =
{
  0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} ;

Is it possible that variable names are inverted in decrypt function in AES.cpp? Line:

byte AES::decrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK]) 
{ 
... 
}

should read:

byte AES::decrypt (byte cipher [N_BLOCK], byte plain [N_BLOCK])
{
...
}

I too am very new to AES. I've learned enough to know basically how it works, but do not quite understand the methods in the arduino library. I'd like to ask for a simple example of encrypting/decrypting a 16 character string.

Could someone respond with some syntax using this AES library to do just that? Sorry but even looking at the library files themselves I am still somewhat lost.

I'm unsure how to set the 'password' and for my purposes I would ALWAYS be encrpyting 16 characters @ 128 bit. If I had an example using the libraries keywords/methods it would really help me to understand the rest of it.

A good example would be 128 bit encrypt/decryption of the string "abcdefghijklmnop" with a password of "panthers".

Any example or help would be greatly appreciated and would help me to understand the library better.

Excellent, library very quick and efficient however, there is an issue with the CBC decrypt, below is my code running on arduino

#include <Base64.h>
#include <AES.h>

AES aes ;

byte key[] = 
{
  12,13,14,15,15,16,17,18,19,10,11,12,13,14,15,16
 ,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
} ;

byte my_iv[] = 
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
} ;

//byte cipher [4*N_BLOCK] ;
byte check [4*N_BLOCK] ;

void loop () 
{}


void setup ()
{
  Serial.begin (57600) ;

  delay(30000);
  
  Serial.println("testing mode") ;

  byte succ = aes.set_key (key, 256) ;

  byte iv [N_BLOCK] ;
  for (byte i = 0 ; i < 16 ; i++)
      iv[i] = my_iv[i] ;

  int decodedLen = 32;
  byte decoded[] = {70,33,158,65,106,36,73,238,61,225,69,115,121,47,148,114,238,92,183,97,37,152,168,11,248,112,41,187,179,2,119,250};

  succ = aes.cbc_decrypt (decoded, check, (decodedLen/N_BLOCK), iv) ;

  aes.clean();

  for(int i=0; i<decodedLen;i++)
  {
    Serial.print((char)check[i]);
  }
  Serial.println("");
}

This is decrypted but not correctly, the second block, first byte us incorrect, decrypted the string should read Decoded hello world encrypted!!! but this library decodes as Decoded hello wnrld encrypted!!!

The encrypted text is from a C# console app

using System;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            var isLE = BitConverter.IsLittleEndian;


            byte[] encrypData = System.Text.Encoding.UTF8.GetBytes("Decoded hello world encrypted!!!");

            using (AesManaged crypto = new AesManaged())
            {
                crypto.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                crypto.Key = new byte[] {12,13,14,15,15,16,17,18,19,10,11,12,13,14,15,16
                                        ,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32};
                crypto.Mode = CipherMode.CBC;

                using (var encryptor = crypto.CreateEncryptor())
                {
                    var outBuffer = new byte[32];

                    encryptor.TransformBlock(encrypData, 0, 32, outBuffer, 0);

                }
            }
        }
    }
}

Any ideas what could be causing the issue? I have checked from previous threads about endian and I can confirm both are little.

After my previous post I noticed an issue with my_iv, had a 01 as last byte and should have been 00, corrected and can confirm the library works 100%, nice work MARKT

Hi
I have quastion about library "AES.h " .

I am use arduino DUE
how I can do this with your library ?
enter voice by microphone in (A0)
the voice out encryption by " AES" from (DAC0)
the encryption voice enter to (A1)
then the voice out decryption from ( DAC1)