Commit 39212987 authored by Richard van der Hoff's avatar Richard van der Hoff
Browse files

Create new constants for key lengths, etc

We were using olm::KEY_LENGTH for everything under the sun which happened to be
32 bytes long, and making a bunch of assumptions in the process. Create a bunch
of new constants (as C #defines rather than C++ consts so that I can use them
in another forthcoming refactor).
parent 0c3f527d
......@@ -27,7 +27,36 @@
extern "C" {
#endif
const size_t SHA256_OUTPUT_LENGTH = 32;
/** length of a sha256 hash */
#define SHA256_OUTPUT_LENGTH 32
/** length of a public or private Curve25519 key */
#define CURVE25519_KEY_LENGTH 32
/** length of the shared secret created by a Curve25519 ECDH operation */
#define CURVE25519_SHARED_SECRET_LENGTH 32
/** amount of random data required to create a Curve25519 keypair */
#define CURVE25519_RANDOM_LENGTH CURVE25519_KEY_LENGTH
/** length of a public Ed25519 key */
#define ED25519_PUBLIC_KEY_LENGTH 32
/** length of a private Ed25519 key */
#define ED25519_PRIVATE_KEY_LENGTH 64
/** amount of random data required to create a Ed25519 keypair */
#define ED25519_RANDOM_LENGTH 32
/** length of an Ed25519 signature */
#define ED25519_SIGNATURE_LENGTH 64
/** length of an aes256 key */
#define AES256_KEY_LENGTH 32
/** length of an aes256 initialisation vector */
#define AES256_IV_LENGTH 16
/** Computes SHA-256 of the input. The output buffer must be a least 32
* bytes long. */
......
......@@ -25,23 +25,18 @@
namespace olm {
static const std::size_t ED25519_PRIVATE_KEY_LENGTH = 64;
static const std::size_t KEY_LENGTH = 32;
static const std::size_t SIGNATURE_LENGTH = 64;
static const std::size_t IV_LENGTH = 16;
struct Curve25519PublicKey {
std::uint8_t public_key[KEY_LENGTH];
std::uint8_t public_key[CURVE25519_KEY_LENGTH];
};
struct Curve25519KeyPair : public Curve25519PublicKey {
std::uint8_t private_key[KEY_LENGTH];
std::uint8_t private_key[CURVE25519_KEY_LENGTH];
};
struct Ed25519PublicKey {
std::uint8_t public_key[KEY_LENGTH];
std::uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH];
};
......@@ -93,12 +88,12 @@ bool ed25519_verify(
struct Aes256Key {
std::uint8_t key[KEY_LENGTH];
std::uint8_t key[AES256_KEY_LENGTH];
};
struct Aes256Iv {
std::uint8_t iv[IV_LENGTH];
std::uint8_t iv[AES256_IV_LENGTH];
};
......
......@@ -21,8 +21,13 @@ struct _olm_cipher;
namespace olm {
typedef std::uint8_t SharedKey[olm::KEY_LENGTH];
/** length of a shared key: the root key R(i), chain key C(i,j), and message key
* M(i,j)). They are all only used to stuff into HMACs, so could be any length
* for that. The chain key and message key are both derived from SHA256
* operations, so their length is determined by that. */
const std::size_t OLM_SHARED_KEY_LENGTH = SHA256_OUTPUT_LENGTH;
typedef std::uint8_t SharedKey[OLM_SHARED_KEY_LENGTH];
struct ChainKey {
std::uint32_t index;
......
......@@ -49,7 +49,7 @@ std::size_t olm::Account::remove_key(
}
std::size_t olm::Account::new_account_random_length() {
return 2 * olm::KEY_LENGTH;
return ED25519_RANDOM_LENGTH + CURVE25519_RANDOM_LENGTH;
}
std::size_t olm::Account::new_account(
......@@ -61,7 +61,7 @@ std::size_t olm::Account::new_account(
}
olm::ed25519_generate_key(random, identity_keys.ed25519_key);
random += KEY_LENGTH;
random += ED25519_RANDOM_LENGTH;
olm::curve25519_generate_key(random, identity_keys.curve25519_key);
return 0;
......@@ -137,7 +137,7 @@ std::size_t olm::Account::get_identity_json(
std::size_t olm::Account::signature_length(
) {
return olm::SIGNATURE_LENGTH;
return ED25519_SIGNATURE_LENGTH;
}
......@@ -238,7 +238,7 @@ std::size_t olm::Account::max_number_of_one_time_keys(
std::size_t olm::Account::generate_one_time_keys_random_length(
std::size_t number_of_keys
) {
return olm::KEY_LENGTH * number_of_keys;
return CURVE25519_RANDOM_LENGTH * number_of_keys;
}
std::size_t olm::Account::generate_one_time_keys(
......@@ -254,7 +254,7 @@ std::size_t olm::Account::generate_one_time_keys(
key.id = ++next_one_time_key_id;
key.published = false;
olm::curve25519_generate_key(random, key.key);
random += olm::KEY_LENGTH;
random += CURVE25519_RANDOM_LENGTH;
}
return number_of_keys;
}
......
......@@ -17,11 +17,13 @@
#include "olm/memory.hh"
#include <cstring>
const std::size_t HMAC_KEY_LENGTH = 32;
namespace {
struct DerivedKeys {
olm::Aes256Key aes_key;
std::uint8_t mac_key[olm::KEY_LENGTH];
std::uint8_t mac_key[HMAC_KEY_LENGTH];
olm::Aes256Iv aes_iv;
};
......@@ -31,7 +33,9 @@ static void derive_keys(
std::uint8_t const * key, std::size_t key_length,
DerivedKeys & keys
) {
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH + olm::IV_LENGTH];
std::uint8_t derived_secrets[
AES256_KEY_LENGTH + HMAC_KEY_LENGTH + AES256_IV_LENGTH
];
_olm_crypto_hkdf_sha256(
key, key_length,
nullptr, 0,
......@@ -81,7 +85,7 @@ size_t aes_sha_256_cipher_encrypt(
);
_olm_crypto_hmac_sha256(
keys.mac_key, olm::KEY_LENGTH, output, output_length - MAC_LENGTH, mac
keys.mac_key, HMAC_KEY_LENGTH, output, output_length - MAC_LENGTH, mac
);
std::memcpy(output + output_length - MAC_LENGTH, mac, MAC_LENGTH);
......@@ -113,7 +117,7 @@ size_t aes_sha_256_cipher_decrypt(
derive_keys(c->kdf_info, c->kdf_info_length, key, key_length, keys);
_olm_crypto_hmac_sha256(
keys.mac_key, olm::KEY_LENGTH, input, input_length - MAC_LENGTH, mac
keys.mac_key, HMAC_KEY_LENGTH, input, input_length - MAC_LENGTH, mac
);
std::uint8_t const * input_mac = input + input_length - MAC_LENGTH;
......
......@@ -31,7 +31,7 @@ namespace {
static const std::uint8_t CURVE25519_BASEPOINT[32] = {9};
static const std::size_t AES_KEY_SCHEDULE_LENGTH = 60;
static const std::size_t AES_KEY_BITS = 8 * olm::KEY_LENGTH;
static const std::size_t AES_KEY_BITS = 8 * AES256_KEY_LENGTH;
static const std::size_t AES_BLOCK_LENGTH = 16;
static const std::size_t SHA256_BLOCK_LENGTH = 64;
static const std::uint8_t HKDF_DEFAULT_SALT[32] = {};
......@@ -104,7 +104,7 @@ void olm::curve25519_generate_key(
std::uint8_t const * random_32_bytes,
olm::Curve25519KeyPair & key_pair
) {
std::memcpy(key_pair.private_key, random_32_bytes, KEY_LENGTH);
std::memcpy(key_pair.private_key, random_32_bytes, CURVE25519_KEY_LENGTH);
::curve25519_donna(
key_pair.public_key, key_pair.private_key, CURVE25519_BASEPOINT
);
......
......@@ -436,8 +436,8 @@ size_t olm_create_outbound_session(
std::size_t id_key_length = their_identity_key_length;
std::size_t ot_key_length = their_one_time_key_length;
if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH
|| olm::decode_base64_length(ot_key_length) != olm::KEY_LENGTH
if (olm::decode_base64_length(id_key_length) != CURVE25519_KEY_LENGTH
|| olm::decode_base64_length(ot_key_length) != CURVE25519_KEY_LENGTH
) {
from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
......@@ -483,7 +483,7 @@ size_t olm_create_inbound_session_from(
std::uint8_t const * id_key = from_c(their_identity_key);
std::size_t id_key_length = their_identity_key_length;
if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) {
if (olm::decode_base64_length(id_key_length) != CURVE25519_KEY_LENGTH) {
from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
}
......@@ -554,7 +554,7 @@ size_t olm_matches_inbound_session_from(
std::uint8_t const * id_key = from_c(their_identity_key);
std::size_t id_key_length = their_identity_key_length;
if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) {
if (olm::decode_base64_length(id_key_length) != CURVE25519_KEY_LENGTH) {
from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
}
......@@ -710,7 +710,7 @@ size_t olm_ed25519_verify(
void const * message, size_t message_length,
void * signature, size_t signature_length
) {
if (olm::decode_base64_length(key_length) != olm::KEY_LENGTH) {
if (olm::decode_base64_length(key_length) != CURVE25519_KEY_LENGTH) {
from_c(utility)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
}
......
......@@ -49,7 +49,7 @@ static void create_chain_key(
) {
olm::SharedKey secret;
olm::curve25519_shared_secret(our_key, their_key, secret);
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
std::uint8_t derived_secrets[2 * olm::OLM_SHARED_KEY_LENGTH];
_olm_crypto_hkdf_sha256(
secret, sizeof(secret),
root_key, sizeof(root_key),
......@@ -191,7 +191,7 @@ void olm::Ratchet::initialise_as_bob(
std::uint8_t const * shared_secret, std::size_t shared_secret_length,
olm::Curve25519PublicKey const & their_ratchet_key
) {
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
std::uint8_t derived_secrets[2 * olm::OLM_SHARED_KEY_LENGTH];
_olm_crypto_hkdf_sha256(
shared_secret, shared_secret_length,
nullptr, 0,
......@@ -212,7 +212,7 @@ void olm::Ratchet::initialise_as_alice(
std::uint8_t const * shared_secret, std::size_t shared_secret_length,
olm::Curve25519KeyPair const & our_ratchet_key
) {
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
std::uint8_t derived_secrets[2 * olm::OLM_SHARED_KEY_LENGTH];
_olm_crypto_hkdf_sha256(
shared_secret, shared_secret_length,
nullptr, 0,
......@@ -234,7 +234,7 @@ namespace olm {
static std::size_t pickle_length(
const olm::SharedKey & value
) {
return olm::KEY_LENGTH;
return olm::OLM_SHARED_KEY_LENGTH;
}
......@@ -242,7 +242,7 @@ static std::uint8_t * pickle(
std::uint8_t * pos,
const olm::SharedKey & value
) {
return olm::pickle_bytes(pos, value, olm::KEY_LENGTH);
return olm::pickle_bytes(pos, value, olm::OLM_SHARED_KEY_LENGTH);
}
......@@ -250,7 +250,7 @@ static std::uint8_t const * unpickle(
std::uint8_t const * pos, std::uint8_t const * end,
olm::SharedKey & value
) {
return olm::unpickle_bytes(pos, end, value, olm::KEY_LENGTH);
return olm::unpickle_bytes(pos, end, value, olm::OLM_SHARED_KEY_LENGTH);
}
......@@ -359,7 +359,7 @@ std::size_t olm::pickle_length(
olm::Ratchet const & value
) {
std::size_t length = 0;
length += olm::KEY_LENGTH;
length += olm::OLM_SHARED_KEY_LENGTH;
length += olm::pickle_length(value.sender_chain);
length += olm::pickle_length(value.receiver_chains);
length += olm::pickle_length(value.skipped_message_keys);
......@@ -409,13 +409,13 @@ std::size_t olm::Ratchet::encrypt_output_length(
plaintext_length
);
return olm::encode_message_length(
counter, olm::KEY_LENGTH, padded, ratchet_cipher->ops->mac_length(ratchet_cipher)
counter, CURVE25519_KEY_LENGTH, padded, ratchet_cipher->ops->mac_length(ratchet_cipher)
);
}
std::size_t olm::Ratchet::encrypt_random_length() {
return sender_chain.empty() ? olm::KEY_LENGTH : 0;
return sender_chain.empty() ? CURVE25519_RANDOM_LENGTH : 0;
}
......@@ -461,7 +461,8 @@ std::size_t olm::Ratchet::encrypt(
olm::MessageWriter writer;
olm::encode_message(
writer, PROTOCOL_VERSION, counter, olm::KEY_LENGTH, ciphertext_length,
writer, PROTOCOL_VERSION, counter, CURVE25519_KEY_LENGTH,
ciphertext_length,
output
);
......@@ -529,7 +530,7 @@ std::size_t olm::Ratchet::decrypt(
return std::size_t(-1);
}
if (reader.ratchet_key_length != olm::KEY_LENGTH) {
if (reader.ratchet_key_length != CURVE25519_KEY_LENGTH) {
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
return std::size_t(-1);
}
......@@ -539,7 +540,7 @@ std::size_t olm::Ratchet::decrypt(
for (olm::ReceiverChain & receiver_chain : receiver_chains) {
if (0 == std::memcmp(
receiver_chain.ratchet_key.public_key, reader.ratchet_key,
olm::KEY_LENGTH
CURVE25519_KEY_LENGTH
)) {
chain = &receiver_chain;
break;
......@@ -559,7 +560,7 @@ std::size_t olm::Ratchet::decrypt(
if (reader.counter == skipped.message_key.index
&& 0 == std::memcmp(
skipped.ratchet_key.public_key, reader.ratchet_key,
olm::KEY_LENGTH
CURVE25519_KEY_LENGTH
)
) {
/* Found the key for this message. Check the MAC. */
......
......@@ -49,7 +49,7 @@ olm::Session::Session(
std::size_t olm::Session::new_outbound_session_random_length() {
return olm::KEY_LENGTH * 2;
return CURVE25519_RANDOM_LENGTH * 2;
}
......@@ -68,7 +68,7 @@ std::size_t olm::Session::new_outbound_session(
olm::curve25519_generate_key(random, base_key);
olm::Curve25519KeyPair ratchet_key;
olm::curve25519_generate_key(random + olm::KEY_LENGTH, ratchet_key);
olm::curve25519_generate_key(random + CURVE25519_RANDOM_LENGTH, ratchet_key);
olm::Curve25519KeyPair const & alice_identity_key_pair = (
local_account.identity_keys.curve25519_key
......@@ -79,13 +79,13 @@ std::size_t olm::Session::new_outbound_session(
alice_base_key = base_key;
bob_one_time_key = one_time_key;
std::uint8_t secret[3 * olm::KEY_LENGTH];
// Calculate the shared secret S via triple DH
std::uint8_t secret[3 * CURVE25519_SHARED_SECRET_LENGTH];
std::uint8_t * pos = secret;
olm::curve25519_shared_secret(alice_identity_key_pair, one_time_key, pos);
pos += olm::KEY_LENGTH;
pos += CURVE25519_SHARED_SECRET_LENGTH;
olm::curve25519_shared_secret(base_key, identity_key, pos);
pos += olm::KEY_LENGTH;
pos += CURVE25519_SHARED_SECRET_LENGTH;
olm::curve25519_shared_secret(base_key, one_time_key, pos);
ratchet.initialise_as_alice(secret, sizeof(secret), ratchet_key);
......@@ -105,13 +105,13 @@ static bool check_message_fields(
bool ok = true;
ok = ok && (have_their_identity_key || reader.identity_key);
if (reader.identity_key) {
ok = ok && reader.identity_key_length == olm::KEY_LENGTH;
ok = ok && reader.identity_key_length == CURVE25519_KEY_LENGTH;
}
ok = ok && reader.message;
ok = ok && reader.base_key;
ok = ok && reader.base_key_length == olm::KEY_LENGTH;
ok = ok && reader.base_key_length == CURVE25519_KEY_LENGTH;
ok = ok && reader.one_time_key;
ok = ok && reader.one_time_key_length == olm::KEY_LENGTH;
ok = ok && reader.one_time_key_length == CURVE25519_KEY_LENGTH;
return ok;
}
......@@ -133,7 +133,7 @@ std::size_t olm::Session::new_inbound_session(
if (reader.identity_key && their_identity_key) {
bool same = 0 == std::memcmp(
their_identity_key->public_key, reader.identity_key, olm::KEY_LENGTH
their_identity_key->public_key, reader.identity_key, CURVE25519_KEY_LENGTH
);
if (!same) {
last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID;
......@@ -152,7 +152,7 @@ std::size_t olm::Session::new_inbound_session(
);
if (!message_reader.ratchet_key
|| message_reader.ratchet_key_length != olm::KEY_LENGTH) {
|| message_reader.ratchet_key_length != CURVE25519_KEY_LENGTH) {
last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
return std::size_t(-1);
}
......@@ -174,12 +174,13 @@ std::size_t olm::Session::new_inbound_session(
);
olm::Curve25519KeyPair const & bob_one_time_key = our_one_time_key->key;
std::uint8_t secret[olm::KEY_LENGTH * 3];
// Calculate the shared secret S via triple DH
std::uint8_t secret[CURVE25519_SHARED_SECRET_LENGTH * 3];
std::uint8_t * pos = secret;
olm::curve25519_shared_secret(bob_one_time_key, alice_identity_key, pos);
pos += olm::KEY_LENGTH;
pos += CURVE25519_SHARED_SECRET_LENGTH;
olm::curve25519_shared_secret(bob_identity_key, alice_base_key, pos);
pos += olm::KEY_LENGTH;
pos += CURVE25519_SHARED_SECRET_LENGTH;
olm::curve25519_shared_secret(bob_one_time_key, alice_base_key, pos);
ratchet.initialise_as_bob(secret, sizeof(secret), ratchet_key);
......@@ -202,7 +203,7 @@ std::size_t olm::Session::session_id(
last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
std::uint8_t tmp[olm::KEY_LENGTH * 3];
std::uint8_t tmp[CURVE25519_KEY_LENGTH * 3];
std::uint8_t * pos = tmp;
pos = olm::store_array(pos, alice_identity_key.public_key);
pos = olm::store_array(pos, alice_base_key.public_key);
......@@ -226,20 +227,20 @@ bool olm::Session::matches_inbound_session(
bool same = true;
if (reader.identity_key) {
same = same && 0 == std::memcmp(
reader.identity_key, alice_identity_key.public_key, olm::KEY_LENGTH
reader.identity_key, alice_identity_key.public_key, CURVE25519_KEY_LENGTH
);
}
if (their_identity_key) {
same = same && 0 == std::memcmp(
their_identity_key->public_key, alice_identity_key.public_key,
olm::KEY_LENGTH
CURVE25519_KEY_LENGTH
);
}
same = same && 0 == std::memcmp(
reader.base_key, alice_base_key.public_key, olm::KEY_LENGTH
reader.base_key, alice_base_key.public_key, CURVE25519_KEY_LENGTH
);
same = same && 0 == std::memcmp(
reader.one_time_key, bob_one_time_key.public_key, olm::KEY_LENGTH
reader.one_time_key, bob_one_time_key.public_key, CURVE25519_KEY_LENGTH
);
return same;
}
......@@ -266,9 +267,9 @@ std::size_t olm::Session::encrypt_message_length(
}
return encode_one_time_key_message_length(
olm::KEY_LENGTH,
olm::KEY_LENGTH,
olm::KEY_LENGTH,
CURVE25519_KEY_LENGTH,
CURVE25519_KEY_LENGTH,
CURVE25519_KEY_LENGTH,
message_length
);
}
......@@ -300,9 +301,9 @@ std::size_t olm::Session::encrypt(
encode_one_time_key_message(
writer,
PROTOCOL_VERSION,
olm::KEY_LENGTH,
olm::KEY_LENGTH,
olm::KEY_LENGTH,
CURVE25519_KEY_LENGTH,
CURVE25519_KEY_LENGTH,
CURVE25519_KEY_LENGTH,
message_body_length,
message
);
......
......@@ -45,7 +45,7 @@ size_t olm::Utility::ed25519_verify(
std::uint8_t const * message, std::size_t message_length,
std::uint8_t const * signature, std::size_t signature_length
) {
if (signature_length < olm::SIGNATURE_LENGTH) {
if (signature_length < ED25519_SIGNATURE_LENGTH) {
last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC;
return std::size_t(-1);
}
......
......@@ -70,7 +70,7 @@ olm::curve25519_generate_key(bob_private, bob_pair);
assert_equals(bob_private, bob_pair.private_key, 32);
assert_equals(bob_public, bob_pair.public_key, 32);
std::uint8_t actual_agreement[olm::KEY_LENGTH] = {};
std::uint8_t actual_agreement[CURVE25519_SHARED_SECRET_LENGTH] = {};
olm::curve25519_shared_secret(alice_pair, bob_pair, actual_agreement);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment