Hi NXP Community,
Use case:
Use private key on PC side to sign some data, use public key on S32K3 side to verify data.
Key pair generation done with OpenSSL:
openssl genpkey -algorithm Ed25519 -outform PEM -out private_key.pem
openssl pkey -in private_key.pem -pubout -outform PEM -out public_key.pem
Listing the key contents with OpenSSL produces the following output (these keys are valid of course, but considered dummy for demo purposes only):
openssl pkey -inform pem -in private_key.pem -text
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEINpkm+ArI/HFbCgWttsHNHS0jW1fwI5GhnIxAoXG4S0i
-----END PRIVATE KEY-----
ED25519 Private-Key:
priv:
da:64:9b:e0:2b:23:f1:c5:6c:28:16:b6:db:07:34:
74:b4:8d:6d:5f:c0:8e:46:86:72:31:02:85:c6:e1:
2d:22
pub:
65:9c:25:9c:4b:e0:5f:46:5c:b7:12:52:91:86:7c:
d8:dc:96:d5:11:90:8c:65:8d:b2:f3:c7:2f:66:2e:
6e:6b
Public key is transformed into an array as follows:
unsigned char eddsa_public_key[] = {
0x6B, 0x6E, 0x2E, 0x66, 0x2F, 0xC7, 0xF3, 0xB2,
0x8D, 0x65, 0x8C, 0x90, 0x11, 0xD5, 0x96, 0xDC,
0xD8, 0x7C, 0x86, 0x91, 0x52, 0x12, 0xB7, 0x5C,
0x46, 0x5F, 0xE0, 0x4B, 0x9C, 0x25, 0x9C, 0x65 };
The key catalog is then formatted according to the following scheme:
/** @brief HSE NVM key catalog configuration */
#define HSE_NVM_KEY_CATALOG_CFG \
/* Group MU Mask Group Owner Group Key Type Number of Slots Maximum slot size (in bits) */ \
/* CUST keys */ \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_CUST, HSE_KEY_TYPE_AES, 3U, HSE_KEY256_BITS, {0U} }, \
/* HMAC key */ \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_CUST, HSE_KEY_TYPE_HMAC, 1U, HSE_KEY512_BITS, {0U} }, \
/* ECC keys */ \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_CUST, HSE_KEY_TYPE_ECC_PAIR, 2U, HSE_KEY256_BITS, {0U} }, \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_CUST, HSE_KEY_TYPE_ECC_PUB, 1U, HSE_KEY256_BITS, {0U} }, \
/* RSA keys */ \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_CUST, HSE_KEY_TYPE_RSA_PAIR, 3U, HSE_KEY4096_BITS, {0U} }, \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_CUST, HSE_KEY_TYPE_RSA_PUB, 4U, HSE_KEY4096_BITS, {0U} }, \
{ 0U, 0U, 0U, 0U, 0U, {0U} }
/** @brief HSE RAM key catalog configuration */
#define HSE_RAM_KEY_CATALOG_CFG \
/* Group MU Mask Group Owner Group Key Type Number of Slots Maximum slot size (in bits) */ \
/* Symmetric key */ \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_AES, 6U, HSE_KEY128_BITS, {0U} }, \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_AES, 3U, HSE_KEY192_BITS, {0U} }, \
/* Usable only on MU1 */ \
{ GRANT_COD_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_AES, 3U, HSE_KEY256_BITS, {0U} }, \
/* HMAC key */ \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_HMAC, 6U, HSE_KEY1024_BITS, {0U} }, \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_HMAC, 2U, HSE_KEY256_BITS, {0U} }, \
/* ECC keys*/ \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_ECC_PAIR, 2U, HSE_KEY521_BITS, {0U} }, \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_ECC_PUB, 6U, HSE_KEY521_BITS, {0U} }, \
/* Temporary secrets */ \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_SHARED_SECRET, 1U, HSE_KEY638_BITS, {0U} }, \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_SHARED_SECRET, 2U, HSE_KEY2048_BITS, {0U} }, \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_SHARED_SECRET, 2U, HSE_KEY4096_BITS, {0U} }, \
/* RSA keys */ \
{ GRANT_ALL_ACCESS, HSE_KEY_OWNER_ANY, HSE_KEY_TYPE_RSA_PUB, 3U, HSE_KEY4096_BITS, {0U} }, \
{ 0U, 0U, 0U, 0U, 0U, {0U} }
A pair of ECC (EdDSA) keys are generated and accommodated in HSE_NVM_KEY_CATALOG_CFG (2, 0).
The public key shown above is imported successfully in HSE_NVM_KEY_CATALOG_CFG (3, 0).
To test the generated key-pair, a signature is verified over the following trivial array:
const char helloTest[5] = {'h','e','l','l','o'};
The array is signed with the private key from HSE_NVM_KEY_CATALOG_CFG (2,0) and then it is verified with the public key from the same slot. This works fine.
Now the problem start.
To test the key-pair generated with OpenSSL (shown above), the following steps are taken:
printf "%s" "hello" > hello.bin
openssl pkeyutl -sign -inkey private_key.pem -rawin -in hello.bin -out hello.bin.sig
openssl pkeyutl -verify -pubin -inkey public_key.pem -rawin -in hello.bin -sigfile hello.bin.sig
Signature Verified Successfully
The signature produced is:
xxd -i hello.bin.sig
unsigned char hello_bin_sig[] = {
0x57, 0x24, 0xbf, 0xf8, 0x28, 0xa6, 0x54, 0xf3, 0x52, 0x4e, 0xf7, 0x0e,
0xc2, 0xd7, 0x0b, 0xf9, 0x06, 0x3f, 0xe7, 0x17, 0xe0, 0x48, 0x6f, 0xe4,
0xa0, 0xa7, 0xaa, 0x7e, 0x15, 0x26, 0x26, 0xa6, 0x47, 0xb7, 0xb8, 0x1a,
0x2f, 0x60, 0x3d, 0x4e, 0x00, 0xb7, 0x42, 0x1a, 0x69, 0xa8, 0x17, 0x03,
0x35, 0xd2, 0xa2, 0x9f, 0xe1, 0x60, 0x8e, 0x8a, 0x41, 0x47, 0x5d, 0x8d,
0xbc, 0x81, 0x51, 0x05
};
unsigned int hello_bin_sig_len = 64;
The hello_bin_sig array is now split up into the r and s parts (32 byte each) and fed into the same Verify-function used previously (when I was testing the generated key pair), only this time using the public key that was installed in HSE_NVM_KEY_CATALOG_CFG (3, 0). The verification fails, returning HSE_SRV_RSP_VERIFY_FAILED ((hseSrvResponse_t)0x55A5A164UL).
Any ideas on what I might be doing wrong here?
BR
See please attached document. It thoroughly explains how to generate ECC key pair in openssl and how to use it in HSE.
Regards,
Lukas