1 /**
2 * (C) 2007-20 - ntop.org and contributors
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not see see <http://www.gnu.org/licenses/>
16 *
17 */
18
19 #include "n2n.h"
20
21 #ifdef N2N_HAVE_AES
22
23 #include <openssl/aes.h>
24 #include <openssl/sha.h>
25 #include <openssl/evp.h>
26 #include <openssl/err.h>
27
28 #define N2N_AES_TRANSFORM_VERSION 1 /* version of the transform encoding */
29 #define N2N_AES_IVEC_SIZE (AES_BLOCK_SIZE)
30
31 #define AES256_KEY_BYTES (256/8)
32 #define AES192_KEY_BYTES (192/8)
33 #define AES128_KEY_BYTES (128/8)
34
35 /* AES plaintext preamble */
36 #define TRANSOP_AES_VER_SIZE 1 /* Support minor variants in encoding in one module. */
37 #define TRANSOP_AES_IV_SEED_SIZE 8 /* size of transmitted random part of IV in bytes; could range
38 * from 0=lowest security (constant IV) to 16=higest security
39 * (fully random IV); default=8 */
40 #define TRANSOP_AES_IV_PADDING_SIZE (N2N_AES_IVEC_SIZE - TRANSOP_AES_IV_SEED_SIZE)
41 #define TRANSOP_AES_IV_KEY_BYTES (AES128_KEY_BYTES) /* use AES128 for IV encryption */
42 #define TRANSOP_AES_PREAMBLE_SIZE (TRANSOP_AES_VER_SIZE + TRANSOP_AES_IV_SEED_SIZE)
43
44 typedef unsigned char n2n_aes_ivec_t[N2N_AES_IVEC_SIZE];
45
46 typedef struct transop_aes {
47 #ifdef HAVE_OPENSSL_1_1
48 EVP_CIPHER_CTX *enc_ctx; /* openssl's reusable evp_* encryption context */
49 EVP_CIPHER_CTX *dec_ctx; /* openssl's reusable evp_* decryption context */
50 const EVP_CIPHER *cipher; /* cipher to use: e.g. EVP_aes_128_cbc */
51 uint8_t key[32]; /* the pure key data for payload encryption & decryption */
52 #else
53 AES_KEY enc_key; /* tx key */
54 AES_KEY dec_key; /* tx key */
55 #endif
56 AES_KEY iv_enc_key; /* key used to encrypt the IV */
57 uint8_t iv_pad_val[TRANSOP_AES_IV_PADDING_SIZE]; /* key used to pad the random IV seed to full block size */
58 } transop_aes_t;
59
60 /* ****************************************************** */
61
transop_deinit_aes(n2n_trans_op_t * arg)62 static int transop_deinit_aes(n2n_trans_op_t *arg) {
63 transop_aes_t *priv = (transop_aes_t *)arg->priv;
64
65 #ifdef HAVE_OPENSSL_1_1
66 EVP_CIPHER_CTX_free(priv->enc_ctx);
67 EVP_CIPHER_CTX_free(priv->dec_ctx);
68 #endif
69
70 if(priv)
71 free(priv);
72
73 return 0;
74 }
75
76 /* ****************************************************** */
77
78 #ifdef HAVE_OPENSSL_1_1
79 /* get any erorr message out of openssl
80 taken from https://en.wikibooks.org/wiki/OpenSSL/Error_handling */
openssl_err_as_string(void)81 static char *openssl_err_as_string (void) {
82 BIO *bio = BIO_new (BIO_s_mem ());
83 ERR_print_errors (bio);
84 char *buf = NULL;
85 size_t len = BIO_get_mem_data (bio, &buf);
86 char *ret = (char *) calloc (1, 1 + len);
87
88 if(ret)
89 memcpy (ret, buf, len);
90
91 BIO_free (bio);
92 return ret;
93 }
94 #endif
95
96 /* ****************************************************** */
97
98 /* convert a given number of bytes from memory to hex string; taken (and modified) from
99 https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c */
to_hex(unsigned char * in,size_t insz,char * out,size_t outsz)100 const char* to_hex(unsigned char * in, size_t insz, char * out, size_t outsz)
101 {
102 unsigned char * pin = in;
103 const char * hex = "0123456789abcdef";
104 char * pout = out;
105 for(; pin < in+insz; pout +=2, pin++){
106 pout[0] = hex[(*pin>>4) & 0xF];
107 pout[1] = hex[ *pin & 0xF];
108 if (pout + 2 - out > outsz){
109 /* Better to truncate output string than overflow buffer */
110 /* it would be still better to either return a status */
111 /* or ensure the target buffer is large enough and it never happen */
112 break;
113 }
114 }
115 pout[2] = 0;
116 return out;
117 }
118
119 /* ****************************************************** */
120
set_aes_cbc_iv(transop_aes_t * priv,n2n_aes_ivec_t ivec,uint8_t * iv_seed)121 static void set_aes_cbc_iv(transop_aes_t *priv, n2n_aes_ivec_t ivec, uint8_t * iv_seed) {
122 uint8_t iv_full[N2N_AES_IVEC_SIZE];
123
124 /* Extend the seed to full block size with padding value */
125 memcpy(iv_full, priv->iv_pad_val, TRANSOP_AES_IV_PADDING_SIZE);
126 memcpy(iv_full + TRANSOP_AES_IV_PADDING_SIZE, iv_seed, TRANSOP_AES_IV_SEED_SIZE);
127
128 /* Encrypt the IV with secret key to make it unpredictable.
129 * As discussed in https://github.com/ntop/n2n/issues/72, it's important to
130 * have an unpredictable IV since the initial part of the packet plaintext
131 * can be easily reconstructed from plaintext headers and used by an attacker
132 * to perform differential analysis.
133 */
134 AES_ecb_encrypt(iv_full, ivec, &priv->iv_enc_key, AES_ENCRYPT);
135 }
136
137 /* ****************************************************** */
138
139 /** The aes packet format consists of:
140 *
141 * - a 8-bit aes encoding version in clear text
142 * - a TRANSOP_AES_IV_SEED_SIZE-sized [bytes] random IV seed
143 * - encrypted payload.
144 *
145 * [V|II|DDDDDDDDDDDDDDDDDDDDD]
146 * |<---- encrypted ---->|
147 */
transop_encode_aes(n2n_trans_op_t * arg,uint8_t * outbuf,size_t out_len,const uint8_t * inbuf,size_t in_len,const uint8_t * peer_mac)148 static int transop_encode_aes(n2n_trans_op_t * arg,
149 uint8_t * outbuf,
150 size_t out_len,
151 const uint8_t * inbuf,
152 size_t in_len,
153 const uint8_t * peer_mac) {
154 int len2=-1;
155 transop_aes_t * priv = (transop_aes_t *)arg->priv;
156 uint8_t assembly[N2N_PKT_BUF_SIZE] = {0};
157
158 if(in_len <= N2N_PKT_BUF_SIZE) {
159 if((in_len + TRANSOP_AES_PREAMBLE_SIZE) <= out_len) {
160 int len=-1;
161 size_t idx=0;
162 uint8_t iv_seed[TRANSOP_AES_IV_SEED_SIZE];
163 uint8_t padding = 0;
164 n2n_aes_ivec_t enc_ivec = {0};
165
166 traceEvent(TRACE_DEBUG, "encode_aes %lu", in_len);
167
168 /* Encode the aes format version. */
169 encode_uint8(outbuf, &idx, N2N_AES_TRANSFORM_VERSION);
170
171 /* Generate and encode the IV seed using as many calls to n2n_rand() as neccessary.
172 * Note: ( N2N_AES_IV_SEED_SIZE % sizeof(rand_value) ) not neccessarily equals 0. */
173 uint64_t rand_value;
174 int8_t i;
175 for (i = TRANSOP_AES_IV_SEED_SIZE; i >= sizeof(rand_value); i -= sizeof(rand_value)) {
176 rand_value = n2n_rand();
177 memcpy(iv_seed + TRANSOP_AES_IV_SEED_SIZE - i, &rand_value, sizeof(rand_value));
178 }
179 /* Are there bytes left to fill? */
180 if (i != 0) {
181 rand_value = n2n_rand();
182 memcpy(iv_seed, &rand_value, i);
183 }
184 encode_buf(outbuf, &idx, iv_seed, TRANSOP_AES_IV_SEED_SIZE);
185
186 /* Encrypt the assembly contents and write the ciphertext after the iv seed. */
187 /* len is set to the length of the cipher plain text to be encrpyted
188 which is (in this case) identical to original packet lentgh */
189 len = in_len;
190
191 /* The assembly buffer is a source for encrypting data.
192 * The whole contents of assembly are encrypted. */
193 memcpy(assembly, inbuf, in_len);
194
195 /* Need at least one encrypted byte at the end for the padding. */
196 len2 = ((len / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE; /* Round up to next whole AES adding at least one byte. */
197 padding = (len2-len);
198 assembly[len2 - 1] = padding;
199
200 char iv_seed_hex[2 * N2N_AES_IVEC_SIZE + 1];
201 traceEvent(TRACE_DEBUG, "padding = %u, seed = 0x%s", padding, to_hex (iv_seed, TRANSOP_AES_IV_SEED_SIZE, iv_seed_hex, 2 * N2N_AES_IVEC_SIZE + 1) );
202
203 set_aes_cbc_iv(priv, enc_ivec, iv_seed);
204
205 #ifdef HAVE_OPENSSL_1_1
206 EVP_CIPHER_CTX *ctx = priv->enc_ctx;
207 int evp_len;
208 int evp_ciphertext_len;
209
210 if(1 == EVP_EncryptInit_ex(ctx, priv->cipher, NULL, priv->key, enc_ivec)) {
211 if(1 == EVP_CIPHER_CTX_set_padding(ctx, 0)) {
212 if(1 == EVP_EncryptUpdate(ctx, outbuf + TRANSOP_AES_PREAMBLE_SIZE, &evp_len, assembly, len2)) {
213 evp_ciphertext_len = evp_len;
214 if(1 == EVP_EncryptFinal_ex(ctx, outbuf + TRANSOP_AES_PREAMBLE_SIZE + evp_len, &evp_len)) {
215 evp_ciphertext_len += evp_len;
216
217 if(evp_ciphertext_len != len2)
218 traceEvent(TRACE_ERROR, "encode_aes openssl encryption: encrypted %u bytes where %u were expected.\n",
219 evp_ciphertext_len, len2);
220 } else
221 traceEvent(TRACE_ERROR, "encode_aes openssl final encryption: %s\n", openssl_err_as_string());
222 } else
223 traceEvent(TRACE_ERROR, "encode_aes openssl encrpytion: %s\n", openssl_err_as_string());
224 } else
225 traceEvent(TRACE_ERROR, "encode_aes openssl padding setup: %s\n", openssl_err_as_string());
226 } else
227 traceEvent(TRACE_ERROR, "encode_aes openssl init: %s\n", openssl_err_as_string());
228
229 EVP_CIPHER_CTX_reset(ctx);
230 #else
231 AES_cbc_encrypt(assembly, /* source */
232 outbuf + TRANSOP_AES_PREAMBLE_SIZE, /* dest */
233 len2, /* enc size */
234 &(priv->enc_key), enc_ivec, AES_ENCRYPT);
235 #endif
236
237 len2 += TRANSOP_AES_PREAMBLE_SIZE; /* size of data carried in UDP. */
238 } else
239 traceEvent(TRACE_ERROR, "encode_aes outbuf too small.");
240 } else
241 traceEvent(TRACE_ERROR, "encode_aes inbuf too big to encrypt.");
242
243 return len2;
244 }
245
246 /* ****************************************************** */
247
248 /* See transop_encode_aes for packet format */
transop_decode_aes(n2n_trans_op_t * arg,uint8_t * outbuf,size_t out_len,const uint8_t * inbuf,size_t in_len,const uint8_t * peer_mac)249 static int transop_decode_aes(n2n_trans_op_t * arg,
250 uint8_t * outbuf,
251 size_t out_len,
252 const uint8_t * inbuf,
253 size_t in_len,
254 const uint8_t * peer_mac) {
255 int len=0;
256 transop_aes_t * priv = (transop_aes_t *)arg->priv;
257 uint8_t assembly[N2N_PKT_BUF_SIZE];
258
259 if(((in_len - TRANSOP_AES_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* Cipher text fits in assembly */
260 && (in_len >= TRANSOP_AES_PREAMBLE_SIZE) /* Has at least version, iv seed */
261 )
262 {
263 size_t rem=in_len;
264 size_t idx=0;
265 uint8_t aes_enc_ver=0;
266 uint8_t iv_seed[TRANSOP_AES_IV_SEED_SIZE];
267
268 /* Get the encoding version to make sure it is supported */
269 decode_uint8(&aes_enc_ver, inbuf, &rem, &idx );
270
271 if(N2N_AES_TRANSFORM_VERSION == aes_enc_ver) {
272 /* Get the IV seed */
273 decode_buf((uint8_t *)&iv_seed, TRANSOP_AES_IV_SEED_SIZE, inbuf, &rem, &idx);
274
275 char iv_seed_hex[2 * N2N_AES_IVEC_SIZE + 1];
276 traceEvent(TRACE_DEBUG, "decode_aes %lu with seed 0x%s", in_len, to_hex (iv_seed, TRANSOP_AES_IV_SEED_SIZE, iv_seed_hex, 2 * N2N_AES_IVEC_SIZE + 1) );
277
278 len = (in_len - TRANSOP_AES_PREAMBLE_SIZE);
279
280 if(0 == (len % AES_BLOCK_SIZE)) {
281 uint8_t padding;
282 n2n_aes_ivec_t dec_ivec = {0};
283
284 set_aes_cbc_iv(priv, dec_ivec, iv_seed);
285
286 #ifdef HAVE_OPENSSL_1_1
287 EVP_CIPHER_CTX *ctx = priv->dec_ctx;
288 int evp_len;
289 int evp_plaintext_len;
290
291 if(1 == EVP_DecryptInit_ex(ctx, priv->cipher, NULL, priv->key, dec_ivec)) {
292 if(1 == EVP_CIPHER_CTX_set_padding(ctx, 0)) {
293 if(1 == EVP_DecryptUpdate(ctx, assembly, &evp_len, inbuf + TRANSOP_AES_PREAMBLE_SIZE, len)) {
294 evp_plaintext_len = evp_len;
295 if(1 == EVP_DecryptFinal_ex(ctx, assembly + evp_len, &evp_len)) {
296 evp_plaintext_len += evp_len;
297
298 if(evp_plaintext_len != len)
299 traceEvent(TRACE_ERROR, "decode_aes openssl decryption: decrypted %u bytes where %u were expected.\n",
300 evp_plaintext_len, len);
301 } else
302 traceEvent(TRACE_ERROR, "decode_aes openssl final decryption: %s\n", openssl_err_as_string());
303 } else
304 traceEvent(TRACE_ERROR, "decode_aes openssl decrpytion: %s\n", openssl_err_as_string());
305 } else
306 traceEvent(TRACE_ERROR, "decode_aes openssl padding setup: %s\n", openssl_err_as_string());
307
308 } else
309 traceEvent(TRACE_ERROR, "decode_aes openssl init: %s\n", openssl_err_as_string());
310
311 EVP_CIPHER_CTX_reset(ctx);
312 #else
313 AES_cbc_encrypt((inbuf + TRANSOP_AES_PREAMBLE_SIZE),
314 assembly, /* destination */
315 len,
316 &(priv->dec_key),
317 dec_ivec, AES_DECRYPT);
318 #endif
319 /* last byte is how much was padding: max value should be
320 * AES_BLOCKSIZE-1 */
321 padding = assembly[ len-1 ] & 0xff;
322
323 if(len >= padding) {
324 /* strictly speaking for this to be an ethernet packet
325 * it is going to need to be even bigger; but this is
326 * enough to prevent segfaults. */
327 traceEvent(TRACE_DEBUG, "padding = %u", padding);
328 len -= padding;
329
330 memcpy(outbuf,
331 assembly,
332 len);
333 } else
334 traceEvent(TRACE_WARNING, "UDP payload decryption failed.");
335 } else {
336 traceEvent(TRACE_WARNING, "Encrypted length %d is not a multiple of AES_BLOCK_SIZE (%d)", len, AES_BLOCK_SIZE);
337 len = 0;
338 }
339 } else
340 traceEvent(TRACE_ERROR, "decode_aes unsupported aes version %u.", aes_enc_ver);
341 } else
342 traceEvent(TRACE_ERROR, "decode_aes inbuf wrong size (%ul) to decrypt.", in_len);
343
344 return len;
345 }
346
347 /* ****************************************************** */
348
setup_aes_key(transop_aes_t * priv,const uint8_t * key,ssize_t key_size)349 static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_size) {
350 size_t aes_key_size_bytes;
351 size_t aes_key_size_bits;
352
353 uint8_t key_mat_buf[SHA512_DIGEST_LENGTH + SHA256_DIGEST_LENGTH];
354 size_t key_mat_buf_length;
355
356 /* Clear out any old possibly longer key matter. */
357 #ifdef HAVE_OPENSSL_1_1
358 memset(&(priv->key), 0, sizeof(priv->key) );
359 #else
360 memset(&(priv->enc_key), 0, sizeof(priv->enc_key) );
361 memset(&(priv->dec_key), 0, sizeof(priv->dec_key) );
362 #endif
363 memset(&(priv->iv_enc_key), 0, sizeof(priv->iv_enc_key) );
364 memset(&(priv->iv_pad_val), 0, sizeof(priv->iv_pad_val) );
365
366 /* Let the user choose the degree of encryption:
367 * Long input keys will pick AES192 or AES256 with more robust but expensive encryption.
368 *
369 * The input key always gets hashed to make a more unpredictable use of the key space and
370 * also to derive some additional material (key for IV encrpytion, IV padding).
371 *
372 * The following scheme for key setup was discussed on github:
373 * https://github.com/ntop/n2n/issues/101
374 */
375
376 /* create a working buffer of maximal occuring hashes size and generate
377 * the hashes for the aes key material, key_mat_buf_lengh indicates the
378 * actual "filling level" of the buffer
379 */
380
381 if(key_size >= 65) {
382 #ifdef HAVE_OPENSSL_1_1
383 priv->cipher = EVP_aes_256_cbc();
384 #endif
385 aes_key_size_bytes = AES256_KEY_BYTES;
386 SHA512(key, key_size, key_mat_buf);
387 key_mat_buf_length = SHA512_DIGEST_LENGTH;
388 } else if(key_size >= 44) {
389 #ifdef HAVE_OPENSSL_1_1
390 priv->cipher = EVP_aes_192_cbc();
391 #endif
392 aes_key_size_bytes = AES192_KEY_BYTES;
393 SHA384(key, key_size, key_mat_buf);
394 /* append a hash of the first hash to create enough material for IV padding */
395 SHA256(key_mat_buf, SHA384_DIGEST_LENGTH, key_mat_buf + SHA384_DIGEST_LENGTH);
396 key_mat_buf_length = SHA384_DIGEST_LENGTH + SHA256_DIGEST_LENGTH;
397 } else {
398 #ifdef HAVE_OPENSSL_1_1
399 priv->cipher = EVP_aes_128_cbc();
400 #endif
401 aes_key_size_bytes = AES128_KEY_BYTES;
402 SHA256(key, key_size, key_mat_buf);
403 /* append a hash of the first hash to create enough material for IV padding */
404 SHA256(key_mat_buf, SHA256_DIGEST_LENGTH, key_mat_buf + SHA256_DIGEST_LENGTH);
405 key_mat_buf_length = 2 * SHA256_DIGEST_LENGTH;
406 }
407
408 /* is there enough material available? */
409 if(key_mat_buf_length < (aes_key_size_bytes + TRANSOP_AES_IV_KEY_BYTES + TRANSOP_AES_IV_PADDING_SIZE)) {
410 /* this should never happen */
411 traceEvent(TRACE_ERROR, "AES missing %u bits hashed key material\n",
412 (aes_key_size_bytes + TRANSOP_AES_IV_KEY_BYTES + TRANSOP_AES_IV_PADDING_SIZE - key_mat_buf_length) * 8);
413 return(1);
414 }
415
416 /* setup of key, used for the CBC encryption */
417 aes_key_size_bits = 8 * aes_key_size_bytes;
418
419 #ifdef HAVE_OPENSSL_1_1
420 memcpy (priv->key, key_mat_buf, aes_key_size_bytes);
421 #else
422 AES_set_encrypt_key(key_mat_buf, aes_key_size_bits, &(priv->enc_key));
423 AES_set_decrypt_key(key_mat_buf, aes_key_size_bits, &(priv->dec_key));
424 #endif
425
426 /* setup of iv_enc_key (AES128 key) and iv_pad_val, used for generating the CBC IV */
427 AES_set_encrypt_key(key_mat_buf + aes_key_size_bytes, TRANSOP_AES_IV_KEY_BYTES * 8, &(priv->iv_enc_key));
428 memcpy(priv->iv_pad_val, key_mat_buf + aes_key_size_bytes + TRANSOP_AES_IV_KEY_BYTES, TRANSOP_AES_IV_PADDING_SIZE);
429
430 traceEvent(TRACE_DEBUG, "AES %u bits setup completed\n",
431 aes_key_size_bits);
432
433 return(0);
434 }
435
436 /* ****************************************************** */
437
transop_tick_aes(n2n_trans_op_t * arg,time_t now)438 static void transop_tick_aes(n2n_trans_op_t * arg, time_t now) { ; }
439
440 /* ****************************************************** */
441
442 /* AES initialization function */
n2n_transop_aes_cbc_init(const n2n_edge_conf_t * conf,n2n_trans_op_t * ttt)443 int n2n_transop_aes_cbc_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
444 transop_aes_t *priv;
445 const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
446 size_t encrypt_key_len = strlen(conf->encrypt_key);
447
448 memset(ttt, 0, sizeof(*ttt));
449 ttt->transform_id = N2N_TRANSFORM_ID_AESCBC;
450
451 ttt->tick = transop_tick_aes;
452 ttt->deinit = transop_deinit_aes;
453 ttt->fwd = transop_encode_aes;
454 ttt->rev = transop_decode_aes;
455
456 priv = (transop_aes_t*) calloc(1, sizeof(transop_aes_t));
457 if(!priv) {
458 traceEvent(TRACE_ERROR, "cannot allocate transop_aes_t memory");
459 return(-1);
460 }
461 ttt->priv = priv;
462
463 #ifdef HAVE_OPENSSL_1_1
464 /* Setup openssl's reusable evp_* contexts for encryption and decryption*/
465 if(!(priv->enc_ctx = EVP_CIPHER_CTX_new())) {
466 traceEvent(TRACE_ERROR, "openssl's evp_* encryption context creation: %s\n", openssl_err_as_string());
467 return(-1);
468 }
469
470 if(!(priv->dec_ctx = EVP_CIPHER_CTX_new())) {
471 traceEvent(TRACE_ERROR, "openssl's evp_* decryption context creation: %s\n", openssl_err_as_string());
472 return(-1);
473 }
474 #endif
475
476 /* Setup the cipher and key */
477 return(setup_aes_key(priv, encrypt_key, encrypt_key_len));
478 }
479
480 #endif /* N2N_HAVE_AES */
481