Arduino Forum

Development => Other Software Development => Topic started by: MarkT on Jan 25, 2012, 07:51 pm

Title: new AES library
Post by: MarkT on Jan 25, 2012, 07:51 pm
I've written an AES (Advanced Encryption Standard) library for Arduino.  It supports 128, 192 and 256 bit key sizes.  Code space overhead is about 4KB I think, each instance requires 240 bytes RAM for subkeys.  Fairly tightly coded and checked against official test vectors for ECB mode.  Also CBC mode supported.

Its derived from Brian Gladman's implementation for byte-oriented processors but signficantly modified.  See the README and examples.

Functions:
Code: [Select]

  byte set_key (byte key[], int keylen) ;
  void clean () ;  // delete key schedule after use
  void copy_n_bytes (byte * dest, byte * src, byte n) ;

  byte encrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK]) ;
  byte cbc_encrypt (byte * plain, byte * cipher, int n_block, byte iv [N_BLOCK]) ;

  byte decrypt (byte cipher [N_BLOCK], byte plain [N_BLOCK]) ;
  byte cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK]) ;


Lives here: http://utter.chaos.org.uk:/~markt/AES-library.zip (http://utter.chaos.org.uk:/~markt/AES-library.zip)

Feedback welcome.
Title: Re: new AES library
Post by: robtillaart on Jan 25, 2012, 10:47 pm
Nice work, not tested it (if i only had time ...),

have you tried it in communication (serial/ethernet/SD/...) yet? especially with other device PC/Mac/pinguin
Title: Re: new AES library
Post by: MarkT on Jan 26, 2012, 02:46 am
Its tested against many of the test-vectors (key varying, plaintext varying, Monte Carlo), which is the only contract it needs to fulfil...  I've some speed/timing information now:

128 bit, key setup 0.37ms
128 bit, ECB, encryption  0.58ms / block (27.5kB/s)
128 bit, ECB, decryption  0.77ms / block (20.5kB/s)

192 bit, key setup 0.41ms
192 bit, ECB, encryption  0.71ms / block (22.5kB/s)
192 bit, ECB, decryption  0.92ms / block (17.5kB/s)

256 bit, key setup 0.52ms
256 bit, ECB, encryption  0.82ms / block (19.5kB/s)
256 bit, ECB, decryption  1.09ms / block (14.5kB/s)

(CBC modes are a little slower than ECB)

(All ATmega328p, 16MHz)
Title: Re: new AES library
Post by: robtillaart on Jan 28, 2012, 12:25 pm

good speed, given that the Arduino/Mega only have a few KB of RAM, it can encode total RAM within a second.

Arduino can make approx 9000 (18KB) of analogRead samples per second [ @100% ] so I think it can keep up with 3-4000 samples/second.

Title: Re: new AES library
Post by: MarkT on Jan 28, 2012, 02:00 pm
Glad you like it.  Next project is elliptic curve public key cryptography! (Only half joking)
Title: Re: new AES library
Post by: dauhee on Jan 16, 2013, 11:21 pm
Thank you so much for this extremely useful library. I'm not too "up" on C. Would you have any examples on encrypting a string that is longer than the N_BLOCK?

