summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2018-07-04 16:25:37 +0200
committerTomaž Vajngerl <quikee@gmail.com>2018-07-06 18:26:08 +0200
commit6db3aeb6e698b07d2fb4985a0c529358b7323f55 (patch)
tree62a041fa75841567662b6df79d3b57e62a06275c
parent0d0bf4132d7cf81306a3de6592fce40ab69ef040 (diff)
CryptoTools: add HMAC, move crypto impl. details to CryptoImpl
Change-Id: I8edb24ee5d9595ef54bd49526b631baf8a7415b1 Reviewed-on: https://gerrit.libreoffice.org/56970 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r--include/oox/crypto/CryptTools.hxx90
-rw-r--r--oox/CppunitTest_oox_crypto.mk15
-rw-r--r--oox/qa/unit/CryptoTest.cxx65
-rw-r--r--oox/source/crypto/CryptTools.cxx402
4 files changed, 413 insertions, 159 deletions
diff --git a/include/oox/crypto/CryptTools.hxx b/include/oox/crypto/CryptTools.hxx
index d5bc5b95bda3..90c60b2a6313 100644
--- a/include/oox/crypto/CryptTools.hxx
+++ b/include/oox/crypto/CryptTools.hxx
@@ -21,26 +21,41 @@
#define INCLUDED_OOX_CRYPTO_CRYPTTOOLS_HXX
#include <config_oox.h>
-
-#if USE_TLS_OPENSSL
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-#endif // USE_TLS_OPENSSL
-
-#if USE_TLS_NSS
-#include <nss.h>
-#include <pk11pub.h>
-#include <sechash.h>
-#endif // USE_TLS_NSS
+#include <oox/dllapi.h>
+#include <sal/types.h>
#include <vector>
-
-#include <sal/types.h>
+#include <memory>
namespace oox {
namespace core {
-class Crypto
+/** Rounds up the input to the nearest multiple
+ *
+ * For example:
+ * input 1, multiple 16 = 16
+ * input 16, multiple 16 = 16
+ * input 17, multiple 16 = 32
+ * input 31, multiple 16 = 32
+ */
+template<typename T>
+T roundUp(T input, T multiple)
+{
+ if (input % multiple == 0)
+ return input;
+ return ((input / multiple) * multiple) + multiple;
+}
+
+enum class CryptoHashType
+{
+ SHA1,
+ SHA256,
+ SHA512
+};
+
+struct CryptoImpl;
+
+class OOX_DLLPUBLIC Crypto
{
public:
enum CryptoType
@@ -52,47 +67,24 @@ public:
};
protected:
-#if USE_TLS_OPENSSL
- EVP_CIPHER_CTX mContext;
-#endif
-#if USE_TLS_NSS
- PK11Context* mContext;
- SECItem* mSecParam;
- PK11SymKey* mSymKey;
-#endif
-
-#if USE_TLS_OPENSSL
- const EVP_CIPHER* getCipher(CryptoType type);
-#endif
-#if USE_TLS_NSS
- void setupContext(
- std::vector<sal_uInt8>& key,
- std::vector<sal_uInt8>& iv,
- CryptoType type,
- CK_ATTRIBUTE_TYPE operation);
-#endif
+ std::unique_ptr<CryptoImpl> mpImpl;
protected:
Crypto();
public:
virtual ~Crypto();
-
- virtual sal_uInt32 update(
- std::vector<sal_uInt8>& output,
- std::vector<sal_uInt8>& input,
- sal_uInt32 inputLength = 0) = 0;
};
-class Decrypt : public Crypto
+class OOX_DLLPUBLIC Decrypt : public Crypto
{
public:
Decrypt(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, CryptoType type);
- virtual sal_uInt32 update(
+ sal_uInt32 update(
std::vector<sal_uInt8>& output,
std::vector<sal_uInt8>& input,
- sal_uInt32 inputLength = 0) override;
+ sal_uInt32 inputLength = 0);
static sal_uInt32 aes128ecb(
@@ -102,17 +94,27 @@ public:
};
-class Encrypt : public Crypto
+class OOX_DLLPUBLIC Encrypt : public Crypto
{
public:
Encrypt(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, CryptoType type);
- virtual sal_uInt32 update(
+ sal_uInt32 update(
std::vector<sal_uInt8>& output,
std::vector<sal_uInt8>& input,
- sal_uInt32 inputLength = 0) override;
+ sal_uInt32 inputLength = 0);
+};
+
+class OOX_DLLPUBLIC CryptoHash : public Crypto
+{
+ sal_Int32 mnHashSize;
+public:
+ CryptoHash(std::vector<sal_uInt8>& rKey, CryptoHashType eType);
+ bool update(std::vector<sal_uInt8>& rInput, sal_uInt32 nInputLength = 0);
+ std::vector<sal_uInt8> finalize();
};
+
} // namespace core
} // namespace oox
diff --git a/oox/CppunitTest_oox_crypto.mk b/oox/CppunitTest_oox_crypto.mk
index 64fd4df490b5..f4a641283152 100644
--- a/oox/CppunitTest_oox_crypto.mk
+++ b/oox/CppunitTest_oox_crypto.mk
@@ -16,6 +16,20 @@ $(eval $(call gb_CppunitTest_add_exception_objects,oox_crypto,\
$(eval $(call gb_CppunitTest_use_sdk_api,oox_crypto))
+ifeq ($(TLS),OPENSSL)
+$(eval $(call gb_CppunitTest_externals,oox_crypto,\
+ openssl \
+ openssl_headers \
+))
+else
+ifeq ($(TLS),NSS)
+$(eval $(call gb_CppunitTest_use_externals,oox_crypto,\
+ plc4 \
+ nss3 \
+))
+endif
+endif
+
$(eval $(call gb_CppunitTest_use_libraries,oox_crypto,\
basegfx \
comphelper \
@@ -68,6 +82,7 @@ $(eval $(call gb_CppunitTest_use_components,oox_crypto,\
unotools/util/utl \
uui/util/uui \
vcl/vcl.common \
+ sax/source/expatwrap/expwrap \
))
diff --git a/oox/qa/unit/CryptoTest.cxx b/oox/qa/unit/CryptoTest.cxx
index efe3e0cb5d6e..c35fa2f7d9a0 100644
--- a/oox/qa/unit/CryptoTest.cxx
+++ b/oox/qa/unit/CryptoTest.cxx
@@ -15,6 +15,7 @@
#include <tools/stream.hxx>
#include <unotools/streamwrap.hxx>
+#include <oox/crypto/CryptTools.hxx>
#include <oox/crypto/Standard2007Engine.hxx>
#include <oox/helper/binaryinputstream.hxx>
#include <oox/helper/binaryoutputstream.hxx>
@@ -24,13 +25,77 @@ using namespace css;
class CryptoTest : public CppUnit::TestFixture
{
public:
+ void testCryptoHash();
+ void testRoundUp();
void testStandard2007();
CPPUNIT_TEST_SUITE(CryptoTest);
+ CPPUNIT_TEST(testCryptoHash);
+ CPPUNIT_TEST(testRoundUp);
CPPUNIT_TEST(testStandard2007);
CPPUNIT_TEST_SUITE_END();
};
+namespace
+{
+std::string toString(std::vector<sal_uInt8> const& aInput)
+{
+ std::stringstream aStream;
+ for (auto const& aValue : aInput)
+ {
+ aStream << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(aValue);
+ }
+
+ return aStream.str();
+}
+}
+
+void CryptoTest::testCryptoHash()
+{
+ // Check examples from Wikipedia (https://en.wikipedia.org/wiki/HMAC)
+ OString aContentString("The quick brown fox jumps over the lazy dog");
+ std::vector<sal_uInt8> aContent(aContentString.getStr(),
+ aContentString.getStr() + aContentString.getLength());
+ std::vector<sal_uInt8> aKey = { 'k', 'e', 'y' };
+ {
+ oox::core::CryptoHash aCryptoHash(aKey, oox::core::CryptoHashType::SHA1);
+ aCryptoHash.update(aContent);
+ std::vector<sal_uInt8> aHash = aCryptoHash.finalize();
+ CPPUNIT_ASSERT_EQUAL(std::string("de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"),
+ toString(aHash));
+ }
+
+ {
+ oox::core::CryptoHash aCryptoHash(aKey, oox::core::CryptoHashType::SHA256);
+ aCryptoHash.update(aContent);
+ std::vector<sal_uInt8> aHash = aCryptoHash.finalize();
+ CPPUNIT_ASSERT_EQUAL(
+ std::string("f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8"),
+ toString(aHash));
+ }
+
+ {
+ oox::core::CryptoHash aCryptoHash(aKey, oox::core::CryptoHashType::SHA512);
+ aCryptoHash.update(aContent);
+ std::vector<sal_uInt8> aHash = aCryptoHash.finalize();
+ CPPUNIT_ASSERT_EQUAL(
+ std::string("b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549"
+ "f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a"),
+ toString(aHash));
+ }
+}
+
+void CryptoTest::testRoundUp()
+{
+ CPPUNIT_ASSERT_EQUAL(16, oox::core::roundUp(16, 16));
+ CPPUNIT_ASSERT_EQUAL(32, oox::core::roundUp(32, 16));
+ CPPUNIT_ASSERT_EQUAL(64, oox::core::roundUp(64, 16));
+
+ CPPUNIT_ASSERT_EQUAL(16, oox::core::roundUp(01, 16));
+ CPPUNIT_ASSERT_EQUAL(32, oox::core::roundUp(17, 16));
+ CPPUNIT_ASSERT_EQUAL(32, oox::core::roundUp(31, 16));
+}
+
void CryptoTest::testStandard2007()
{
oox::core::Standard2007Engine aEngine;
diff --git a/oox/source/crypto/CryptTools.cxx b/oox/source/crypto/CryptTools.cxx
index e0b39f67cca4..1f280b1c1196 100644
--- a/oox/source/crypto/CryptTools.cxx
+++ b/oox/source/crypto/CryptTools.cxx
@@ -12,105 +12,243 @@
#include <filter/msfilter/mscodec.hxx>
#include <com/sun/star/uno/RuntimeException.hpp>
-namespace oox {
-namespace core {
+#include <o3tl/make_unique.hxx>
+
+#if USE_TLS_OPENSSL
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+#include <openssl/hmac.h>
+#endif // USE_TLS_OPENSSL
-Crypto::Crypto()
-#if USE_TLS_NSS
- : mContext(nullptr)
- , mSecParam(nullptr)
- , mSymKey(nullptr)
-#endif
-{
#if USE_TLS_NSS
- // Initialize NSS, database functions are not needed
- NSS_NoDB_Init(nullptr);
+#include <nss.h>
+#include <pk11pub.h>
+#include <sechash.h>
#endif // USE_TLS_NSS
-}
-Crypto::~Crypto()
-{
-#if USE_TLS_OPENSSL
- EVP_CIPHER_CTX_cleanup( &mContext );
-#endif
-#if USE_TLS_NSS
- if (mContext)
- PK11_DestroyContext(mContext, PR_TRUE);
- if (mSymKey)
- PK11_FreeSymKey(mSymKey);
- if (mSecParam)
- SECITEM_FreeItem(mSecParam, PR_TRUE);
-#endif
-}
+namespace oox {
+namespace core {
#if USE_TLS_OPENSSL
-const EVP_CIPHER* Crypto::getCipher(CryptoType type)
+struct CryptoImpl
{
- switch(type)
+ std::unique_ptr<EVP_CIPHER_CTX> mpContext;
+ std::unique_ptr<HMAC_CTX> mpHmacContext;
+
+ CryptoImpl() = default;
+
+ void setupEncryptContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, Crypto::CryptoType eType)
{
- case AES_128_ECB:
- return EVP_aes_128_ecb();
- case AES_128_CBC:
- return EVP_aes_128_cbc();
- case AES_256_CBC:
- return EVP_aes_256_cbc();
- default:
- break;
+ mpContext.reset(new EVP_CIPHER_CTX);
+ EVP_CIPHER_CTX_init(mpContext.get());
+
+ const EVP_CIPHER* cipher = getCipher(eType);
+ if (cipher == nullptr)
+ return;
+
+ if (iv.empty())
+ EVP_EncryptInit_ex(mpContext.get(), cipher, nullptr, key.data(), 0);
+ else
+ EVP_EncryptInit_ex(mpContext.get(), cipher, nullptr, key.data(), iv.data());
+ EVP_CIPHER_CTX_set_padding(mpContext.get(), 0);
}
- return NULL;
-}
-#endif
-#if USE_TLS_NSS
-void Crypto::setupContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, CryptoType type, CK_ATTRIBUTE_TYPE operation)
-{
- CK_MECHANISM_TYPE mechanism = static_cast<CK_ULONG>(-1);
+ void setupDecryptContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, Crypto::CryptoType eType)
+ {
+ mpContext.reset(new EVP_CIPHER_CTX);
+ EVP_CIPHER_CTX_init(mpContext.get());
+
+ const EVP_CIPHER* pCipher = getCipher(eType);
+ if (pCipher == nullptr)
+ return;
+
+ const size_t nMinKeySize = EVP_CIPHER_key_length(pCipher);
+ if (key.size() < nMinKeySize)
+ key.resize(nMinKeySize, 0);
+
+ if (iv.empty())
+ EVP_DecryptInit_ex(mpContext.get(), pCipher, nullptr, key.data(), 0);
+ else
+ {
+ const size_t nMinIVSize = EVP_CIPHER_iv_length(pCipher);
+ if (iv.size() < nMinIVSize)
+ iv.resize(nMinIVSize, 0);
+
+ EVP_DecryptInit_ex(mpContext.get(), pCipher, nullptr, key.data(), iv.data());
+ }
+ EVP_CIPHER_CTX_set_padding(mpContext.get(), 0);
+ }
- SECItem ivItem;
- ivItem.type = siBuffer;
- if(iv.empty())
- ivItem.data = nullptr;
- else
- ivItem.data = iv.data();
- ivItem.len = iv.size();
+ void setupCryptoHashContext(std::vector<sal_uInt8>& rKey, CryptoHashType eType)
+ {
+ mpHmacContext.reset(new HMAC_CTX);
+ HMAC_CTX_init(mpHmacContext.get());
+ const EVP_MD* aEvpMd;
+ switch (eType)
+ {
+ case CryptoHashType::SHA1:
+ aEvpMd = EVP_sha1(); break;
+ case CryptoHashType::SHA256:
+ aEvpMd = EVP_sha256(); break;
+ case CryptoHashType::SHA512:
+ aEvpMd = EVP_sha512(); break;
+ }
+ HMAC_Init(mpHmacContext.get(), rKey.data(), rKey.size(), aEvpMd);
+ }
- SECItem* pIvItem = nullptr;
+ ~CryptoImpl()
+ {
+ if (mpContext)
+ EVP_CIPHER_CTX_cleanup(mpContext.get());
+ if (mpHmacContext)
+ HMAC_CTX_cleanup(mpHmacContext.get());
+ }
- switch(type)
+ const EVP_CIPHER* getCipher(Crypto::CryptoType type)
{
- case AES_128_ECB:
- mechanism = CKM_AES_ECB;
- break;
- case AES_128_CBC:
- mechanism = CKM_AES_CBC;
- pIvItem = &ivItem;
- break;
- case AES_256_CBC:
- mechanism = CKM_AES_CBC;
- pIvItem = &ivItem;
- break;
- default:
- break;
+ switch(type)
+ {
+ case Crypto::CryptoType::AES_128_ECB:
+ return EVP_aes_128_ecb();
+ case Crypto::CryptoType::AES_128_CBC:
+ return EVP_aes_128_cbc();
+ case Crypto::CryptoType::AES_256_CBC:
+ return EVP_aes_256_cbc();
+ default:
+ break;
+ }
+ return nullptr;
}
+};
- PK11SlotInfo* pSlot(PK11_GetBestSlot(mechanism, nullptr));
+#elif USE_TLS_NSS
- if (!pSlot)
- throw css::uno::RuntimeException("NSS Slot failure", css::uno::Reference<css::uno::XInterface>());
+struct CryptoImpl
+{
+ PK11Context* mContext;
+ SECItem* mSecParam;
+ PK11SymKey* mSymKey;
+ PK11SlotInfo* mpSlot;
+
+ CryptoImpl()
+ : mContext(nullptr)
+ , mSecParam(nullptr)
+ , mSymKey(nullptr)
+ {
+ // Initialize NSS, database functions are not needed
+ NSS_NoDB_Init(nullptr);
+ }
- SECItem keyItem;
- keyItem.type = siBuffer;
- keyItem.data = key.data();
- keyItem.len = key.size();
+ ~CryptoImpl()
+ {
+ if (mContext)
+ PK11_DestroyContext(mContext, PR_TRUE);
+ if (mSymKey)
+ PK11_FreeSymKey(mSymKey);
+ if (mSecParam)
+ SECITEM_FreeItem(mSecParam, PR_TRUE);
+ if (mpSlot)
+ PK11_FreeSlot(mpSlot);
+ }
- mSymKey = PK11_ImportSymKey(pSlot, mechanism, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr);
- if (!mSymKey)
- throw css::uno::RuntimeException("NSS SymKey failure", css::uno::Reference<css::uno::XInterface>());
+ void setupCryptoContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, Crypto::CryptoType type, CK_ATTRIBUTE_TYPE operation)
+ {
+ CK_MECHANISM_TYPE mechanism = static_cast<CK_ULONG>(-1);
+
+ SECItem ivItem;
+ ivItem.type = siBuffer;
+ if(iv.empty())
+ ivItem.data = nullptr;
+ else
+ ivItem.data = iv.data();
+ ivItem.len = iv.size();
+
+ SECItem* pIvItem = nullptr;
+
+ switch(type)
+ {
+ case Crypto::CryptoType::AES_128_ECB:
+ mechanism = CKM_AES_ECB;
+ break;
+ case Crypto::CryptoType::AES_128_CBC:
+ mechanism = CKM_AES_CBC;
+ pIvItem = &ivItem;
+ break;
+ case Crypto::CryptoType::AES_256_CBC:
+ mechanism = CKM_AES_CBC;
+ pIvItem = &ivItem;
+ break;
+ default:
+ break;
+ }
+
+ mpSlot = PK11_GetBestSlot(mechanism, nullptr);
+
+ if (!mpSlot)
+ throw css::uno::RuntimeException("NSS Slot failure", css::uno::Reference<css::uno::XInterface>());
+
+ SECItem keyItem;
+ keyItem.type = siBuffer;
+ keyItem.data = key.data();
+ keyItem.len = key.size();
+
+ mSymKey = PK11_ImportSymKey(mpSlot, mechanism, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr);
+ if (!mSymKey)
+ throw css::uno::RuntimeException("NSS SymKey failure", css::uno::Reference<css::uno::XInterface>());
+
+ mSecParam = PK11_ParamFromIV(mechanism, pIvItem);
+ mContext = PK11_CreateContextBySymKey(mechanism, operation, mSymKey, mSecParam);
+ }
- mSecParam = PK11_ParamFromIV(mechanism, pIvItem);
- mContext = PK11_CreateContextBySymKey(mechanism, operation, mSymKey, mSecParam);
+ void setupCryptoHashContext(std::vector<sal_uInt8>& rKey, CryptoHashType eType)
+ {
+ CK_MECHANISM_TYPE aMechanism = static_cast<CK_ULONG>(-1);
+
+ switch(eType)
+ {
+ case CryptoHashType::SHA1:
+ aMechanism = CKM_SHA_1_HMAC;
+ break;
+ case CryptoHashType::SHA256:
+ aMechanism = CKM_SHA256_HMAC;
+ break;
+ case CryptoHashType::SHA512:
+ aMechanism = CKM_SHA512_HMAC;
+ break;
+ }
+
+ mpSlot = PK11_GetBestSlot(aMechanism, nullptr);
+
+ if (!mpSlot)
+ throw css::uno::RuntimeException("NSS Slot failure", css::uno::Reference<css::uno::XInterface>());
+
+ SECItem aKeyItem;
+ aKeyItem.data = rKey.data();
+ aKeyItem.len = rKey.size();
+
+ mSymKey = PK11_ImportSymKey(mpSlot, aMechanism, PK11_OriginUnwrap, CKA_SIGN, &aKeyItem, nullptr);
+ if (!mSymKey)
+ throw css::uno::RuntimeException("NSS SymKey failure", css::uno::Reference<css::uno::XInterface>());
+
+ SECItem param;
+ param.data = nullptr;
+ param.len = 0;
+ mContext = PK11_CreateContextBySymKey(aMechanism, CKA_SIGN, mSymKey, &param);
+ }
+};
+#else
+struct CryptoImpl
+{};
+#endif
+
+Crypto::Crypto()
+ : mpImpl(o3tl::make_unique<CryptoImpl>())
+{
+}
+
+Crypto::~Crypto()
+{
}
-#endif // USE_TLS_NSS
// DECRYPT
@@ -124,29 +262,11 @@ Decrypt::Decrypt(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, Crypto
#endif
#if USE_TLS_OPENSSL
- EVP_CIPHER_CTX_init(&mContext);
-
- const EVP_CIPHER* cipher = getCipher(type);
-
- const size_t nMinKeySize = EVP_CIPHER_key_length(cipher);
- if (key.size() < nMinKeySize)
- key.resize(nMinKeySize, 0);
-
- if (iv.empty())
- EVP_DecryptInit_ex(&mContext, cipher, nullptr, key.data(), 0);
- else
- {
- const size_t nMinIVSize = EVP_CIPHER_iv_length(cipher);
- if (iv.size() < nMinIVSize)
- iv.resize(nMinIVSize, 0);
-
- EVP_DecryptInit_ex(&mContext, cipher, nullptr, key.data(), iv.data());
- }
- EVP_CIPHER_CTX_set_padding(&mContext, 0);
+ mpImpl->setupDecryptContext(key, iv, type);
#endif
#if USE_TLS_NSS
- setupContext(key, iv, type, CKA_DECRYPT);
+ mpImpl->setupCryptoContext(key, iv, type, CKA_DECRYPT);
#endif // USE_TLS_NSS
}
@@ -163,11 +283,11 @@ sal_uInt32 Decrypt::update(std::vector<sal_uInt8>& output, std::vector<sal_uInt8
#endif
#if USE_TLS_OPENSSL
- (void)EVP_DecryptUpdate(&mContext, output.data(), &outputLength, input.data(), actualInputLength);
+ (void)EVP_DecryptUpdate(mpImpl->mpContext.get(), output.data(), &outputLength, input.data(), actualInputLength);
#endif // USE_TLS_OPENSSL
#if USE_TLS_NSS
- (void)PK11_CipherOp( mContext, output.data(), &outputLength, actualInputLength, input.data(), actualInputLength );
+ (void)PK11_CipherOp(mpImpl->mContext, output.data(), &outputLength, actualInputLength, input.data(), actualInputLength);
#endif // USE_TLS_NSS
return static_cast<sal_uInt32>(outputLength);
@@ -194,19 +314,9 @@ Encrypt::Encrypt(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, Crypto
#endif
#if USE_TLS_OPENSSL
- EVP_CIPHER_CTX_init(&mContext);
-
- const EVP_CIPHER* cipher = getCipher(type);
-
- if (iv.empty())
- EVP_EncryptInit_ex(&mContext, cipher, nullptr, key.data(), 0);
- else
- EVP_EncryptInit_ex(&mContext, cipher, nullptr, key.data(), iv.data());
- EVP_CIPHER_CTX_set_padding(&mContext, 0);
-#endif
-
-#if USE_TLS_NSS
- setupContext(key, iv, type, CKA_ENCRYPT);
+ mpImpl->setupEncryptContext(key, iv, type);
+#elif USE_TLS_NSS
+ mpImpl->setupCryptoContext(key, iv, type, CKA_ENCRYPT);
#endif // USE_TLS_NSS
}
@@ -223,16 +333,78 @@ sal_uInt32 Encrypt::update(std::vector<sal_uInt8>& output, std::vector<sal_uInt8
#endif
#if USE_TLS_OPENSSL
- (void)EVP_EncryptUpdate(&mContext, output.data(), &outputLength, input.data(), actualInputLength);
+ (void)EVP_EncryptUpdate(mpImpl->mpContext.get(), output.data(), &outputLength, input.data(), actualInputLength);
#endif // USE_TLS_OPENSSL
#if USE_TLS_NSS
- (void)PK11_CipherOp(mContext, output.data(), &outputLength, actualInputLength, input.data(), actualInputLength);
+ (void)PK11_CipherOp(mpImpl->mContext, output.data(), &outputLength, actualInputLength, input.data(), actualInputLength);
#endif // USE_TLS_NSS
return static_cast<sal_uInt32>(outputLength);
}
+// CryptoHash - HMAC
+
+namespace
+{
+
+sal_Int32 getSizeForHashType(CryptoHashType eType)
+{
+ switch (eType)
+ {
+ case CryptoHashType::SHA1: return 20;
+ case CryptoHashType::SHA256: return 32;
+ case CryptoHashType::SHA512: return 64;
+ }
+ return 0;
+}
+
+} // end anonymous namespace
+
+CryptoHash::CryptoHash(std::vector<sal_uInt8>& rKey, CryptoHashType eType)
+ : Crypto()
+ , mnHashSize(getSizeForHashType(eType))
+{
+#if USE_TLS_OPENSSL
+ mpImpl->setupCryptoHashContext(rKey, eType);
+#elif USE_TLS_NSS
+ mpImpl->setupCryptoHashContext(rKey, eType);
+ PK11_DigestBegin(mpImpl->mContext);
+#else
+ (void)rKey;
+#endif
+}
+
+bool CryptoHash::update(std::vector<sal_uInt8>& rInput, sal_uInt32 nInputLength)
+{
+#if USE_TLS_OPENSSL + USE_TLS_NSS > 0
+ sal_uInt32 nActualInputLength = (nInputLength == 0 || nInputLength > rInput.size()) ? rInput.size() : nInputLength;
+#else
+ (void)input;
+ (void)inputLength;
+#endif
+
+#if USE_TLS_OPENSSL
+ return HMAC_Update(mpImpl->mpHmacContext.get(), rInput.data(), nActualInputLength) != 0;
+#elif USE_TLS_NSS
+ return PK11_DigestOp(mpImpl->mContext, rInput.data(), nActualInputLength) == SECSuccess;
+#endif
+}
+
+std::vector<sal_uInt8> CryptoHash::finalize()
+{
+ std::vector<sal_uInt8> aHash(mnHashSize, 0);
+ unsigned int nSizeWritten;
+#if USE_TLS_OPENSSL
+ (void) HMAC_Final(mpImpl->mpHmacContext.get(), aHash.data(), &nSizeWritten) != 0;
+#elif USE_TLS_NSS
+ PK11_DigestFinal(mpImpl->mContext, aHash.data(), &nSizeWritten, aHash.size());
+#endif
+ (void)nSizeWritten;
+
+ return aHash;
+}
+
} // namespace core
} // namespace oox