diff options
-rw-r--r-- | auto_tests/crypto_test.c | 38 | ||||
-rw-r--r-- | core/net_crypto.c | 72 |
2 files changed, 54 insertions, 56 deletions
diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 9ac81349..8b5397e4 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c | |||
@@ -197,6 +197,43 @@ START_TEST(test_endtoend) | |||
197 | } | 197 | } |
198 | END_TEST | 198 | END_TEST |
199 | 199 | ||
200 | START_TEST(test_large_data) | ||
201 | { | ||
202 | unsigned char k[crypto_box_BEFORENMBYTES]; | ||
203 | |||
204 | unsigned char n[crypto_box_NONCEBYTES]; | ||
205 | |||
206 | unsigned char m1[MAX_DATA_SIZE - ENCRYPTION_PADDING]; | ||
207 | unsigned char c1[sizeof(m1) + ENCRYPTION_PADDING]; | ||
208 | unsigned char m1prime[sizeof(m1)]; | ||
209 | |||
210 | unsigned char m2[MAX_DATA_SIZE]; | ||
211 | unsigned char c2[sizeof(m2) + ENCRYPTION_PADDING]; | ||
212 | |||
213 | int c1len, c2len; | ||
214 | int m1plen; | ||
215 | |||
216 | //Generate random messages | ||
217 | rand_bytes(m1, sizeof(m1)); | ||
218 | rand_bytes(m2, sizeof(m2)); | ||
219 | rand_bytes(n, crypto_box_NONCEBYTES); | ||
220 | |||
221 | //Generate key | ||
222 | rand_bytes(k, crypto_box_BEFORENMBYTES); | ||
223 | |||
224 | c1len = encrypt_data_fast(k, n, m1, sizeof(m1), c1); | ||
225 | c2len = encrypt_data_fast(k, n, m2, sizeof(m2), c2); | ||
226 | |||
227 | ck_assert_msg(c1len == sizeof(m1) + ENCRYPTION_PADDING, "Could not encrypt max size"); | ||
228 | ck_assert_msg(c2len == -1, "incorrectly succeeded encrypting massive size"); | ||
229 | |||
230 | m1plen = decrypt_data_fast(k, n, c1, c1len, m1prime); | ||
231 | |||
232 | ck_assert_msg(m1plen == sizeof(m1), "decrypted text lengths differ"); | ||
233 | ck_assert_msg(memcmp(m1prime, m1, sizeof(m1)) == 0, "decrypted texts differ"); | ||
234 | } | ||
235 | END_TEST | ||
236 | |||
200 | #define DEFTESTCASE(NAME) \ | 237 | #define DEFTESTCASE(NAME) \ |
201 | TCase *NAME = tcase_create(#NAME); \ | 238 | TCase *NAME = tcase_create(#NAME); \ |
202 | tcase_add_test(NAME, test_##NAME); \ | 239 | tcase_add_test(NAME, test_##NAME); \ |
@@ -209,6 +246,7 @@ Suite* crypto_suite(void) | |||
209 | DEFTESTCASE(known); | 246 | DEFTESTCASE(known); |
210 | DEFTESTCASE(fast_known); | 247 | DEFTESTCASE(fast_known); |
211 | DEFTESTCASE(endtoend); | 248 | DEFTESTCASE(endtoend); |
249 | DEFTESTCASE(large_data); | ||
212 | 250 | ||
213 | return s; | 251 | return s; |
214 | } | 252 | } |
diff --git a/core/net_crypto.c b/core/net_crypto.c index fd606335..ab18dd63 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -71,33 +71,6 @@ uint8_t crypto_iszero(uint8_t *mem, uint32_t length) | |||
71 | return check; // We return zero if mem is made out of zeroes. | 71 | return check; // We return zero if mem is made out of zeroes. |
72 | } | 72 | } |
73 | 73 | ||
74 | /* encrypts plain of length length to encrypted of length + 16 using the | ||
75 | public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce | ||
76 | return -1 if there was a problem. | ||
77 | return length of encrypted data if everything was fine. */ | ||
78 | int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | ||
79 | uint8_t *plain, uint32_t length, uint8_t *encrypted) | ||
80 | { | ||
81 | if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0) | ||
82 | return -1; | ||
83 | |||
84 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; | ||
85 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES]; | ||
86 | |||
87 | memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */ | ||
88 | |||
89 | crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key); | ||
90 | |||
91 | /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero | ||
92 | apparently memcmp should not be used so we do this instead:*/ | ||
93 | if(crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0) | ||
94 | return -1; | ||
95 | |||
96 | /* unpad the encrypted message */ | ||
97 | memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); | ||
98 | return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; | ||
99 | } | ||
100 | |||
101 | /* Precomputes the shared key from their public_key and our secret_key. | 74 | /* Precomputes the shared key from their public_key and our secret_key. |
102 | This way we can avoid an expensive elliptic curve scalar multiply for each | 75 | This way we can avoid an expensive elliptic curve scalar multiply for each |
103 | encrypt/decrypt operation. | 76 | encrypt/decrypt operation. |
@@ -129,35 +102,6 @@ int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, | |||
129 | return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; | 102 | return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; |
130 | } | 103 | } |
131 | 104 | ||
132 | /* decrypts encrypted of length length to plain of length length - 16 using the | ||
133 | public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce | ||
134 | return -1 if there was a problem(decryption failed) | ||
135 | return length of plain data if everything was fine. */ | ||
136 | int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | ||
137 | uint8_t *encrypted, uint32_t length, uint8_t *plain) | ||
138 | { | ||
139 | if (length > MAX_DATA_SIZE || length <= crypto_box_BOXZEROBYTES) | ||
140 | return -1; | ||
141 | |||
142 | uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; | ||
143 | uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES] = {0}; | ||
144 | |||
145 | memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); /* pad the message with 16 0 bytes. */ | ||
146 | |||
147 | if (crypto_box_open(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, | ||
148 | nonce, public_key, secret_key) == -1) | ||
149 | return -1; | ||
150 | |||
151 | /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero | ||
152 | apparently memcmp should not be used so we do this instead:*/ | ||
153 | if(crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0) | ||
154 | return -1; | ||
155 | |||
156 | /* unpad the plain message */ | ||
157 | memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES); | ||
158 | return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES; | ||
159 | } | ||
160 | |||
161 | /* Fast decrypt. Depends on enc_ley from encrypt_precompute. */ | 105 | /* Fast decrypt. Depends on enc_ley from encrypt_precompute. */ |
162 | int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, | 106 | int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, |
163 | uint8_t *encrypted, uint32_t length, uint8_t *plain) | 107 | uint8_t *encrypted, uint32_t length, uint8_t *plain) |
@@ -184,6 +128,22 @@ int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, | |||
184 | return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES; | 128 | return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES; |
185 | } | 129 | } |
186 | 130 | ||
131 | int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | ||
132 | uint8_t *plain, uint32_t length, uint8_t *encrypted) | ||
133 | { | ||
134 | uint8_t k[crypto_box_BEFORENMBYTES]; | ||
135 | encrypt_precompute(public_key, secret_key, k); | ||
136 | return encrypt_data_fast(k, nonce, plain, length, encrypted); | ||
137 | } | ||
138 | |||
139 | int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, | ||
140 | uint8_t *encrypted, uint32_t length, uint8_t *plain) | ||
141 | { | ||
142 | uint8_t k[crypto_box_BEFORENMBYTES]; | ||
143 | encrypt_precompute(public_key, secret_key, k); | ||
144 | return decrypt_data_fast(k, nonce, encrypted, length, plain); | ||
145 | } | ||
146 | |||
187 | /* increment the given nonce by 1 */ | 147 | /* increment the given nonce by 1 */ |
188 | static void increment_nonce(uint8_t *nonce) | 148 | static void increment_nonce(uint8_t *nonce) |
189 | { | 149 | { |