I have hit a stumbling block (no pun intended), and am trying multi-dimentional arrays to create blocks for encrypting/decrypting - I haven't gotten it working so am not even sure if plain and cipher will always be the same length.
Title: Re: new AES library
Post by: robtillaart on Jan 17, 2013, 06:22 pm
you make a loop that takes n_BLOCK bytes per iteration of the character array until all chars are done. (you might need to pad the last block with zero's or so).

Title: Re: new AES library
Post by: westfw on Jan 18, 2013, 02:52 am
Note that AES is a block hash, not suitable for encrypting bulk data simply by dividing the data into blocks and encrypting each one with the same key.  That would open up all sorts of flaws and vulnerabilities.  typically you use something like "cipher block chaining" or "random ctr-mode" that generate separate xor keys for each block of data, BASED on your AES key.  Essentially you need a library like openSSL on top of AES before you have something more than a mathematical curiosity.

"Cryptography is hard."
Title: Re: new AES library
Post by: dauhee on Jan 19, 2013, 11:26 am
Not looking to encrypt bulk data, just more than 16 characters each time.
Title: Re: new AES library
Post by: westfw on Jan 20, 2013, 09:57 am
"bulk" means more than the native block size, in this case.  For example, if you were to just run AES with your key on each block, an attacked could immediately tell whether both blocks were the same, which would be a terrible thing from a cryptographic point of view.
Random-ctr mode consists of picking a random number (N) the same size as a block, and then running THAT through AES with your key to give you something to xor with the first 16 bytes, and then AES(N+1, k) to get something to xor with the second 16 bytes, and so on.  (then you transmit N at the start of your message.)  Aside from it being a bit tricky to generate 128bit random numbers, it should be TOO hard.
Title: Re: new AES library
Post by: dauhee on Jan 20, 2013, 05:12 pm
Thanks to robtillaart for putting me on the right track. Fundamental mistake on my part. When transferring string value to char array, I needed to size array to str.length() + 1 and also null terminate the final element.
Title: Re: new AES library
Post by: MarkT on Jan 20, 2013, 11:36 pm

Thank you so much for this extremely useful library. I'm not too "up" on C. Would you have any examples on encrypting a string that is longer than the N_BLOCK?

I have hit a stumbling block (no pun intended), and am trying multi-dimentional arrays to create blocks for encrypting/decrypting - I haven't gotten it working so am not even sure if plain and cipher will always be the same length.


Assuming you have padded your plaintext up to a whole number of blocks "blockcount", and
assuming ciphertext is a byte array long enough for that amount of data, and that iv is a block's
worth of initialization vector, the encryption call is
Code: [Select]
  success_flag = aes.cbc_encrypt (plaintext, ciphertext, blockcount, iv);

Similarly for cbc_decrypt.  If "iv" and "padding" don't mean anything to you you will need to read up about
block cipher encryption modes - all details matter.

These routines side-effect the iv argument to perform chaining (meaning they can be called repeatedly on groups of blocks
without having to pass around a chaning block explicitly).
Title: Re: new AES library
Post by: westfw on Jan 22, 2013, 09:37 am
I apologize for not noticing that the library already has a CBC-mode function.  That's (one possibility) for what should be used to encrypt more than one block worth of data.
Title: Re: new AES library
Post by: toonamo on Mar 24, 2014, 01:57 am
I am new to this encryption and decryption stuff, so i was playing with this library to get a idea on how it works.

My questions is why does the decryption function require the original unencrpyted plain message? Should it not be requesting the key and the cypher to decrypt it?

If I encrpted a message on one arduino and sent the cypher to another arduino with the keys hard coded into each seperate program how would i decrpyt the message on the second arduino? I wouldn't want to send the plain text in the message because then it defeats the purpose of encrypting in the first place.
Title: Re: new AES library
Post by: nooby on May 17, 2014, 04:37 am

I am new to this encryption and decryption stuff, so i was playing with this library to get a idea on how it works.

My questions is why does the decryption function require the original unencrpyted plain message? Should it not be requesting the key and the cypher to decrypt it?

If I encrpted a message on one arduino and sent the cypher to another arduino with the keys hard coded into each seperate program how would i decrpyt the message on the second arduino? I wouldn't want to send the plain text in the message because then it defeats the purpose of encrypting in the first place.


I'll try explain some symmetric encryption AES concepts a little (I found this while googling an arduino AES library - thanks to the O.P. for his/her hard work!)

The password is the actual 'secret' that must never be disclosed to the public. The sender and receiver must know the password to encrypt and decrypt correctly.

To keep things VERY simple, lets NOT break things up and pad strings - I'm simply explaining concepts.
We have our plaintext - "Hello World"
We have our password - "Hunter2"

The encryption will use the password to scramble "Hello World" into (example) "Um1nvnlmPP".
But what happens if you want to send the same encrypted message again? The ciphertext will look exactly the same! This means the bad guys can do "Pattern analysis", not exactly figuring out exactly what's in your message, but they know the same message was sent.

An excellent example is here on Wikipedia:
https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_.28ECB.29

Block based encryption breaks a message up into little "blocks of data" to encrypt. In the above link, you can clearly see why ECB is a very very bad thing if Initialization Vectors (IV) aren't used for EACH block. What's an IV?

The IV is purely random data that is used WITH your password to encrypt the data. The IV does not need to be kept private, it is often sent with the encrypted message, eg:
Plaintext: "Hello World"
Password: "Hunter2"
IV: (randomly generated) "aabbaabbaa"
The complete message: "[aabbaabbaa][mnmnmnmnmn]"

So the encrypted message that anyone can see contains the IV in plain text. The IV does not need to be kept secret, only the password since it's not easy to crack the encryption without the password. The decrypter takes the IV, the user supplied password and attempts to decrypt the ciphertext

How does the IV help? Lets encrypt the same message again:
Plaintext: "Hello World"
Password: "Hunter2"
IV: (randomly generated) "ccddccddccdd"
Ciphertext: "[ccddccddccdd][opopopopopop]

See the ciphertext is always different, even if the same password is used because the IV is always different. This is only one step of preventing the bad guys identifying the contents of your message.

CBC is a little different. CBC uses a little bit of encrypted data from the previous block to encrypt the next block. The first block still needs the IV to be random. CBC has a smaller data size for a lot of blocks since a single IV can be used for a lot of blocks, while ECB can have only one IV for the lot, to prevent pattern matching as per the wikipedia article, better security would necessitate it should have a unique IV per block.
Title: Re: new AES library
Post by: bilica on Jun 18, 2014, 04:03 pm
Great lib! Thanks MarkT!

Does it work for larger keys, like 1024 or 2048 ?


I've written an AES (Advanced Encryption Standard) library for Arduino.  It supports 128, 192 and 256 bit key sizes.  Code space overhead is about 4KB I think, each instance requires 240 bytes RAM for subkeys.  Fairly tightly coded and checked against official test vectors for ECB mode.  Also CBC mode supported.

Its derived from Brian Gladman's implementation for byte-oriented processors but signficantly modified.  See the README and examples.

Functions:
Code: [Select]

  byte set_key (byte key[], int keylen) ;
  void clean () ;  // delete key schedule after use
  void copy_n_bytes (byte * dest, byte * src, byte n) ;

  byte encrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK]) ;
  byte cbc_encrypt (byte * plain, byte * cipher, int n_block, byte iv [N_BLOCK]) ;

  byte decrypt (byte cipher [N_BLOCK], byte plain [N_BLOCK]) ;
  byte cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK]) ;


