]> git.wh0rd.org - dump.git/blob - common/transformation_ssl.c
Regenerate configure.
[dump.git] / common / transformation_ssl.c
1 #include <stdio.h>
2 #include <config.h>
3 #include <sys/mman.h>
4
5 #ifdef HAVE_OPENSSL
6 #include <openssl/err.h>
7 #include <openssl/evp.h>
8 #include <openssl/rand.h>
9 #include <openssl/pkcs12.h>
10 #endif
11
12 #ifdef HAVE_ZLIB
13 #include <zlib.h>
14 #endif /* HAVE_ZLIB */
15
16 #include "transformation.h"
17
18 /*
19 * IMPORTANT: this is an important piece of the puzzle for native
20 * support of encrypted backups but Key management is much more
21 * important and much harder. The best encryption algorithms in the
22 * world won't help you if you have to reveal your one key to everyone.
23 *
24 * IMPORTANT: always comply with local laws! Do not modify the source
25 * to give you stronger encryption than permitted by local law.
26 *
27 * -----------------------
28 * 30-second cryptanalysis
29 * -----------------------
30 *
31 * This is a known-plaintext problem since many of the encrypted blocks
32 * will start with a BSD inode structure. (It will be compressed binary
33 * data but still (mostly) known.) This means that it is very important
34 * to choose a strong IV.
35 *
36 * The dump tape/file is written by multiple slave processes so we don't
37 * have ready access to an intrinsic value such as tape position. That
38 * leaves random salts that are included in the dump buffer. The salt
39 * doesn't need to be cryptographically strong since it will be published.
40 *
41 * The IV is created by calculating the hash of the salt, a function of
42 * the salt and session key, and the salt again.
43 *
44 * The greatest vulnerability is predictable keys (and weak ciphers
45 * required by local laws). The key should also be protected in memory
46 * while dumping and restoring files but it's not as critical since
47 * anyone able to read the key probably has the ability to read the
48 * filesystem directly.
49 */
50
51 /*
52 * Initialize.
53 *
54 * 1. load policy file, select ciphers based on it.
55 * 2. PKCS12 keystore contains certificate (public keys) and
56 * private keys.
57 * 3. private keys can be password-protected individually, and
58 * you can also password-protect the entire keystore.
59 * 4. PKCS12 keystores can be manipulated by openssl, java,
60 * windows apps, more.
61 *
62 * questions:
63 * 1. how to select which keystore? (command line option passed
64 * in as function argument?
65 * 2. how to select which key, if doing restore?
66 * 3. how to pass keystore password(s), if doing restore?
67 */
68 static int
69 ssl_initialize(Transformation *xform, int enc)
70 {
71 #ifdef HAVE_OPENSSL
72 int keylen;
73
74 OpenSSL_add_all_algorithms(); // see below */
75 OpenSSL_add_all_ciphers(); // see below */
76 OpenSSL_add_all_digests(); // see below */
77 ERR_load_crypto_strings();
78 ERR_load_RAND_strings();
79 ERR_load_ERR_strings();
80
81 // read policy file and call those two methods to load acceptable
82 // ciphers and digests. We always want CBC mode, not ECB mode.
83
84 /*
85 If we are encrypting we need to
86 1. create a random session key (good random numbers are critical!)
87 2. read the X509 certificates for everyone who needs to be able to read the dump file -
88 extract the public keys. These certificates may be in a PKCS12 keystore which many
89 applications use. OpenSSL also provides a large number of programs for it.
90 3. encrypt the session key with the public keys and put it into another PKCS12 keystore.
91 This keystore will be written to the tape in startnewtape().
92 4. set up the cipher context.
93
94 If we are decrypting we need to
95 1. open our keystore(PKCS12) containing our private keys. The keystore itself may be
96 password protected, the individual keys definitely should be.
97 2. read the PKCS12 keystore from the tape header.
98 3. look for matching key ids. If we can't find a match tell the user.
99 4. we still need to be able to open the private key so get the password somewhere.
100 5. set up the cipher context.
101 */
102
103 // RAND_egd(path);
104
105 #endif /* HAVE_OPENSSL */
106
107 return 0;
108 }
109
110 /*
111 * Shut down.
112 *
113 * The OpenSSL library may be using a physical crypto device so
114 * we need to make sure we properly release it.
115 */
116 static int
117 ssl_shutdown(Transformation *xform)
118 {
119 #ifdef HAVE_OPENSSL
120 OPENSSL_cleanse(xform->state.ssl.key, sizeof xform->state.ssl.key);
121
122 munlock(xform, sizeof(Transformation));
123 free(xform);
124
125 /* is this the right method? */
126 EVP_cleanup();
127 RAND_cleanup();
128 free(xform);
129 #endif /* HAVE_OPENSSL */
130 return 0;
131 }
132
133 /*
134 * We need to write new crypto header containing the encrypted
135 * session key.
136 */
137 static int
138 ssl_startNewTape(Transformation *xform, struct tapebuf *tpbin,
139 unsigned long *destlen)
140 {
141 #ifdef HAVE_OPENSSL
142 /* write new TS containing PKCS12 containing encrypted session key. */
143 #endif /* HAVE_OPENSSL */
144
145 return 0;
146 }
147
148 /*
149 * Start slave process. We need to reinitialize the encryption
150 * engine.
151 */
152 static int
153 ssl_startDiskIOProcess(Transformation *xform)
154 {
155 #ifdef HAVE_OPENSSL
156 mlock(xform, sizeof(Transformation));
157
158 OpenSSL_add_all_algorithms(); // see below */
159 OpenSSL_add_all_ciphers(); // see below */
160 OpenSSL_add_all_digests(); // see below */
161 ERR_load_crypto_strings();
162 ERR_load_RAND_strings();
163 ERR_load_ERR_strings();
164
165 // Initialize key information with values we obtained from parent
166 // thread's startNewTape().
167
168 xform->state.ssl.dataCtx = EVP_CIPHER_CTX_new();
169 xform->state.ssl.ivCtx = EVP_CIPHER_CTX_new();
170 #endif /* HAVE_OPENSSL */
171
172 return 0;
173 }
174
175 /*
176 * End of slave process. Clear encryption keys, etc.
177 */
178 static int
179 ssl_endDiskIOProcess(Transformation *xform)
180 {
181 #ifdef HAVE_OPENSSL
182 EVP_CIPHER_CTX_cleanup(xform->state.ssl.dataCtx);
183 EVP_CIPHER_CTX_cleanup(xform->state.ssl.ivCtx);
184 EVP_CIPHER_CTX_free(xform->state.ssl.dataCtx);
185 EVP_CIPHER_CTX_free(xform->state.ssl.ivCtx);
186
187 OPENSSL_cleanse(xform->state.ssl.key, sizeof xform->state.ssl.key);
188
189 munlock(xform, sizeof(Transformation));
190 free(xform);
191
192 /* is this the right method? */
193 EVP_cleanup();
194 RAND_cleanup();
195 #endif /* HAVE_OPENSSL */
196 return 0;
197 }
198
199 /*
200 * Method to generate 'random' salt and IV.
201 *
202 * The generated salt is 16 bytes long. It is duplicated to get a 256-bit value (to support
203 * 256-bit block ciphers.)
204 *
205 */
206 #ifdef HAVE_OPENSSL
207 static int
208 generateIV(Transformation *xform, unsigned char *salt, unsigned int *saltlen,
209 unsigned char *iv, unsigned int *ivlen)
210 {
211 unsigned char ivbuffer[64];
212 unsigned int buflen, y;
213
214 /* we can use pseudorandom bytes since they're going */
215 /* to be exposed to any attacker anyway. */
216 *saltlen = 16;
217 if (xform->enc == 1) {
218 RAND_pseudo_bytes(salt, *saltlen);
219 }
220 memcpy(ivbuffer, salt, 16);
221
222 /* -decrypt- salt value */
223 memset(ivbuffer, 0, sizeof(ivbuffer));
224 EVP_CipherInit_ex(xform->state.ssl.ivCtx, xform->state.ssl.cipher, xform->state.ssl.engine, NULL, NULL, 0);
225 //EVP_CIPHER_CTX_set_key_length(&ctx, 8);
226 EVP_CIPHER_CTX_set_padding(xform->state.ssl.ivCtx, 0); // -nopad
227 EVP_CipherInit_ex(xform->state.ssl.ivCtx, NULL, NULL, xform->state.ssl.key, ivbuffer, 0);
228 buflen = 32;
229 if (!EVP_CipherUpdate(xform->state.ssl.ivCtx, ivbuffer + 16, &buflen, salt, 16)) {
230 y = 32 - buflen;
231 if (!EVP_CipherFinal(xform->state.ssl.ivCtx, ivbuffer + 16 + buflen, &y)) {
232 buflen += y;
233 } else {
234 memset(ivbuffer + 16, 0, 32);
235 }
236 } else {
237 memset(ivbuffer + 16, 0, 32);
238 }
239 memcpy(ivbuffer + 48, salt, 16);
240
241 /* now digest it. */
242 EVP_Digest(ivbuffer, 64, iv, ivlen, xform->state.ssl.digest, NULL);
243
244 return 0;
245 }
246 #endif
247
248
249 /*
250 * Encrypt a single chunk of blocks. Each chunk is encrypted
251 * independently so it's critically important to choose a good
252 * initial vector (iv).
253 *
254 * The ciphertext format is:
255 * - 20 bytes of random salt
256 * - encrypted (plaintext . digest(plaintext))
257 */
258 static int
259 ssl_compress(Transformation *xform, struct tapebuf *tpbin,
260 unsigned long *destlen, const char *src, int srclen)
261 {
262 #ifdef HAVE_OPENSSL
263 unsigned char salt[16], iv[EVP_MAX_MD_SIZE];
264 unsigned int saltlen = sizeof(salt);
265 unsigned int ivlen = sizeof(iv);
266 unsigned char digest[EVP_MAX_MD_SIZE];
267 unsigned int digestlen = 0;
268 char *buf;
269 unsigned int len, len2;
270
271 len = srclen + 1000;
272 buf = malloc(len);
273
274 digestlen = sizeof(digest);
275
276 /* generate salt, put it in header */
277 generateIV(xform, salt, &saltlen, iv, &ivlen);
278 memcpy(tpbin->buf, salt, saltlen);
279
280 /* compress the buffer first - increase the entropy */
281 int compresult;
282 compresult = compress2(buf, destlen, src, srclen, xform->state.ssl.complvl);
283 if (compresult != Z_OK) {
284 printf("unable to compress...\n");
285 return 0;
286 }
287
288 EVP_EncryptInit_ex(xform->state.ssl.dataCtx, xform->state.ssl.cipher, xform->state.ssl.engine, NULL, NULL);
289 //EVP_CIPHER_CTX_set_key_length(&ctx, 8);
290 EVP_EncryptInit_ex(xform->state.ssl.dataCtx, NULL, NULL, xform->state.ssl.key, iv);
291
292 // encrypt content.
293 if (!EVP_EncryptUpdate(xform->state.ssl.dataCtx, tpbin->buf + saltlen, &len, buf, *destlen)) {
294 EVP_CIPHER_CTX_cleanup(xform->state.ssl.dataCtx);
295 ERR_print_errors_fp(stdout);
296 free(buf);
297 return 0;
298 }
299
300 // calculate digest, add it.
301 EVP_Digest(src, srclen, digest, &digestlen, xform->state.ssl.digest, xform->state.ssl.engine);
302
303 len2 = *destlen - len - saltlen;
304 if (!EVP_EncryptUpdate(xform->state.ssl.dataCtx, tpbin->buf + saltlen + len, &len2, digest, digestlen)) {
305 EVP_CIPHER_CTX_cleanup(xform->state.ssl.dataCtx);
306 ERR_print_errors_fp(stdout);
307 free(buf);
308 return 0;
309 }
310
311 len += len2;
312
313 // finish up
314 len2 = *destlen - len - saltlen;
315 if (!EVP_EncryptFinal(xform->state.ssl.dataCtx, tpbin->buf + saltlen + len, &len2)) {
316 EVP_CIPHER_CTX_cleanup(xform->state.ssl.dataCtx);
317 ERR_print_errors_fp(stdout);
318 free(buf);
319 return 0;
320 }
321
322 *destlen = len + len2 + saltlen;
323 free(buf);
324
325 OPENSSL_cleanse(iv, sizeof iv);
326 #endif /* HAVE_OPENSSL */
327
328 return 1;
329 }
330
331 /*
332 *
333 */
334 static int
335 ssl_decompress(Transformation *xform, struct tapebuf *tpbin,
336 unsigned long *destlen, const char *src, int srclen, char **reason)
337 {
338 #ifdef HAVE_OPENSSL
339 unsigned char salt[16], iv[EVP_MAX_MD_SIZE];
340 unsigned int saltlen = sizeof(salt);
341 unsigned int ivlen = sizeof(iv);
342 unsigned char digest[EVP_MAX_MD_SIZE];
343 unsigned int digestlen;
344 char *buf;
345 unsigned int len, len2;
346
347 digestlen = EVP_MD_size(xform->state.ssl.digest);
348
349 len = *destlen + 1000;
350 buf = malloc(len);
351
352 // how to know salt length?
353 memcpy(salt, src, saltlen);
354 generateIV(xform, salt, &saltlen, iv, &ivlen);
355
356 EVP_DecryptInit_ex(xform->state.ssl.dataCtx, xform->state.ssl.cipher, xform->state.ssl.engine, NULL, NULL);
357 //EVP_CIPHER_CTX_set_key_length(&ctx, 8);
358 EVP_DecryptInit_ex(xform->state.ssl.dataCtx, NULL, NULL, xform->state.ssl.key, iv);
359
360 if (!EVP_DecryptUpdate(xform->state.ssl.dataCtx, buf, &len, src+saltlen, srclen-saltlen)) {
361 EVP_CIPHER_CTX_cleanup(xform->state.ssl.dataCtx);
362 free(buf);
363 ERR_print_errors_fp(stdout);
364 printf("error 1\n");
365 return 0;
366 }
367
368 len2 = *destlen + 1000 - len;
369 if (!EVP_DecryptFinal(xform->state.ssl.dataCtx, buf + len, &len2)) {
370 EVP_CIPHER_CTX_cleanup(xform->state.ssl.dataCtx);
371 free(buf);
372 ERR_print_errors_fp(stdout);
373 printf("error 2\n");
374 return 0;
375 }
376 len += len2;
377 len -= digestlen;
378
379 OPENSSL_cleanse(iv, sizeof iv);
380
381 int cresult;
382 cresult = uncompress(tpbin->buf, destlen, buf, len);
383 switch (cresult) {
384 case Z_OK:
385 *reason = "";
386 break;
387 case Z_MEM_ERROR:
388 *reason = "not enough memory";
389 break;
390 case Z_BUF_ERROR:
391 *reason = "buffer too small";
392 break;
393 case Z_DATA_ERROR:
394 *reason = "data error";
395 break;
396 default:
397 *reason = "unknown";
398 }
399 if (cresult != Z_OK) {
400 printf("compression failed: %s\n", *reason);
401 free(buf);
402 return 0;
403 }
404
405 /* verify digest */
406 EVP_Digest(tpbin->buf, *destlen, digest, &digestlen, xform->state.ssl.digest, xform->state.ssl.engine);
407
408 if (memcmp(buf + len, digest, digestlen)) {
409 *reason = "digests did not match";
410 return 0;
411 }
412
413 free(buf);
414
415 #endif /* HAVE_OPENSSL */
416
417 return 1;
418 }
419
420 /*
421 *
422 */
423 #if 0
424 static int
425 ssl_compress_ts_addr(char *state, struct tapebuf *comp_buf,
426 unsigned int *worklen, char *data, int writesize, int compressed)
427 {
428 #ifdef HAVE_OPENSSL
429 SSLState *s = (SSLState *) state;
430 unsigned char iv[32];
431 unsigned int len;
432
433 EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *) malloc(sizeof(EVP_CIPHER_CTX));
434
435 //EVP_BytesToKey(cipher, EVP_md5(), NULL, buf, strlen(buf), 1, key, iv);
436
437 //EVP_CIPHER_CTX_init(ctx);
438 //EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, do_encrypt);
439 //blocksize = EVP_CIPHER_CTX_block_size(ctx);
440
441 s->digest = EVP_md_null;
442 s->cipher = EVP_enc_null;
443 EVP_CIPHER_CTX_init(s->ctx);
444
445 /* calculate 'random' IV. */
446 EVP_MD_CTX_init(&md);
447 EVP_DigestInit_ex(s->md, s->md, NULL);
448 /* EVP_DigestUpdate(s->md, x, len); <-- use logical record number */
449 EVP_DigestUpdate(s->md, s->salt, s->saltlen);
450 len = sizeof(iv);
451 EVP_DigestFinal(s->md, iv, &len);
452
453 // mlock on state info...
454
455 /* do the actual encryption */
456 EVP_CipherInit(s->ctx, s->cipher, s->key, iv);
457 EVP_CipherUpdate(s->ctx, out, &n, buf, buflen);
458 EVP_CipherFinal(s->ctx, out + n, outlen - y);
459 return 1;
460 #endif /* HAVE_OPENSSL */
461
462 return 1;
463 }
464 #endif
465
466
467 /*
468 * Factory. The cipher and digestnames should be read from a localized
469 * policy file.
470 *
471 * TODO: indicate error if unknown cipher or digest.
472 */
473 Transformation
474 *transformation_ssl_factory(int enc, int complvl, const char *ciphername, const char *digestname)
475 {
476 int keylen;
477 Transformation *t;
478
479 t = (Transformation *) malloc(sizeof (Transformation));
480 mlock(t, sizeof(Transformation));
481
482 OpenSSL_add_all_ciphers();
483 OpenSSL_add_all_digests();
484
485 t->enc = enc;
486 t->state.ssl.complvl = complvl;
487 t->state.ssl.cipher = EVP_get_cipherbyname(ciphername);
488 t->state.ssl.digest = EVP_get_digestbyname(digestname);
489 t->state.ssl.engine = NULL;
490
491 t->name = "ssl";
492 t->mandatory = 1;
493 t->initialize = &ssl_initialize;
494 t->shutdown = &ssl_shutdown;
495 t->startNewTape = &ssl_startNewTape;
496 t->startDiskIOProcess = &ssl_startDiskIOProcess;
497 t->endDiskIOProcess = &ssl_endDiskIOProcess;
498 t->compress = &ssl_compress;
499 t->decompress = &ssl_decompress;
500
501 // we could use this to generate a key from a passphrase.
502 // using this as the actual encryption key has the problems
503 // discussed elsewhere.
504 //EVP_BytesToKey(cipher, EVP_md5(), NULL, buf, strlen(buf), 1, key, iv);
505
506 if (enc) {
507 /* generate random session key */
508 //EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
509 //EVP_CIPHER_CTX_init(ctx);
510 //EVP_CIPHER_CTX_rand_key(ctx, t->state.ssl.key);
511 //EVP_CIPHER_CTX_cleanup(ctx);
512 //EVP_CIPHER_CTX_free(ctx);
513 RAND_bytes(t->state.ssl.key, t->state.ssl.cipher->key_len);
514 } else {
515 // how do we get keys?
516 }
517
518 return t;
519 }