Commit 057ab15c authored by Richard van der Hoff's avatar Richard van der Hoff Committed by GitHub
Browse files

Merge pull request #14 from matrix-org/rav/convert_crypto_to_c

Convert crypto.hh into C-compatible interface
parents 2aad4cfa 69f269ff
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define OLM_ACCOUNT_HH_ #define OLM_ACCOUNT_HH_
#include "olm/list.hh" #include "olm/list.hh"
#include "olm/crypto.hh" #include "olm/crypto.h"
#include "olm/error.h" #include "olm/error.h"
#include <cstdint> #include <cstdint>
...@@ -25,14 +25,14 @@ namespace olm { ...@@ -25,14 +25,14 @@ namespace olm {
struct IdentityKeys { struct IdentityKeys {
Ed25519KeyPair ed25519_key; _olm_ed25519_key_pair ed25519_key;
Curve25519KeyPair curve25519_key; _olm_curve25519_key_pair curve25519_key;
}; };
struct OneTimeKey { struct OneTimeKey {
std::uint32_t id; std::uint32_t id;
bool published; bool published;
Curve25519KeyPair key; _olm_curve25519_key_pair key;
}; };
...@@ -128,12 +128,12 @@ struct Account { ...@@ -128,12 +128,12 @@ struct Account {
/** Lookup a one time key with the given public key */ /** Lookup a one time key with the given public key */
OneTimeKey const * lookup_key( OneTimeKey const * lookup_key(
Curve25519PublicKey const & public_key _olm_curve25519_public_key const & public_key
); );
/** Remove a one time key with the given public key */ /** Remove a one time key with the given public key */
std::size_t remove_key( std::size_t remove_key(
Curve25519PublicKey const & public_key _olm_curve25519_public_key const & public_key
); );
}; };
......
...@@ -57,9 +57,70 @@ extern "C" { ...@@ -57,9 +57,70 @@ extern "C" {
/** length of an aes256 initialisation vector */ /** length of an aes256 initialisation vector */
#define AES256_IV_LENGTH 16 #define AES256_IV_LENGTH 16
struct _olm_aes256_key {
uint8_t key[AES256_KEY_LENGTH];
};
/** Computes SHA-256 of the input. The output buffer must be a least 32 struct _olm_aes256_iv {
* bytes long. */ uint8_t iv[AES256_IV_LENGTH];
};
struct _olm_curve25519_public_key {
uint8_t public_key[CURVE25519_KEY_LENGTH];
};
struct _olm_curve25519_private_key {
uint8_t private_key[CURVE25519_KEY_LENGTH];
};
struct _olm_curve25519_key_pair {
struct _olm_curve25519_public_key public_key;
struct _olm_curve25519_private_key private_key;
};
struct _olm_ed25519_public_key {
uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH];
};
struct _olm_ed25519_private_key {
uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH];
};
struct _olm_ed25519_key_pair {
struct _olm_ed25519_public_key public_key;
struct _olm_ed25519_private_key private_key;
};
/** The length of output the aes_encrypt_cbc function will write */
size_t _olm_crypto_aes_encrypt_cbc_length(
size_t input_length
);
/** Encrypts the input using AES256 in CBC mode with PKCS#7 padding.
* The output buffer must be big enough to hold the output including padding */
void _olm_crypto_aes_encrypt_cbc(
const struct _olm_aes256_key *key,
const struct _olm_aes256_iv *iv,
const uint8_t *input, size_t input_length,
uint8_t *output
);
/** Decrypts the input using AES256 in CBC mode. The output buffer must be at
* least the same size as the input buffer. Returns the length of the plaintext
* without padding on success or std::size_t(-1) if the padding is invalid.
*/
size_t _olm_crypto_aes_decrypt_cbc(
const struct _olm_aes256_key *key,
const struct _olm_aes256_iv *iv,
uint8_t const * input, size_t input_length,
uint8_t * output
);
/** Computes SHA-256 of the input. The output buffer must be a least
* SHA256_OUTPUT_LENGTH (32) bytes long. */
void _olm_crypto_sha256( void _olm_crypto_sha256(
uint8_t const * input, size_t input_length, uint8_t const * input, size_t input_length,
uint8_t * output uint8_t * output
...@@ -68,7 +129,7 @@ void _olm_crypto_sha256( ...@@ -68,7 +129,7 @@ void _olm_crypto_sha256(
/** HMAC: Keyed-Hashing for Message Authentication /** HMAC: Keyed-Hashing for Message Authentication
* http://tools.ietf.org/html/rfc2104 * http://tools.ietf.org/html/rfc2104
* Computes HMAC-SHA-256 of the input for the key. The output buffer must * Computes HMAC-SHA-256 of the input for the key. The output buffer must
* be at least 32 bytes long. */ * be at least SHA256_OUTPUT_LENGTH (32) bytes long. */
void _olm_crypto_hmac_sha256( void _olm_crypto_hmac_sha256(
uint8_t const * key, size_t key_length, uint8_t const * key, size_t key_length,
uint8_t const * input, size_t input_length, uint8_t const * input, size_t input_length,
...@@ -87,6 +148,53 @@ void _olm_crypto_hkdf_sha256( ...@@ -87,6 +148,53 @@ void _olm_crypto_hkdf_sha256(
); );
/** Generate a curve25519 key pair
* random_32_bytes should be CURVE25519_RANDOM_LENGTH (32) bytes long.
*/
void _olm_crypto_curve25519_generate_key(
uint8_t const * random_32_bytes,
struct _olm_curve25519_key_pair *output
);
/** Create a shared secret using our private key and their public key.
* The output buffer must be at least CURVE25519_SHARED_SECRET_LENGTH (32) bytes long.
*/
void _olm_crypto_curve25519_shared_secret(
const struct _olm_curve25519_key_pair *our_key,
const struct _olm_curve25519_public_key *their_key,
uint8_t * output
);
/** Generate an ed25519 key pair
* random_32_bytes should be ED25519_RANDOM_LENGTH (32) bytes long.
*/
void _olm_crypto_ed25519_generate_key(
uint8_t const * random_bytes,
struct _olm_ed25519_key_pair *output
);
/** Signs the message using our private key.
*
* The output buffer must be at least ED25519_SIGNATURE_LENGTH (64) bytes
* long. */
void _olm_crypto_ed25519_sign(
const struct _olm_ed25519_key_pair *our_key,
const uint8_t * message, size_t message_length,
uint8_t * output
);
/** Verify an ed25519 signature
* The signature input buffer must be ED25519_SIGNATURE_LENGTH (64) bytes long.
* Returns non-zero if the signature is valid. */
int _olm_crypto_ed25519_verify(
const struct _olm_ed25519_public_key *their_key,
const uint8_t * message, size_t message_length,
const uint8_t * signature
);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif
......
/* 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.
*/
#ifndef OLM_CRYPTO_HH_
#define OLM_CRYPTO_HH_
#include <cstdint>
#include <cstddef>
// eventually all of this needs to move into crypto.h, and everything should
// use that. For now, include crypto.h here.
#include "olm/crypto.h"
namespace olm {
struct Curve25519PublicKey {
std::uint8_t public_key[CURVE25519_KEY_LENGTH];
};
struct Curve25519KeyPair : public Curve25519PublicKey {
std::uint8_t private_key[CURVE25519_KEY_LENGTH];
};
struct Ed25519PublicKey {
std::uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH];
};
struct Ed25519KeyPair : public Ed25519PublicKey {
std::uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH];
};
/** Generate a curve25519 key pair from 32 random bytes. */
void curve25519_generate_key(
std::uint8_t const * random_32_bytes,
Curve25519KeyPair & key_pair
);
/** Create a shared secret using our private key and their public key.
* The output buffer must be at least 32 bytes long. */
void curve25519_shared_secret(
Curve25519KeyPair const & our_key,
Curve25519PublicKey const & their_key,
std::uint8_t * output
);
/** Generate a curve25519 key pair from 32 random bytes. */
void ed25519_generate_key(
std::uint8_t const * random_32_bytes,
Ed25519KeyPair & key_pair
);
/** Signs the message using our private key.
* The output buffer must be at least 64 bytes long. */
void ed25519_sign(
Ed25519KeyPair const & our_key,
std::uint8_t const * message, std::size_t message_length,
std::uint8_t * output
);
/** Verify their message using their public key.
* The signature input buffer must be 64 bytes long.
* Returns true if the signature is valid. */
bool ed25519_verify(
Ed25519PublicKey const & their_key,
std::uint8_t const * message, std::size_t message_length,
std::uint8_t const * signature
);
struct Aes256Key {
std::uint8_t key[AES256_KEY_LENGTH];
};
struct Aes256Iv {
std::uint8_t iv[AES256_IV_LENGTH];
};
/** The length of output the aes_encrypt_cbc function will write */
std::size_t aes_encrypt_cbc_length(
std::size_t input_length
);
/** Encrypts the input using AES256 in CBC mode with PKCS#7 padding.
* The output buffer must be big enough to hold the output including padding */
void aes_encrypt_cbc(
Aes256Key const & key,
Aes256Iv const & iv,
std::uint8_t const * input, std::size_t input_length,
std::uint8_t * output
);
/** Decrypts the input using AES256 in CBC mode. The output buffer must be at
* least the same size as the input buffer. Returns the length of the plaintext
* without padding on success or std::size_t(-1) if the padding is invalid.
*/
std::size_t aes_decrypt_cbc(
Aes256Key const & key,
Aes256Iv const & iv,
std::uint8_t const * input, std::size_t input_length,
std::uint8_t * output
);
} // namespace olm
#endif /* OLM_CRYPTO_HH_ */
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define OLM_PICKLE_HH_ #define OLM_PICKLE_HH_
#include "olm/list.hh" #include "olm/list.hh"
#include "olm/crypto.hh" #include "olm/crypto.h"
#include <cstring> #include <cstring>
#include <cstdint> #include <cstdint>
...@@ -109,70 +109,70 @@ std::uint8_t const * unpickle_bytes( ...@@ -109,70 +109,70 @@ std::uint8_t const * unpickle_bytes(
std::size_t pickle_length( std::size_t pickle_length(
const Curve25519PublicKey & value const _olm_curve25519_public_key & value
); );
std::uint8_t * pickle( std::uint8_t * pickle(
std::uint8_t * pos, std::uint8_t * pos,
const Curve25519PublicKey & value const _olm_curve25519_public_key & value
); );
std::uint8_t const * unpickle( std::uint8_t const * unpickle(
std::uint8_t const * pos, std::uint8_t const * end, std::uint8_t const * pos, std::uint8_t const * end,
Curve25519PublicKey & value _olm_curve25519_public_key & value
); );
std::size_t pickle_length( std::size_t pickle_length(
const Curve25519KeyPair & value const _olm_curve25519_key_pair & value
); );
std::uint8_t * pickle( std::uint8_t * pickle(
std::uint8_t * pos, std::uint8_t * pos,
const Curve25519KeyPair & value const _olm_curve25519_key_pair & value
); );
std::uint8_t const * unpickle( std::uint8_t const * unpickle(
std::uint8_t const * pos, std::uint8_t const * end, std::uint8_t const * pos, std::uint8_t const * end,
Curve25519KeyPair & value _olm_curve25519_key_pair & value
); );
std::size_t pickle_length( std::size_t pickle_length(
const Ed25519PublicKey & value const _olm_ed25519_public_key & value
); );
std::uint8_t * pickle( std::uint8_t * pickle(
std::uint8_t * pos, std::uint8_t * pos,
const Ed25519PublicKey & value const _olm_ed25519_public_key & value
); );
std::uint8_t const * unpickle( std::uint8_t const * unpickle(
std::uint8_t const * pos, std::uint8_t const * end, std::uint8_t const * pos, std::uint8_t const * end,
Ed25519PublicKey & value _olm_ed25519_public_key & value
); );
std::size_t pickle_length( std::size_t pickle_length(
const Ed25519KeyPair & value const _olm_ed25519_key_pair & value
); );
std::uint8_t * pickle( std::uint8_t * pickle(
std::uint8_t * pos, std::uint8_t * pos,
const Ed25519KeyPair & value const _olm_ed25519_key_pair & value
); );
std::uint8_t const * unpickle( std::uint8_t const * unpickle(
std::uint8_t const * pos, std::uint8_t const * end, std::uint8_t const * pos, std::uint8_t const * end,
Ed25519KeyPair & value _olm_ed25519_key_pair & value
); );
} // namespace olm } // namespace olm
......
...@@ -13,7 +13,9 @@ ...@@ -13,7 +13,9 @@
* limitations under the License. * limitations under the License.
*/ */
#include "olm/crypto.hh" #include <cstdint>
#include "olm/crypto.h"
#include "olm/list.hh" #include "olm/list.hh"
#include "olm/error.h" #include "olm/error.h"
...@@ -41,19 +43,19 @@ struct MessageKey { ...@@ -41,19 +43,19 @@ struct MessageKey {
struct SenderChain { struct SenderChain {
Curve25519KeyPair ratchet_key; _olm_curve25519_key_pair ratchet_key;
ChainKey chain_key; ChainKey chain_key;
}; };
struct ReceiverChain { struct ReceiverChain {
Curve25519PublicKey ratchet_key; _olm_curve25519_public_key ratchet_key;
ChainKey chain_key; ChainKey chain_key;
}; };
struct SkippedMessageKey { struct SkippedMessageKey {
Curve25519PublicKey ratchet_key; _olm_curve25519_public_key ratchet_key;
MessageKey message_key; MessageKey message_key;
}; };
...@@ -108,14 +110,14 @@ struct Ratchet { ...@@ -108,14 +110,14 @@ struct Ratchet {
* remote's first ratchet key */ * remote's first ratchet key */
void initialise_as_bob( void initialise_as_bob(
std::uint8_t const * shared_secret, std::size_t shared_secret_length, std::uint8_t const * shared_secret, std::size_t shared_secret_length,
Curve25519PublicKey const & their_ratchet_key _olm_curve25519_public_key const & their_ratchet_key
); );
/** Initialise the session using a shared secret and the public/private key /** Initialise the session using a shared secret and the public/private key
* pair for the first ratchet key */ * pair for the first ratchet key */
void initialise_as_alice( void initialise_as_alice(
std::uint8_t const * shared_secret, std::size_t shared_secret_length, std::uint8_t const * shared_secret, std::size_t shared_secret_length,
Curve25519KeyPair const & our_ratchet_key _olm_curve25519_key_pair const & our_ratchet_key
); );
/** The number of bytes of output the encrypt method will write for /** The number of bytes of output the encrypt method will write for
......
...@@ -35,9 +35,9 @@ struct Session { ...@@ -35,9 +35,9 @@ struct Session {
bool received_message; bool received_message;
Curve25519PublicKey alice_identity_key; _olm_curve25519_public_key alice_identity_key;
Curve25519PublicKey alice_base_key; _olm_curve25519_public_key alice_base_key;
Curve25519PublicKey bob_one_time_key; _olm_curve25519_public_key bob_one_time_key;
/** The number of random bytes that are needed to create a new outbound /** The number of random bytes that are needed to create a new outbound
* session. This will be 64 bytes since two ephemeral keys are needed. */ * session. This will be 64 bytes since two ephemeral keys are needed. */
...@@ -48,8 +48,8 @@ struct Session { ...@@ -48,8 +48,8 @@ struct Session {
* NOT_ENOUGH_RANDOM if the number of random bytes was too small. */ * NOT_ENOUGH_RANDOM if the number of random bytes was too small. */
std::size_t new_outbound_session( std::size_t new_outbound_session(
Account const & local_account, Account const & local_account,
Curve25519PublicKey const & identity_key, _olm_curve25519_public_key const & identity_key,
Curve25519PublicKey const & one_time_key, _olm_curve25519_public_key const & one_time_key,
std::uint8_t const * random, std::size_t random_length std::uint8_t const * random, std::size_t random_length
); );
...@@ -59,7 +59,7 @@ struct Session { ...@@ -59,7 +59,7 @@ struct Session {
* the message headers could not be decoded. */ * the message headers could not be decoded. */
std::size_t new_inbound_session( std::size_t new_inbound_session(
Account & local_account, Account & local_account,
Curve25519PublicKey const * their_identity_key, _olm_curve25519_public_key const * their_identity_key,
std::uint8_t const * pre_key_message, std::size_t message_length std::uint8_t const * pre_key_message, std::size_t message_length
); );
...@@ -82,7 +82,7 @@ struct Session { ...@@ -82,7 +82,7 @@ struct Session {
* session does not match or the pre-key message could not be decoded. * session does not match or the pre-key message could not be decoded.
*/ */
bool matches_inbound_session( bool matches_inbound_session(
Curve25519PublicKey const * their_identity_key, _olm_curve25519_public_key const * their_identity_key,
std::uint8_t const * pre_key_message, std::size_t message_length std::uint8_t const * pre_key_message, std::size_t message_length
); );
......
...@@ -21,9 +21,9 @@ ...@@ -21,9 +21,9 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
namespace olm { struct _olm_ed25519_public_key;
struct Ed25519PublicKey; namespace olm {
struct Utility { struct Utility {