Lives here: http://utter.chaos.org.uk:/~markt/AES-library.zip (http://utter.chaos.org.uk:/~markt/AES-library.zip)

Feedback welcome.
Title: Re: new AES library
Post by: dkosasih on Jul 03, 2014, 04:37 pm
Hi,

I am working on simple encryption on my Arduino to be able to talk back and forth with web service, and stumbled upon this useful library. However, I have few questions regarding the CRC_decrypt and encrypt.

I got this example from somewhere in the thread and modify in a little bit.

Code: [Select]
#include <AES.h>

#define KEYLENGTH 32  // this means 32 bit encryption only following values are allowed 16, 128, 24, 192, 32, 256
AES aes;
char PassString[] = "This is hard to believe but true however";// this must be at least KEYLENGTH characters long
byte my_iv[N_BLOCK] =
{
 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
} ;
byte key[KEYLENGTH];
void setup()
{
Serial.begin(115200);

Serial.println("Starting AES test");
for (int i = 0; i < KEYLENGTH; i++)
{
key[i] = PassString[i];
}

if (aes.set_key(key, KEYLENGTH) != 0)
{
Serial.println(F("Failed to set key"));
}

}

// The loop function is called in an endless loop
void loop()
{

char Message[] = "A top secret message. 123456789012345678901234";
byte plain[N_BLOCK];
byte cipher[N_BLOCK];
byte decrypted[N_BLOCK];

 byte iv [N_BLOCK] ;
 
Serial.print(F("message : '"));
Serial.print(Message);
Serial.println(F("'"));
Serial.print(F("plain binary: '"));
for (int i = 0; i < N_BLOCK; i++)
{
plain[i] = Message[i];
cipher[i] = 0;
decrypted[i] = 0;
Serial.print(plain[i]);
}
Serial.println(F("'"));

Serial.print(F("plain char: '"));
for (int i = 0; i < N_BLOCK; i++)
{
Serial.print(char(plain[i]));
}
Serial.println(F("'"));

for (byte i = 0 ; i < 16 ; i++)
     iv[i] = my_iv[i] ;
if (aes.cbc_encrypt(plain, cipher,4,iv) == 0)
{
Serial.print(F("encrypted : '"));
for (int i = 0; i < N_BLOCK; i++)
{
Serial.print(cipher[i]);
}
Serial.println(F("'"));
} else
{
Serial.println(F("Failed to encrypt"));
}

if (aes.cbc_decrypt(cipher, decrypted,4,iv) == 0)
{
Serial.print(F("decrypted binary : '"));
for (int i = 0; i < N_BLOCK; i++)
{
Serial.print(decrypted[i]);
}
Serial.println(F("'"));

Serial.print(F("decrypted char : '"));
for (int i = 0; i < N_BLOCK; i++)
{
Serial.print(char(decrypted[i]));
}
Serial.println(F("'"));
} else
{
Serial.println(F("Failed to decrypt"));
}

delay(5000);
}


