spaniakos / AES

AES for microcontrollers (Arduino & Raspberry pi)
http://spaniakos.github.io/AES/
GNU Affero General Public License v3.0
126 stars 55 forks source link

Corruption of the last char of the decrypted text. (solved) #7

Closed sunny127 closed 7 years ago

sunny127 commented 7 years ago

In example aes.pde , the last char of variable 'plain' is not decrypted correctly. It should be zero ( cause it is a zero terminated string ). The result given by line 54: aes.printArray(check,(bool)true); corrupts the last byte of the original 'Plain' variable.

A bad walkaround is just to change line 40 from: aes.do_aes_encrypt(plain,41,cipher,key,bits,iv); to aes.do_aes_encrypt(plain,41+1,cipher,key,bits,iv);

But this is just a walkraround for a problem in the decryption mechanism.

spaniakos commented 7 years ago

i dont get what you mean, can you please share your the results? as i never had a problem with the decryption.

sunny127 commented 7 years ago

In the aes.pde example, when I print the results using the original line aes.do_aes_encrypt(plain,41,cipher,key,bits,iv); I get:

PLAIN :65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 0.

CHECK :65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 7 7 7 7 7 7 7 7.

This "check" is bad, the #41 char should be 0, not 7.

After the fix: aes.do_aes_encrypt(plain,41+1,cipher,key,bits,iv); I get:

PLAIN :65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 0.

CHECK :65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 0 7 7 7 7 7 7 7 .

The check values is good. the #41 char is 0 as should be.

spaniakos commented 7 years ago

Are you running the example as is? or have you changed something?

spaniakos commented 7 years ago

i am at work now and i cant check, but if you havent changed anything in the algorithm, the default behavior is to pad using 8 characters. if you want to encrypt 41 characters the algorithm (as is now) requires the +1. i have an updated version with a framework on top of the AES that does all the calculation automatically, but i havent` uploaded yet as it requires fixes (its a complete framework that can use AES/DES/MD5/SHA). if you have changed something please post your code example so i can run it.

sglvladi commented 7 years ago

Same issue here. Using the provided example:

#include <AES.h>

AES aes ;

byte *key = (unsigned char*)"0123456789010123";

byte plain[] = "Add NodeAdd NodeAdd NodeAdd NodeAdd Node";

//real iv = iv x2 ex: 01234567 = 0123456701234567
unsigned long long int my_iv = 36753562;

void setup ()
{
  Serial.begin (57600) ;
  delay(500);
  printf("\n===testng mode\n") ;

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

void loop () 
{
  byte plain[] = "Add NodeAdd NodeAdd NodeAdd NodeAdd Node";
  prekey_test () ;
  delay(2000);
}

void prekey (int bits)
{
  aes.iv_inc();
  byte iv [N_BLOCK] ;
  byte plain_p[48];
  byte cipher [48] ;
  byte check [48] ;
  unsigned long ms = micros ();
  aes.set_IV(my_iv);
  aes.get_IV(iv);
  aes.do_aes_encrypt(plain,41,cipher,key,bits,iv);
  Serial.print("Encryption took: ");
  Serial.println(micros() - ms);
  ms = micros ();
  aes.set_IV(my_iv);
  aes.get_IV(iv);
  aes.do_aes_decrypt(cipher,48,check,key,bits,iv);
  Serial.print("Decryption took: ");
  Serial.println(micros() - ms);
  Serial.print("\n\nPLAIN :");
  for(int i = 0; i < sizeof(plain)/sizeof(plain[0]); i++)
  {
    Serial.print(plain[i]);
  }
  Serial.print("\nCIPHER:");
  for(int i = 0; i < sizeof(cipher)/sizeof(cipher[0]); i++)
  {
    Serial.print(cipher[i]);
  }
  Serial.print("\nCHECK :");
  for(int i = 0; i < sizeof(check)/sizeof(check[0]); i++)
  {
    Serial.print(check[i]);
  }
  Serial.print("\n============================================================\n");
}

void prekey_test ()
{
  prekey (128) ;
}

I have simply modified the print outs in order to get the code to run on ESP8266. Leaving aes.do_aes_encrypt(plain,41,cipher,key,bits,iv) as is and the printout is:

PLAIN :6510010032781111001016510010032781111001016510010032781111001016510010032781111001016510010032781111001010
CIPHER:32202105051122242217249114181209192272452111619220513968153219410818118521318610617229781282172182378482122103722720128235160157
CHECK :65100100327811110010165100100327811110010165100100327811110010165100100327811110010165100100327811110010188888888
============================================================

Then swapping to aes.do_aes_encrypt(plain,42,cipher,key,bits,iv) :

PLAIN :6510010032781111001016510010032781111001016510010032781111001016510010032781111001016510010032781111001010
CIPHER:3220210505112224221724911418120919227245211161922051396815321941081811852131861061722914317810991111331917717777677921923520885
CHECK :65100100327811110010165100100327811110010165100100327811110010165100100327811110010165100100327811110010107777777
============================================================

Any ideas? I really want to use the library, but this thing has been driving me crazy all day...

Thanks in advance.

spaniakos commented 7 years ago

the algorythm is correct. The way you are printing the results is wrong. Look at the results below and i will explain.

PLAIN :65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 0. 65 = A 100 = d 100 = d 32 = " " 78 = N 111 = o 100 = d 101 = e if you count the bytes on top they end as they should in character 101 The last character 0. is a terminating character. In Cryptography we need to encrypt byte by byte the string. Therefore, the terminating character should not be accounted. We always need to encrypt the string as is, without excess information. That is the reason you are getting these results. if you want to check the results with other function, please use the provided void AES::printArray(byte output[],bool p_pad) OR void AES::printArray(byte output[],int sizel)

you can check the manual at: http://spaniakos.github.io/AES/classAES.html

as you can see there is documentation for all function. the ones you need are: http://spaniakos.github.io/AES/classAES.html#a6b0db893a71f8650d3e59441c23fc9dd and http://spaniakos.github.io/AES/classAES.html#add8ddd9cce8b4de87b9ef2ff2f5ddb29

thank you spaniakos

CHECK :65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 65 100 100 32 78 111 100 101 7 7 7 7 7 7 7 7.

sglvladi commented 7 years ago

Hi again,

First of all, thanks for the quick response. Unfortunately, I still don't seem to be getting it.

I did try void AES::printArray(byte output[],int sizel) but the output still does not match plain. Here's an example:

Replaced:

Serial.print("\nCHECK :");
  for(int i = 0; i < sizeof(check)/sizeof(check[0]); i++)
  {
    Serial.print(check[i]);
  }

with:


Serial.print("\nCHECK :");
aes.printArray(check,48);

and the output is:

PLAIN :6510010032781111001016510010032781111001016510010032781111001016510010032781111001016510010032781111001010
CIPHER:32202105051122242217249114181209192272452111619220513968153219410818118521318610617229781282172182378482122103722720128235160157
CHECK :3ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f03ffef4f0

============================================================

In any case, maybe I should cut straight to the exact problem I am having. Since, it is somewhat of a different issue, I have created a separate thread (see #11) in order to discuss it.

spaniakos commented 7 years ago

please change all the print functions if you want to see the same results.

sglvladi commented 7 years ago

So, I have forked your library and made some modifications so that it is readily compatible with ESP8266. See here. Using the provided print functions (as suggested), the above issue is fixed.

However, I have another issue. The example only works if you use the same AES instance to encrypt and decrypt. Moving further discussion to #11.