From d8d9f4968917324f9a71bdaaa299e5984837f022 Mon Sep 17 00:00:00 2001 From: Antoine Lochet Date: Thu, 31 Aug 2023 15:38:08 +0200 Subject: [PATCH 1/2] Fixed use of ECB with Botan --- src/lib/SoftHSM.cpp | 53 ++- src/lib/SoftHSM.h | 2 +- src/lib/crypto/AESKey.cpp | 6 +- src/lib/crypto/test/AESTests.h | 2 + src/lib/crypto/test/DESTests.h | 2 + src/lib/data_mgr/SecureDataManager.cpp | 549 +++++++++++++------------ 6 files changed, 340 insertions(+), 274 deletions(-) diff --git a/src/lib/SoftHSM.cpp b/src/lib/SoftHSM.cpp index 02c0f95ec..eb0e6d520 100644 --- a/src/lib/SoftHSM.cpp +++ b/src/lib/SoftHSM.cpp @@ -597,7 +597,7 @@ CK_RV SoftHSM::C_Initialize(CK_VOID_PTR pInitArgs) } // Load the enabled list of algorithms - prepareSupportedMecahnisms(mechanisms_table); + prepareSupportedMechanisms(mechanisms_table); isRemovable = Configuration::i()->getBool("slots.removable", false); @@ -720,7 +720,7 @@ CK_RV SoftHSM::C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) return token->getTokenInfo(pInfo); } -void SoftHSM::prepareSupportedMecahnisms(std::map &t) +void SoftHSM::prepareSupportedMechanisms(std::map &t) { #ifndef WITH_FIPS t["CKM_MD5"] = CKM_MD5; @@ -765,20 +765,30 @@ void SoftHSM::prepareSupportedMecahnisms(std::mapflags = CKF_WRAP | CKF_UNWRAP; /* FALLTHROUGH */ #ifndef WITH_FIPS +#ifndef WITH_BOTAN case CKM_DES_ECB: /* FALLTHROUGH */ +#endif case CKM_DES_CBC: /* FALLTHROUGH */ #endif case CKM_DES3_CBC: pInfo->flags |= CKF_WRAP; /* FALLTHROUGH */ +#ifndef WITH_BOTAN case CKM_DES3_ECB: // Key size is not in use pInfo->ulMinKeySize = 0; pInfo->ulMaxKeySize = 0; pInfo->flags |= CKF_ENCRYPT | CKF_DECRYPT; break; +#endif case CKM_DES3_CMAC: // Key size is not in use pInfo->ulMinKeySize = 0; @@ -1160,7 +1176,9 @@ CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_ /* FALLTHROUGH */ case CKM_AES_CBC: pInfo->flags |= CKF_WRAP; +#ifndef WITH_BOTAN case CKM_AES_ECB: +#endif case CKM_AES_CTR: case CKM_AES_GCM: pInfo->ulMinKeySize = 16; @@ -1180,12 +1198,18 @@ CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_ break; #endif #ifndef WITH_FIPS +#ifndef WITH_BOTAN case CKM_DES_ECB_ENCRYPT_DATA: +#endif case CKM_DES_CBC_ENCRYPT_DATA: #endif +#ifndef WITH_BOTAN case CKM_DES3_ECB_ENCRYPT_DATA: +#endif case CKM_DES3_CBC_ENCRYPT_DATA: +#ifndef WITH_BOTAN case CKM_AES_ECB_ENCRYPT_DATA: +#endif case CKM_AES_CBC_ENCRYPT_DATA: // Key size is not in use pInfo->ulMinKeySize = 0; @@ -2203,6 +2227,7 @@ CK_RV SoftHSM::SymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech size_t tagBytes = 0; switch(pMechanism->mechanism) { #ifndef WITH_FIPS +#ifndef WITH_BOTAN case CKM_DES_ECB: if (keyType != CKK_DES) return CKR_KEY_TYPE_INCONSISTENT; @@ -2210,6 +2235,7 @@ CK_RV SoftHSM::SymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech mode = SymMode::ECB; bb = 7; break; +#endif case CKM_DES_CBC: if (keyType != CKK_DES) return CKR_KEY_TYPE_INCONSISTENT; @@ -2242,6 +2268,7 @@ CK_RV SoftHSM::SymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech bb = 7; break; #endif +#ifndef WITH_BOTAN case CKM_DES3_ECB: if (keyType != CKK_DES2 && keyType != CKK_DES3) return CKR_KEY_TYPE_INCONSISTENT; @@ -2249,6 +2276,7 @@ CK_RV SoftHSM::SymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech mode = SymMode::ECB; bb = 7; break; +#endif case CKM_DES3_CBC: if (keyType != CKK_DES2 && keyType != CKK_DES3) return CKR_KEY_TYPE_INCONSISTENT; @@ -2280,12 +2308,14 @@ CK_RV SoftHSM::SymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen); bb = 7; break; +#ifndef WITH_BOTAN case CKM_AES_ECB: if (keyType != CKK_AES) return CKR_KEY_TYPE_INCONSISTENT; algo = SymAlgo::AES; mode = SymMode::ECB; break; +#endif case CKM_AES_CBC: if (keyType != CKK_AES) return CKR_KEY_TYPE_INCONSISTENT; @@ -2933,6 +2963,7 @@ CK_RV SoftHSM::SymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech size_t tagBytes = 0; switch(pMechanism->mechanism) { #ifndef WITH_FIPS +#ifndef WITH_BOTAN case CKM_DES_ECB: if (keyType != CKK_DES) return CKR_KEY_TYPE_INCONSISTENT; @@ -2940,6 +2971,7 @@ CK_RV SoftHSM::SymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech mode = SymMode::ECB; bb = 7; break; +#endif case CKM_DES_CBC: if (keyType != CKK_DES) return CKR_KEY_TYPE_INCONSISTENT; @@ -2972,6 +3004,7 @@ CK_RV SoftHSM::SymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech bb = 7; break; #endif +#ifndef WITH_BOTAN case CKM_DES3_ECB: if (keyType != CKK_DES2 && keyType != CKK_DES3) return CKR_KEY_TYPE_INCONSISTENT; @@ -2979,6 +3012,7 @@ CK_RV SoftHSM::SymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech mode = SymMode::ECB; bb = 7; break; +#endif case CKM_DES3_CBC: if (keyType != CKK_DES2 && keyType != CKK_DES3) return CKR_KEY_TYPE_INCONSISTENT; @@ -3010,12 +3044,14 @@ CK_RV SoftHSM::SymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen); bb = 7; break; +#ifndef WITH_BOTAN case CKM_AES_ECB: if (keyType != CKK_AES) return CKR_KEY_TYPE_INCONSISTENT; algo = SymAlgo::AES; mode = SymMode::ECB; break; +#endif case CKM_AES_CBC: if (keyType != CKK_AES) return CKR_KEY_TYPE_INCONSISTENT; @@ -7257,12 +7293,18 @@ CK_RV SoftHSM::C_DeriveKey case CKM_ECDH1_DERIVE: #endif #ifndef WITH_FIPS +#ifndef WITH_BOTAN case CKM_DES_ECB_ENCRYPT_DATA: +#endif case CKM_DES_CBC_ENCRYPT_DATA: #endif +#ifndef WITH_BOTAN case CKM_DES3_ECB_ENCRYPT_DATA: +#endif case CKM_DES3_CBC_ENCRYPT_DATA: +#ifndef WITH_BOTAN case CKM_AES_ECB_ENCRYPT_DATA: +#endif case CKM_AES_CBC_ENCRYPT_DATA: case CKM_CONCATENATE_DATA_AND_BASE: case CKM_CONCATENATE_BASE_AND_DATA: @@ -8004,6 +8046,7 @@ CK_RV SoftHSM::generateDES kcv = key->getKeyCheckValue(); } bOK = bOK && osobject->setAttribute(CKA_VALUE, value); + if (checkValue) bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv); @@ -11547,11 +11590,13 @@ CK_RV SoftHSM::deriveSymmetric size_t bb = 8; switch(pMechanism->mechanism) { #ifndef WITH_FIPS +#ifndef WITH_BOTAN case CKM_DES_ECB_ENCRYPT_DATA: algo = SymAlgo::DES; mode = SymMode::ECB; bb = 7; break; +#endif case CKM_DES_CBC_ENCRYPT_DATA: algo = SymAlgo::DES; mode = SymMode::CBC; @@ -11562,11 +11607,13 @@ CK_RV SoftHSM::deriveSymmetric 8); break; #endif +#ifndef WITH_BOTAN case CKM_DES3_ECB_ENCRYPT_DATA: algo = SymAlgo::DES3; mode = SymMode::ECB; bb = 7; break; +#endif case CKM_DES3_CBC_ENCRYPT_DATA: algo = SymAlgo::DES3; mode = SymMode::CBC; @@ -11576,10 +11623,12 @@ CK_RV SoftHSM::deriveSymmetric &(CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR(pMechanism->pParameter)->iv[0]), 8); break; +#ifndef WITH_BOTAN case CKM_AES_ECB_ENCRYPT_DATA: algo = SymAlgo::AES; mode = SymMode::ECB; break; +#endif case CKM_AES_CBC_ENCRYPT_DATA: algo = SymAlgo::AES; mode = SymMode::CBC; diff --git a/src/lib/SoftHSM.h b/src/lib/SoftHSM.h index 4c8f5fe8e..e92a1772c 100644 --- a/src/lib/SoftHSM.h +++ b/src/lib/SoftHSM.h @@ -490,7 +490,7 @@ class SoftHSM CK_RV MechParamCheckRSAPKCSOAEP(CK_MECHANISM_PTR pMechanism); bool isMechanismPermitted(OSObject* key, CK_MECHANISM_PTR pMechanism); - void prepareSupportedMecahnisms(std::map &t); + void prepareSupportedMechanisms(std::map &t); bool detectFork(void); }; diff --git a/src/lib/crypto/AESKey.cpp b/src/lib/crypto/AESKey.cpp index 9b511b555..ff5523797 100644 --- a/src/lib/crypto/AESKey.cpp +++ b/src/lib/crypto/AESKey.cpp @@ -51,7 +51,11 @@ ByteString AESKey::getKeyCheckValue() const data.resize(cipher->getBlockSize()); memset(&data[0], 0, data.size()); - if (!cipher->encryptInit(this, SymMode::ECB, iv, false) || + // Single block of null (0x00) bytes + iv.resize(cipher->getBlockSize()); + memset(&iv[0], 0, iv.size()); + + if (!cipher->encryptInit(this, SymMode::CBC, iv, false) || !cipher->encryptUpdate(data, encryptedData) || !cipher->encryptFinal(encryptedFinal)) { diff --git a/src/lib/crypto/test/AESTests.h b/src/lib/crypto/test/AESTests.h index a0c29dc28..ed928b01b 100644 --- a/src/lib/crypto/test/AESTests.h +++ b/src/lib/crypto/test/AESTests.h @@ -41,7 +41,9 @@ class AESTests : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(AESTests); CPPUNIT_TEST(testBlockSize); CPPUNIT_TEST(testCBC); + #ifndef WITH_BOTAN CPPUNIT_TEST(testECB); + #endif CPPUNIT_TEST(testCTR); CPPUNIT_TEST(testGCM); #ifdef HAVE_AES_KEY_WRAP diff --git a/src/lib/crypto/test/DESTests.h b/src/lib/crypto/test/DESTests.h index 083446287..77fac93aa 100644 --- a/src/lib/crypto/test/DESTests.h +++ b/src/lib/crypto/test/DESTests.h @@ -41,7 +41,9 @@ class DESTests : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(DESTests); CPPUNIT_TEST(testBlockSize); CPPUNIT_TEST(testCBC); + #ifndef WITH_BOTAN CPPUNIT_TEST(testECB); + #endif CPPUNIT_TEST(testOFB); CPPUNIT_TEST(testCFB); CPPUNIT_TEST_SUITE_END(); diff --git a/src/lib/data_mgr/SecureDataManager.cpp b/src/lib/data_mgr/SecureDataManager.cpp index 987e76b09..83545f9a1 100644 --- a/src/lib/data_mgr/SecureDataManager.cpp +++ b/src/lib/data_mgr/SecureDataManager.cpp @@ -51,487 +51,496 @@ // Initialise the object; called by all constructors void SecureDataManager::initObject() { - // Get an RNG instance - rng = CryptoFactory::i()->getRNG(); + // Get an RNG instance + rng = CryptoFactory::i()->getRNG(); - // Get an AES implementation - aes = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::AES); + // Get an AES implementation + aes = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::AES); - // Initialise masking data - mask = new ByteString(); + // Initialise masking data + mask = new ByteString(); - rng->generateRandom(*mask, 32); + rng->generateRandom(*mask, 32); - // Set the initial login state - soLoggedIn = userLoggedIn = false; + // Set the initial login state + soLoggedIn = userLoggedIn = false; - // Set the magic - magic = ByteString("524A52"); // RJR + // Set the magic + magic = ByteString("524A52"); // RJR - // Get a mutex - dataMgrMutex = MutexFactory::i()->getMutex(); + // Get a mutex + dataMgrMutex = MutexFactory::i()->getMutex(); } // Constructs a new SecureDataManager for a blank token; actual // initialisation is done by setting the SO PIN SecureDataManager::SecureDataManager() { - initObject(); + initObject(); } // Constructs a SecureDataManager using the specified key blob SecureDataManager::SecureDataManager(const ByteString& soPINBlob, const ByteString& userPINBlob) { - initObject(); + initObject(); - // De-serialise the key blob - soEncryptedKey = soPINBlob; - userEncryptedKey = userPINBlob; + // De-serialise the key blob + soEncryptedKey = soPINBlob; + userEncryptedKey = userPINBlob; } // Destructor SecureDataManager::~SecureDataManager() { - // Recycle the AES instance - CryptoFactory::i()->recycleSymmetricAlgorithm(aes); + // Recycle the AES instance + CryptoFactory::i()->recycleSymmetricAlgorithm(aes); - // Clean up the mask - delete mask; + // Clean up the mask + delete mask; - MutexFactory::i()->recycleMutex(dataMgrMutex); + MutexFactory::i()->recycleMutex(dataMgrMutex); } // Generic function for creating an encrypted version of the key from the specified passphrase bool SecureDataManager::pbeEncryptKey(const ByteString& passphrase, ByteString& encryptedKey) { - // Generate salt - ByteString salt; + // Generate salt + ByteString salt; - if (!rng->generateRandom(salt, 8)) return false; + if (!rng->generateRandom(salt, 8)) return false; - // Derive the key using RFC4880 PBE - AESKey* pbeKey = NULL; + // Derive the key using RFC4880 PBE + AESKey* pbeKey = NULL; - if (!RFC4880::PBEDeriveKey(passphrase, salt, &pbeKey)) - { - return false; - } + if (!RFC4880::PBEDeriveKey(passphrase, salt, &pbeKey)) + { + return false; + } - // Add the salt - encryptedKey.wipe(); - encryptedKey += salt; + // Add the salt + encryptedKey.wipe(); + encryptedKey += salt; - // Generate random IV - ByteString IV; + // Generate random IV + ByteString IV; - if (!rng->generateRandom(IV, aes->getBlockSize())) return false; + if (!rng->generateRandom(IV, aes->getBlockSize())) return false; - // Add the IV - encryptedKey += IV; + // Add the IV + encryptedKey += IV; - // Encrypt the data - ByteString block; + // Encrypt the data + ByteString block; - if (!aes->encryptInit(pbeKey, SymMode::CBC, IV)) - { - delete pbeKey; + if (!aes->encryptInit(pbeKey, SymMode::CBC, IV)) + { + delete pbeKey; - return false; - } + return false; + } - // First, add the magic - if (!aes->encryptUpdate(magic, block)) - { - delete pbeKey; + // First, add the magic + if (!aes->encryptUpdate(magic, block)) + { + delete pbeKey; - return false; - } + return false; + } - encryptedKey += block; + encryptedKey += block; - // Then, add the key itself - ByteString key; + // Then, add the key itself + ByteString key; - { - MutexLocker lock(dataMgrMutex); + { + MutexLocker lock(dataMgrMutex); - unmask(key); + unmask(key); - bool rv = aes->encryptUpdate(key, block); + bool rv = aes->encryptUpdate(key, block); - remask(key); + remask(key); - if (!rv) - { - delete pbeKey; + if (!rv) + { + delete pbeKey; - return false; - } - } + return false; + } + } - encryptedKey += block; + encryptedKey += block; - // And finalise encryption - if (!aes->encryptFinal(block)) - { - delete pbeKey; + // And finalise encryption + if (!aes->encryptFinal(block)) + { + delete pbeKey; - return false; - } + return false; + } - encryptedKey += block; + encryptedKey += block; - delete pbeKey; + delete pbeKey; - return true; + return true; } // Set the SO PIN (requires either a blank SecureDataManager or the // SO to have logged in previously) bool SecureDataManager::setSOPIN(const ByteString& soPIN) { - // Check the new PIN - if (soPIN.size() == 0) - { - DEBUG_MSG("Zero length PIN specified"); + // Check the new PIN + if (soPIN.size() == 0) + { + DEBUG_MSG("Zero length PIN specified"); - return false; - } + return false; + } - // Check if the SO needs to be logged in - if ((soEncryptedKey.size() > 0) && !soLoggedIn) - { - DEBUG_MSG("SO must be logged in to change the SO PIN"); + // Check if the SO needs to be logged in + if ((soEncryptedKey.size() > 0) && !soLoggedIn) + { + DEBUG_MSG("SO must be logged in to change the SO PIN"); - return false; - } + return false; + } - // If no SO PIN was set, then this is a SecureDataManager for a blank token. This - // means a new key has to be generated - if (soEncryptedKey.size() == 0) - { - ByteString key; + // If no SO PIN was set, then this is a SecureDataManager for a blank token. This + // means a new key has to be generated + if (soEncryptedKey.size() == 0) + { + ByteString key; - rng->generateRandom(key, 32); + rng->generateRandom(key, 32); - remask(key); - } + remask(key); + } - return pbeEncryptKey(soPIN, soEncryptedKey); + return pbeEncryptKey(soPIN, soEncryptedKey); } // Set the user PIN (requires either the SO or the user to have logged // in previously) bool SecureDataManager::setUserPIN(const ByteString& userPIN) { - // Check if the SO or the user is logged in - if (!soLoggedIn && !userLoggedIn) - { - DEBUG_MSG("Must be logged in to change the user PIN"); + // Check if the SO or the user is logged in + if (!soLoggedIn && !userLoggedIn) + { + DEBUG_MSG("Must be logged in to change the user PIN"); - return false; - } + return false; + } - // Check the new PIN - if (userPIN.size() == 0) - { - DEBUG_MSG("Zero length PIN specified"); + // Check the new PIN + if (userPIN.size() == 0) + { + DEBUG_MSG("Zero length PIN specified"); - return false; - } + return false; + } - return pbeEncryptKey(userPIN, userEncryptedKey); + return pbeEncryptKey(userPIN, userEncryptedKey); } // Generic login function bool SecureDataManager::login(const ByteString& passphrase, const ByteString& encryptedKey) { - // Log out first - this->logout(); + // Log out first + this->logout(); - // First, take the salt from the encrypted key - ByteString salt = encryptedKey.substr(0,8); + // First, take the salt from the encrypted key + ByteString salt = encryptedKey.substr(0,8); - // Then, take the IV from the encrypted key - ByteString IV = encryptedKey.substr(8, aes->getBlockSize()); + // Then, take the IV from the encrypted key + ByteString IV = encryptedKey.substr(8, aes->getBlockSize()); - // Now, take the encrypted data from the encrypted key - ByteString encryptedKeyData = encryptedKey.substr(8 + aes->getBlockSize()); + // Now, take the encrypted data from the encrypted key + ByteString encryptedKeyData = encryptedKey.substr(8 + aes->getBlockSize()); - // Derive the PBE key - AESKey* pbeKey = NULL; + // Derive the PBE key + AESKey* pbeKey = NULL; - if (!RFC4880::PBEDeriveKey(passphrase, salt, &pbeKey)) - { - return false; - } + if (!RFC4880::PBEDeriveKey(passphrase, salt, &pbeKey)) + { + return false; + } - // Decrypt the key data - ByteString decryptedKeyData; - ByteString finalBlock; + // Decrypt the key data + ByteString decryptedKeyData; + ByteString finalBlock; - // NOTE: The login will fail here if incorrect passphrase is supplied - if (!aes->decryptInit(pbeKey, SymMode::CBC, IV) || - !aes->decryptUpdate(encryptedKeyData, decryptedKeyData) || - !aes->decryptFinal(finalBlock)) - { - delete pbeKey; + // NOTE: The login will fail here if incorrect passphrase is supplied + if (!aes->decryptInit(pbeKey, SymMode::CBC, IV) || + !aes->decryptUpdate(encryptedKeyData, decryptedKeyData) || + !aes->decryptFinal(finalBlock)) + { + delete pbeKey; - return false; - } + return false; + } - delete pbeKey; + delete pbeKey; - decryptedKeyData += finalBlock; + decryptedKeyData += finalBlock; - // Check the magic - if (decryptedKeyData.substr(0, 3) != magic) - { - // The passphrase was incorrect - DEBUG_MSG("Incorrect passphrase supplied"); + // Check the magic + if (decryptedKeyData.substr(0, 3) != magic) + { + // The passphrase was incorrect + DEBUG_MSG("Incorrect passphrase supplied"); - return false; - } + return false; + } - // Strip off the magic - ByteString key = decryptedKeyData.substr(3); + // Strip off the magic + ByteString key = decryptedKeyData.substr(3); - // And mask the key - decryptedKeyData.wipe(); + // And mask the key + decryptedKeyData.wipe(); - MutexLocker lock(dataMgrMutex); - remask(key); + MutexLocker lock(dataMgrMutex); + remask(key); - return true; + return true; } // Log in using the SO PIN bool SecureDataManager::loginSO(const ByteString& soPIN) { - return (soLoggedIn = login(soPIN, soEncryptedKey)); + return (soLoggedIn = login(soPIN, soEncryptedKey)); } // Log in using the user PIN bool SecureDataManager::loginUser(const ByteString& userPIN) { - return (userLoggedIn = login(userPIN, userEncryptedKey)); + return (userLoggedIn = login(userPIN, userEncryptedKey)); } // Generic re-authentication function bool SecureDataManager::reAuthenticate(const ByteString& passphrase, const ByteString& encryptedKey) { - // First, take the salt from the encrypted key - ByteString salt = encryptedKey.substr(0,8); + // First, take the salt from the encrypted key + ByteString salt = encryptedKey.substr(0,8); - // Then, take the IV from the encrypted key - ByteString IV = encryptedKey.substr(8, aes->getBlockSize()); + // Then, take the IV from the encrypted key + ByteString IV = encryptedKey.substr(8, aes->getBlockSize()); - // Now, take the encrypted data from the encrypted key - ByteString encryptedKeyData = encryptedKey.substr(8 + aes->getBlockSize()); + // Now, take the encrypted data from the encrypted key + ByteString encryptedKeyData = encryptedKey.substr(8 + aes->getBlockSize()); - // Derive the PBE key - AESKey* pbeKey = NULL; + // Derive the PBE key + AESKey* pbeKey = NULL; - if (!RFC4880::PBEDeriveKey(passphrase, salt, &pbeKey)) - { - return false; - } + if (!RFC4880::PBEDeriveKey(passphrase, salt, &pbeKey)) + { + return false; + } - // Decrypt the key data - ByteString decryptedKeyData; - ByteString finalBlock; + // Decrypt the key data + ByteString decryptedKeyData; + ByteString finalBlock; - // NOTE: The login will fail here if incorrect passphrase is supplied - if (!aes->decryptInit(pbeKey, SymMode::CBC, IV) || - !aes->decryptUpdate(encryptedKeyData, decryptedKeyData) || - !aes->decryptFinal(finalBlock)) - { - delete pbeKey; + // NOTE: The login will fail here if incorrect passphrase is supplied + if (!aes->decryptInit(pbeKey, SymMode::CBC, IV) || + !aes->decryptUpdate(encryptedKeyData, decryptedKeyData) || + !aes->decryptFinal(finalBlock)) + { + delete pbeKey; - return false; - } + return false; + } - delete pbeKey; + delete pbeKey; - decryptedKeyData += finalBlock; + decryptedKeyData += finalBlock; - // Check the magic - if (decryptedKeyData.substr(0, 3) != magic) - { - // The passphrase was incorrect - DEBUG_MSG("Incorrect passphrase supplied"); + // Check the magic + if (decryptedKeyData.substr(0, 3) != magic) + { + // The passphrase was incorrect + DEBUG_MSG("Incorrect passphrase supplied"); - return false; - } + return false; + } - // And mask the key - decryptedKeyData.wipe(); + // And mask the key + decryptedKeyData.wipe(); - return true; + return true; } // Re-authenticate the SO bool SecureDataManager::reAuthenticateSO(const ByteString& soPIN) { - return reAuthenticate(soPIN, soEncryptedKey); + return reAuthenticate(soPIN, soEncryptedKey); } // Re-authenticate the user bool SecureDataManager::reAuthenticateUser(const ByteString& userPIN) { - return reAuthenticate(userPIN, userEncryptedKey); + return reAuthenticate(userPIN, userEncryptedKey); } // Log out void SecureDataManager::logout() { - MutexLocker lock(dataMgrMutex); + MutexLocker lock(dataMgrMutex); - // Clear the logged in state - soLoggedIn = userLoggedIn = false; + // Clear the logged in state + soLoggedIn = userLoggedIn = false; - // Clear the masked key - maskedKey.wipe(); + // Clear the masked key + maskedKey.wipe(); } // Decrypt the supplied data bool SecureDataManager::decrypt(const ByteString& encrypted, ByteString& plaintext) { - // Check the object logged in state - if ((!userLoggedIn && !soLoggedIn) || (maskedKey.size() != 32)) - { - return false; - } + DEBUG_MSG("encrypted: %s", encrypted.hex_str().c_str()); + // Check the object logged in state + if ((!userLoggedIn && !soLoggedIn) || (maskedKey.size() != 32)) + { + return false; + } - // Do not attempt decryption of empty byte strings - if (encrypted.size() == 0) - { - plaintext = ByteString(""); - return true; - } + // Do not attempt decryption of empty byte strings + if (encrypted.size() == 0) + { + plaintext = ByteString(""); + return true; + } - AESKey theKey(256); - ByteString unmaskedKey; + AESKey theKey(256); + ByteString unmaskedKey; - { - MutexLocker lock(dataMgrMutex); + { + MutexLocker lock(dataMgrMutex); - unmask(unmaskedKey); + unmask(unmaskedKey); - theKey.setKeyBits(unmaskedKey); + theKey.setKeyBits(unmaskedKey); - remask(unmaskedKey); - } + remask(unmaskedKey); + } - // Take the IV from the input data - ByteString IV = encrypted.substr(0, aes->getBlockSize()); + // Take the IV from the input data + DEBUG_MSG("AES block size: %d", aes->getBlockSize()); + ByteString IV = encrypted.substr(0, aes->getBlockSize()); - if (IV.size() != aes->getBlockSize()) - { - ERROR_MSG("Invalid IV in encrypted data"); + if (IV.size() != aes->getBlockSize()) + { + ERROR_MSG("Invalid IV in encrypted data"); - return false; - } + return false; + } - ByteString finalBlock; + DEBUG_MSG("IV: %s", IV.hex_str().c_str()); - if (!aes->decryptInit(&theKey, SymMode::CBC, IV) || - !aes->decryptUpdate(encrypted.substr(aes->getBlockSize()), plaintext) || - !aes->decryptFinal(finalBlock)) - { - return false; - } + ByteString finalBlock; - plaintext += finalBlock; + if (!aes->decryptInit(&theKey, SymMode::CBC, IV) || + !aes->decryptUpdate(encrypted.substr(aes->getBlockSize()), plaintext) || + !aes->decryptFinal(finalBlock)) + { + return false; + } - return true; + plaintext += finalBlock; + + DEBUG_MSG("plaintext: %s", plaintext.hex_str().c_str()); + + return true; } // Encrypt the supplied data bool SecureDataManager::encrypt(const ByteString& plaintext, ByteString& encrypted) { - // Check the object logged in state - if ((!userLoggedIn && !soLoggedIn) || (maskedKey.size() != 32)) - { - return false; - } + DEBUG_MSG("plaintext: %s", plaintext.hex_str().c_str()); + // Check the object logged in state + if ((!userLoggedIn && !soLoggedIn) || (maskedKey.size() != 32)) + { + return false; + } + + AESKey theKey(256); + ByteString unmaskedKey; - AESKey theKey(256); - ByteString unmaskedKey; + { + MutexLocker lock(dataMgrMutex); - { - MutexLocker lock(dataMgrMutex); + unmask(unmaskedKey); - unmask(unmaskedKey); + theKey.setKeyBits(unmaskedKey); - theKey.setKeyBits(unmaskedKey); + remask(unmaskedKey); + } - remask(unmaskedKey); - } + // Wipe encrypted data block + encrypted.wipe(); - // Wipe encrypted data block - encrypted.wipe(); + // Generate random IV + ByteString IV; - // Generate random IV - ByteString IV; + if (!rng->generateRandom(IV, aes->getBlockSize())) return false; - if (!rng->generateRandom(IV, aes->getBlockSize())) return false; + DEBUG_MSG("IV: %s", IV.hex_str().c_str()); - ByteString finalBlock; + ByteString finalBlock; - if (!aes->encryptInit(&theKey, SymMode::CBC, IV) || - !aes->encryptUpdate(plaintext, encrypted) || - !aes->encryptFinal(finalBlock)) - { - return false; - } + if (!aes->encryptInit(&theKey, SymMode::CBC, IV) || + !aes->encryptUpdate(plaintext, encrypted) || + !aes->encryptFinal(finalBlock)) + { + return false; + } - encrypted += finalBlock; + encrypted += finalBlock; - // Add IV to output data - encrypted = IV + encrypted; + // Add IV to output data + encrypted = IV + encrypted; - return true; + return true; } // Returns the key blob for the SO PIN ByteString SecureDataManager::getSOPINBlob() { - return soEncryptedKey; + return soEncryptedKey; } // Returns the key blob for the user PIN ByteString SecureDataManager::getUserPINBlob() { - return userEncryptedKey; + return userEncryptedKey; } // Unmask the key void SecureDataManager::unmask(ByteString& key) { - key = maskedKey; - key ^= *mask; + key = maskedKey; + key ^= *mask; } // Remask the key void SecureDataManager::remask(ByteString& key) { - // Generate a new mask - rng->generateRandom(*mask, 32); + // Generate a new mask + rng->generateRandom(*mask, 32); - key ^= *mask; - maskedKey = key; + key ^= *mask; + maskedKey = key; } // Check if the SO is logged in bool SecureDataManager::isSOLoggedIn() { - return soLoggedIn; + return soLoggedIn; } // Check if the user is logged in bool SecureDataManager::isUserLoggedIn() { - return userLoggedIn; + return userLoggedIn; } From 409056949bf75a4e5e43247cb8fafac8d6f35350 Mon Sep 17 00:00:00 2001 From: Antoine Lochet Date: Fri, 29 Nov 2024 14:46:19 +0100 Subject: [PATCH 2/2] Fixed more unit tests --- src/lib/crypto/DESKey.cpp | 6 +++- src/lib/test/DeriveTests.cpp | 46 ++++++++++++++---------- src/lib/test/ObjectTests.cpp | 11 +++--- src/lib/test/SymmetricAlgorithmTests.cpp | 14 ++++++++ src/lib/test/TestsNoPINInitBase.h | 31 ++++++++++++++++ 5 files changed, 84 insertions(+), 24 deletions(-) diff --git a/src/lib/crypto/DESKey.cpp b/src/lib/crypto/DESKey.cpp index 1d5f9bc8d..f5209f21c 100644 --- a/src/lib/crypto/DESKey.cpp +++ b/src/lib/crypto/DESKey.cpp @@ -99,7 +99,11 @@ ByteString DESKey::getKeyCheckValue() const data.resize(cipher->getBlockSize()); memset(&data[0], 0, data.size()); - if (!cipher->encryptInit(this, SymMode::ECB, iv, false) || + // Single block of null (0x00) bytes + iv.resize(cipher->getBlockSize()); + memset(&iv[0], 0, iv.size()); + + if (!cipher->encryptInit(this, SymMode::CBC, iv, false) || !cipher->encryptUpdate(data, encryptedData) || !cipher->encryptFinal(encryptedFinal)) { diff --git a/src/lib/test/DeriveTests.cpp b/src/lib/test/DeriveTests.cpp index 9438ac230..ee6443929 100644 --- a/src/lib/test/DeriveTests.cpp +++ b/src/lib/test/DeriveTests.cpp @@ -658,6 +658,7 @@ void DeriveTests::symDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, C CK_KEY_DERIVATION_STRING_DATA param1; CK_DES_CBC_ENCRYPT_DATA_PARAMS param2; CK_AES_CBC_ENCRYPT_DATA_PARAMS param3; + int memcmpResult; CK_BYTE data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, @@ -703,13 +704,31 @@ void DeriveTests::symDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, C break; case CKK_DES: mechEncrypt.mechanism = CKM_DES_ECB; + #ifdef WITH_BOTAN + if (mechType == CKM_DES_CBC_ENCRYPT_DATA || mechType == CKM_DES3_CBC_ENCRYPT_DATA) { + CK_BYTE iv[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + mechEncrypt = { CKM_DES_CBC, iv, sizeof(iv) }; + } + #endif break; case CKK_DES2: case CKK_DES3: mechEncrypt.mechanism = CKM_DES3_ECB; + #ifdef WITH_BOTAN + if (mechType == CKM_DES_CBC_ENCRYPT_DATA || mechType == CKM_DES3_CBC_ENCRYPT_DATA) { + CK_BYTE iv[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + mechEncrypt = { CKM_DES3_CBC, iv, sizeof(iv) }; + } + #endif break; case CKK_AES: mechEncrypt.mechanism = CKM_AES_ECB; + #ifdef WITH_BOTAN + if (mechType == CKM_AES_CBC_ENCRYPT_DATA) { + CK_BYTE iv[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 }; + mechEncrypt = { CKM_AES_CBC, iv, sizeof(iv) }; + } + #endif secLen = 32; break; default: @@ -764,7 +783,7 @@ void DeriveTests::symDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, C CK_ULONG ulRecoveredTextLen; rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechEncrypt,hDerive) ); - CPPUNIT_ASSERT(rv==CKR_OK); + CPPUNIT_ASSERT_STREAM("Could not C_EncryptInit with mechType=" << int_to_hex(mechType) << ", mechEncrypt.mechanism=" << int_to_hex(mechEncrypt.mechanism) << " keyType=" << int_to_hex(keyType) << ".rv=" << int_to_hex(rv), rv==CKR_OK); ulCipherTextLen = sizeof(cipherText); rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,data,sizeof(data),cipherText,&ulCipherTextLen) ); @@ -778,7 +797,10 @@ void DeriveTests::symDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, C CPPUNIT_ASSERT(rv==CKR_OK); CPPUNIT_ASSERT(ulRecoveredTextLen==sizeof(data)); - CPPUNIT_ASSERT(memcmp(data, recoveredText, sizeof(data)) == 0); + memcmpResult = memcmp(data, recoveredText, sizeof(data)); + CPPUNIT_ASSERT_STREAM("memcmp != 0 with mechType=" << int_to_hex(mechType) << ", mechEncrypt.mechanism=" << int_to_hex(mechEncrypt.mechanism) << ", keyType=" << int_to_hex(keyType) << ", memcmpResult=" << int_to_hex(memcmpResult) + << ", ulCipherTextLen=" << ulCipherTextLen << ", cipherText=" << hexStr(cipherText, ulCipherTextLen) + << ", data=" << hexStr(data, sizeof(data)) << ", recoveredText=" << hexStr(recoveredText, ulRecoveredTextLen), memcmpResult==0); } void DeriveTests::testSymDerive() @@ -830,12 +852,12 @@ void DeriveTests::testSymDerive() // Derive keys CK_OBJECT_HANDLE hDerive = CK_INVALID_HANDLE; +#ifndef WITH_BOTAN #ifndef WITH_FIPS symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_ECB_ENCRYPT_DATA,CKK_GENERIC_SECRET); symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_ECB_ENCRYPT_DATA,CKK_DES); symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_ECB_ENCRYPT_DATA,CKK_DES2); symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_ECB_ENCRYPT_DATA,CKK_DES3); - symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_ECB_ENCRYPT_DATA,CKK_AES); #endif symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_GENERIC_SECRET); #ifndef WITH_FIPS @@ -843,27 +865,21 @@ void DeriveTests::testSymDerive() #endif symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES2); symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES3); - symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_AES); symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_GENERIC_SECRET); #ifndef WITH_FIPS symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES); #endif symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES2); symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES3); - symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_AES); symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_GENERIC_SECRET); -#ifndef WITH_FIPS - symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_DES); -#endif - symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_DES2); - symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_DES3); + symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_AES); +#endif #ifndef WITH_FIPS symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_CBC_ENCRYPT_DATA,CKK_GENERIC_SECRET); symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_CBC_ENCRYPT_DATA,CKK_DES); symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_CBC_ENCRYPT_DATA,CKK_DES2); symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_CBC_ENCRYPT_DATA,CKK_DES3); - symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_CBC_ENCRYPT_DATA,CKK_AES); #endif symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_GENERIC_SECRET); #ifndef WITH_FIPS @@ -871,20 +887,14 @@ void DeriveTests::testSymDerive() #endif symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES2); symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES3); - symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_AES); symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_GENERIC_SECRET); #ifndef WITH_FIPS symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES); #endif symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES2); symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES3); - symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_AES); symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_GENERIC_SECRET); -#ifndef WITH_FIPS - symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_DES); -#endif - symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_DES2); - symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_DES3); + symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_AES); } diff --git a/src/lib/test/ObjectTests.cpp b/src/lib/test/ObjectTests.cpp index d851d1ee0..a082ee3f9 100644 --- a/src/lib/test/ObjectTests.cpp +++ b/src/lib/test/ObjectTests.cpp @@ -918,7 +918,7 @@ void ObjectTests::testCreateObject() rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PUBLIC, hObject); CPPUNIT_ASSERT(rv == CKR_OK); rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) ); - CPPUNIT_ASSERT(rv == CKR_OK); + CPPUNIT_ASSERT_STREAM("rv=" << int_to_hex(rv), rv == CKR_OK); // Only public objects can be created unless the normal user is logged in. rv = createDataObjectMinimal(hSession, ON_TOKEN, IS_PRIVATE, hObject); @@ -1162,11 +1162,11 @@ void ObjectTests::testDestroyObject() // On a read-only session we should not be able to destroy the public token object rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRO,hObjectTokenPublic) ); - CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY); + CPPUNIT_ASSERT_STREAM("rv=" << int_to_hex(rv), rv == CKR_SESSION_READ_ONLY); // On a read-only session we should not be able to destroy the private token object rv = CRYPTOKI_F_PTR( C_DestroyObject(hSessionRO,hObjectTokenPrivate) ); - CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY); + CPPUNIT_ASSERT_STREAM("rv=" << int_to_hex(rv), rv == CKR_SESSION_READ_ONLY); // Logout with a different session than the one used for login should be fine. rv = CRYPTOKI_F_PTR( C_Logout(hSessionRW) ); @@ -1390,7 +1390,7 @@ void ObjectTests::testSetAttributeValue() rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRO,hObjectSessionPrivate,&attribs[0],1) ); CPPUNIT_ASSERT(rv == CKR_OK); rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRO,hObjectTokenPublic,&attribs[0],1) ); - CPPUNIT_ASSERT(rv == CKR_SESSION_READ_ONLY); + CPPUNIT_ASSERT_STREAM("rv=" << int_to_hex(rv), rv == CKR_SESSION_READ_ONLY); rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRW,hObjectTokenPublic,&attribs[0],1) ); CPPUNIT_ASSERT(rv == CKR_OK); rv = CRYPTOKI_F_PTR( C_SetAttributeValue (hSessionRO,hObjectTokenPrivate,&attribs[0],1) ); @@ -1453,7 +1453,7 @@ void ObjectTests::testFindObjects() // Login USER into the sessions so we can create a private objects rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) ); - CPPUNIT_ASSERT(rv==CKR_OK); + CPPUNIT_ASSERT_STREAM("rv=" << int_to_hex(rv), rv == CKR_OK); // Create all permutations of session/token, public/private objects rv = createDataObjectMinimal(hSessionRO, IN_SESSION, IS_PUBLIC, hObjectSessionPublic); @@ -2417,6 +2417,7 @@ void ObjectTests::testCreateSecretKey() CPPUNIT_ASSERT(rv == CKR_OK); rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hObject, attribKCV, 1) ); CPPUNIT_ASSERT(rv == CKR_OK); + CPPUNIT_ASSERT_STREAM("attribKCV[0].ulValueLen=" << attribKCV[0].ulValueLen, attribKCV[0].ulValueLen == 3); CPPUNIT_ASSERT(attribKCV[0].ulValueLen == 3); CPPUNIT_ASSERT(memcmp(pCheckValue, desKCV, 3) == 0); rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession,hObject) ); diff --git a/src/lib/test/SymmetricAlgorithmTests.cpp b/src/lib/test/SymmetricAlgorithmTests.cpp index c7b9e2084..fde02c820 100644 --- a/src/lib/test/SymmetricAlgorithmTests.cpp +++ b/src/lib/test/SymmetricAlgorithmTests.cpp @@ -1426,10 +1426,16 @@ void SymmetricAlgorithmTests::aesWrapUnwrapED(CK_MECHANISM_TYPE mechanismType, C CK_BBOOL bFalse = CK_FALSE; CK_BBOOL bTrue = CK_TRUE; + #ifdef WITH_BOTAN + std::map curves { + { "ED25519", {0x06, 0x03, 0x2b, 0x65, 0x70} } + }; + #else std::map curves { { "ED25519", {0x06, 0x03, 0x2b, 0x65, 0x70} }, { "ED448", {0x06, 0x03, 0x2b, 0x65, 0x71} } }; + #endif for(auto &curve : curves) { const auto curvename = "Curve name: " + curve.first; @@ -1599,8 +1605,10 @@ void SymmetricAlgorithmTests::testAesEncryptDecrypt() encryptDecrypt({CKM_AES_CBC_PAD,NULL_PTR,0},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_AES_CBC,NULL_PTR,0},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_AES_CBC,NULL_PTR,0},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false); + #ifndef WITH_BOTAN encryptDecrypt({CKM_AES_ECB,NULL_PTR,0},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_AES_ECB,NULL_PTR,0},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false); + #endif encryptDecrypt({CKM_AES_CTR,&ctrParams,sizeof(ctrParams)},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1); encryptDecrypt({CKM_AES_CTR,&ctrParams,sizeof(ctrParams)},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1); encryptDecrypt({CKM_AES_CTR,&ctrParams,sizeof(ctrParams)},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST); @@ -1714,8 +1722,10 @@ void SymmetricAlgorithmTests::testDesEncryptDecrypt() encryptDecrypt({CKM_DES_CBC_PAD,NULL_PTR,0},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_DES_CBC,NULL_PTR,0},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_DES_CBC,NULL_PTR,0},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false); + #ifndef WITH_BOTAN encryptDecrypt({CKM_DES_ECB,NULL_PTR,0},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_DES_ECB,NULL_PTR,0},blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false); + #endif CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE; @@ -1728,8 +1738,10 @@ void SymmetricAlgorithmTests::testDesEncryptDecrypt() encryptDecrypt({CKM_DES3_CBC_PAD,NULL_PTR,0},blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_DES3_CBC,NULL_PTR,0},blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_DES3_CBC,NULL_PTR,0},blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST+1, false); + #ifndef WITH_BOTAN encryptDecrypt({CKM_DES3_ECB,NULL_PTR,0},blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_DES3_ECB,NULL_PTR,0},blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST+1, false); + #endif #endif CK_OBJECT_HANDLE hKey3 = CK_INVALID_HANDLE; @@ -1743,8 +1755,10 @@ void SymmetricAlgorithmTests::testDesEncryptDecrypt() encryptDecrypt({CKM_DES3_CBC_PAD,NULL_PTR,0},blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_DES3_CBC,NULL_PTR,0},blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_DES3_CBC,NULL_PTR,0},blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST+1, false); + #ifndef WITH_BOTAN encryptDecrypt({CKM_DES3_ECB,NULL_PTR,0},blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST); encryptDecrypt({CKM_DES3_ECB,NULL_PTR,0},blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST+1, false); + #endif } void SymmetricAlgorithmTests::testDesWrapUnwrap() diff --git a/src/lib/test/TestsNoPINInitBase.h b/src/lib/test/TestsNoPINInitBase.h index d2cc7fc8f..ff43992b7 100644 --- a/src/lib/test/TestsNoPINInitBase.h +++ b/src/lib/test/TestsNoPINInitBase.h @@ -34,6 +34,7 @@ #define SRC_LIB_TEST_TESTSNOPININITBASE_H_ #include "cryptoki.h" +#include "iomanip" #include @@ -43,6 +44,36 @@ #define CRYPTOKI_F_PTR(func) func #endif +#define CPPUNIT_ASSERT_STREAM(MSG, CONDITION) \ + do { \ + std::ostringstream oss; \ + CPPUNIT_ASSERT_MESSAGE(\ + static_cast(oss << MSG).str(), \ + CONDITION); \ + } while (0) + +template< typename T > +std::string int_to_hex( T i ) +{ + std::stringstream stream; + stream << "0x" + << std::setfill ('0') << std::setw(sizeof(T)) + << std::hex << i; + return stream.str(); +} + +template< typename T > +std::string hexStr(const T *data, int len) +{ + std::stringstream ss; + ss << std::hex; + + for( int i(0) ; i < len; ++i ) + ss << std::setfill ('0') << std::setw(sizeof(T) * 2) << static_cast(static_cast(data[i])); + + return ss.str(); +} + class TestsNoPINInitBase : public CppUnit::TestFixture { public: TestsNoPINInitBase();