Skip to content

Commit

Permalink
Disable copy/move of AES_SIV
Browse files Browse the repository at this point in the history
The CryptoPP classes may not have well defined copy constructor.

Related issues:

* #144
* #137
  • Loading branch information
netheril96 committed Nov 3, 2022
1 parent 65464f6 commit bb7088e
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 21 deletions.
5 changes: 5 additions & 0 deletions sources/crypto.cpp
@@ -1,5 +1,6 @@
#include "crypto.h"
#include "exceptions.h"
#include "lock_guard.h"

#include <cryptopp/aes.h>
#include <cryptopp/gcm.h>
Expand Down Expand Up @@ -112,6 +113,8 @@ void AES_SIV::encrypt_and_authenticate(const void* plaintext,
void* ciphertext,
void* siv)
{
LockGuard<Mutex> lg(m_mutex);

s2v(plaintext, text_len, additional_data, additional_len, siv);
byte modded_iv[AES_SIV::IV_SIZE];
memcpy(modded_iv, siv, AES_SIV::IV_SIZE);
Expand All @@ -132,6 +135,8 @@ bool AES_SIV::decrypt_and_verify(const void* ciphertext,
void* plaintext,
const void* siv)
{
LockGuard<Mutex> lg(m_mutex);

byte temp_iv[AES_SIV::IV_SIZE];
memcpy(temp_iv, siv, AES_SIV::IV_SIZE);
// Clear the 31st and 63rd bits in the IV.
Expand Down
20 changes: 13 additions & 7 deletions sources/crypto.h
@@ -1,5 +1,7 @@
#pragma once

#include "platform.h"

#include <cryptopp/aes.h>
#include <cryptopp/cmac.h>
#include <cryptopp/modes.h>
Expand All @@ -13,8 +15,16 @@ namespace securefs
class AES_SIV
{
private:
CryptoPP::CMAC<CryptoPP::AES> m_cmac;
CryptoPP::CTR_Mode<CryptoPP::AES>::Encryption m_ctr;
Mutex m_mutex;
CryptoPP::CMAC<CryptoPP::AES> m_cmac THREAD_ANNOTATION_GUARDED_BY(m_mutex);
CryptoPP::CTR_Mode<CryptoPP::AES>::Encryption m_ctr THREAD_ANNOTATION_GUARDED_BY(m_mutex);

private:
void s2v(const void* plaintext,
size_t text_len,
const void* additional_data,
size_t additional_len,
void* iv);

public:
static constexpr size_t IV_SIZE = 16;
Expand All @@ -23,11 +33,7 @@ class AES_SIV
explicit AES_SIV(const void* key, size_t size);
~AES_SIV();

void s2v(const void* plaintext,
size_t text_len,
const void* additional_data,
size_t additional_len,
void* iv);
DISABLE_COPY_MOVE(AES_SIV);

void encrypt_and_authenticate(const void* plaintext,
size_t text_len,
Expand Down
26 changes: 13 additions & 13 deletions sources/lite_fs.cpp
Expand Up @@ -31,7 +31,7 @@ namespace lite
unsigned iv_size,
unsigned max_padding_size,
unsigned flags)
: m_name_encryptor(name_key.data(), name_key.size())
: m_name_encryptor(std::make_shared<AES_SIV>(name_key.data(), name_key.size()))
, m_content_key(content_key)
, m_padding_aes(padding_key.data(), padding_key.size())
, m_root(std::move(root))
Expand Down Expand Up @@ -144,7 +144,7 @@ namespace lite
else
{
std::string str = lite::encrypt_path(
m_name_encryptor,
*m_name_encryptor,
transform(path, m_flags & kOptionCaseFoldFileName, m_flags & kOptionNFCFileName)
.get());
if (!preserve_leading_slash && !str.empty() && str[0] == '/')
Expand Down Expand Up @@ -215,7 +215,7 @@ namespace lite
// Resize to actual size
buffer.resize(static_cast<size_t>(link_size));

auto resolved = decrypt_path(m_name_encryptor, buffer);
auto resolved = decrypt_path(*m_name_encryptor, buffer);
buf->st_size = resolved.size();
break;
}
Expand Down Expand Up @@ -300,7 +300,7 @@ namespace lite
auto underbuf = securefs::make_unique_array<char>(max_size);
memset(underbuf.get(), 0, max_size);
m_root->readlink(translate_path(path, false), underbuf.get(), max_size - 1);
std::string resolved = decrypt_path(m_name_encryptor, underbuf.get());
std::string resolved = decrypt_path(*m_name_encryptor, underbuf.get());
size_t copy_size = std::min(resolved.size(), size - 1);
memcpy(buf, resolved.data(), copy_size);
buf[copy_size] = '\0';
Expand Down Expand Up @@ -333,18 +333,18 @@ namespace lite
std::string m_path;
std::unique_ptr<DirectoryTraverser>
m_underlying_traverser THREAD_ANNOTATION_GUARDED_BY(*this);
AES_SIV m_name_encryptor THREAD_ANNOTATION_GUARDED_BY(*this);
std::shared_ptr<AES_SIV> m_name_encryptor;
unsigned m_block_size, m_iv_size;

public:
explicit LiteDirectory(std::string path,
std::unique_ptr<DirectoryTraverser> underlying_traverser,
const AES_SIV& name_encryptor,
std::shared_ptr<AES_SIV> name_encryptor,
unsigned block_size,
unsigned iv_size)
: m_path(std::move(path))
, m_underlying_traverser(std::move(underlying_traverser))
, m_name_encryptor(name_encryptor)
, m_name_encryptor(std::move(name_encryptor))
, m_block_size(block_size)
, m_iv_size(iv_size)
{
Expand Down Expand Up @@ -389,12 +389,12 @@ namespace lite
}
name->assign(decoded_bytes.size() - AES_SIV::IV_SIZE, '\0');
bool success
= m_name_encryptor.decrypt_and_verify(&decoded_bytes[AES_SIV::IV_SIZE],
name->size(),
nullptr,
0,
&(*name)[0],
&decoded_bytes[0]);
= m_name_encryptor->decrypt_and_verify(&decoded_bytes[AES_SIV::IV_SIZE],
name->size(),
nullptr,
0,
&(*name)[0],
&decoded_bytes[0]);
if (!success)
{
WARN_LOG("Skipping filename %s (decrypted to %s) since it fails "
Expand Down
2 changes: 1 addition & 1 deletion sources/lite_fs.h
Expand Up @@ -149,7 +149,7 @@ namespace lite
DISABLE_COPY_MOVE(FileSystem)

private:
AES_SIV m_name_encryptor;
std::shared_ptr<AES_SIV> m_name_encryptor;
key_type m_content_key;
CryptoPP::GCM<CryptoPP::AES>::Encryption m_xattr_enc;
CryptoPP::GCM<CryptoPP::AES>::Decryption m_xattr_dec;
Expand Down

0 comments on commit bb7088e

Please sign in to comment.