From 09d4125ff164f5ca686d12ccb0790c35ce721a6b Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 27 Jun 2015 01:15:23 +0200 Subject: Rename axolotlpp as olm to avoid confusion with Axolotl-the-spec and Axolotl-the-OWS-libraries at moxie's request --- src/account.cpp | 88 ++++----- src/axolotl.cpp | 580 -------------------------------------------------------- src/base64.cpp | 10 +- src/cipher.cpp | 46 ++--- src/crypto.cpp | 70 +++---- src/memory.cpp | 6 +- src/message.cpp | 20 +- src/olm.cpp | 580 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pickle.cpp | 38 ++-- src/ratchet.cpp | 258 ++++++++++++------------- src/session.cpp | 170 ++++++++--------- 11 files changed, 933 insertions(+), 933 deletions(-) delete mode 100644 src/axolotl.cpp create mode 100644 src/olm.cpp (limited to 'src') diff --git a/src/account.cpp b/src/account.cpp index cafa014..45e4b6d 100644 --- a/src/account.cpp +++ b/src/account.cpp @@ -12,20 +12,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "axolotl/account.hh" -#include "axolotl/pickle.hh" +#include "olm/account.hh" +#include "olm/pickle.hh" -axolotl::LocalKey const * axolotl::Account::lookup_key( +olm::LocalKey const * olm::Account::lookup_key( std::uint32_t id ) { - for (axolotl::LocalKey const & key : one_time_keys) { + for (olm::LocalKey const & key : one_time_keys) { if (key.id == id) return &key; } return 0; } -std::size_t axolotl::Account::remove_key( +std::size_t olm::Account::remove_key( std::uint32_t id ) { LocalKey * i; @@ -38,34 +38,34 @@ std::size_t axolotl::Account::remove_key( return std::size_t(-1); } -std::size_t axolotl::Account::new_account_random_length() { +std::size_t olm::Account::new_account_random_length() { return 103 * 32; } -std::size_t axolotl::Account::new_account( +std::size_t olm::Account::new_account( uint8_t const * random, std::size_t random_length ) { if (random_length < new_account_random_length()) { - last_error = axolotl::ErrorCode::NOT_ENOUGH_RANDOM; + last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM; return std::size_t(-1); } unsigned id = 0; identity_key.id = ++id; - axolotl::generate_key(random, identity_key.key); + olm::generate_key(random, identity_key.key); random += 32; random += 32; last_resort_one_time_key.id = ++id; - axolotl::generate_key(random, last_resort_one_time_key.key); + olm::generate_key(random, last_resort_one_time_key.key); random += 32; for (unsigned i = 0; i < 10; ++i) { LocalKey & key = *one_time_keys.insert(one_time_keys.end()); key.id = ++id; - axolotl::generate_key(random, key.key); + olm::generate_key(random, key.key); random += 32; } @@ -73,94 +73,94 @@ std::size_t axolotl::Account::new_account( } -namespace axolotl { +namespace olm { static std::size_t pickle_length( - axolotl::LocalKey const & value + olm::LocalKey const & value ) { - return axolotl::pickle_length(value.id) + axolotl::pickle_length(value.key); + return olm::pickle_length(value.id) + olm::pickle_length(value.key); } static std::uint8_t * pickle( std::uint8_t * pos, - axolotl::LocalKey const & value + olm::LocalKey const & value ) { - pos = axolotl::pickle(pos, value.id); - pos = axolotl::pickle(pos, value.key); + pos = olm::pickle(pos, value.id); + pos = olm::pickle(pos, value.key); return pos; } static std::uint8_t const * unpickle( std::uint8_t const * pos, std::uint8_t const * end, - axolotl::LocalKey & value + olm::LocalKey & value ) { - pos = axolotl::unpickle(pos, end, value.id); - pos = axolotl::unpickle(pos, end, value.key); + pos = olm::unpickle(pos, end, value.id); + pos = olm::unpickle(pos, end, value.key); return pos; } static std::size_t pickle_length( - axolotl::SignedKey const & value + olm::SignedKey const & value ) { - return axolotl::pickle_length((axolotl::LocalKey const &) value) + 64; + return olm::pickle_length((olm::LocalKey const &) value) + 64; } static std::uint8_t * pickle( std::uint8_t * pos, - axolotl::SignedKey const & value + olm::SignedKey const & value ) { - pos = axolotl::pickle(pos, (axolotl::LocalKey const &) value); - pos = axolotl::pickle_bytes(pos, value.signature, 64); + pos = olm::pickle(pos, (olm::LocalKey const &) value); + pos = olm::pickle_bytes(pos, value.signature, 64); return pos; } static std::uint8_t const * unpickle( std::uint8_t const * pos, std::uint8_t const * end, - axolotl::SignedKey & value + olm::SignedKey & value ) { - pos = axolotl::unpickle(pos, end, (axolotl::LocalKey &) value); - pos = axolotl::unpickle_bytes(pos, end, value.signature, 64); + pos = olm::unpickle(pos, end, (olm::LocalKey &) value); + pos = olm::unpickle_bytes(pos, end, value.signature, 64); return pos; } -} // namespace axolotl +} // namespace olm -std::size_t axolotl::pickle_length( - axolotl::Account const & value +std::size_t olm::pickle_length( + olm::Account const & value ) { std::size_t length = 0; - length += axolotl::pickle_length(value.identity_key); - length += axolotl::pickle_length(value.last_resort_one_time_key); - length += axolotl::pickle_length(value.one_time_keys); + length += olm::pickle_length(value.identity_key); + length += olm::pickle_length(value.last_resort_one_time_key); + length += olm::pickle_length(value.one_time_keys); return length; } -std::uint8_t * axolotl::pickle( +std::uint8_t * olm::pickle( std::uint8_t * pos, - axolotl::Account const & value + olm::Account const & value ) { - pos = axolotl::pickle(pos, value.identity_key); - pos = axolotl::pickle(pos, value.last_resort_one_time_key); - pos = axolotl::pickle(pos, value.one_time_keys); + pos = olm::pickle(pos, value.identity_key); + pos = olm::pickle(pos, value.last_resort_one_time_key); + pos = olm::pickle(pos, value.one_time_keys); return pos; } -std::uint8_t const * axolotl::unpickle( +std::uint8_t const * olm::unpickle( std::uint8_t const * pos, std::uint8_t const * end, - axolotl::Account & value + olm::Account & value ) { - pos = axolotl::unpickle(pos, end, value.identity_key); - pos = axolotl::unpickle(pos, end, value.last_resort_one_time_key); - pos = axolotl::unpickle(pos, end, value.one_time_keys); + pos = olm::unpickle(pos, end, value.identity_key); + pos = olm::unpickle(pos, end, value.last_resort_one_time_key); + pos = olm::unpickle(pos, end, value.one_time_keys); return pos; } diff --git a/src/axolotl.cpp b/src/axolotl.cpp deleted file mode 100644 index 2586204..0000000 --- a/src/axolotl.cpp +++ /dev/null @@ -1,580 +0,0 @@ -/* Copyright 2015 OpenMarket Ltd - * - * 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 "axolotl/axolotl.hh" -#include "axolotl/session.hh" -#include "axolotl/account.hh" -#include "axolotl/base64.hh" -#include "axolotl/cipher.hh" - -#include -#include - -namespace { - -static AxolotlAccount * to_c(axolotl::Account * account) { - return reinterpret_cast(account); -} - -static AxolotlSession * to_c(axolotl::Session * account) { - return reinterpret_cast(account); -} - -static axolotl::Account * from_c(AxolotlAccount * account) { - return reinterpret_cast(account); -} - -static axolotl::Session * from_c(AxolotlSession * account) { - return reinterpret_cast(account); -} - -static std::uint8_t * from_c(void * bytes) { - return reinterpret_cast(bytes); -} - -static std::uint8_t const * from_c(void const * bytes) { - return reinterpret_cast(bytes); -} - -static const std::uint8_t CIPHER_KDF_INFO[] = "Pickle"; - -static const axolotl::CipherAesSha256 PICKLE_CIPHER( - CIPHER_KDF_INFO, sizeof(CIPHER_KDF_INFO) -1 -); - -std::size_t enc_output_length( - size_t raw_length -) { - std::size_t length = PICKLE_CIPHER.encrypt_ciphertext_length(raw_length); - length += PICKLE_CIPHER.mac_length(); - return axolotl::encode_base64_length(length); -} - - -std::uint8_t * enc_output_pos( - std::uint8_t * output, - size_t raw_length -) { - std::size_t length = PICKLE_CIPHER.encrypt_ciphertext_length(raw_length); - length += PICKLE_CIPHER.mac_length(); - return output + axolotl::encode_base64_length(length) - length; -} - -std::size_t enc_output( - std::uint8_t const * key, std::size_t key_length, - std::uint8_t * output, size_t raw_length -) { - std::size_t ciphertext_length = PICKLE_CIPHER.encrypt_ciphertext_length( - raw_length - ); - std::size_t length = ciphertext_length + PICKLE_CIPHER.mac_length(); - std::size_t base64_length = axolotl::encode_base64_length(length); - std::uint8_t * raw_output = output + base64_length - length; - PICKLE_CIPHER.encrypt( - key, key_length, - raw_output, raw_length, - raw_output, ciphertext_length, - raw_output, length - ); - axolotl::encode_base64(raw_output, length, output); - return raw_length; -} - -std::size_t enc_input( - std::uint8_t const * key, std::size_t key_length, - std::uint8_t * input, size_t b64_length, - axolotl::ErrorCode & last_error -) { - std::size_t enc_length = axolotl::decode_base64_length(b64_length); - if (enc_length == std::size_t(-1)) { - last_error = axolotl::ErrorCode::INVALID_BASE64; - return std::size_t(-1); - } - axolotl::decode_base64(input, b64_length, input); - std::size_t raw_length = enc_length - PICKLE_CIPHER.mac_length(); - std::size_t result = PICKLE_CIPHER.decrypt( - key, key_length, - input, enc_length, - input, raw_length, - input, raw_length - ); - if (result == std::size_t(-1)) { - last_error = axolotl::ErrorCode::BAD_ACCOUNT_KEY; - } - return result; -} - - -std::size_t b64_output_length( - size_t raw_length -) { - return axolotl::encode_base64_length(raw_length); -} - -std::uint8_t * b64_output_pos( - std::uint8_t * output, - size_t raw_length -) { - return output + axolotl::encode_base64_length(raw_length) - raw_length; -} - -std::size_t b64_output( - std::uint8_t * output, size_t raw_length -) { - std::size_t base64_length = axolotl::encode_base64_length(raw_length); - std::uint8_t * raw_output = output + base64_length - raw_length; - axolotl::encode_base64(raw_output, raw_length, output); - return base64_length; -} - -std::size_t b64_input( - std::uint8_t * input, size_t b64_length, - axolotl::ErrorCode & last_error -) { - std::size_t raw_length = axolotl::decode_base64_length(b64_length); - if (raw_length == std::size_t(-1)) { - last_error = axolotl::ErrorCode::INVALID_BASE64; - return std::size_t(-1); - } - axolotl::decode_base64(input, b64_length, input); - return raw_length; -} - -const char * errors[9] { - "SUCCESS", - "NOT_ENOUGH_RANDOM", - "OUTPUT_BUFFER_TOO_SMALL", - "BAD_MESSAGE_VERSION", - "BAD_MESSAGE_FORMAT", - "BAD_MESSAGE_MAC", - "BAD_MESSAGE_KEY_ID", - "INVALID_BASE64", - "BAD_ACCOUNT_KEY", -}; - -} // namespace - - -extern "C" { - - -size_t axolotl_error() { - return std::size_t(-1); -} - - -const char * axolotl_account_last_error( - AxolotlSession * account -) { - unsigned error = unsigned(from_c(account)->last_error); - if (error < 9) { - return errors[error]; - } else { - return "UNKNOWN_ERROR"; - } -} - - -const char * axolotl_session_last_error( - AxolotlSession * session -) { - unsigned error = unsigned(from_c(session)->last_error); - if (error < 9) { - return errors[error]; - } else { - return "UNKNOWN_ERROR"; - } -} - - -size_t axolotl_account_size() { - return sizeof(axolotl::Account); -} - - -size_t axolotl_session_size() { - return sizeof(axolotl::Session); -} - - -AxolotlAccount * axolotl_account( - void * memory -) { - return to_c(new(memory) axolotl::Account()); -} - - -AxolotlSession * axolotl_session( - void * memory -) { - return to_c(new(memory) axolotl::Session()); -} - - -size_t axolotl_pickle_account_length( - AxolotlAccount * account -) { - return enc_output_length(pickle_length(*from_c(account))); -} - - -size_t axolotl_pickle_session_length( - AxolotlSession * session -) { - return enc_output_length(pickle_length(*from_c(session))); -} - - -size_t axolotl_pickle_account( - AxolotlAccount * account, - void const * key, size_t key_length, - void * pickled, size_t pickled_length -) { - axolotl::Account & object = *from_c(account); - std::size_t raw_length = pickle_length(object); - if (pickled_length < enc_output_length(raw_length)) { - object.last_error = axolotl::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; - return size_t(-1); - } - pickle(enc_output_pos(from_c(pickled), raw_length), object); - return enc_output(from_c(key), key_length, from_c(pickled), raw_length); -} - - -size_t axolotl_pickle_session( - AxolotlSession * session, - void const * key, size_t key_length, - void * pickled, size_t pickled_length -) { - axolotl::Session & object = *from_c(session); - std::size_t raw_length = pickle_length(object); - if (pickled_length < enc_output_length(raw_length)) { - object.last_error = axolotl::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; - return size_t(-1); - } - pickle(enc_output_pos(from_c(pickled), raw_length), object); - return enc_output(from_c(key), key_length, from_c(pickled), raw_length); -} - - -size_t axolotl_unpickle_account( - AxolotlAccount * account, - void const * key, size_t key_length, - void * pickled, size_t pickled_length -) { - axolotl::Account & object = *from_c(account); - std::uint8_t * const pos = from_c(pickled); - std::size_t raw_length = enc_input( - from_c(key), key_length, pos, pickled_length, object.last_error - ); - if (raw_length == std::size_t(-1)) { - return std::size_t(-1); - } - std::uint8_t * const end = pos + raw_length; - unpickle(pos, end, object); - return pickled_length; -} - - -size_t axolotl_unpickle_session( - AxolotlSession * session, - void const * key, size_t key_length, - void * pickled, size_t pickled_length -) { - axolotl::Session & object = *from_c(session); - std::uint8_t * const pos = from_c(pickled); - std::size_t raw_length = enc_input( - from_c(key), key_length, pos, pickled_length, object.last_error - ); - if (raw_length == std::size_t(-1)) { - return std::size_t(-1); - } - std::uint8_t * const end = pos + raw_length; - unpickle(pos, end, object); - return pickled_length; -} - - -size_t axolotl_create_account_random_length( - AxolotlAccount * account -) { - return from_c(account)->new_account_random_length(); -} - - -size_t axolotl_create_account( - AxolotlAccount * account, - void const * random, size_t random_length -) { - return from_c(account)->new_account(from_c(random), random_length); -} - -namespace { - -static const std::size_t OUTPUT_KEY_LENGTH = 2 + 10 + 2 + - axolotl::encode_base64_length(32) + 3; - -void output_key( - axolotl::LocalKey const & key, - std::uint8_t sep, - std::uint8_t * output -) { - output[0] = sep; - output[1] = '['; - std::memset(output + 2, ' ', 10); - uint32_t value = key.id; - uint8_t * number = output + 11; - *number = '0' + value % 10; - value /= 10; - while (value) { - *(--number) = '0' + value % 10; - value /= 10; - } - output[12] = ','; - output[13] = '"'; - axolotl::encode_base64(key.key.public_key, 32, output + 14); - output[OUTPUT_KEY_LENGTH - 3] = '"'; - output[OUTPUT_KEY_LENGTH - 2] = ']'; - output[OUTPUT_KEY_LENGTH - 1] = '\n'; -} - -} // namespace - - -size_t axolotl_account_identity_keys_length( - AxolotlAccount * account -) { - return OUTPUT_KEY_LENGTH + 1; -} - - -size_t axolotl_account_identity_keys( - AxolotlAccount * account, - void * identity_keys, size_t identity_key_length -) { - std::size_t length = axolotl_account_identity_keys_length(account); - if (identity_key_length < length) { - from_c(account)->last_error = - axolotl::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; - return size_t(-1); - } - std::uint8_t * output = from_c(identity_keys); - output_key(from_c(account)->identity_key, '[', output); - output += OUTPUT_KEY_LENGTH; - output[0] = ']'; - return length; -} - - -size_t axolotl_account_one_time_keys_length( - AxolotlAccount * account -) { - size_t count = from_c(account)->one_time_keys.size(); - return OUTPUT_KEY_LENGTH * (count + 1) + 1; -} - - -size_t axolotl_account_one_time_keys( - AxolotlAccount * account, - void * identity_keys, size_t identity_key_length -) { - std::size_t length = axolotl_account_one_time_keys_length(account); - if (identity_key_length < length) { - from_c(account)->last_error = - axolotl::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; - return size_t(-1); - } - std::uint8_t * output = from_c(identity_keys); - output_key(from_c(account)->last_resort_one_time_key, '[', output); - output += OUTPUT_KEY_LENGTH; - for (auto const & key : from_c(account)->one_time_keys) { - output_key(key, ',', output); - output += OUTPUT_KEY_LENGTH; - } - output[0] = ']'; - return length; -} - - -size_t axolotl_create_outbound_session_random_length( - AxolotlSession * session -) { - return from_c(session)->new_outbound_session_random_length(); -} - -size_t axolotl_create_outbound_session( - AxolotlSession * session, - AxolotlAccount * account, - void const * their_identity_key, size_t their_identity_key_length, - unsigned their_one_time_key_id, - void const * their_one_time_key, size_t their_one_time_key_length, - void const * random, size_t random_length -) { - if (axolotl::decode_base64_length(their_identity_key_length) != 32 - || axolotl::decode_base64_length(their_one_time_key_length) != 32 - ) { - from_c(session)->last_error = axolotl::ErrorCode::INVALID_BASE64; - return std::size_t(-1); - } - axolotl::Curve25519PublicKey identity_key; - axolotl::RemoteKey one_time_key; - - axolotl::decode_base64( - from_c(their_identity_key), their_identity_key_length, - identity_key.public_key - ); - one_time_key.id = their_one_time_key_id; - axolotl::decode_base64( - from_c(their_one_time_key), their_one_time_key_length, - one_time_key.key.public_key - ); - - return from_c(session)->new_outbound_session( - *from_c(account), identity_key, one_time_key, - from_c(random), random_length - ); -} - - -size_t axolotl_create_inbound_session( - AxolotlSession * session, - AxolotlAccount * account, - void * one_time_key_message, size_t message_length -) { - std::size_t raw_length = b64_input( - from_c(one_time_key_message), message_length, from_c(session)->last_error - ); - if (raw_length == std::size_t(-1)) { - return std::size_t(-1); - } - return from_c(session)->new_inbound_session( - *from_c(account), from_c(one_time_key_message), raw_length - ); -} - - -size_t axolotl_matches_inbound_session( - AxolotlSession * session, - void * one_time_key_message, size_t message_length -) { - std::size_t raw_length = b64_input( - from_c(one_time_key_message), message_length, from_c(session)->last_error - ); - if (raw_length == std::size_t(-1)) { - return std::size_t(-1); - } - bool matches = from_c(session)->matches_inbound_session( - from_c(one_time_key_message), raw_length - ); - return matches ? 1 : 0; -} - - -size_t axolotl_remove_one_time_keys( - AxolotlAccount * account, - AxolotlSession * session -) { - size_t result = from_c(account)->remove_key( - from_c(session)->bob_one_time_key_id - ); - if (result == std::size_t(-1)) { - from_c(account)->last_error = axolotl::ErrorCode::BAD_MESSAGE_KEY_ID; - } - return result; -} - - -size_t axolotl_encrypt_message_type( - AxolotlSession * session -) { - return size_t(from_c(session)->encrypt_message_type()); -} - - -size_t axolotl_encrypt_random_length( - AxolotlSession * session -) { - return from_c(session)->encrypt_random_length(); -} - - -size_t axolotl_encrypt_message_length( - AxolotlSession * session, - size_t plaintext_length -) { - return b64_output_length( - from_c(session)->encrypt_message_length(plaintext_length) - ); -} - - -size_t axolotl_encrypt( - AxolotlSession * session, - void const * plaintext, size_t plaintext_length, - void const * random, size_t random_length, - void * message, size_t message_length -) { - std::size_t raw_length = from_c(session)->encrypt_message_length( - plaintext_length - ); - if (message_length < raw_length) { - from_c(session)->last_error = - axolotl::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; - return std::size_t(-1); - } - from_c(session)->encrypt( - from_c(plaintext), plaintext_length, - from_c(random), random_length, - b64_output_pos(from_c(message), raw_length), raw_length - ); - return b64_output(from_c(message), raw_length); -} - - -size_t axolotl_decrypt_max_plaintext_length( - AxolotlSession * session, - size_t message_type, - void * message, size_t message_length -) { - std::size_t raw_length = b64_input( - from_c(message), message_length, from_c(session)->last_error - ); - if (raw_length == std::size_t(-1)) { - return std::size_t(-1); - } - return from_c(session)->decrypt_max_plaintext_length( - axolotl::MessageType(message_type), from_c(message), raw_length - ); -} - - -size_t axolotl_decrypt( - AxolotlSession * session, - size_t message_type, - void * message, size_t message_length, - void * plaintext, size_t max_plaintext_length -) { - std::size_t raw_length = b64_input( - from_c(message), message_length, from_c(session)->last_error - ); - if (raw_length == std::size_t(-1)) { - return std::size_t(-1); - } - return from_c(session)->decrypt( - axolotl::MessageType(message_type), from_c(message), raw_length, - from_c(plaintext), max_plaintext_length - ); -} - -} diff --git a/src/base64.cpp b/src/base64.cpp index 6fafa44..a8631a1 100644 --- a/src/base64.cpp +++ b/src/base64.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "axolotl/base64.hh" +#include "olm/base64.hh" namespace { @@ -45,14 +45,14 @@ static const std::uint8_t DECODE_BASE64[128] = { } // namespace -std::size_t axolotl::encode_base64_length( +std::size_t olm::encode_base64_length( std::size_t input_length ) { return 4 * ((input_length + 2) / 3) + (input_length + 2) % 3 - 2; } -void axolotl::encode_base64( +void olm::encode_base64( std::uint8_t const * input, std::size_t input_length, std::uint8_t * output ) { @@ -87,7 +87,7 @@ void axolotl::encode_base64( } -std::size_t axolotl::decode_base64_length( +std::size_t olm::decode_base64_length( std::size_t input_length ) { if (input_length % 4 == 1) { @@ -98,7 +98,7 @@ std::size_t axolotl::decode_base64_length( } -void axolotl::decode_base64( +void olm::decode_base64( std::uint8_t const * input, std::size_t input_length, std::uint8_t * output ) { diff --git a/src/cipher.cpp b/src/cipher.cpp index 2d700b1..2202746 100644 --- a/src/cipher.cpp +++ b/src/cipher.cpp @@ -12,12 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "axolotl/cipher.hh" -#include "axolotl/crypto.hh" -#include "axolotl/memory.hh" +#include "olm/cipher.hh" +#include "olm/crypto.hh" +#include "olm/memory.hh" #include -axolotl::Cipher::~Cipher() { +olm::Cipher::~Cipher() { } @@ -26,9 +26,9 @@ namespace { static const std::size_t SHA256_LENGTH = 32; struct DerivedKeys { - axolotl::Aes256Key aes_key; + olm::Aes256Key aes_key; std::uint8_t mac_key[SHA256_LENGTH]; - axolotl::Aes256Iv aes_iv; + olm::Aes256Iv aes_iv; }; @@ -38,7 +38,7 @@ static void derive_keys( DerivedKeys & keys ) { std::uint8_t derived_secrets[80]; - axolotl::hkdf_sha256( + olm::hkdf_sha256( key, key_length, nullptr, 0, kdf_info, kdf_info_length, @@ -47,7 +47,7 @@ static void derive_keys( std::memcpy(keys.aes_key.key, derived_secrets, 32); std::memcpy(keys.mac_key, derived_secrets + 32, 32); std::memcpy(keys.aes_iv.iv, derived_secrets + 64, 16); - axolotl::unset(derived_secrets); + olm::unset(derived_secrets); } static const std::size_t MAC_LENGTH = 8; @@ -55,26 +55,26 @@ static const std::size_t MAC_LENGTH = 8; } // namespace -axolotl::CipherAesSha256::CipherAesSha256( +olm::CipherAesSha256::CipherAesSha256( std::uint8_t const * kdf_info, std::size_t kdf_info_length ) : kdf_info(kdf_info), kdf_info_length(kdf_info_length) { } -std::size_t axolotl::CipherAesSha256::mac_length() const { +std::size_t olm::CipherAesSha256::mac_length() const { return MAC_LENGTH; } -std::size_t axolotl::CipherAesSha256::encrypt_ciphertext_length( +std::size_t olm::CipherAesSha256::encrypt_ciphertext_length( std::size_t plaintext_length ) const { - return axolotl::aes_encrypt_cbc_length(plaintext_length); + return olm::aes_encrypt_cbc_length(plaintext_length); } -std::size_t axolotl::CipherAesSha256::encrypt( +std::size_t olm::CipherAesSha256::encrypt( std::uint8_t const * key, std::size_t key_length, std::uint8_t const * plaintext, std::size_t plaintext_length, std::uint8_t * ciphertext, std::size_t ciphertext_length, @@ -88,28 +88,28 @@ std::size_t axolotl::CipherAesSha256::encrypt( derive_keys(kdf_info, kdf_info_length, key, key_length, keys); - axolotl::aes_encrypt_cbc( + olm::aes_encrypt_cbc( keys.aes_key, keys.aes_iv, plaintext, plaintext_length, ciphertext ); - axolotl::hmac_sha256( + olm::hmac_sha256( keys.mac_key, SHA256_LENGTH, output, output_length - MAC_LENGTH, mac ); std::memcpy(output + output_length - MAC_LENGTH, mac, MAC_LENGTH); - axolotl::unset(keys); + olm::unset(keys); return output_length; } -std::size_t axolotl::CipherAesSha256::decrypt_max_plaintext_length( +std::size_t olm::CipherAesSha256::decrypt_max_plaintext_length( std::size_t ciphertext_length ) const { return ciphertext_length; } -std::size_t axolotl::CipherAesSha256::decrypt( +std::size_t olm::CipherAesSha256::decrypt( std::uint8_t const * key, std::size_t key_length, std::uint8_t const * input, std::size_t input_length, std::uint8_t const * ciphertext, std::size_t ciphertext_length, @@ -120,20 +120,20 @@ std::size_t axolotl::CipherAesSha256::decrypt( derive_keys(kdf_info, kdf_info_length, key, key_length, keys); - axolotl::hmac_sha256( + olm::hmac_sha256( keys.mac_key, SHA256_LENGTH, input, input_length - MAC_LENGTH, mac ); std::uint8_t const * input_mac = input + input_length - MAC_LENGTH; - if (!axolotl::is_equal(input_mac, mac, MAC_LENGTH)) { - axolotl::unset(keys); + if (!olm::is_equal(input_mac, mac, MAC_LENGTH)) { + olm::unset(keys); return std::size_t(-1); } - std::size_t plaintext_length = axolotl::aes_decrypt_cbc( + std::size_t plaintext_length = olm::aes_decrypt_cbc( keys.aes_key, keys.aes_iv, ciphertext, ciphertext_length, plaintext ); - axolotl::unset(keys); + olm::unset(keys); return plaintext_length; } diff --git a/src/crypto.cpp b/src/crypto.cpp index b287919..ebe4724 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "axolotl/crypto.hh" -#include "axolotl/memory.hh" +#include "olm/crypto.hh" +#include "olm/memory.hh" #include @@ -110,7 +110,7 @@ inline void hmac_sha256_init( } ::sha256_init(context); ::sha256_update(context, i_pad, SHA256_BLOCK_LENGTH); - axolotl::unset(i_pad); + olm::unset(i_pad); } @@ -129,16 +129,16 @@ inline void hmac_sha256_final( ::sha256_init(&final_context); ::sha256_update(&final_context, o_pad, sizeof(o_pad)); ::sha256_final(&final_context, output); - axolotl::unset(final_context); - axolotl::unset(o_pad); + olm::unset(final_context); + olm::unset(o_pad); } } // namespace -void axolotl::generate_key( +void olm::generate_key( std::uint8_t const * random_32_bytes, - axolotl::Curve25519KeyPair & key_pair + olm::Curve25519KeyPair & key_pair ) { std::memcpy(key_pair.private_key, random_32_bytes, 32); ::curve25519_donna( @@ -147,17 +147,17 @@ void axolotl::generate_key( } -void axolotl::curve25519_shared_secret( - axolotl::Curve25519KeyPair const & our_key, - axolotl::Curve25519PublicKey const & their_key, +void olm::curve25519_shared_secret( + olm::Curve25519KeyPair const & our_key, + olm::Curve25519PublicKey const & their_key, std::uint8_t * output ) { ::curve25519_donna(output, our_key.private_key, their_key.public_key); } -void axolotl::curve25519_sign( - axolotl::Curve25519KeyPair const & our_key, +void olm::curve25519_sign( + olm::Curve25519KeyPair const & our_key, std::uint8_t const * message, std::size_t message_length, std::uint8_t * output ) { @@ -174,8 +174,8 @@ void axolotl::curve25519_sign( } -bool axolotl::curve25519_verify( - axolotl::Curve25519PublicKey const & their_key, +bool olm::curve25519_verify( + olm::Curve25519PublicKey const & their_key, std::uint8_t const * message, std::size_t message_length, std::uint8_t const * signature ) { @@ -191,16 +191,16 @@ bool axolotl::curve25519_verify( ); } -std::size_t axolotl::aes_encrypt_cbc_length( +std::size_t olm::aes_encrypt_cbc_length( std::size_t input_length ) { return input_length + AES_BLOCK_LENGTH - input_length % AES_BLOCK_LENGTH; } -void axolotl::aes_encrypt_cbc( - axolotl::Aes256Key const & key, - axolotl::Aes256Iv const & iv, +void olm::aes_encrypt_cbc( + olm::Aes256Key const & key, + olm::Aes256Iv const & iv, std::uint8_t const * input, std::size_t input_length, std::uint8_t * output ) { @@ -224,14 +224,14 @@ void axolotl::aes_encrypt_cbc( input_block[i] ^= AES_BLOCK_LENGTH - input_length; } ::aes_encrypt(input_block, output, key_schedule, 256); - axolotl::unset(key_schedule); - axolotl::unset(input_block); + olm::unset(key_schedule); + olm::unset(input_block); } -std::size_t axolotl::aes_decrypt_cbc( - axolotl::Aes256Key const & key, - axolotl::Aes256Iv const & iv, +std::size_t olm::aes_decrypt_cbc( + olm::Aes256Key const & key, + olm::Aes256Iv const & iv, std::uint8_t const * input, std::size_t input_length, std::uint8_t * output ) { @@ -246,15 +246,15 @@ std::size_t axolotl::aes_decrypt_cbc( xor_block(&output[i], block1); std::memcpy(block1, block2, AES_BLOCK_LENGTH); } - axolotl::unset(key_schedule); - axolotl::unset(block1); - axolotl::unset(block2); + olm::unset(key_schedule); + olm::unset(block1); + olm::unset(block2); std::size_t padding = output[input_length - 1]; return (padding > input_length) ? std::size_t(-1) : (input_length - padding); } -void axolotl::sha256( +void olm::sha256( std::uint8_t const * input, std::size_t input_length, std::uint8_t * output ) { @@ -262,10 +262,10 @@ void axolotl::sha256( ::sha256_init(&context); ::sha256_update(&context, input, input_length); ::sha256_final(&context, output); - axolotl::unset(context); + olm::unset(context); } -void axolotl::hmac_sha256( +void olm::hmac_sha256( std::uint8_t const * key, std::size_t key_length, std::uint8_t const * input, std::size_t input_length, std::uint8_t * output @@ -276,12 +276,12 @@ void axolotl::hmac_sha256( hmac_sha256_init(&context, hmac_key); ::sha256_update(&context, input, input_length); hmac_sha256_final(&context, hmac_key, output); - axolotl::unset(hmac_key); - axolotl::unset(context); + olm::unset(hmac_key); + olm::unset(context); } -void axolotl::hkdf_sha256( +void olm::hkdf_sha256( std::uint8_t const * input, std::size_t input_length, std::uint8_t const * salt, std::size_t salt_length, std::uint8_t const * info, std::size_t info_length, @@ -320,7 +320,7 @@ void axolotl::hkdf_sha256( hmac_sha256_final(&context, hmac_key, step_result); } std::memcpy(output, step_result, bytes_remaining); - axolotl::unset(context); - axolotl::unset(hmac_key); - axolotl::unset(step_result); + olm::unset(context); + olm::unset(hmac_key); + olm::unset(step_result); } diff --git a/src/memory.cpp b/src/memory.cpp index deb3076..16a4683 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -12,10 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "axolotl/memory.hh" +#include "olm/memory.hh" -void axolotl::unset( +void olm::unset( void volatile * buffer, std::size_t buffer_length ) { char volatile * pos = reinterpret_cast(buffer); @@ -26,7 +26,7 @@ void axolotl::unset( } -bool axolotl::is_equal( +bool olm::is_equal( std::uint8_t const * buffer_a, std::uint8_t const * buffer_b, std::size_t length diff --git a/src/message.cpp b/src/message.cpp index 343b094..af43916 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "axolotl/message.hh" +#include "olm/message.hh" namespace { @@ -161,7 +161,7 @@ std::uint8_t const * skip_unknown( } // namespace -std::size_t axolotl::encode_message_length( +std::size_t olm::encode_message_length( std::uint32_t counter, std::size_t ratchet_key_length, std::size_t ciphertext_length, @@ -176,8 +176,8 @@ std::size_t axolotl::encode_message_length( } -void axolotl::encode_message( - axolotl::MessageWriter & writer, +void olm::encode_message( + olm::MessageWriter & writer, std::uint8_t version, std::uint32_t counter, std::size_t ratchet_key_length, @@ -192,8 +192,8 @@ void axolotl::encode_message( } -void axolotl::decode_message( - axolotl::MessageReader & reader, +void olm::decode_message( + olm::MessageReader & reader, std::uint8_t const * input, std::size_t input_length, std::size_t mac_length ) { @@ -240,7 +240,7 @@ static std::uint8_t const MESSAGE_TAG = 042; } // namespace -std::size_t axolotl::encode_one_time_key_message_length( +std::size_t olm::encode_one_time_key_message_length( std::uint32_t one_time_key_id, std::size_t identity_key_length, std::size_t base_key_length, @@ -255,8 +255,8 @@ std::size_t axolotl::encode_one_time_key_message_length( } -void axolotl::encode_one_time_key_message( - axolotl::PreKeyMessageWriter & writer, +void olm::encode_one_time_key_message( + olm::PreKeyMessageWriter & writer, std::uint8_t version, std::uint32_t one_time_key_id, std::size_t identity_key_length, @@ -273,7 +273,7 @@ void axolotl::encode_one_time_key_message( } -void axolotl::decode_one_time_key_message( +void olm::decode_one_time_key_message( PreKeyMessageReader & reader, std::uint8_t const * input, std::size_t input_length ) { diff --git a/src/olm.cpp b/src/olm.cpp new file mode 100644 index 0000000..f5425fa --- /dev/null +++ b/src/olm.cpp @@ -0,0 +1,580 @@ +/* Copyright 2015 OpenMarket Ltd + * + * 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 "olm/olm.hh" +#include "olm/session.hh" +#include "olm/account.hh" +#include "olm/base64.hh" +#include "olm/cipher.hh" + +#include +#include + +namespace { + +static OlmAccount * to_c(olm::Account * account) { + return reinterpret_cast(account); +} + +static OlmSession * to_c(olm::Session * account) { + return reinterpret_cast(account); +} + +static olm::Account * from_c(OlmAccount * account) { + return reinterpret_cast(account); +} + +static olm::Session * from_c(OlmSession * account) { + return reinterpret_cast(account); +} + +static std::uint8_t * from_c(void * bytes) { + return reinterpret_cast(bytes); +} + +static std::uint8_t const * from_c(void const * bytes) { + return reinterpret_cast(bytes); +} + +static const std::uint8_t CIPHER_KDF_INFO[] = "Pickle"; + +static const olm::CipherAesSha256 PICKLE_CIPHER( + CIPHER_KDF_INFO, sizeof(CIPHER_KDF_INFO) -1 +); + +std::size_t enc_output_length( + size_t raw_length +) { + std::size_t length = PICKLE_CIPHER.encrypt_ciphertext_length(raw_length); + length += PICKLE_CIPHER.mac_length(); + return olm::encode_base64_length(length); +} + + +std::uint8_t * enc_output_pos( + std::uint8_t * output, + size_t raw_length +) { + std::size_t length = PICKLE_CIPHER.encrypt_ciphertext_length(raw_length); + length += PICKLE_CIPHER.mac_length(); + return output + olm::encode_base64_length(length) - length; +} + +std::size_t enc_output( + std::uint8_t const * key, std::size_t key_length, + std::uint8_t * output, size_t raw_length +) { + std::size_t ciphertext_length = PICKLE_CIPHER.encrypt_ciphertext_length( + raw_length + ); + std::size_t length = ciphertext_length + PICKLE_CIPHER.mac_length(); + std::size_t base64_length = olm::encode_base64_length(length); + std::uint8_t * raw_output = output + base64_length - length; + PICKLE_CIPHER.encrypt( + key, key_length, + raw_output, raw_length, + raw_output, ciphertext_length, + raw_output, length + ); + olm::encode_base64(raw_output, length, output); + return raw_length; +} + +std::size_t enc_input( + std::uint8_t const * key, std::size_t key_length, + std::uint8_t * input, size_t b64_length, + olm::ErrorCode & last_error +) { + std::size_t enc_length = olm::decode_base64_length(b64_length); + if (enc_length == std::size_t(-1)) { + last_error = olm::ErrorCode::INVALID_BASE64; + return std::size_t(-1); + } + olm::decode_base64(input, b64_length, input); + std::size_t raw_length = enc_length - PICKLE_CIPHER.mac_length(); + std::size_t result = PICKLE_CIPHER.decrypt( + key, key_length, + input, enc_length, + input, raw_length, + input, raw_length + ); + if (result == std::size_t(-1)) { + last_error = olm::ErrorCode::BAD_ACCOUNT_KEY; + } + return result; +} + + +std::size_t b64_output_length( + size_t raw_length +) { + return olm::encode_base64_length(raw_length); +} + +std::uint8_t * b64_output_pos( + std::uint8_t * output, + size_t raw_length +) { + return output + olm::encode_base64_length(raw_length) - raw_length; +} + +std::size_t b64_output( + std::uint8_t * output, size_t raw_length +) { + std::size_t base64_length = olm::encode_base64_length(raw_length); + std::uint8_t * raw_output = output + base64_length - raw_length; + olm::encode_base64(raw_output, raw_length, output); + return base64_length; +} + +std::size_t b64_input( + std::uint8_t * input, size_t b64_length, + olm::ErrorCode & last_error +) { + std::size_t raw_length = olm::decode_base64_length(b64_length); + if (raw_length == std::size_t(-1)) { + last_error = olm::ErrorCode::INVALID_BASE64; + return std::size_t(-1); + } + olm::decode_base64(input, b64_length, input); + return raw_length; +} + +const char * errors[9] { + "SUCCESS", + "NOT_ENOUGH_RANDOM", + "OUTPUT_BUFFER_TOO_SMALL", + "BAD_MESSAGE_VERSION", + "BAD_MESSAGE_FORMAT", + "BAD_MESSAGE_MAC", + "BAD_MESSAGE_KEY_ID", + "INVALID_BASE64", + "BAD_ACCOUNT_KEY", +}; + +} // namespace + + +extern "C" { + + +size_t olm_error() { + return std::size_t(-1); +} + + +const char * olm_account_last_error( + OlmSession * account +) { + unsigned error = unsigned(from_c(account)->last_error); + if (error < 9) { + return errors[error]; + } else { + return "UNKNOWN_ERROR"; + } +} + + +const char * olm_session_last_error( + OlmSession * session +) { + unsigned error = unsigned(from_c(session)->last_error); + if (error < 9) { + return errors[error]; + } else { + return "UNKNOWN_ERROR"; + } +} + + +size_t olm_account_size() { + return sizeof(olm::Account); +} + + +size_t olm_session_size() { + return sizeof(olm::Session); +} + + +OlmAccount * olm_account( + void * memory +) { + return to_c(new(memory) olm::Account()); +} + + +OlmSession * olm_session( + void * memory +) { + return to_c(new(memory) olm::Session()); +} + + +size_t olm_pickle_account_length( + OlmAccount * account +) { + return enc_output_length(pickle_length(*from_c(account))); +} + + +size_t olm_pickle_session_length( + OlmSession * session +) { + return enc_output_length(pickle_length(*from_c(session))); +} + + +size_t olm_pickle_account( + OlmAccount * account, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +) { + olm::Account & object = *from_c(account); + std::size_t raw_length = pickle_length(object); + if (pickled_length < enc_output_length(raw_length)) { + object.last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + return size_t(-1); + } + pickle(enc_output_pos(from_c(pickled), raw_length), object); + return enc_output(from_c(key), key_length, from_c(pickled), raw_length); +} + + +size_t olm_pickle_session( + OlmSession * session, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +) { + olm::Session & object = *from_c(session); + std::size_t raw_length = pickle_length(object); + if (pickled_length < enc_output_length(raw_length)) { + object.last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + return size_t(-1); + } + pickle(enc_output_pos(from_c(pickled), raw_length), object); + return enc_output(from_c(key), key_length, from_c(pickled), raw_length); +} + + +size_t olm_unpickle_account( + OlmAccount * account, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +) { + olm::Account & object = *from_c(account); + std::uint8_t * const pos = from_c(pickled); + std::size_t raw_length = enc_input( + from_c(key), key_length, pos, pickled_length, object.last_error + ); + if (raw_length == std::size_t(-1)) { + return std::size_t(-1); + } + std::uint8_t * const end = pos + raw_length; + unpickle(pos, end, object); + return pickled_length; +} + + +size_t olm_unpickle_session( + OlmSession * session, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +) { + olm::Session & object = *from_c(session); + std::uint8_t * const pos = from_c(pickled); + std::size_t raw_length = enc_input( + from_c(key), key_length, pos, pickled_length, object.last_error + ); + if (raw_length == std::size_t(-1)) { + return std::size_t(-1); + } + std::uint8_t * const end = pos + raw_length; + unpickle(pos, end, object); + return pickled_length; +} + + +size_t olm_create_account_random_length( + OlmAccount * account +) { + return from_c(account)->new_account_random_length(); +} + + +size_t olm_create_account( + OlmAccount * account, + void const * random, size_t random_length +) { + return from_c(account)->new_account(from_c(random), random_length); +} + +namespace { + +static const std::size_t OUTPUT_KEY_LENGTH = 2 + 10 + 2 + + olm::encode_base64_length(32) + 3; + +void output_key( + olm::LocalKey const & key, + std::uint8_t sep, + std::uint8_t * output +) { + output[0] = sep; + output[1] = '['; + std::memset(output + 2, ' ', 10); + uint32_t value = key.id; + uint8_t * number = output + 11; + *number = '0' + value % 10; + value /= 10; + while (value) { + *(--number) = '0' + value % 10; + value /= 10; + } + output[12] = ','; + output[13] = '"'; + olm::encode_base64(key.key.public_key, 32, output + 14); + output[OUTPUT_KEY_LENGTH - 3] = '"'; + output[OUTPUT_KEY_LENGTH - 2] = ']'; + output[OUTPUT_KEY_LENGTH - 1] = '\n'; +} + +} // namespace + + +size_t olm_account_identity_keys_length( + OlmAccount * account +) { + return OUTPUT_KEY_LENGTH + 1; +} + + +size_t olm_account_identity_keys( + OlmAccount * account, + void * identity_keys, size_t identity_key_length +) { + std::size_t length = olm_account_identity_keys_length(account); + if (identity_key_length < length) { + from_c(account)->last_error = + olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + return size_t(-1); + } + std::uint8_t * output = from_c(identity_keys); + output_key(from_c(account)->identity_key, '[', output); + output += OUTPUT_KEY_LENGTH; + output[0] = ']'; + return length; +} + + +size_t olm_account_one_time_keys_length( + OlmAccount * account +) { + size_t count = from_c(account)->one_time_keys.size(); + return OUTPUT_KEY_LENGTH * (count + 1) + 1; +} + + +size_t olm_account_one_time_keys( + OlmAccount * account, + void * identity_keys, size_t identity_key_length +) { + std::size_t length = olm_account_one_time_keys_length(account); + if (identity_key_length < length) { + from_c(account)->last_error = + olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + return size_t(-1); + } + std::uint8_t * output = from_c(identity_keys); + output_key(from_c(account)->last_resort_one_time_key, '[', output); + output += OUTPUT_KEY_LENGTH; + for (auto const & key : from_c(account)->one_time_keys) { + output_key(key, ',', output); + output += OUTPUT_KEY_LENGTH; + } + output[0] = ']'; + return length; +} + + +size_t olm_create_outbound_session_random_length( + OlmSession * session +) { + return from_c(session)->new_outbound_session_random_length(); +} + +size_t olm_create_outbound_session( + OlmSession * session, + OlmAccount * account, + void const * their_identity_key, size_t their_identity_key_length, + unsigned their_one_time_key_id, + void const * their_one_time_key, size_t their_one_time_key_length, + void const * random, size_t random_length +) { + if (olm::decode_base64_length(their_identity_key_length) != 32 + || olm::decode_base64_length(their_one_time_key_length) != 32 + ) { + from_c(session)->last_error = olm::ErrorCode::INVALID_BASE64; + return std::size_t(-1); + } + olm::Curve25519PublicKey identity_key; + olm::RemoteKey one_time_key; + + olm::decode_base64( + from_c(their_identity_key), their_identity_key_length, + identity_key.public_key + ); + one_time_key.id = their_one_time_key_id; + olm::decode_base64( + from_c(their_one_time_key), their_one_time_key_length, + one_time_key.key.public_key + ); + + return from_c(session)->new_outbound_session( + *from_c(account), identity_key, one_time_key, + from_c(random), random_length + ); +} + + +size_t olm_create_inbound_session( + OlmSession * session, + OlmAccount * account, + void * one_time_key_message, size_t message_length +) { + std::size_t raw_length = b64_input( + from_c(one_time_key_message), message_length, from_c(session)->last_error + ); + if (raw_length == std::size_t(-1)) { + return std::size_t(-1); + } + return from_c(session)->new_inbound_session( + *from_c(account), from_c(one_time_key_message), raw_length + ); +} + + +size_t olm_matches_inbound_session( + OlmSession * session, + void * one_time_key_message, size_t message_length +) { + std::size_t raw_length = b64_input( + from_c(one_time_key_message), message_length, from_c(session)->last_error + ); + if (raw_length == std::size_t(-1)) { + return std::size_t(-1); + } + bool matches = from_c(session)->matches_inbound_session( + from_c(one_time_key_message), raw_length + ); + return matches ? 1 : 0; +} + + +size_t olm_remove_one_time_keys( + OlmAccount * account, + OlmSession * session +) { + size_t result = from_c(account)->remove_key( + from_c(session)->bob_one_time_key_id + ); + if (result == std::size_t(-1)) { + from_c(account)->last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID; + } + return result; +} + + +size_t olm_encrypt_message_type( + OlmSession * session +) { + return size_t(from_c(session)->encrypt_message_type()); +} + + +size_t olm_encrypt_random_length( + OlmSession * session +) { + return from_c(session)->encrypt_random_length(); +} + + +size_t olm_encrypt_message_length( + OlmSession * session, + size_t plaintext_length +) { + return b64_output_length( + from_c(session)->encrypt_message_length(plaintext_length) + ); +} + + +size_t olm_encrypt( + OlmSession * session, + void const * plaintext, size_t plaintext_length, + void const * random, size_t random_length, + void * message, size_t message_length +) { + std::size_t raw_length = from_c(session)->encrypt_message_length( + plaintext_length + ); + if (message_length < raw_length) { + from_c(session)->last_error = + olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + return std::size_t(-1); + } + from_c(session)->encrypt( + from_c(plaintext), plaintext_length, + from_c(random), random_length, + b64_output_pos(from_c(message), raw_length), raw_length + ); + return b64_output(from_c(message), raw_length); +} + + +size_t olm_decrypt_max_plaintext_length( + OlmSession * session, + size_t message_type, + void * message, size_t message_length +) { + std::size_t raw_length = b64_input( + from_c(message), message_length, from_c(session)->last_error + ); + if (raw_length == std::size_t(-1)) { + return std::size_t(-1); + } + return from_c(session)->decrypt_max_plaintext_length( + olm::MessageType(message_type), from_c(message), raw_length + ); +} + + +size_t olm_decrypt( + OlmSession * session, + size_t message_type, + void * message, size_t message_length, + void * plaintext, size_t max_plaintext_length +) { + std::size_t raw_length = b64_input( + from_c(message), message_length, from_c(session)->last_error + ); + if (raw_length == std::size_t(-1)) { + return std::size_t(-1); + } + return from_c(session)->decrypt( + olm::MessageType(message_type), from_c(message), raw_length, + from_c(plaintext), max_plaintext_length + ); +} + +} diff --git a/src/pickle.cpp b/src/pickle.cpp index 1597326..3aa64ed 100644 --- a/src/pickle.cpp +++ b/src/pickle.cpp @@ -12,32 +12,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "axolotl/pickle.hh" +#include "olm/pickle.hh" -std::size_t axolotl::pickle_length( - const axolotl::Curve25519PublicKey & value +std::size_t olm::pickle_length( + const olm::Curve25519PublicKey & value ) { return sizeof(value.public_key); } -std::uint8_t * axolotl::pickle( +std::uint8_t * olm::pickle( std::uint8_t * pos, - const axolotl::Curve25519PublicKey & value + const olm::Curve25519PublicKey & value ) { - pos = axolotl::pickle_bytes( + pos = olm::pickle_bytes( pos, value.public_key, sizeof(value.public_key) ); return pos; } -std::uint8_t const * axolotl::unpickle( +std::uint8_t const * olm::unpickle( std::uint8_t const * pos, std::uint8_t const * end, - axolotl::Curve25519PublicKey & value + olm::Curve25519PublicKey & value ) { - pos = axolotl::unpickle_bytes( + pos = olm::unpickle_bytes( pos, end, value.public_key, sizeof(value.public_key) ); return pos; @@ -45,35 +45,35 @@ std::uint8_t const * axolotl::unpickle( } -std::size_t axolotl::pickle_length( - const axolotl::Curve25519KeyPair & value +std::size_t olm::pickle_length( + const olm::Curve25519KeyPair & value ) { return sizeof(value.public_key) + sizeof(value.private_key); } -std::uint8_t * axolotl::pickle( +std::uint8_t * olm::pickle( std::uint8_t * pos, - const axolotl::Curve25519KeyPair & value + const olm::Curve25519KeyPair & value ) { - pos = axolotl::pickle_bytes( + pos = olm::pickle_bytes( pos, value.public_key, sizeof(value.public_key) ); - pos = axolotl::pickle_bytes( + pos = olm::pickle_bytes( pos, value.private_key, sizeof(value.private_key) ); return pos; } -std::uint8_t const * axolotl::unpickle( +std::uint8_t const * olm::unpickle( std::uint8_t const * pos, std::uint8_t const * end, - axolotl::Curve25519KeyPair & value + olm::Curve25519KeyPair & value ) { - pos = axolotl::unpickle_bytes( + pos = olm::unpickle_bytes( pos, end, value.public_key, sizeof(value.public_key) ); - pos = axolotl::unpickle_bytes( + pos = olm::unpickle_bytes( pos, end, value.private_key, sizeof(value.private_key) ); return pos; diff --git a/src/ratchet.cpp b/src/ratchet.cpp index 37d2d4e..2f361fa 100644 --- a/src/ratchet.cpp +++ b/src/ratchet.cpp @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "axolotl/ratchet.hh" -#include "axolotl/message.hh" -#include "axolotl/memory.hh" -#include "axolotl/cipher.hh" -#include "axolotl/pickle.hh" +#include "olm/ratchet.hh" +#include "olm/message.hh" +#include "olm/memory.hh" +#include "olm/cipher.hh" +#include "olm/pickle.hh" #include @@ -24,23 +24,23 @@ namespace { std::uint8_t PROTOCOL_VERSION = 3; -std::size_t KEY_LENGTH = axolotl::Curve25519PublicKey::LENGTH; +std::size_t KEY_LENGTH = olm::Curve25519PublicKey::LENGTH; std::uint8_t MESSAGE_KEY_SEED[1] = {0x01}; std::uint8_t CHAIN_KEY_SEED[1] = {0x02}; std::size_t MAX_MESSAGE_GAP = 2000; void create_chain_key( - axolotl::SharedKey const & root_key, - axolotl::Curve25519KeyPair const & our_key, - axolotl::Curve25519PublicKey const & their_key, - axolotl::KdfInfo const & info, - axolotl::SharedKey & new_root_key, - axolotl::ChainKey & new_chain_key + olm::SharedKey const & root_key, + olm::Curve25519KeyPair const & our_key, + olm::Curve25519PublicKey const & their_key, + olm::KdfInfo const & info, + olm::SharedKey & new_root_key, + olm::ChainKey & new_chain_key ) { - axolotl::SharedKey secret; - axolotl::curve25519_shared_secret(our_key, their_key, secret); + olm::SharedKey secret; + olm::curve25519_shared_secret(our_key, their_key, secret); std::uint8_t derived_secrets[64]; - axolotl::hkdf_sha256( + olm::hkdf_sha256( secret, sizeof(secret), root_key, sizeof(root_key), info.ratchet_info, info.ratchet_info_length, @@ -49,16 +49,16 @@ void create_chain_key( std::memcpy(new_root_key, derived_secrets, 32); std::memcpy(new_chain_key.key, derived_secrets + 32, 32); new_chain_key.index = 0; - axolotl::unset(derived_secrets); - axolotl::unset(secret); + olm::unset(derived_secrets); + olm::unset(secret); } void advance_chain_key( - axolotl::ChainKey const & chain_key, - axolotl::ChainKey & new_chain_key + olm::ChainKey const & chain_key, + olm::ChainKey & new_chain_key ) { - axolotl::hmac_sha256( + olm::hmac_sha256( chain_key.key, sizeof(chain_key.key), CHAIN_KEY_SEED, sizeof(CHAIN_KEY_SEED), new_chain_key.key @@ -68,11 +68,11 @@ void advance_chain_key( void create_message_keys( - axolotl::ChainKey const & chain_key, - axolotl::KdfInfo const & info, - axolotl::MessageKey & message_key + olm::ChainKey const & chain_key, + olm::KdfInfo const & info, + olm::MessageKey & message_key ) { - axolotl::hmac_sha256( + olm::hmac_sha256( chain_key.key, sizeof(chain_key.key), MESSAGE_KEY_SEED, sizeof(MESSAGE_KEY_SEED), message_key.key @@ -82,9 +82,9 @@ void create_message_keys( std::size_t verify_mac_and_decrypt( - axolotl::Cipher const & cipher, - axolotl::MessageKey const & message_key, - axolotl::MessageReader const & reader, + olm::Cipher const & cipher, + olm::MessageKey const & message_key, + olm::MessageReader const & reader, std::uint8_t * plaintext, std::size_t max_plaintext_length ) { return cipher.decrypt( @@ -97,9 +97,9 @@ std::size_t verify_mac_and_decrypt( std::size_t verify_mac_and_decrypt_for_existing_chain( - axolotl::Ratchet const & session, - axolotl::ChainKey const & chain, - axolotl::MessageReader const & reader, + olm::Ratchet const & session, + olm::ChainKey const & chain, + olm::MessageReader const & reader, std::uint8_t * plaintext, std::size_t max_plaintext_length ) { if (reader.counter < chain.index) { @@ -111,13 +111,13 @@ std::size_t verify_mac_and_decrypt_for_existing_chain( return std::size_t(-1); } - axolotl::ChainKey new_chain = chain; + olm::ChainKey new_chain = chain; while (new_chain.index < reader.counter) { advance_chain_key(new_chain, new_chain); } - axolotl::MessageKey message_key; + olm::MessageKey message_key; create_message_keys(new_chain, session.kdf_info, message_key); std::size_t result = verify_mac_and_decrypt( @@ -125,18 +125,18 @@ std::size_t verify_mac_and_decrypt_for_existing_chain( plaintext, max_plaintext_length ); - axolotl::unset(new_chain); + olm::unset(new_chain); return result; } std::size_t verify_mac_and_decrypt_for_new_chain( - axolotl::Ratchet const & session, - axolotl::MessageReader const & reader, + olm::Ratchet const & session, + olm::MessageReader const & reader, std::uint8_t * plaintext, std::size_t max_plaintext_length ) { - axolotl::SharedKey new_root_key; - axolotl::ReceiverChain new_chain; + olm::SharedKey new_root_key; + olm::ReceiverChain new_chain; /* They shouldn't move to a new chain until we've sent them a message * acknowledging the last one */ @@ -162,29 +162,29 @@ std::size_t verify_mac_and_decrypt_for_new_chain( session, new_chain.chain_key, reader, plaintext, max_plaintext_length ); - axolotl::unset(new_root_key); - axolotl::unset(new_chain); + olm::unset(new_root_key); + olm::unset(new_chain); return result; } } // namespace -axolotl::Ratchet::Ratchet( - axolotl::KdfInfo const & kdf_info, +olm::Ratchet::Ratchet( + olm::KdfInfo const & kdf_info, Cipher const & ratchet_cipher ) : kdf_info(kdf_info), ratchet_cipher(ratchet_cipher), - last_error(axolotl::ErrorCode::SUCCESS) { + last_error(olm::ErrorCode::SUCCESS) { } -void axolotl::Ratchet::initialise_as_bob( +void olm::Ratchet::initialise_as_bob( std::uint8_t const * shared_secret, std::size_t shared_secret_length, - axolotl::Curve25519PublicKey const & their_ratchet_key + olm::Curve25519PublicKey const & their_ratchet_key ) { std::uint8_t derived_secrets[64]; - axolotl::hkdf_sha256( + olm::hkdf_sha256( shared_secret, shared_secret_length, nullptr, 0, kdf_info.root_info, kdf_info.root_info_length, @@ -195,16 +195,16 @@ void axolotl::Ratchet::initialise_as_bob( std::memcpy(root_key, derived_secrets, 32); std::memcpy(receiver_chains[0].chain_key.key, derived_secrets + 32, 32); receiver_chains[0].ratchet_key = their_ratchet_key; - axolotl::unset(derived_secrets); + olm::unset(derived_secrets); } -void axolotl::Ratchet::initialise_as_alice( +void olm::Ratchet::initialise_as_alice( std::uint8_t const * shared_secret, std::size_t shared_secret_length, - axolotl::Curve25519KeyPair const & our_ratchet_key + olm::Curve25519KeyPair const & our_ratchet_key ) { std::uint8_t derived_secrets[64]; - axolotl::hkdf_sha256( + olm::hkdf_sha256( shared_secret, shared_secret_length, nullptr, 0, kdf_info.root_info, kdf_info.root_info_length, @@ -215,14 +215,14 @@ void axolotl::Ratchet::initialise_as_alice( std::memcpy(root_key, derived_secrets, 32); std::memcpy(sender_chain[0].chain_key.key, derived_secrets + 32, 32); sender_chain[0].ratchet_key = our_ratchet_key; - axolotl::unset(derived_secrets); + olm::unset(derived_secrets); } -namespace axolotl { +namespace olm { static std::size_t pickle_length( - const axolotl::SharedKey & value + const olm::SharedKey & value ) { return KEY_LENGTH; } @@ -230,135 +230,135 @@ static std::size_t pickle_length( static std::uint8_t * pickle( std::uint8_t * pos, - const axolotl::SharedKey & value + const olm::SharedKey & value ) { - return axolotl::pickle_bytes(pos, value, KEY_LENGTH); + return olm::pickle_bytes(pos, value, KEY_LENGTH); } static std::uint8_t const * unpickle( std::uint8_t const * pos, std::uint8_t const * end, - axolotl::SharedKey & value + olm::SharedKey & value ) { - return axolotl::unpickle_bytes(pos, end, value, KEY_LENGTH); + return olm::unpickle_bytes(pos, end, value, KEY_LENGTH); } static std::size_t pickle_length( - const axolotl::SenderChain & value + const olm::SenderChain & value ) { std::size_t length = 0; - length += axolotl::pickle_length(value.ratchet_key); - length += axolotl::pickle_length(value.chain_key.key); - length += axolotl::pickle_length(value.chain_key.index); + length += olm::pickle_length(value.ratchet_key); + length += olm::pickle_length(value.chain_key.key); + length += olm::pickle_length(value.chain_key.index); return length; } static std::uint8_t * pickle( std::uint8_t * pos, - const axolotl::SenderChain & value + const olm::SenderChain & value ) { - pos = axolotl::pickle(pos, value.ratchet_key); - pos = axolotl::pickle(pos, value.chain_key.key); - pos = axolotl::pickle(pos, value.chain_key.index); + pos = olm::pickle(pos, value.ratchet_key); + pos = olm::pickle(pos, value.chain_key.key); + pos = olm::pickle(pos, value.chain_key.index); return pos; } static std::uint8_t const * unpickle( std::uint8_t const * pos, std::uint8_t const * end, - axolotl::SenderChain & value + olm::SenderChain & value ) { - pos = axolotl::unpickle(pos, end, value.ratchet_key); - pos = axolotl::unpickle(pos, end, value.chain_key.key); - pos = axolotl::unpickle(pos, end, value.chain_key.index); + pos = olm::unpickle(pos, end, value.ratchet_key); + pos = olm::unpickle(pos, end, value.chain_key.key); + pos = olm::unpickle(pos, end, value.chain_key.index); return pos; } static std::size_t pickle_length( - const axolotl::ReceiverChain & value + const olm::ReceiverChain & value ) { std::size_t length = 0; - length += axolotl::pickle_length(value.ratchet_key); - length += axolotl::pickle_length(value.chain_key.key); - length += axolotl::pickle_length(value.chain_key.index); + length += olm::pickle_length(value.ratchet_key); + length += olm::pickle_length(value.chain_key.key); + length += olm::pickle_length(value.chain_key.index); return length; } static std::uint8_t * pickle( std::uint8_t * pos, - const axolotl::ReceiverChain & value + const olm::ReceiverChain & value ) { - pos = axolotl::pickle(pos, value.ratchet_key); - pos = axolotl::pickle(pos, value.chain_key.key); - pos = axolotl::pickle(pos, value.chain_key.index); + pos = olm::pickle(pos, value.ratchet_key); + pos = olm::pickle(pos, value.chain_key.key); + pos = olm::pickle(pos, value.chain_key.index); return pos; } static std::uint8_t const * unpickle( std::uint8_t const * pos, std::uint8_t const * end, - axolotl::ReceiverChain & value + olm::ReceiverChain & value ) { - pos = axolotl::unpickle(pos, end, value.ratchet_key); - pos = axolotl::unpickle(pos, end, value.chain_key.key); - pos = axolotl::unpickle(pos, end, value.chain_key.index); + pos = olm::unpickle(pos, end, value.ratchet_key); + pos = olm::unpickle(pos, end, value.chain_key.key); + pos = olm::unpickle(pos, end, value.chain_key.index); return pos; } static std::size_t pickle_length( - const axolotl::SkippedMessageKey & value + const olm::SkippedMessageKey & value ) { std::size_t length = 0; - length += axolotl::pickle_length(value.ratchet_key); - length += axolotl::pickle_length(value.message_key.key); - length += axolotl::pickle_length(value.message_key.index); + length += olm::pickle_length(value.ratchet_key); + length += olm::pickle_length(value.message_key.key); + length += olm::pickle_length(value.message_key.index); return length; } static std::uint8_t * pickle( std::uint8_t * pos, - const axolotl::SkippedMessageKey & value + const olm::SkippedMessageKey & value ) { - pos = axolotl::pickle(pos, value.ratchet_key); - pos = axolotl::pickle(pos, value.message_key.key); - pos = axolotl::pickle(pos, value.message_key.index); + pos = olm::pickle(pos, value.ratchet_key); + pos = olm::pickle(pos, value.message_key.key); + pos = olm::pickle(pos, value.message_key.index); return pos; } static std::uint8_t const * unpickle( std::uint8_t const * pos, std::uint8_t const * end, - axolotl::SkippedMessageKey & value + olm::SkippedMessageKey & value ) { - pos = axolotl::unpickle(pos, end, value.ratchet_key); - pos = axolotl::unpickle(pos, end, value.message_key.key); - pos = axolotl::unpickle(pos, end, value.message_key.index); + pos = olm::unpickle(pos, end, value.ratchet_key); + pos = olm::unpickle(pos, end, value.message_key.key); + pos = olm::unpickle(pos, end, value.message_key.index); return pos; } -} // namespace axolotl +} // namespace olm -std::size_t axolotl::pickle_length( - axolotl::Ratchet const & value +std::size_t olm::pickle_length( + olm::Ratchet const & value ) { std::size_t length = 0; length += KEY_LENGTH; - length += axolotl::pickle_length(value.sender_chain); - length += axolotl::pickle_length(value.receiver_chains); - length += axolotl::pickle_length(value.skipped_message_keys); + length += olm::pickle_length(value.sender_chain); + length += olm::pickle_length(value.receiver_chains); + length += olm::pickle_length(value.skipped_message_keys); return length; } -std::uint8_t * axolotl::pickle( +std::uint8_t * olm::pickle( std::uint8_t * pos, - axolotl::Ratchet const & value + olm::Ratchet const & value ) { pos = pickle(pos, value.root_key); pos = pickle(pos, value.sender_chain); @@ -368,9 +368,9 @@ std::uint8_t * axolotl::pickle( } -std::uint8_t const * axolotl::unpickle( +std::uint8_t const * olm::unpickle( std::uint8_t const * pos, std::uint8_t const * end, - axolotl::Ratchet & value + olm::Ratchet & value ) { pos = unpickle(pos, end, value.root_key); pos = unpickle(pos, end, value.sender_chain); @@ -380,7 +380,7 @@ std::uint8_t const * axolotl::unpickle( } -std::size_t axolotl::Ratchet::encrypt_output_length( +std::size_t olm::Ratchet::encrypt_output_length( std::size_t plaintext_length ) { std::size_t counter = 0; @@ -390,18 +390,18 @@ std::size_t axolotl::Ratchet::encrypt_output_length( std::size_t padded = ratchet_cipher.encrypt_ciphertext_length( plaintext_length ); - return axolotl::encode_message_length( + return olm::encode_message_length( counter, KEY_LENGTH, padded, ratchet_cipher.mac_length() ); } -std::size_t axolotl::Ratchet::encrypt_random_length() { +std::size_t olm::Ratchet::encrypt_random_length() { return sender_chain.empty() ? KEY_LENGTH : 0; } -std::size_t axolotl::Ratchet::encrypt( +std::size_t olm::Ratchet::encrypt( std::uint8_t const * plaintext, std::size_t plaintext_length, std::uint8_t const * random, std::size_t random_length, std::uint8_t * output, std::size_t max_output_length @@ -409,17 +409,17 @@ std::size_t axolotl::Ratchet::encrypt( std::size_t output_length = encrypt_output_length(plaintext_length); if (random_length < encrypt_random_length()) { - last_error = axolotl::ErrorCode::NOT_ENOUGH_RANDOM; + last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM; return std::size_t(-1); } if (max_output_length < output_length) { - last_error = axolotl::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } if (sender_chain.empty()) { sender_chain.insert(); - axolotl::generate_key(random, sender_chain[0].ratchet_key); + olm::generate_key(random, sender_chain[0].ratchet_key); create_chain_key( root_key, sender_chain[0].ratchet_key, @@ -439,9 +439,9 @@ std::size_t axolotl::Ratchet::encrypt( std::uint32_t counter = keys.index; Curve25519PublicKey const & ratchet_key = sender_chain[0].ratchet_key; - axolotl::MessageWriter writer; + olm::MessageWriter writer; - axolotl::encode_message( + olm::encode_message( writer, PROTOCOL_VERSION, counter, KEY_LENGTH, ciphertext_length, output ); @@ -454,21 +454,21 @@ std::size_t axolotl::Ratchet::encrypt( output, output_length ); - axolotl::unset(keys); + olm::unset(keys); return output_length; } -std::size_t axolotl::Ratchet::decrypt_max_plaintext_length( +std::size_t olm::Ratchet::decrypt_max_plaintext_length( std::uint8_t const * input, std::size_t input_length ) { - axolotl::MessageReader reader; - axolotl::decode_message( + olm::MessageReader reader; + olm::decode_message( reader, input, input_length, ratchet_cipher.mac_length() ); if (!reader.ciphertext) { - last_error = axolotl::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; return std::size_t(-1); } @@ -476,22 +476,22 @@ std::size_t axolotl::Ratchet::decrypt_max_plaintext_length( } -std::size_t axolotl::Ratchet::decrypt( +std::size_t olm::Ratchet::decrypt( std::uint8_t const * input, std::size_t input_length, std::uint8_t * plaintext, std::size_t max_plaintext_length ) { - axolotl::MessageReader reader; - axolotl::decode_message( + olm::MessageReader reader; + olm::decode_message( reader, input, input_length, ratchet_cipher.mac_length() ); if (reader.version != PROTOCOL_VERSION) { - last_error = axolotl::ErrorCode::BAD_MESSAGE_VERSION; + last_error = olm::ErrorCode::BAD_MESSAGE_VERSION; return std::size_t(-1); } if (!reader.has_counter || !reader.ratchet_key || !reader.ciphertext) { - last_error = axolotl::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; return std::size_t(-1); } @@ -500,17 +500,17 @@ std::size_t axolotl::Ratchet::decrypt( ); if (max_plaintext_length < max_length) { - last_error = axolotl::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } if (reader.ratchet_key_length != KEY_LENGTH) { - last_error = axolotl::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; return std::size_t(-1); } ReceiverChain * chain = nullptr; - for (axolotl::ReceiverChain & receiver_chain : receiver_chains) { + for (olm::ReceiverChain & receiver_chain : receiver_chains) { if (0 == std::memcmp( receiver_chain.ratchet_key.public_key, reader.ratchet_key, KEY_LENGTH @@ -529,7 +529,7 @@ std::size_t axolotl::Ratchet::decrypt( } else if (chain->chain_key.index > reader.counter) { /* Chain already advanced beyond the key for this message * Check if the message keys are in the skipped key list. */ - for (axolotl::SkippedMessageKey & skipped : skipped_message_keys) { + for (olm::SkippedMessageKey & skipped : skipped_message_keys) { if (reader.counter == skipped.message_key.index && 0 == std::memcmp( skipped.ratchet_key.public_key, reader.ratchet_key, @@ -546,7 +546,7 @@ std::size_t axolotl::Ratchet::decrypt( if (result != std::size_t(-1)) { /* Remove the key from the skipped keys now that we've * decoded the message it corresponds to. */ - axolotl::unset(skipped); + olm::unset(skipped); skipped_message_keys.erase(&skipped); return result; } @@ -559,7 +559,7 @@ std::size_t axolotl::Ratchet::decrypt( } if (result == std::size_t(-1)) { - last_error = axolotl::ErrorCode::BAD_MESSAGE_MAC; + last_error = olm::ErrorCode::BAD_MESSAGE_MAC; return std::size_t(-1); } @@ -576,12 +576,12 @@ std::size_t axolotl::Ratchet::decrypt( root_key, sender_chain[0].ratchet_key, chain->ratchet_key, kdf_info, root_key, chain->chain_key ); - axolotl::unset(sender_chain[0]); + olm::unset(sender_chain[0]); sender_chain.erase(sender_chain.begin()); } while (chain->chain_key.index < reader.counter) { - axolotl::SkippedMessageKey & key = *skipped_message_keys.insert(); + olm::SkippedMessageKey & key = *skipped_message_keys.insert(); create_message_keys(chain->chain_key, kdf_info, key.message_key); key.ratchet_key = chain->ratchet_key; advance_chain_key(chain->chain_key, chain->chain_key); diff --git a/src/session.cpp b/src/session.cpp index 9d0935b..a028431 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -12,13 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "axolotl/session.hh" -#include "axolotl/cipher.hh" -#include "axolotl/crypto.hh" -#include "axolotl/account.hh" -#include "axolotl/memory.hh" -#include "axolotl/message.hh" -#include "axolotl/pickle.hh" +#include "olm/session.hh" +#include "olm/cipher.hh" +#include "olm/crypto.hh" +#include "olm/account.hh" +#include "olm/memory.hh" +#include "olm/message.hh" +#include "olm/pickle.hh" #include @@ -27,51 +27,51 @@ namespace { static const std::size_t KEY_LENGTH = 32; static const std::uint8_t PROTOCOL_VERSION = 0x3; -static const std::uint8_t ROOT_KDF_INFO[] = "AXOLOTL_ROOT"; -static const std::uint8_t RATCHET_KDF_INFO[] = "AXOLOTL_RATCHET"; -static const std::uint8_t CIPHER_KDF_INFO[] = "AXOLOTL_KEYS"; +static const std::uint8_t ROOT_KDF_INFO[] = "OLM_ROOT"; +static const std::uint8_t RATCHET_KDF_INFO[] = "OLM_RATCHET"; +static const std::uint8_t CIPHER_KDF_INFO[] = "OLM_KEYS"; -static const axolotl::CipherAesSha256 AXOLOTL_CIPHER( +static const olm::CipherAesSha256 OLM_CIPHER( CIPHER_KDF_INFO, sizeof(CIPHER_KDF_INFO) -1 ); -static const axolotl::KdfInfo AXOLOTL_KDF_INFO = { +static const olm::KdfInfo OLM_KDF_INFO = { ROOT_KDF_INFO, sizeof(ROOT_KDF_INFO) - 1, RATCHET_KDF_INFO, sizeof(RATCHET_KDF_INFO) - 1 }; } // namespace -axolotl::Session::Session( -) : ratchet(AXOLOTL_KDF_INFO, AXOLOTL_CIPHER), - last_error(axolotl::ErrorCode::SUCCESS), +olm::Session::Session( +) : ratchet(OLM_KDF_INFO, OLM_CIPHER), + last_error(olm::ErrorCode::SUCCESS), received_message(false), bob_one_time_key_id(0) { } -std::size_t axolotl::Session::new_outbound_session_random_length() { +std::size_t olm::Session::new_outbound_session_random_length() { return KEY_LENGTH * 2; } -std::size_t axolotl::Session::new_outbound_session( - axolotl::Account const & local_account, - axolotl::Curve25519PublicKey const & identity_key, - axolotl::RemoteKey const & one_time_key, +std::size_t olm::Session::new_outbound_session( + olm::Account const & local_account, + olm::Curve25519PublicKey const & identity_key, + olm::RemoteKey const & one_time_key, std::uint8_t const * random, std::size_t random_length ) { if (random_length < new_outbound_session_random_length()) { - last_error = axolotl::ErrorCode::NOT_ENOUGH_RANDOM; + last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM; return std::size_t(-1); } Curve25519KeyPair base_key; - axolotl::generate_key(random, base_key); + olm::generate_key(random, base_key); Curve25519KeyPair ratchet_key; - axolotl::generate_key(random + 32, ratchet_key); + olm::generate_key(random + 32, ratchet_key); received_message = false; alice_identity_key.id = local_account.identity_key.id; @@ -81,21 +81,21 @@ std::size_t axolotl::Session::new_outbound_session( std::uint8_t shared_secret[96]; - axolotl::curve25519_shared_secret( + olm::curve25519_shared_secret( local_account.identity_key.key, one_time_key.key, shared_secret ); - axolotl::curve25519_shared_secret( + olm::curve25519_shared_secret( base_key, identity_key, shared_secret + 32 ); - axolotl::curve25519_shared_secret( + olm::curve25519_shared_secret( base_key, one_time_key.key, shared_secret + 64 ); ratchet.initialise_as_alice(shared_secret, 96, ratchet_key); - axolotl::unset(base_key); - axolotl::unset(ratchet_key); - axolotl::unset(shared_secret); + olm::unset(base_key); + olm::unset(ratchet_key); + olm::unset(shared_secret); return std::size_t(0); } @@ -103,7 +103,7 @@ std::size_t axolotl::Session::new_outbound_session( namespace { bool check_message_fields( - axolotl::PreKeyMessageReader & reader + olm::PreKeyMessageReader & reader ) { bool ok = true; ok = ok && reader.identity_key; @@ -118,19 +118,19 @@ bool check_message_fields( } // namespace -std::size_t axolotl::Session::new_inbound_session( - axolotl::Account & local_account, +std::size_t olm::Session::new_inbound_session( + olm::Account & local_account, std::uint8_t const * one_time_key_message, std::size_t message_length ) { - axolotl::PreKeyMessageReader reader; + olm::PreKeyMessageReader reader; decode_one_time_key_message(reader, one_time_key_message, message_length); if (!check_message_fields(reader)) { - last_error = axolotl::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; return std::size_t(-1); } - axolotl::MessageReader message_reader; + olm::MessageReader message_reader; decode_message( message_reader, reader.message, reader.message_length, ratchet.ratchet_cipher.mac_length() @@ -138,34 +138,34 @@ std::size_t axolotl::Session::new_inbound_session( if (!message_reader.ratchet_key || message_reader.ratchet_key_length != KEY_LENGTH) { - last_error = axolotl::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; return std::size_t(-1); } std::memcpy(alice_identity_key.key.public_key, reader.identity_key, 32); std::memcpy(alice_base_key.public_key, reader.base_key, 32); bob_one_time_key_id = reader.one_time_key_id; - axolotl::Curve25519PublicKey ratchet_key; + olm::Curve25519PublicKey ratchet_key; std::memcpy(ratchet_key.public_key, message_reader.ratchet_key, 32); - axolotl::LocalKey const * bob_one_time_key = local_account.lookup_key( + olm::LocalKey const * bob_one_time_key = local_account.lookup_key( bob_one_time_key_id ); if (!bob_one_time_key) { - last_error = axolotl::ErrorCode::BAD_MESSAGE_KEY_ID; + last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID; return std::size_t(-1); } std::uint8_t shared_secret[96]; - axolotl::curve25519_shared_secret( + olm::curve25519_shared_secret( bob_one_time_key->key, alice_identity_key.key, shared_secret ); - axolotl::curve25519_shared_secret( + olm::curve25519_shared_secret( local_account.identity_key.key, alice_base_key, shared_secret + 32 ); - axolotl::curve25519_shared_secret( + olm::curve25519_shared_secret( bob_one_time_key->key, alice_base_key, shared_secret + 64 ); @@ -175,10 +175,10 @@ std::size_t axolotl::Session::new_inbound_session( } -bool axolotl::Session::matches_inbound_session( +bool olm::Session::matches_inbound_session( std::uint8_t const * one_time_key_message, std::size_t message_length ) { - axolotl::PreKeyMessageReader reader; + olm::PreKeyMessageReader reader; decode_one_time_key_message(reader, one_time_key_message, message_length); if (!check_message_fields(reader)) { @@ -197,16 +197,16 @@ bool axolotl::Session::matches_inbound_session( } -axolotl::MessageType axolotl::Session::encrypt_message_type() { +olm::MessageType olm::Session::encrypt_message_type() { if (received_message) { - return axolotl::MessageType::MESSAGE; + return olm::MessageType::MESSAGE; } else { - return axolotl::MessageType::PRE_KEY; + return olm::MessageType::PRE_KEY; } } -std::size_t axolotl::Session::encrypt_message_length( +std::size_t olm::Session::encrypt_message_length( std::size_t plaintext_length ) { std::size_t message_length = ratchet.encrypt_output_length( @@ -226,18 +226,18 @@ std::size_t axolotl::Session::encrypt_message_length( } -std::size_t axolotl::Session::encrypt_random_length() { +std::size_t olm::Session::encrypt_random_length() { return ratchet.encrypt_random_length(); } -std::size_t axolotl::Session::encrypt( +std::size_t olm::Session::encrypt( std::uint8_t const * plaintext, std::size_t plaintext_length, std::uint8_t const * random, std::size_t random_length, std::uint8_t * message, std::size_t message_length ) { if (message_length < encrypt_message_length(plaintext_length)) { - last_error = axolotl::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } std::uint8_t * message_body; @@ -248,7 +248,7 @@ std::size_t axolotl::Session::encrypt( if (received_message) { message_body = message; } else { - axolotl::PreKeyMessageWriter writer; + olm::PreKeyMessageWriter writer; encode_one_time_key_message( writer, PROTOCOL_VERSION, @@ -275,26 +275,26 @@ std::size_t axolotl::Session::encrypt( if (result == std::size_t(-1)) { last_error = ratchet.last_error; - ratchet.last_error = axolotl::ErrorCode::SUCCESS; + ratchet.last_error = olm::ErrorCode::SUCCESS; } return result; } -std::size_t axolotl::Session::decrypt_max_plaintext_length( +std::size_t olm::Session::decrypt_max_plaintext_length( MessageType message_type, std::uint8_t const * message, std::size_t message_length ) { std::uint8_t const * message_body; std::size_t message_body_length; - if (message_type == axolotl::MessageType::MESSAGE) { + if (message_type == olm::MessageType::MESSAGE) { message_body = message; message_body_length = message_length; } else { - axolotl::PreKeyMessageReader reader; + olm::PreKeyMessageReader reader; decode_one_time_key_message(reader, message, message_length); if (!reader.message) { - last_error = axolotl::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; return std::size_t(-1); } message_body = reader.message; @@ -307,27 +307,27 @@ std::size_t axolotl::Session::decrypt_max_plaintext_length( if (result == std::size_t(-1)) { last_error = ratchet.last_error; - ratchet.last_error = axolotl::ErrorCode::SUCCESS; + ratchet.last_error = olm::ErrorCode::SUCCESS; } return result; } -std::size_t axolotl::Session::decrypt( - axolotl::MessageType message_type, +std::size_t olm::Session::decrypt( + olm::MessageType message_type, std::uint8_t const * message, std::size_t message_length, std::uint8_t * plaintext, std::size_t max_plaintext_length ) { std::uint8_t const * message_body; std::size_t message_body_length; - if (message_type == axolotl::MessageType::MESSAGE) { + if (message_type == olm::MessageType::MESSAGE) { message_body = message; message_body_length = message_length; } else { - axolotl::PreKeyMessageReader reader; + olm::PreKeyMessageReader reader; decode_one_time_key_message(reader, message, message_length); if (!reader.message) { - last_error = axolotl::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; return std::size_t(-1); } message_body = reader.message; @@ -340,7 +340,7 @@ std::size_t axolotl::Session::decrypt( if (result == std::size_t(-1)) { last_error = ratchet.last_error; - ratchet.last_error = axolotl::ErrorCode::SUCCESS; + ratchet.last_error = olm::ErrorCode::SUCCESS; } else { received_message = true; } @@ -348,44 +348,44 @@ std::size_t axolotl::Session::decrypt( } -std::size_t axolotl::pickle_length( +std::size_t olm::pickle_length( Session const & value ) { std::size_t length = 0; - length += axolotl::pickle_length(value.received_message); - length += axolotl::pickle_length(value.alice_identity_key.id); - length += axolotl::pickle_length(value.alice_identity_key.key); - length += axolotl::pickle_length(value.alice_base_key); - length += axolotl::pickle_length(value.bob_one_time_key_id); - length += axolotl::pickle_length(value.ratchet); + length += olm::pickle_length(value.received_message); + length += olm::pickle_length(value.alice_identity_key.id); + length += olm::pickle_length(value.alice_identity_key.key); + length += olm::pickle_length(value.alice_base_key); + length += olm::pickle_length(value.bob_one_time_key_id); + length += olm::pickle_length(value.ratchet); return length; } -std::uint8_t * axolotl::pickle( +std::uint8_t * olm::pickle( std::uint8_t * pos, Session const & value ) { - pos = axolotl::pickle(pos, value.received_message); - pos = axolotl::pickle(pos, value.alice_identity_key.id); - pos = axolotl::pickle(pos, value.alice_identity_key.key); - pos = axolotl::pickle(pos, value.alice_base_key); - pos = axolotl::pickle(pos, value.bob_one_time_key_id); - pos = axolotl::pickle(pos, value.ratchet); + pos = olm::pickle(pos, value.received_message); + pos = olm::pickle(pos, value.alice_identity_key.id); + pos = olm::pickle(pos, value.alice_identity_key.key); + pos = olm::pickle(pos, value.alice_base_key); + pos = olm::pickle(pos, value.bob_one_time_key_id); + pos = olm::pickle(pos, value.ratchet); return pos; } -std::uint8_t const * axolotl::unpickle( +std::uint8_t const * olm::unpickle( std::uint8_t const * pos, std::uint8_t const * end, Session & value ) { - pos = axolotl::unpickle(pos, end, value.received_message); - pos = axolotl::unpickle(pos, end, value.alice_identity_key.id); - pos = axolotl::unpickle(pos, end, value.alice_identity_key.key); - pos = axolotl::unpickle(pos, end, value.alice_base_key); - pos = axolotl::unpickle(pos, end, value.bob_one_time_key_id); - pos = axolotl::unpickle(pos, end, value.ratchet); + pos = olm::unpickle(pos, end, value.received_message); + pos = olm::unpickle(pos, end, value.alice_identity_key.id); + pos = olm::unpickle(pos, end, value.alice_identity_key.key); + pos = olm::unpickle(pos, end, value.alice_base_key); + pos = olm::unpickle(pos, end, value.bob_one_time_key_id); + pos = olm::unpickle(pos, end, value.ratchet); return pos; } -- cgit v1.2.3