Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from dscharrer:master #7

Merged
merged 3 commits into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions src/crypto/iteratedhash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,28 @@ class iterated_hash : public checksum_base< iterated_hash<T> > {
typedef typename transform::byte_order byte_order;
static const size_t block_size = transform::block_size;
static const size_t hash_size = transform::hash_size / sizeof(hash_word);
typedef hash_word state_t[hash_size];

void init() { count_lo = count_hi = 0; transform::init(state); }

void update(const char * data, size_t length);

void finalize(char * result);

static void prepare_state(const char * data, size_t count, state_t state) {
transform::init(state);
hash(state, data, count * block_size);
}

void init(const state_t init_state, size_t init_count) {
count_lo = hash_word(init_count * block_size);
count_hi = hash_word(util::safe_right_shift<8 * sizeof(hash_word)>(init_count * block_size));
std::memcpy(state, init_state, sizeof(state));
}

private:

size_t hash(const char * input, size_t length);
static size_t hash(state_t state, const char * input, size_t length);
void pad(size_t last_block_size, char pad_first = '\x80');

hash_word bit_count_hi() const {
Expand All @@ -69,7 +81,7 @@ class iterated_hash : public checksum_base< iterated_hash<T> > {
hash_word bit_count_lo() const { return count_lo << 3; }

char buffer[block_size];
hash_word state[hash_size];
state_t state;

hash_word count_lo, count_hi;

Expand All @@ -91,7 +103,7 @@ void iterated_hash<T>::update(const char * data, size_t length) {
if(num != 0) { // process left over data
if(num + length >= block_size) {
std::memcpy(buffer + num, data, block_size - num);
hash(buffer, block_size);
hash(state, buffer, block_size);
data += (block_size - num);
length -= (block_size - num);
// drop through and do the rest
Expand All @@ -103,7 +115,7 @@ void iterated_hash<T>::update(const char * data, size_t length) {

// now process the input data in blocks of BlockSize bytes and save the leftovers to m_data
if(length >= block_size) {
size_t left_over = hash(data, length);
size_t left_over = hash(state, data, length);
data += (length - left_over);
length = left_over;
}
Expand All @@ -114,7 +126,7 @@ void iterated_hash<T>::update(const char * data, size_t length) {
}

template <class T>
size_t iterated_hash<T>::hash(const char * input, size_t length) {
size_t iterated_hash<T>::hash(hash_word state[hash_size], const char * input, size_t length) {

if(byte_order::native() && util::is_aligned<hash_word>(input)) {

Expand Down Expand Up @@ -157,7 +169,7 @@ void iterated_hash<T>::pad(size_t last_block_size, char pad_first) {
memset(buffer + num, 0, last_block_size - num);
} else {
memset(buffer + num, 0, block_size - num);
hash(buffer, block_size);
hash(state, buffer, block_size);
memset(buffer, 0, last_block_size);
}
}
Expand All @@ -172,7 +184,7 @@ void iterated_hash<T>::finalize(char * result) {
byte_order::store(bit_count_lo(), buffer + size + order);
byte_order::store(bit_count_hi(), buffer + size + sizeof(hash_word) - order);

hash(buffer, block_size);
hash(state, buffer, block_size);

byte_order::store(state, hash_size, result);

Expand Down
30 changes: 16 additions & 14 deletions src/crypto/pbkdf2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,36 +43,35 @@ namespace crypto {
template <typename T>
struct hmac {

typedef typename T::state_t state_t;
enum constants {
block_size = T::block_size,
hash_size = T::hash_size * sizeof(typename T::hash_word),
};

void init(const char ikey[block_size]) {
inner.init();
inner.update(ikey, block_size);
void init(const state_t istate) {
inner.init(istate, 1);
}

void update(const char * data, size_t length) {
inner.update(data, length);
}

void finalize(const char okey[block_size], char mac[hash_size]) {
void finalize(const state_t ostate, char mac[hash_size]) {

char buffer[hash_size];
inner.finalize(buffer);

T outer;
outer.init();
outer.update(okey, block_size);
outer.init(ostate, 1);
outer.update(buffer, hash_size);
outer.finalize(mac);

}

static void prepare_key(const char * password, size_t length,
char ikey[block_size], char okey[block_size]) {
static void prepare_state(const char * password, size_t length, state_t istate, state_t ostate) {

char ikey[block_size], okey[block_size];
if(length > block_size) {
T hash;
hash.init();
Expand All @@ -89,6 +88,9 @@ struct hmac {
ikey[i] = char(boost::uint8_t(ikey[i]) ^ boost::uint8_t(0x36));
}

T::prepare_state(ikey, 1, istate);
T::prepare_state(okey, 1, ostate);

}

private:
Expand All @@ -110,28 +112,28 @@ struct pbkdf2 {
static void derive(const char * password, size_t password_length, const char * salt, size_t salt_length,
size_t iterations, char * key, size_t key_length) {

char ikey[block_size], okey[block_size];
hmac_t::prepare_key(password, password_length, ikey, okey);
typename hmac_t::state_t istate, ostate;
hmac_t::prepare_state(password, password_length, istate, ostate);

for(size_t block = 1; key_length > 0; block++) {

char u[hash_size];
{
char b[4] = { char(block >> 24), char(block >> 16), char(block >> 8), char(block) };
hmac_t mac;
mac.init(ikey);
mac.init(istate);
mac.update(salt, salt_length);
mac.update(b, sizeof(b));
mac.finalize(okey, u);
mac.finalize(ostate, u);
}
char f[hash_size];
std::memcpy(f, u, hash_size);

for(size_t i = 1; i < iterations; i++) {
hmac_t mac;
mac.init(ikey);
mac.init(istate);
mac.update(u, hash_size);
mac.finalize(okey, u);
mac.finalize(ostate, u);
for(size_t j = 0; j < hash_size; j++) {
f[j] = char(boost::uint8_t(f[j]) ^ boost::uint8_t(u[j]));
}
Expand Down
10 changes: 8 additions & 2 deletions src/crypto/xchacha20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,14 @@ void xchacha20::derive_subkey(const char key[key_size], const char nonce[16], ch
state[14] = util::little_endian::load<word>(nonce + 8);
state[15] = util::little_endian::load<word>(nonce + 12);
run_rounds(state);
std::memcpy(subkey, state, 16);
std::memcpy(subkey + 16, state + 12, 16);
util::little_endian::store<word>(state[0], subkey);
util::little_endian::store<word>(state[1], subkey + 4);
util::little_endian::store<word>(state[2], subkey + 8);
util::little_endian::store<word>(state[3], subkey + 12);
util::little_endian::store<word>(state[12], subkey + 16);
util::little_endian::store<word>(state[13], subkey + 20);
util::little_endian::store<word>(state[14], subkey + 24);
util::little_endian::store<word>(state[15], subkey + 28);

}

Expand Down
Loading