diff --git a/wolfcrypt/src/wc_pkcs11.c b/wolfcrypt/src/wc_pkcs11.c index d8a291627e6..b0c6a7634ca 100644 --- a/wolfcrypt/src/wc_pkcs11.c +++ b/wolfcrypt/src/wc_pkcs11.c @@ -102,6 +102,14 @@ static CK_OBJECT_CLASS privKeyClass = CKO_PRIVATE_KEY; static CK_OBJECT_CLASS secretKeyClass = CKO_SECRET_KEY; #endif +#if (!defined(NO_AES) && (defined(WOLFSSL_AES_COUNTER))) +/* AES CTR parameter structure for PKCS#11. */ +typedef struct CK_AES_CTR_PARAMS { + CK_ULONG ulCounterBits; + CK_BYTE cb[WC_AES_BLOCK_SIZE]; +} CK_AES_CTR_PARAMS; +#endif + static CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; #ifdef WOLFSSL_DEBUG_PKCS11 @@ -3775,6 +3783,172 @@ static int Pkcs11AesCbcDecrypt(Pkcs11Session* session, wc_CryptoInfo* info) return ret; } + +#endif + +#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) +/** + * Performs the AES-CTR encryption operation. + * + * @param [in] session Session object. + * @param [in] info Cryptographic operation data. + * @return WC_HW_E when a PKCS#11 library call fails. + * @return MEMORY_E when a memory allocation fails. + * @return 0 on success. + */ +static int Pkcs11AesCtrEncrypt(Pkcs11Session* session, wc_CryptoInfo* info) +{ + int ret = 0; + CK_RV rv; + Aes* aes = info->cipher.aesctr.aes; + CK_MECHANISM_INFO mechInfo; + CK_AES_CTR_PARAMS params; + CK_OBJECT_HANDLE key = NULL_PTR; + CK_MECHANISM mech; + CK_ULONG outLen; + + /* Check operation is supported. */ + rv = session->func->C_GetMechanismInfo(session->slotId, CKM_AES_CTR, + &mechInfo); + PKCS11_RV("C_GetMechanismInfo", rv); + if (rv != CKR_OK || (mechInfo.flags & CKF_ENCRYPT) == 0) + ret = NOT_COMPILED_IN; + + if (ret == 0) { + WOLFSSL_MSG("PKCS#11: AES-CTR Encryption Operation"); + + /* Create a private key object or find by id. */ + if (aes->idLen == 0 && aes->labelLen == 0) { + ret = Pkcs11CreateSecretKey(&key, session, CKK_AES, + (unsigned char*)aes->devKey, + aes->keylen, NULL, 0, NULL, 0, + CKA_ENCRYPT); + } + else if (aes->labelLen != 0) { + ret = Pkcs11FindKeyByLabel(&key, CKO_SECRET_KEY, CKK_AES, session, + aes->label, aes->labelLen); + } + else { + ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session, + aes->id, aes->idLen); + } + } + + if (ret == 0) { + XMEMSET(¶ms, 0, sizeof(params)); + params.ulCounterBits = WC_AES_BLOCK_SIZE * 8; + XMEMCPY(params.cb, info->cipher.aesctr.aes->reg, WC_AES_BLOCK_SIZE); + + mech.mechanism = CKM_AES_CTR; + mech.ulParameterLen = sizeof(params); + mech.pParameter = ¶ms; + + rv = session->func->C_EncryptInit(session->handle, &mech, key); + PKCS11_RV("C_EncryptInit", rv); + if (rv != CKR_OK) { + ret = WC_HW_E; + } + } + if (ret == 0) { + outLen = info->cipher.aesctr.sz; + rv = session->func->C_Encrypt(session->handle, + (CK_BYTE_PTR)info->cipher.aesctr.in, + info->cipher.aesctr.sz, + info->cipher.aesctr.out, + &outLen); + PKCS11_RV("C_Encrypt", rv); + if (rv != CKR_OK) { + ret = WC_HW_E; + } + } + + if (aes->idLen == 0 && aes->labelLen == 0 && key != NULL_PTR) + session->func->C_DestroyObject(session->handle, key); + + return ret; +} + +/** + * Performs the AES-CTR decryption operation. + * + * @param [in] session Session object. + * @param [in] info Cryptographic operation data. + * @return WC_HW_E when a PKCS#11 library call fails. + * @return MEMORY_E when a memory allocation fails. + * @return 0 on success. + */ +static int Pkcs11AesCtrDecrypt(Pkcs11Session* session, wc_CryptoInfo* info) +{ + int ret = 0; + CK_RV rv; + Aes* aes = info->cipher.aesctr.aes; + CK_MECHANISM_INFO mechInfo; + CK_AES_CTR_PARAMS params; + CK_OBJECT_HANDLE key = NULL_PTR; + CK_MECHANISM mech; + CK_ULONG outLen; + + /* Check operation is supported. */ + rv = session->func->C_GetMechanismInfo(session->slotId, CKM_AES_CTR, + &mechInfo); + PKCS11_RV("C_GetMechanismInfo", rv); + if (rv != CKR_OK || (mechInfo.flags & CKF_DECRYPT) == 0) + ret = NOT_COMPILED_IN; + + if (ret == 0) { + WOLFSSL_MSG("PKCS#11: AES-CTR Decryption Operation"); + + /* Create a private key object or find by id. */ + if (aes->idLen == 0 && aes->labelLen == 0) { + ret = Pkcs11CreateSecretKey(&key, session, CKK_AES, + (unsigned char*)aes->devKey, + aes->keylen, NULL, 0, NULL, 0, + CKA_DECRYPT); + } + else if (aes->labelLen != 0) { + ret = Pkcs11FindKeyByLabel(&key, CKO_SECRET_KEY, CKK_AES, session, + aes->label, aes->labelLen); + } + else { + ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session, + aes->id, aes->idLen); + } + } + + if (ret == 0) { + XMEMSET(¶ms, 0, sizeof(params)); + params.ulCounterBits = WC_AES_BLOCK_SIZE * 8; + XMEMCPY(params.cb, info->cipher.aesctr.aes->reg, WC_AES_BLOCK_SIZE); + + mech.mechanism = CKM_AES_CTR; + mech.ulParameterLen = sizeof(params); + mech.pParameter = ¶ms; + + rv = session->func->C_DecryptInit(session->handle, &mech, key); + PKCS11_RV("C_DecryptInit", rv); + if (rv != CKR_OK) { + ret = WC_HW_E; + } + } + if (ret == 0) { + outLen = info->cipher.aesctr.sz; + rv = session->func->C_Decrypt(session->handle, + (CK_BYTE_PTR)info->cipher.aesctr.in, + info->cipher.aesctr.sz, + info->cipher.aesctr.out, + &outLen); + PKCS11_RV("C_Decrypt", rv); + if (rv != CKR_OK) { + ret = WC_HW_E; + } + } + + if (aes->idLen == 0 && aes->labelLen == 0 && key != NULL_PTR) + session->func->C_DestroyObject(session->handle, key); + + return ret; +} + #endif #ifndef NO_HMAC @@ -4205,6 +4379,24 @@ int wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx) } } break; + #endif + #ifdef WOLFSSL_AES_COUNTER + case WC_CIPHER_AES_CTR: + if (info->cipher.enc) { + ret = Pkcs11OpenSession(token, &session, readWrite); + if (ret == 0) { + ret = Pkcs11AesCtrEncrypt(&session, info); + Pkcs11CloseSession(token, &session); + } + } + else { + ret = Pkcs11OpenSession(token, &session, readWrite); + if (ret == 0) { + ret = Pkcs11AesCtrDecrypt(&session, info); + Pkcs11CloseSession(token, &session); + } + } + break; #endif } #else diff --git a/wolfssl/wolfcrypt/pkcs11.h b/wolfssl/wolfcrypt/pkcs11.h index 4d36e366c0d..2413e724e02 100644 --- a/wolfssl/wolfcrypt/pkcs11.h +++ b/wolfssl/wolfcrypt/pkcs11.h @@ -164,6 +164,7 @@ extern "C" { #define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL #define CKM_AES_KEY_GEN 0x00001080UL #define CKM_AES_CBC 0x00001082UL +#define CKM_AES_CTR 0x00001086UL #define CKM_AES_GCM 0x00001087UL /* full data RSA PK callbacks */