Created
November 7, 2018 19:50
-
-
Save cnlohr/96128ef4126bcc878b1b5a7586c624ef to your computer and use it in GitHub Desktop.
Example of using hardware AES 256 Crypto in CBC mode on the ESP32 using ESP-IDF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string.h> | |
#include <stdio.h> | |
#include <hwcrypto/aes.h> | |
/* | |
For Encryption time: 1802.40us (9.09 MB/s) at 16kB blocks. | |
*/ | |
static inline int32_t _getCycleCount(void) { | |
int32_t ccount; | |
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount)); | |
return ccount; | |
} | |
char plaintext[16384]; | |
char encrypted[16384]; | |
int encodetest() | |
{ | |
uint8_t key[32]; | |
uint8_t iv[16]; | |
//If you have cryptographically random data in the start of your payload, you do not need | |
//an IV. If you start a plaintext payload, you will need an IV. | |
memset( iv, 0, sizeof( iv ) ); | |
//Right now, I am using a key of all zeroes. This should change. You should fill the key | |
//out with actual data. | |
memset( key, 0, sizeof( key ) ); | |
memset( plaintext, 0, sizeof( plaintext ) ); | |
strcpy( plaintext, "Hello, world, how are you doing today?" ); | |
//Just FYI - you must be encrypting/decrypting data that is in BLOCKSIZE chunks!!! | |
esp_aes_context ctx; | |
esp_aes_init( &ctx ); | |
esp_aes_setkey( &ctx, key, 256 ); | |
int32_t start = _getCycleCount(); | |
esp_aes_crypt_cbc( &ctx, ESP_AES_ENCRYPT, sizeof(plaintext), iv, (uint8_t*)plaintext, (uint8_t*)encrypted ); | |
int32_t end = _getCycleCount(); | |
float enctime = (end-start)/240.0; | |
printf( "Encryption time: %.2fus (%f MB/s)\n", enctime, (sizeof(plaintext)*1.0)/enctime ); | |
//See encrypted payload, and wipe out plaintext. | |
memset( plaintext, 0, sizeof( plaintext ) ); | |
int i; | |
for( i = 0; i < 128; i++ ) | |
{ | |
printf( "%02x[%c]%c", encrypted[i], (encrypted[i]>31)?encrypted[i]:' ', ((i&0xf)!=0xf)?' ':'\n' ); | |
} | |
printf( "\n" ); | |
//Must reset IV. | |
//XXX TODO: Research further: I found out if you don't reset the IV, the first block will fail | |
//but subsequent blocks will pass. Is there some strange cryptoalgebra going on that permits this? | |
printf( "IV: %02x %02x\n", iv[0], iv[1] ); | |
memset( iv, 0, sizeof( iv ) ); | |
//Use the ESP32 to decrypt the CBC block. | |
esp_aes_crypt_cbc( &ctx, ESP_AES_DECRYPT, sizeof(encrypted), iv, (uint8_t*)encrypted, (uint8_t*)plaintext ); | |
//Verify output | |
for( i = 0; i < 128; i++ ) | |
{ | |
printf( "%02x[%c]%c", plaintext[i], (plaintext[i]>31)?plaintext[i]:' ', ((i&0xf)!=0xf)?' ':'\n' ); | |
} | |
printf( "\n" ); | |
esp_aes_free( &ctx ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for this, here is my final version: