1 /* SPDX-License-Identifier: GPL-3.0-or-later
2 * Copyright © 2016-2018 The TokTok team.
3 * Copyright © 2013 Tox project.
4 */
5
6 /*
7 * Functions for the core crypto.
8 *
9 * NOTE: This code has to be perfect. We don't mess around with encryption.
10 */
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14
15 #include "crypto_core.h"
16
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include "ccompat.h"
21
22 #ifndef VANILLA_NACL
23 /* We use libsodium by default. */
24 #include <sodium.h>
25 #else
26 #include <crypto_box.h>
27 #include <crypto_hash_sha256.h>
28 #include <crypto_hash_sha512.h>
29 #include <crypto_scalarmult_curve25519.h>
30 #include <crypto_verify_16.h>
31 #include <crypto_verify_32.h>
32 #include <randombytes.h>
33 #define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
34 #endif
35
36 //!TOKSTYLE-
37 static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES,
38 "CRYPTO_PUBLIC_KEY_SIZE should be equal to crypto_box_PUBLICKEYBYTES");
39 static_assert(CRYPTO_SECRET_KEY_SIZE == crypto_box_SECRETKEYBYTES,
40 "CRYPTO_SECRET_KEY_SIZE should be equal to crypto_box_SECRETKEYBYTES");
41 static_assert(CRYPTO_SHARED_KEY_SIZE == crypto_box_BEFORENMBYTES,
42 "CRYPTO_SHARED_KEY_SIZE should be equal to crypto_box_BEFORENMBYTES");
43 static_assert(CRYPTO_SYMMETRIC_KEY_SIZE == crypto_box_BEFORENMBYTES,
44 "CRYPTO_SYMMETRIC_KEY_SIZE should be equal to crypto_box_BEFORENMBYTES");
45 static_assert(CRYPTO_MAC_SIZE == crypto_box_MACBYTES,
46 "CRYPTO_MAC_SIZE should be equal to crypto_box_MACBYTES");
47 static_assert(CRYPTO_NONCE_SIZE == crypto_box_NONCEBYTES,
48 "CRYPTO_NONCE_SIZE should be equal to crypto_box_NONCEBYTES");
49 static_assert(CRYPTO_SHA256_SIZE == crypto_hash_sha256_BYTES,
50 "CRYPTO_SHA256_SIZE should be equal to crypto_hash_sha256_BYTES");
51 static_assert(CRYPTO_SHA512_SIZE == crypto_hash_sha512_BYTES,
52 "CRYPTO_SHA512_SIZE should be equal to crypto_hash_sha512_BYTES");
53 static_assert(CRYPTO_PUBLIC_KEY_SIZE == 32,
54 "CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_cmp to work");
55 //!TOKSTYLE+
56
crypto_malloc(size_t bytes)57 static uint8_t *crypto_malloc(size_t bytes)
58 {
59 return (uint8_t *)malloc(bytes);
60 }
61
crypto_free(uint8_t * ptr,size_t bytes)62 static void crypto_free(uint8_t *ptr, size_t bytes)
63 {
64 if (ptr != nullptr) {
65 crypto_memzero(ptr, bytes);
66 }
67
68 free(ptr);
69 }
70
public_key_cmp(const uint8_t * pk1,const uint8_t * pk2)71 int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2)
72 {
73 return crypto_verify_32(pk1, pk2);
74 }
75
random_u08(void)76 uint8_t random_u08(void)
77 {
78 uint8_t randnum;
79 random_bytes(&randnum, 1);
80 return randnum;
81 }
82
random_u16(void)83 uint16_t random_u16(void)
84 {
85 uint16_t randnum;
86 random_bytes((uint8_t *)&randnum, sizeof(randnum));
87 return randnum;
88 }
89
random_u32(void)90 uint32_t random_u32(void)
91 {
92 uint32_t randnum;
93 random_bytes((uint8_t *)&randnum, sizeof(randnum));
94 return randnum;
95 }
96
random_u64(void)97 uint64_t random_u64(void)
98 {
99 uint64_t randnum;
100 random_bytes((uint8_t *)&randnum, sizeof(randnum));
101 return randnum;
102 }
103
public_key_valid(const uint8_t * public_key)104 bool public_key_valid(const uint8_t *public_key)
105 {
106 if (public_key[31] >= 128) { /* Last bit of key is always zero. */
107 return 0;
108 }
109
110 return 1;
111 }
112
113 /* Precomputes the shared key from their public_key and our secret_key.
114 * This way we can avoid an expensive elliptic curve scalar multiply for each
115 * encrypt/decrypt operation.
116 * shared_key has to be crypto_box_BEFORENMBYTES bytes long.
117 */
encrypt_precompute(const uint8_t * public_key,const uint8_t * secret_key,uint8_t * shared_key)118 int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key,
119 uint8_t *shared_key)
120 {
121 return crypto_box_beforenm(shared_key, public_key, secret_key);
122 }
123
encrypt_data_symmetric(const uint8_t * secret_key,const uint8_t * nonce,const uint8_t * plain,size_t length,uint8_t * encrypted)124 int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
125 const uint8_t *plain, size_t length, uint8_t *encrypted)
126 {
127 if (length == 0 || !secret_key || !nonce || !plain || !encrypted) {
128 return -1;
129 }
130
131 const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
132 const size_t size_temp_encrypted = length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES;
133
134 uint8_t *temp_plain = crypto_malloc(size_temp_plain);
135 uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted);
136
137 if (temp_plain == nullptr || temp_encrypted == nullptr) {
138 crypto_free(temp_plain, size_temp_plain);
139 crypto_free(temp_encrypted, size_temp_encrypted);
140 return -1;
141 }
142
143 memset(temp_plain, 0, crypto_box_ZEROBYTES);
144 // Pad the message with 32 0 bytes.
145 memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length);
146
147 if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce,
148 secret_key) != 0) {
149 crypto_free(temp_plain, size_temp_plain);
150 crypto_free(temp_encrypted, size_temp_encrypted);
151 return -1;
152 }
153
154 // Unpad the encrypted message.
155 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
156
157 crypto_free(temp_plain, size_temp_plain);
158 crypto_free(temp_encrypted, size_temp_encrypted);
159
160 return length + crypto_box_MACBYTES;
161 }
162
decrypt_data_symmetric(const uint8_t * secret_key,const uint8_t * nonce,const uint8_t * encrypted,size_t length,uint8_t * plain)163 int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
164 const uint8_t *encrypted, size_t length, uint8_t *plain)
165 {
166 if (length <= crypto_box_BOXZEROBYTES || !secret_key || !nonce || !encrypted || !plain) {
167 return -1;
168 }
169
170 const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
171 const size_t size_temp_encrypted = length + crypto_box_BOXZEROBYTES;
172
173 uint8_t *temp_plain = crypto_malloc(size_temp_plain);
174 uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted);
175
176 if (temp_plain == nullptr || temp_encrypted == nullptr) {
177 crypto_free(temp_plain, size_temp_plain);
178 crypto_free(temp_encrypted, size_temp_encrypted);
179 return -1;
180 }
181
182 memset(temp_encrypted, 0, crypto_box_BOXZEROBYTES);
183 // Pad the message with 16 0 bytes.
184 memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length);
185
186 if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce,
187 secret_key) != 0) {
188 crypto_free(temp_plain, size_temp_plain);
189 crypto_free(temp_encrypted, size_temp_encrypted);
190 return -1;
191 }
192
193 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
194
195 crypto_free(temp_plain, size_temp_plain);
196 crypto_free(temp_encrypted, size_temp_encrypted);
197 return length - crypto_box_MACBYTES;
198 }
199
encrypt_data(const uint8_t * public_key,const uint8_t * secret_key,const uint8_t * nonce,const uint8_t * plain,size_t length,uint8_t * encrypted)200 int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
201 const uint8_t *plain, size_t length, uint8_t *encrypted)
202 {
203 if (!public_key || !secret_key) {
204 return -1;
205 }
206
207 uint8_t k[crypto_box_BEFORENMBYTES];
208 encrypt_precompute(public_key, secret_key, k);
209 int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted);
210 crypto_memzero(k, sizeof(k));
211 return ret;
212 }
213
decrypt_data(const uint8_t * public_key,const uint8_t * secret_key,const uint8_t * nonce,const uint8_t * encrypted,size_t length,uint8_t * plain)214 int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
215 const uint8_t *encrypted, size_t length, uint8_t *plain)
216 {
217 if (!public_key || !secret_key) {
218 return -1;
219 }
220
221 uint8_t k[crypto_box_BEFORENMBYTES];
222 encrypt_precompute(public_key, secret_key, k);
223 int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain);
224 crypto_memzero(k, sizeof(k));
225 return ret;
226 }
227
228 /* Increment the given nonce by 1. */
increment_nonce(uint8_t * nonce)229 void increment_nonce(uint8_t *nonce)
230 {
231 /* TODO(irungentoo): use `increment_nonce_number(nonce, 1)` or
232 * sodium_increment (change to little endian).
233 *
234 * NOTE don't use breaks inside this loop.
235 * In particular, make sure, as far as possible,
236 * that loop bounds and their potential underflow or overflow
237 * are independent of user-controlled input (you may have heard of the Heartbleed bug).
238 */
239 uint32_t i = crypto_box_NONCEBYTES;
240 uint_fast16_t carry = 1U;
241
242 for (; i != 0; --i) {
243 carry += (uint_fast16_t)nonce[i - 1];
244 nonce[i - 1] = (uint8_t)carry;
245 carry >>= 8;
246 }
247 }
248
host_to_network(uint32_t x)249 static uint32_t host_to_network(uint32_t x)
250 {
251 #if !defined(BYTE_ORDER) || BYTE_ORDER == LITTLE_ENDIAN
252 return ((x >> 24) & 0x000000FF) | // move byte 3 to byte 0
253 ((x >> 8) & 0x0000FF00) | // move byte 2 to byte 1
254 ((x << 8) & 0x00FF0000) | // move byte 1 to byte 2
255 ((x << 24) & 0xFF000000); // move byte 0 to byte 3
256 #else
257 return x;
258 #endif
259 }
260
261 /* increment the given nonce by num */
increment_nonce_number(uint8_t * nonce,uint32_t host_order_num)262 void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num)
263 {
264 /* NOTE don't use breaks inside this loop
265 * In particular, make sure, as far as possible,
266 * that loop bounds and their potential underflow or overflow
267 * are independent of user-controlled input (you may have heard of the Heartbleed bug).
268 */
269 const uint32_t big_endian_num = host_to_network(host_order_num);
270 const uint8_t *const num_vec = (const uint8_t *)&big_endian_num;
271 uint8_t num_as_nonce[crypto_box_NONCEBYTES] = {0};
272 num_as_nonce[crypto_box_NONCEBYTES - 4] = num_vec[0];
273 num_as_nonce[crypto_box_NONCEBYTES - 3] = num_vec[1];
274 num_as_nonce[crypto_box_NONCEBYTES - 2] = num_vec[2];
275 num_as_nonce[crypto_box_NONCEBYTES - 1] = num_vec[3];
276
277 uint32_t i = crypto_box_NONCEBYTES;
278 uint_fast16_t carry = 0U;
279
280 for (; i != 0; --i) {
281 carry += (uint_fast16_t)nonce[i - 1] + (uint_fast16_t)num_as_nonce[i - 1];
282 nonce[i - 1] = (uint8_t)carry;
283 carry >>= 8;
284 }
285 }
286
287 /* Fill the given nonce with random bytes. */
random_nonce(uint8_t * nonce)288 void random_nonce(uint8_t *nonce)
289 {
290 random_bytes(nonce, crypto_box_NONCEBYTES);
291 }
292
293 /* Fill a key CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes */
new_symmetric_key(uint8_t * key)294 void new_symmetric_key(uint8_t *key)
295 {
296 random_bytes(key, CRYPTO_SYMMETRIC_KEY_SIZE);
297 }
298
crypto_new_keypair(uint8_t * public_key,uint8_t * secret_key)299 int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key)
300 {
301 return crypto_box_keypair(public_key, secret_key);
302 }
303
crypto_derive_public_key(uint8_t * public_key,const uint8_t * secret_key)304 void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key)
305 {
306 crypto_scalarmult_curve25519_base(public_key, secret_key);
307 }
308
crypto_sha256(uint8_t * hash,const uint8_t * data,size_t length)309 void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length)
310 {
311 crypto_hash_sha256(hash, data, length);
312 }
313
crypto_sha512(uint8_t * hash,const uint8_t * data,size_t length)314 void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length)
315 {
316 crypto_hash_sha512(hash, data, length);
317 }
318
random_bytes(uint8_t * data,size_t length)319 void random_bytes(uint8_t *data, size_t length)
320 {
321 randombytes(data, length);
322 }
323