diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 5476e1494d..f1b0acb3f0 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -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) diff --git a/wolfcrypt/src/port/maxim/maxq10xx.c b/wolfcrypt/src/port/maxim/maxq10xx.c index 370a170a8d..f3552e2181 100644 --- a/wolfcrypt/src/port/maxim/maxq10xx.c +++ b/wolfcrypt/src/port/maxim/maxq10xx.c @@ -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,12 +781,26 @@ 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, @@ -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; }