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 | |