suculent / thinx-aes-lib

AES wrapper for ESP8266/ESP32/Arduino/nRF5x
Other
113 stars 39 forks source link

Error Decrypt64 function on ESP32 #58

Closed emanavas closed 1 year ago

emanavas commented 2 years ago

The problem its the code do a decode of base64 text on same variable. I propouse the solution for this issue: on AESLib.cpp:

/* Suggested size for the plaintext buffer is 1/2 length of `msg`. Refactor! */
uint16_t AESLib::decrypt64(char * msg, uint16_t msgLen, char * plain, const byte key[],int bits, byte my_iv[]) {

#ifdef AES_DEBUG
  Serial.println("[decrypt64] decrypting message:  ");
#endif

  aes.set_key(key, bits);

#ifdef AES_DEBUG
  Serial.print("[decrypt64] msgLen (strlen msg):  "); Serial.println(msgLen);
#endif

  // decoded base64 takes some space, but less than original...
  // it should therefore never overfill when reusing the msg-text buffer
  char *msgOut = (char*)malloc(msgLen);
  int b64len = base64_decode(msgOut, msg, msgLen);

  // decrypting will keep the message length
#ifdef AES_DEBUG
  Serial.print("[decrypt64] base64_decode allocating decrypt buffer len:  "); Serial.println(b64len);
#endif

  byte out[b64len]; // unfortunately this needs to fit to stack... that's hard limit for chunk

#ifdef AES_DEBUG
  // Serial.print("[decrypt64] Clearing-out buffer to allow safe strlen (zero-in-the-middle will still fail)...");
#endif

  if (b64len > 0) {
    // void * memset ( void * ptr, int value, size_t num );
    memset( out, 0x00, b64len );
  }

#ifdef AES_DEBUG
#ifdef ESP8266
  Serial.print("[decrypt64] free heap: "); Serial.println(ESP.getFreeHeap());
#endif
#endif

  int b64_len = aes.do_aes_decrypt((byte *)msgOut, b64len, (byte*)out, key, bits, (byte *)my_iv);
  // ToWI: 2021-01-22: Check the padding length, negative value means deciphering error and cause ESP restarts due to stack smashing error
  free(msgOut);
  if (b64_len < 0)
      return 0;

  out[b64_len] = 0;
  memset( plain, 0x00, msgLen );
  memcpy((byte*)plain, (byte*)out, b64_len);

#ifdef AES_DEBUG
  for(byte i=0; i<b64_len;i++)
    printf("%X ",out[i]);
  printf("\n");
  //Serial.print("[decrypt64] aes_decrypt length before b64-decode:  "); Serial.println(b64_len);
#endif
/*
  // calculate required output length
  uint16_t outLen = base64_dec_len((char*)out, b64_len);

#ifdef AES_DEBUG
  Serial.print("[decrypt64] expected base64_dec_len after b64-decode:  "); Serial.println(outLen);
#endif

  // decode buffer to output plain-text, output buffer will never overfill...
  outLen = base64_decode(plain, (char *)out, b64_len);
  // plain[outLen+1] = 0; // trailing zero for safety?

#ifdef AES_DEBUG
  Serial.print("[decrypt64] base64_decode->outLen =  "); Serial.println(outLen);
#endif
*/
  // only this method can return b64
  return b64_len;
}

the diferent respect original code it's do a malloc of a tmp var to store the output of decode base64 text and use this new var for do a AES decrypt.

suculent commented 2 years ago

Can you fork it and make a proper PR so I can see the differences? I see you can probably code better than write Czech (which is my native language :-)). Thanks.