Merge pull request #11 from SparkiDev/wolfpkcs11_fixup_1

Added support for CKM_AES_CBC_PAD and RSA sign/verify
David Garske 2022-03-24 08:23:13 -07:00 committed by GitHub
commit c59f6d7de0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1244 additions and 30 deletions

View File

@ -13,7 +13,7 @@ Build wolfSSL:
git clone https://github.com/wolfSSL/wolfssl.git
cd wolfssl
./autogen.sh
./configure --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP"
./configure --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT"
make
make check
sudo make install

View File

@ -1047,6 +1047,22 @@ CK_RV C_EncryptInit(CK_SESSION_HANDLE hSession,
return CKR_FUNCTION_FAILED;
init = WP11_INIT_AES_CBC_ENC;
break;
case CKM_AES_CBC_PAD:
if (type != CKK_AES)
return CKR_KEY_TYPE_INCONSISTENT;
if (pMechanism->pParameter == NULL)
return CKR_MECHANISM_PARAM_INVALID;
if (pMechanism->ulParameterLen != AES_IV_SIZE)
return CKR_MECHANISM_PARAM_INVALID;
ret = WP11_Session_SetCbcParams(session, pMechanism->pParameter, 1,
obj);
if (ret == MEMORY_E)
return CKR_DEVICE_MEMORY;
if (ret != 0)
return CKR_FUNCTION_FAILED;
init = WP11_INIT_AES_CBC_PAD_ENC;
break;
#endif
#ifdef HAVE_AESGCM
@ -1212,6 +1228,26 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
return CKR_FUNCTION_FAILED;
*pulEncryptedDataLen = encDataLen;
break;
case CKM_AES_CBC_PAD:
if (!WP11_Session_IsOpInitialized(session,
WP11_INIT_AES_CBC_PAD_ENC)) {
return CKR_OPERATION_NOT_INITIALIZED;
}
encDataLen = (word32)ulDataLen;
if (pEncryptedData == NULL) {
*pulEncryptedDataLen = encDataLen;
return CKR_OK;
}
if (encDataLen > (word32)*pulEncryptedDataLen)
return CKR_BUFFER_TOO_SMALL;
ret = WP11_AesCbcPad_Encrypt(pData, (int)ulDataLen, pEncryptedData,
&encDataLen, session);
if (ret < 0)
return CKR_FUNCTION_FAILED;
*pulEncryptedDataLen = encDataLen;
break;
#endif
#ifdef HAVE_AESGCM
case CKM_AES_GCM:
@ -1312,6 +1348,28 @@ CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
return CKR_FUNCTION_FAILED;
*pulEncryptedPartLen = encPartLen;
break;
case CKM_AES_CBC_PAD:
if (!WP11_Session_IsOpInitialized(session,
WP11_INIT_AES_CBC_PAD_ENC)) {
return CKR_OPERATION_NOT_INITIALIZED;
}
encPartLen = (word32)ulPartLen + WP11_AesCbc_PartLen(session);
encPartLen &= ~0xf;
if (pEncryptedPart == NULL) {
*pulEncryptedPartLen = encPartLen;
return CKR_OK;
}
if (encPartLen > (word32)*pulEncryptedPartLen)
return CKR_BUFFER_TOO_SMALL;
ret = WP11_AesCbcPad_EncryptUpdate(pPart, (int)ulPartLen,
pEncryptedPart, &encPartLen,
session);
if (ret < 0)
return CKR_FUNCTION_FAILED;
*pulEncryptedPartLen = encPartLen;
break;
#endif
#ifdef HAVE_AESGCM
case CKM_AES_GCM:
@ -1407,6 +1465,25 @@ CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession,
if (ret < 0)
return CKR_FUNCTION_FAILED;
break;
case CKM_AES_CBC_PAD:
if (!WP11_Session_IsOpInitialized(session,
WP11_INIT_AES_CBC_PAD_ENC)) {
return CKR_OPERATION_NOT_INITIALIZED;
}
encPartLen = 16;
if (pLastEncryptedPart == NULL) {
*pulLastEncryptedPartLen = encPartLen;
return CKR_OK;
}
if (encPartLen > (word32)*pulLastEncryptedPartLen)
return CKR_BUFFER_TOO_SMALL;
ret = WP11_AesCbcPad_EncryptFinal(pLastEncryptedPart, &encPartLen,
session);
if (ret < 0)
return CKR_FUNCTION_FAILED;
break;
#endif
#ifdef HAVE_AESGCM
case CKM_AES_GCM:
@ -1542,6 +1619,21 @@ CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession,
return CKR_FUNCTION_FAILED;
init = WP11_INIT_AES_CBC_DEC;
break;
case CKM_AES_CBC_PAD:
if (type != CKK_AES)
return CKR_KEY_TYPE_INCONSISTENT;
if (pMechanism->pParameter == NULL)
return CKR_MECHANISM_PARAM_INVALID;
if (pMechanism->ulParameterLen != AES_IV_SIZE)
return CKR_MECHANISM_PARAM_INVALID;
ret = WP11_Session_SetCbcParams(session, pMechanism->pParameter, 0,
obj);
if (ret == MEMORY_E)
return CKR_DEVICE_MEMORY;
if (ret != 0)
return CKR_FUNCTION_FAILED;
init = WP11_INIT_AES_CBC_PAD_DEC;
break;
#endif
#ifdef HAVE_AESGCM
case CKM_AES_GCM: {
@ -1708,6 +1800,25 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
return CKR_FUNCTION_FAILED;
*pulDataLen = decDataLen;
break;
case CKM_AES_CBC_PAD:
if (!WP11_Session_IsOpInitialized(session,
WP11_INIT_AES_CBC_PAD_DEC)) {
return CKR_OPERATION_NOT_INITIALIZED;
}
decDataLen = (word32)ulEncryptedDataLen;
if (pData == NULL) {
*pulDataLen = decDataLen - 1;
return CKR_OK;
}
ret = WP11_AesCbcPad_Decrypt(pEncryptedData,
(int)ulEncryptedDataLen, pData,
&decDataLen, session);
if (ret < 0)
return CKR_FUNCTION_FAILED;
*pulDataLen = decDataLen;
break;
#endif
#ifdef HAVE_AESGCM
case CKM_AES_GCM:
@ -1811,6 +1922,33 @@ CK_RV C_DecryptUpdate(CK_SESSION_HANDLE hSession,
return CKR_FUNCTION_FAILED;
*pulPartLen = decPartLen;
break;
case CKM_AES_CBC_PAD:
if (!WP11_Session_IsOpInitialized(session,
WP11_INIT_AES_CBC_PAD_DEC)) {
return CKR_OPERATION_NOT_INITIALIZED;
}
decPartLen = (word32)ulEncryptedPartLen +
WP11_AesCbc_PartLen(session);
/* Keep last block for final. */
if ((decPartLen & 0xf) != 0)
decPartLen &= ~0xf;
else if (decPartLen > 0)
decPartLen -= 16;
if (pPart == NULL) {
*pulPartLen = decPartLen;
return CKR_OK;
}
if (decPartLen > (word32)*pulPartLen)
return CKR_BUFFER_TOO_SMALL;
ret = WP11_AesCbcPad_DecryptUpdate(pEncryptedPart,
(int)ulEncryptedPartLen, pPart,
&decPartLen, session);
if (ret < 0)
return CKR_FUNCTION_FAILED;
*pulPartLen = decPartLen;
break;
#endif
#ifdef HAVE_AESGCM
case CKM_AES_GCM:
@ -1899,6 +2037,26 @@ CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart,
if (ret < 0)
return CKR_FUNCTION_FAILED;
break;
case CKM_AES_CBC_PAD:
if (!WP11_Session_IsOpInitialized(session,
WP11_INIT_AES_CBC_PAD_DEC)) {
return CKR_OPERATION_NOT_INITIALIZED;
}
decPartLen = WP11_AesCbc_PartLen(session);
if (decPartLen != 16) {
WP11_AesCbc_DecryptFinal(session);
return CKR_DATA_LEN_RANGE;
}
*pulLastPartLen = 15;
if (pLastPart == NULL)
return CKR_OK;
ret = WP11_AesCbcPad_DecryptFinal(pLastPart, &decPartLen, session);
if (ret < 0)
return CKR_FUNCTION_FAILED;
*pulLastPartLen = decPartLen;
break;
#endif
#ifdef HAVE_AESGCM
case CKM_AES_GCM:
@ -2126,6 +2284,15 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
type = WP11_Object_GetType(obj);
switch (pMechanism->mechanism) {
#ifndef NO_RSA
case CKM_RSA_X_509:
if (type != CKK_RSA)
return CKR_KEY_TYPE_INCONSISTENT;
if (pMechanism->pParameter != NULL ||
pMechanism->ulParameterLen != 0) {
return CKR_MECHANISM_PARAM_INVALID;
}
init = WP11_INIT_RSA_X_509_SIGN;
break;
case CKM_RSA_PKCS:
if (type != CKK_RSA)
return CKR_KEY_TYPE_INCONSISTENT;
@ -2255,6 +2422,24 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
mechanism = WP11_Session_GetMechanism(session);
switch (mechanism) {
#ifndef NO_RSA
case CKM_RSA_X_509:
if (!WP11_Session_IsOpInitialized(session,
WP11_INIT_RSA_X_509_SIGN)) {
return CKR_OPERATION_NOT_INITIALIZED;
}
sigLen = WP11_Rsa_KeyLen(obj);
if (pSignature == NULL) {
*pulSignatureLen = sigLen;
return CKR_OK;
}
if (sigLen > (word32)*pulSignatureLen)
return CKR_BUFFER_TOO_SMALL;
ret = WP11_Rsa_Sign(pData, (int)ulDataLen, pSignature, &sigLen, obj,
WP11_Session_GetSlot(session));
*pulSignatureLen = sigLen;
break;
case CKM_RSA_PKCS:
if (!WP11_Session_IsOpInitialized(session, WP11_INIT_RSA_PKCS_SIGN))
return CKR_OPERATION_NOT_INITIALIZED;
@ -2629,6 +2814,15 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
type = WP11_Object_GetType(obj);
switch (pMechanism->mechanism) {
#ifndef NO_RSA
case CKM_RSA_X_509:
if (type != CKK_RSA)
return CKR_KEY_TYPE_INCONSISTENT;
if (pMechanism->pParameter != NULL ||
pMechanism->ulParameterLen != 0) {
return CKR_MECHANISM_PARAM_INVALID;
}
init = WP11_INIT_RSA_X_509_VERIFY;
break;
case CKM_RSA_PKCS:
if (type != CKK_RSA)
return CKR_KEY_TYPE_INCONSISTENT;
@ -2755,6 +2949,15 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
mechanism = WP11_Session_GetMechanism(session);
switch (mechanism) {
#ifndef NO_RSA
case CKM_RSA_X_509:
if (!WP11_Session_IsOpInitialized(session,
WP11_INIT_RSA_X_509_VERIFY)) {
return CKR_OPERATION_NOT_INITIALIZED;
}
ret = WP11_Rsa_Verify(pSignature, (int)ulSignatureLen, pData,
(int)ulDataLen, &stat, obj);
break;
case CKM_RSA_PKCS:
if (!WP11_Session_IsOpInitialized(session,
WP11_INIT_RSA_PKCS_VERIFY)) {

View File

@ -543,7 +543,8 @@ static void wp11_Session_Final(WP11_Session* session)
#endif
#ifndef NO_RSA
#ifdef HAVE_AES_CBC
if (session->mechanism == CKM_AES_CBC && session->init) {
if ((session->mechanism == CKM_AES_CBC ||
session->mechanism == CKM_AES_CBC_PAD) && session->init) {
wc_AesFree(&session->params.cbc.aes);
session->init = 0;
}
@ -2604,6 +2605,23 @@ static int GetBool(CK_BBOOL value, byte* data, CK_ULONG* len)
return ret;
}
/**
* Get the boolean data for flags.
*
* @param value [in] Flags.
* @param flag [in] Flag to check for.
* @param data [in] Buffer to hold boolean.
* @param len [in,out] On in, length of buffer in bytes.
* On out, length of data in buffer.
* @return BUFFER_E when buffer is too small for boolean.
* 0 on success.
*/
static int GetBoolForFlag(CK_ULONG flags, CK_ULONG flag, byte* data,
CK_ULONG* len)
{
return GetBool((flags & flag) == flag, data, len);
}
/**
* Get the data for a CK_ULONG.
*
@ -2976,35 +2994,38 @@ int WP11_Object_GetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data,
ret = GetBool(object->onToken, data, len);
break;
case CKA_PRIVATE:
ret = GetBool(object->opFlag | WP11_FLAG_PRIVATE, data, len);
ret = GetBoolForFlag(object->opFlag, WP11_FLAG_PRIVATE, data, len);
break;
case CKA_SENSITIVE:
ret = GetBool(object->opFlag | WP11_FLAG_SENSITIVE, data, len);
ret = GetBoolForFlag(object->opFlag, WP11_FLAG_SENSITIVE, data,
len);
break;
case CKA_EXTRACTABLE:
ret = GetBool(object->opFlag | WP11_FLAG_EXTRACTABLE, data, len);
ret = GetBoolForFlag(object->opFlag, WP11_FLAG_EXTRACTABLE, data,
len);
break;
case CKA_MODIFIABLE:
ret = GetBool(object->opFlag | WP11_FLAG_MODIFIABLE, data, len);
ret = GetBoolForFlag(object->opFlag, WP11_FLAG_MODIFIABLE, data,
len);
break;
case CKA_ALWAYS_SENSITIVE:
ret = GetBool(object->opFlag | WP11_FLAG_ALWAYS_SENSITIVE, data,
len);
ret = GetBoolForFlag(object->opFlag, WP11_FLAG_ALWAYS_SENSITIVE,
data, len);
break;
case CKA_NEVER_EXTRACTABLE:
ret = GetBool(object->opFlag | WP11_FLAG_NEVER_EXTRACTABLE, data,
len);
ret = GetBoolForFlag(object->opFlag, WP11_FLAG_NEVER_EXTRACTABLE,
data, len);
break;
case CKA_ALWAYS_AUTHENTICATE:
ret = GetBool(object->opFlag | WP11_FLAG_ALWAYS_AUTHENTICATE, data,
len);
ret = GetBoolForFlag(object->opFlag, WP11_FLAG_ALWAYS_AUTHENTICATE,
data, len);
break;
case CKA_WRAP_WITH_TRUSTED:
ret = GetBool(object->opFlag | WP11_FLAG_WRAP_WITH_TRUSTED, data,
len);
ret = GetBoolForFlag(object->opFlag, WP11_FLAG_WRAP_WITH_TRUSTED,
data, len);
break;
case CKA_TRUSTED:
ret = GetBool(object->opFlag | WP11_FLAG_TRUSTED, data, len);
ret = GetBoolForFlag(object->opFlag, WP11_FLAG_TRUSTED, data, len);
break;
case CKA_COPYABLE:
ret = GetBool(CK_FALSE, data, len);
@ -3046,31 +3067,31 @@ int WP11_Object_GetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data,
break;
case CKA_ENCRYPT:
ret = GetBool(object->opFlag | CKF_ENCRYPT, data, len);
ret = GetBoolForFlag(object->opFlag, CKF_ENCRYPT, data, len);
break;
case CKA_DECRYPT:
ret = GetBool(object->opFlag | CKF_DECRYPT, data, len);
ret = GetBoolForFlag(object->opFlag, CKF_DECRYPT, data, len);
break;
case CKA_VERIFY:
ret = GetBool(object->opFlag | CKF_VERIFY, data, len);
ret = GetBoolForFlag(object->opFlag, CKF_VERIFY, data, len);
break;
case CKA_VERIFY_RECOVER:
ret = GetBool(object->opFlag | CKF_VERIFY_RECOVER, data, len);
ret = GetBoolForFlag(object->opFlag, CKF_VERIFY_RECOVER, data, len);
break;
case CKA_SIGN:
ret = GetBool(object->opFlag | CKF_SIGN, data, len);
ret = GetBoolForFlag(object->opFlag, CKF_SIGN, data, len);
break;
case CKA_SIGN_RECOVER:
ret = GetBool(object->opFlag | CKF_SIGN_RECOVER, data, len);
ret = GetBoolForFlag(object->opFlag, CKF_SIGN_RECOVER, data, len);
break;
case CKA_WRAP:
ret = GetBool(object->opFlag | CKF_WRAP, data, len);
ret = GetBoolForFlag(object->opFlag, CKF_WRAP, data, len);
break;
case CKA_UNWRAP:
ret = GetBool(object->opFlag | CKF_UNWRAP, data, len);
ret = GetBoolForFlag(object->opFlag, CKF_UNWRAP, data, len);
break;
case CKA_DERIVE:
ret = GetBool(object->opFlag | CKF_DERIVE, data, len);
ret = GetBoolForFlag(object->opFlag, CKF_DERIVE, data, len);
break;
case CKA_SUBJECT:
@ -3800,6 +3821,105 @@ int WP11_RsaOaep_PrivateDecrypt(unsigned char* in, word32 inLen,
}
#endif
/**
* RSA sign data with private key.
*
* @param in [in] Data to sign.
* @param inLen [in] Length of data.
* @param sig [in] Buffer to hold signature data.
* @param sigLen [in,out] On in, length of buffer.
* On out, length data in buffer.
* @param priv [in] Private key object.
* @param slot [in] Slot operation is performed on.
* @return RSA_BUFFER_E or BUFFER_E when sigLen is too small.
* Other -ve when signing fails.
* 0 on success.
*/
int WP11_Rsa_Sign(unsigned char* in, word32 inLen, unsigned char* sig,
word32* sigLen, WP11_Object* priv, WP11_Slot* slot)
{
int ret;
WC_RNG rng;
byte data[RSA_MAX_SIZE / 8];
word32 keyLen;
keyLen = wc_RsaEncryptSize(&priv->data.rsaKey);
if (inLen < keyLen) {
XMEMSET(data, 0, keyLen - inLen);
XMEMCPY(data + keyLen - inLen, in, inLen);
in = data;
inLen = keyLen;
}
if (priv->onToken)
WP11_Lock_LockRO(priv->lock);
ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng);
if (ret == 0) {
ret = wc_RsaDirect(in, inLen, sig, sigLen, &priv->data.rsaKey,
RSA_PRIVATE_ENCRYPT, &rng);
Rng_Free(&rng);
}
if (priv->onToken)
WP11_Lock_UnlockRO(priv->lock);
if (ret > 0)
*sigLen = ret;
return ret;
}
/**
* RSA verify data with public key.
*
* @param sig [in] Signature data.
* @param sigLen [in] Length of buffer.
* @param in [in] Data to verify.
* @param inLen [in] Length of data.
* @param stat [out] Status of verification. 1 on success, otherwise 0.
* @param pub [in] Public key object.
* @return -ve when verifying fails.
* 0 on success.
*/
int WP11_Rsa_Verify(unsigned char* sig, word32 sigLen, unsigned char* in,
word32 inLen, int* stat, WP11_Object* pub)
{
byte decSig[RSA_MAX_SIZE / 8];
word32 decSigLen;
int ret = 0;
byte bits;
word32 i;
word32 j;
*stat = 0;
if (pub->onToken)
WP11_Lock_LockRO(pub->lock);
decSigLen = wc_RsaEncryptSize(&pub->data.rsaKey);
ret = wc_RsaDirect(sig, sigLen, decSig, &decSigLen, &pub->data.rsaKey,
RSA_PUBLIC_DECRYPT, NULL);
if (pub->onToken)
WP11_Lock_UnlockRO(pub->lock);
if (ret > 0)
ret = 0;
if (ret == 0) {
bits = 0;
if (inLen < decSigLen) {
for (i = 0; (bits == 0) && (i < decSigLen - inLen); i++) {
bits |= decSigLen;
}
}
for (j=0,i=decSigLen - inLen; (bits == 0) && (i < decSigLen); i++,j++) {
bits |= (in[j] ^ decSig[i]);
}
*stat = (bits == 0);
}
return ret;
}
/**
* PKCS#1.5 sign encoded hash with private key.
*
@ -4628,6 +4748,227 @@ int WP11_AesCbc_DecryptFinal(WP11_Session* session)
return ret;
}
/**
* Encrypt plain text with AES-CBC and PKCS#5/7 padding.
* Output buffer must be large enough to hold all data and padding.
*
* @param plain [in] Plain text.
* @param plainSz [in] Length of plain text in bytes.
* @param enc [in] Buffer to hold encrypted data.
* @param encSz [in,out] On in, length of buffer in bytes.
* On out, length of encrypted data in bytes.
* @param session [in] Session object holding Aes object.
* @return -ve on encryption failure.
* 0 on success.
*/
int WP11_AesCbcPad_Encrypt(unsigned char* plain, word32 plainSz,
unsigned char* enc, word32* encSz,
WP11_Session* session)
{
int ret;
word32 sz = *encSz;
word32 finalSz;
ret = WP11_AesCbcPad_EncryptUpdate(plain, plainSz, enc, &sz, session);
if (ret == 0) {
finalSz = *encSz - sz;
ret = WP11_AesCbcPad_EncryptFinal(enc + sz, &finalSz, session);
if (ret == 0) {
*encSz = sz + finalSz;
}
}
return ret;
}
/**
* Encrypt more plain text with AES-CBC.
* Data not filling a block is cached.
*
* @param plain [in] Plain text.
* @param plainSz [in] Length of plain text in bytes.
* @param enc [in] Buffer to hold encrypted data.
* @param encSz [in,out] On in, length of buffer in bytes.
* On out, length of encrypted data in bytes.
* @param session [in] Session object holding Aes object.
* @return -ve on encryption failure.
* 0 on success.
*/
int WP11_AesCbcPad_EncryptUpdate(unsigned char* plain, word32 plainSz,
unsigned char* enc, word32* encSz,
WP11_Session* session)
{
return WP11_AesCbc_EncryptUpdate(plain, plainSz, enc, encSz, session);
}
/**
* Finalize encryption with AES-CBC and PKCS#5/7 padding.
* A block of encrypted data is returned due to padding.
*
* @param enc [in] Buffer to hold encrypted data.
* @param encSz [in,out] On in, length of buffer in bytes.
* On out, length of encrypted data in bytes.
* @param session [in] Session object holding Aes object.
* @return 0 on success.
*/
int WP11_AesCbcPad_EncryptFinal(unsigned char* enc, word32* encSz,
WP11_Session* session)
{
int ret = 0;
WP11_CbcParams* cbc = &session->params.cbc;
int padCnt = AES_BLOCK_SIZE - cbc->partialSz;
int i;
for (i = 0; i < AES_BLOCK_SIZE; i++) {
byte mask = 0 - (i >= AES_BLOCK_SIZE - padCnt);
cbc->partial[i] &= ~mask;
cbc->partial[i] |= padCnt & mask;
}
ret = wc_AesCbcEncrypt(&cbc->aes, enc, cbc->partial, AES_BLOCK_SIZE);
if (ret == 0)
*encSz = AES_BLOCK_SIZE;
wc_AesFree(&cbc->aes);
cbc->partialSz = 0;
session->init = 0;
return ret;
}
/**
* Decrypt data with AES-CBC that has PKCS#5/7 padding.
* Output buffer must be large enough to hold all decrypted data.
* Padding is removed.
*
* @param enc [in] Encrypted data.
* @param encSz [in] Length of encrypted data in bytes.
* @param dec [in] Buffer to hold decrypted data.
* @param decSz [in,out] On in, length of buffer in bytes.
* On out, length of decrypted data in bytes.
* @param session [in] Session object holding Aes object.
* @return -ve on encryption failure.
* 0 on success.
*/
int WP11_AesCbcPad_Decrypt(unsigned char* enc, word32 encSz, unsigned char* dec,
word32* decSz, WP11_Session* session)
{
int ret;
word32 sz = *decSz;
word32 finalSz;
ret = WP11_AesCbcPad_DecryptUpdate(enc, encSz, dec, &sz, session);
if (ret == 0) {
finalSz = *decSz - sz;
ret = WP11_AesCbcPad_DecryptFinal(dec + sz, &finalSz, session);
if (ret == 0) {
*decSz = sz + finalSz;
}
}
return ret;
}
/**
* Decrypt more data with AES-CBC. Keep data for padding.
* Data not filling a block or last block is cached.
*
* @param enc [in] Encrypted data.
* @param encSz [in] Length of encrypted data in bytes.
* @param dec [in] Buffer to hold decrypted data.
* @param decSz [in,out] On in, length of buffer in bytes.
* On out, length of decrypted data in bytes.
* @param session [in] Session object holding Aes object.
* @return -ve on encryption failure.
* 0 on success.
*/
int WP11_AesCbcPad_DecryptUpdate(unsigned char* enc, word32 encSz,
unsigned char* dec, word32* decSz,
WP11_Session* session)
{
int ret = 0;
WP11_CbcParams* cbc = &session->params.cbc;
int sz = 0;
int outSz = 0;
if (cbc->partialSz > 0) {
sz = AES_BLOCK_SIZE - cbc->partialSz;
if (sz > (int)encSz)
sz = encSz;
XMEMCPY(cbc->partial + cbc->partialSz, enc, sz);
cbc->partialSz += sz;
enc += sz;
encSz -= sz;
if (cbc->partialSz == AES_BLOCK_SIZE && encSz > 0) {
ret = wc_AesCbcDecrypt(&cbc->aes, dec, cbc->partial,
AES_BLOCK_SIZE);
dec += AES_BLOCK_SIZE;
outSz += AES_BLOCK_SIZE;
cbc->partialSz = 0;
}
}
if (ret == 0 && encSz > AES_BLOCK_SIZE) {
sz = encSz - (encSz & (AES_BLOCK_SIZE - 1));
if (sz == (int)encSz)
sz -= AES_BLOCK_SIZE;
ret = wc_AesCbcDecrypt(&cbc->aes, dec, enc, sz);
outSz += sz;
enc += sz;
encSz -= sz;
}
if (ret == 0 && encSz > 0) {
XMEMCPY(cbc->partial, enc, encSz);
cbc->partialSz = encSz;
}
if (ret == 0)
*decSz = outSz;
return ret;
}
/**
* Finalize decryption with AES-CBC and remove PKCS#5/7 padding.
* Decrypted data without padding is returned.
*
* @param dec [in] Buffer to hold decrypted data.
* @param decSz [in,out] On in, length of buffer in bytes.
* On out, length of decrypted data in bytes.
* @param session [in] Session object holding Aes object.
* @return 0 on success.
*/
int WP11_AesCbcPad_DecryptFinal(unsigned char* dec, word32* decSz,
WP11_Session* session)
{
int ret = 0;
WP11_CbcParams* cbc = &session->params.cbc;
int i;
byte padCnt;
byte outSz;
unsigned char tmp[AES_BLOCK_SIZE];
unsigned char* p = dec;
size_t mask;
ret = wc_AesCbcDecrypt(&cbc->aes, cbc->partial, cbc->partial,
cbc->partialSz);
if (ret == 0) {
padCnt = cbc->partial[AES_BLOCK_SIZE-1];
outSz = AES_BLOCK_SIZE - (padCnt & (0 - (padCnt <= AES_BLOCK_SIZE)));
for (i = 0; i < AES_BLOCK_SIZE; i++) {
mask = (size_t)0 - (i != outSz);
p = (unsigned char*)((size_t)p & mask);
p = (unsigned char*)((size_t)p | ((size_t)tmp & (~mask)));
*p = cbc->partial[i];
p++;
}
*decSz = outSz;
}
wc_AesFree(&cbc->aes);
cbc->partialSz = 0;
session->init = 0;
return ret;
}
#endif
#ifdef HAVE_AESGCM

View File

@ -106,7 +106,7 @@ static CK_TOKEN_INFO tokenInfoTemplate = {
"wolfpkcs11",
"wolfpkcs11",
"0000000000000000",
CKF_RNG | CKF_CLOCK_ON_TOKEN,
CKF_RNG | CKF_CLOCK_ON_TOKEN | CKF_LOGIN_REQUIRED,
WP11_SESSION_CNT_MAX, /* ulMaxSessionCount */
CK_UNAVAILABLE_INFORMATION, /* ulSessionCount */
WP11_SESSION_CNT_MAX, /* ulMaxRwSessionCount */
@ -227,6 +227,7 @@ static CK_MECHANISM_TYPE mechanismList[] = {
#ifndef NO_AES
#ifdef HAVE_AES_CBC
CKM_AES_CBC,
CKM_AES_CBC_PAD,
#endif
#ifdef HAVE_AESGCM
CKM_AES_GCM,
@ -310,7 +311,7 @@ static CK_MECHANISM_INFO rsaKgMechInfo = {
#endif
/* Info on RSA X.509 mechanism. */
static CK_MECHANISM_INFO rsaX509MechInfo = {
1024, 4096, CKF_ENCRYPT | CKF_DECRYPT
1024, 4096, CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY
};
/* Info on RSA PKCS#1.5 mechanism. */
static CK_MECHANISM_INFO rsaPkcsMechInfo = {
@ -473,6 +474,7 @@ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
#endif
#ifndef NO_AES
#ifdef HAVE_AES_CBC
case CKM_AES_CBC_PAD:
case CKM_AES_CBC:
XMEMCPY(pInfo, &aesCbcMechInfo, sizeof(CK_MECHANISM_INFO));
break;

View File

@ -4868,6 +4868,8 @@ static CK_RV test_aes_cbc_fixed_key(void* args)
CK_RV ret;
CK_OBJECT_HANDLE key = CK_INVALID_HANDLE;
(void)aes_128_cbc_pad_exp;
ret = get_aes_128_key(session, NULL, 0, &key);
if (ret == CKR_OK)
ret = test_aes_cbc_encdec(session, aes_128_cbc_exp, key);

View File

@ -399,7 +399,7 @@ static CK_RV test_no_token_init(void* args)
CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args;
CK_RV ret;
CK_TOKEN_INFO tokenInfo;
CK_FLAGS expFlags = CKF_RNG | CKF_CLOCK_ON_TOKEN;
CK_FLAGS expFlags = CKF_RNG | CKF_CLOCK_ON_TOKEN | CKF_LOGIN_REQUIRED;
int flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
session = CK_INVALID_HANDLE;
@ -583,7 +583,8 @@ static CK_RV test_token(void* args)
CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args;
CK_RV ret;
CK_TOKEN_INFO tokenInfo;
CK_FLAGS expFlags = CKF_RNG | CKF_CLOCK_ON_TOKEN | CKF_TOKEN_INITIALIZED;
CK_FLAGS expFlags = CKF_RNG | CKF_CLOCK_ON_TOKEN | CKF_LOGIN_REQUIRED |
CKF_TOKEN_INITIALIZED;
unsigned char label[32];
int flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
@ -882,8 +883,8 @@ static CK_RV test_login_logout(void* args)
int roFlags = CKF_SERIAL_SESSION;
CK_OBJECT_HANDLE roSession;
CK_TOKEN_INFO tokenInfo;
CK_FLAGS expFlags = CKF_RNG | CKF_CLOCK_ON_TOKEN | CKF_TOKEN_INITIALIZED |
CKF_USER_PIN_INITIALIZED;
CK_FLAGS expFlags = CKF_RNG | CKF_CLOCK_ON_TOKEN | CKF_LOGIN_REQUIRED |
CKF_TOKEN_INITIALIZED | CKF_USER_PIN_INITIALIZED;
funcList->C_Logout(session);
@ -3390,6 +3391,60 @@ static CK_RV rsa_oaep_test(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv,
}
#endif
static CK_RV rsa_x_509_sig_test(CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE priv, CK_OBJECT_HANDLE pub,
int hashSz)
{
CK_RV ret = CKR_OK;
byte hash[64], badHash[32], out[2048/8];
CK_ULONG outSz;
CK_MECHANISM mech;
memset(hash, 9, sizeof(hash));
memset(badHash, 7, sizeof(badHash));
outSz = sizeof(out);
mech.mechanism = CKM_RSA_X_509;
mech.ulParameterLen = 0;
mech.pParameter = NULL;
ret = funcList->C_SignInit(session, &mech, priv);
CHECK_CKR(ret, "RSA X_509 Sign Init");
if (ret == CKR_OK) {
outSz = 0;
ret = funcList->C_Sign(session, hash, hashSz, NULL, &outSz);
CHECK_CKR(ret, "RSA X_509 Sign no out");
}
if (ret == CKR_OK) {
CHECK_COND(outSz == sizeof(out), ret, "RSA X_509 Sign out size");
}
if (ret == CKR_OK) {
outSz = 0;
ret = funcList->C_Sign(session, hash, hashSz, out, &outSz);
CHECK_CKR_FAIL(ret, CKR_BUFFER_TOO_SMALL,
"RSA X_509 Sign zero out size");
outSz = sizeof(out);
}
if (ret == CKR_OK) {
ret = funcList->C_Sign(session, hash, hashSz, out, &outSz);
CHECK_CKR(ret, "RSA X_509 Sign");
}
if (ret == CKR_OK) {
ret = funcList->C_VerifyInit(session, &mech, pub);
CHECK_CKR(ret, "RSA X_509 Verify Init");
}
if (ret == CKR_OK) {
ret = funcList->C_Verify(session, hash, hashSz, out, outSz);
CHECK_CKR(ret, "RSA X_509 Verify");
}
if (ret == CKR_OK) {
ret = funcList->C_Verify(session, badHash, sizeof(badHash), out, outSz);
CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, "RSA X_509 Verify bad hash");
}
return ret;
}
static CK_RV rsa_pkcs15_sig_test(CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE priv, CK_OBJECT_HANDLE pub,
int hashSz)
@ -3595,6 +3650,36 @@ static CK_RV test_rsa_fixed_keys_oaep(void* args)
}
#endif
static CK_RV test_rsa_fixed_keys_x_509_sig(void* args)
{
CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args;
CK_RV ret;
CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
ret = get_rsa_priv_key(session, NULL, 0, CK_FALSE, &priv);
if (ret == CKR_OK)
ret = get_rsa_pub_key(session, NULL, 0, &pub);
if (ret == CKR_OK) {
ret = rsa_x_509_sig_test(session, priv, pub, 32);
CHECK_CKR(ret, "RSA X_509 - 32 byte hash");
}
if (ret == CKR_OK) {
ret = rsa_x_509_sig_test(session, priv, pub, 28);
CHECK_CKR(ret, "RSA X_509 - 28 byte hash");
}
if (ret == CKR_OK) {
ret = rsa_x_509_sig_test(session, priv, pub, 48);
CHECK_CKR(ret, "RSA X_509 - 48 byte hash");
}
if (ret == CKR_OK) {
ret = rsa_x_509_sig_test(session, priv, pub, 64);
CHECK_CKR(ret, "RSA X_509 - 64 byte hash");
}
return ret;
}
static CK_RV test_rsa_fixed_keys_pkcs15_sig(void* args)
{
CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args;
@ -5787,6 +5872,548 @@ static CK_RV test_aes_cbc_gen_key_id(void* args)
return ret;
}
static CK_RV test_aes_cbc_pad_encdec(CK_SESSION_HANDLE session,
unsigned char* exp, CK_OBJECT_HANDLE key)
{
CK_RV ret;
byte plain[32], enc[sizeof(plain)+16], dec[32], iv[16];
CK_ULONG plainSz, encSz, decSz, ivSz;
CK_MECHANISM mech;
memset(plain, 9, sizeof(plain));
memset(iv, 9, sizeof(iv));
plainSz = sizeof(plain);
encSz = sizeof(enc);
decSz = sizeof(dec);
ivSz = sizeof(iv);
mech.mechanism = CKM_AES_CBC_PAD;
mech.ulParameterLen = ivSz;
mech.pParameter = iv;
ret = funcList->C_EncryptInit(session, &mech, key);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Init");
if (ret == CKR_OK) {
encSz = 0;
ret = funcList->C_Encrypt(session, plain, plainSz, NULL, &encSz);
CHECK_CKR(ret, "AES-CBC Pad Encrypt no enc");
}
if (ret == CKR_OK && encSz != plainSz) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Encrypt encrypted length");
}
if (ret == CKR_OK) {
encSz = 0;
ret = funcList->C_Encrypt(session, plain, plainSz, enc, &encSz);
CHECK_CKR_FAIL(ret, CKR_BUFFER_TOO_SMALL,
"AES-CBC Pad Encrypt zero enc size");
}
if (ret == CKR_OK) {
encSz = sizeof(enc);
ret = funcList->C_Encrypt(session, plain, plainSz, enc, &encSz);
CHECK_CKR(ret, "AES-CBC Pad Encrypt");
}
if (ret == CKR_OK && exp != NULL) {
if (encSz != plainSz + 16 || XMEMCMP(enc, exp, encSz) != 0)
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Encrypt Result not matching expected");
}
if (ret == CKR_OK) {
ret = funcList->C_DecryptInit(session, &mech, key);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Init");
}
if (ret == CKR_OK) {
decSz = 0;
ret = funcList->C_Decrypt(session, enc, encSz, NULL, &decSz);
CHECK_CKR(ret, "AES-CBC Pad Decrypt");
}
if (ret == CKR_OK && decSz != encSz-1) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypt decrypted length");
}
if (ret == CKR_OK) {
decSz = sizeof(dec);
ret = funcList->C_Decrypt(session, enc, encSz, dec, &decSz);
CHECK_CKR(ret, "AES-CBC Pad Decrypt");
}
if (ret == CKR_OK) {
if (decSz != plainSz || XMEMCMP(plain, dec, decSz) != 0) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypted data match plain text");
}
}
return ret;
}
static CK_RV test_aes_cbc_pad_update(CK_SESSION_HANDLE session,
unsigned char* exp, CK_OBJECT_HANDLE key,
CK_ULONG inc)
{
CK_RV ret;
byte plain[32], enc[sizeof(plain)+16], dec[32], iv[16];
byte* pIn;
byte* pOut;
CK_ULONG plainSz, encSz, decSz, ivSz, remSz, cumSz, partSz, inRemSz;
CK_MECHANISM mech;
memset(plain, 9, sizeof(plain));
memset(iv, 9, sizeof(iv));
memset(enc, 0, sizeof(enc));
memset(dec, 0, sizeof(dec));
plainSz = sizeof(plain);
encSz = sizeof(enc);
decSz = sizeof(dec);
ivSz = sizeof(iv);
remSz = encSz;
cumSz = 0;
mech.mechanism = CKM_AES_CBC_PAD;
mech.ulParameterLen = ivSz;
mech.pParameter = iv;
ret = funcList->C_EncryptInit(session, &mech, key);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Init");
if (ret == CKR_OK) {
encSz = 1;
ret = funcList->C_EncryptUpdate(session, plain, 1, NULL, &encSz);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Update");
}
if (ret == CKR_OK && encSz != 0) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Encrypt Update encrypted size");
}
if (ret == CKR_OK) {
encSz = 0;
ret = funcList->C_EncryptUpdate(session, plain, 16, NULL, &encSz);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Update");
}
if (ret == CKR_OK && encSz != 16) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Encrypt Update encrypted size");
}
if (ret == CKR_OK) {
encSz = 0;
ret = funcList->C_EncryptUpdate(session, plain, 16, enc, &encSz);
CHECK_CKR_FAIL(ret, CKR_BUFFER_TOO_SMALL,
"AES-CBC Pad Encrypt Update zero enc size");
encSz = sizeof(enc);
}
if (ret == CKR_OK) {
pIn = plain;
pOut = enc;
inRemSz = plainSz;
partSz = inc;
while (ret == CKR_OK && inRemSz > 0) {
if (inc > inRemSz)
partSz = inRemSz;
ret = funcList->C_EncryptUpdate(session, pIn, partSz, pOut, &encSz);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Update");
pIn += partSz;
inRemSz -= partSz;
pOut += encSz;
cumSz += encSz;
encSz = (remSz -= encSz);
}
}
if (ret == CKR_OK) {
encSz = 1;
ret = funcList->C_EncryptFinal(session, NULL, &encSz);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Final");
}
if (ret == CKR_OK && encSz != 16) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Encrypt Final encrypted size");
}
if (ret == CKR_OK) {
encSz = remSz;
ret = funcList->C_EncryptFinal(session, pOut, &encSz);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Final");
encSz += cumSz;
}
if (ret == CKR_OK && exp != NULL) {
if (encSz != plainSz + 16 || XMEMCMP(enc, exp, encSz) != 0)
ret = -1;
CHECK_CKR(ret,
"AES-CBC Pad Encrypt Update Result not matching expected");
}
if (ret == CKR_OK) {
ret = funcList->C_DecryptInit(session, &mech, key);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Init");
}
if (ret == CKR_OK) {
decSz = 1;
ret = funcList->C_DecryptUpdate(session, enc, 1, NULL, &decSz);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Update");
}
if (ret == CKR_OK && decSz != 0) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypt Update encrypted size");
}
if (ret == CKR_OK) {
decSz = 0;
ret = funcList->C_DecryptUpdate(session, enc, 16, NULL, &decSz);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Update");
}
if (ret == CKR_OK && decSz != 0) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypt Update encrypted size");
}
if (ret == CKR_OK) {
decSz = 0;
ret = funcList->C_DecryptUpdate(session, enc, 32, dec, &decSz);
CHECK_CKR_FAIL(ret, CKR_BUFFER_TOO_SMALL,
"AES-CBC Pad Encrypt Update zero dec size");
decSz = sizeof(dec);
}
if (ret == CKR_OK) {
pIn = enc;
pOut = dec;
cumSz = 0;
remSz = decSz;
inRemSz = encSz;
partSz = inc;
while (ret == CKR_OK && inRemSz > 0) {
if (inc > inRemSz)
partSz = inRemSz;
ret = funcList->C_DecryptUpdate(session, pIn, partSz, pOut, &decSz);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Update");
pIn += partSz;
inRemSz -= partSz;
pOut += decSz;
cumSz += decSz;
decSz = (remSz -= decSz);
}
}
if (ret == CKR_OK) {
decSz = 16;
ret = funcList->C_DecryptFinal(session, NULL, &decSz);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Final");
}
if (ret == CKR_OK && decSz != 15) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypt Final decrypted size");
}
if (ret == CKR_OK) {
decSz = remSz;
ret = funcList->C_DecryptFinal(session, pOut, &decSz);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Final");
decSz += cumSz;
}
if (ret == CKR_OK) {
if (decSz != plainSz) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypted data length match");
}
else if (XMEMCMP(plain, dec, decSz) != 0) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypted data match plain text");
}
}
return ret;
}
static CK_RV test_aes_cbc_pad(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key,
CK_ULONG len, CK_ULONG inc)
{
CK_RV ret;
byte plain[32], enc[sizeof(plain)+16], dec[32], iv[16];
byte* pIn;
byte* pOut;
CK_ULONG encSz, decSz, ivSz, remSz, cumSz, partSz, inRemSz;
CK_MECHANISM mech;
memset(plain, 9, sizeof(plain));
memset(iv, 9, sizeof(iv));
memset(enc, 0, sizeof(enc));
memset(dec, 0, sizeof(dec));
encSz = sizeof(enc);
decSz = sizeof(dec);
ivSz = sizeof(iv);
remSz = encSz;
cumSz = 0;
mech.mechanism = CKM_AES_CBC_PAD;
mech.ulParameterLen = ivSz;
mech.pParameter = iv;
ret = funcList->C_EncryptInit(session, &mech, key);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Init");
if (ret == CKR_OK) {
ret = funcList->C_Encrypt(session, plain, len, enc, &encSz);
CHECK_CKR(ret, "AES-CBC Pad Encrypt no enc");
}
if (ret == CKR_OK) {
ret = funcList->C_DecryptInit(session, &mech, key);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Init");
}
if (ret == CKR_OK) {
ret = funcList->C_Decrypt(session, enc, encSz, dec, &decSz);
CHECK_CKR(ret, "AES-CBC Pad Decrypt");
}
if (ret == CKR_OK) {
if (decSz != len) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypted data length match");
}
else if (XMEMCMP(plain, dec, decSz) != 0) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypted data match plain text");
}
}
if (ret == CKR_OK) {
ret = funcList->C_EncryptInit(session, &mech, key);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Init");
}
if (ret == CKR_OK) {
pIn = plain;
pOut = enc;
inRemSz = len;
partSz = inc;
while (ret == CKR_OK && inRemSz > 0) {
if (inc > inRemSz)
partSz = inRemSz;
ret = funcList->C_EncryptUpdate(session, pIn, partSz, pOut, &encSz);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Update");
pIn += partSz;
inRemSz -= partSz;
pOut += encSz;
cumSz += encSz;
encSz = (remSz -= encSz);
}
}
if (ret == CKR_OK) {
ret = funcList->C_EncryptFinal(session, pOut, &encSz);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Final");
}
if (ret == CKR_OK) {
ret = funcList->C_DecryptInit(session, &mech, key);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Init");
}
if (ret == CKR_OK) {
pIn = enc;
pOut = dec;
cumSz = 0;
remSz = decSz;
inRemSz = encSz;
partSz = inc;
while (ret == CKR_OK && inRemSz > 0) {
if (inc > inRemSz)
partSz = inRemSz;
ret = funcList->C_DecryptUpdate(session, pIn, partSz, pOut, &decSz);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Update");
pIn += partSz;
inRemSz -= partSz;
pOut += decSz;
cumSz += decSz;
decSz = (remSz -= decSz);
}
}
if (ret == CKR_OK) {
ret = funcList->C_DecryptFinal(session, pOut, &decSz);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Final");
decSz += cumSz;
}
if (ret == CKR_OK) {
if (decSz != len) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypted data length match");
}
else if (XMEMCMP(plain, dec, decSz) != 0) {
ret = -1;
CHECK_CKR(ret, "AES-CBC Pad Decrypted data match plain text");
}
}
return ret;
}
static CK_RV test_aes_cbc_pad_fixed_key(void* args)
{
CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args;
CK_RV ret;
CK_OBJECT_HANDLE key;
ret = get_aes_128_key(session, NULL, 0, &key);
if (ret == CKR_OK)
ret = test_aes_cbc_pad_encdec(session, aes_128_cbc_pad_exp, key);
if (ret == CKR_OK)
ret = test_aes_cbc_pad_update(session, aes_128_cbc_pad_exp, key, 16);
if (ret == CKR_OK)
ret = test_aes_cbc_pad_update(session, aes_128_cbc_pad_exp, key, 1);
if (ret == CKR_OK)
ret = test_aes_cbc_pad_update(session, aes_128_cbc_pad_exp, key, 5);
if (ret == CKR_OK)
ret = test_aes_cbc_pad_update(session, aes_128_cbc_pad_exp, key, 18);
if (ret == CKR_OK)
ret = test_aes_cbc_pad(session, key, 31, 1);
if (ret == CKR_OK)
ret = test_aes_cbc_pad(session, key, 17, 4);
return ret;
}
static CK_RV test_aes_cbc_pad_fail(void* args)
{
CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args;
CK_RV ret;
CK_OBJECT_HANDLE key;
CK_OBJECT_HANDLE generic;
byte plain[32], enc[sizeof(plain)+16], dec[32], iv[16];
CK_ULONG plainSz, encSz, decSz, ivSz;
CK_MECHANISM mech;
memset(plain, 9, sizeof(plain));
memset(iv, 9, sizeof(iv));
plainSz = sizeof(plain);
encSz = sizeof(enc);
decSz = sizeof(dec);
ivSz = sizeof(iv);
mech.mechanism = CKM_AES_CBC_PAD;
mech.ulParameterLen = ivSz;
mech.pParameter = iv;
ret = get_aes_128_key(session, NULL, 0, &key);
if (ret == CKR_OK) {
ret = get_generic_key(session, plain, sizeof(plain), CK_FALSE,
&generic);
}
if (ret == CKR_OK) {
ret = funcList->C_EncryptInit(session, &mech, generic);
CHECK_CKR_FAIL(ret, CKR_KEY_TYPE_INCONSISTENT,
"AES-CBC Pad Encrypt Init wrong key type");
}
if (ret == CKR_OK) {
ret = funcList->C_DecryptInit(session, &mech, generic);
CHECK_CKR_FAIL(ret, CKR_KEY_TYPE_INCONSISTENT,
"AES-CBC Pad Decrypt Init wrong key type");
}
if (ret == CKR_OK) {
mech.pParameter = NULL;
ret = funcList->C_EncryptInit(session, &mech, key);
CHECK_CKR_FAIL(ret, CKR_MECHANISM_PARAM_INVALID,
"AES-CBC Pad Encrypt Init parameter NULL");
mech.pParameter = iv;
}
if (ret == CKR_OK) {
mech.ulParameterLen = ivSz - 1;
ret = funcList->C_EncryptInit(session, &mech, key);
CHECK_CKR_FAIL(ret, CKR_MECHANISM_PARAM_INVALID,
"AES-CBC Pad Encrypt Init parameter length short");
mech.ulParameterLen = ivSz;
}
if (ret == CKR_OK) {
mech.ulParameterLen = ivSz + 1;
ret = funcList->C_EncryptInit(session, &mech, key);
CHECK_CKR_FAIL(ret, CKR_MECHANISM_PARAM_INVALID,
"AES-CBC Pad Encrypt Init parameter length long");
mech.ulParameterLen = ivSz;
}
if (ret == CKR_OK) {
mech.pParameter = NULL;
ret = funcList->C_DecryptInit(session, &mech, key);
CHECK_CKR_FAIL(ret, CKR_MECHANISM_PARAM_INVALID,
"AES-CBC Pad Decrypt Init parameter NULL");
mech.pParameter = iv;
}
if (ret == CKR_OK) {
mech.ulParameterLen = ivSz - 1;
ret = funcList->C_DecryptInit(session, &mech, key);
CHECK_CKR_FAIL(ret, CKR_MECHANISM_PARAM_INVALID,
"AES-CBC Pad Decrypt Init parameter length short");
mech.ulParameterLen = ivSz;
}
if (ret == CKR_OK) {
mech.ulParameterLen = ivSz + 1;
ret = funcList->C_DecryptInit(session, &mech, key);
CHECK_CKR_FAIL(ret, CKR_MECHANISM_PARAM_INVALID,
"AES-CBC Pad Decrypt Init parameter length long");
mech.ulParameterLen = ivSz;
}
if (ret == CKR_OK) {
ret = funcList->C_EncryptInit(session, &mech, key);
CHECK_CKR(ret, "AES-CBC Pad Encrypt Init");
}
if (ret == CKR_OK) {
ret = funcList->C_Decrypt(session, enc, encSz, dec, &decSz);
CHECK_CKR_FAIL(ret, CKR_OPERATION_NOT_INITIALIZED,
"AES-CBC Pad Decrypt wrong init");
}
if (ret == CKR_OK) {
ret = funcList->C_DecryptUpdate(session, enc, encSz, dec, &decSz);
CHECK_CKR_FAIL(ret, CKR_OPERATION_NOT_INITIALIZED,
"AES-CBC Pad Decrypt Update wrong init");
}
if (ret == CKR_OK) {
ret = funcList->C_DecryptFinal(session, enc, &decSz);
CHECK_CKR_FAIL(ret, CKR_OPERATION_NOT_INITIALIZED,
"AES-CBC Pad Decrypt Final wrong init");
}
if (ret == CKR_OK) {
ret = funcList->C_DecryptInit(session, &mech, key);
CHECK_CKR(ret, "AES-CBC Pad Decrypt Init");
}
if (ret == CKR_OK) {
ret = funcList->C_Encrypt(session, plain, plainSz, enc, &encSz);
CHECK_CKR_FAIL(ret, CKR_OPERATION_NOT_INITIALIZED,
"AES-CBC Pad Encrypt wrong init");
}
if (ret == CKR_OK) {
ret = funcList->C_EncryptUpdate(session, plain, plainSz, enc, &encSz);
CHECK_CKR_FAIL(ret, CKR_OPERATION_NOT_INITIALIZED,
"AES-CBC Pad Encrypt Update wrong init");
}
if (ret == CKR_OK) {
ret = funcList->C_EncryptFinal(session, enc, &encSz);
CHECK_CKR_FAIL(ret, CKR_OPERATION_NOT_INITIALIZED,
"AES-CBC Pad Encrypt Final wrong init");
}
return ret;
}
static CK_RV test_aes_cbc_pad_gen_key(void* args)
{
CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args;
CK_RV ret;
CK_OBJECT_HANDLE key;
ret = gen_aes_key(session, 16, NULL, 0, 0, &key);
if (ret == CKR_OK)
ret = test_aes_cbc_pad_encdec(session, NULL, key);
if (ret == CKR_OK)
ret = test_aes_cbc_pad_update(session, NULL, key, 32);
return ret;
}
static CK_RV test_aes_cbc_pad_gen_key_id(void* args)
{
CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args;
CK_RV ret;
CK_OBJECT_HANDLE key;
unsigned char* id = (unsigned char*)"123aes128";
int idSz = 9;
ret = gen_aes_key(session, 32, id, idSz, 0, NULL);
if (ret == CKR_OK)
ret = find_aes_key(session, id, idSz, &key);
if (ret == CKR_OK)
ret = test_aes_cbc_pad_encdec(session, NULL, key);
if (ret == CKR_OK)
ret = test_aes_cbc_pad_update(session, NULL, key, 32);
return ret;
}
#endif
#ifdef HAVE_AESGCM
@ -6990,6 +7617,7 @@ static TEST_FUNC testFunc[] = {
#ifndef WC_NO_RSA_OAEP
PKCS11TEST_FUNC_SESS_DECL(test_rsa_fixed_keys_oaep),
#endif
PKCS11TEST_FUNC_SESS_DECL(test_rsa_fixed_keys_x_509_sig),
PKCS11TEST_FUNC_SESS_DECL(test_rsa_fixed_keys_pkcs15_sig),
#ifdef WC_RSA_PSS
PKCS11TEST_FUNC_SESS_DECL(test_rsa_fixed_keys_pss),
@ -7030,6 +7658,10 @@ static TEST_FUNC testFunc[] = {
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_fail),
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_gen_key),
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_gen_key_id),
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_pad_fixed_key),
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_pad_fail),
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_pad_gen_key),
PKCS11TEST_FUNC_SESS_DECL(test_aes_cbc_pad_gen_key_id),
#endif
#ifdef HAVE_AESGCM
PKCS11TEST_FUNC_SESS_DECL(test_aes_gcm_fixed_key),

