suculent / thinx-aes-lib

AES wrapper for ESP8266/ESP32/Arduino/nRF5x
Other
118 stars 37 forks source link

encryption result always equal iv #76

Closed wiryonolau closed 5 months ago

wiryonolau commented 5 months ago

Hi , I have problem encrypting uint32_t message

wokwi simulation

Is there an error in my code

#include <AESLib.h>

byte aesKey[16] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
AESLib aesLib;

void generateRandomIV(byte* iv, int length) {
  for (int i = 0; i < length; i++) {
    iv[i] = random(0, 256);
  }
}

void printByteArray(byte* arr, int length) {
  for (int i = 0; i < length; i++) {
    if (arr[i] < 0x10) {
      Serial.print("0");
    }
    Serial.print(arr[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

void uint32ToBytes(uint32_t value, byte* bytes) {
  bytes[0] = (byte)(value >> 24);
  bytes[1] = (byte)(value >> 16);
  bytes[2] = (byte)(value >> 8);
  bytes[3] = (byte)value;
}

void encrypt(uint32_t message, byte* cipherText, int& outputLength) {
  byte messageBytes[4];
  uint32ToBytes(message, messageBytes);

  Serial.print("Message : ");
  printByteArray(messageBytes, 4);

  int messageLength = sizeof(messageBytes);
  int blockSize = 16;
  int paddedLength = ((messageLength / blockSize) + 1) * blockSize;
  byte paddedMessage[paddedLength];

  Serial.print("Padded Length : ");
  Serial.println(paddedLength);

  memcpy(paddedMessage, messageBytes, messageLength);
  byte paddingValue = paddedLength - messageLength;
  for (int i = messageLength; i < paddedLength; i++) {
    paddedMessage[i] = paddingValue;
  }

  Serial.print("Padded Message : ");
  printByteArray(paddedMessage, paddedLength);

  byte iv[16];
  byte encryptedMessage[16];

  generateRandomIV(iv, 16);
  // aesLib.set_paddingmode((paddingMode)0);
  outputLength = aesLib.encrypt(paddedMessage, paddedLength, encryptedMessage, aesKey, 128, iv);

  memcpy(cipherText, iv, 16);
  memcpy(cipherText + 16, encryptedMessage, 16);

  Serial.print("IV : ");
  printByteArray(iv, 16);

  Serial.print("Encrypted : ");
  printByteArray(encryptedMessage, 16);

  Serial.print("Final : ");
  printByteArray(cipherText, 32);

  // Set output length
  outputLength += paddedLength;

}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  randomSeed(analogRead(0));

  uint32_t data = (uint32_t)0xFFFFFFFF;
  int outputLength;
  byte encryptedMessage[32];
  encrypt(data, encryptedMessage, outputLength);
}

void loop() {
  // put your main code here, to run repeatedly:
}

Here is example result Encrypted message always equal iv

Message : FF FF FF FF 
Padded Length : 16
Padded Message : FF FF FF FF 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 
IV : 6E 22 58 FC A5 F1 80 DB 88 9D FD B8 D6 2B 31 78 
Encrypted : 6E 22 58 FC A5 F1 80 DB 88 9D FD B8 D6 2B 31 78 
Final : 6E 22 58 FC A5 F1 80 DB 88 9D FD B8 D6 2B 31 78 6E 22 58 FC A5 F1 80 DB 88 9D FD B8 D6 2B 31 78 
suculent commented 5 months ago

This is indeed error from secure coding perspective, however in this case it is intentional to have the static IV.

wiryonolau commented 5 months ago

Updated the simulation Apparently when calling encrypt , aeslib change the iv variable. So I have to copy it first before doing encrypt.

suculent commented 5 months ago

The IV is supposed to be rolling. Just examples are resetting it for simplicity so it doesn’t have to be transferred. uint32 is too short for block cipher. You should use stream cipher (ChaCha/Poly kind).M. 11. 6. 2024 v 3:22, Sakya @.***>: Updated the simulation Apparently when calling encrypt , aeslib change the iv variable. So I have to copy it first before doing encrypt.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>

wiryonolau commented 5 months ago

The IV is supposed to be rolling. Just examples are resetting it for simplicity so it doesn’t have to be transferred. uint32 is too short for block cipher. You should use stream cipher (ChaCha/Poly kind).M. 11. 6. 2024 v 3:22, Sakya @.***>: Updated the simulation Apparently when calling encrypt , aeslib change the iv variable. So I have to copy it first before doing encrypt.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>

I see. My message is short max at 4 byte, so uint32 is suffice.

it is working ok if I copy the iv to other variable before encrypt.

Thanks.

suculent commented 5 months ago

Just set the same IV before each encrypt, as in examples. It’s not 100% secure, but still better than sending plaintext.

Cheers, Matej

On 13. 6. 2024, at 1:18, Sakya @.***> wrote:

The IV is supposed to be rolling. Just examples are resetting it for simplicity so it doesn’t have to be transferred. uint32 is too short for block cipher. You should use stream cipher (ChaCha/Poly kind).M. 11. 6. 2024 v 3:22, Sakya @.***>: Updated the simulation Apparently when calling encrypt , aeslib change the iv variable. So I have to copy it first before doing encrypt.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>

I see. My message is short max at 4 byte, so uint32 is suffice.

it is working ok if I copy the iv to other variable before encrypt.

Thanks.

— Reply to this email directly, view it on GitHub https://github.com/suculent/thinx-aes-lib/issues/76#issuecomment-2164047192, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABWFRYMB3PG4CSM6K2AFETZHDJKZAVCNFSM6AAAAABJCPKVGOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNRUGA2DOMJZGI. You are receiving this because you commented.