Hi All,
Since I couldn't find a CC310 function for calculating a public key from a private one, I got around it by providing to CRYS_ECPKI_GenKeyPair() the private key through the fixed_vector() function, rather than providing the usual pointer to the random vector generation function CRYS_RND_GenerateVector (as done in an older implementation of Solo).
The problem is that CRYS_ECPKI_GenKeyPair() modifies the original input private key passed using fixed_vector() by adding 0x01 to it's last byte. The generated public key is then mistakenly derived from the private key with 0x01 added to its last byte, rather than the original private key. Why does this happen?
I worked around this by subtracting 0x01 to the last byte of the private key I pass to fixed_vector() as in the script below. It works, however I don't understand why this addition of 0x01 is happening. What am I missing?
In short: why does Line 27 make my code work successfully?
Thank you.
uint8_t fixed_vector_hmac[32];
int fixed_vector_iter = 31;
uint32_t fixed_vector(void * rng, uint16_t sz, uint8_t * out)
{
while(sz--)
{
*out++ = fixed_vector_hmac[fixed_vector_iter--];
if (fixed_vector_iter == -1)
{
fixed_vector_iter = 31;
}
}
return 0;
}
void compute_public_key(uint8_t * privkey, uint8_t * pubkey)
{
CRYS_ECPKI_UserPrivKey_t nrfpriv;
CRYS_ECPKI_UserPublKey_t nrfpub;
CRYS_ECPKI_KG_TempData_t tmp;
CRYS_ECPKI_KG_FipsContext_t FipsBuff;
uint32_t ret;
uint32_t sz;
uint8_t pubkey1[65];
memmove(fixed_vector_hmac, privkey, 32);
fixed_vector_hmac[31] -= 1; // Contrast CRYS_ECPKI_GenKeyPair() which adds 1 to last byte of private key
fixed_vector_iter=31;
// There isn't a CC310 function for calculating a public key from a private,
// so to get around it, we can "fix" the RNG input to GenKeyPair
ret = CRYS_ECPKI_GenKeyPair(&rndState_ptr,
fixed_vector,
/*CRYS_RND_GenerateVector,*/
_es256_curve,
&nrfpriv, &nrfpub, &tmp, &FipsBuff);
if (ret != SA_SILIB_RET_OK){
printf2(TAG_ERR, "Gen key failed with 0x%x \n",ret);
exit(1);
}
/* Check that nrfpriv is same as privkey*/
#include "ssi_pal_mem.h"
//Export UserPrivKey into buffer
uint8_t privKeyBuffCompare[256];
sz = 32;
ret = CRYS_ECPKI_ExportPrivKey(&nrfpriv, privKeyBuffCompare, &sz);
if (ret != 0 || sz != 32)
{
printf2(TAG_ERR, "nrfpriv export fail 0x%04x\n",ret);
}
//Compare privKeyBuff with UserPrivKey
ret = SaSi_PalMemCmp(privKeyBuffCompare, privkey, 32);
if (ret != SA_SILIB_RET_OK){
printf2(TAG_ERR, " SaSi_PalMemCmp failed \n");
}
printf1(TAG_U2F,"privkey: "); dump_hex1(TAG_RED, privkey, 32);
printf1(TAG_U2F,"privKeyBuffCompare: "); dump_hex1(TAG_RED, privKeyBuffCompare, 32);
/*******/
sz = 65;
ret = CRYS_ECPKI_ExportPublKey(&nrfpub, CRYS_EC_PointUncompressed , pubkey1, &sz);
if (ret != 0 || sz != 65)
{
printf2(TAG_ERR, "pubkey export fail 0x%04x\n",ret);
exit(1);
}
if (pubkey1[0] != 0x04)
{
printf2(TAG_ERR, "pubkey uncompressed export fail 0x%02x\n",(int)pubkey1[0]);
exit(1);
}
memmove(pubkey, pubkey1+1 , 64);
}