Go Down

Topic: new AES library (Read 20629 times) previous topic - next topic

bilica

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

Feedback welcome.

dkosasih

#16
Jul 03, 2014, 04:37 pm Last Edit: Jul 03, 2014, 04:57 pm by dkosasih Reason: 1
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.

MarkT

As hexadecimal is conventional.
[ I won't respond to messages, use the forum please ]

dkosasih

Mark, 
Sorry,  I'm afraid I don't understand what you mean.  : :smiley-red:

MarkT

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?
[ I won't respond to messages, use the forum please ]

dkosasih

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.

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

MarkT

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.
[ I won't respond to messages, use the forum please ]

puglee

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?

/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.

puglee

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?


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy