Skip to content

Instantly share code, notes, and snippets.

@VNovytskyi
Created March 12, 2022 11:13
Show Gist options
  • Save VNovytskyi/e6d29b3d473a41141e27059a25e64100 to your computer and use it in GitHub Desktop.
Save VNovytskyi/e6d29b3d473a41141e27059a25e64100 to your computer and use it in GitHub Desktop.
Arduino ESP32 RSA OAEP decryption with Base64 decoding
#include "mbedtls/pk.h"
#include "mbedtls/rsa.h"
#include "mbedtls/error.h"
#include "mbedtls/base64.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#define PERS "rsa_encrypt"
const char* esp_pub_key_pem_test = "-----BEGIN PUBLIC KEY-----\n\
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUFcS52Ld0we4h8ZSPQTqMgv0I\n\
yRMOvUn81RRfRFO0Htuk6tn1CtXVdKq0Kd+w8Q9L0AKIfekBxQc53xEj+6Y3lg7k\n\
gtM6Q0s04AKUYzrHkcE/7ZL9pLuFzmbnyDAgCMaVoYQ29b+9328LA1B4s64ffMUS\n\
BalvdyJ9xPoAELaYEwIDAQAB\n\
-----END PUBLIC KEY-----";
const char* esp_priv_key_pem_test = "-----BEGIN PRIVATE KEY-----\n\
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJQVxLnYt3TB7iHx\n\
lI9BOoyC/QjJEw69SfzVFF9EU7Qe26Tq2fUK1dV0qrQp37DxD0vQAoh96QHFBznf\n\
ESP7pjeWDuSC0zpDSzTgApRjOseRwT/tkv2ku4XOZufIMCAIxpWhhDb1v73fbwsD\n\
UHizrh98xRIFqW93In3E+gAQtpgTAgMBAAECgYAKqpC7dC0up0NQRZbWRLQDZ/Hy\n\
3ozVXHQGVpC7le/Tgv9+Hv5pBIlHcTpUdMmsdIiOBOMR0sPkQT1WgUc6SMd9kG/h\n\
WinXTnGUdx1ZiR8FuTXtVi4NZnpFpFg7Dv2JjX197aGYmcOYAL9FWAi87mZlVR1a\n\
cKVwKx+vhwCIATUNfQJBAMUpD2QacEs7239F97CWblSaKS7BKRb2RVuABzByL9zK\n\
kwxHwuzHQ/BTlTuXbcK7hV6DbXCquUU/8In0A7qAgtUCQQDAR2Edyhcm8wShavxI\n\
UWH8ERF6qBhCn5TamXePteHoTRBFDbFux6BWrLbeXCxQMAikObHsSYi+1zWHKUpB\n\
KpNHAkA9uRYFa7V+CBY2aQwa721I9R4xce1QL/cUpycZBpZvU8fnT0v53oQpZ7FP\n\
f5+wGA6vwQtw+zGXOWYvegH00CilAkAWOWnhPpWUe+xiF/KXDUkNEI/7pGhBcx6K\n\
ccifBL/a0OV7hcynaE2BFy9/3hmFHzgweza0f/9dR5S5Ta12gMxLAkALEOGT5hfY\n\
x68v8P0OHj8DG8BKtbX81tyUE0n6qPx8228GyAjPX6SS4Gdc8pZDpn0XNKtQTe6U\n\
ssKUNkvdee7V\n\
-----END PRIVATE KEY-----";
mbedtls_pk_context private_key;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
size_t get_decoded_size(const char *base64_str_p) {
if (base64_str_p == NULL) {
return 0;
}
size_t pad_char_count = 0;
size_t base64_str_len = strlen(base64_str_p);
if ((base64_str_len < 4) || (base64_str_len % 4 != 0)) {
return 0;
}
if (base64_str_p[base64_str_len - 1] == '=') {
pad_char_count++;
}
if (base64_str_p[base64_str_len - 2] == '=') {
pad_char_count++;
}
return (3 * (base64_str_len / 4)) - pad_char_count;
}
void setup() {
const char *data_base64 = "P63rXnF40nLwvvhPfE/et+kGjttMPHd13nEQazXudx1lhC4Udk8v7Qhsu+13qZa66l3AgTg6Vqa/JDOCGzdzYfbzAPUkXl5PgWZoloSqReqJsQn5F0GvMAQUnpTUXKPIr7yAvM0IY/mwOkut/3mjMa9LhMVbb1pF+ryRRi7zt18=";
//Allocate memory for decoded byte array
size_t calc_decode_size = get_decoded_size(data_base64);
uint8_t *decoded_data_buff = (uint8_t *)malloc(calc_decode_size);
if (decoded_data_buff == NULL) {
printf("Fail to allocate %zu bytes...\n", calc_decode_size);
return;
}
//Decoding base64 string
size_t decoded_data_length = 0;
int res = mbedtls_base64_decode(
decoded_data_buff,
calc_decode_size,
&decoded_data_length,
(const uint8_t*)data_base64,
strlen(data_base64)
);
if (res != 0) {
char err_buff_str[128];
mbedtls_strerror(res, err_buff_str, sizeof(err_buff_str));
printf("Failed decode data, error: %s\n", err_buff_str);
free(decoded_data_buff);
return;
}
//Parsing RSA private key in PEM format from string
mbedtls_pk_init(&private_key);
size_t key_len = strlen(esp_priv_key_pem_test) + 1;
res = mbedtls_pk_parse_key(&private_key, (const uint8_t*)esp_priv_key_pem_test, key_len, NULL, 0);
if (res != 0) {
char buff[512];
mbedtls_strerror(res, buff, sizeof(buff));
printf("Parse key error: %s\n", buff);
free(decoded_data_buff);
return;
}
//Initialization of the random generation
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_entropy_init(&entropy);
res = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const uint8_t*)PERS, strlen(PERS));
if (res != 0) {
char buff[512];
mbedtls_strerror(res, buff, sizeof(buff));
printf("Seed error: %s\n", buff);
free(decoded_data_buff);
return;
}
//Set padding according to PKCS_V21
mbedtls_rsa_set_padding(mbedtls_pk_rsa(private_key), MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
size_t key_size = mbedtls_pk_rsa(private_key)->len;
uint8_t *decrypt_data_buff = (uint8_t *)malloc(key_size);
if (decrypt_data_buff == NULL) {
printf("Fail to allocate %zu bytes...\n", key_size);
free(decoded_data_buff);
return;
}
size_t decrypted_length = 0;
res = mbedtls_rsa_rsaes_oaep_decrypt(
mbedtls_pk_rsa(private_key),
mbedtls_ctr_drbg_random,
&ctr_drbg,
MBEDTLS_RSA_PRIVATE,
NULL,
0,
&decrypted_length,
(const uint8_t*)decoded_data_buff,
decrypt_data_buff,
key_size
);
if (res != 0) {
char buff[512];
mbedtls_strerror(res, buff, sizeof(buff));
printf("Decryption failed: %s\n", buff);
free(decoded_data_buff);
free(decrypt_data_buff);
return;
}
printf("Decrypted: %s\n", decrypt_data_buff);
free(decoded_data_buff);
free(decrypt_data_buff);
}
void loop() {
delay(10);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment