cancel
Showing results for 
Search instead for 
Did you mean: 

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

DGast.1
Associate III

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.

2 REPLIES 2

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 Venmo
Up vote any posts that you find helpful, it shows what's working..
DGast.1
Associate III

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?