diff options
author | irungentoo <irungentoo@gmail.com> | 2014-04-21 16:51:36 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2014-04-21 16:51:36 -0400 |
commit | 9c6a8432ce7298766669d1e6a966b5493971afb7 (patch) | |
tree | 8fd98c412610cbcf3fa8b7c28e0a5efbe02bad77 /toxcore/crypto_core.c | |
parent | 1603ca974eae3fe0d94b597103f04acfb96fcab0 (diff) |
Crypto related cleanups.
Moved Bunch of functions from net_crypto to crypto_core.
decrypt_data_fast and decrypt_data_symmetric were the same thing
therefore, removed decrypt_data_fast.
Replaced all the crypto_secretbox_* defines with the equivalent
crypto_box_* one.
New define: crypto_box_KEYBYTES that is equal to
crypto_box_BEFORENMBYTES.
Diffstat (limited to 'toxcore/crypto_core.c')
-rw-r--r-- | toxcore/crypto_core.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c new file mode 100644 index 00000000..38048076 --- /dev/null +++ b/toxcore/crypto_core.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* net_crypto.c | ||
2 | * | ||
3 | * Functions for the core crypto. | ||
4 | * | ||
5 | * NOTE: This code has to be perfect. We don't mess around with encryption. | ||
6 | * | ||
7 | * Copyright (C) 2013 Tox project All Rights Reserved. | ||
8 | * | ||
9 | * This file is part of Tox. | ||
10 | * | ||
11 | * Tox is free software: you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation, either version 3 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * Tox is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #ifdef HAVE_CONFIG_H | ||
27 | #include "config.h" | ||
28 | #endif | ||
29 | |||
30 | #include "crypto_core.h" | ||
31 | |||
32 | /* Use this instead of memcmp; not vulnerable to timing attacks. */ | ||
33 | uint8_t crypto_iszero(uint8_t *mem, uint32_t length) | ||
34 | { | ||
35 | uint8_t check = 0; | ||
36 | uint32_t i; | ||
37 | |||
38 | for (i = 0; i < length; ++i) { | ||
39 | check |= mem[i]; | ||
40 | } | ||
41 | |||
42 | return check; // We return zero if mem is made out of zeroes. | ||
43 | } | ||
44 | |||
45 | /* Precomputes the shared key from their public_key and our secret_key. | ||
46 | * This way we can avoid an expensive elliptic curve scalar multiply for each | ||
47 | * encrypt/decrypt operation. | ||
48 | * enc_key has to be crypto_box_BEFORENMBYTES bytes long. | ||
49 | */ | ||
50 | void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key) | ||
51 | { | ||
52 | crypto_box_beforenm(enc_key, public_key, secret_key); | ||
53 | } | ||
54 | |||
55 | int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted) | ||
56 | { | ||
57 | if (length == 0) | ||
58 | return -1; | ||
59 | |||
60 | uint8_t temp_plain[length + crypto_box_ZEROBYTES]; | ||
61 | uint8_t temp_encrypted[length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES]; | ||
62 | |||
63 | memset(temp_plain, 0, crypto_box_ZEROBYTES); | ||
64 | memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes. | ||
65 | |||
66 | if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, secret_key) != 0) | ||
67 | return -1; | ||
68 | /* Unpad the encrypted message. */ | ||
69 | memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); | ||
70 | return length + crypto_box_MACBYTES; | ||
71 | } | ||
72 | |||
73 | int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain) | ||
74 | { | ||
75 | if (length <= crypto_box_BOXZEROBYTES) | ||
76 | return -1; | ||
77 | |||
78 | uint8_t temp_plain[length + crypto_box_ZEROBYTES]; | ||
79 | uint8_t temp_encrypted[length + crypto_box_BOXZEROBYTES]; | ||
80 | |||
81 | memset(temp_plain, 0, crypto_box_BOXZEROBYTES); | ||
82 | memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes. | ||
83 | |||
84 | if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce, secret_key) != 0) | ||
85 | return -1; | ||
86 | |||
87 | memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES); | ||
88 | return length - crypto_box_MACBYTES; | ||
89 | } | ||
90 | |||
91 | int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | ||
92 | uint8_t *plain, uint32_t length, uint8_t *encrypted) | ||
93 | { | ||
94 | uint8_t k[crypto_box_BEFORENMBYTES]; | ||
95 | encrypt_precompute(public_key, secret_key, k); | ||
96 | return encrypt_data_symmetric(k, nonce, plain, length, encrypted); | ||
97 | } | ||
98 | |||
99 | int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | ||
100 | uint8_t *encrypted, uint32_t length, uint8_t *plain) | ||
101 | { | ||
102 | uint8_t k[crypto_box_BEFORENMBYTES]; | ||
103 | encrypt_precompute(public_key, secret_key, k); | ||
104 | return decrypt_data_symmetric(k, nonce, encrypted, length, plain); | ||
105 | } | ||
106 | |||
107 | |||
108 | /* Increment the given nonce by 1. */ | ||
109 | void increment_nonce(uint8_t *nonce) | ||
110 | { | ||
111 | uint32_t i; | ||
112 | |||
113 | for (i = crypto_box_NONCEBYTES; i != 0; --i) { | ||
114 | ++nonce[i - 1]; | ||
115 | |||
116 | if (nonce[i - 1] != 0) | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | /* increment the given nonce by num */ | ||
121 | void increment_nonce_number(uint8_t *nonce, uint32_t num) | ||
122 | { | ||
123 | uint32_t num1, num2; | ||
124 | memcpy(&num1, nonce + (crypto_box_NONCEBYTES - sizeof(num1)), sizeof(num1)); | ||
125 | num1 = ntohl(num1); | ||
126 | num2 = num + num1; | ||
127 | |||
128 | if (num2 < num1) { | ||
129 | uint32_t i; | ||
130 | |||
131 | for (i = crypto_box_NONCEBYTES - sizeof(num1); i != 0; --i) { | ||
132 | ++nonce[i - 1]; | ||
133 | |||
134 | if (nonce[i - 1] != 0) | ||
135 | break; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | num2 = htonl(num2); | ||
140 | memcpy(nonce + (crypto_box_NONCEBYTES - sizeof(num2)), &num2, sizeof(num2)); | ||
141 | } | ||
142 | |||
143 | /* Fill the given nonce with random bytes. */ | ||
144 | void random_nonce(uint8_t *nonce) | ||
145 | { | ||
146 | randombytes(nonce, crypto_box_NONCEBYTES); | ||
147 | } | ||
148 | |||
149 | /* Fill a key crypto_box_KEYBYTES big with random bytes */ | ||
150 | void new_symmetric_key(uint8_t *key) | ||
151 | { | ||
152 | randombytes(key, crypto_box_KEYBYTES); | ||
153 | } | ||
154 | |||
155 | static uint8_t base_nonce[crypto_box_NONCEBYTES]; | ||
156 | static uint8_t nonce_set = 0; | ||
157 | |||
158 | /* Gives a nonce guaranteed to be different from previous ones.*/ | ||
159 | void new_nonce(uint8_t *nonce) | ||
160 | { | ||
161 | if (nonce_set == 0) { | ||
162 | random_nonce(base_nonce); | ||
163 | nonce_set = 1; | ||
164 | } | ||
165 | |||
166 | increment_nonce(base_nonce); | ||
167 | memcpy(nonce, base_nonce, crypto_box_NONCEBYTES); | ||
168 | } \ No newline at end of file | ||