cancel
Showing results for 
Search instead for 
Did you mean: 

X-CUBE-CRYPTOLIB: ECDSA invalid public key format

SRB
Associate II

Hi,

I'm using STM32CubeExpansion_Crypto_V4.0.1 library for verifying a signed firmware file on STM32F7 controller. The key-pair has been generated using openssl command-line. The firmware has been signed using the private key (PEM). The signature has been stripped off the container headers and 64-byte sign generated. The public key has been converted to binary format (C array of 64 bytes) and embedded in the bootloader. However, the call to cmox_ecdsa_verify() fails with code 'CMOX_ECC_ERR_INVALID_PUBKEY (0x00060008) /*!< Invalid Public Key value */'.

Sequence of function calls, with few params:

cmox_ecc_construct(..., CMOX_ECC256_MATH_FUNCS, staticBuff[2048],... )

cmox_ecdsa_verify(..., CMOX_ECC_CURVE_SECP256K1, pubKeyBin[64],...)

cmox_ecc_cleanup()

The signature verification works fine on openssl command-line, with a dummy file. Would appreciate any pointers on this issue. Thank you.

5 REPLIES 5
Jocelyn RICARD
ST Employee

Hello @SRB​ ,

are you sure you are using right curve ?

The more common used curve is SECP256R1 which translate to prime256v1 in openssl.

Best regards

Jocelyn

Hi Jocelyn,

Thanks, yes, it's SECP256R1. When I checked using sign & verify functions of cmox_ecdsa API, it worked. Shall compare using other online tools and post an update.

Mr_M_from_G
Senior II

Same issue for me.

The first post shows that the op used CMOX_ECC_CURVE_SECP256K1 -> ! K1 !

I have the issue that a cmox_ecdsa_verify with K1 fails although a cmox_ecdsa_sign produces the identical signature.
With R1 there are no issues.

In case of interest I can send an example but it is based on ECC/ECDSA_SignVerify/Src/main.c from STM32CubeExpansion_Crypto_V4.2.0, so only the input values have changed.

My fault, I was using one curve with keys generated for another...

I'd created the 'C' arrays for this test-pattern for SECP256K1 in another thread, and for libraries I was testing/validating. Usually testing the public key for validity before verifying the signing.

//****************************************************************************

#if (FIPS_TEST == 123) // secp256k1

// https://github.com/pyca/cryptography/blob/main/vectors/cryptography_vectors/asymmetric/ECDSA/SECP256K1/SigGen.txt#L6314

// [K-256,SHA-256]

// Msg = 5c868fedb8026979ebd26f1ba07c27eedf4ff6d10443505a96ecaf21ba8c4f0937b3cd23ffdc3dd429d4cd1905fb8dbcceeff1350020e18b58d2ba70887baa3a9b783ad30d3fbf210331cdd7df8d77defa398cdacdfc2e359c7ba4cae46bb74401deb417f8b912a1aa966aeeba9c39c7dd22479ae2b30719dca2f2206c5eb4b7
// d   = 42202a98374f6dca439c0af88140e41f8eced3062682ec7f9fc8ac9ea83c7cb2
// Qx  = 131ca4e5811267fa90fc631d6298c2d7a4ecccc45cc60d378e0660b61f82fe8d
// Qy  = cf5acf8ed3e0bbf735308cc415604bd34ab8f7fc8b4a22741117a7fbc72a7949
// R   = d89f9586070230bb03e625cca18c89bb3117cd472ff6ee2a50809f0e89039309
// S   = 45972842e92e3a41abeea1089d812eb5343ca8f075ac9c66e13f3db287048638