View File

@ -415,6 +415,14 @@ static unsigned char aes_128_cbc_exp[] = {
0xe3, 0xca, 0x03, 0xb5, 0x0a, 0x0f, 0x33, 0x84,
0xc6, 0x4a, 0xb7, 0x12, 0xd0, 0xb0, 0x32, 0x76
};
static unsigned char aes_128_cbc_pad_exp[] = {
0x00, 0x1b, 0x7d, 0x66, 0x5c, 0xdc, 0xbb, 0x82,
0x19, 0x0c, 0xe4, 0x59, 0xfa, 0x05, 0x4e, 0x1f,
0xe3, 0xca, 0x03, 0xb5, 0x0a, 0x0f, 0x33, 0x84,
0xc6, 0x4a, 0xb7, 0x12, 0xd0, 0xb0, 0x32, 0x76,
0x37, 0x7e, 0x93, 0x5b, 0x2a, 0x3e, 0x6e, 0xec,
0x20, 0x1a, 0x10, 0xbb, 0x3f, 0x0d, 0xde, 0x28
};
#endif
#ifdef HAVE_AESGCM

View File

@ -105,6 +105,8 @@ extern "C" {
#define WP11_INIT_AES_CBC_DEC 0x0002
#define WP11_INIT_AES_GCM_ENC 0x0003
#define WP11_INIT_AES_GCM_DEC 0x0004
#define WP11_INIT_AES_CBC_PAD_ENC 0x0005
#define WP11_INIT_AES_CBC_PAD_DEC 0x0006
#define WP11_INIT_HMAC_SIGN 0x0010
#define WP11_INIT_HMAC_VERIFY 0x0011
#define WP11_INIT_RSA_X_509_ENC 0x0020
@ -117,6 +119,8 @@ extern "C" {
#define WP11_INIT_RSA_PKCS_VERIFY 0x0031
#define WP11_INIT_RSA_PKCS_PSS_SIGN 0x0032
#define WP11_INIT_RSA_PKCS_PSS_VERIFY 0x0033
#define WP11_INIT_RSA_X_509_SIGN 0x0034
#define WP11_INIT_RSA_X_509_VERIFY 0x0035
#define WP11_INIT_ECDSA_SIGN 0x0040
#define WP11_INIT_ECDSA_VERIFY 0x0041
@ -278,6 +282,10 @@ int WP11_RsaOaep_PublicEncrypt(unsigned char* in, word32 inLen,
int WP11_RsaOaep_PrivateDecrypt(unsigned char* in, word32 inLen,
unsigned char* out, word32* outLen,
WP11_Object* priv, WP11_Session* session);
int WP11_Rsa_Sign(unsigned char* in, word32 inLen, unsigned char* sig,
word32* sigLen, WP11_Object* priv, WP11_Slot* slot);
int WP11_Rsa_Verify(unsigned char* sig, word32 sigLen, unsigned char* in,
word32 inLen, int* stat, WP11_Object* pub);
int WP11_RsaPkcs15_Sign(unsigned char* encHash, word32 encHashLen,
unsigned char* sig, word32* sigLen, WP11_Object* priv,
WP11_Slot* slot);
@ -307,6 +315,7 @@ int WP11_Dh_Derive(unsigned char* pub, word32 pubLen, unsigned char* key,
word32* keyLen, WP11_Object* priv);
int WP11_AesGenerateKey(WP11_Object* secret, WP11_Slot* slot);
int WP11_AesCbc_PartLen(WP11_Session* session);
int WP11_AesCbc_Encrypt(unsigned char* plain, word32 plainSz,
unsigned char* enc, word32* encSz,
@ -321,6 +330,22 @@ int WP11_AesCbc_DecryptUpdate(unsigned char* enc, word32 encSz,
unsigned char* dec, word32* decSz,
WP11_Session* session);
int WP11_AesCbc_DecryptFinal(WP11_Session* session);
int WP11_AesCbcPad_Encrypt(unsigned char* plain, word32 plainSz,
unsigned char* enc, word32* encSz,
WP11_Session* session);
int WP11_AesCbcPad_EncryptUpdate(unsigned char* plain, word32 plainSz,
unsigned char* enc, word32* encSz,
WP11_Session* session);
int WP11_AesCbcPad_EncryptFinal(unsigned char* enc, word32* encSz,
WP11_Session* session);
int WP11_AesCbcPad_Decrypt(unsigned char* enc, word32 encSz, unsigned char* dec,
word32* decSz, WP11_Session* session);
int WP11_AesCbcPad_DecryptUpdate(unsigned char* enc, word32 encSz,
unsigned char* dec, word32* decSz,
WP11_Session* session);
int WP11_AesCbcPad_DecryptFinal(unsigned char* dec, word32* decSz,
WP11_Session* session);
int WP11_AesGcm_GetTagBits(WP11_Session* session);
int WP11_AesGcm_EncDataLen(WP11_Session* session);
int WP11_AesGcm_Encrypt(unsigned char* plain, word32 plainSz,

View File

@ -205,6 +205,7 @@ extern "C" {
#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL
#define CKM_AES_KEY_GEN 0x00001080UL
#define CKM_AES_CBC 0x00001082UL
#define CKM_AES_CBC_PAD 0x00001085UL
#define CKM_AES_GCM 0x00001087UL
#define CKR_OK 0x00000000UL