AES Encryption and general understanding

Hi,
I’m trying to understand how the aes encryption given by this library ( GitHub - intrbiz/arduino-crypto: A minimal crypto library for ESP8266 Arduino ) and this code work

#include <Crypto.h>
#include <base64.hpp>

#define BLOCK_SIZE 16

uint8_t key[BLOCK_SIZE] = { 0x1C,0x3E,0x4B,0xAF,0x13,0x4A,0x89,0xC3,0xF3,0x87,0x4F,0xBC,0xD7,0xF3, 0x31, 0x31 };
uint8_t iv[BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

void bufferSize(char* text, int &length)
{
  int i = strlen(text);
  int buf = round(i / BLOCK_SIZE) * BLOCK_SIZE;
  length = (buf <= i) ? buf + BLOCK_SIZE : length = buf;
}
    
void encrypt(char* plain_text, char* output, int length)
{
  byte enciphered[length];
  RNG::fill(iv, BLOCK_SIZE); 
  AES aesEncryptor(key, iv, AES::AES_MODE_128, AES::CIPHER_ENCRYPT);
  aesEncryptor.process((uint8_t*)plain_text, enciphered, length);
  int encrypted_size = sizeof(enciphered);
  char encoded[encrypted_size];
  encode_base64(enciphered, encrypted_size, (unsigned char*)encoded);
  strcpy(output, encoded);
}

void decrypt(char* enciphered, char* output, int length)
{
  length = length + 1; //re-adjust
  char decoded[length];
  decode_base64((unsigned char*)enciphered, (unsigned char*)decoded);
  bufferSize(enciphered, length);
  byte deciphered[length];
  AES aesDecryptor(key, iv, AES::AES_MODE_128, AES::CIPHER_DECRYPT);
  aesDecryptor.process((uint8_t*)decoded, deciphered, length);
  strcpy(output, (char*)deciphered);
}

void setup() {
  Serial.begin(115200);
  while (!Serial) {
    ; //wait
  }
  
}

void loop() {
  char plain_text[] = "G0 X25";
  unsigned long time = 0;
  
  time = micros();
  // encrypt
  int length = 0;
  bufferSize(plain_text, length);
  char encrypted[length];
  encrypt(plain_text, encrypted, length);
  

  Serial.println("");
  Serial.print("Encrypted: ");
  Serial.println(encrypted); 
  Serial.print("en ");
  Serial.print(micros()-time);
  Serial.println(" µs");
  time = micros();
  // decrypt
  length = strlen(encrypted);
  char decrypted[length];
  decrypt(encrypted, decrypted, length);

  Serial.print("Decrypted: ");
  Serial.println(decrypted);

   Serial.print("en ");
  Serial.print(micros()-time);
  Serial.println(" µs");

  delay(5000);
}

I expected to get the same encoded text at each reboot but every time I restart the esp8266 I get a new encrypted text so I’m not able to understand how the protocol works even with wikipedia explanation and how to decode strings from an external server
The code works but if I send the first encoded string via mqtt I’m not able to decrypt the string after the reboot
(Two program here: First I encode the text and then I use another program to receive the string via mqtt and decode it.
Same key, same iv and both at the first try so the key is expected to be the same, right?)
The final aim is to comunicate with a nodejs server.
I’ve found a lot of code on the web but the given library is the only one which compile on nodemcu.
Is anyone able to explain me why it does not works and how to make that works?

Thanks
Guillaume

I would suspect code lines like: RNG::fill(iv, BLOCK_SIZE); Are causing your issue.

Thanks for your reply The given code works but when i'm trying to encrypt on a device and decrypt with a second device (Actually it's the same esp8266 but with differents codes) I get a weird thing (something like a big string composed by few letters and a lot of "?") I'm unable to understand why I can't encrypt and decrypt if I start with the same initial conditions on two devices. Keys and iv are the same for both codes and I'm trying for the first string so the encryption key (if everythings is clear on my mind) must be the same for both codes at the same iteration

The other thing I'm unable to understand is why, when I restart the esp I don't get the same encrypted string for the same iteration and the same key + iv

RNG is a function to generate a random number...

So everytime it’s run it gives a different value. Well ideally everytime at least.

Maybe change any parts that are RNG generated into a “fixed number” to see if that stops your issue of the numbers not working after a reboot reset and on different units..

Send the random IV first, then the encrypted data. The IV keeps the first blocks of the encryption from being the same when the same shared key is used to encrypt the same plaintext (even if only the same in the leading blocks.

Thanks a lot, issue is solved I didn't notice that iv was generated randomly. I thought it was calculated IV will be generated on the serve side so I can delete this part from the esp