static uint8_t msg[] = { // Message
0x5c,0x86,0x8f,0xed,0xb8,0x02,0x69,0x79,0xeb,0xd2,0x6f,0x1b,0xa0,0x7c,0x27,0xee, // Msg
0xdf,0x4f,0xf6,0xd1,0x04,0x43,0x50,0x5a,0x96,0xec,0xaf,0x21,0xba,0x8c,0x4f,0x09,
0x37,0xb3,0xcd,0x23,0xff,0xdc,0x3d,0xd4,0x29,0xd4,0xcd,0x19,0x05,0xfb,0x8d,0xbc,
0xce,0xef,0xf1,0x35,0x00,0x20,0xe1,0x8b,0x58,0xd2,0xba,0x70,0x88,0x7b,0xaa,0x3a,
0x9b,0x78,0x3a,0xd3,0x0d,0x3f,0xbf,0x21,0x03,0x31,0xcd,0xd7,0xdf,0x8d,0x77,0xde,
0xfa,0x39,0x8c,0xda,0xcd,0xfc,0x2e,0x35,0x9c,0x7b,0xa4,0xca,0xe4,0x6b,0xb7,0x44,
0x01,0xde,0xb4,0x17,0xf8,0xb9,0x12,0xa1,0xaa,0x96,0x6a,0xee,0xba,0x9c,0x39,0xc7,
0xdd,0x22,0x47,0x9a,0xe2,0xb3,0x07,0x19,0xdc,0xa2,0xf2,0x20,0x6c,0x5e,0xb4,0xb7 };

static uint8_t digest[] = { // Digest (sha256) Actual
0x5a,0xe8,0x31,0x7d,0x34,0xd1,0xe5,0x95,0xe3,0xfa,0x72,0x47,0xdb,0x80,0xc0,0xaf, // sha256(Msg)
0x43,0x20,0xcc,0xe1,0x11,0x6d,0xe1,0x87,0xf8,0xf7,0xe2,0xe0,0x99,0xc0,0xd8,0xd0 };

static uint8_t keyprivate[] = { // Private Key
0x42,0x20,0x2a,0x98,0x37,0x4f,0x6d,0xca,0x43,0x9c,0x0a,0xf8,0x81,0x40,0xe4,0x1f, // d
0x8e,0xce,0xd3,0x06,0x26,0x82,0xec,0x7f,0x9f,0xc8,0xac,0x9e,0xa8,0x3c,0x7c,0xb2 };

static uint8_t key[] = { // Public Key
0x13,0x1c,0xa4,0xe5,0x81,0x12,0x67,0xfa,0x90,0xfc,0x63,0x1d,0x62,0x98,0xc2,0xd7, // Qx
0xa4,0xec,0xcc,0xc4,0x5c,0xc6,0x0d,0x37,0x8e,0x06,0x60,0xb6,0x1f,0x82,0xfe,0x8d,
0xcf,0x5a,0xcf,0x8e,0xd3,0xe0,0xbb,0xf7,0x35,0x30,0x8c,0xc4,0x15,0x60,0x4b,0xd3, // Qy
0x4a,0xb8,0xf7,0xfc,0x8b,0x4a,0x22,0x74,0x11,0x17,0xa7,0xfb,0xc7,0x2a,0x79,0x49 };

static uint8_t signature[] = { // Signature (sha256)
0xd8,0x9f,0x95,0x86,0x07,0x02,0x30,0xbb,0x03,0xe6,0x25,0xcc,0xa1,0x8c,0x89,0xbb, // R
0x31,0x17,0xcd,0x47,0x2f,0xf6,0xee,0x2a,0x50,0x80,0x9f,0x0e,0x89,0x03,0x93,0x09,
0x45,0x97,0x28,0x42,0xe9,0x2e,0x3a,0x41,0xab,0xee,0xa1,0x08,0x9d,0x81,0x2e,0xb5, // S
0x34,0x3c,0xa8,0xf0,0x75,0xac,0x9c,0x66,0xe1,0x3f,0x3d,0xb2,0x87,0x04,0x86,0x38 };

char sQx[] = "131ca4e5811267fa90fc631d6298c2d7a4ecccc45cc60d378e0660b61f82fe8d";
char sQy[] = "cf5acf8ed3e0bbf735308cc415604bd34ab8f7fc8b4a22741117a7fbc72a7949";

#endif // FIPS_TEST == 123

//****************************************************************************

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..