Support for the MAXQ1065 wolfPKCS11 effort.

- in wc_ecc_import_private_key_ex, check to make sure devid is not invalid
  before calling wc_MAXQ10XX_EccSetKey. This is because we sometimes need to
  locally sign material.
- in various places, delete a key in case it already exists; ignore error since
  it might not exist.
- in various places, unlock and then lock the HW mutex around ECDSA_sign()
  because it needs access to rng
- in wolfSSL_MAXQ10XX_CryptoDevCb allow 1065 to call the crypto callback.
- in wolfSSL_MAXQ10XX_CryptoDevCb don't set the key during signing; use
  pre-provisioned one instead; DEVICE_KEY_PAIR_OBJ_ID
- add ecc_establish and modifications to key creation to support ECDH
- support AES CBC
This commit is contained in:
Anthony Hu 2024-10-17 13:11:05 -09:00
parent 878cf3afaa
commit b938073202
2 changed files with 345 additions and 20 deletions

View File

@ -11273,7 +11273,7 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
#endif
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
if (ret == 0) {
if ((ret == 0) && (key->devId != INVALID_DEVID)) {
ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
}
#elif defined(WOLFSSL_SILABS_SE_ACCEL)

View File

@ -600,6 +600,9 @@ static int aes_set_key(Aes* aes, const byte* userKey, word32 keylen)
goto end_AesSetKey;
}
/* Delete object if one already exists. Ignore error in case it doesn't
* exist. */
mxq_rc = MXQ_DeleteObject(obj_id);
mxq_rc = MXQ_CreateObject(obj_id, keylen, MXQ_OBJTYPE_SECRETKEY,
OBJPROP_PERSISTENT,
(char *)"ahs=rwdgx:ahs=rwdgx:ahs=rwdgx");
@ -626,13 +629,26 @@ static int aes_set_key(Aes* aes, const byte* userKey, word32 keylen)
LoadDefaultImportKey(sign_key, &sign_key_len, &sign_key_curve,
&sign_key_type);
/* Unlock because signing operation will need to use the RNG. */
#if defined(MAXQ10XX_MUTEX)
wolfSSL_CryptHwMutexUnLock();
#endif
rc = ECDSA_sign(signature, &signature_len, sign_key, key_buff, key_buff_len,
sign_key_curve);
if (rc) {
WOLFSSL_ERROR_MSG("MAXQ: ECDSA_sign() failed");
goto end_AesSetKey;
goto end_AesSetKey_noUnlock;
}
#if defined(MAXQ10XX_MUTEX)
rc = maxq_CryptHwMutexTryLock();
if (rc != 0) {
WOLFSSL_ERROR_MSG("MAXQ: aes_set_key() lock could not be acquired");
rc = NOT_COMPILED_IN;
goto end_AesSetKey_noUnlock;
}
#endif
mxq_rc = MXQ_ImportKey(obj_id, getSignAlgoFromCurve(sign_key_curve),
PUBKEY_IMPORT_OBJID, key_buff, key_buff_len,
signature, signature_len);
@ -647,6 +663,7 @@ static int aes_set_key(Aes* aes, const byte* userKey, word32 keylen)
end_AesSetKey:
wolfSSL_CryptHwMutexUnLock();
end_AesSetKey_noUnlock:
return rc;
}
#endif /* MAXQ_AESGCM */
@ -680,12 +697,14 @@ void wc_MAXQ10XX_AesFree(Aes* aes)
}
#ifdef MAXQ_ECC
static int ecc_set_key(ecc_key* key, const byte* userKey, word32 keycomplen)
static int ecc_set_key(ecc_key* key, const byte* userKey, word32 keycomplen,
int for_ecdh)
{
mxq_err_t mxq_rc;
int rc;
word32 keylen;
int objtype;
mxq_keyuse_t key_use;
mxq_u1 key_buff[MAX_KEY_DATASIZE];
mxq_length key_buff_len = sizeof(key_buff);
unsigned char sign_key[MAX_SIGNKEY_DATASIZE];
@ -708,6 +727,13 @@ static int ecc_set_key(ecc_key* key, const byte* userKey, word32 keycomplen)
objtype = MXQ_OBJTYPE_KEYPAIR;
}
if (for_ecdh) {
key_use = MXQ_KEYUSE_KEY_EXCHAGE;
}
else {
key_use = MXQ_KEYUSE_DATASIGNATURE;
}
#if defined(MAXQ10XX_MUTEX)
rc = maxq_CryptHwMutexTryLock();
if (rc != 0) {
@ -728,6 +754,9 @@ static int ecc_set_key(ecc_key* key, const byte* userKey, word32 keycomplen)
goto end_EccSetKey;
}
/* Delete object if one already exists. Ignore error in case it doesn't
* exist. */
mxq_rc = MXQ_DeleteObject(obj_id);
mxq_rc = MXQ_CreateObject(obj_id, keylen, objtype, OBJPROP_PERSISTENT,
(char *)"ahs=rwdgx:ahs=rwdgx:ahs=rwdgx");
if (mxq_rc) {
@ -741,7 +770,7 @@ static int ecc_set_key(ecc_key* key, const byte* userKey, word32 keycomplen)
mxq_rc = MXQ_BuildKey(key_buff, &key_buff_len, MXQ_KEYTYPE_ECC,
MXQ_KEYPARAM_EC_P256R1, keycomplen, keylen,
MXQ_KEYUSE_DATASIGNATURE, ALGO_ECDSA_SHA_256,
key_use, ALGO_ECDSA_SHA_256,
MXQ_KEYUSE_NONE, ALGO_NONE, (mxq_u1 *)userKey);
if (mxq_rc) {
WOLFSSL_ERROR_MSG("MAXQ: MXQ_BuildKey() failed");
@ -752,13 +781,27 @@ static int ecc_set_key(ecc_key* key, const byte* userKey, word32 keycomplen)
LoadDefaultImportKey(sign_key, &sign_key_len, &sign_key_curve,
&sign_key_type);
/* Unlock because signing operation will need to use the RNG. */
#if defined(MAXQ10XX_MUTEX)
wolfSSL_CryptHwMutexUnLock();
#endif
rc = ECDSA_sign(signature, &signature_len, sign_key, key_buff, key_buff_len,
sign_key_curve);
if (rc) {
WOLFSSL_ERROR_MSG("MAXQ: ECDSA_sign() failed");
goto end_EccSetKey;
goto end_EccSetKey_noUnlock;
}
#if defined(MAXQ10XX_MUTEX)
rc = maxq_CryptHwMutexTryLock();
if (rc != 0) {
WOLFSSL_ERROR_MSG("MAXQ: ecc_set_key() lock could not be acquired");
rc = NOT_COMPILED_IN;
goto end_EccSetKey_noUnlock;
}
#endif
mxq_rc = MXQ_ImportKey(obj_id, getSignAlgoFromCurve(sign_key_curve),
PUBKEY_IMPORT_OBJID, key_buff, key_buff_len,
signature, signature_len);
@ -772,9 +815,206 @@ static int ecc_set_key(ecc_key* key, const byte* userKey, word32 keycomplen)
key->maxq_ctx.key_pending = 0;
end_EccSetKey:
#if defined(MAXQ10XX_MUTEX)
wolfSSL_CryptHwMutexUnLock();
#endif
end_EccSetKey_noUnlock:
return rc;
}
static int ecc_gen_key(ecc_key* key, word32 keycomplen)
{
mxq_err_t mxq_rc;
int rc;
word32 keylen;
int objtype;
mxq_u1 key_buff[MAX_KEY_DATASIZE];
mxq_length key_buff_len = sizeof(key_buff);
unsigned char sign_key[MAX_SIGNKEY_DATASIZE];
int sign_key_len, sign_key_curve, sign_key_type;
mxq_u1 signature[MAX_SIG_DATASIZE];
int signature_len = (int)sizeof(signature);
if ((key->type != 0) && (key->type != ECC_PRIVATEKEY)
&& (key->type != ECC_PRIVATEKEY_ONLY)) {
return BAD_FUNC_ARG;
}
key->type = ECC_PRIVATEKEY;
keylen = keycomplen * 3;
objtype = MXQ_OBJTYPE_KEYPAIR;
#if defined(MAXQ10XX_MUTEX)
rc = maxq_CryptHwMutexTryLock();
if (rc != 0) {
WOLFSSL_ERROR_MSG("MAXQ: ecc_set_key() lock could not be acquired");
rc = NOT_COMPILED_IN;
return rc;
}
#endif
if (key->maxq_ctx.key_obj_id) {
wc_MAXQ10XX_EccFree(key);
}
int obj_id = alloc_ecc_key_id();
if (!obj_id) {
WOLFSSL_ERROR_MSG("MAXQ: alloc_ecc_key_id() failed");
rc = NOT_COMPILED_IN;
goto end_EccGenKey;
}
/* Delete object if one already exists. Ignore error in case it doesn't
* exist. */
mxq_rc = MXQ_DeleteObject(obj_id);
mxq_rc = MXQ_CreateObject(obj_id, keylen, objtype, OBJPROP_PERSISTENT,
(char *)"ahs=rwdgx:ahs=rwdgx:ahs=rwdgx");
if (mxq_rc) {
WOLFSSL_ERROR_MSG("MAXQ: MXQ_CreateObject() failed");
rc = NOT_COMPILED_IN;
goto end_EccGenKey;
}
/* store the object id in the context */
key->maxq_ctx.key_obj_id = obj_id;
/* Note that total_keylen is 0 and psrc is NULL. This ensures that when
* MXQ_ImportKey() is called, it does a keygen; not import. */
mxq_rc = MXQ_BuildKey(key_buff, &key_buff_len, MXQ_KEYTYPE_ECC,
MXQ_KEYPARAM_EC_P256R1, keycomplen, 0,
MXQ_KEYUSE_KEY_EXCHAGE, ALGO_ECDSA_SHA_256,
MXQ_KEYUSE_NONE, ALGO_NONE, NULL);
if (mxq_rc) {
WOLFSSL_ERROR_MSG("MAXQ: MXQ_BuildKey() failed");
rc = WC_HW_E;
goto end_EccGenKey;
}
LoadDefaultImportKey(sign_key, &sign_key_len, &sign_key_curve,
&sign_key_type);
/* Unlock because signing operation will need to use the RNG. */
#if defined(MAXQ10XX_MUTEX)
wolfSSL_CryptHwMutexUnLock();
#endif
rc = ECDSA_sign(signature, &signature_len, sign_key, key_buff, key_buff_len,
sign_key_curve);
if (rc) {
WOLFSSL_ERROR_MSG("MAXQ: ECDSA_sign() failed");
goto end_EccGenKey_noUnlock;
}
#if defined(MAXQ10XX_MUTEX)
rc = maxq_CryptHwMutexTryLock();
if (rc != 0) {
WOLFSSL_ERROR_MSG("MAXQ: ecc_set_key() lock could not be acquired");
rc = NOT_COMPILED_IN;
goto end_EccGenKey_noUnlock;
}
#endif
mxq_rc = MXQ_ImportKey(obj_id, getSignAlgoFromCurve(sign_key_curve),
PUBKEY_IMPORT_OBJID, key_buff, key_buff_len,
signature, signature_len);
if (mxq_rc) {
WOLFSSL_ERROR_MSG("MAXQ: MXQ_ImportKey() failed");
rc = WC_HW_E;
goto end_EccGenKey;
}
key->maxq_ctx.hw_ecc = 1;
end_EccGenKey:
#if defined(MAXQ10XX_MUTEX)
wolfSSL_CryptHwMutexUnLock();
#endif
end_EccGenKey_noUnlock:
return rc;
}
static int ecc_establish(ecc_key* key, ecc_key* peer, byte *ss, word32 *ss_len)
{
mxq_err_t mxq_rc;
int rc = 0;
byte fixed_info_len = 32;
byte fixed_info[32];
mxq_length output_len = 128;
byte output[128];
word32 peerKeySz = peer->dp->size;
uint8_t peerKeyBuf[MAX_EC_KEY_SIZE];
uint8_t* peerKey = peerKeyBuf;
uint8_t* qx = peerKey;
uint8_t* qy = &peerKey[peerKeySz];
word32 qxLen = peerKeySz;
word32 qyLen = peerKeySz;
/* ECC P256 shared secret is 32 bytes. */
if (*ss_len != 32) {
return BAD_FUNC_ARG;
}
if (peer == NULL) {
return BAD_FUNC_ARG;
}
if (key == NULL) {
return BAD_FUNC_ARG;
}
if (key->maxq_ctx.hw_ecc != 1) {
/* The key was not generated. Lets import it. */
if (key->maxq_ctx.hw_ecc == 0) {
rc = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
if (rc != 0) {
return rc;
}
}
if (key->maxq_ctx.hw_ecc == -1) {
return CRYPTOCB_UNAVAILABLE;
}
rc = ecc_set_key(key, key->maxq_ctx.ecc_key, key->dp->size, 1);
}
if (rc != 0) {
return rc;
}
if (key->maxq_ctx.key_obj_id == 0) {
return WC_HW_E;
}
wc_ecc_export_public_raw(peer, qx, &qxLen, qy, &qyLen);
if (rc != 0) {
return rc;
}
memset(fixed_info, 0xaa, fixed_info_len);
/* 0xFFFF indicates that the peer's public key will be in the buffer; not
* referenced via key ID. */
mxq_rc = MXQ_EstablishKey(SHARE_SECRET, MXQ_KEYPARAM_EC_P256R1,
key->maxq_ctx.key_obj_id, 0xFFFF, peerKey,
0, NULL, 0, 0, 0, 0, fixed_info_len, fixed_info,
0, 0, NULL, output, &output_len);
if (mxq_rc) {
WOLFSSL_ERROR_MSG("MAXQ: MXQ_EstablishKey() failed");
rc = WC_HW_E;
}
/* Output contains the public key and shared secret concatenated. The public
* key is (0x04 || X || Y) which means its 65 bytes. The shared secret is
* in the 32 bytes after that. */
memcpy(ss, &output[65], *ss_len);
return rc;
}
#endif /* MAXQ_ECC */
void wc_MAXQ10XX_EccFree(ecc_key* key)
@ -894,12 +1134,14 @@ static int maxq10xx_cipher_do(mxq_algo_id_t algo_id, mxq_u1 encrypt,
cparams.p_aad = p_aad;
cparams.aad_length = aad_len;
if (encrypt) {
cparams.aead_tag_len = tag_len;
}
else {
XMEMCPY(cparams.aead_tag, p_tag, tag_len);
cparams.aead_tag_len = tag_len;
if (algo_id == ALGO_CIPHER_AES_GCM) {
if (encrypt) {
cparams.aead_tag_len = tag_len;
}
else {
XMEMCPY(cparams.aead_tag, p_tag, tag_len);
cparams.aead_tag_len = tag_len;
}
}
mxq_rc = MXQ_Cipher_Init(encrypt, algo_id, key_id, &cparams, 0);
@ -1222,6 +1464,69 @@ static int do_aesgcm(wc_CryptoInfo* info)
}
#endif /* !NO_AES && HAVE_AESGCM && MAXQ_AESGCM */
static int do_aescbc(wc_CryptoInfo* info)
{
int rc;
byte *out = info->cipher.aescbc.out;
const byte *in = info->cipher.aescbc.in;
if (info->cipher.aescbc.sz == 0) {
return CRYPTOCB_UNAVAILABLE;
}
if (info->cipher.aescbc.aes->reg == NULL) {
return CRYPTOCB_UNAVAILABLE;
}
/* Cannot do in place decryption because we get the incoming IV and that
* would already get over written. */
if (in == out) {
return CRYPTOCB_UNAVAILABLE;
}
if (info->cipher.aesgcm_enc.aes->maxq_ctx.key_pending) {
rc = aes_set_key(
info->cipher.aescbc.aes,
(const byte *)info->cipher.aescbc.aes->maxq_ctx.key,
info->cipher.aescbc.aes->keylen);
if (rc != 0) {
return rc;
}
}
rc = wolfSSL_CryptHwMutexLock();
if (rc != 0) {
return rc;
}
rc = maxq10xx_cipher_do(
ALGO_CIPHER_AES_CBC,
info->cipher.enc,
info->cipher.aescbc.aes->maxq_ctx.key_obj_id,
(byte *)info->cipher.aescbc.in,
(byte *)info->cipher.aescbc.out,
info->cipher.aescbc.sz,
(byte *)info->cipher.aescbc.aes->reg, 16,
NULL, 0,
NULL, 0);
wolfSSL_CryptHwMutexUnLock();
/* Take the last 16 bytes and throw them into reg. Then it will be ready in
* case Update() is called. For both encryption and decryption, we get it
* from the ciphertext. (Note in and out usage) */
if (info->cipher.enc) {
memcpy(info->cipher.aescbc.aes->reg,
&out[info->cipher.aescbc.sz - 16], 16);
}
else {
memcpy(info->cipher.aescbc.aes->reg,
&in[info->cipher.aescbc.sz - 16], 16);
}
/* done */
return rc;
}
#if !defined(NO_SHA) && !defined(NO_SHA256) && defined(MAXQ_SHA256)
static int do_sha256(wc_CryptoInfo* info)
{
@ -1296,10 +1601,11 @@ int wolfSSL_MAXQ10XX_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
(void)devId;
(void)ctx;
/* In the case of MAXQ1065, this callback is always enabled. */
#if defined(WOLFSSL_MAXQ108X)
if (!tls13active)
#endif
return CRYPTOCB_UNAVAILABLE;
#endif
if (info->algo_type == WC_ALGO_TYPE_CIPHER) {
#if !defined(NO_AES) || !defined(NO_DES3)
@ -1310,8 +1616,7 @@ int wolfSSL_MAXQ10XX_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
#endif /* HAVE_AESGCM && MAXQ_AESGCM */
#ifdef HAVE_AES_CBC
if (info->cipher.type == WC_CIPHER_AES_CBC) {
/* TODO */
return CRYPTOCB_UNAVAILABLE;
rc = do_aescbc(info);
}
#endif /* HAVE_AES_CBC */
#endif /* !NO_AES || !NO_DES3 */
@ -1343,12 +1648,22 @@ int wolfSSL_MAXQ10XX_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
else if (info->algo_type == WC_ALGO_TYPE_PK) {
#if defined(HAVE_ECC) && defined(MAXQ_ECC)
if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) {
/* TODO */
return CRYPTOCB_UNAVAILABLE;
if (info->pk.eckg.key->maxq_ctx.hw_ecc == -1) {
return CRYPTOCB_UNAVAILABLE;
}
rc = ecc_gen_key(info->pk.eckg.key, info->pk.eckg.key->dp->size);
if (rc != 0) {
return rc;
}
}
else if (info->pk.type == WC_PK_TYPE_ECDH) {
/* TODO */
return CRYPTOCB_UNAVAILABLE;
rc = ecc_establish(info->pk.ecdh.private_key,
info->pk.ecdh.public_key,
info->pk.ecdh.out, info->pk.ecdh.outlen);
if (rc != 0) {
return rc;
}
}
else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
if (info->pk.eccsign.key->maxq_ctx.hw_ecc == 0) {
@ -1363,22 +1678,32 @@ int wolfSSL_MAXQ10XX_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
return CRYPTOCB_UNAVAILABLE;
}
#if defined(WOLFSSL_MAXQ108X)
/* This is not done for MAXQ1065 because we want to use the pre-
* provisioned key in the case of PKCS11. */
if (info->pk.eccsign.key->maxq_ctx.key_pending) {
rc = ecc_set_key(info->pk.eccsign.key,
info->pk.eccsign.key->maxq_ctx.ecc_key,
info->pk.eccsign.key->dp->size);
info->pk.eccsign.key->dp->size, 0);
if (rc != 0) {
return rc;
}
}
#endif
rc = wolfSSL_CryptHwMutexLock();
if (rc != 0) {
return rc;
}
/* Note that we are using the DEVICE_KEY_PAIR_OBJ_ID; its the pre-
* provisioned key in the case of MAXQ1065. */
rc = maxq10xx_ecc_sign_local(
#if defined(WOLFSSL_MAXQ108X)
info->pk.eccsign.key->maxq_ctx.key_obj_id,
#else
DEVICE_KEY_PAIR_OBJ_ID,
#endif
(byte *)info->pk.eccsign.in, info->pk.eccsign.inlen,
info->pk.eccsign.out, info->pk.eccsign.outlen,
info->pk.eccsign.key->dp->size);
@ -1412,7 +1737,7 @@ int wolfSSL_MAXQ10XX_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
if (info->pk.eccverify.key->maxq_ctx.key_pending) {
rc = ecc_set_key(info->pk.eccverify.key,
info->pk.eccverify.key->maxq_ctx.ecc_key,
info->pk.eccverify.key->dp->size);
info->pk.eccverify.key->dp->size, 0);
if (rc != 0) {
return rc;
}