Mbedtls_pk_decrypt returns -17184 (0x4320) error

Hi everyone,

I am trying to decrypt a RSA-2048 message by using MbedTLS on an expressif esp32 board.

mbedtls_pk_parse_key works but when I invoke to mbedtls_pk_decrypt it returns an unknown error code
-17184 (0x4320)

Has anybody experience same problem?

A simplified version of the code is enclosed as follows:

std::string validateRSA (unsigned char * messageEncripted)
{
int status;
mbedtls_pk_context pk;
mbedtls_ctr_drbg_context ctr_drbg;

unsigned char decrypted[MAX_LENGTH_MESSAGE];
size_t decriptedMessageSizeOlen = 0;

const unsigned char mbedtls_private_key = “-----BEGIN RSA PRIVATE KEY-----\n”
“MIIEoQIBAAKCAQBjl+RyR7ujndXhkJTJOL2b3xk3oZ6KZC/LZJgdxDqHp548EuUB\n”
“ILHySlGRawmgPDxJyrtLj0Emv1ffy9J+I+xTRMtMNsDi8tN428mB3pOGLhwbcMoC\n”
“sSRwLsNbcz2g79PoXIgS1T3VfPIl56fihdXPqMGhj4aNBfehiAu7YrV24wcsBq2L\n”
“bXAuTnZJizHOUoA+UBv1y9IxjOFW4+5x1YOVQF+wDEvZ2BHmnIC3p79GCj+coOto\n”
“GCKMNOendMh4XujmOxpsPKIZr/Gm1KhacNYJhm4BhQHTiJ5T7srDd5wBBpQM6oMT\n”
“NLSiUyDhtoOb1YVOnltBmv2qLeXWrr0mS8FXAgMBAAECggEALhNnrTdiqB+tg93P\n”
“+Ag4MJTWpdYv8vbG5eJ0PdE7AueZXVGggRUPPnkDo7NRkMBNZBZW8G4mRjbgALnb\n”
“eGBGRX/eTjRGqLiO/asxXtQKjFlox4k27Gfn476+wuBd8scB0s58ZboiEVLs9Hxo\n”
“P3SLprb8XjJ4nWXVWvYF93uDWKy5nYt4mkFTDU9URBVyjhsnyX58+uS27TM5NfaS\n”
“iwAbyT/anFbr/27mO3SRONoGRmhnacLU0x0ZIWFJZILwpeCTrCeUjZNzkCUZMyOo\n”
“6UOdplRtJ7DGrM9Z4GH6LbH2VVZkbdDRFngza2EJ226mZubE6y2M46gkwUk44mpm\n”
“XUHIgQKBgQDAiVLmyus+Vz26o22wBaY2W4n8eX1gwzutEMV25zosqbiZqcZLa00w\n”
“tfD7LNlDxDebMBuaH8Reu8tPjkjtNl6YkUkA4+cj4X7iJ8naS1AZGVir6YiAbLvP\n”
“941BbNJmoTDaWk+HdTAD+8BLkMMDonryO+70h7Y0qMKZlx740jzVHQKBgQCEa8/S\n”
“3Ki3/5KttJ+LewOkw4O87I3JOYulIi+v3JXg58ja/vcsJefpErkxq/G/uaCKml2c\n”
“v7uMKz3eTCHQ6pYM8sYNvGl6Iui1DMfVHCBGPj6dhDZ5UP/QhkttYIon8Ea3GGu1\n”
“tobV5+uuCL1yjZLxfHEOOv/eIqs+6TW4pVCqAwKBgDDAFJ+fbaUhTd3+F33kUEuf\n”
“Lfchg9+GT4vonTcYISDB8J3n4O+jwa29w8C1gGWqPzIqIjMKLByYjEgejNSTWaxj\n”
“zQpOqm3pYMk+rdt6ClPwmQUeYpOx9HQaCEgyl6uo0MfY6h4wS/IWQoBfrSE0eNDw\n”
“3/ZGjpoSyQM+wnbaNND5AoGAKObwO46C4sqjcNowybGGj5cAkxNyPCx1MN2dYzG8\n”
“bcrKZLKKgG1486of3/LfajwZFZbWwXsLoCEfLBHSBCjhjkBS4p1G6z3rKTk4ZGAa\n”
“q/e/+YGEHfbh/XPtymweYHW8MgPuCSPHBD1ts8TpV3/ZWpP4i8+3htKomHcKa+1M\n”
“PCcCgYBOIDHBeHI8VItDkkX9wzm8pClA6V+c6T/uf/GXXWIbRi+p5omtdNxzQBt1\n”
“5nTlmkX6TW3Q08/fZv6LTmGfpeWytezq5ER51i5d0ReJg32I6Y3EmqLoqdwij+7V\n”
“UGw7O/wD1lDKuiRrMCogvUTg0Q4Z6w6ax3jfZH3UtWASg2Z5QA==\n”
“-----END RSA PRIVATE KEY-----\n”;

mbedtls_pk_init(&pk);
mbedtls_ctr_drbg_init(&ctr_drbg);

// Parse private key
status = mbedtls_pk_parse_key( &pk, mbedtls_private_key, strlen((const char *)mbedtls_private_key) + 1, NULL, 0);
if (status != 0)
{
return “error”;
}

// validateRSA mbedtls_pk_decrypt returns error:-17184 ( 0x4320 )

status = mbedtls_pk_decrypt( &pk, (const unsigned char *) messageEncripted, strlen((char *) messageEncripted), (unsigned char *) decrypted, &decriptedMessageSizeOlen, sizeof(decrypted),
mbedtls_ctr_drbg_random, &ctr_drbg );
if (status != 0)
{
return “error”;
}

Serial.println(F(“validateRSA3 OK!”));
Serial.println((char *)decrypted);

mbedtls_pk_free(&pk);
mbedtls_ctr_drbg_free(&ctr_drbg);

std::string *dev = new std::string((char *)decrypted);
return *dev;
}

