Created
March 12, 2022 11:13
-
-
Save VNovytskyi/e6d29b3d473a41141e27059a25e64100 to your computer and use it in GitHub Desktop.
Arduino ESP32 RSA OAEP decryption with Base64 decoding
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 "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