The result seemed to be stable, as in I get it decrypt and encrypt. How do I print those bytes in readable character? encrypted and decrypted plain text. if I cannot have this printed in ascii format, I cannot prove that I can decrypt the message in the web server.

Thanks.
Title: Re: new AES library
Post by: MarkT on Jul 03, 2014, 05:08 pm
As hexadecimal is conventional.
Title: Re: new AES library
Post by: dkosasih on Jul 03, 2014, 11:47 pm
Mark, 
Sorry,  I'm afraid I don't understand what you mean.  : :smiley-red:
Title: Re: new AES library
Post by: MarkT on Jul 04, 2014, 12:41 am
If you have binary data to display, it is conventional to display it in
hexadecimal.

What exactly are you wanting to achieve and do you understand about
cryptography?
Title: Re: new AES library
Post by: dkosasih on Jul 04, 2014, 01:21 am
Here is what I try to achieve.
I tried to encrypt "dkosasih" in node.js I got 1200d4366608c5e16de242ea5aae753e.
I would've thought that it will work the same way in arduino.
Instead, when I try to encrypt the same word in arduino, I get numbers.

How do I send those number, in the form of '1200d4366608c5e16de242ea5aae753e' so that I can send them through the network and be able to be decrypted by the node.js and vice versa.
I hope I am making sense here.
Title: Re: new AES library
Post by: JochenAlt on Oct 05, 2014, 01:04 am
Hi all,
I was not able to produce the results like in java: What I tried was

   // encrypt:
           SecretKeySpec secretKeySpec = new SecretKeySpec(key128, "AES");
          Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
          cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
          byte[] encrypted = cipher.doFinal(source);

  // decrypt ( in a different method)
           SecretKeySpec secretKeySpec = new SecretKeySpec(key128, "AES");
           Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
           cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
           byte[] decrypted = cipher.doFinal(encrypted);

Although the java code does encrypt and decrypt it correctly, the encrypted array is different from the AES library's result.
Did anyone else try to encrypt on avr and decrypt in java?
Cheers
Jochen
Title: Re: new AES library
Post by: MarkT on Oct 05, 2014, 09:37 pm
ECB mode?  How insecure do you want to be ;)

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.
Title: Re: new AES library
Post by: puglee on Jan 16, 2015, 04:02 pm
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?
Title: Re: new AES library
Post by: -dev on Jan 16, 2015, 04:44 pm
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.
Title: Re: new AES library
Post by: puglee on Jan 16, 2015, 05:15 pm
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!!!
Title: Re: new AES library
Post by: awesomeonfar on Feb 01, 2015, 02:37 am
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?

Title: Re: new AES library
Post by: Fuzzhead77 on Apr 19, 2015, 04:32 am
I hello MarkT. I've been studying this lib and was wondering what size files you tested to get your processing times.
Title: Re: new AES library
Post by: paul393 on Jun 19, 2015, 08:00 pm
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.

Code: [Select]
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(" ");
  }
}
Title: Re: new AES library
Post by: MarkT on Jun 20, 2015, 02:06 am
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.
Title: Re: new AES library
Post by: paul393 on Jun 21, 2015, 06:45 am
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.









Title: Re: new AES library Arduino Zero
Post by: d3str0y3rport on Jul 27, 2015, 11:44 pm
Hi could you help me making this library able for the Arduino Zero

Thank you!!!
Title: Re: new AES library
Post by: pYro_65 on Jul 28, 2015, 04:31 am
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).
Title: Re: new AES library
Post by: gpra on Oct 18, 2015, 09:51 am
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
http://aes.online-domain-tools.com/

Here you find usefull info and test-vectors:
http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf

Greetings,
gprand
Title: Re: new AES library
Post by: zasf on Oct 18, 2015, 05:38 pm
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 :)
Title: Re: new AES library
Post by: MarkT on Oct 19, 2015, 05:01 am
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?
Title: Re: new AES library
Post by: gpra on Oct 19, 2015, 03:28 pm
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
 
Title: Re: new AES library
Post by: zasf on Oct 23, 2015, 08:08 pm
In the "aes" example, line:

Code: [Select]
succ = aes.decrypt (cipher, plain) ;

should read:

Code: [Select]
succ = aes.decrypt (cipher, check) ;

With original aes example code, when running:
Code: [Select]
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:

Code: [Select]
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:

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


should read:

Code: [Select]
byte AES::decrypt (byte cipher [N_BLOCK], byte plain [N_BLOCK])
{
...
}
Title: Re: new AES library
Post by: relic1974 on Sep 10, 2016, 07:51 pm
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.
Title: Re: new AES library
Post by: bigpjo on Sep 27, 2016, 03:59 pm
Excellent, library very quick and efficient however, there is an issue with the CBC decrypt, below is my code running on arduino

Code: [Select]
#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

Code: [Select]
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.
Title: Re: new AES library
Post by: bigpjo on Sep 27, 2016, 04:43 pm
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
Title: Re: new AES library
Post by: alias33 on Oct 04, 2016, 01:01 pm
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)


Title: Re: new AES library
Post by: Alejandr010 on Jan 17, 2017, 11:30 am
Hi at all, I'm trying to use this aes lib on my arduino uno to encrypt and decrypt a string, how can I do? thank you
Title: Re: new AES library
Post by: Altelectronics on Mar 18, 2017, 03:24 pm
Hi Mark,

I might came across a minor bug (with a workaround) in your library.
how to reproduce
if you run your example code with the following calls

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

you get

testng modeset_key 256 ->0 took 748us
encrypt 0 took 716us
decrypt 0 took 968us
F3 44 81 EC 3C C6 27 BA CD 5D C3 FB 08 F2 73 E6
63 60 DD 58 F0 F1 A4 93 8B 40 6A 8E AA 7E 0A 14
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


so the decrypt for block==1 fails
however if you run the following calls

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


then the both work fine

testng modeset_key 256 ->0 took 748us
encrypt 0 took 1492us
decrypt 0 took 2044us
F3 44 81 EC 3C C6 27 BA CD 5D C3 FB 08 F2 73 E6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
6A BB C9 E8 A0 FD 6D E7 FB 8A A5 D8 A6 CF 4C 7D D3 2B 9D 08 7B AA 9D 43 09 56 B0 D9 21 0B 62 C8
F3 44 81 EC 3C C6 27 BA CD 5D C3 FB 08 F2 73 E6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
D3 2B 9D 08 7B AA 9D 43 09 56 B0 D9 21 0B 62 C8
set_key 256 ->0 took 752us
encrypt 0 took 708us
decrypt 0 took 972us
F3 44 81 EC 3C C6 27 BA CD 5D C3 FB 08 F2 73 E6
63 60 DD 58 F0 F1 A4 93 8B 40 6A 8E AA 7E 0A 14
F3 44 81 EC 3C C6 27 BA CD 5D C3 FB 08 F2 73 E6


not a big deal - but it might worth a look.
Thanks for the great work!

Best Regards,
Aurelian













Title: Re: new AES library
Post by: rsegecin on Oct 31, 2017, 02:30 am
Does this library exists on github that may have all this issues fixed?
Title: Re: new AES library
Post by: casloureiro on Apr 15, 2018, 09:29 pm
Hello,

I have a program where I have several strings. To avoid the use of RAM, I'm using the PROGMEM to have array of strings, and also the F() to store strings on the flash (PGM).

I'm using a arduino mega2560, and I see if changes some strings to the flash, with F(), I start having problems with the encoding and decondig.

I have arrived to the point where I have a program with 83346 bytes (32% of program space). And all is working.

If I change the line:

Code: [Select]
_lcd->print("1) ");

to

_lcd->print(F("1) "));


The program size jumps to 83598 bytes, and the encode and decode doesn't work correctly.
I have made several changes on the code, but always I get a program above the 83346 I get problems on the AES library. All the rest is working.

I see that the library also uses PGM to store values.

My question, is there the possibility that the use of several strings stored on the PGM, could cause problem on the library?

I'm using AES CBC 128bits.

Thanks for any idea that can be shared.
Title: Re: new AES library
Post by: -dev on Apr 16, 2018, 04:45 pm
Quote
Thanks for any idea that can be shared.
It is probably a near vs. far address problem.  Most pointers, like "const char *" or "const __FlashStringHelper *", are 16-bit addresses (i.e., "near" in the first 64K).

For function calls to "far" destinations, the linker is "supposed" to use a "trampoline" to get there, jumping to a "near" address first.  I get the impression that far calls are usually handled correctly.

For "far" data, I can't find anything other than managing it yourself with explicit declarations like uint_farptr_t and xxxx_PF variants, like memcpy_PF.

I don't think FLASH data (e.g., declared via the F macro) is guaranteed to be anywhere in particular.  The sketch code is preferentially loaded in the first 64K, but libraries may extend past that boundary.  I wonder if the code size pushes FLASH data past the 64K address boundary.  Then it is dereferenced incorrectly by code that expectes near pointers (e.g., Print methods).

To force the code to use far pointers for FLASH data, you have to do something like this:

Code: [Select]
const char someFlashData[] PROGMEM = "stringity string.";

void farPrint( const char *farFD )
{
  uint_farptr_t farAddr = pgm_get_far_address( farFD );
 
  do {
    char c = pgm_read_byte_far( farAddr++ );
    if (!c)
      break;
    Serial.write( c );
  }
}

void foo()
{
  farPrint( someFlashData );
}

Untested.   Functions/macros documented here (https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html).

