1/* Copyright 2018, 2019 New Vector 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#ifndef OLM_PK_H_
17#define OLM_PK_H_
18
19#include <stddef.h>
20#include <stdint.h>
21
22#include "olm/error.h"
23
24#include "olm/olm_export.h"
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30typedef struct OlmPkEncryption OlmPkEncryption;
31
32/* The size of an encryption object in bytes */
33OLM_EXPORT size_t olm_pk_encryption_size(void);
34
35/** Initialise an encryption object using the supplied memory
36 * The supplied memory must be at least olm_pk_encryption_size() bytes */
37OLM_EXPORT OlmPkEncryption *olm_pk_encryption(
38 void * memory
39);
40
41/** A null terminated string describing the most recent error to happen to an
42 * encryption object */
43OLM_EXPORT const char * olm_pk_encryption_last_error(
44 const OlmPkEncryption * encryption
45);
46
47/** An error code describing the most recent error to happen to an encryption
48 * object */
49OLM_EXPORT enum OlmErrorCode olm_pk_encryption_last_error_code(
50 const OlmPkEncryption * encryption
51);
52
53/** Clears the memory used to back this encryption object */
54OLM_EXPORT size_t olm_clear_pk_encryption(
55 OlmPkEncryption *encryption
56);
57
58/** Set the recipient's public key for encrypting to */
59OLM_EXPORT size_t olm_pk_encryption_set_recipient_key(
60 OlmPkEncryption *encryption,
61 void const *public_key, size_t public_key_length
62);
63
64/** Get the length of the ciphertext that will correspond to a plaintext of the
65 * given length. */
66OLM_EXPORT size_t olm_pk_ciphertext_length(
67 const OlmPkEncryption *encryption,
68 size_t plaintext_length
69);
70
71/** Get the length of the message authentication code. */
72OLM_EXPORT size_t olm_pk_mac_length(
73 const OlmPkEncryption *encryption
74);
75
76/** Get the length of a public or ephemeral key */
77OLM_EXPORT size_t olm_pk_key_length(void);
78
79/** The number of random bytes needed to encrypt a message. */
80OLM_EXPORT size_t olm_pk_encrypt_random_length(
81 const OlmPkEncryption *encryption
82);
83
84/** Encrypt a plaintext for the recipient set using
85 * olm_pk_encryption_set_recipient_key. Writes to the ciphertext, mac, and
86 * ephemeral_key buffers, whose values should be sent to the recipient. mac is
87 * a Message Authentication Code to ensure that the data is received and
88 * decrypted properly. ephemeral_key is the public part of the ephemeral key
89 * used (together with the recipient's key) to generate a symmetric encryption
90 * key. Returns olm_error() on failure. If the ciphertext, mac, or
91 * ephemeral_key buffers were too small then olm_pk_encryption_last_error()
92 * will be "OUTPUT_BUFFER_TOO_SMALL". If there weren't enough random bytes then
93 * olm_pk_encryption_last_error() will be "OLM_INPUT_BUFFER_TOO_SMALL". */
94OLM_EXPORT size_t olm_pk_encrypt(
95 OlmPkEncryption *encryption,
96 void const * plaintext, size_t plaintext_length,
97 void * ciphertext, size_t ciphertext_length,
98 void * mac, size_t mac_length,
99 void * ephemeral_key, size_t ephemeral_key_size,
100 const void * random, size_t random_length
101);
102
103typedef struct OlmPkDecryption OlmPkDecryption;
104
105/* The size of a decryption object in bytes */
106OLM_EXPORT size_t olm_pk_decryption_size(void);
107
108/** Initialise a decryption object using the supplied memory
109 * The supplied memory must be at least olm_pk_decryption_size() bytes */
110OLM_EXPORT OlmPkDecryption *olm_pk_decryption(
111 void * memory
112);
113
114/** A null terminated string describing the most recent error to happen to a
115 * decription object */
116OLM_EXPORT const char * olm_pk_decryption_last_error(
117 const OlmPkDecryption * decryption
118);
119
120/** An error code describing the most recent error to happen to a decription
121 * object */
122OLM_EXPORT enum OlmErrorCode olm_pk_decryption_last_error_code(
123 const OlmPkDecryption * decryption
124);
125
126/** Clears the memory used to back this decryption object */
127OLM_EXPORT size_t olm_clear_pk_decryption(
128 OlmPkDecryption *decryption
129);
130
131/** Get the number of bytes required to store an olm private key
132 */
133OLM_EXPORT size_t olm_pk_private_key_length(void);
134
135/** DEPRECATED: Use olm_pk_private_key_length()
136 */
137OLM_EXPORT size_t olm_pk_generate_key_random_length(void);
138
139/** Initialise the key from the private part of a key as returned by
140 * olm_pk_get_private_key(). The associated public key will be written to the
141 * pubkey buffer. Returns olm_error() on failure. If the pubkey buffer is too
142 * small then olm_pk_decryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL".
143 * If the private key was not long enough then olm_pk_decryption_last_error()
144 * will be "OLM_INPUT_BUFFER_TOO_SMALL".
145 *
146 * Note that the pubkey is a base64 encoded string, but the private key is
147 * an unencoded byte array
148 */
149OLM_EXPORT size_t olm_pk_key_from_private(
150 OlmPkDecryption * decryption,
151 void * pubkey, size_t pubkey_length,
152 const void * privkey, size_t privkey_length
153);
154
155/** DEPRECATED: Use olm_pk_key_from_private
156 */
157OLM_EXPORT size_t olm_pk_generate_key(
158 OlmPkDecryption * decryption,
159 void * pubkey, size_t pubkey_length,
160 const void * privkey, size_t privkey_length
161);
162
163/** Returns the number of bytes needed to store a decryption object. */
164OLM_EXPORT size_t olm_pickle_pk_decryption_length(
165 const OlmPkDecryption * decryption
166);
167
168/** Stores decryption object as a base64 string. Encrypts the object using the
169 * supplied key. Returns the length of the pickled object on success.
170 * Returns olm_error() on failure. If the pickle output buffer
171 * is smaller than olm_pickle_pk_decryption_length() then
172 * olm_pk_decryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
173OLM_EXPORT size_t olm_pickle_pk_decryption(
174 OlmPkDecryption * decryption,
175 void const * key, size_t key_length,
176 void *pickled, size_t pickled_length
177);
178
179/** Loads a decryption object from a pickled base64 string. The associated
180 * public key will be written to the pubkey buffer. Decrypts the object using
181 * the supplied key. Returns olm_error() on failure. If the key doesn't
182 * match the one used to encrypt the account then olm_pk_decryption_last_error()
183 * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
184 * olm_pk_decryption_last_error() will be "INVALID_BASE64". The input pickled
185 * buffer is destroyed */
186OLM_EXPORT size_t olm_unpickle_pk_decryption(
187 OlmPkDecryption * decryption,
188 void const * key, size_t key_length,
189 void *pickled, size_t pickled_length,
190 void *pubkey, size_t pubkey_length
191);
192
193/** Get the length of the plaintext that will correspond to a ciphertext of the
194 * given length. */
195OLM_EXPORT size_t olm_pk_max_plaintext_length(
196 const OlmPkDecryption * decryption,
197 size_t ciphertext_length
198);
199
200/** Decrypt a ciphertext. The input ciphertext buffer is destroyed. See the
201 * olm_pk_encrypt function for descriptions of the ephemeral_key and mac
202 * arguments. Returns the length of the plaintext on success. Returns
203 * olm_error() on failure. If the plaintext buffer is too small then
204 * olm_pk_encryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */
205OLM_EXPORT size_t olm_pk_decrypt(
206 OlmPkDecryption * decryption,
207 void const * ephemeral_key, size_t ephemeral_key_length,
208 void const * mac, size_t mac_length,
209 void * ciphertext, size_t ciphertext_length,
210 void * plaintext, size_t max_plaintext_length
211);
212
213/**
214 * Get the private key for an OlmDecryption object as an unencoded byte array
215 * private_key must be a pointer to a buffer of at least
216 * olm_pk_private_key_length() bytes and this length must be passed in
217 * private_key_length. If the given buffer is too small, returns olm_error()
218 * and olm_pk_encryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL".
219 * Returns the number of bytes written.
220 */
221OLM_EXPORT size_t olm_pk_get_private_key(
222 OlmPkDecryption * decryption,
223 void *private_key, size_t private_key_length
224);
225
226typedef struct OlmPkSigning OlmPkSigning;
227
228/* The size of a signing object in bytes */
229OLM_EXPORT size_t olm_pk_signing_size(void);
230
231/** Initialise a signing object using the supplied memory
232 * The supplied memory must be at least olm_pk_signing_size() bytes */
233OLM_EXPORT OlmPkSigning *olm_pk_signing(
234 void * memory
235);
236
237/** A null terminated string describing the most recent error to happen to a
238 * signing object */
239OLM_EXPORT const char * olm_pk_signing_last_error(
240 const OlmPkSigning * sign
241);
242
243/** A null terminated string describing the most recent error to happen to a
244 * signing object */
245OLM_EXPORT enum OlmErrorCode olm_pk_signing_last_error_code(
246 const OlmPkSigning * sign
247);
248
249/** Clears the memory used to back this signing object */
250OLM_EXPORT size_t olm_clear_pk_signing(
251 OlmPkSigning *sign
252);
253
254/**
255 * Initialise the signing object with a public/private keypair from a seed. The
256 * associated public key will be written to the pubkey buffer. Returns
257 * olm_error() on failure. If the public key buffer is too small then
258 * olm_pk_signing_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If the seed
259 * buffer is too small then olm_pk_signing_last_error() will be
260 * "INPUT_BUFFER_TOO_SMALL".
261 */
262OLM_EXPORT size_t olm_pk_signing_key_from_seed(
263 OlmPkSigning * sign,
264 void * pubkey, size_t pubkey_length,
265 const void * seed, size_t seed_length
266);
267
268/**
269 * The size required for the seed for initialising a signing object.
270 */
271OLM_EXPORT size_t olm_pk_signing_seed_length(void);
272
273/**
274 * The size of the public key of a signing object.
275 */
276OLM_EXPORT size_t olm_pk_signing_public_key_length(void);
277
278/**
279 * The size of a signature created by a signing object.
280 */
281OLM_EXPORT size_t olm_pk_signature_length(void);
282
283/**
284 * Sign a message. The signature will be written to the signature
285 * buffer. Returns olm_error() on failure. If the signature buffer is too
286 * small, olm_pk_signing_last_error() will be "OUTPUT_BUFFER_TOO_SMALL".
287 */
288OLM_EXPORT size_t olm_pk_sign(
289 OlmPkSigning *sign,
290 uint8_t const * message, size_t message_length,
291 uint8_t * signature, size_t signature_length
292);
293
294#ifdef __cplusplus
295}
296#endif
297
298#endif /* OLM_PK_H_ */
299