From 256bce10fc6c811293cd7d9089ba2d69cec0d59b Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 16 May 2016 16:47:49 +0100 Subject: Factor out olm_error_to_string to a separate file I want to be able to use this functionality from elsewhere, so factor it out to its own file. --- include/olm/error.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/olm/error.h b/include/olm/error.h index a4f373e..460017e 100644 --- a/include/olm/error.h +++ b/include/olm/error.h @@ -31,8 +31,15 @@ enum OlmErrorCode { 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 */ + + /* remember to update the list of string constants in error.c when updating + * this list. */ + }; +/** get a string representation of the given error code. */ +const char * _olm_error_to_string(enum OlmErrorCode error); + #ifdef __cplusplus } // extern "C" #endif -- cgit v1.2.3 From 42a300fc62a2d10fc14868ac6135d3da3857469f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 17 May 2016 18:48:16 +0100 Subject: Factor out pickle_encoding from olm.cpp We don't need to have all of the top-level pickling functions in olm.cpp; factor out the utilities to support it to pickle_encoding.cpp (and make sure that they have plain-C bindings). --- include/olm/pickle_encoding.h | 76 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 include/olm/pickle_encoding.h (limited to 'include') diff --git a/include/olm/pickle_encoding.h b/include/olm/pickle_encoding.h new file mode 100644 index 0000000..03611df --- /dev/null +++ b/include/olm/pickle_encoding.h @@ -0,0 +1,76 @@ +/* Copyright 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. + */ + +/* functions for encrypting and decrypting pickled representations of objects */ + +#ifndef OLM_PICKLE_ENCODING_H_ +#define OLM_PICKLE_ENCODING_H_ + +#include +#include + +#include "olm/error.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Get the number of bytes needed to encode a pickle of the length given + */ +size_t _olm_enc_output_length(size_t raw_length); + +/** + * Get the point in the output buffer that the raw pickle should be written to. + * + * In order that we can use the same buffer for the raw pickle, and the encoded + * pickle, the raw pickle needs to be written at the end of the buffer. (The + * base-64 encoding would otherwise overwrite the end of the input before it + * was encoded.) + */ + uint8_t *_olm_enc_output_pos(uint8_t * output, size_t raw_length); + +/** + * Encrypt and encode the given pickle in-situ. + * + * The raw pickle should have been written to enc_output_pos(pickle, + * raw_length). + * + * Returns the number of bytes in the encoded pickle. + */ +size_t _olm_enc_output( + uint8_t const * key, size_t key_length, + uint8_t *pickle, size_t raw_length +); + +/** + * Decode and decrypt the given pickle in-situ. + * + * Returns the number of bytes in the decoded pickle, or olm_error() on error, + * in which case *last_error will be updated, if last_error is non-NULL. + */ +size_t _olm_enc_input( + uint8_t const * key, size_t key_length, + uint8_t * input, size_t b64_length, + enum OlmErrorCode * last_error +); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* OLM_PICKLE_ENCODING_H_ */ -- cgit v1.2.3 From 68d3c7bfa9d0d2f8a44edcd2d277c4a516ed6ed5 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 27 Apr 2016 17:16:55 +0100 Subject: Implementation of the megolm ratchet --- include/olm/megolm.h | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 include/olm/megolm.h (limited to 'include') diff --git a/include/olm/megolm.h b/include/olm/megolm.h new file mode 100644 index 0000000..784597e --- /dev/null +++ b/include/olm/megolm.h @@ -0,0 +1,72 @@ +/* Copyright 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_MEGOLM_H_ +#define OLM_MEGOLM_H_ + +/** + * implementation of the Megolm multi-part ratchet used in group chats. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * number of bytes in each part of the ratchet; this should be the same as + * the length of the hash function used in the HMAC (32 bytes for us, as we + * use HMAC-SHA-256) + */ +#define MEGOLM_RATCHET_PART_LENGTH 32 /* SHA256_OUTPUT_LENGTH */ + +/** + * number of parts in the ratchet; the advance() implementations rely on + * this being 4. + */ +#define MEGOLM_RATCHET_PARTS 4 + +#define MEGOLM_RATCHET_LENGTH (MEGOLM_RATCHET_PARTS * MEGOLM_RATCHET_PART_LENGTH) + +typedef struct Megolm { + uint8_t data[MEGOLM_RATCHET_PARTS][MEGOLM_RATCHET_PART_LENGTH]; + uint32_t counter; +} Megolm; + +/** + * initialize the megolm ratchet. random_data should be at least + * MEGOLM_RATCHET_LENGTH bytes of randomness. + */ +void megolm_init(Megolm *megolm, uint8_t const *random_data, uint32_t counter); + +/** advance the ratchet by one step */ +void megolm_advance(Megolm *megolm); + +/** + * get the key data in the ratchet. The returned data is + * MEGOLM_RATCHET_LENGTH bytes long. + */ +#define megolm_get_data(megolm) ((const uint8_t *)((megolm)->data)) + +/** advance the ratchet to a given count */ +void megolm_advance_to(Megolm *megolm, uint32_t advance_to); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* OLM_MEGOLM_H_ */ -- cgit v1.2.3 From caaed796ad54de3f8ee1e56123973ae9ace346b9 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 17 May 2016 11:52:06 +0100 Subject: Implementation of an outbound group session --- include/olm/error.h | 1 - include/olm/megolm.h | 8 ++++ include/olm/message.h | 72 +++++++++++++++++++++++++++++ include/olm/message.hh | 12 +++++ include/olm/olm.h | 2 + include/olm/outbound_group_session.h | 90 ++++++++++++++++++++++++++++++++++++ 6 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 include/olm/message.h create mode 100644 include/olm/outbound_group_session.h (limited to 'include') diff --git a/include/olm/error.h b/include/olm/error.h index 460017e..87e019a 100644 --- a/include/olm/error.h +++ b/include/olm/error.h @@ -34,7 +34,6 @@ enum OlmErrorCode { /* remember to update the list of string constants in error.c when updating * this list. */ - }; /** get a string representation of the given error code. */ diff --git a/include/olm/megolm.h b/include/olm/megolm.h index 784597e..5cae353 100644 --- a/include/olm/megolm.h +++ b/include/olm/megolm.h @@ -47,6 +47,14 @@ typedef struct Megolm { uint32_t counter; } Megolm; + +/** + * Get the cipher used in megolm-backed conversations + * + * (AES256 + SHA256, with keys based on an HKDF with info of MEGOLM_KEYS) + */ +const struct _olm_cipher *megolm_cipher(); + /** * initialize the megolm ratchet. random_data should be at least * MEGOLM_RATCHET_LENGTH bytes of randomness. diff --git a/include/olm/message.h b/include/olm/message.h new file mode 100644 index 0000000..05fb56c --- /dev/null +++ b/include/olm/message.h @@ -0,0 +1,72 @@ +/* Copyright 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. + */ + +/** + * functions for encoding and decoding messages in the Olm protocol. + * + * Some of these functions have only C++ bindings, and are declared in + * message.hh; in time, they should probably be converted to plain C and + * declared here. + */ + +#ifndef OLM_MESSAGE_H_ +#define OLM_MESSAGE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The length of the buffer needed to hold a group message. + */ +size_t _olm_encode_group_message_length( + size_t group_session_id_length, + uint32_t chain_index, + size_t ciphertext_length, + size_t mac_length +); + +/** + * Writes the message headers into the output buffer. + * + * version: version number of the olm protocol + * session_id: group session identifier + * session_id_length: length of session_id + * chain_index: message index + * ciphertext_length: length of the ciphertext + * output: where to write the output. Should be at least + * olm_encode_group_message_length() bytes long. + * ciphertext_ptr: returns the address that the ciphertext + * should be written to, followed by the MAC. + */ +void _olm_encode_group_message( + uint8_t version, + const uint8_t *session_id, + size_t session_id_length, + uint32_t chain_index, + size_t ciphertext_length, + uint8_t *output, + uint8_t **ciphertext_ptr +); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* OLM_MESSAGE_H_ */ diff --git a/include/olm/message.hh b/include/olm/message.hh index 5ce0a62..bd912d9 100644 --- a/include/olm/message.hh +++ b/include/olm/message.hh @@ -12,6 +12,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + + +/** + * functions for encoding and decoding messages in the Olm protocol. + * + * Some of these functions have plain-C bindings, and are declared in + * message.h; in time, all of the functions declared here should probably be + * converted to plain C and moved to message.h. + */ + +#include "message.h" + #include #include diff --git a/include/olm/olm.h b/include/olm/olm.h index 8abac49..00e1f63 100644 --- a/include/olm/olm.h +++ b/include/olm/olm.h @@ -19,6 +19,8 @@ #include #include +#include "olm/outbound_group_session.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/include/olm/outbound_group_session.h b/include/olm/outbound_group_session.h new file mode 100644 index 0000000..6c02370 --- /dev/null +++ b/include/olm/outbound_group_session.h @@ -0,0 +1,90 @@ +/* Copyright 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_OUTBOUND_GROUP_SESSION_H_ +#define OLM_OUTBOUND_GROUP_SESSION_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OlmOutboundGroupSession OlmOutboundGroupSession; + +/** get the size of an outbound group session, in bytes. */ +size_t olm_outbound_group_session_size(); + +/** + * Initialise an outbound group session object using the supplied memory + * The supplied memory should be at least olm_outbound_group_session_size() + * bytes. + */ +OlmOutboundGroupSession * olm_outbound_group_session( + void *memory +); + +/** + * A null terminated string describing the most recent error to happen to a + * group session */ +const char *olm_outbound_group_session_last_error( + const OlmOutboundGroupSession *session +); + +/** Clears the memory used to back this group session */ +size_t olm_clear_outbound_group_session( + OlmOutboundGroupSession *session +); + +/** The number of random bytes needed to create an outbound group session */ +size_t olm_init_outbound_group_session_random_length( + const OlmOutboundGroupSession *session +); + +/** + * Start a new outbound group session. Returns std::size_t(-1) on failure. On + * failure last_error will be set with an error code. The last_error will be + * NOT_ENOUGH_RANDOM if the number of random bytes was too small. + */ +size_t olm_init_outbound_group_session( + OlmOutboundGroupSession *session, + uint8_t const * random, size_t random_length +); + +/** + * The number of bytes that will be created by encrypting a message + */ +size_t olm_group_encrypt_message_length( + OlmOutboundGroupSession *session, + size_t plaintext_length +); + +/** + * Encrypt some plain-text. Returns the length of the encrypted message or + * std::size_t(-1) on failure. On failure last_error will be set with an + * error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if the output + * buffer is too small. + */ +size_t olm_group_encrypt( + OlmOutboundGroupSession *session, + uint8_t const * plaintext, size_t plaintext_length, + uint8_t * message, size_t message_length +); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* OLM_OUTBOUND_GROUP_SESSION_H_ */ -- cgit v1.2.3 From c058554132a0f97e8e8ae3a402605220f8fdaed4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 17 May 2016 18:53:00 +0100 Subject: Implement pickling/unpickling for outbound group sessions --- include/olm/megolm.h | 15 +++++++++++++++ include/olm/outbound_group_session.h | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) (limited to 'include') diff --git a/include/olm/megolm.h b/include/olm/megolm.h index 5cae353..831c6fb 100644 --- a/include/olm/megolm.h +++ b/include/olm/megolm.h @@ -61,6 +61,21 @@ const struct _olm_cipher *megolm_cipher(); */ void megolm_init(Megolm *megolm, uint8_t const *random_data, uint32_t counter); +/** Returns the number of bytes needed to store a megolm */ +size_t megolm_pickle_length(const Megolm *megolm); + +/** + * Pickle the megolm. Returns a pointer to the next free space in the buffer. + */ +uint8_t * megolm_pickle(const Megolm *megolm, uint8_t *pos); + +/** + * Unpickle the megolm. Returns a pointer to the next item in the buffer. + */ +const uint8_t * megolm_unpickle(Megolm *megolm, const uint8_t *pos, + const uint8_t *end); + + /** advance the ratchet by one step */ void megolm_advance(Megolm *megolm); diff --git a/include/olm/outbound_group_session.h b/include/olm/outbound_group_session.h index 6c02370..27991ac 100644 --- a/include/olm/outbound_group_session.h +++ b/include/olm/outbound_group_session.h @@ -48,6 +48,42 @@ size_t olm_clear_outbound_group_session( OlmOutboundGroupSession *session ); +/** Returns the number of bytes needed to store an outbound group session */ +size_t olm_pickle_outbound_group_session_length( + const OlmOutboundGroupSession *session +); + +/** + * Stores a group session as a base64 string. Encrypts the session using the + * supplied key. Returns the length of the session on success. + * + * Returns olm_error() on failure. If the pickle output buffer + * is smaller than olm_pickle_outbound_group_session_length() then + * olm_outbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" + */ +size_t olm_pickle_outbound_group_session( + OlmOutboundGroupSession *session, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +); + +/** + * Loads a group 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_outbound_group_session_last_error() will be + * "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then + * olm_outbound_group_session_last_error() will be "INVALID_BASE64". The input + * pickled buffer is destroyed + */ +size_t olm_unpickle_outbound_group_session( + OlmOutboundGroupSession *session, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +); + + /** The number of random bytes needed to create an outbound group session */ size_t olm_init_outbound_group_session_random_length( const OlmOutboundGroupSession *session -- cgit v1.2.3 From 8b1514c0a653ccc3f49db70131d7d4f7524f1f9b Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 18 May 2016 17:20:06 +0100 Subject: Implement functions to get the state of outbound session We need to be able to inspect an outbound session so that we can tell our peer how to set up an inbound session. --- include/olm/outbound_group_session.h | 59 ++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/olm/outbound_group_session.h b/include/olm/outbound_group_session.h index 27991ac..90859e9 100644 --- a/include/olm/outbound_group_session.h +++ b/include/olm/outbound_group_session.h @@ -90,7 +90,7 @@ size_t olm_init_outbound_group_session_random_length( ); /** - * Start a new outbound group session. Returns std::size_t(-1) on failure. On + * Start a new outbound group session. Returns olm_error() on failure. On * failure last_error will be set with an error code. The last_error will be * NOT_ENOUGH_RANDOM if the number of random bytes was too small. */ @@ -109,7 +109,7 @@ size_t olm_group_encrypt_message_length( /** * Encrypt some plain-text. Returns the length of the encrypted message or - * std::size_t(-1) on failure. On failure last_error will be set with an + * olm_error() on failure. On failure last_error will be set with an * error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if the output * buffer is too small. */ @@ -119,6 +119,61 @@ size_t olm_group_encrypt( uint8_t * message, size_t message_length ); + +/** + * Get the number of bytes returned by olm_outbound_group_session_id() + */ +size_t olm_outbound_group_session_id_length( + const OlmOutboundGroupSession *session +); + +/** + * Get a base64-encoded identifier for this session. + * + * Returns the length of the session id on success or olm_error() on + * failure. On failure last_error will be set with an error code. The + * last_error will be OUTPUT_BUFFER_TOO_SMALL if the id buffer was too + * small. + */ +size_t olm_outbound_group_session_id( + OlmOutboundGroupSession *session, + uint8_t * id, size_t id_length +); + +/** + * Get the current message index for this session. + * + * Each message is sent with an increasing index; this returns the index for + * the next message. + */ +uint32_t olm_outbound_group_session_message_index( + OlmOutboundGroupSession *session +); + +/** + * Get the number of bytes returned by olm_outbound_group_session_key() + */ +size_t olm_outbound_group_session_key_length( + const OlmOutboundGroupSession *session +); + +/** + * Get the base64-encoded current ratchet key for this session. + * + * Each message is sent with a diffent ratchet key. This function returns the + * ratchet key that will be used for the next message. + * + * Returns the length of the ratchet key on success or olm_error() on + * failure. On failure last_error will be set with an error code. The + * last_error will be OUTPUT_BUFFER_TOO_SMALL if the buffer was too small. + */ +size_t olm_outbound_group_session_key( + OlmOutboundGroupSession *session, + uint8_t * key, size_t key_length +); + + + #ifdef __cplusplus } // extern "C" #endif -- cgit v1.2.3 From 39ad75314b9e28053f568ed6a4109f5d3a9468fe Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 18 May 2016 17:23:09 +0100 Subject: Implement decrypting inbound group messages Includes creation of inbound sessions, etc --- include/olm/error.h | 3 + include/olm/inbound_group_session.h | 153 ++++++++++++++++++++++++++++++++++++ include/olm/message.h | 24 ++++++ include/olm/olm.h | 1 + 4 files changed, 181 insertions(+) create mode 100644 include/olm/inbound_group_session.h (limited to 'include') diff --git a/include/olm/error.h b/include/olm/error.h index 87e019a..3f74992 100644 --- a/include/olm/error.h +++ b/include/olm/error.h @@ -32,6 +32,9 @@ enum OlmErrorCode { OLM_UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */ OLM_CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */ + OLM_BAD_RATCHET_KEY = 11, + OLM_BAD_CHAIN_INDEX = 12, + /* remember to update the list of string constants in error.c when updating * this list. */ }; diff --git a/include/olm/inbound_group_session.h b/include/olm/inbound_group_session.h new file mode 100644 index 0000000..4cf4ac4 --- /dev/null +++ b/include/olm/inbound_group_session.h @@ -0,0 +1,153 @@ +/* Copyright 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_INBOUND_GROUP_SESSION_H_ +#define OLM_INBOUND_GROUP_SESSION_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OlmInboundGroupSession OlmInboundGroupSession; + +/** get the size of an inbound group session, in bytes. */ +size_t olm_inbound_group_session_size(); + +/** + * Initialise an inbound group session object using the supplied memory + * The supplied memory should be at least olm_inbound_group_session_size() + * bytes. + */ +OlmInboundGroupSession * olm_inbound_group_session( + void *memory +); + +/** + * A null terminated string describing the most recent error to happen to a + * group session */ +const char *olm_inbound_group_session_last_error( + const OlmInboundGroupSession *session +); + +/** Clears the memory used to back this group session */ +size_t olm_clear_inbound_group_session( + OlmInboundGroupSession *session +); + +/** Returns the number of bytes needed to store an inbound group session */ +size_t olm_pickle_inbound_group_session_length( + const OlmInboundGroupSession *session +); + +/** + * Stores a group session as a base64 string. Encrypts the session using the + * supplied key. Returns the length of the session on success. + * + * Returns olm_error() on failure. If the pickle output buffer + * is smaller than olm_pickle_inbound_group_session_length() then + * olm_inbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" + */ +size_t olm_pickle_inbound_group_session( + OlmInboundGroupSession *session, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +); + +/** + * Loads a group 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_inbound_group_session_last_error() will be + * "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then + * olm_inbound_group_session_last_error() will be "INVALID_BASE64". The input + * pickled buffer is destroyed + */ +size_t olm_unpickle_inbound_group_session( + OlmInboundGroupSession *session, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +); + + +/** + * Start a new inbound group session, based on the parameters supplied. + * + * Returns olm_error() on failure. On failure last_error will be set with an + * error code. The last_error will be: + * + * * OLM_INVALID_BASE64 if the session_key is not valid base64 + * * OLM_BAD_RATCHET_KEY if the session_key is invalid + */ +size_t olm_init_inbound_group_session( + OlmInboundGroupSession *session, + uint32_t message_index, + + /* base64-encoded key */ + uint8_t const * session_key, size_t session_key_length +); + +/** + * Get an upper bound on the number of bytes of plain-text the decrypt method + * will write for a given input message length. The actual size could be + * different due to padding. + * + * The input message buffer is destroyed. + * + * Returns olm_error() on failure. + */ +size_t olm_group_decrypt_max_plaintext_length( + OlmInboundGroupSession *session, + uint8_t * message, size_t message_length +); + +/** + * Decrypt a message. + * + * The input message buffer is destroyed. + * + * Returns the length of the decrypted plain-text, or olm_error() on failure. + * + * On failure last_error will be set with an error code. The last_error will + * be: + * * OLM_OUTPUT_BUFFER_TOO_SMALL if the plain-text buffer is too small + * * OLM_INVALID_BASE64 if the message is not valid base-64 + * * OLM_BAD_MESSAGE_VERSION if the message was encrypted with an unsupported + * version of the protocol + * * OLM_BAD_MESSAGE_FORMAT if the message headers could not be decoded + * * OLM_BAD_MESSAGE_MAC if the message could not be verified + * * OLM_BAD_CHAIN_INDEX if we do not have a ratchet key corresponding to the + * message's index (ie, it was sent before the ratchet key was shared with + * us) + */ +size_t olm_group_decrypt( + OlmInboundGroupSession *session, + + /* input; note that it will be overwritten with the base64-decoded + message. */ + uint8_t * message, size_t message_length, + + /* output */ + uint8_t * plaintext, size_t max_plaintext_length +); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* OLM_INBOUND_GROUP_SESSION_H_ */ diff --git a/include/olm/message.h b/include/olm/message.h index 05fb56c..bd7aec3 100644 --- a/include/olm/message.h +++ b/include/olm/message.h @@ -65,6 +65,30 @@ void _olm_encode_group_message( ); +struct _OlmDecodeGroupMessageResults { + uint8_t version; + const uint8_t *session_id; + size_t session_id_length; + uint32_t chain_index; + int has_chain_index; + const uint8_t *ciphertext; + size_t ciphertext_length; +}; + + +/** + * Reads the message headers from the input buffer. + */ +void _olm_decode_group_message( + const uint8_t *input, size_t input_length, + size_t mac_length, + + /* output structure: updated with results */ + struct _OlmDecodeGroupMessageResults *results +); + + + #ifdef __cplusplus } // extern "C" #endif diff --git a/include/olm/olm.h b/include/olm/olm.h index 00e1f63..dbaf71e 100644 --- a/include/olm/olm.h +++ b/include/olm/olm.h @@ -19,6 +19,7 @@ #include #include +#include "olm/inbound_group_session.h" #include "olm/outbound_group_session.h" #ifdef __cplusplus -- cgit v1.2.3 From fc4756ddf17f536912a89a4ffcf90a309c236ced Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 19 May 2016 07:53:07 +0100 Subject: Fix up some names, and protobuf tags Make names (of session_key and message_index) more consistent. Use our own protobuf tags rather than trying to piggyback on the one-to-one structure. --- include/olm/error.h | 8 ++++++-- include/olm/inbound_group_session.h | 8 ++++---- include/olm/message.h | 8 ++++---- 3 files changed, 14 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/olm/error.h b/include/olm/error.h index 3f74992..98d2cf5 100644 --- a/include/olm/error.h +++ b/include/olm/error.h @@ -32,8 +32,12 @@ enum OlmErrorCode { OLM_UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */ OLM_CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */ - OLM_BAD_RATCHET_KEY = 11, - OLM_BAD_CHAIN_INDEX = 12, + OLM_BAD_SESSION_KEY = 11, /*!< Attempt to initialise an inbound group + session from an invalid session key */ + OLM_UNKNOWN_MESSAGE_INDEX = 12, /*!< Attempt to decode a message whose + * index is earlier than our earliest + * known session key. + */ /* remember to update the list of string constants in error.c when updating * this list. */ diff --git a/include/olm/inbound_group_session.h b/include/olm/inbound_group_session.h index 4cf4ac4..e24f377 100644 --- a/include/olm/inbound_group_session.h +++ b/include/olm/inbound_group_session.h @@ -91,7 +91,7 @@ size_t olm_unpickle_inbound_group_session( * error code. The last_error will be: * * * OLM_INVALID_BASE64 if the session_key is not valid base64 - * * OLM_BAD_RATCHET_KEY if the session_key is invalid + * * OLM_BAD_SESSION_KEY if the session_key is invalid */ size_t olm_init_inbound_group_session( OlmInboundGroupSession *session, @@ -129,9 +129,9 @@ size_t olm_group_decrypt_max_plaintext_length( * * OLM_BAD_MESSAGE_VERSION if the message was encrypted with an unsupported * version of the protocol * * OLM_BAD_MESSAGE_FORMAT if the message headers could not be decoded - * * OLM_BAD_MESSAGE_MAC if the message could not be verified - * * OLM_BAD_CHAIN_INDEX if we do not have a ratchet key corresponding to the - * message's index (ie, it was sent before the ratchet key was shared with + * * OLM_BAD_MESSAGE_MAC if the message could not be verified + * * OLM_UNKNOWN_MESSAGE_INDEX if we do not have a session key corresponding to the + * message's index (ie, it was sent before the session key was shared with * us) */ size_t olm_group_decrypt( diff --git a/include/olm/message.h b/include/olm/message.h index bd7aec3..cff15f3 100644 --- a/include/olm/message.h +++ b/include/olm/message.h @@ -47,7 +47,7 @@ size_t _olm_encode_group_message_length( * version: version number of the olm protocol * session_id: group session identifier * session_id_length: length of session_id - * chain_index: message index + * message_index: message index * ciphertext_length: length of the ciphertext * output: where to write the output. Should be at least * olm_encode_group_message_length() bytes long. @@ -58,7 +58,7 @@ void _olm_encode_group_message( uint8_t version, const uint8_t *session_id, size_t session_id_length, - uint32_t chain_index, + uint32_t message_index, size_t ciphertext_length, uint8_t *output, uint8_t **ciphertext_ptr @@ -69,8 +69,8 @@ struct _OlmDecodeGroupMessageResults { uint8_t version; const uint8_t *session_id; size_t session_id_length; - uint32_t chain_index; - int has_chain_index; + uint32_t message_index; + int has_message_index; const uint8_t *ciphertext; size_t ciphertext_length; }; -- cgit v1.2.3 From a919a149fbb192e3fae7aba921ca28e02d9c0d10 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 24 May 2016 14:54:01 +0100 Subject: Update megolm_cipher as a global struct Initialise megolm_cipher via the preprocessor macro, instead of with a function. --- include/olm/megolm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/olm/megolm.h b/include/olm/megolm.h index 831c6fb..e4e5d0b 100644 --- a/include/olm/megolm.h +++ b/include/olm/megolm.h @@ -49,11 +49,11 @@ typedef struct Megolm { /** - * Get the cipher used in megolm-backed conversations + * The cipher used in megolm-backed conversations * * (AES256 + SHA256, with keys based on an HKDF with info of MEGOLM_KEYS) */ -const struct _olm_cipher *megolm_cipher(); +extern const struct _olm_cipher *megolm_cipher; /** * initialize the megolm ratchet. random_data should be at least -- cgit v1.2.3 From 1b15465c42a88f750a960a0e73f186245f9bba33 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 24 May 2016 16:23:19 +0100 Subject: Separate base64ing from the rest of msg encoding Factor the actual message encoding/decoding and encrypting/decrypting out to separate functions from the top-level functions which do the base64-wrangling. This is particularly helpful in the 'outbound' code-path where the offsets required to allow room to base64-encode make the flow hard to see when it's all inline. --- include/olm/message.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/olm/message.h b/include/olm/message.h index cff15f3..e80d54c 100644 --- a/include/olm/message.h +++ b/include/olm/message.h @@ -53,8 +53,10 @@ size_t _olm_encode_group_message_length( * olm_encode_group_message_length() bytes long. * ciphertext_ptr: returns the address that the ciphertext * should be written to, followed by the MAC. + * + * Returns the size of the message, up to the MAC. */ -void _olm_encode_group_message( +size_t _olm_encode_group_message( uint8_t version, const uint8_t *session_id, size_t session_id_length, -- cgit v1.2.3