Thanks in advance

Hi @mabitainnova

First, you should not publish your private key in the public. This should be a key for your test purposes only.
Please replace the key pair you are using.

As for your code, running the utility program strerror you will see:

Last error was: -0x4320 - RSA - The private key operation failed : AES - Invalid key length

The only place an AES error might be returned in you rrsa decryption, is in the mbedtls_ctr_drbg_random function for the blinding.

  • Does this error happen when you don’t use key blinding? ( Send NULL instead of mbedtls_ctr_drbg_random and 0 instead of &ctr_drbg)?
  • I don’t see in your sample where you seed your ctr_drbg. Does you real code have a sseding operation?
    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
                                       &entropy, (const unsigned char *) pers,
                                       strlen( pers ) ) ) != 0 )
  • Does you device have a hardware accelerated AES? If so, doyou have an alternative implementation of AES? What AES key sizes does it support? Specifically, does your board support AES 256? What does mbedtls_aes_setkey_enc() on your board return for 256 bit key size?
  • If your board doesn’t support AES 256 ( and only in this case), what is returned if you enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY in your configuration?
    Regards,
    Mbed TLS Support
    Ron

Thanks, it was solved.

Private key was only for testing purposes :smiley:

Hi @mabitainnova
Thank you for your information.
For the record, may I know what solved your issue?
Regards

Hi @roneld01,

I got the solution from RSA-example/main.c at master · Secure-Embedded-Systems/RSA-example · GitHub. The function mbedtls_pk_decrypt requires to add as parameter sizeof(buffer)-1.

I share the final solution. We receive a JSON message from BLE connection, so first we need to desealize the Json, then decode Base64 and then decrypt.

std::string validateRSA (std::string messageEncripted)
{

StaticJsonDocument<MAX_LENGTH_MESSAGE> doc;
unsigned char decrypted[MAX_LENGTH_MESSAGE];
DeserializationError error;

static uint8_t privkey = “-----BEGIN RSA PRIVATE KEY-----\n”
“MIIEoQIBAAKCAQBjl+RyR7ujndXhkJTJOL2b3xk3oZ6KZC/LZJgdxDqHp548EuUB\n”
“ILHySlGRawmgPDxJyrtLj0Emv1ffy9J+I+xTRMtMNsDi8tN428mB3pOGLhwbcMoC\n”
“sSRwLsNbcz2g79PoXIgS1T3VfPIl56fihdXPqMGhj4aNBfehiAu7YrV24wcsBq2L\n”
" … "
“-----END RSA PRIVATE KEY-----\n”;

const char *pers = “rsa_decrypt”;

// Get signature from JSON
error = deserializeJson(doc, messageEncripted);
if (error)
{
return “error”;
}

const char* signature = doc[“signature”];

mbedtls_entropy_context entropy;
mbedtls_entropy_init( &entropy );

mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ctr_drbg_init(&ctr_drbg);

mbedtls_pk_context pk;
mbedtls_pk_init( &pk );

int ret;

if (( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
&entropy, (const unsigned char *) pers,
strlen( pers ) ) ) != 0)
{
return “error”
}

if ((ret=mbedtls_pk_parse_key(&pk, privkey, sizeof(privkey), NULL, 0)) != 0)
{
return “error”;
}

int signatureBase64Length = b64_decoded_size(signature);

unsigned char signatureDecodedBase64[MAX_LENGTH_MESSAGE];
b64_decode((const char *)signature, (unsigned char *)signatureDecodedBase64, (signatureBase64Length + 1));
signatureDecodedBase64[signatureBase64Length] = ‘\0’;

size_t olen = 0;

int sizeBase64 = strlen((char *) signatureDecodedBase64);
uint8_t ctBase64DecodeHex[sizeBase64 + 1];
int iterator = 0;
while (iterator < sizeBase64)
{
ctBase64DecodeHex[iterator] = (uint8_t)signatureDecodedBase64[iterator];
iterator++;
}
ctBase64DecodeHex[sizeBase64] = ‘\0’;

if( ( ret = mbedtls_pk_decrypt( &pk, ctBase64DecodeHex, sizeof(ctBase64DecodeHex)-1, decrypted, &olen, sizeof(decrypted),
mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
{
return “error”;
}
decrypted[olen] = ‘\0’;

mbedtls_pk_free( &pk );
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free( &entropy );
doc.clear();

std::string *dev = new std::string((char *)decrypted);
return *dev;
}

Best regards,