Closed swanav closed 5 years ago
@projectgus Please help.
Anything?
Hi @swanav, ESP-IDF includes mbedtls library. Please refer to mbedtls API reference for AES functions: https://tls.mbed.org/api/aes_8h.html
What he wants to know is how to enable encryption in smartconfig on the esp32 side
Hi @swanav ,
If you use the AES functions in the Esp-Touch library to encrypt the SSID & Password before sending then it will use a relatively simple block cipher to obfuscate the values: AES ECB mode with PKCS7 padding.
When you get the ciphertext values for SSID & Password back from the SmartConfig library on the ESP32 side, you can get back the plaintext using some code like this:
#include <string.h>
#include "esp_log.h"
#include "mbedtls/cipher.h"
const char *TAG = "esptouch decrypt";
static int decrypt_parameter(const unsigned char *ciphertext, const unsigned char *key, size_t len, unsigned char *plaintext)
{
int r;
size_t olen;
mbedtls_cipher_context_t ctx;
const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
if (len % 16 != 0) {
ESP_LOGE(TAG, "len must be a multiple of block size");
return -1;
}
mbedtls_cipher_init(&ctx);
r = mbedtls_cipher_setup(&ctx, info);
if (r != 0) {
ESP_LOGE(TAG, "mbedtls_cipher_setup failed -%x", -r);
goto done;
}
r = mbedtls_cipher_setkey(&ctx, key, 128, MBEDTLS_DECRYPT);
if (r != 0) {
ESP_LOGE(TAG, "mbedtls_cipher_setkey failed -%x", -r);
goto done;
}
r = mbedtls_cipher_reset(&ctx);
if (r != 0) {
ESP_LOGE(TAG, "mbedtls_cipher_reset failed -%x", -r);
goto done;
}
olen = 0;
for (int i = 0; i < len; i += 16) {
size_t olen_block = 16;
r = mbedtls_cipher_update(&ctx, ciphertext + i, 16, plaintext + i, &olen_block);
if (r != 0) {
ESP_LOGE(TAG, "mbedtls_cipher_update failed -%x", -r);
goto done;
}
olen += olen_block;
}
//ESP_LOG_BUFFER_HEX(TAG, plaintext, olen);
// Check and remove PKCS7 padding
uint8_t pad_len = plaintext[olen-1];
uint8_t dlen = olen - pad_len;
if (pad_len >= olen || dlen >= olen) {
ESP_LOGE(TAG, "Bad PKCS7 padding byte: %d", pad_len);
r = MBEDTLS_ERR_CIPHER_INVALID_PADDING;
goto done;
}
for (int i = dlen; i < olen; i++) {
if (plaintext[i] != pad_len) {
ESP_LOGE(TAG, "Bad PKCS7 padding byte at offset %d", i);
r = MBEDTLS_ERR_CIPHER_INVALID_PADDING;
goto done;
}
plaintext[i] = 0;
}
ESP_LOGI(TAG, "decrypt successful");
r = dlen;
done:
mbedtls_cipher_free(&ctx);
return r;
}
void app_main()
{
const unsigned char key[16] = "secret key!!"; // will 0-pad to 16 bytes
unsigned char ciphertext[32] = {
0x1a, 0x8a, 0x97, 0x89, 0xb7, 0x1e, 0xa4, 0x36, 0x08, 0x53, 0x25, 0x21, 0x5d, 0x53, 0xe5, 0x0d, 0x77, 0x67, 0x8b, 0xa1, 0xde, 0x56, 0x38, 0xdb, 0x20, 0x0e, 0x52, 0xf4, 0x60, 0xe8, 0xfa, 0xd2, };
unsigned char plaintext[32] = { 0 }; // note: must be same size as ciphertext buffer
int r = decrypt_parameter(ciphertext, key, sizeof(ciphertext), plaintext);
ESP_LOGI(TAG, "decrypt result %d", r);
ESP_LOGI(TAG, "plaintext as a string: %s\n", plaintext);
printf("Done");
}
(Note: The above de-padding code leaks some timing information which could be used to find length of SSID/password in bytes. If you need that level of security then you may want to consider using a different cipher combination in app & firmware as well.)
(I'm going to close this, but please comment and will reopen if the code above isn't working.)
@projectgus Ok but the fact that you can just pass the aes key on the client side means it should be just as easy on the device side
Ok I see it is private and there is this note:
Hide EsptouchTask's aes constructor, device doesn't support currently
Time to fix?
@negativekelvin For now, using AES in EspTouch will require some hacking of the library. We are discussing about adding some more complete encryption support, but possibly this will use a different cipher scheme.
There is a research paper concluding that the use of Esptouch creates a security risk since it does not use encryption by default: https://loccs.sjtu.edu.cn/~romangol/publications/wisec18.pdf
It would be good if Espressif would implement fixes here.
Hi @projectgus,
thank you for the great solution. I am using Platformio and i will like to use the AES key in Esptouch V2 with Esp32. Has this solution already been updated in the present Wifi.h and SmartConfig libary? Is there an example or a guideline of how I can implement it?
That will be great thanks and Have a nice day :)
I know this is a bit old but, I felt it is important to reply. The AES encryption is available through ESPTOUCH_V2
typedef struct {
bool enable_log; /**< Enable smartconfig logs. */
bool esp_touch_v2_enable_crypt; /**< Enable ESPTouch v2 crypt. */
char *esp_touch_v2_key; /**< ESPTouch v2 crypt key, len should be 16. */
} smartconfig_start_config_t;
#define SMARTCONFIG_START_CONFIG_DEFAULT() { \
.enable_log = false, \
.esp_touch_v2_enable_crypt = false,\
.esp_touch_v2_key = NULL \
};
The ESPTouch library for Android and iOS includes a class called
EspAes
for AES encryption while using EspTouch. But there are no references to the same AES functionality in the ESP-IDF api reference or any of the examples. How can I implement the AES functionality in my firmware?