diff options
Diffstat (limited to 'src/wrap/sqlite/codec.cpp')
-rw-r--r-- | src/wrap/sqlite/codec.cpp | 208 |
1 files changed, 144 insertions, 64 deletions
diff --git a/src/wrap/sqlite/codec.cpp b/src/wrap/sqlite/codec.cpp index 60c8f6a21..9799b058f 100644 --- a/src/wrap/sqlite/codec.cpp +++ b/src/wrap/sqlite/codec.cpp @@ -13,111 +13,191 @@ Codec::Codec(void *db) InitializeCodec(db); } -Codec::Codec(const Codec& other, void *db) +Codec::Codec(const Codec *other, void *db) { //Only used to copy main db key for an attached db InitializeCodec(db); - m_hasReadKey = other.m_hasReadKey; - m_hasWriteKey = other.m_hasWriteKey; - m_readKey = other.m_readKey; - m_ivReadKey = other.m_ivReadKey; - m_writeKey = other.m_writeKey; - m_ivWriteKey = other.m_ivWriteKey; + m_hasReadKey = other->m_hasReadKey; + m_hasWriteKey = other->m_hasWriteKey; + m_readKey = other->m_readKey; + m_ivReadKey = other->m_ivReadKey; + m_writeKey = other->m_writeKey; + m_ivWriteKey = other->m_ivWriteKey; } -void -Codec::InitializeCodec(void *db) +void Codec::InitializeCodec(void *db) { - bool botanInitialized = false; - Library_State* state = swap_global_state(0); - if(state) - { - botanInitialized = true; - swap_global_state(state); // should return NULL FIXME: what if not? - } - - if (!botanInitialized) - LibraryInitializer::initialize(); - m_hasReadKey = false; m_hasWriteKey = false; m_db = db; - m_encipherFilter = get_cipher(BLOCK_CIPHER_STR, ENCRYPTION); - m_decipherFilter = get_cipher(BLOCK_CIPHER_STR, DECRYPTION); - m_cmac = new MAC_Filter(MAC_STR); - m_encipherPipe.append(m_encipherFilter); - m_decipherPipe.append(m_decipherFilter); - m_macPipe.append(m_cmac); + try + { + m_encipherFilter = get_cipher(BLOCK_CIPHER_STR, ENCRYPTION); + m_decipherFilter = get_cipher(BLOCK_CIPHER_STR, DECRYPTION); + m_cmac = new MAC_Filter(MAC_STR); + m_encipherPipe.append(m_encipherFilter); + m_decipherPipe.append(m_decipherFilter); + m_macPipe.append(m_cmac); + } + catch(Botan::Exception e) + { + m_botanErrorMsg = e.what(); + } } -void -Codec::GenerateWriteKey(const char* userPassword, int passwordLength) +void Codec::GenerateWriteKey(const char *userPassword, int passwordLength) { - PBKDF* pbkdf = get_pbkdf(PBKDF_STR); - pbkdf->set_iterations(PBKDF_ITERATIONS); - pbkdf->change_salt((const byte*)SALT_STR.c_str(), SALT_SIZE); - - SymmetricKey masterKey = - pbkdf->derive_key(KEY_SIZE + IV_DERIVATION_KEY_SIZE, std::string(userPassword, passwordLength)); - - m_writeKey = SymmetricKey(masterKey.bits_of(), KEY_SIZE); - m_ivWriteKey = SymmetricKey(masterKey.bits_of() + KEY_SIZE, IV_DERIVATION_KEY_SIZE); - - m_hasWriteKey = true; + try + { +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,4) + PBKDF *pbkdf = get_pbkdf(PBKDF_STR); + SymmetricKey masterKey = + pbkdf->derive_key(KEY_SIZE + IV_DERIVATION_KEY_SIZE, std::string(userPassword, passwordLength), + (const byte*)SALT_STR.c_str(), SALT_SIZE, PBKDF_ITERATIONS); +#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0) + S2K* s2k = get_s2k(PBKDF_STR); + s2k->set_iterations(PBKDF_ITERATIONS); + s2k->change_salt((const byte*)SALT_STR.c_str(), SALT_SIZE); + + SymmetricKey masterKey = + s2k->derive_key(KEY_SIZE + IV_DERIVATION_KEY_SIZE, std::string(userPassword, passwordLength)); +#else +#error "This code requires botan 1.8 or newer" +#endif + m_writeKey = SymmetricKey(masterKey.bits_of(), KEY_SIZE); + m_ivWriteKey = SymmetricKey(masterKey.bits_of() + KEY_SIZE, IV_DERIVATION_KEY_SIZE); + + m_hasWriteKey = true; + } + catch(Botan::Exception e) + { + m_botanErrorMsg = e.what(); + } } -void -Codec::DropWriteKey() +void Codec::DropWriteKey() { m_hasWriteKey = false; } -void -Codec::SetReadIsWrite() +void Codec::SetReadIsWrite() { m_readKey = m_writeKey; m_ivReadKey = m_ivWriteKey; m_hasReadKey = m_hasWriteKey; } -void -Codec::SetWriteIsRead() +void Codec::SetWriteIsRead() { m_writeKey = m_readKey; m_ivWriteKey = m_ivReadKey; m_hasWriteKey = m_hasReadKey; } -unsigned char * -Codec::Encrypt(int page, unsigned char* data, bool useWriteKey) +unsigned char* Codec::Encrypt(int page, unsigned char *data, bool useWriteKey) { memcpy(m_page, data, m_pageSize); - m_encipherFilter->set_key(useWriteKey ? m_writeKey : m_readKey); - m_encipherFilter->set_iv(GetIVForPage(page, useWriteKey)); - m_encipherPipe.process_msg(m_page, m_pageSize); - m_encipherPipe.read(m_page, m_encipherPipe.remaining(Pipe::LAST_MESSAGE), Pipe::LAST_MESSAGE); + try + { + m_encipherFilter->set_key(useWriteKey ? m_writeKey : m_readKey); + m_encipherFilter->set_iv(GetIVForPage(page, useWriteKey)); + m_encipherPipe.process_msg(m_page, m_pageSize); + m_encipherPipe.read(m_page, m_encipherPipe.remaining(Pipe::LAST_MESSAGE), Pipe::LAST_MESSAGE); + } + catch(Botan::Exception e) + { + m_botanErrorMsg = e.what(); + } return m_page; //return location of newly ciphered data } -void -Codec::Decrypt(int page, unsigned char* data) +void Codec::Decrypt(int page, unsigned char *data) { - m_decipherFilter->set_key(m_readKey); - m_decipherFilter->set_iv(GetIVForPage(page, false)); - m_decipherPipe.process_msg(data, m_pageSize); - m_decipherPipe.read(data, m_decipherPipe.remaining(Pipe::LAST_MESSAGE), Pipe::LAST_MESSAGE); + try + { + m_decipherFilter->set_key(m_readKey); + m_decipherFilter->set_iv(GetIVForPage(page, false)); + m_decipherPipe.process_msg(data, m_pageSize); + m_decipherPipe.read(data, m_decipherPipe.remaining(Pipe::LAST_MESSAGE), Pipe::LAST_MESSAGE); + } + catch(Botan::Exception e) + { + m_botanErrorMsg = e.what(); + } } -InitializationVector -Codec::GetIVForPage(u32bit page, bool useWriteKey) +InitializationVector Codec::GetIVForPage(u32bit page, bool useWriteKey) { - static unsigned char* intiv[4]; - store_le(page, (byte*)intiv); - m_cmac->set_key(useWriteKey ? m_ivWriteKey : m_ivReadKey); - m_macPipe.process_msg((byte*)intiv, 4); - return m_macPipe.read_all(Pipe::LAST_MESSAGE); + try + { + static unsigned char *intiv[4]; + store_le(page, (byte*)intiv); + m_cmac->set_key(useWriteKey ? m_ivWriteKey : m_ivReadKey); + m_macPipe.process_msg((byte*)intiv, 4); + return m_macPipe.read_all(Pipe::LAST_MESSAGE); + } + catch(Botan::Exception e) + { + m_botanErrorMsg = e.what(); + } +} + +const char* Codec::GetAndResetError() +{ + const char *message = m_botanErrorMsg; + m_botanErrorMsg = 0; + return message; } +#include "codec_c_interface.h" + +void InitializeBotan() { + LibraryInitializer::initialize(); +} +void* InitializeNewCodec(void *db) { + return new Codec(db); +} +void* InitializeFromOtherCodec(const void *otherCodec, void *db) { + return new Codec((Codec*)otherCodec, db); +} +void GenerateWriteKey(void *codec, const char *userPassword, int passwordLength) { + ((Codec*)codec)->GenerateWriteKey(userPassword, passwordLength); +} +void DropWriteKey(void *codec) { + ((Codec*)codec)->DropWriteKey(); +} +void SetWriteIsRead(void *codec) { + ((Codec*)codec)->SetWriteIsRead(); +} +void SetReadIsWrite(void *codec) { + ((Codec*)codec)->SetReadIsWrite(); +} +unsigned char* Encrypt(void *codec, int page, unsigned char *data, Bool useWriteKey) { + ((Codec*)codec)->Encrypt(page, data, useWriteKey); +} +void Decrypt(void *codec, int page, unsigned char *data) { + ((Codec*)codec)->Decrypt(page, data); +} +void SetPageSize(void *codec, int pageSize) { + ((Codec*)codec)->SetPageSize(pageSize); +} +Bool HasReadKey(void *codec) { + return ((Codec*)codec)->HasReadKey(); +} +Bool HasWriteKey(void *codec) { + return ((Codec*)codec)->HasWriteKey(); +} +void* GetDB(void *codec) { + return ((Codec*)codec)->GetDB(); +} +const char* GetAndResetError(void *codec) +{ + return ((Codec*)codec)->GetAndResetError(); +} +void DeleteCodec(void *codec) { + Codec *deleteThisCodec = (Codec*)codec; + delete deleteThisCodec; +} |