diff --git a/Makefile b/Makefile index 7995b28..cbdb948 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ JS_TARGET := javascript/olm.js JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json -PUBLIC_HEADERS := include/olm/olm.hh +PUBLIC_HEADERS := include/olm/olm.h SOURCES := $(wildcard src/*.cpp) $(wildcard src/*.c) RELEASE_OBJECTS := $(patsubst src/%,$(BUILD_DIR)/release/%,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES)))) diff --git a/include/olm/account.hh b/include/olm/account.hh index 209139a..6ea0d19 100644 --- a/include/olm/account.hh +++ b/include/olm/account.hh @@ -17,7 +17,7 @@ #include "olm/list.hh" #include "olm/crypto.hh" -#include "olm/error.hh" +#include "olm/error.h" #include @@ -44,7 +44,7 @@ struct Account { IdentityKeys identity_keys; List one_time_keys; std::uint32_t next_one_time_key_id; - ErrorCode last_error; + OlmErrorCode last_error; /** Number of random bytes needed to create a new account */ std::size_t new_account_random_length(); diff --git a/include/olm/base64.h b/include/olm/base64.h new file mode 100644 index 0000000..80384a8 --- /dev/null +++ b/include/olm/base64.h @@ -0,0 +1,77 @@ +/* Copyright 2015, 2016 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. + */ + +/* C bindings for base64 functions */ + + +#ifndef OLM_BASE64_H_ +#define OLM_BASE64_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * The number of bytes of unpadded base64 needed to encode a length of input. + */ +size_t _olm_encode_base64_length( + size_t input_length +); + +/** + * Encode the raw input as unpadded base64. + * Writes encode_base64_length(input_length) bytes to the output buffer. + * The input can overlap with the last three quarters of the output buffer. + * That is, the input pointer may be output + output_length - input_length. + * + * Returns number of bytes encoded + */ +size_t _olm_encode_base64( + uint8_t const * input, size_t input_length, + uint8_t * output +); + +/** + * The number of bytes of raw data a length of unpadded base64 will encode to. + * Returns size_t(-1) if the length is not a valid length for base64. + */ +size_t _olm_decode_base64_length( + size_t input_length +); + +/** + * Decodes the unpadded base64 input to raw bytes. + * Writes decode_base64_length(input_length) bytes to the output buffer. + * The output can overlap with the first three quarters of the input buffer. + * That is, the input pointers and output pointer may be the same. + * + * Returns number of bytes decoded + */ +size_t _olm_decode_base64( + uint8_t const * input, size_t input_length, + uint8_t * output +); + + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif /* OLM_BASE64_H_ */ diff --git a/include/olm/cipher.h b/include/olm/cipher.h new file mode 100644 index 0000000..b26f8ba --- /dev/null +++ b/include/olm/cipher.h @@ -0,0 +1,138 @@ +/* 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_CIPHER_H_ +#define OLM_CIPHER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct _olm_cipher; + +struct _olm_cipher_ops { + /** + * Returns the length of the message authentication code that will be + * appended to the output. + */ + size_t (*mac_length)(const struct _olm_cipher *cipher); + + /** + * Returns the length of cipher-text for a given length of plain-text. + */ + size_t (*encrypt_ciphertext_length)( + const struct _olm_cipher *cipher, + size_t plaintext_length + ); + + /* + * Encrypts the plain-text into the output buffer and authenticates the + * contents of the output buffer covering both cipher-text and any other + * associated data in the output buffer. + * + * |---------------------------------------output_length-->| + * output |--ciphertext_length-->| |---mac_length-->| + * ciphertext + * + * The plain-text pointers and cipher-text pointers may be the same. + * + * Returns size_t(-1) if the length of the cipher-text or the output + * buffer is too small. Otherwise returns the length of the output buffer. + */ + size_t (*encrypt)( + const struct _olm_cipher *cipher, + uint8_t const * key, size_t key_length, + uint8_t const * plaintext, size_t plaintext_length, + uint8_t * ciphertext, size_t ciphertext_length, + uint8_t * output, size_t output_length + ); + + /** + * Returns the maximum length of plain-text that a given length of + * cipher-text can contain. + */ + size_t (*decrypt_max_plaintext_length)( + const struct _olm_cipher *cipher, + size_t ciphertext_length + ); + + /** + * Authenticates the input and decrypts the cipher-text into the plain-text + * buffer. + * + * |----------------------------------------input_length-->| + * input |--ciphertext_length-->| |---mac_length-->| + * ciphertext + * + * The plain-text pointers and cipher-text pointers may be the same. + * + * Returns size_t(-1) if the length of the plain-text buffer is too + * small or if the authentication check fails. Otherwise returns the length + * of the plain text. + */ + size_t (*decrypt)( + const struct _olm_cipher *cipher, + uint8_t const * key, size_t key_length, + uint8_t const * input, size_t input_length, + uint8_t const * ciphertext, size_t ciphertext_length, + uint8_t * plaintext, size_t max_plaintext_length + ); +}; + +struct _olm_cipher { + const struct _olm_cipher_ops *ops; + /* cipher-specific fields follow */ +}; + +struct _olm_cipher_aes_sha_256 { + struct _olm_cipher base_cipher; + + /** context string for the HKDF used for deriving the AES256 key, HMAC key, + * and AES IV, from the key material passed to encrypt/decrypt. + */ + uint8_t const * kdf_info; + + /** length of context string kdf_info */ + size_t kdf_info_length; +}; + +extern const struct _olm_cipher_ops _olm_cipher_aes_sha_256_ops; + +/** + * get an initializer for an instance of struct _olm_cipher_aes_sha_256. + * + * To use it, declare: + * + * struct _olm_cipher_aes_sha_256 MY_CIPHER = + * OLM_CIPHER_INIT_AES_SHA_256("MY_KDF"); + * struct _olm_cipher *cipher = OLM_CIPHER_BASE(&MY_CIPHER); + */ +#define OLM_CIPHER_INIT_AES_SHA_256(KDF_INFO) { \ + .base_cipher = { &_olm_cipher_aes_sha_256_ops },\ + .kdf_info = (uint8_t *)(KDF_INFO), \ + .kdf_info_length = sizeof(KDF_INFO) - 1 \ +} +#define OLM_CIPHER_BASE(CIPHER) \ + (&((CIPHER)->base_cipher)) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* OLM_CIPHER_H_ */ diff --git a/include/olm/cipher.hh b/include/olm/cipher.hh deleted file mode 100644 index c561972..0000000 --- a/include/olm/cipher.hh +++ /dev/null @@ -1,132 +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. - */ - -#ifndef OLM_CIPHER_HH_ -#define OLM_CIPHER_HH_ - -#include -#include - -namespace olm { - -class Cipher { -public: - virtual ~Cipher(); - - /** - * Returns the length of the message authentication code that will be - * appended to the output. - */ - virtual std::size_t mac_length() const = 0; - - /** - * Returns the length of cipher-text for a given length of plain-text. - */ - virtual std::size_t encrypt_ciphertext_length( - std::size_t plaintext_length - ) const = 0; - - /* - * Encrypts the plain-text into the output buffer and authenticates the - * contents of the output buffer covering both cipher-text and any other - * associated data in the output buffer. - * - * |---------------------------------------output_length-->| - * output |--ciphertext_length-->| |---mac_length-->| - * ciphertext - * - * The plain-text pointers and cipher-text pointers may be the same. - * - * Returns std::size_t(-1) if the length of the cipher-text or the output - * buffer is too small. Otherwise returns the length of the output buffer. - */ - virtual std::size_t 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, - std::uint8_t * output, std::size_t output_length - ) const = 0; - - /** - * Returns the maximum length of plain-text that a given length of - * cipher-text can contain. - */ - virtual std::size_t decrypt_max_plaintext_length( - std::size_t ciphertext_length - ) const = 0; - - /** - * Authenticates the input and decrypts the cipher-text into the plain-text - * buffer. - * - * |----------------------------------------input_length-->| - * input |--ciphertext_length-->| |---mac_length-->| - * ciphertext - * - * The plain-text pointers and cipher-text pointers may be the same. - * - * Returns std::size_t(-1) if the length of the plain-text buffer is too - * small or if the authentication check fails. Otherwise returns the length - * of the plain text. - */ - virtual std::size_t 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, - std::uint8_t * plaintext, std::size_t max_plaintext_length - ) const = 0; -}; - - -class CipherAesSha256 : public Cipher { -public: - CipherAesSha256( - std::uint8_t const * kdf_info, std::size_t kdf_info_length - ); - - virtual std::size_t mac_length() const; - - virtual std::size_t encrypt_ciphertext_length( - std::size_t plaintext_length - ) const; - - virtual std::size_t 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, - std::uint8_t * output, std::size_t output_length - ) const; - - virtual std::size_t decrypt_max_plaintext_length( - std::size_t ciphertext_length - ) const; - - virtual std::size_t 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, - std::uint8_t * plaintext, std::size_t max_plaintext_length - ) const; - -private: - std::uint8_t const * kdf_info; - std::size_t kdf_info_length; -}; - - -} // namespace - - -#endif /* OLM_CIPHER_HH_ */ diff --git a/include/olm/crypto.h b/include/olm/crypto.h new file mode 100644 index 0000000..31b9b60 --- /dev/null +++ b/include/olm/crypto.h @@ -0,0 +1,65 @@ +/* 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. + */ + +/* C-compatible crpyto utility functions. At some point all of crypto.hh will + * move here. + */ + +#ifndef OLM_CRYPTO_H_ +#define OLM_CRYPTO_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +const size_t SHA256_OUTPUT_LENGTH = 32; + +/** Computes SHA-256 of the input. The output buffer must be a least 32 + * bytes long. */ +void _olm_crypto_sha256( + uint8_t const * input, size_t input_length, + uint8_t * output +); + +/** HMAC: Keyed-Hashing for Message Authentication + * http://tools.ietf.org/html/rfc2104 + * Computes HMAC-SHA-256 of the input for the key. The output buffer must + * be at least 32 bytes long. */ +void _olm_crypto_hmac_sha256( + uint8_t const * key, size_t key_length, + uint8_t const * input, size_t input_length, + uint8_t * output +); + + +/** HMAC-based Key Derivation Function (HKDF) + * https://tools.ietf.org/html/rfc5869 + * Derives key material from the input bytes. */ +void _olm_crypto_hkdf_sha256( + uint8_t const * input, size_t input_length, + uint8_t const * info, size_t info_length, + uint8_t const * salt, size_t salt_length, + uint8_t * output, size_t output_length +); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* OLM_CRYPTO_H_ */ diff --git a/include/olm/crypto.hh b/include/olm/crypto.hh index 159bac7..2380cd3 100644 --- a/include/olm/crypto.hh +++ b/include/olm/crypto.hh @@ -19,6 +19,11 @@ #include #include +// 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 { static const std::size_t KEY_LENGTH = 32; @@ -144,38 +149,6 @@ std::size_t aes_decrypt_cbc( ); -/** Computes SHA-256 of the input. The output buffer must be a least 32 - * bytes long. */ -void sha256( - std::uint8_t const * input, std::size_t input_length, - std::uint8_t * output -); - - -const std::size_t SHA256_OUTPUT_LENGTH = 32; - - -/** HMAC: Keyed-Hashing for Message Authentication - * http://tools.ietf.org/html/rfc2104 - * Computes HMAC-SHA-256 of the input for the key. The output buffer must - * be at least 32 bytes long. */ -void 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 -); - - -/** HMAC-based Key Derivation Function (HKDF) - * https://tools.ietf.org/html/rfc5869 - * Derives key material from the input bytes. */ -void hkdf_sha256( - std::uint8_t const * input, std::size_t input_length, - std::uint8_t const * info, std::size_t info_length, - std::uint8_t const * salt, std::size_t salt_length, - std::uint8_t * output, std::size_t output_length -); - } // namespace olm #endif /* OLM_CRYPTO_HH_ */ diff --git a/include/olm/error.h b/include/olm/error.h new file mode 100644 index 0000000..a4f373e --- /dev/null +++ b/include/olm/error.h @@ -0,0 +1,40 @@ +/* Copyright 2015-2016 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_ERROR_H_ +#define OLM_ERROR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum OlmErrorCode { + OLM_SUCCESS = 0, /*!< There wasn't an error */ + OLM_NOT_ENOUGH_RANDOM = 1, /*!< Not enough entropy was supplied */ + OLM_OUTPUT_BUFFER_TOO_SMALL = 2, /*!< Supplied output buffer is too small */ + OLM_BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */ + OLM_BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */ + OLM_BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */ + OLM_BAD_MESSAGE_KEY_ID = 6, /*!< The message references an unknown key id */ + OLM_INVALID_BASE64 = 7, /*!< The input base64 was invalid */ + OLM_BAD_ACCOUNT_KEY = 8, /*!< The supplied account key is invalid */ + OLM_UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */ + OLM_CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */ +}; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* OLM_ERROR_H_ */ diff --git a/include/olm/error.hh b/include/olm/error.hh deleted file mode 100644 index b0d3764..0000000 --- a/include/olm/error.hh +++ /dev/null @@ -1,36 +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. - */ -#ifndef ERROR_HH_ -#define ERROR_HH_ - -namespace olm { - -enum struct ErrorCode { - SUCCESS = 0, /*!< There wasn't an error */ - NOT_ENOUGH_RANDOM = 1, /*!< Not enough entropy was supplied */ - OUTPUT_BUFFER_TOO_SMALL = 2, /*!< Supplied output buffer is too small */ - BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */ - BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */ - BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */ - BAD_MESSAGE_KEY_ID = 6, /*!< The message references an unknown key id */ - INVALID_BASE64 = 7, /*!< The input base64 was invalid */ - BAD_ACCOUNT_KEY = 8, /*!< The supplied account key is invalid */ - UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */ - CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */ -}; - -} // namespace olm - -#endif /* ERROR_HH_ */ diff --git a/include/olm/memory.h b/include/olm/memory.h new file mode 100644 index 0000000..cc346d0 --- /dev/null +++ b/include/olm/memory.h @@ -0,0 +1,41 @@ +/* Copyright 2015, 2016 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. + */ + +/* C bindings for memory functions */ + + +#ifndef OLM_MEMORY_H_ +#define OLM_MEMORY_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Clear the memory held in the buffer. This is more resilient to being + * optimised away than memset or bzero. + */ +void _olm_unset( + void volatile * buffer, size_t buffer_length +); + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif /* OLM_MEMORY_H_ */ diff --git a/include/olm/olm.h b/include/olm/olm.h new file mode 100644 index 0000000..15b895b --- /dev/null +++ b/include/olm/olm.h @@ -0,0 +1,430 @@ +/* Copyright 2015, 2016 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_H_ +#define OLM_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static const size_t OLM_MESSAGE_TYPE_PRE_KEY = 0; +static const size_t OLM_MESSAGE_TYPE_MESSAGE = 1; + +typedef struct OlmAccount OlmAccount; +typedef struct OlmSession OlmSession; +typedef struct OlmUtility OlmUtility; + +/** The size of an account object in bytes */ +size_t olm_account_size(); + +/** The size of a session object in bytes */ +size_t olm_session_size(); + +/** The size of a utility object in bytes */ +size_t olm_utility_size(); + +/** Initialise an account object using the supplied memory + * The supplied memory must be at least olm_account_size() bytes */ +OlmAccount * olm_account( + void * memory +); + +/** Initialise a session object using the supplied memory + * The supplied memory must be at least olm_session_size() bytes */ +OlmSession * olm_session( + void * memory +); + +/** Initialise a utility object using the supplied memory + * The supplied memory must be at least olm_utility_size() bytes */ +OlmUtility * olm_utility( + void * memory +); + +/** The value that olm will return from a function if there was an error */ +size_t olm_error(); + +/** A null terminated string describing the most recent error to happen to an + * account */ +const char * olm_account_last_error( + OlmAccount * account +); + +/** A null terminated string describing the most recent error to happen to a + * session */ +const char * olm_session_last_error( + OlmSession * session +); + +/** A null terminated string describing the most recent error to happen to a + * utility */ +const char * olm_utility_last_error( + OlmUtility * utility +); + +/** Clears the memory used to back this account */ +size_t olm_clear_account( + OlmAccount * account +); + +/** Clears the memory used to back this session */ +size_t olm_clear_session( + OlmSession * session +); + +/** Clears the memory used to back this utility */ +size_t olm_clear_utility( + OlmUtility * utility +); + +/** Returns the number of bytes needed to store an account */ +size_t olm_pickle_account_length( + OlmAccount * account +); + +/** Returns the number of bytes needed to store a session */ +size_t olm_pickle_session_length( + OlmSession * session +); + +/** Stores an account as a base64 string. Encrypts the account using the + * supplied key. Returns the length of the pickled account on success. + * Returns olm_error() on failure. If the pickle output buffer + * is smaller than olm_pickle_account_length() then + * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ +size_t olm_pickle_account( + OlmAccount * account, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +); + +/** Stores a session as a base64 string. Encrypts the session using the + * supplied key. Returns the length of the pickled session on success. + * Returns olm_error() on failure. If the pickle output buffer + * is smaller than olm_pickle_session_length() then + * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ +size_t olm_pickle_session( + OlmSession * session, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +); + +/** Loads an account from a pickled base64 string. Decrypts the account using + * the supplied key. Returns olm_error() on failure. If the key doesn't + * match the one used to encrypt the account then olm_account_last_error() + * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then + * olm_account_last_error() will be "INVALID_BASE64". The input pickled + * buffer is destroyed */ +size_t olm_unpickle_account( + OlmAccount * account, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +); + +/** Loads a session from a pickled base64 string. Decrypts the session using + * the supplied key. Returns olm_error() on failure. If the key doesn't + * match the one used to encrypt the account then olm_session_last_error() + * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then + * olm_session_last_error() will be "INVALID_BASE64". The input pickled + * buffer is destroyed */ +size_t olm_unpickle_session( + OlmSession * session, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +); + +/** The number of random bytes needed to create an account.*/ +size_t olm_create_account_random_length( + OlmAccount * account +); + +/** Creates a new account. Returns olm_error() on failure. If weren't + * enough random bytes then olm_account_last_error() will be + * "NOT_ENOUGH_RANDOM" */ +size_t olm_create_account( + OlmAccount * account, + void * random, size_t random_length +); + +/** The size of the output buffer needed to hold the identity keys */ +size_t olm_account_identity_keys_length( + OlmAccount * account +); + +/** Writes the public parts of the identity keys for the account into the + * identity_keys output buffer. Returns olm_error() on failure. If the + * identity_keys buffer was too small then olm_account_last_error() will be + * "OUTPUT_BUFFER_TOO_SMALL". */ +size_t olm_account_identity_keys( + OlmAccount * account, + void * identity_keys, size_t identity_key_length +); + + +/** The length of an ed25519 signature encoded as base64. */ +size_t olm_account_signature_length( + OlmAccount * account +); + +/** Signs a message with the ed25519 key for this account. Returns olm_error() + * on failure. If the signature buffer was too small then + * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ +size_t olm_account_sign( + OlmAccount * account, + void const * message, size_t message_length, + void * signature, size_t signature_length +); + +/** The size of the output buffer needed to hold the one time keys */ +size_t olm_account_one_time_keys_length( + OlmAccount * account +); + +/** Writes the public parts of the unpublished one time keys for the account + * into the one_time_keys output buffer. Returns olm_error() on failure. + * If the one_time_keys buffer was too small then olm_account_last_error() + * will be "OUTPUT_BUFFER_TOO_SMALL". */ +size_t olm_account_one_time_keys( + OlmAccount * account, + void * one_time_keys, size_t one_time_keys_length +); + +/** Marks the current set of one time keys as being published. */ +size_t olm_account_mark_keys_as_published( + OlmAccount * account +); + +/** The largest number of one time keys this account can store. */ +size_t olm_account_max_number_of_one_time_keys( + OlmAccount * account +); + +/** The number of random bytes needed to generate a given number of new one + * time keys. */ +size_t olm_account_generate_one_time_keys_random_length( + OlmAccount * account, + size_t number_of_keys +); + +/** Generates a number of new one time keys. If the total number of keys stored + * by this account exceeds max_number_of_one_time_keys() then the old keys are + * discarded. Returns olm_error() on error. If the number of random bytes is + * too small then olm_account_last_error() will be "NOT_ENOUGH_RANDOM". */ +size_t olm_account_generate_one_time_keys( + OlmAccount * account, + size_t number_of_keys, + void * random, size_t random_length +); + +/** The number of random bytes needed to create an outbound session */ +size_t olm_create_outbound_session_random_length( + OlmSession * session +); + +/** Creates a new out-bound session for sending messages to a given identity_key + * and one_time_key. Returns olm_error() on failure. If the keys couldn't be + * decoded as base64 then olm_session_last_error() will be "INVALID_BASE64" + * If there weren't enough random bytes then olm_session_last_error() will + * be "NOT_ENOUGH_RANDOM". */ +size_t olm_create_outbound_session( + OlmSession * session, + OlmAccount * account, + void const * their_identity_key, size_t their_identity_key_length, + void const * their_one_time_key, size_t their_one_time_key_length, + void * random, size_t random_length +); + +/** Create a new in-bound session for sending/receiving messages from an + * incoming PRE_KEY message. Returns olm_error() on failure. If the base64 + * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64". + * If the message was for an unsupported protocol version then + * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message + * couldn't be decoded then then olm_session_last_error() will be + * "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time + * key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */ +size_t olm_create_inbound_session( + OlmSession * session, + OlmAccount * account, + void * one_time_key_message, size_t message_length +); + +/** Create a new in-bound session for sending/receiving messages from an + * incoming PRE_KEY message. Returns olm_error() on failure. If the base64 + * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64". + * If the message was for an unsupported protocol version then + * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message + * couldn't be decoded then then olm_session_last_error() will be + * "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time + * key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */ +size_t olm_create_inbound_session_from( + OlmSession * session, + OlmAccount * account, + void const * their_identity_key, size_t their_identity_key_length, + void * one_time_key_message, size_t message_length +); + +/** The length of the buffer needed to return the id for this session. */ +size_t olm_session_id_length( + OlmSession * session +); + +/** An identifier for this session. Will be the same for both ends of the + * conversation. If the id buffer is too small then olm_session_last_error() + * will be "OUTPUT_BUFFER_TOO_SMALL". */ +size_t olm_session_id( + OlmSession * session, + void * id, size_t id_length +); + +/** Checks if the PRE_KEY message is for this in-bound session. This can happen + * if multiple messages are sent to this account before this account sends a + * message in reply. Returns olm_error() on failure. If the base64 + * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64". + * If the message was for an unsupported protocol version then + * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message + * couldn't be decoded then then olm_session_last_error() will be + * "BAD_MESSAGE_FORMAT". */ +size_t olm_matches_inbound_session( + OlmSession * session, + void * one_time_key_message, size_t message_length +); + +/** Checks if the PRE_KEY message is for this in-bound session. This can happen + * if multiple messages are sent to this account before this account sends a + * message in reply. Returns olm_error() on failure. If the base64 + * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64". + * If the message was for an unsupported protocol version then + * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message + * couldn't be decoded then then olm_session_last_error() will be + * "BAD_MESSAGE_FORMAT". */ +size_t olm_matches_inbound_session_from( + OlmSession * session, + void const * their_identity_key, size_t their_identity_key_length, + void * one_time_key_message, size_t message_length +); + +/** Removes the one time keys that the session used from the account. Returns + * olm_error() on failure. If the account doesn't have any matching one time + * keys then olm_account_last_error() will be "BAD_MESSAGE_KEY_ID". */ +size_t olm_remove_one_time_keys( + OlmAccount * account, + OlmSession * session +); + +/** The type of the next message that olm_encrypt() will return. Returns + * OLM_MESSAGE_TYPE_PRE_KEY if the message will be a PRE_KEY message. + * Returns OLM_MESSAGE_TYPE_MESSAGE if the message will be a normal message. + * Returns olm_error on failure. */ +size_t olm_encrypt_message_type( + OlmSession * session +); + +/** The number of random bytes needed to encrypt the next message. */ +size_t olm_encrypt_random_length( + OlmSession * session +); + +/** The size of the next message in bytes for the given number of plain-text + * bytes. */ +size_t olm_encrypt_message_length( + OlmSession * session, + size_t plaintext_length +); + +/** Encrypts a message using the session. Returns the length of the message in + * bytes on success. Writes the message as base64 into the message buffer. + * Returns olm_error() on failure. If the message buffer is too small then + * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If there + * weren't enough random bytes then olm_session_last_error() will be + * "NOT_ENOUGH_RANDOM". */ +size_t olm_encrypt( + OlmSession * session, + void const * plaintext, size_t plaintext_length, + void * random, size_t random_length, + void * message, size_t message_length +); + +/** The maximum number of bytes of plain-text a given message could decode to. + * The actual size could be different due to padding. The input message buffer + * is destroyed. Returns olm_error() on failure. If the message base64 + * couldn't be decoded then olm_session_last_error() will be + * "INVALID_BASE64". If the message is for an unsupported version of the + * protocol then olm_session_last_error() will be "BAD_MESSAGE_VERSION". + * If the message couldn't be decoded then olm_session_last_error() will be + * "BAD_MESSAGE_FORMAT". */ +size_t olm_decrypt_max_plaintext_length( + OlmSession * session, + size_t message_type, + void * message, size_t message_length +); + +/** Decrypts a message using the session. The input message buffer is destroyed. + * Returns the length of the plain-text on success. Returns olm_error() on + * failure. If the plain-text buffer is smaller than + * olm_decrypt_max_plaintext_length() then olm_session_last_error() + * will be "OUTPUT_BUFFER_TOO_SMALL". If the base64 couldn't be decoded then + * olm_session_last_error() will be "INVALID_BASE64". If the message is for + * an unsupported version of the protocol then olm_session_last_error() will + * be "BAD_MESSAGE_VERSION". If the message couldn't be decoded then + * olm_session_last_error() will be BAD_MESSAGE_FORMAT". + * If the MAC on the message was invalid then olm_session_last_error() will + * be "BAD_MESSAGE_MAC". */ +size_t olm_decrypt( + OlmSession * session, + size_t message_type, + void * message, size_t message_length, + void * plaintext, size_t max_plaintext_length +); + +/** The length of the buffer needed to hold the SHA-256 hash. */ +size_t olm_sha256_length( + OlmUtility * utility +); + +/** Calculates the SHA-256 hash of the input and encodes it as base64. If the + * output buffer is smaller than olm_sha256_length() then + * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */ +size_t olm_sha256( + OlmUtility * utility, + void const * input, size_t input_length, + void * output, size_t output_length +); + +/** Verify an ed25519 signature. If the key was too small then + * olm_session_last_error will be "INVALID_BASE64". If the signature was invalid + * then olm_session_last_error() will be "BAD_MESSAGE_MAC". */ +size_t olm_ed25519_verify( + OlmUtility * utility, + void const * key, size_t key_length, + void const * message, size_t message_length, + void * signature, size_t signature_length +); + +/** + * Set the log level. By default, 1, which logs only FATAL messages. + */ +void olm_set_log_level( + unsigned int level +); + +#ifdef __cplusplus +} +#endif + +#endif /* OLM_HH_ */ diff --git a/include/olm/olm.hh b/include/olm/olm.hh index ffecb10..5ca59c3 100644 --- a/include/olm/olm.hh +++ b/include/olm/olm.hh @@ -1,429 +1,4 @@ -/* Copyright 2015, 2016 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. +/* this file exists only for compatibility with existing applications. + * You should use "#include " instead. */ -#ifndef OLM_HH_ -#define OLM_HH_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -static const size_t OLM_MESSAGE_TYPE_PRE_KEY = 0; -static const size_t OLM_MESSAGE_TYPE_MESSAGE = 1; - -typedef struct OlmAccount OlmAccount; -typedef struct OlmSession OlmSession; -typedef struct OlmUtility OlmUtility; - -/** The size of an account object in bytes */ -size_t olm_account_size(); - -/** The size of a session object in bytes */ -size_t olm_session_size(); - -/** The size of a utility object in bytes */ -size_t olm_utility_size(); - -/** Initialise an account object using the supplied memory - * The supplied memory must be at least olm_account_size() bytes */ -OlmAccount * olm_account( - void * memory -); - -/** Initialise a session object using the supplied memory - * The supplied memory must be at least olm_session_size() bytes */ -OlmSession * olm_session( - void * memory -); - -/** Initialise a utility object using the supplied memory - * The supplied memory must be at least olm_utility_size() bytes */ -OlmUtility * olm_utility( - void * memory -); - -/** The value that olm will return from a function if there was an error */ -size_t olm_error(); - -/** A null terminated string describing the most recent error to happen to an - * account */ -const char * olm_account_last_error( - OlmAccount * account -); - -/** A null terminated string describing the most recent error to happen to a - * session */ -const char * olm_session_last_error( - OlmSession * session -); - -/** A null terminated string describing the most recent error to happen to a - * utility */ -const char * olm_utility_last_error( - OlmUtility * utility -); - -/** Clears the memory used to back this account */ -size_t olm_clear_account( - OlmAccount * account -); - -/** Clears the memory used to back this session */ -size_t olm_clear_session( - OlmSession * session -); - -/** Clears the memory used to back this utility */ -size_t olm_clear_utility( - OlmUtility * utility -); - -/** Returns the number of bytes needed to store an account */ -size_t olm_pickle_account_length( - OlmAccount * account -); - -/** Returns the number of bytes needed to store a session */ -size_t olm_pickle_session_length( - OlmSession * session -); - -/** Stores an account as a base64 string. Encrypts the account using the - * supplied key. Returns the length of the pickled account on success. - * Returns olm_error() on failure. If the pickle output buffer - * is smaller than olm_pickle_account_length() then - * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ -size_t olm_pickle_account( - OlmAccount * account, - void const * key, size_t key_length, - void * pickled, size_t pickled_length -); - -/** Stores a session as a base64 string. Encrypts the session using the - * supplied key. Returns the length of the pickled session on success. - * Returns olm_error() on failure. If the pickle output buffer - * is smaller than olm_pickle_session_length() then - * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ -size_t olm_pickle_session( - OlmSession * session, - void const * key, size_t key_length, - void * pickled, size_t pickled_length -); - -/** Loads an account from a pickled base64 string. Decrypts the account using - * the supplied key. Returns olm_error() on failure. If the key doesn't - * match the one used to encrypt the account then olm_account_last_error() - * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then - * olm_account_last_error() will be "INVALID_BASE64". The input pickled - * buffer is destroyed */ -size_t olm_unpickle_account( - OlmAccount * account, - void const * key, size_t key_length, - void * pickled, size_t pickled_length -); - -/** Loads a session from a pickled base64 string. Decrypts the session using - * the supplied key. Returns olm_error() on failure. If the key doesn't - * match the one used to encrypt the account then olm_session_last_error() - * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then - * olm_session_last_error() will be "INVALID_BASE64". The input pickled - * buffer is destroyed */ -size_t olm_unpickle_session( - OlmSession * session, - void const * key, size_t key_length, - void * pickled, size_t pickled_length -); - -/** The number of random bytes needed to create an account.*/ -size_t olm_create_account_random_length( - OlmAccount * account -); - -/** Creates a new account. Returns olm_error() on failure. If weren't - * enough random bytes then olm_account_last_error() will be - * "NOT_ENOUGH_RANDOM" */ -size_t olm_create_account( - OlmAccount * account, - void * random, size_t random_length -); - -/** The size of the output buffer needed to hold the identity keys */ -size_t olm_account_identity_keys_length( - OlmAccount * account -); - -/** Writes the public parts of the identity keys for the account into the - * identity_keys output buffer. Returns olm_error() on failure. If the - * identity_keys buffer was too small then olm_account_last_error() will be - * "OUTPUT_BUFFER_TOO_SMALL". */ -size_t olm_account_identity_keys( - OlmAccount * account, - void * identity_keys, size_t identity_key_length -); - - -/** The length of an ed25519 signature encoded as base64. */ -size_t olm_account_signature_length( - OlmAccount * account -); - -/** Signs a message with the ed25519 key for this account. Returns olm_error() - * on failure. If the signature buffer was too small then - * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ -size_t olm_account_sign( - OlmAccount * account, - void const * message, size_t message_length, - void * signature, size_t signature_length -); - -/** The size of the output buffer needed to hold the one time keys */ -size_t olm_account_one_time_keys_length( - OlmAccount * account -); - -/** Writes the public parts of the unpublished one time keys for the account - * into the one_time_keys output buffer. Returns olm_error() on failure. - * If the one_time_keys buffer was too small then olm_account_last_error() - * will be "OUTPUT_BUFFER_TOO_SMALL". */ -size_t olm_account_one_time_keys( - OlmAccount * account, - void * one_time_keys, size_t one_time_keys_length -); - -/** Marks the current set of one time keys as being published. */ -size_t olm_account_mark_keys_as_published( - OlmAccount * account -); - -/** The largest number of one time keys this account can store. */ -size_t olm_account_max_number_of_one_time_keys( - OlmAccount * account -); - -/** The number of random bytes needed to generate a given number of new one - * time keys. */ -size_t olm_account_generate_one_time_keys_random_length( - OlmAccount * account, - size_t number_of_keys -); - -/** Generates a number of new one time keys. If the total number of keys stored - * by this account exceeds max_number_of_one_time_keys() then the old keys are - * discarded. Returns olm_error() on error. If the number of random bytes is - * too small then olm_account_last_error() will be "NOT_ENOUGH_RANDOM". */ -size_t olm_account_generate_one_time_keys( - OlmAccount * account, - size_t number_of_keys, - void * random, size_t random_length -); - -/** The number of random bytes needed to create an outbound session */ -size_t olm_create_outbound_session_random_length( - OlmSession * session -); - -/** Creates a new out-bound session for sending messages to a given identity_key - * and one_time_key. Returns olm_error() on failure. If the keys couldn't be - * decoded as base64 then olm_session_last_error() will be "INVALID_BASE64" - * If there weren't enough random bytes then olm_session_last_error() will - * be "NOT_ENOUGH_RANDOM". */ -size_t olm_create_outbound_session( - OlmSession * session, - OlmAccount * account, - void const * their_identity_key, size_t their_identity_key_length, - void const * their_one_time_key, size_t their_one_time_key_length, - void * random, size_t random_length -); - -/** Create a new in-bound session for sending/receiving messages from an - * incoming PRE_KEY message. Returns olm_error() on failure. If the base64 - * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64". - * If the message was for an unsupported protocol version then - * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message - * couldn't be decoded then then olm_session_last_error() will be - * "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time - * key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */ -size_t olm_create_inbound_session( - OlmSession * session, - OlmAccount * account, - void * one_time_key_message, size_t message_length -); - -/** Create a new in-bound session for sending/receiving messages from an - * incoming PRE_KEY message. Returns olm_error() on failure. If the base64 - * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64". - * If the message was for an unsupported protocol version then - * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message - * couldn't be decoded then then olm_session_last_error() will be - * "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time - * key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */ -size_t olm_create_inbound_session_from( - OlmSession * session, - OlmAccount * account, - void const * their_identity_key, size_t their_identity_key_length, - void * one_time_key_message, size_t message_length -); - -/** The length of the buffer needed to return the id for this session. */ -size_t olm_session_id_length( - OlmSession * session -); - -/** An identifier for this session. Will be the same for both ends of the - * conversation. If the id buffer is too small then olm_session_last_error() - * will be "OUTPUT_BUFFER_TOO_SMALL". */ -size_t olm_session_id( - OlmSession * session, - void * id, size_t id_length -); - -/** Checks if the PRE_KEY message is for this in-bound session. This can happen - * if multiple messages are sent to this account before this account sends a - * message in reply. Returns olm_error() on failure. If the base64 - * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64". - * If the message was for an unsupported protocol version then - * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message - * couldn't be decoded then then olm_session_last_error() will be - * "BAD_MESSAGE_FORMAT". */ -size_t olm_matches_inbound_session( - OlmSession * session, - void * one_time_key_message, size_t message_length -); - -/** Checks if the PRE_KEY message is for this in-bound session. This can happen - * if multiple messages are sent to this account before this account sends a - * message in reply. Returns olm_error() on failure. If the base64 - * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64". - * If the message was for an unsupported protocol version then - * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message - * couldn't be decoded then then olm_session_last_error() will be - * "BAD_MESSAGE_FORMAT". */ -size_t olm_matches_inbound_session_from( - OlmSession * session, - void const * their_identity_key, size_t their_identity_key_length, - void * one_time_key_message, size_t message_length -); - -/** Removes the one time keys that the session used from the account. Returns - * olm_error() on failure. If the account doesn't have any matching one time - * keys then olm_account_last_error() will be "BAD_MESSAGE_KEY_ID". */ -size_t olm_remove_one_time_keys( - OlmAccount * account, - OlmSession * session -); - -/** The type of the next message that olm_encrypt() will return. Returns - * OLM_MESSAGE_TYPE_PRE_KEY if the message will be a PRE_KEY message. - * Returns OLM_MESSAGE_TYPE_MESSAGE if the message will be a normal message. - * Returns olm_error on failure. */ -size_t olm_encrypt_message_type( - OlmSession * session -); - -/** The number of random bytes needed to encrypt the next message. */ -size_t olm_encrypt_random_length( - OlmSession * session -); - -/** The size of the next message in bytes for the given number of plain-text - * bytes. */ -size_t olm_encrypt_message_length( - OlmSession * session, - size_t plaintext_length -); - -/** Encrypts a message using the session. Returns the length of the message in - * bytes on success. Writes the message as base64 into the message buffer. - * Returns olm_error() on failure. If the message buffer is too small then - * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If there - * weren't enough random bytes then olm_session_last_error() will be - * "NOT_ENOUGH_RANDOM". */ -size_t olm_encrypt( - OlmSession * session, - void const * plaintext, size_t plaintext_length, - void * random, size_t random_length, - void * message, size_t message_length -); - -/** The maximum number of bytes of plain-text a given message could decode to. - * The actual size could be different due to padding. The input message buffer - * is destroyed. Returns olm_error() on failure. If the message base64 - * couldn't be decoded then olm_session_last_error() will be - * "INVALID_BASE64". If the message is for an unsupported version of the - * protocol then olm_session_last_error() will be "BAD_MESSAGE_VERSION". - * If the message couldn't be decoded then olm_session_last_error() will be - * "BAD_MESSAGE_FORMAT". */ -size_t olm_decrypt_max_plaintext_length( - OlmSession * session, - size_t message_type, - void * message, size_t message_length -); - -/** Decrypts a message using the session. The input message buffer is destroyed. - * Returns the length of the plain-text on success. Returns olm_error() on - * failure. If the plain-text buffer is smaller than - * olm_decrypt_max_plaintext_length() then olm_session_last_error() - * will be "OUTPUT_BUFFER_TOO_SMALL". If the base64 couldn't be decoded then - * olm_session_last_error() will be "INVALID_BASE64". If the message is for - * an unsupported version of the protocol then olm_session_last_error() will - * be "BAD_MESSAGE_VERSION". If the message couldn't be decoded then - * olm_session_last_error() will be BAD_MESSAGE_FORMAT". - * If the MAC on the message was invalid then olm_session_last_error() will - * be "BAD_MESSAGE_MAC". */ -size_t olm_decrypt( - OlmSession * session, - size_t message_type, - void * message, size_t message_length, - void * plaintext, size_t max_plaintext_length -); - -/** The length of the buffer needed to hold the SHA-256 hash. */ -size_t olm_sha256_length( - OlmUtility * utility -); - -/** Calculates the SHA-256 hash of the input and encodes it as base64. If the - * output buffer is smaller than olm_sha256_length() then - * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */ -size_t olm_sha256( - OlmUtility * utility, - void const * input, size_t input_length, - void * output, size_t output_length -); - -/** Verify an ed25519 signature. If the key was too small then - * olm_session_last_error will be "INVALID_BASE64". If the signature was invalid - * then olm_session_last_error() will be "BAD_MESSAGE_MAC". */ -size_t olm_ed25519_verify( - OlmUtility * utility, - void const * key, size_t key_length, - void const * message, size_t message_length, - void * signature, size_t signature_length -); - -/** - * Set the log level. By default, 1, which logs only FATAL messages. - */ -void olm_set_log_level( - unsigned int level -); - -#ifdef __cplusplus -} -#endif - -#endif /* OLM_HH_ */ +#include "olm/olm.h" diff --git a/include/olm/pickle.h b/include/olm/pickle.h new file mode 100644 index 0000000..c1e8192 --- /dev/null +++ b/include/olm/pickle.h @@ -0,0 +1,50 @@ +/* Copyright 2015-2016 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_PICKLE_H_ +#define OLM_PICKLE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define _olm_pickle_uint32_length(value) 4 +uint8_t * _olm_pickle_uint32(uint8_t * pos, uint32_t value); +uint8_t const * _olm_unpickle_uint32( + uint8_t const * pos, uint8_t const * end, + uint32_t *value +); + + +#define _olm_pickle_bool_length(value) 1 +uint8_t * _olm_pickle_bool(uint8_t * pos, int value); +uint8_t const * _olm_unpickle_bool( + uint8_t const * pos, uint8_t const * end, + int *value +); + +#define _olm_pickle_bytes_length(bytes, bytes_length) (bytes_length) +uint8_t * _olm_pickle_bytes(uint8_t * pos, uint8_t const * bytes, + size_t bytes_length); +uint8_t const * _olm_unpickle_bytes(uint8_t const * pos, uint8_t const * end, + uint8_t * bytes, size_t bytes_length); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* OLM_PICKLE_H */ diff --git a/include/olm/ratchet.hh b/include/olm/ratchet.hh index 071e349..acb5608 100644 --- a/include/olm/ratchet.hh +++ b/include/olm/ratchet.hh @@ -15,12 +15,12 @@ #include "olm/crypto.hh" #include "olm/list.hh" -#include "olm/error.hh" +#include "olm/error.h" + +struct _olm_cipher; namespace olm { -class Cipher; - typedef std::uint8_t SharedKey[olm::KEY_LENGTH]; @@ -69,17 +69,17 @@ struct Ratchet { Ratchet( KdfInfo const & kdf_info, - Cipher const & ratchet_cipher + _olm_cipher const *ratchet_cipher ); /** A some strings identifying the application to feed into the KDF. */ KdfInfo const & kdf_info; /** The AEAD cipher to use for encrypting messages. */ - Cipher const & ratchet_cipher; + _olm_cipher const *ratchet_cipher; /** The last error that happened encrypting or decrypting a message. */ - ErrorCode last_error; + OlmErrorCode last_error; /** * A count of the number of times the root key has been advanced; this is diff --git a/include/olm/session.hh b/include/olm/session.hh index 829f271..5b91cb1 100644 --- a/include/olm/session.hh +++ b/include/olm/session.hh @@ -31,7 +31,7 @@ struct Session { Session(); Ratchet ratchet; - ErrorCode last_error; + OlmErrorCode last_error; bool received_message; diff --git a/include/olm/utility.hh b/include/olm/utility.hh index 1e77675..1339fe5 100644 --- a/include/olm/utility.hh +++ b/include/olm/utility.hh @@ -16,7 +16,7 @@ #ifndef UTILITY_HH_ #define UTILITY_HH_ -#include "olm/error.hh" +#include "olm/error.h" #include #include @@ -29,7 +29,7 @@ struct Utility { Utility(); - ErrorCode last_error; + OlmErrorCode last_error; /** The length of a SHA-256 hash in bytes. */ std::size_t sha256_length(); diff --git a/src/account.cpp b/src/account.cpp index d34110a..33dd2c2 100644 --- a/src/account.cpp +++ b/src/account.cpp @@ -22,7 +22,7 @@ static const char *LOG_CATEGORY = "olm::Account"; olm::Account::Account( ) : next_one_time_key_id(0), - last_error(olm::ErrorCode::SUCCESS) { + last_error(OlmErrorCode::OLM_SUCCESS) { } @@ -61,7 +61,7 @@ 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 = olm::ErrorCode::NOT_ENOUGH_RANDOM; + last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM; return std::size_t(-1); } @@ -117,7 +117,7 @@ std::size_t olm::Account::get_identity_json( size_t expected_length = get_identity_json_length(); if (identity_json_length < expected_length) { - last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } @@ -153,7 +153,7 @@ std::size_t olm::Account::sign( std::uint8_t * signature, std::size_t signature_length ) { if (signature_length < this->signature_length()) { - last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } olm::ed25519_sign( @@ -192,7 +192,7 @@ std::size_t olm::Account::get_one_time_keys_json( ) { std::uint8_t * pos = one_time_json; if (one_time_json_length < get_one_time_keys_json_length()) { - last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } *(pos++) = '{'; @@ -253,7 +253,7 @@ std::size_t olm::Account::generate_one_time_keys( std::uint8_t const * random, std::size_t random_length ) { if (random_length < generate_one_time_keys_random_length(number_of_keys)) { - last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM; + last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM; return std::size_t(-1); } for (unsigned i = 0; i < number_of_keys; ++i) { @@ -368,7 +368,7 @@ std::uint8_t const * olm::unpickle( uint32_t pickle_version; pos = olm::unpickle(pos, end, pickle_version); if (pickle_version != ACCOUNT_PICKLE_VERSION) { - value.last_error = olm::ErrorCode::UNKNOWN_PICKLE_VERSION; + value.last_error = OlmErrorCode::OLM_UNKNOWN_PICKLE_VERSION; return end; } pos = olm::unpickle(pos, end, value.identity_keys); diff --git a/src/base64.cpp b/src/base64.cpp index 66f512b..bbfb210 100644 --- a/src/base64.cpp +++ b/src/base64.cpp @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "olm/base64.h" #include "olm/base64.hh" - namespace { static const std::uint8_t ENCODE_BASE64[64] = { @@ -134,3 +134,34 @@ std::uint8_t const * olm::decode_base64( } return input + input_length; } + + +// implementations of base64.h + +size_t _olm_encode_base64_length( + size_t input_length +) { + return olm::encode_base64_length(input_length); +} + +size_t _olm_encode_base64( + uint8_t const * input, size_t input_length, + uint8_t * output +) { + uint8_t * r = olm::encode_base64(input, input_length, output); + return r - output; +} + +size_t _olm_decode_base64_length( + size_t input_length +) { + return olm::decode_base64_length(input_length); +} + +size_t _olm_decode_base64( + uint8_t const * input, size_t input_length, + uint8_t * output +) { + olm::decode_base64(input, input_length, output); + return olm::decode_base64_length(input_length); +} diff --git a/src/cipher.cpp b/src/cipher.cpp index 7bb11b8..8c3de92 100644 --- a/src/cipher.cpp +++ b/src/cipher.cpp @@ -12,15 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "olm/cipher.hh" +#include "olm/cipher.h" #include "olm/crypto.hh" #include "olm/memory.hh" #include -olm::Cipher::~Cipher() { - -} - namespace { struct DerivedKeys { @@ -36,7 +32,7 @@ static void derive_keys( DerivedKeys & keys ) { std::uint8_t derived_secrets[2 * olm::KEY_LENGTH + olm::IV_LENGTH]; - olm::hkdf_sha256( + _olm_crypto_hkdf_sha256( key, key_length, nullptr, 0, kdf_info, kdf_info_length, @@ -51,47 +47,40 @@ static void derive_keys( static const std::size_t MAC_LENGTH = 8; -} // namespace - - -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 olm::CipherAesSha256::mac_length() const { +size_t aes_sha_256_cipher_mac_length(const struct _olm_cipher *cipher) { return MAC_LENGTH; } - -std::size_t olm::CipherAesSha256::encrypt_ciphertext_length( - std::size_t plaintext_length -) const { +size_t aes_sha_256_cipher_encrypt_ciphertext_length( + const struct _olm_cipher *cipher, size_t plaintext_length +) { return olm::aes_encrypt_cbc_length(plaintext_length); } +size_t aes_sha_256_cipher_encrypt( + const struct _olm_cipher *cipher, + uint8_t const * key, size_t key_length, + uint8_t const * plaintext, size_t plaintext_length, + uint8_t * ciphertext, size_t ciphertext_length, + uint8_t * output, size_t output_length +) { + auto *c = reinterpret_cast(cipher); -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, - std::uint8_t * output, std::size_t output_length -) const { - if (encrypt_ciphertext_length(plaintext_length) < ciphertext_length) { + if (aes_sha_256_cipher_encrypt_ciphertext_length(cipher, plaintext_length) + < ciphertext_length) { return std::size_t(-1); } - struct DerivedKeys keys; - std::uint8_t mac[olm::SHA256_OUTPUT_LENGTH]; - derive_keys(kdf_info, kdf_info_length, key, key_length, keys); + struct DerivedKeys keys; + std::uint8_t mac[SHA256_OUTPUT_LENGTH]; + + derive_keys(c->kdf_info, c->kdf_info_length, key, key_length, keys); olm::aes_encrypt_cbc( keys.aes_key, keys.aes_iv, plaintext, plaintext_length, ciphertext ); - olm::hmac_sha256( + _olm_crypto_hmac_sha256( keys.mac_key, olm::KEY_LENGTH, output, output_length - MAC_LENGTH, mac ); @@ -102,24 +91,28 @@ std::size_t olm::CipherAesSha256::encrypt( } -std::size_t olm::CipherAesSha256::decrypt_max_plaintext_length( - std::size_t ciphertext_length -) const { +size_t aes_sha_256_cipher_decrypt_max_plaintext_length( + const struct _olm_cipher *cipher, + size_t ciphertext_length +) { return ciphertext_length; } -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, - std::uint8_t * plaintext, std::size_t max_plaintext_length -) const { +size_t aes_sha_256_cipher_decrypt( + const struct _olm_cipher *cipher, + uint8_t const * key, size_t key_length, + uint8_t const * input, size_t input_length, + uint8_t const * ciphertext, size_t ciphertext_length, + uint8_t * plaintext, size_t max_plaintext_length +) { + auto *c = reinterpret_cast(cipher); + DerivedKeys keys; - std::uint8_t mac[olm::SHA256_OUTPUT_LENGTH]; + std::uint8_t mac[SHA256_OUTPUT_LENGTH]; - derive_keys(kdf_info, kdf_info_length, key, key_length, keys); + derive_keys(c->kdf_info, c->kdf_info_length, key, key_length, keys); - olm::hmac_sha256( + _olm_crypto_hmac_sha256( keys.mac_key, olm::KEY_LENGTH, input, input_length - MAC_LENGTH, mac ); @@ -136,3 +129,13 @@ std::size_t olm::CipherAesSha256::decrypt( olm::unset(keys); return plaintext_length; } + +} // namespace + +const struct _olm_cipher_ops _olm_cipher_aes_sha_256_ops = { + aes_sha_256_cipher_mac_length, + aes_sha_256_cipher_encrypt_ciphertext_length, + aes_sha_256_cipher_encrypt, + aes_sha_256_cipher_decrypt_max_plaintext_length, + aes_sha_256_cipher_decrypt, +}; diff --git a/src/crypto.cpp b/src/crypto.cpp index 5a2689f..2049a8b 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -85,7 +85,7 @@ inline static void hmac_sha256_final( std::uint8_t const * hmac_key, std::uint8_t * output ) { - std::uint8_t o_pad[SHA256_BLOCK_LENGTH + olm::SHA256_OUTPUT_LENGTH]; + std::uint8_t o_pad[SHA256_BLOCK_LENGTH + SHA256_OUTPUT_LENGTH]; std::memcpy(o_pad, hmac_key, SHA256_BLOCK_LENGTH); for (std::size_t i = 0; i < SHA256_BLOCK_LENGTH; ++i) { o_pad[i] ^= 0x5C; @@ -260,7 +260,7 @@ std::size_t olm::aes_decrypt_cbc( } -void olm::sha256( +void _olm_crypto_sha256( std::uint8_t const * input, std::size_t input_length, std::uint8_t * output ) { @@ -272,7 +272,7 @@ void olm::sha256( } -void olm::hmac_sha256( +void _olm_crypto_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 @@ -288,7 +288,7 @@ void olm::hmac_sha256( } -void olm::hkdf_sha256( +void _olm_crypto_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, @@ -296,7 +296,7 @@ void olm::hkdf_sha256( ) { ::SHA256_CTX context; std::uint8_t hmac_key[SHA256_BLOCK_LENGTH]; - std::uint8_t step_result[olm::SHA256_OUTPUT_LENGTH]; + std::uint8_t step_result[SHA256_OUTPUT_LENGTH]; std::size_t bytes_remaining = output_length; std::uint8_t iteration = 1; if (!salt) { @@ -308,20 +308,20 @@ void olm::hkdf_sha256( hmac_sha256_init(&context, hmac_key); ::sha256_update(&context, input, input_length); hmac_sha256_final(&context, hmac_key, step_result); - hmac_sha256_key(step_result, olm::SHA256_OUTPUT_LENGTH, hmac_key); + hmac_sha256_key(step_result, SHA256_OUTPUT_LENGTH, hmac_key); /* Expand */ hmac_sha256_init(&context, hmac_key); ::sha256_update(&context, info, info_length); ::sha256_update(&context, &iteration, 1); hmac_sha256_final(&context, hmac_key, step_result); - while (bytes_remaining > olm::SHA256_OUTPUT_LENGTH) { - std::memcpy(output, step_result, olm::SHA256_OUTPUT_LENGTH); - output += olm::SHA256_OUTPUT_LENGTH; - bytes_remaining -= olm::SHA256_OUTPUT_LENGTH; + while (bytes_remaining > SHA256_OUTPUT_LENGTH) { + std::memcpy(output, step_result, SHA256_OUTPUT_LENGTH); + output += SHA256_OUTPUT_LENGTH; + bytes_remaining -= SHA256_OUTPUT_LENGTH; iteration ++; hmac_sha256_init(&context, hmac_key); - ::sha256_update(&context, step_result, olm::SHA256_OUTPUT_LENGTH); + ::sha256_update(&context, step_result, SHA256_OUTPUT_LENGTH); ::sha256_update(&context, info, info_length); ::sha256_update(&context, &iteration, 1); hmac_sha256_final(&context, hmac_key, step_result); diff --git a/src/memory.cpp b/src/memory.cpp index 16a4683..20e0683 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -13,7 +13,13 @@ * limitations under the License. */ #include "olm/memory.hh" +#include "olm/memory.h" +void _olm_unset( + void volatile * buffer, size_t buffer_length +) { + olm::unset(buffer, buffer_length); +} void olm::unset( void volatile * buffer, std::size_t buffer_length diff --git a/src/olm.cpp b/src/olm.cpp index 69e02b9..d538be7 100644 --- a/src/olm.cpp +++ b/src/olm.cpp @@ -12,12 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "olm/olm.hh" +#include "olm/olm.h" #include "olm/session.hh" #include "olm/account.hh" +#include "olm/cipher.h" #include "olm/utility.hh" #include "olm/base64.hh" -#include "olm/cipher.hh" #include "olm/memory.hh" #include "olm/logging.h" @@ -58,17 +58,15 @@ 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 -); +static const struct _olm_cipher_aes_sha_256 PICKLE_CIPHER = + OLM_CIPHER_INIT_AES_SHA_256("Pickle"); 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(); + auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER); + std::size_t length = cipher->ops->encrypt_ciphertext_length(cipher, raw_length); + length += cipher->ops->mac_length(cipher); return olm::encode_base64_length(length); } @@ -77,8 +75,9 @@ 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(); + auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER); + std::size_t length = cipher->ops->encrypt_ciphertext_length(cipher, raw_length); + length += cipher->ops->mac_length(cipher); return output + olm::encode_base64_length(length) - length; } @@ -86,13 +85,15 @@ 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 + auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER); + std::size_t ciphertext_length = cipher->ops->encrypt_ciphertext_length( + cipher, raw_length ); - std::size_t length = ciphertext_length + PICKLE_CIPHER.mac_length(); + std::size_t length = ciphertext_length + cipher->ops->mac_length(cipher); std::size_t base64_length = olm::encode_base64_length(length); std::uint8_t * raw_output = output + base64_length - length; - PICKLE_CIPHER.encrypt( + cipher->ops->encrypt( + cipher, key, key_length, raw_output, raw_length, raw_output, ciphertext_length, @@ -105,23 +106,25 @@ std::size_t enc_output( 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 + OlmErrorCode & 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; + last_error = OlmErrorCode::OLM_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( + auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER); + std::size_t raw_length = enc_length - cipher->ops->mac_length(cipher); + std::size_t result = cipher->ops->decrypt( + cipher, 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; + last_error = OlmErrorCode::OLM_BAD_ACCOUNT_KEY; } return result; } @@ -151,11 +154,11 @@ std::size_t b64_output( std::size_t b64_input( std::uint8_t * input, size_t b64_length, - olm::ErrorCode & last_error + OlmErrorCode & 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; + last_error = OlmErrorCode::OLM_INVALID_BASE64; return std::size_t(-1); } olm::decode_base64(input, b64_length, input); @@ -313,7 +316,7 @@ size_t olm_pickle_account( 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; + object.last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return size_t(-1); } pickle(enc_output_pos(from_c(pickled), raw_length), object); @@ -329,7 +332,7 @@ size_t olm_pickle_session( 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; + object.last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return size_t(-1); } pickle(enc_output_pos(from_c(pickled), raw_length), object); @@ -356,8 +359,8 @@ size_t olm_unpickle_account( * (pos + raw_length). On error unpickle will return (pos + raw_length + 1). */ if (end != unpickle(pos, end + 1, object)) { - if (object.last_error == olm::ErrorCode::SUCCESS) { - object.last_error = olm::ErrorCode::CORRUPTED_PICKLE; + if (object.last_error == OlmErrorCode::OLM_SUCCESS) { + object.last_error = OlmErrorCode::OLM_CORRUPTED_PICKLE; } return std::size_t(-1); } @@ -385,8 +388,8 @@ size_t olm_unpickle_session( * (pos + raw_length). On error unpickle will return (pos + raw_length + 1). */ if (end != unpickle(pos, end + 1, object)) { - if (object.last_error == olm::ErrorCode::SUCCESS) { - object.last_error = olm::ErrorCode::CORRUPTED_PICKLE; + if (object.last_error == OlmErrorCode::OLM_SUCCESS) { + object.last_error = OlmErrorCode::OLM_CORRUPTED_PICKLE; } return std::size_t(-1); } @@ -443,7 +446,7 @@ size_t olm_account_sign( std::size_t raw_length = from_c(account)->signature_length(); if (signature_length < b64_output_length(raw_length)) { from_c(account)->last_error = - olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } from_c(account)->sign( @@ -529,7 +532,7 @@ size_t olm_create_outbound_session( if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH || olm::decode_base64_length(ot_key_length) != olm::KEY_LENGTH ) { - from_c(session)->last_error = olm::ErrorCode::INVALID_BASE64; + from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64; return std::size_t(-1); } olm::Curve25519PublicKey identity_key; @@ -574,7 +577,7 @@ size_t olm_create_inbound_session_from( std::size_t id_key_length = their_identity_key_length; if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) { - from_c(session)->last_error = olm::ErrorCode::INVALID_BASE64; + from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64; return std::size_t(-1); } olm::Curve25519PublicKey identity_key; @@ -606,7 +609,7 @@ size_t olm_session_id( std::size_t raw_length = from_c(session)->session_id_length(); if (id_length < b64_output_length(raw_length)) { from_c(session)->last_error = - olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } std::size_t result = from_c(session)->session_id( @@ -645,7 +648,7 @@ size_t olm_matches_inbound_session_from( std::size_t id_key_length = their_identity_key_length; if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) { - from_c(session)->last_error = olm::ErrorCode::INVALID_BASE64; + from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64; return std::size_t(-1); } olm::Curve25519PublicKey identity_key; @@ -672,7 +675,7 @@ size_t olm_remove_one_time_keys( from_c(session)->bob_one_time_key ); if (result == std::size_t(-1)) { - from_c(account)->last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID; + from_c(account)->last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID; } return result; } @@ -713,7 +716,7 @@ size_t olm_encrypt( ); if (message_length < b64_output_length(raw_length)) { from_c(session)->last_error = - olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } std::size_t result = from_c(session)->encrypt( @@ -780,7 +783,7 @@ size_t olm_sha256( std::size_t raw_length = from_c(utility)->sha256_length(); if (output_length < b64_output_length(raw_length)) { from_c(utility)->last_error = - olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } std::size_t result = from_c(utility)->sha256( @@ -801,7 +804,7 @@ size_t olm_ed25519_verify( void * signature, size_t signature_length ) { if (olm::decode_base64_length(key_length) != olm::KEY_LENGTH) { - from_c(utility)->last_error = olm::ErrorCode::INVALID_BASE64; + from_c(utility)->last_error = OlmErrorCode::OLM_INVALID_BASE64; return std::size_t(-1); } olm::Ed25519PublicKey verify_key; diff --git a/src/pickle.cpp b/src/pickle.cpp index 00f7cd4..fc3e2b4 100644 --- a/src/pickle.cpp +++ b/src/pickle.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "olm/pickle.hh" +#include "olm/pickle.h" std::uint8_t * olm::pickle( std::uint8_t * pos, @@ -196,3 +197,37 @@ std::uint8_t const * olm::unpickle( ); return pos; } + +////// pickle.h implementations + +uint8_t * _olm_pickle_uint32(uint8_t * pos, uint32_t value) { + return olm::pickle(pos, value); +} + +uint8_t const * _olm_unpickle_uint32( + uint8_t const * pos, uint8_t const * end, + uint32_t *value +) { + return olm::unpickle(pos, end, *value); +} + +uint8_t * _olm_pickle_bool(uint8_t * pos, int value) { + return olm::pickle(pos, (bool)value); +} + +uint8_t const * _olm_unpickle_bool( + uint8_t const * pos, uint8_t const * end, + int *value +) { + return olm::unpickle(pos, end, *reinterpret_cast(value)); +} + +uint8_t * _olm_pickle_bytes(uint8_t * pos, uint8_t const * bytes, + size_t bytes_length) { + return olm::pickle_bytes(pos, bytes, bytes_length); +} + +uint8_t const * _olm_unpickle_bytes(uint8_t const * pos, uint8_t const * end, + uint8_t * bytes, size_t bytes_length) { + return olm::unpickle_bytes(pos, end, bytes, bytes_length); +} diff --git a/src/ratchet.cpp b/src/ratchet.cpp index 06912af..01b3054 100644 --- a/src/ratchet.cpp +++ b/src/ratchet.cpp @@ -15,7 +15,7 @@ #include "olm/ratchet.hh" #include "olm/message.hh" #include "olm/memory.hh" -#include "olm/cipher.hh" +#include "olm/cipher.h" #include "olm/pickle.hh" #include "olm/logging.h" @@ -53,7 +53,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]; - olm::hkdf_sha256( + _olm_crypto_hkdf_sha256( secret, sizeof(secret), root_key, sizeof(root_key), info.ratchet_info, info.ratchet_info_length, @@ -73,7 +73,7 @@ static void advance_chain_key( olm::ChainKey const & chain_key, olm::ChainKey & new_chain_key ) { - olm::hmac_sha256( + _olm_crypto_hmac_sha256( chain_key.key, sizeof(chain_key.key), CHAIN_KEY_SEED, sizeof(CHAIN_KEY_SEED), new_chain_key.key @@ -89,7 +89,7 @@ static void create_message_keys( olm::ChainKey const & chain_key, olm::KdfInfo const & info, olm::MessageKey & message_key) { - olm::hmac_sha256( + _olm_crypto_hmac_sha256( chain_key.key, sizeof(chain_key.key), MESSAGE_KEY_SEED, sizeof(MESSAGE_KEY_SEED), message_key.key @@ -101,12 +101,13 @@ static void create_message_keys( static std::size_t verify_mac_and_decrypt( - olm::Cipher const & cipher, + _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( + return cipher->ops->decrypt( + cipher, message_key.key, sizeof(message_key.key), reader.input, reader.input_length, reader.ciphertext, reader.ciphertext_length, @@ -193,10 +194,10 @@ static std::size_t verify_mac_and_decrypt_for_new_chain( olm::Ratchet::Ratchet( olm::KdfInfo const & kdf_info, - Cipher const & ratchet_cipher + _olm_cipher const * ratchet_cipher ) : kdf_info(kdf_info), ratchet_cipher(ratchet_cipher), - last_error(olm::ErrorCode::SUCCESS) { + last_error(OlmErrorCode::OLM_SUCCESS) { } @@ -205,7 +206,7 @@ void olm::Ratchet::initialise_as_bob( olm::Curve25519PublicKey const & their_ratchet_key ) { std::uint8_t derived_secrets[2 * olm::KEY_LENGTH]; - olm::hkdf_sha256( + _olm_crypto_hkdf_sha256( shared_secret, shared_secret_length, nullptr, 0, kdf_info.root_info, kdf_info.root_info_length, @@ -228,7 +229,7 @@ void olm::Ratchet::initialise_as_alice( olm::Curve25519KeyPair const & our_ratchet_key ) { std::uint8_t derived_secrets[2 * olm::KEY_LENGTH]; - olm::hkdf_sha256( + _olm_crypto_hkdf_sha256( shared_secret, shared_secret_length, nullptr, 0, kdf_info.root_info, kdf_info.root_info_length, @@ -417,11 +418,12 @@ std::size_t olm::Ratchet::encrypt_output_length( if (!sender_chain.empty()) { counter = sender_chain[0].chain_key.index; } - std::size_t padded = ratchet_cipher.encrypt_ciphertext_length( + std::size_t padded = ratchet_cipher->ops->encrypt_ciphertext_length( + ratchet_cipher, plaintext_length ); return olm::encode_message_length( - counter, olm::KEY_LENGTH, padded, ratchet_cipher.mac_length() + counter, olm::KEY_LENGTH, padded, ratchet_cipher->ops->mac_length(ratchet_cipher) ); } @@ -439,11 +441,11 @@ std::size_t olm::Ratchet::encrypt( std::size_t output_length = encrypt_output_length(plaintext_length); if (random_length < encrypt_random_length()) { - last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM; + last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM; return std::size_t(-1); } if (max_output_length < output_length) { - last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } @@ -469,7 +471,8 @@ std::size_t olm::Ratchet::encrypt( create_message_keys(chain_index, sender_chain[0].chain_key, kdf_info, keys); advance_chain_key(chain_index, sender_chain[0].chain_key, sender_chain[0].chain_key); - std::size_t ciphertext_length = ratchet_cipher.encrypt_ciphertext_length( + std::size_t ciphertext_length = ratchet_cipher->ops->encrypt_ciphertext_length( + ratchet_cipher, plaintext_length ); std::uint32_t counter = keys.index; @@ -484,7 +487,8 @@ std::size_t olm::Ratchet::encrypt( olm::store_array(writer.ratchet_key, ratchet_key.public_key); - ratchet_cipher.encrypt( + ratchet_cipher->ops->encrypt( + ratchet_cipher, keys.key, sizeof(keys.key), plaintext, plaintext_length, writer.ciphertext, ciphertext_length, @@ -509,15 +513,17 @@ std::size_t olm::Ratchet::decrypt_max_plaintext_length( ) { olm::MessageReader reader; olm::decode_message( - reader, input, input_length, ratchet_cipher.mac_length() + reader, input, input_length, + ratchet_cipher->ops->mac_length(ratchet_cipher) ); if (!reader.ciphertext) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } - return ratchet_cipher.decrypt_max_plaintext_length(reader.ciphertext_length); + return ratchet_cipher->ops->decrypt_max_plaintext_length( + ratchet_cipher, reader.ciphertext_length); } @@ -531,30 +537,32 @@ std::size_t olm::Ratchet::decrypt( olm::MessageReader reader; olm::decode_message( - reader, input, input_length, ratchet_cipher.mac_length() + reader, input, input_length, + ratchet_cipher->ops->mac_length(ratchet_cipher) ); if (reader.version != PROTOCOL_VERSION) { - last_error = olm::ErrorCode::BAD_MESSAGE_VERSION; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_VERSION; return std::size_t(-1); } if (!reader.has_counter || !reader.ratchet_key || !reader.ciphertext) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } - std::size_t max_length = ratchet_cipher.decrypt_max_plaintext_length( + std::size_t max_length = ratchet_cipher->ops->decrypt_max_plaintext_length( + ratchet_cipher, reader.ciphertext_length ); if (max_plaintext_length < max_length) { - last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } if (reader.ratchet_key_length != olm::KEY_LENGTH) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } @@ -619,7 +627,7 @@ std::size_t olm::Ratchet::decrypt( } if (result == std::size_t(-1)) { - last_error = olm::ErrorCode::BAD_MESSAGE_MAC; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC; return std::size_t(-1); } diff --git a/src/session.cpp b/src/session.cpp index 816dd26..6a86d21 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ #include "olm/session.hh" -#include "olm/cipher.hh" +#include "olm/cipher.h" #include "olm/crypto.hh" #include "olm/account.hh" #include "olm/logging.h" @@ -33,20 +33,19 @@ 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 olm::CipherAesSha256 OLM_CIPHER( - CIPHER_KDF_INFO, sizeof(CIPHER_KDF_INFO) -1 -); - static const olm::KdfInfo OLM_KDF_INFO = { ROOT_KDF_INFO, sizeof(ROOT_KDF_INFO) - 1, RATCHET_KDF_INFO, sizeof(RATCHET_KDF_INFO) - 1 }; +static const struct _olm_cipher_aes_sha_256 OLM_CIPHER = + OLM_CIPHER_INIT_AES_SHA_256(CIPHER_KDF_INFO); + } // namespace olm::Session::Session( -) : ratchet(OLM_KDF_INFO, OLM_CIPHER), - last_error(olm::ErrorCode::SUCCESS), +) : ratchet(OLM_KDF_INFO, OLM_CIPHER_BASE(&OLM_CIPHER)), + last_error(OlmErrorCode::OLM_SUCCESS), received_message(false) { } @@ -64,7 +63,7 @@ std::size_t olm::Session::new_outbound_session( std::uint8_t const * random, std::size_t random_length ) { if (random_length < new_outbound_session_random_length()) { - last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM; + last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM; return std::size_t(-1); } @@ -142,7 +141,7 @@ std::size_t olm::Session::new_inbound_session( decode_one_time_key_message(reader, one_time_key_message, message_length); if (!check_message_fields(reader, their_identity_key)) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } @@ -158,7 +157,7 @@ std::size_t olm::Session::new_inbound_session( olm::bytes_to_string(reader.identity_key, reader.identity_key + olm::KEY_LENGTH) .c_str()); - last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID; return std::size_t(-1); } } @@ -177,12 +176,12 @@ std::size_t olm::Session::new_inbound_session( olm::MessageReader message_reader; decode_message( message_reader, reader.message, reader.message_length, - ratchet.ratchet_cipher.mac_length() + ratchet.ratchet_cipher->ops->mac_length(ratchet.ratchet_cipher) ); if (!message_reader.ratchet_key || message_reader.ratchet_key_length != olm::KEY_LENGTH) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } @@ -200,7 +199,7 @@ std::size_t olm::Session::new_inbound_session( olm_logf(OLM_LOG_INFO, LOG_CATEGORY, "Session uses unknown ephemeral key %s", bob_one_time_key.to_string().c_str()); - last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID; return std::size_t(-1); } @@ -227,7 +226,7 @@ std::size_t olm::Session::new_inbound_session( std::size_t olm::Session::session_id_length() { - return olm::SHA256_OUTPUT_LENGTH; + return SHA256_OUTPUT_LENGTH; } @@ -235,7 +234,7 @@ std::size_t olm::Session::session_id( std::uint8_t * id, std::size_t id_length ) { if (id_length < session_id_length()) { - last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } std::uint8_t tmp[olm::KEY_LENGTH * 3]; @@ -243,7 +242,7 @@ std::size_t olm::Session::session_id( pos = olm::store_array(pos, alice_identity_key.public_key); pos = olm::store_array(pos, alice_base_key.public_key); pos = olm::store_array(pos, bob_one_time_key.public_key); - olm::sha256(tmp, sizeof(tmp), id); + _olm_crypto_sha256(tmp, sizeof(tmp), id); return session_id_length(); } @@ -324,7 +323,7 @@ std::size_t olm::Session::encrypt( (int)plaintext_length, plaintext); if (message_length < encrypt_message_length(plaintext_length)) { - last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } std::uint8_t * message_body; @@ -369,7 +368,7 @@ std::size_t olm::Session::encrypt( if (result == std::size_t(-1)) { last_error = ratchet.last_error; - ratchet.last_error = olm::ErrorCode::SUCCESS; + ratchet.last_error = OlmErrorCode::OLM_SUCCESS; return result; } @@ -393,7 +392,7 @@ std::size_t olm::Session::decrypt_max_plaintext_length( olm::PreKeyMessageReader reader; decode_one_time_key_message(reader, message, message_length); if (!reader.message) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } message_body = reader.message; @@ -406,7 +405,7 @@ std::size_t olm::Session::decrypt_max_plaintext_length( if (result == std::size_t(-1)) { last_error = ratchet.last_error; - ratchet.last_error = olm::ErrorCode::SUCCESS; + ratchet.last_error = OlmErrorCode::OLM_SUCCESS; } return result; } @@ -429,7 +428,7 @@ std::size_t olm::Session::decrypt( olm::PreKeyMessageReader reader; decode_one_time_key_message(reader, message, message_length); if (!reader.message) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } message_body = reader.message; @@ -442,7 +441,7 @@ std::size_t olm::Session::decrypt( if (result == std::size_t(-1)) { last_error = ratchet.last_error; - ratchet.last_error = olm::ErrorCode::SUCCESS; + ratchet.last_error = OlmErrorCode::OLM_SUCCESS; return result; } @@ -491,7 +490,7 @@ std::uint8_t const * olm::unpickle( uint32_t pickle_version; pos = olm::unpickle(pos, end, pickle_version); if (pickle_version != SESSION_PICKLE_VERSION) { - value.last_error = olm::ErrorCode::UNKNOWN_PICKLE_VERSION; + value.last_error = OlmErrorCode::OLM_UNKNOWN_PICKLE_VERSION; return end; } pos = olm::unpickle(pos, end, value.received_message); diff --git a/src/utility.cpp b/src/utility.cpp index bc51cff..67029c9 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -18,12 +18,12 @@ olm::Utility::Utility( -) : last_error(olm::ErrorCode::SUCCESS) { +) : last_error(OlmErrorCode::OLM_SUCCESS) { } size_t olm::Utility::sha256_length() { - return olm::SHA256_OUTPUT_LENGTH; + return SHA256_OUTPUT_LENGTH; } @@ -32,11 +32,11 @@ size_t olm::Utility::sha256( std::uint8_t * output, std::size_t output_length ) { if (output_length < sha256_length()) { - last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } - olm::sha256(input, input_length, output); - return olm::SHA256_OUTPUT_LENGTH; + _olm_crypto_sha256(input, input_length, output); + return SHA256_OUTPUT_LENGTH; } @@ -46,11 +46,11 @@ size_t olm::Utility::ed25519_verify( std::uint8_t const * signature, std::size_t signature_length ) { if (signature_length < olm::SIGNATURE_LENGTH) { - last_error = olm::ErrorCode::BAD_MESSAGE_MAC; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC; return std::size_t(-1); } if (!olm::ed25519_verify(key, message, message_length, signature)) { - last_error = olm::ErrorCode::BAD_MESSAGE_MAC; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC; return std::size_t(-1); } return std::size_t(0); diff --git a/tests/test_base64.cpp b/tests/test_base64.cpp index 5bae2f9..c95e3c9 100644 --- a/tests/test_base64.cpp +++ b/tests/test_base64.cpp @@ -1,10 +1,11 @@ #include "olm/base64.hh" +#include "olm/base64.h" #include "unittest.hh" int main() { { /* Base64 encode test */ -TestCase test_case("Base64 encode test"); +TestCase test_case("Base64 C++ binding encode test"); std::uint8_t input[] = "Hello World"; std::uint8_t expected_output[] = "SGVsbG8gV29ybGQ"; @@ -18,8 +19,24 @@ olm::encode_base64(input, input_length, output); assert_equals(expected_output, output, output_length); } +{ +TestCase test_case("Base64 C binding encode test"); + +std::uint8_t input[] = "Hello World"; +std::uint8_t expected_output[] = "SGVsbG8gV29ybGQ"; +std::size_t input_length = sizeof(input) - 1; + +std::size_t output_length = ::_olm_encode_base64_length(input_length); +assert_equals(std::size_t(15), output_length); + +std::uint8_t output[output_length]; +output_length = ::_olm_encode_base64(input, input_length, output); +assert_equals(std::size_t(15), output_length); +assert_equals(expected_output, output, output_length); +} + { /* Base64 decode test */ -TestCase test_case("Base64 decode test"); +TestCase test_case("Base64 C++ binding decode test"); std::uint8_t input[] = "SGVsbG8gV29ybGQ"; std::uint8_t expected_output[] = "Hello World"; @@ -33,4 +50,21 @@ olm::decode_base64(input, input_length, output); assert_equals(expected_output, output, output_length); } +{ +TestCase test_case("Base64 C binding decode test"); + +std::uint8_t input[] = "SGVsbG8gV29ybGQ"; +std::uint8_t expected_output[] = "Hello World"; +std::size_t input_length = sizeof(input) - 1; + +std::size_t output_length = ::_olm_decode_base64_length(input_length); +assert_equals(std::size_t(11), output_length); + +std::uint8_t output[output_length]; +output_length = ::_olm_decode_base64(input, input_length, output); +assert_equals(std::size_t(11), output_length); +assert_equals(expected_output, output, output_length); +} + + } diff --git a/tests/test_crypto.cpp b/tests/test_crypto.cpp index 4606c52..1041538 100644 --- a/tests/test_crypto.cpp +++ b/tests/test_crypto.cpp @@ -186,7 +186,7 @@ std::uint8_t expected[32] = { std::uint8_t actual[32]; -olm::sha256(input, sizeof(input), actual); +_olm_crypto_sha256(input, sizeof(input), actual); assert_equals(expected, actual, 32); @@ -207,7 +207,7 @@ std::uint8_t expected[32] = { std::uint8_t actual[32]; -olm::hmac_sha256(input, sizeof(input), input, sizeof(input), actual); +_olm_crypto_hmac_sha256(input, sizeof(input), input, sizeof(input), actual); assert_equals(expected, actual, 32); @@ -242,7 +242,7 @@ std::uint8_t hmac_expected_output[32] = { std::uint8_t hmac_actual_output[32] = {}; -olm::hmac_sha256( +_olm_crypto_hmac_sha256( salt, sizeof(salt), input, sizeof(input), hmac_actual_output @@ -261,7 +261,7 @@ std::uint8_t hkdf_expected_output[42] = { std::uint8_t hkdf_actual_output[42] = {}; -olm::hkdf_sha256( +_olm_crypto_hkdf_sha256( input, sizeof(input), salt, sizeof(salt), info, sizeof(info), diff --git a/tests/test_olm.cpp b/tests/test_olm.cpp index fbc14cf..de7e236 100644 --- a/tests/test_olm.cpp +++ b/tests/test_olm.cpp @@ -1,4 +1,4 @@ -#include "olm/olm.hh" +#include "olm/olm.h" #include "unittest.hh" #include diff --git a/tests/test_olm_decrypt.cpp b/tests/test_olm_decrypt.cpp index 4ec873c..95cb18e 100644 --- a/tests/test_olm_decrypt.cpp +++ b/tests/test_olm_decrypt.cpp @@ -1,4 +1,4 @@ -#include "olm/olm.hh" +#include "olm/olm.h" #include "unittest.hh" const char * test_cases[] = { diff --git a/tests/test_olm_sha256.cpp b/tests/test_olm_sha256.cpp index fe5bf42..c6d0242 100644 --- a/tests/test_olm_sha256.cpp +++ b/tests/test_olm_sha256.cpp @@ -1,4 +1,4 @@ -#include "olm/olm.hh" +#include "olm/olm.h" #include "unittest.hh" int main() { diff --git a/tests/test_olm_signature.cpp b/tests/test_olm_signature.cpp index a7cce63..d7259de 100644 --- a/tests/test_olm_signature.cpp +++ b/tests/test_olm_signature.cpp @@ -1,4 +1,4 @@ -#include "olm/olm.hh" +#include "olm/olm.h" #include "unittest.hh" #include diff --git a/tests/test_olm_using_malloc.cpp b/tests/test_olm_using_malloc.cpp index 84fbbd7..fff3ea2 100644 --- a/tests/test_olm_using_malloc.cpp +++ b/tests/test_olm_using_malloc.cpp @@ -1,4 +1,4 @@ -#include "olm/olm.hh" +#include "olm/olm.h" #include "unittest.hh" #include diff --git a/tests/test_ratchet.cpp b/tests/test_ratchet.cpp index 8f89048..2f8412e 100644 --- a/tests/test_ratchet.cpp +++ b/tests/test_ratchet.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ #include "olm/ratchet.hh" -#include "olm/cipher.hh" +#include "olm/cipher.h" #include "unittest.hh" @@ -28,9 +28,8 @@ olm::KdfInfo kdf_info = { ratchet_info, sizeof(ratchet_info) - 1 }; -olm::CipherAesSha256 cipher( - message_info, sizeof(message_info) - 1 -); +_olm_cipher_aes_sha_256 cipher0 = OLM_CIPHER_INIT_AES_SHA_256(message_info); +_olm_cipher *cipher = OLM_CIPHER_BASE(&cipher0); std::uint8_t random_bytes[] = "0123456789ABDEF0123456789ABCDEF"; olm::Curve25519KeyPair alice_key;