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