Skip to main content
DGast.1
Associate III
August 26, 2020
Question

I'm trying to initialize an ECDSA 256 public key with the STM32 Crypto library following the example provided in the documentation, but I'm getting the error: ECC_ERR_BAD_OPERATION

  • August 26, 2020
  • 2 replies
  • 984 views

EC key information:

> openssl ec -in fake_key.pem -text -param_enc explicit -noout

read EC key
Private-Key: (256 bit)
priv:
 af:b9:...
pub:
 04:c0:ae:88:33:3d:a3:d9:ba:20:37:20:05:28:3e:
 2a:eb:3e:44:c6:fb:57:08:cd:e4:f4:3e:f9:4d:a6:
 f0:29:70:94:90:53:87:50:8c:9f:4d:a7:81:83:e2:
 d7:ad:ab:98:09:71:9e:94:1f:d3:f7:2d:e1:0e:79:
 ac:e7:d9:3e:53
Field Type: prime-field
Prime:
 00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
 00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
 ff:ff:ff
A: 
 00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
 00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
 ff:ff:fc
B: 
 5a:c6:35:d8:aa:3a:93:e7:b3:eb:bd:55:76:98:86:
 bc:65:1d:06:b0:cc:53:b0:f6:3b:ce:3c:3e:27:d2:
 60:4b
Generator (uncompressed):
 04:6b:17:d1:f2:e1:2c:42:47:f8:bc:e6:e5:63:a4:
 40:f2:77:03:7d:81:2d:eb:33:a0:f4:a1:39:45:d8:
 98:c2:96:4f:e3:42:e2:fe:1a:7f:9b:8e:e7:eb:4a:
 7c:0f:9e:16:2b:ce:33:57:6b:31:5e:ce:cb:b6:40:
 68:37:bf:51:f5
Order: 
 00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:
 ff:ff:bc:e6:fa:ad:a7:17:9e:84:f3:b9:ca:c2:fc:
 63:25:51
Cofactor: 1 (0x1)
Seed:
 c4:9d:36:08:86:e7:04:93:6a:66:78:e1:13:9d:26:
 b7:81:9f:7e:90

Source code to initialize the above key with STM32 Crypto API (with all the required data hardcoded):

const uint8_t ec256_p[] =
{
 0xff, 0xff, 0xff, 0xff, 0x0, ..., 0xff, 0xff, 0xff
};
 
const uint8_t ec256_a[] =
{
 0xff, 0xff, 0xff, 0xff, 0x0, ..., 0xff, 0xff, 0xfc
};
 
const uint8_t ec256_b[] =
{
 0x5a, 0xc6, 0x35, ..., 0xd2, 0x60, 0x4b
};
 
const uint8_t ec256_n[] =
{
 0x00, 0xff, 0xff, ..., 0x63, 0x25, 0x51
};
 
const uint8_t ec256_gen_coord_x[] =
{
 0x6b, 0x17, 0xd1, ..., 0x98, 0xc2, 0x96
};
 
const uint8_t ec256_gen_coord_y[] =
{
 0x4f, 0xe3, 0x42, ..., 0xbf, 0x51, 0xf5
};
 
const uint8_t ec256_pub_x[] =
{
 0xc0, 0xae, 0x88, ..., 0xf0, 0x29, 0x70
};
 
const uint8_t ec256_pub_y[] =
{
 0x94, 0x90, 0x53, ..., 0xd9, 0x3e, 0x53
};
 
 
//
// Define and initialize EC (in this case, curve P-256)
//
EC_stt ec_st = {0};
 
ec_st.pmA = ec256_a;
ec_st.mAsize = sizeof(ec256_a);
 
ec_st.pmB = ec256_b;
ec_st.mBsize = sizeof(ec256_b);
 
ec_st.pmP = ec256_p;
ec_st.mPsize = sizeof(ec256_p);
 
ec_st.pmN = ec256_n;
ec_st.mNsize = sizeof(ec256_n);
 
ec_st.pmGx = ec256_gen_coord_x;
ec_st.mGxsize = sizeof(ec256_gen_coord_x);
 
ec_st.pmGy = ec256_gen_coord_y;
ec_st.mGysize = sizeof(ec256_gen_coord_y);
 
 
membuf_stt crypt_buff = {0};
 
crypt_buff.pmBuf = preallocated_buffer;
crypt_buff.mUsed = 0;
crypt_buff.mSize = sizeof(preallocated_buffer);
 
 
int32_t rc = ECCinitEC(&ec_st, &crypt_buff);
if (rc != ECC_SUCCESS)
{
 printk("error trying to init. EC\n");
 return rc;
}
 
ECpoint_stt *pub_key = NULL;
rc = ECCinitPoint(&pub_key, &ec_st, &crypt_buff);
if (rc != ECC_SUCCESS)
{
 printk("error trying to allocate a curve point\n");
 return rc;
}
 
//
// Import public key
//
ECCsetPointCoordinate(pub_key, E_ECC_POINT_COORDINATE_X, ec256_pub_x, sizeof(ec256_pub_x));
ECCsetPointCoordinate(pub_key, E_ECC_POINT_COORDINATE_Y, ec256_pub_y, sizeof(ec256_pub_y));
rc = ECCvalidatePubKey(pub_key, &ec_st, &crypt_buff);
if (rc != ECC_SUCCESS)
{
 printk("error trying to validate public key\n");
 return rc;
}

As explained `ECCvalidatePubKey` returns error code 5202.

This topic has been closed for replies.

2 replies

Tesla DeLorean
Guru
August 26, 2020

A and P start with zero, check sizeof arrays correct and endian ordering.

Enable the CRC peripheral, ST frequently checks this to device lock libraries.​

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
DGast.1
DGast.1Author
Associate III
August 26, 2020

I have made sure that the CRC peripheral is initialized executing the following block just before starting the key import:

CRC_HandleTypeDef x = {0};
 HAL_StatusTypeDef hrc = HAL_CRC_Init(&x);
 
 if(hrc != HAL_OK)
 {
 printk("-- hrc is not HAL_OK (%d)\n", hrc);
 return -3;
 }
 
 HAL_CRC_StateTypeDef csrc = HAL_CRC_GetState(&x);
 
 if(csrc != HAL_CRC_STATE_READY)
 {
 printk("-- csrc is not HAL_CRC_STATE_READY (%d)\n", csrc);
 return -4;
 }
 
 printk("-- crc module initialized correctly\n");

I can see the latest print, so the CRC periph. must be enabled. In addition, I have tried with both big and little endian.

PD.:

Correct me if I'm wrong, but H7 Crypto processor does not support ECDSA. Still, is it necessary to enable it to use the STM32 EC Crypto API?