| 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 | /* C-compatible crpyto utility functions. At some point all of crypto.hh will |
| 17 | * move here. |
| 18 | */ |
| 19 | |
| 20 | #ifndef OLM_CRYPTO_H_ |
| 21 | #define OLM_CRYPTO_H_ |
| 22 | |
| 23 | // Note: exports in this file are only for unit tests. Nobody else should be |
| 24 | // using this externally |
| 25 | #include "olm/olm_export.h" |
| 26 | |
| 27 | #include <stdint.h> |
| 28 | #include <stdlib.h> |
| 29 | |
| 30 | #ifdef __cplusplus |
| 31 | extern "C" { |
| 32 | #endif |
| 33 | |
| 34 | /** length of a sha256 hash */ |
| 35 | #define SHA256_OUTPUT_LENGTH 32 |
| 36 | |
| 37 | /** length of a public or private Curve25519 key */ |
| 38 | #define CURVE25519_KEY_LENGTH 32 |
| 39 | |
| 40 | /** length of the shared secret created by a Curve25519 ECDH operation */ |
| 41 | #define CURVE25519_SHARED_SECRET_LENGTH 32 |
| 42 | |
| 43 | /** amount of random data required to create a Curve25519 keypair */ |
| 44 | #define CURVE25519_RANDOM_LENGTH CURVE25519_KEY_LENGTH |
| 45 | |
| 46 | /** length of a public Ed25519 key */ |
| 47 | #define ED25519_PUBLIC_KEY_LENGTH 32 |
| 48 | |
| 49 | /** length of a private Ed25519 key */ |
| 50 | #define ED25519_PRIVATE_KEY_LENGTH 64 |
| 51 | |
| 52 | /** amount of random data required to create a Ed25519 keypair */ |
| 53 | #define ED25519_RANDOM_LENGTH 32 |
| 54 | |
| 55 | /** length of an Ed25519 signature */ |
| 56 | #define ED25519_SIGNATURE_LENGTH 64 |
| 57 | |
| 58 | /** length of an aes256 key */ |
| 59 | #define AES256_KEY_LENGTH 32 |
| 60 | |
| 61 | /** length of an aes256 initialisation vector */ |
| 62 | #define AES256_IV_LENGTH 16 |
| 63 | |
| 64 | struct _olm_aes256_key { |
| 65 | uint8_t key[AES256_KEY_LENGTH]; |
| 66 | }; |
| 67 | |
| 68 | struct _olm_aes256_iv { |
| 69 | uint8_t iv[AES256_IV_LENGTH]; |
| 70 | }; |
| 71 | |
| 72 | |
| 73 | struct _olm_curve25519_public_key { |
| 74 | uint8_t public_key[CURVE25519_KEY_LENGTH]; |
| 75 | }; |
| 76 | |
| 77 | struct _olm_curve25519_private_key { |
| 78 | uint8_t private_key[CURVE25519_KEY_LENGTH]; |
| 79 | }; |
| 80 | |
| 81 | struct _olm_curve25519_key_pair { |
| 82 | struct _olm_curve25519_public_key public_key; |
| 83 | struct _olm_curve25519_private_key private_key; |
| 84 | }; |
| 85 | |
| 86 | struct _olm_ed25519_public_key { |
| 87 | uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH]; |
| 88 | }; |
| 89 | |
| 90 | struct _olm_ed25519_private_key { |
| 91 | uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH]; |
| 92 | }; |
| 93 | |
| 94 | struct _olm_ed25519_key_pair { |
| 95 | struct _olm_ed25519_public_key public_key; |
| 96 | struct _olm_ed25519_private_key private_key; |
| 97 | }; |
| 98 | |
| 99 | |
| 100 | /** The length of output the aes_encrypt_cbc function will write */ |
| 101 | OLM_EXPORT size_t _olm_crypto_aes_encrypt_cbc_length( |
| 102 | size_t input_length |
| 103 | ); |
| 104 | |
| 105 | /** Encrypts the input using AES256 in CBC mode with PKCS#7 padding. |
| 106 | * The output buffer must be big enough to hold the output including padding */ |
| 107 | OLM_EXPORT void _olm_crypto_aes_encrypt_cbc( |
| 108 | const struct _olm_aes256_key *key, |
| 109 | const struct _olm_aes256_iv *iv, |
| 110 | const uint8_t *input, size_t input_length, |
| 111 | uint8_t *output |
| 112 | ); |
| 113 | |
| 114 | /** Decrypts the input using AES256 in CBC mode. The output buffer must be at |
| 115 | * least the same size as the input buffer. Returns the length of the plaintext |
| 116 | * without padding on success or std::size_t(-1) if the padding is invalid. |
| 117 | */ |
| 118 | OLM_EXPORT size_t _olm_crypto_aes_decrypt_cbc( |
| 119 | const struct _olm_aes256_key *key, |
| 120 | const struct _olm_aes256_iv *iv, |
| 121 | uint8_t const * input, size_t input_length, |
| 122 | uint8_t * output |
| 123 | ); |
| 124 | |
| 125 | |
| 126 | /** Computes SHA-256 of the input. The output buffer must be a least |
| 127 | * SHA256_OUTPUT_LENGTH (32) bytes long. */ |
| 128 | OLM_EXPORT void _olm_crypto_sha256( |
| 129 | uint8_t const * input, size_t input_length, |
| 130 | uint8_t * output |
| 131 | ); |
| 132 | |
| 133 | /** HMAC: Keyed-Hashing for Message Authentication |
| 134 | * http://tools.ietf.org/html/rfc2104 |
| 135 | * Computes HMAC-SHA-256 of the input for the key. The output buffer must |
| 136 | * be at least SHA256_OUTPUT_LENGTH (32) bytes long. */ |
| 137 | OLM_EXPORT void _olm_crypto_hmac_sha256( |
| 138 | uint8_t const * key, size_t key_length, |
| 139 | uint8_t const * input, size_t input_length, |
| 140 | uint8_t * output |
| 141 | ); |
| 142 | |
| 143 | |
| 144 | /** HMAC-based Key Derivation Function (HKDF) |
| 145 | * https://tools.ietf.org/html/rfc5869 |
| 146 | * Derives key material from the input bytes. */ |
| 147 | OLM_EXPORT void _olm_crypto_hkdf_sha256( |
| 148 | uint8_t const * input, size_t input_length, |
| 149 | uint8_t const * info, size_t info_length, |
| 150 | uint8_t const * salt, size_t salt_length, |
| 151 | uint8_t * output, size_t output_length |
| 152 | ); |
| 153 | |
| 154 | |
| 155 | /** Generate a curve25519 key pair |
| 156 | * random_32_bytes should be CURVE25519_RANDOM_LENGTH (32) bytes long. |
| 157 | */ |
| 158 | OLM_EXPORT void _olm_crypto_curve25519_generate_key( |
| 159 | uint8_t const * random_32_bytes, |
| 160 | struct _olm_curve25519_key_pair *output |
| 161 | ); |
| 162 | |
| 163 | |
| 164 | /** Create a shared secret using our private key and their public key. |
| 165 | * The output buffer must be at least CURVE25519_SHARED_SECRET_LENGTH (32) bytes long. |
| 166 | */ |
| 167 | OLM_EXPORT void _olm_crypto_curve25519_shared_secret( |
| 168 | const struct _olm_curve25519_key_pair *our_key, |
| 169 | const struct _olm_curve25519_public_key *their_key, |
| 170 | uint8_t * output |
| 171 | ); |
| 172 | |
| 173 | /** Generate an ed25519 key pair |
| 174 | * random_32_bytes should be ED25519_RANDOM_LENGTH (32) bytes long. |
| 175 | */ |
| 176 | OLM_EXPORT void _olm_crypto_ed25519_generate_key( |
| 177 | uint8_t const * random_bytes, |
| 178 | struct _olm_ed25519_key_pair *output |
| 179 | ); |
| 180 | |
| 181 | /** Signs the message using our private key. |
| 182 | * |
| 183 | * The output buffer must be at least ED25519_SIGNATURE_LENGTH (64) bytes |
| 184 | * long. */ |
| 185 | OLM_EXPORT void _olm_crypto_ed25519_sign( |
| 186 | const struct _olm_ed25519_key_pair *our_key, |
| 187 | const uint8_t * message, size_t message_length, |
| 188 | uint8_t * output |
| 189 | ); |
| 190 | |
| 191 | /** Verify an ed25519 signature |
| 192 | * The signature input buffer must be ED25519_SIGNATURE_LENGTH (64) bytes long. |
| 193 | * Returns non-zero if the signature is valid. */ |
| 194 | OLM_EXPORT int _olm_crypto_ed25519_verify( |
| 195 | const struct _olm_ed25519_public_key *their_key, |
| 196 | const uint8_t * message, size_t message_length, |
| 197 | const uint8_t * signature |
| 198 | ); |
| 199 | |
| 200 | |
| 201 | |
| 202 | #ifdef __cplusplus |
| 203 | } // extern "C" |
| 204 | #endif |
| 205 | |
| 206 | #endif /* OLM_CRYPTO_H_ */ |
| 207 | |