]> gitweb.ps.run Git - matrix_esp_thesis/blob - ext/olm/include/olm/ratchet.hh
add dependencies to repo
[matrix_esp_thesis] / ext / olm / include / olm / ratchet.hh
1 /* Copyright 2015 OpenMarket Ltd
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <cstdint>
17
18 #include "olm/crypto.h"
19 #include "olm/list.hh"
20 #include "olm/error.h"
21
22 // Note: exports in this file are only for unit tests.  Nobody else should be
23 // using this externally
24 #include "olm/olm_export.h"
25
26 struct _olm_cipher;
27
28 namespace olm {
29
30 /** length of a shared key: the root key R(i), chain key C(i,j), and message key
31  * M(i,j)). They are all only used to stuff into HMACs, so could be any length
32  * for that. The chain key and message key are both derived from SHA256
33  * operations, so their length is determined by that. */
34 const std::size_t OLM_SHARED_KEY_LENGTH = SHA256_OUTPUT_LENGTH;
35
36 typedef std::uint8_t SharedKey[OLM_SHARED_KEY_LENGTH];
37
38 struct ChainKey {
39     std::uint32_t index;
40     SharedKey key;
41 };
42
43 struct MessageKey {
44     std::uint32_t index;
45     SharedKey key;
46 };
47
48
49 struct SenderChain {
50     _olm_curve25519_key_pair ratchet_key;
51     ChainKey chain_key;
52 };
53
54
55 struct ReceiverChain {
56     _olm_curve25519_public_key ratchet_key;
57     ChainKey chain_key;
58 };
59
60
61 struct SkippedMessageKey {
62     _olm_curve25519_public_key ratchet_key;
63     MessageKey message_key;
64 };
65
66
67 static std::size_t const MAX_RECEIVER_CHAINS = 5;
68 static std::size_t const MAX_SKIPPED_MESSAGE_KEYS = 40;
69
70
71 struct KdfInfo {
72     std::uint8_t const * root_info;
73     std::size_t root_info_length;
74     std::uint8_t const * ratchet_info;
75     std::size_t ratchet_info_length;
76 };
77
78
79 struct OLM_EXPORT Ratchet {
80
81     Ratchet(
82         KdfInfo const & kdf_info,
83         _olm_cipher const *ratchet_cipher
84     );
85
86     /** A some strings identifying the application to feed into the KDF. */
87     KdfInfo const & kdf_info;
88
89     /** The AEAD cipher to use for encrypting messages. */
90     _olm_cipher const *ratchet_cipher;
91
92     /** The last error that happened encrypting or decrypting a message. */
93     OlmErrorCode last_error;
94
95     /** The root key is used to generate chain keys from the ephemeral keys.
96      * A new root_key derived each time a new chain is started. */
97     SharedKey root_key;
98
99     /** The sender chain is used to send messages. Each time a new ephemeral
100      * key is received from the remote server we generate a new sender chain
101      * with a new ephemeral key when we next send a message. */
102     List<SenderChain, 1> sender_chain;
103
104     /** The receiver chain is used to decrypt received messages. We store the
105      * last few chains so we can decrypt any out of order messages we haven't
106      * received yet. */
107     List<ReceiverChain, MAX_RECEIVER_CHAINS> receiver_chains;
108
109     /** List of message keys we've skipped over when advancing the receiver
110      * chain. */
111     List<SkippedMessageKey, MAX_SKIPPED_MESSAGE_KEYS> skipped_message_keys;
112
113     /** Initialise the session using a shared secret and the public part of the
114      * remote's first ratchet key */
115     void initialise_as_bob(
116         std::uint8_t const * shared_secret, std::size_t shared_secret_length,
117         _olm_curve25519_public_key const & their_ratchet_key
118     );
119
120     /** Initialise the session using a shared secret and the public/private key
121      * pair for the first ratchet key */
122     void initialise_as_alice(
123         std::uint8_t const * shared_secret, std::size_t shared_secret_length,
124         _olm_curve25519_key_pair const & our_ratchet_key
125     );
126
127     /** The number of bytes of output the encrypt method will write for
128      * a given message length. */
129     std::size_t encrypt_output_length(
130         std::size_t plaintext_length
131     ) const;
132
133     /** The number of bytes of random data the encrypt method will need to
134      * encrypt a message. This will be 32 bytes if the session needs to
135      * generate a new ephemeral key, or will be 0 bytes otherwise.*/
136     std::size_t encrypt_random_length() const;
137
138     /** Encrypt some plain-text. Returns the length of the encrypted message
139      * or std::size_t(-1) on failure. On failure last_error will be set with
140      * an error code. The last_error will be NOT_ENOUGH_RANDOM if the number
141      * of random bytes is too small. The last_error will be
142      * OUTPUT_BUFFER_TOO_SMALL if the output buffer is too small. */
143     std::size_t encrypt(
144         std::uint8_t const * plaintext, std::size_t plaintext_length,
145         std::uint8_t const * random, std::size_t random_length,
146         std::uint8_t * output, std::size_t max_output_length
147     );
148
149     /** An upper bound on the number of bytes of plain-text the decrypt method
150      * will write for a given input message length. */
151     std::size_t decrypt_max_plaintext_length(
152         std::uint8_t const * input, std::size_t input_length
153     );
154
155     /** Decrypt a message. Returns the length of the decrypted plain-text or
156      * std::size_t(-1) on failure. On failure last_error will be set with an
157      * error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if the
158      * plain-text buffer is too small. The last_error will be
159      * BAD_MESSAGE_VERSION if the message was encrypted with an unsupported
160      * version of the protocol. The last_error will be BAD_MESSAGE_FORMAT if
161      * the message headers could not be decoded. The last_error will be
162      * BAD_MESSAGE_MAC if the message could not be verified */
163     std::size_t decrypt(
164         std::uint8_t const * input, std::size_t input_length,
165         std::uint8_t * plaintext, std::size_t max_plaintext_length
166     );
167 };
168
169
170 std::size_t pickle_length(
171     Ratchet const & value
172 );
173
174
175 std::uint8_t * pickle(
176     std::uint8_t * pos,
177     Ratchet const & value
178 );
179
180
181 std::uint8_t const * unpickle(
182     std::uint8_t const * pos, std::uint8_t const * end,
183     Ratchet & value,
184     bool includes_chain_index
185 );
186
187
188 } // namespace olm