If the AES library is using FLASH data, it would have to be modified to always use far pointers.  If it's just your sketch that is using FLASH data, you *should* be able to modify all the F macro uses to do something different.  Initial values may also fall into that category: they are loaded from FLASH into the RAM variable being initialized.

That's about all I can suggest.  Free advice is worth what you paid for it, my $0.02, YMMV, etc., etc.

You've been warned.  ;)
Title: Re: new AES library
Post by: spatula on Jan 23, 2019, 05:31 am
I am trying to use this library to encrypt some data I'm sending to a Raspberry Pi using a transceiver module. In order to make a small test prototype I've modified the example code provided with this library so that it performs 256 2 block CBC encryption and then prints the cipher to the Serial monitor.
Code: [Select]

#include <AES.h>

AES aes ;

byte key[] =
{
  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} ;

byte plain[] =
{
  // 0xf3, 0x44, 0x81, 0xec, 0x3c, 0xc6, 0x27, 0xba, 0xcd, 0x5d, 0xc3, 0xfb, 0x08, 0xf2, 0x73, 0xe6
  0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} ;

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) ;
  Serial.print ("testng mode") ;

  prekey_test () ;
 
//  otfly_test () ;
//  otfly_test256 () ;
}

void prekey (int bits, int blocks)
{
  byte iv [N_BLOCK] ;
 
  long t0 = micros () ;
  byte succ = aes.set_key (key, bits) ;
  long t1 = micros()-t0 ;
  Serial.print ("set_key ") ; Serial.print (bits) ; Serial.print (" ->") ; Serial.print ((int) succ) ;
  Serial.print (" took ") ; Serial.print (t1) ; Serial.println ("us") ;
  t0 = micros () ;
  if (blocks == 1)
    succ = aes.encrypt (plain, cipher) ;
  else
  {
    for (byte i = 0 ; i < 16 ; i++)
      iv[i] = my_iv[i] ;
    succ = aes.cbc_encrypt (plain, cipher, blocks, iv) ;
  }
  t1 = micros () - t0 ;
  Serial.print ("encrypt ") ; Serial.print ((int) succ) ;
  Serial.print (" took ") ; Serial.print (t1) ; Serial.println ("us") ;
  Serial.println();
  Serial.println("-------------------");
  for(byte i = 0; i < sizeof(cipher); i++) {
    Serial.print(cipher[i], HEX);
  }
  Serial.println("");
  Serial.println("------------------------------");

}

void prekey_test ()
{
  prekey (256,2) ;

}


I am then taking the cipher text and copying it to Python on the Raspberry Pi to the decryption code which uses the pycryptodome library, which is where I don't understand what to do. I am unsure of the block length of this library (I've serially printed N_BLOCK and found it to be 16, but the cipher array is 64 bytes long...) and I continually get a padding error in Python. I realise this is more of a Python problem than anything else but I have tried everything I can think of.

Code: [Select]


from Crypto.Cipher import AES
from base64 import b64encode, b64decode
from Crypto.Util.Padding import pad, unpad

BLOCK_SIZE = 64 # is that right?

def encrypt(plaintext, key, IV):
    cipher = AES.new(key, AES.MODE_CBC, IV)
    cipher_bytes = cipher.encrypt(pad(plaintext, BLOCK_SIZE))
    return(cipher_bytes)

def decrypt(ct, passkey, IV):
    cipher = AES.new(passkey, AES.MODE_CBC, IV)
    decrypted = cipher.decrypt(ct)
    return((unpad(decrypted, BLOCK_SIZE)))

passkey = b'80000000000000000000000000000000' #have I converted the passkey from the example code correctly?
IV = b'0000000000000001' # have I converted the IV from the example code correctly?
ct = b"F7B337A3C81C50169E4851F823E8C8B78EB31B013171CA23641F0D385DB38B00000000000000000000000000000000"
print(decrypt(ct, passkey, IV))

"""
>> ValueError: Data must be padded to 16 byte boundary in CBC mode

"""