Parsing EC Keys created with openssl

Hi,

i created a keypair using openssl and curve secp256r1 using the following commands:

openssl ecparam -genkey -name secp256r1 -out priv.pem
openssl ec -in priv.pem -pubout -out pub.pem

I copied the resulting strings in my c-code and tryied to parse them using mbedtls_pk_parse_key.

While the parsing succeeds the verify will fail. I have been able to verify the keypair with another library. So I guess the parsing is somehow wrong. However, I cannot detect any misbehaviour when stepping through the parse functions. Do you have a hint how to proceed?

Further, I would prefer to import directly the binary representations of the keys. Is there a interface to do so instead of parsing the strings?

See below for my code:

#include "mbedtls/sha256.h"
#include "mbedtls/memory_buffer_alloc.h"
#include "mbedtls/pk.h"
#include "mbedtls/ctr_drbg.h"


const uint8_t pubKeyOpenSSL[]  = "-----BEGIN PUBLIC KEY-----\r\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE47/JslJ5N94yGC5xRNB+4IV/5bT4\r\nVVXz1NcFOY7+mV8AhHvK0K0VTJsU/RLYQ2QPV+lNYjBAPfP2BLE35TnJBg==\r\n-----END PUBLIC KEY-----";
const uint8_t privKeyOpenSSL[] = "-----BEGIN EC PRIVATE KEY-----\r\nMHQCAQEEIBK1MYhb8HK+1vDRK4wNskDGBS51F1w8dZmVzbhQqOhyoAcGBSuBBAAK\r\noUQDQgAEHiDVK9AhsXMJ6I2YF5MvLYM65f779UvEAgJHKTI0Dj6mT49zm9/oqgPq\r\nIRl5me3tlvVAj5bLy8wVbJ85CQTYaw==\r\n-----END EC PRIVATE KEY-----";

const uint8_t pubKeyOpenSSLBin[] = {0x04, 0x1e, 0x20, 0xd5, 0x2b, 0xd0, 0x21, 0xb1, 0x73, 0x09, 0xe8, 0x8d, 0x98, 0x17, 0x93, 0x2f, 0x2d, 0x83, 0x3a, 0xe5, 0xfe, 0xfb, 0xf5, 0x4b, 0xc4, 0x02, 0x02, 0x47, 0x29, 0x32, 0x34, 0x0e, 0x3e, 0xa6, 0x4f, 0x8f, 0x73, 0x9b, 0xdf, 0xe8, 0xaa, 0x03, 0xea, 0x21, 0x19, 0x79, 0x99, 0xed, 0xed, 0x96, 0xf5, 0x40, 0x8f, 0x96, 0xcb, 0xcb, 0xcc, 0x15, 0x6c, 0x9f, 0x39, 0x09, 0x04, 0xd8, 0x6b};
const uint8_t privKeyOpenSSLBin[] = {0x12, 0xb5, 0x31, 0x88, 0x5b, 0xf0, 0x72, 0xbe, 0xd6, 0xf0, 0xd1, 0x2b, 0x8c, 0x0d, 0xb2, 0x40, 0xc6, 0x05, 0x2e, 0x75, 0x17, 0x5c, 0x3c, 0x75, 0x99, 0x95, 0xcd, 0xb8, 0x50, 0xa8, 0xe8, 0x72};


const unsigned char testInput[] = "ksdfmlösdmflödsmflömmmmmlmmkmkklümlllkkpkk234hhhallllloooosdfokokopsadkfopdskfopsdkofpkdsofpvjijviodjiosdjvüjsdiovjasksdopfkopfksdfmlösdmflödsmflömmmmmlmmkmkklümlllkkpkk234hhhallllloooosdfokokopsadkfopdskfopsdkofpkdsofpvjijviodjiosdjvüjsdiovjasksdopfkopfk";

uint8_t cipherText[256] = {0};
unsigned char messageDigest[32] = {0};

#define LENGTH_OF_STATIC_MEMORY 8000
unsigned char memory_buf[LENGTH_OF_STATIC_MEMORY];

int getEntropyItfFunction(void* userData,uint8_t* buffer,size_t bytes)
{
	int i;
	for(i = 0; i < bytes ; i++)
	{
		buffer[i] = i;
	}
	
	return 0;
}


int main(void)
{
	int rC;
	
	mbedtls_sha256_context sha256;

	mbedtls_sha256_init(&sha256);

	mbedtls_sha256_starts(&sha256,0);

	mbedtls_sha256_update(&sha256,testInput,sizeof(testInput));

	mbedtls_sha256_finish(&sha256, messageDigest );

	mbedtls_pk_context privateKey;
	mbedtls_ctr_drbg_context ctr_drbg;

	mbedtls_ctr_drbg_init( &ctr_drbg );

	rC = mbedtls_ctr_drbg_seed( &ctr_drbg, getEntropyItfFunction,NULL, NULL, 0);
		if(rC != 0){while(1);}

	mbedtls_memory_buffer_alloc_init( memory_buf, sizeof(memory_buf) );

	mbedtls_pk_init(&privateKey);

	rC = mbedtls_pk_parse_key(&privateKey, privKeyOpenSSL, strlen(privKeyOpenSSL)+1,NULL,0);
	if(rC != 0){while(1);}

	size_t sig_len;
	rC = mbedtls_pk_sign (&privateKey,MBEDTLS_MD_SHA256,messageDigest,0,cipherText,&sig_len,mbedtls_ctr_drbg_random,&ctr_drbg);
	if(rC != 0){while(1);}

	mbedtls_pk_context publicKey;
	mbedtls_pk_init(&publicKey);

	rC = mbedtls_pk_parse_public_key(&publicKey, pubKeyOpenSSL,strlen(pubKeyOpenSSL)+1);
	if(rC != 0){while(1);}

	rC = mbedtls_pk_verify(&publicKey,MBEDTLS_MD_SHA256,messageDigest,0,cipherText,sig_len);
	if(rC != 0){while(1);}

	while(1);
	
}

Regards and thanks for you help.

Hi @GH1
Thank you for your information!

I have checked your code and the reason for failure is because the private key and public key you posted are from different curves, meaning they are not same key pair.
The private key is from secp256k1 curve, and the public is secp256r1 curve.

I have also looked at an online ASN.1 decoder, which shows same information on the ec curves.

Further, I would prefer to import directly the binary representations of the keys. Is there a interface to do so instead of parsing the strings?

Is your binary information DER format of the keys, or the raw data?
If it’s der format, then mbedtls_pk_parse_key() works on DER as well.
If it’s the raw data, you could try using mbedtls_ecp_point_read_binary() to read the public component (point Q of the context), and mbedtls_mpi_read_binary() to read the private key(d) of your mbedtls_ecp_keypair.

In addition, I suggest you add to your code a call to mbedtls_pk_check_pair(), after parsing the keys.

Regards,
Mbed TLS Team member
Ron

Hi Ron,

thank you for your fast reply and sorry for not double checking my example keys.

I was looking for raw data input and use mbedtls_ecp_point_read_binary etc. now.

Thanks again and regards,
Gregor

Hi Gregor,
Is it working for you now?

Regards,
Ron

Hi Ron,

yes I’m all happy.

Thanks for your help.