Skip to content

Commit

Permalink
Merge pull request softhsm#445 from martinpaljak/wrap-with-aes-cbc
Browse files Browse the repository at this point in the history
Add wrap support with CKM_AES_CBC
  • Loading branch information
halderen authored Mar 3, 2020
2 parents 853b724 + eec37b9 commit b50ad17
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 13 deletions.
Empty file modified autogen.sh
100644 → 100755
Empty file.
80 changes: 67 additions & 13 deletions src/lib/SoftHSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1074,13 +1074,14 @@ CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_
case CKM_DES_CBC:
case CKM_DES_CBC_PAD:
#endif
case CKM_DES3_ECB:
case CKM_DES3_CBC:
pInfo->flags = CKF_WRAP;
case CKM_DES3_ECB:
case CKM_DES3_CBC_PAD:
// Key size is not in use
pInfo->ulMinKeySize = 0;
pInfo->ulMaxKeySize = 0;
pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT;
pInfo->flags |= CKF_ENCRYPT | CKF_DECRYPT;
break;
case CKM_DES3_CMAC:
// Key size is not in use
Expand All @@ -1093,14 +1094,15 @@ CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_
pInfo->ulMaxKeySize = 32;
pInfo->flags = CKF_GENERATE;
break;
case CKM_AES_ECB:
case CKM_AES_CBC:
pInfo->flags = CKF_WRAP;
case CKM_AES_ECB:
case CKM_AES_CBC_PAD:
case CKM_AES_CTR:
case CKM_AES_GCM:
pInfo->ulMinKeySize = 16;
pInfo->ulMaxKeySize = 32;
pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT;
pInfo->flags |= CKF_ENCRYPT | CKF_DECRYPT;
break;
case CKM_AES_KEY_WRAP:
pInfo->ulMinKeySize = 16;
Expand Down Expand Up @@ -6044,6 +6046,12 @@ CK_RV SoftHSM::WrapKeySym
mode = SymWrap::AES_KEYWRAP_PAD;
break;
#endif
case CKM_AES_CBC:
algo = SymAlgo::AES;
break;
case CKM_DES3_CBC:
algo = SymAlgo::DES3;
break;
default:
return CKR_MECHANISM_INVALID;
}
Expand All @@ -6062,12 +6070,49 @@ CK_RV SoftHSM::WrapKeySym
// adjust key bit length
wrappingkey->setBitLen(wrappingkey->getKeyBits().size() * bb);

// Wrap the key
if (!cipher->wrapKey(wrappingkey, mode, keydata, wrapped))
{
cipher->recycleKey(wrappingkey);
CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
return CKR_GENERAL_ERROR;
ByteString iv;
ByteString encryptedFinal;

if (pMechanism->mechanism == CKM_AES_CBC) {
iv.resize(16);
memcpy(&iv[0], pMechanism->pParameter, 16);
} else if (pMechanism->mechanism == CKM_DES3_CBC){
iv.resize(8);
memcpy(&iv[0], pMechanism->pParameter, 8);
}
switch(pMechanism->mechanism) {

case CKM_AES_CBC:
case CKM_DES3_CBC:
if (!cipher->encryptInit(wrappingkey, SymMode::CBC, iv, false))
{
cipher->recycleKey(wrappingkey);
CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
return CKR_MECHANISM_INVALID;
}
if (!cipher->encryptUpdate(keydata, wrapped))
{
cipher->recycleKey(wrappingkey);
CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
return CKR_GENERAL_ERROR;
}
// Finalize encryption
if (!cipher->encryptFinal(encryptedFinal))
{
cipher->recycleKey(wrappingkey);
CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
return CKR_GENERAL_ERROR;
}
wrapped += encryptedFinal;
break;
default:
// Wrap the key
if (!cipher->wrapKey(wrappingkey, mode, keydata, wrapped))
{
cipher->recycleKey(wrappingkey);
CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
return CKR_GENERAL_ERROR;
}
}

cipher->recycleKey(wrappingkey);
Expand Down Expand Up @@ -6205,7 +6250,11 @@ CK_RV SoftHSM::C_WrapKey
if (rv != CKR_OK)
return rv;
break;

case CKM_AES_CBC:
if (pMechanism->pParameter == NULL_PTR ||
pMechanism->ulParameterLen != 16)
return CKR_ARGUMENTS_BAD;
break;
default:
return CKR_MECHANISM_INVALID;
}
Expand Down Expand Up @@ -6242,13 +6291,18 @@ CK_RV SoftHSM::C_WrapKey
return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
if ((pMechanism->mechanism == CKM_RSA_PKCS || pMechanism->mechanism == CKM_RSA_PKCS_OAEP) && wrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_RSA)
return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
if (pMechanism->mechanism == CKM_AES_CBC && wrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_AES)
return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
if (pMechanism->mechanism == CKM_DES3_CBC && (wrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_DES2 ||
wrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_DES3))
return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;

// Check if the wrapping key can be used for wrapping
if (wrapKey->getBooleanValue(CKA_WRAP, false) == false)
return CKR_KEY_FUNCTION_NOT_PERMITTED;

// Check if the specified mechanism is allowed for the wrapping key
if (!isMechanismPermitted(wrapKey, pMechanism))
// Check if the specified mechanism is allowed for the wrapping key
if (!isMechanismPermitted(wrapKey, pMechanism))
return CKR_MECHANISM_INVALID;

// Check the to be wrapped key handle.
Expand Down

0 comments on commit b50ad17

Please sign in to comment.