| 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 |
| 27 | extern "C" { |
| 28 | #endif |
| 29 | |
| 30 | typedef struct OlmPkEncryption OlmPkEncryption; |
| 31 | |
| 32 | /* The size of an encryption object in bytes */ |
| 33 | OLM_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 */ |
| 37 | OLM_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 */ |
| 43 | OLM_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 */ |
| 49 | OLM_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 */ |
| 54 | OLM_EXPORT size_t olm_clear_pk_encryption( |
| 55 | OlmPkEncryption *encryption |
| 56 | ); |
| 57 | |
| 58 | /** Set the recipient's public key for encrypting to */ |
| 59 | OLM_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. */ |
| 66 | OLM_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. */ |
| 72 | OLM_EXPORT size_t olm_pk_mac_length( |
| 73 | const OlmPkEncryption *encryption |
| 74 | ); |
| 75 | |
| 76 | /** Get the length of a public or ephemeral key */ |
| 77 | OLM_EXPORT size_t olm_pk_key_length(void); |
| 78 | |
| 79 | /** The number of random bytes needed to encrypt a message. */ |
| 80 | OLM_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". */ |
| 94 | OLM_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 | |
| 103 | typedef struct OlmPkDecryption OlmPkDecryption; |
| 104 | |
| 105 | /* The size of a decryption object in bytes */ |
| 106 | OLM_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 */ |
| 110 | OLM_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 */ |
| 116 | OLM_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 */ |
| 122 | OLM_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 */ |
| 127 | OLM_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 | */ |
| 133 | OLM_EXPORT size_t olm_pk_private_key_length(void); |
| 134 | |
| 135 | /** DEPRECATED: Use olm_pk_private_key_length() |
| 136 | */ |
| 137 | OLM_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 | */ |
| 149 | OLM_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 | */ |
| 157 | OLM_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. */ |
| 164 | OLM_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" */ |
| 173 | OLM_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 */ |
| 186 | OLM_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. */ |
| 195 | OLM_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". */ |
| 205 | OLM_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 | */ |
| 221 | OLM_EXPORT size_t olm_pk_get_private_key( |
| 222 | OlmPkDecryption * decryption, |
| 223 | void *private_key, size_t private_key_length |
| 224 | ); |
| 225 | |
| 226 | typedef struct OlmPkSigning OlmPkSigning; |
| 227 | |
| 228 | /* The size of a signing object in bytes */ |
| 229 | OLM_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 */ |
| 233 | OLM_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 */ |
| 239 | OLM_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 */ |
| 245 | OLM_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 */ |
| 250 | OLM_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 | */ |
| 262 | OLM_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 | */ |
| 271 | OLM_EXPORT size_t olm_pk_signing_seed_length(void); |
| 272 | |
| 273 | /** |
| 274 | * The size of the public key of a signing object. |
| 275 | */ |
| 276 | OLM_EXPORT size_t olm_pk_signing_public_key_length(void); |
| 277 | |
| 278 | /** |
| 279 | * The size of a signature created by a signing object. |
| 280 | */ |
| 281 | OLM_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 | */ |
| 288 | OLM_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 | |