Reiplementation of crypto-logic (old name DBCryptoModule).
Change-Id: Id1bdd4d48ee342ede3cf8cb78ff6c30a294ec541
${KEY_MANAGER_PATH}/service/ckm-logic.cpp
${KEY_MANAGER_PATH}/service/key-provider.cpp
${KEY_MANAGER_PATH}/service/ocsp.cpp
- ${KEY_MANAGER_PATH}/service/DBCryptoModule.cpp
+ ${KEY_MANAGER_PATH}/service/crypto-logic.cpp
${KEY_MANAGER_PATH}/service/CryptoService.cpp
${KEY_MANAGER_PATH}/service/file-system.cpp
${KEY_MANAGER_PATH}/service/db-crypto.cpp
SET(COMMON_SOURCES
${COMMON_PATH}/common/base64.cpp
${COMMON_PATH}/common/digest.cpp
- ${COMMON_PATH}/common/aesCrypt.cpp
${COMMON_PATH}/common/protocols.cpp
${COMMON_PATH}/common/message-buffer.cpp
${COMMON_PATH}/common/smack-check.cpp
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <features.h>
-
-#include <dpl/log/log.h>
-
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-
-#include <aesCrypt.h>
-
-namespace CKM {
-
-CryptoAlgConf::CryptoAlgConf(const EVP_CIPHER *cipher) :
- m_key(EVP_MAX_KEY_LENGTH),
- m_salt(PKCS5_SALT_LEN)
-{
- preinit(cipher);
-}
-
-CryptoAlgConf::CryptoAlgConf(const EVP_CIPHER *cipher, std::string &password) :
- m_key(EVP_MAX_KEY_LENGTH),
- m_salt(PKCS5_SALT_LEN)
-{
- preinit(cipher);
- if (not password.empty())
- generateKey(password);
-}
-
-CryptoAlgConf::~CryptoAlgConf()
-{
-}
-
-const EVP_CIPHER *CryptoAlgConf::getCipher(void)
-{
- return m_cipher;
-}
-
-void CryptoAlgConf::generateKey(std::string &password, bool use_iv)
-{
- int ret = -1;
-
- if (password.empty()) {
- ThrowMsg(Exception::InternalError, "Password is empty.");
- }
- if (not use_iv)
- generateRandIV();
- ret = PKCS5_PBKDF2_HMAC_SHA1(password.c_str(), password.length(), NULL, 0,
- m_pkcs5_password_iter, m_keyLen,
- m_key.data());
- if (ret != 1) {
- ThrowMsg(Exception::InternalError,
- "PKCS5_PBKDF2_HMAC_SHA1 has failed.");
- }
-}
-
-void CryptoAlgConf::generateRandIV()
-{
- RawBuffer civ(EVP_MAX_IV_LENGTH);
-
- if (RAND_bytes(civ.data(), civ.size()) != 1) {
- ThrowMsg(Exception::InternalError,
- "RAND_bytes failed to generate IV.");
- }
- m_iv = civ;
-}
-
-void CryptoAlgConf::setKey(const RawBuffer &key)
-{
- if (key.size() != m_keyLen) {
- ThrowMsg(Exception::InternalError, "Invalid key length.");
- }
- m_key = key;
-}
-
-void CryptoAlgConf::setIV(const RawBuffer &iv)
-{
- if ((iv.size() != m_ivLen) && (iv.size() != 0)) {
- ThrowMsg(Exception::InternalError, "Invalid IV length.");
- }
- m_iv = iv;
-}
-
-void CryptoAlgConf::setSalt(const RawBuffer &salt)
-{
- if (salt.size() != m_saltLen) {
- ThrowMsg(Exception::InternalError, "Invalid salt length.");
- }
- m_salt = salt;
-}
-
-RawBuffer CryptoAlgConf::getKey()
-{
- return m_key;
-}
-
-RawBuffer CryptoAlgConf::getIV()
-{
- return m_iv;
-}
-
-RawBuffer CryptoAlgConf::getSalt()
-{
- return m_salt;
-}
-
-void CryptoAlgConf::preinit(const EVP_CIPHER *cipher)
-{
- m_cipher = cipher;
- if (m_cipher == nullptr)
- m_cipher = EVP_aes_256_cbc();
- m_keyLen = EVP_CIPHER_key_length(m_cipher);
- m_ivLen = EVP_CIPHER_iv_length(m_cipher);
- m_saltLen = PKCS5_SALT_LEN;
- m_key.resize(m_keyLen);
- m_pkcs5_password_iter = 1024;
- generateRandIV();
-}
-
-std::size_t CryptoAlgConf::maxBufLen(std::size_t len)
-{
- return len + EVP_CIPHER_block_size(m_cipher);
-}
-
-/******************************************************************************
- *****************************************************************************/
-
-AesCrypt::AesCrypt(AESCryptMode mode, std::string password) :
- conf(nullptr, password)
-{
- m_ctx = nullptr;
- if ((mode != AESCryptMode::ENCODER) && (mode != AESCryptMode::DECODER)) {
- ThrowMsg(Exception::InternalError,
- "Unknown mode of crypto operations.");
- } else
- m_mode = mode;
- m_initialized = false;
- m_finalized = false;
- m_padding = true;
- if (m_mode == AESCryptMode::ENCODER) {
- m_fInit = EVP_EncryptInit_ex;
- m_fUpdate = EVP_EncryptUpdate;
- m_fFinal = EVP_EncryptFinal_ex;
- } else {
- m_fInit = EVP_DecryptInit_ex;
- m_fUpdate = EVP_DecryptUpdate;
- m_fFinal = EVP_DecryptFinal_ex;
- }
-}
-
-AesCrypt::~AesCrypt()
-{
- EVP_CIPHER_CTX_free(m_ctx);
-}
-
-void AesCrypt::reset()
-{
- int ret = -1;
-
- if (m_initialized) {
- EVP_CIPHER_CTX_free(m_ctx);
- m_ctx = nullptr;
- }
- m_initialized = false;
- m_finalized = false;
- m_ctx = EVP_CIPHER_CTX_new();
- if (m_ctx == nullptr) {
- ThrowMsg(Exception::InternalError,
- "Failed to alloc security context.");
- }
- ret = m_fInit(m_ctx, conf.getCipher(), NULL, conf.getKey().data(),
- conf.getIV().data());
- if (ret != 1) {
- ThrowMsg(Exception::InternalError,
- "Failed to initialize encryption in openssl.");
- }
- if (m_padding)
- EVP_CIPHER_CTX_set_padding(m_ctx, 1);
- m_bufWritePos = 0;
- m_buf.clear();
- m_initialized = true;
-}
-
-RawBuffer AesCrypt::finalize()
-{
- int ret = -1;
- int outlf;
-
- if (not m_initialized) {
- ThrowMsg(Exception::InternalError, "Not initialized.");
- }
- if (m_finalized) {
- ThrowMsg(Exception::InternalError, "Already finalized.");
- }
- if (m_buf.size() == 0) {
- ThrowMsg(Exception::InternalError,
- "Empty buffor: append() was missing?");
- }
- m_buf.resize(conf.maxBufLen(m_bufWritePos));
- ret = m_fFinal(m_ctx, m_buf.data() + m_bufWritePos, &outlf);
- if (ret != 1) {
- ThrowMsg(Exception::InternalError,
- "Failed to encrypt data in openssl (final)");
- }
- m_bufWritePos += outlf;
- if (0 == m_bufWritePos) {
- ThrowMsg(Exception::InternalError,
- "No output data.");
- }
- EVP_CIPHER_CTX_free(m_ctx);
- m_ctx = nullptr;
- m_buf.resize(m_bufWritePos);
- m_initialized = false;
- m_finalized = true;
-
- return m_buf;
-}
-
-int AesCrypt::append(const RawBuffer &data)
-{
- int ret = -1;
- int outl = -1;
-
- if (data.size() == 0) {
- ThrowMsg(Exception::InternalError, "Empty data.");
- }
- if (m_finalized) {
- ThrowMsg(Exception::InternalError, "Already finalized.");
- }
- if (not m_initialized)
- reset();
-
- m_buf.resize(conf.maxBufLen(data.size()));
- ret = m_fUpdate(m_ctx, m_buf.data() + m_bufWritePos, &outl, data.data(),
- data.size());
- if (ret != 1) {
- ThrowMsg(Exception::InternalError,
- "Failed to encrypt data in openssl");
- }
- m_bufWritePos += outl;
-
- return outl;
-}
-
-RawBuffer AesCrypt::get()
-{
- if (m_finalized)
- return m_buf;
- else
- return RawBuffer();
-}
-
-AESCryptMode AesCrypt::getMode()
-{
- return m_mode;
-}
-
-/******************************************************************************
- *****************************************************************************/
-
-AesEncrypt::AesEncrypt() :
- AesCrypt(AESCryptMode::ENCODER, "")
-{
-}
-
-AesEncrypt::AesEncrypt(std::string password) :
- AesCrypt(AESCryptMode::ENCODER, password)
-{
-}
-
-AesEncrypt::~AesEncrypt()
-{
-}
-
-/******************************************************************************
- *****************************************************************************/
-
-AesDecrypt::AesDecrypt() :
- AesCrypt(AESCryptMode::DECODER, "")
-{
-}
-
-AesDecrypt::AesDecrypt(std::string password) :
- AesCrypt(AESCryptMode::DECODER, password)
-{
-}
-
-AesDecrypt::~AesDecrypt()
-{
-}
-
-} // namespace CKM
-
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-
-#include <dpl/noncopyable.h>
-#include <dpl/exception.h>
-
-#include <ckm/ckm-type.h>
-
-/*
- * Taken from openssl/ossl_typ.h
- */
-struct evp_cipher_st;
-typedef evp_cipher_st EVP_CIPHER;
-struct evp_cipher_ctx_st;
-typedef evp_cipher_ctx_st EVP_CIPHER_CTX;
-struct engine_st;
-typedef engine_st ENGINE;
-
-namespace CKM {
-
-class CryptoAlgConf
-{
- public:
- class Exception
- {
- public:
- DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
- DECLARE_EXCEPTION_TYPE(Base, InternalError)
- };
-
- CryptoAlgConf(const EVP_CIPHER *cipher);
- CryptoAlgConf(const EVP_CIPHER *cipher, std::string &password);
- ~CryptoAlgConf();
-
- const EVP_CIPHER *getCipher(void);
- void setKey(const RawBuffer &key);
- void setIV(const RawBuffer &iv);
- void setSalt(const RawBuffer &salt); // TODO: not used yet
- RawBuffer getKey(void);
- RawBuffer getIV(void);
- RawBuffer getSalt(void);
- void generateKey(std::string &password, bool use_iv = false);
- void generateRandIV(void);
- std::size_t maxBufLen(std::size_t len);
-
- private:
- RawBuffer m_key;
- RawBuffer m_iv;
- RawBuffer m_salt; // TODO: not used yet
- const EVP_CIPHER *m_cipher;
- std::size_t m_keyLen;
- std::size_t m_ivLen;
- std::size_t m_saltLen;
- int m_pkcs5_password_iter;
-
- void preinit(const EVP_CIPHER *cipher);
-};
-
-enum class AESCryptMode : int {
- ENCODER,
- DECODER
-};
-
-class AesCrypt : public CKM::Noncopyable
-{
- public:
- class Exception
- {
- public:
- DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
- DECLARE_EXCEPTION_TYPE(Base, InternalError)
- };
-
- AesCrypt(AESCryptMode mode, std::string password);
- ~AesCrypt();
-
- void reset(void);
- RawBuffer finalize(void);
- RawBuffer get(void);
- int append(const RawBuffer &data);
- AESCryptMode getMode(void);
- CryptoAlgConf conf;
-
- private:
- EVP_CIPHER_CTX *m_ctx;
- RawBuffer m_buf;
- bool m_initialized;
- bool m_finalized;
- int m_bufWritePos;
- AESCryptMode m_mode;
- bool m_padding;
-
- int (*m_fInit)(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
- ENGINE *impl, const unsigned char *key,
- const unsigned char *iv);
- int (*m_fUpdate)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
- const unsigned char *in, int inl);
- int (*m_fFinal)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
-};
-
-class AesEncrypt : public AesCrypt
-{
- public:
- AesEncrypt();
- AesEncrypt(std::string password);
- ~AesEncrypt();
-};
-
-class AesDecrypt : public AesCrypt
-{
- public:
- AesDecrypt();
- AesDecrypt(std::string password);
- ~AesDecrypt();
-};
-
-} // namespace CKM
-
--- /dev/null
+/* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ *
+ * @file crypto.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Crypto module implementation.
+ */
+#pragma once
+
+#include <dpl/log/log.h>
+
+#include <openssl/evp.h>
+
+#include <vector>
+
+namespace CKM {
+
+typedef std::vector<unsigned char> RawBuffer;
+
+namespace Crypto {
+
+class Exception
+{
+public:
+ DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, InternalError)
+};
+
+namespace Cipher {
+
+template<class T>
+struct Base {
+ Base()
+ : m_ctx(EVP_CIPHER_CTX_new())
+ {
+ static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside conatainer.");
+ }
+ Base(const Base&) = delete;
+ Base(Base &&) = delete;
+ Base<T>& operator=(const Base&) = delete;
+ Base<T>& operator=(Base &&) = delete;
+
+ virtual T Append(const T&) = 0;
+ virtual T Finalize() = 0;
+ virtual ~Base(){
+ EVP_CIPHER_CTX_free(m_ctx);
+ }
+protected:
+ EVP_CIPHER_CTX *m_ctx;
+};
+
+template<class T>
+class EvpCipherWrapper : public Base<T> {
+public:
+ using Base<T>::m_ctx;
+
+ EvpCipherWrapper(const EVP_CIPHER *type, const T &key, const T &iv, bool encryption)
+ {
+ if (static_cast<int>(key.size()) != EVP_CIPHER_key_length(type)) {
+ LogError("Wrong key size! Expected: "
+ << EVP_CIPHER_key_length(type) << " Get: " << key.size());
+ ThrowMsg(CKM::Crypto::Exception::InternalError, "Wrong key size! Expected: "
+ << EVP_CIPHER_key_length(type) << " Get: " << key.size());
+ }
+
+ if (static_cast<int>(iv.size()) < EVP_CIPHER_iv_length(type)) {
+ LogError("Wrong iv size! Expected: "
+ << EVP_CIPHER_iv_length(type) << " Get: " << iv.size());
+ ThrowMsg(CKM::Crypto::Exception::InternalError, "Wrong iv size! Expected: "
+ << EVP_CIPHER_iv_length(type) << " Get: " << iv.size());
+ }
+
+ if (1 != EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(), encryption ? 1 : 0)) {
+ LogError("Failed in EVP_CipherInit");
+ ThrowMsg(CKM::Crypto::Exception::InternalError, "Failed in EVP_CipherInit");
+ }
+
+ EVP_CIPHER_CTX_set_padding(m_ctx, 1);
+ }
+
+ T Append(const T& data) {
+ static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside container.");
+ int bytesLen = static_cast<int>(data.size() + EVP_CIPHER_CTX_block_size(m_ctx));
+ T output(bytesLen);
+ if (1 != EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(), data.size())) {
+ LogError("Failed in EVP_CipherUpdate");
+ ThrowMsg(CKM::Crypto::Exception::InternalError, "Failed in EVP_CipherUpdate");
+ }
+ output.resize(bytesLen);
+ return output;
+ }
+
+ T Finalize() {
+ int bytesLen = EVP_CIPHER_CTX_block_size(m_ctx);
+ T output(bytesLen);
+ if (1 != EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen)) {
+ LogError("Failed in EVP_CipherFinal");
+ ThrowMsg(CKM::Crypto::Exception::InternalError, "Failed in EVP_CipherFinal");
+ }
+ output.resize(bytesLen);
+ return output;
+ }
+};
+
+#define DEFINE_CIPHER(__classname, __type, __evpcipher, __encryption) \
+class __classname : public EvpCipherWrapper<__type> { \
+public: \
+ __classname(const __type &key, const __type &iv) \
+ : EvpCipherWrapper(__evpcipher, key, iv, __encryption) \
+ {} \
+}
+
+DEFINE_CIPHER(AesCbcEncryption, RawBuffer, EVP_aes_256_cbc(), true);
+DEFINE_CIPHER(AesCbcDecryption, RawBuffer, EVP_aes_256_cbc(), false);
+
+#undef DEFINE_CIPHER
+
+} // namespace Cipher
+} // namespace Crypto
+} // namespace CKM
+
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iostream>
-#include <fstream>
-#include <stdio.h>
-#include <string.h>
-
-#include <dpl/log/log.h>
-#include <base64.h>
-#include <ckm/ckm-error.h>
-#include <digest.h>
-
-#include <DBCryptoModule.h>
-
-namespace CKM {
-
-DBCryptoModule::DBCryptoModule(){}
-
-DBCryptoModule::DBCryptoModule(DBCryptoModule &&second) {
- m_keyMap = std::move(second.m_keyMap);
-}
-
-DBCryptoModule& DBCryptoModule::operator=(DBCryptoModule &&second) {
- if (this == &second)
- return *this;
- m_keyMap = std::move(second.m_keyMap);
- return *this;
-}
-
-bool DBCryptoModule::haveKey(const std::string &smackLabel)
-{
- return (m_keyMap.count(smackLabel) > 0);
-}
-
-int DBCryptoModule::pushKey(const std::string &smackLabel,
- const RawBuffer &applicationKey)
-{
- if (smackLabel.length() == 0) {
- ThrowMsg(Exception::InternalError, "Empty smack label.");
- }
- if (applicationKey.size() == 0) {
- ThrowMsg(Exception::InternalError, "Empty application key.");
- }
- if (haveKey(smackLabel)) {
- ThrowMsg(Exception::InternalError, "Application key for " << smackLabel
- << "label already exists.");
- }
- m_keyMap[smackLabel] = applicationKey;
- return CKM_API_SUCCESS;
-}
-
-std::size_t DBCryptoModule::insertDigest(RawBuffer &data, const int dataSize)
-{
- RawBuffer digest;
-
- try {
- Digest dig;
- dig.append(data, dataSize);
- digest = dig.finalize();
- } catch (Digest::Exception::Base &e) {
- LogError("Failed to calculate digest in insertDigest: " <<
- e.DumpToString());
- throw;
- }
- data.insert(data.begin(), digest.begin(), digest.end());
- return digest.size();
-}
-
-void DBCryptoModule::removeDigest(RawBuffer &data, RawBuffer &digest)
-{
- unsigned int dlen = Digest().length();
-
- if (data.size() < dlen) {
- ThrowMsg(Exception::InternalError,
- "Cannot remove digest: data size mismatch.");
- }
-
- digest.assign(data.begin(), data.begin() + dlen);
- data.erase(data.begin(), data.begin() + dlen);
-}
-
-int DBCryptoModule::encryptRow(const std::string &password, DBRow &row)
-{
- RawBuffer emptyiv;
- RawBuffer emptykey;
- DBRow crow = row;
- RawBuffer appkey;
-
- crow.algorithmType = DBCMAlgType::NONE;
- if (row.dataSize <= 0) {
- ThrowMsg(Exception::EncryptDBRowError, "Invalid dataSize.");
- }
- if (!haveKey(row.smackLabel)) {
- ThrowMsg(Exception::EncryptDBRowError, "Missing application key for " <<
- row.smackLabel << " label.");
- }
- appkey = m_keyMap[row.smackLabel];
- crow.encryptionScheme = 0;
-
- try {
- insertDigest(crow.data, crow.dataSize);
- cryptAES(crow.data, appkey, emptyiv, "");
- crow.encryptionScheme |= ENCR_APPKEY;
- if (!password.empty()) {
- crow.iv = cryptAES(crow.data, emptykey, emptyiv, password).getIV();
- crow.encryptionScheme |= ENCR_PASSWORD;
- }
- encBase64(crow.data);
- crow.encryptionScheme |= ENCR_BASE64;
- encBase64(crow.iv);
- } catch (Exception::Base &e) {
- LogError("Failed to encrypt db row: " << e.DumpToString());
- throw;
- } catch (AesCrypt::Exception::Base &e) {
- LogError("Failed to encrypt db row: " << e.DumpToString());
- throw;
- }
- crow.algorithmType = DBCMAlgType::AES_CBC_256;
- row = crow;
-
- return CKM_API_SUCCESS;
-}
-
-int DBCryptoModule::decryptRow(const std::string &password, DBRow &row)
-{
- DBRow crow = row;
- RawBuffer appkey;
- RawBuffer emptykey;
- RawBuffer dropiv;
- RawBuffer emptyiv;
- RawBuffer digest, dataDigest;
-
- if (row.dataSize <= 0) {
- ThrowMsg(Exception::DecryptDBRowError, "Invalid dataSize.");
- }
- if (row.algorithmType != DBCMAlgType::AES_CBC_256) {
- ThrowMsg(Exception::DecryptDBRowError, "Invalid algorithm type.");
- }
- if (row.encryptionScheme & ENCR_PASSWORD)
- if (password.empty()) {
- ThrowMsg(Exception::DecryptDBRowError,
- "DB row is password protected, but given password is "
- "empty.");
- }
- if (!haveKey(row.smackLabel)) {
- ThrowMsg(Exception::DecryptDBRowError, "Missing application key for " <<
- row.smackLabel << " label.");
- }
- appkey = m_keyMap[row.smackLabel];
-
- try {
- decBase64(crow.iv);
- if (crow.encryptionScheme & ENCR_BASE64) {
- decBase64(crow.data);
- }
- if (crow.encryptionScheme & ENCR_PASSWORD) {
- decryptAES(crow.data, emptykey, crow.iv, password);
- }
- if (crow.encryptionScheme & ENCR_APPKEY) {
- decryptAES(crow.data, appkey, emptyiv, "");
- }
- removeDigest(crow.data, digest);
- if (static_cast<std::size_t>(crow.dataSize) != crow.data.size()) {
- ThrowMsg(Exception::DecryptDBRowError,
- "Decrypted db row data size mismatch.");
- }
- Digest dig;
- dig.append(crow.data);
- dataDigest = dig.finalize();
- } catch (Exception::Base &e) {
- LogError("Failed to decrypt db row: " << e.DumpToString());
- throw;
- } catch (AesCrypt::Exception::Base &e) {
- LogError("Failed to decrypt db row: " << e.DumpToString());
- throw;
- } catch (Digest::Exception::Base &e) {
- LogError("Failed to decrypt db row: " << e.DumpToString());
- throw;
- }
- if (not equalDigests(digest, dataDigest)) {
- ThrowMsg(Exception::DecryptDBRowError,
- "Decrypted db row data digest mismatch.");
- }
- row = crow;
-
- return CKM_API_SUCCESS;
-}
-
-CryptoAlgConf DBCryptoModule::cryptAES(RawBuffer &data,
- const RawBuffer &key,
- const RawBuffer &iv,
- std::string password)
-{
- try {
- AesEncrypt enc(password);
-
- if (password.empty()) {
- enc.conf.setKey(key);
- enc.conf.setIV(iv);
- }
- enc.append(data);
- data = enc.finalize();
- return enc.conf;
- } catch (CryptoAlgConf::Exception::Base &e) {
- LogError("Failed to configure AES encryption: " << e.DumpToString());
- throw;
- } catch (AesCrypt::Exception::Base &e) {
- LogError("AES encryption failed: " << e.DumpToString());
- throw;
- }
-}
-
-void DBCryptoModule::decryptAES(RawBuffer &data, const RawBuffer &key,
- const RawBuffer &iv, std::string password)
-{
- try {
- AesDecrypt dec(password);
-
- if (password.empty()) {
- dec.conf.setKey(key);
- }
- dec.conf.setIV(iv);
- dec.append(data);
- data = dec.finalize();
- } catch (CryptoAlgConf::Exception::Base &e) {
- LogError("Failed to configure AES decryption: " << e.DumpToString());
- throw;
- } catch (AesCrypt::Exception::Base &e) {
- LogError("AES Decryption failed: " << e.DumpToString());
- throw;
- }
-}
-
-void DBCryptoModule::encBase64(RawBuffer &data)
-{
- Base64Encoder benc;
- RawBuffer encdata;
-
- try {
- benc.append(data);
- benc.finalize();
- encdata = benc.get();
- } catch (Base64Encoder::Exception::Base &e) {
- LogError("Failed to encode data in Base64Encoder: " <<
- e.DumpToString());
- throw;
- }
-
- if (encdata.size() == 0) {
- ThrowMsg(Exception::Base64EncoderError, "Base64Encoder returned empty data.");
- }
-
- data = std::move(encdata);
-}
-
-void DBCryptoModule::decBase64(RawBuffer &data)
-{
- Base64Decoder bdec;
- RawBuffer decdata;
-
- try {
- bdec.reset();
- bdec.append(data);
- if (not bdec.finalize()) {
- ThrowMsg(Exception::Base64DecoderError,
- "Failed in Base64Decoder.finalize.");
- }
-
- decdata = bdec.get();
- } catch (Base64Decoder::Exception::Base &e) {
- LogError("Failed to decode data in Base64Decoder: " <<
- e.DumpToString());
- throw;
- }
- if (decdata.size() == 0) {
- ThrowMsg(Exception::Base64DecoderError, "Base64Decoder returned empty data.");
- }
-
- data = std::move(decdata);
-}
-
-bool DBCryptoModule::equalDigests(RawBuffer &dig1, RawBuffer &dig2)
-{
- unsigned int dlen = Digest().length();
-
- if ((dig1.size() != dlen) || (dig2.size() != dlen))
- return false;
- return (dig1 == dig2);
-}
-
-} // namespace CKM
-
RawBuffer key = handle.keyProvider.getPureDomainKEK();
handle.database = DBCrypto(fs.getDBPath(), key);
- handle.crypto = DBCryptoModule();
+ handle.crypto = CryptoLogic();
// TODO wipe key
}
} catch (const KeyProvider::Exception::Base &e) {
LogError("Error in KeyProvider " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
+ } catch (const CryptoLogic::Exception::Base &e) {
+ LogError("CryptoLogic error: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
+ } catch (const CKM::Exception &e) {
+ LogError("CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
}
MessageBuffer response;
DBRow row = { alias, cred.smackLabel, policy.restricted,
policy.extractable, dataType, DBCMAlgType::NONE,
- 0, RawBuffer(10, 'c'), static_cast<int>(key.size()), key };
+ 0, RawBuffer(), static_cast<int>(key.size()), key };
auto &handler = m_userDataMap[cred.uid];
DBCrypto::Transaction transaction(&handler.database);
} catch (const KeyProvider::Exception::Base &e) {
LogError("KeyProvider failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
- } catch (const DBCryptoModule::Exception::Base &e) {
- LogError("DBCryptoModule failed with message: " << e.GetMessage());
+ } catch (const CryptoLogic::Exception::Base &e) {
+ LogError("CryptoLogic failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
} catch (const DBCrypto::Exception::InternalError &e) {
LogError("DBCrypto failed with message: " << e.GetMessage());
} catch (const KeyProvider::Exception::Base &e) {
LogError("KeyProvider failed with error: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
- } catch (const DBCryptoModule::Exception::Base &e) {
- LogError("DBCryptoModule failed with message: " << e.GetMessage());
+ } catch (const CryptoLogic::Exception::Base &e) {
+ LogError("CryptoLogic failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
} catch (const DBCrypto::Exception::Base &e) {
LogError("DBCrypto failed with message: " << e.GetMessage());
} catch (DBCrypto::Exception::TransactionError &e) {
LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (CKM::CryptoLogic::Exception::Base &e) {
+ LogDebug("CryptoLogic error: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
} catch (DBCrypto::Exception::InternalError &e) {
LogDebug("DBCrypto internal error: " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
} catch (const DBCrypto::Exception::TransactionError &e) {
LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const CKM::CryptoLogic::Exception::Base &e) {
+ LogDebug("CryptoLogic error: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
} catch (const DBCrypto::Exception::InternalError &e) {
LogDebug("DBCrypto internal error: " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
for (auto &i: chainVector)
chainRawVector.push_back(i.getDER());
- } catch (const DBCryptoModule::Exception::Base &e) {
+ } catch (const CryptoLogic::Exception::Base &e) {
LogError("DBCyptorModule failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
} catch (const DBCrypto::Exception::Base &e) {
} catch (const KeyProvider::Exception::Base &e) {
LogError("KeyProvider failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
- } catch (const DBCryptoModule::Exception::Base &e) {
- LogError("DBCryptoModule failed with message: " << e.GetMessage());
+ } catch (const CryptoLogic::Exception::Base &e) {
+ LogError("CryptoLogic failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
} catch (const DBCrypto::Exception::Base &e) {
LogError("DBCrypto failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const CKM::Exception &e) {
+ LogError("Unknown CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
}
MessageBuffer response;
} catch (const KeyProvider::Exception::Base &e) {
LogError("KeyProvider failed with error: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
- } catch (const DBCryptoModule::Exception::Base &e) {
- LogError("DBCryptoModule failed with message: " << e.GetMessage());
+ } catch (const CryptoLogic::Exception::Base &e) {
+ LogError("CryptoLogic failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
} catch (const DBCrypto::Exception::Base &e) {
LogError("DBCrypto failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const CKM::Exception &e) {
+ LogError("Unknown CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
}
MessageBuffer response;
#include <connection-info.h>
#include <db-crypto.h>
#include <key-provider.h>
-#include <DBCryptoModule.h>
+#include <crypto-logic.h>
#include <certificate-store.h>
namespace CKM {
struct UserData {
KeyProvider keyProvider;
DBCrypto database;
- DBCryptoModule crypto;
+ CryptoLogic crypto;
};
class CKMLogic {
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @file crypto-logic.cpp
+ * @author Sebastian Grabowski (s.grabowski@samsung.com)
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Crypto module implementation.
+ */
+
+#include <iostream>
+#include <fstream>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+
+#include <ckm/ckm-error.h>
+
+#include <dpl/log/log.h>
+
+#include <base64.h>
+#include <digest.h>
+#include <crypto.h>
+#include <crypto-logic.h>
+
+#define AES_CBC_KEY_SIZE 32
+
+namespace CKM {
+
+CryptoLogic::CryptoLogic(){}
+
+CryptoLogic::CryptoLogic(CryptoLogic &&second) {
+ m_keyMap = std::move(second.m_keyMap);
+}
+
+CryptoLogic& CryptoLogic::operator=(CryptoLogic &&second) {
+ if (this == &second)
+ return *this;
+ m_keyMap = std::move(second.m_keyMap);
+ return *this;
+}
+
+bool CryptoLogic::haveKey(const std::string &smackLabel)
+{
+ return (m_keyMap.count(smackLabel) > 0);
+}
+
+void CryptoLogic::pushKey(const std::string &smackLabel,
+ const RawBuffer &applicationKey)
+{
+ if (smackLabel.length() == 0) {
+ ThrowMsg(Exception::InternalError, "Empty smack label.");
+ }
+ if (applicationKey.size() == 0) {
+ ThrowMsg(Exception::InternalError, "Empty application key.");
+ }
+ if (haveKey(smackLabel)) {
+ ThrowMsg(Exception::InternalError, "Application key for " << smackLabel
+ << "label already exists.");
+ }
+ m_keyMap[smackLabel] = applicationKey;
+}
+
+std::size_t CryptoLogic::insertDigest(RawBuffer &data, const int dataSize)
+{
+ RawBuffer digest;
+
+ try {
+ Digest dig;
+ dig.append(data, dataSize);
+ digest = dig.finalize();
+ } catch (Digest::Exception::Base &e) {
+ LogError("Failed to calculate digest in insertDigest: " <<
+ e.DumpToString());
+ ThrowMsg(Exception::InternalError, e.GetMessage());
+ }
+ data.insert(data.begin(), digest.begin(), digest.end());
+ return digest.size();
+}
+
+void CryptoLogic::removeDigest(RawBuffer &data, RawBuffer &digest)
+{
+ unsigned int dlen = Digest().length();
+
+ if (data.size() < dlen) {
+ ThrowMsg(Exception::InternalError,
+ "Cannot remove digest: data size mismatch.");
+ }
+
+ digest.assign(data.begin(), data.begin() + dlen);
+ data.erase(data.begin(), data.begin() + dlen);
+}
+
+RawBuffer CryptoLogic::encryptData(
+ const RawBuffer &data,
+ const RawBuffer &key,
+ const RawBuffer &iv) const
+{
+ Crypto::Cipher::AesCbcEncryption enc(key, iv);
+ RawBuffer result = enc.Append(data);
+ RawBuffer tmp = enc.Finalize();
+ std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
+ return result;
+}
+
+RawBuffer CryptoLogic::decryptData(
+ const RawBuffer &data,
+ const RawBuffer &key,
+ const RawBuffer &iv) const
+{
+ Crypto::Cipher::AesCbcDecryption dec(key, iv);
+ RawBuffer result = dec.Append(data);
+ RawBuffer tmp = dec.Finalize();
+ std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
+ return result;
+}
+
+RawBuffer CryptoLogic::passwordToKey(
+ const std::string &password,
+ const RawBuffer &salt,
+ size_t keySize) const
+{
+ RawBuffer result(keySize);
+
+ if (1 != PKCS5_PBKDF2_HMAC_SHA1(
+ password.c_str(),
+ password.size(),
+ salt.data(),
+ salt.size(),
+ 1024,
+ result.size(),
+ result.data()))
+ {
+ ThrowMsg(Exception::InternalError, "PCKS5_PKKDF_HMAC_SHA1 failed.");
+ }
+ return result;
+}
+
+RawBuffer CryptoLogic::generateRandIV() const {
+ RawBuffer civ(EVP_MAX_IV_LENGTH);
+
+ if (1 != RAND_bytes(civ.data(), civ.size())) {
+ ThrowMsg(Exception::InternalError,
+ "RAND_bytes failed to generate IV.");
+ }
+
+ return civ;
+}
+
+void CryptoLogic::encryptRow(const std::string &password, DBRow &row)
+{
+ try {
+ DBRow crow = row;
+ RawBuffer key;
+ RawBuffer result1;
+ RawBuffer result2;
+
+ crow.algorithmType = DBCMAlgType::AES_CBC_256;
+
+ if (crow.dataSize <= 0) {
+ ThrowMsg(Exception::EncryptDBRowError, "Invalid dataSize.");
+ }
+
+ if (!haveKey(row.smackLabel)) {
+ ThrowMsg(Exception::EncryptDBRowError, "Missing application key for " <<
+ row.smackLabel << " label.");
+ }
+
+ if (crow.iv.empty()) {
+ crow.iv = generateRandIV();
+ }
+
+ key = m_keyMap[row.smackLabel];
+ crow.encryptionScheme = ENCR_APPKEY;
+
+ insertDigest(crow.data, crow.dataSize);
+ crow.data = encryptData(crow.data, key, crow.iv);
+
+ if (!password.empty()) {
+ key = passwordToKey(password, crow.iv, AES_CBC_KEY_SIZE);
+ crow.data = encryptData(crow.data, key, crow.iv);
+ crow.encryptionScheme |= ENCR_PASSWORD;
+ }
+
+ encBase64(crow.data);
+ crow.encryptionScheme |= ENCR_BASE64;
+ encBase64(crow.iv);
+
+ row = crow;
+ } catch(const CKM::Base64Encoder::Exception::Base &e) {
+ LogDebug("Base64Encoder error: " << e.GetMessage());
+ ThrowMsg(Exception::Base64EncoderError, e.GetMessage());
+ } catch(const CKM::Base64Decoder::Exception::Base &e) {
+ LogDebug("Base64Encoder error: " << e.GetMessage());
+ ThrowMsg(Exception::Base64DecoderError, e.GetMessage());
+ } catch(const CKM::Crypto::Exception::Base &e) {
+ LogDebug("Crypto error: " << e.GetMessage());
+ ThrowMsg(Exception::EncryptDBRowError, e.GetMessage());
+ }
+}
+
+void CryptoLogic::decryptRow(const std::string &password, DBRow &row)
+{
+ try {
+ DBRow crow = row;
+ RawBuffer key;
+ RawBuffer digest, dataDigest;
+
+ if (row.algorithmType != DBCMAlgType::AES_CBC_256) {
+ ThrowMsg(Exception::DecryptDBRowError, "Invalid algorithm type.");
+ }
+
+ if ((row.encryptionScheme & ENCR_PASSWORD) && password.empty()) {
+ ThrowMsg(Exception::DecryptDBRowError,
+ "DB row is password protected, but given password is "
+ "empty.");
+ }
+
+ if ((row.encryptionScheme & ENCR_APPKEY) && !haveKey(row.smackLabel)) {
+ ThrowMsg(Exception::DecryptDBRowError, "Missing application key for " <<
+ row.smackLabel << " label.");
+ }
+
+ decBase64(crow.iv);
+ if (crow.encryptionScheme & ENCR_BASE64) {
+ decBase64(crow.data);
+ }
+
+ if (crow.encryptionScheme & ENCR_PASSWORD) {
+ key = passwordToKey(password, crow.iv, AES_CBC_KEY_SIZE);
+ crow.data = decryptData(crow.data, key, crow.iv);
+ }
+
+ if (crow.encryptionScheme & ENCR_APPKEY) {
+ key = m_keyMap[crow.smackLabel];
+ crow.data = decryptData(crow.data, key, crow.iv);
+ }
+
+ removeDigest(crow.data, digest);
+
+ if (static_cast<std::size_t>(crow.dataSize) != crow.data.size()) {
+ ThrowMsg(Exception::DecryptDBRowError,
+ "Decrypted db row data size mismatch.");
+ }
+
+ Digest dig;
+ dig.append(crow.data);
+ dataDigest = dig.finalize();
+
+ if (not equalDigests(digest, dataDigest)) {
+ ThrowMsg(Exception::DecryptDBRowError,
+ "Decrypted db row data digest mismatch.");
+ }
+ row = crow;
+ } catch(const CKM::Base64Encoder::Exception::Base &e) {
+ LogDebug("Base64Encoder error: " << e.GetMessage());
+ ThrowMsg(Exception::Base64EncoderError, e.GetMessage());
+ } catch(const CKM::Base64Decoder::Exception::Base &e) {
+ LogDebug("Base64Encoder error: " << e.GetMessage());
+ ThrowMsg(Exception::Base64DecoderError, e.GetMessage());
+ } catch(const CKM::Crypto::Exception::Base &e) {
+ LogDebug("Crypto error: " << e.GetMessage());
+ ThrowMsg(Exception::DecryptDBRowError, e.GetMessage());
+ }
+}
+
+void CryptoLogic::encBase64(RawBuffer &data)
+{
+ Base64Encoder benc;
+ RawBuffer encdata;
+
+ benc.append(data);
+ benc.finalize();
+ encdata = benc.get();
+
+ if (encdata.size() == 0) {
+ ThrowMsg(Exception::Base64EncoderError, "Base64Encoder returned empty data.");
+ }
+
+ data = std::move(encdata);
+}
+
+void CryptoLogic::decBase64(RawBuffer &data)
+{
+ Base64Decoder bdec;
+ RawBuffer decdata;
+
+ bdec.reset();
+ bdec.append(data);
+ if (not bdec.finalize()) {
+ ThrowMsg(Exception::Base64DecoderError,
+ "Failed in Base64Decoder.finalize.");
+ }
+
+ decdata = bdec.get();
+
+ if (decdata.size() == 0) {
+ ThrowMsg(Exception::Base64DecoderError, "Base64Decoder returned empty data.");
+ }
+
+ data = std::move(decdata);
+}
+
+bool CryptoLogic::equalDigests(RawBuffer &dig1, RawBuffer &dig2)
+{
+ unsigned int dlen = Digest().length();
+
+ if ((dig1.size() != dlen) || (dig2.size() != dlen))
+ return false;
+ return (dig1 == dig2);
+}
+
+} // namespace CKM
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
+ *
+ * @file crypto-logic.h
+ * @author Sebastian Grabowski (s.grabowski@samsung.com)
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Crypto module implementation.
*/
-
#pragma once
#include <map>
#include <ckm/ckm-type.h>
#include <db-crypto.h>
#include <dpl/exception.h>
-#include <aesCrypt.h>
namespace CKM {
-class DBCryptoModule {
+class CryptoLogic {
public:
class Exception
{
DECLARE_EXCEPTION_TYPE(Base, EncryptDBRowError)
DECLARE_EXCEPTION_TYPE(Base, DecryptDBRowError)
};
- DBCryptoModule();
- DBCryptoModule(const DBCryptoModule &second) = delete;
- DBCryptoModule(DBCryptoModule &&second);
- DBCryptoModule& operator=(DBCryptoModule &&second);
- DBCryptoModule& operator=(const DBCryptoModule &second) = delete;
+ CryptoLogic();
+ CryptoLogic(const CryptoLogic &second) = delete;
+ CryptoLogic(CryptoLogic &&second);
+ CryptoLogic& operator=(CryptoLogic &&second);
+ CryptoLogic& operator=(const CryptoLogic &second) = delete;
- virtual ~DBCryptoModule(){}
+ virtual ~CryptoLogic(){}
- int decryptRow(const std::string &password, DBRow &row);
- int encryptRow(const std::string &password, DBRow &row);
+ void decryptRow(const std::string &password, DBRow &row);
+ void encryptRow(const std::string &password, DBRow &row);
bool haveKey(const std::string &smackLabel);
- int pushKey(const std::string &smackLabel,
- const RawBuffer &applicationKey);
+ void pushKey(const std::string &smackLabel,
+ const RawBuffer &applicationKey);
private:
static const int ENCR_BASE64 = 1 << 0;
static const int ENCR_APPKEY = 1 << 1;
static const int ENCR_PASSWORD = 1 << 2;
-
+
std::map<std::string, RawBuffer> m_keyMap;
- /* TODO: Move it to private/protected after tests (or remove if not needed) */
- CryptoAlgConf cryptAES(RawBuffer &data, const RawBuffer &key,
- const RawBuffer &iv, std::string password);
- void decryptAES(RawBuffer &data, const RawBuffer &key, const RawBuffer &iv,
- std::string password);
+ RawBuffer generateRandIV() const;
+ RawBuffer passwordToKey(const std::string &password,
+ const RawBuffer &salt,
+ size_t keySize) const;
+
+ RawBuffer encryptData(
+ const RawBuffer &data,
+ const RawBuffer &key,
+ const RawBuffer &iv) const;
+
+ RawBuffer decryptData(
+ const RawBuffer &data,
+ const RawBuffer &key,
+ const RawBuffer &iv) const;
+
void decBase64(RawBuffer &data);
void encBase64(RawBuffer &data);
bool equalDigests(RawBuffer &dig1, RawBuffer &dig2);
std::size_t insertDigest(RawBuffer &data, const int dataSize);
- void generateKeysFromPassword(const std::string &password,
- RawBuffer &key, RawBuffer &iv);
void removeDigest(RawBuffer &data, RawBuffer &digest);
};