]>
git.wh0rd.org - dump.git/blob - common/transformation_ssl.c
6 #include <openssl/err.h>
7 #include <openssl/evp.h>
8 #include <openssl/rand.h>
9 #include <openssl/pkcs12.h>
14 #endif /* HAVE_ZLIB */
16 #include "transformation.h"
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.
24 * IMPORTANT: always comply with local laws! Do not modify the source
25 * to give you stronger encryption than permitted by local law.
27 * -----------------------
28 * 30-second cryptanalysis
29 * -----------------------
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.
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.
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.
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.
54 * 1. load policy file, select ciphers based on it.
55 * 2. PKCS12 keystore contains certificate (public keys) and
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,
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?
69 ssl_initialize(Transformation
*xform
, int enc
)
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();
81 // read policy file and call those two methods to load acceptable
82 // ciphers and digests. We always want CBC mode, not ECB mode.
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.
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.
105 #endif /* HAVE_OPENSSL */
113 * The OpenSSL library may be using a physical crypto device so
114 * we need to make sure we properly release it.
117 ssl_shutdown(Transformation
*xform
)
120 OPENSSL_cleanse(xform
->state
.ssl
.key
, sizeof xform
->state
.ssl
.key
);
122 munlock(xform
, sizeof(Transformation
));
125 /* is this the right method? */
129 #endif /* HAVE_OPENSSL */
134 * We need to write new crypto header containing the encrypted
138 ssl_startNewTape(Transformation
*xform
, struct tapebuf
*tpbin
,
139 unsigned long *destlen
)
142 /* write new TS containing PKCS12 containing encrypted session key. */
143 #endif /* HAVE_OPENSSL */
149 * Start slave process. We need to reinitialize the encryption
153 ssl_startDiskIOProcess(Transformation
*xform
)
156 mlock(xform
, sizeof(Transformation
));
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();
165 // Initialize key information with values we obtained from parent
166 // thread's startNewTape().
168 xform
->state
.ssl
.dataCtx
= EVP_CIPHER_CTX_new();
169 xform
->state
.ssl
.ivCtx
= EVP_CIPHER_CTX_new();
170 #endif /* HAVE_OPENSSL */
176 * End of slave process. Clear encryption keys, etc.
179 ssl_endDiskIOProcess(Transformation
*xform
)
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
);
187 OPENSSL_cleanse(xform
->state
.ssl
.key
, sizeof xform
->state
.ssl
.key
);
189 munlock(xform
, sizeof(Transformation
));
192 /* is this the right method? */
195 #endif /* HAVE_OPENSSL */
200 * Method to generate 'random' salt and IV.
202 * The generated salt is 16 bytes long. It is duplicated to get a 256-bit value (to support
203 * 256-bit block ciphers.)
208 generateIV(Transformation
*xform
, unsigned char *salt
, unsigned int *saltlen
,
209 unsigned char *iv
, unsigned int *ivlen
)
211 unsigned char ivbuffer
[64];
212 unsigned int buflen
, y
;
214 /* we can use pseudorandom bytes since they're going */
215 /* to be exposed to any attacker anyway. */
217 if (xform
->enc
== 1) {
218 RAND_pseudo_bytes(salt
, *saltlen
);
220 memcpy(ivbuffer
, salt
, 16);
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);
229 if (!EVP_CipherUpdate(xform
->state
.ssl
.ivCtx
, ivbuffer
+ 16, &buflen
, salt
, 16)) {
231 if (!EVP_CipherFinal(xform
->state
.ssl
.ivCtx
, ivbuffer
+ 16 + buflen
, &y
)) {
234 memset(ivbuffer
+ 16, 0, 32);
237 memset(ivbuffer
+ 16, 0, 32);
239 memcpy(ivbuffer
+ 48, salt
, 16);
242 EVP_Digest(ivbuffer
, 64, iv
, ivlen
, xform
->state
.ssl
.digest
, NULL
);
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).
254 * The ciphertext format is:
255 * - 20 bytes of random salt
256 * - encrypted (plaintext . digest(plaintext))
259 ssl_compress(Transformation
*xform
, struct tapebuf
*tpbin
,
260 unsigned long *destlen
, const char *src
, int srclen
)
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;
269 unsigned int len
, len2
;
274 digestlen
= sizeof(digest
);
276 /* generate salt, put it in header */
277 generateIV(xform
, salt
, &saltlen
, iv
, &ivlen
);
278 memcpy(tpbin
->buf
, salt
, saltlen
);
280 /* compress the buffer first - increase the entropy */
282 compresult
= compress2(buf
, destlen
, src
, srclen
, xform
->state
.ssl
.complvl
);
283 if (compresult
!= Z_OK
) {
284 printf("unable to compress...\n");
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
);
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
);
300 // calculate digest, add it.
301 EVP_Digest(src
, srclen
, digest
, &digestlen
, xform
->state
.ssl
.digest
, xform
->state
.ssl
.engine
);
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
);
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
);
322 *destlen
= len
+ len2
+ saltlen
;
325 OPENSSL_cleanse(iv
, sizeof iv
);
326 #endif /* HAVE_OPENSSL */
335 ssl_decompress(Transformation
*xform
, struct tapebuf
*tpbin
,
336 unsigned long *destlen
, const char *src
, int srclen
, char **reason
)
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
;
345 unsigned int len
, len2
;
347 digestlen
= EVP_MD_size(xform
->state
.ssl
.digest
);
349 len
= *destlen
+ 1000;
352 // how to know salt length?
353 memcpy(salt
, src
, saltlen
);
354 generateIV(xform
, salt
, &saltlen
, iv
, &ivlen
);
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
);
360 if (!EVP_DecryptUpdate(xform
->state
.ssl
.dataCtx
, buf
, &len
, src
+saltlen
, srclen
-saltlen
)) {
361 EVP_CIPHER_CTX_cleanup(xform
->state
.ssl
.dataCtx
);
363 ERR_print_errors_fp(stdout
);
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
);
372 ERR_print_errors_fp(stdout
);
379 OPENSSL_cleanse(iv
, sizeof iv
);
382 cresult
= uncompress(tpbin
->buf
, destlen
, buf
, len
);
388 *reason
= "not enough memory";
391 *reason
= "buffer too small";
394 *reason
= "data error";
399 if (cresult
!= Z_OK
) {
400 printf("compression failed: %s\n", *reason
);
406 EVP_Digest(tpbin
->buf
, *destlen
, digest
, &digestlen
, xform
->state
.ssl
.digest
, xform
->state
.ssl
.engine
);
408 if (memcmp(buf
+ len
, digest
, digestlen
)) {
409 *reason
= "digests did not match";
415 #endif /* HAVE_OPENSSL */
425 ssl_compress_ts_addr(char *state
, struct tapebuf
*comp_buf
,
426 unsigned int *worklen
, char *data
, int writesize
, int compressed
)
429 SSLState
*s
= (SSLState
*) state
;
430 unsigned char iv
[32];
433 EVP_CIPHER_CTX
*ctx
= (EVP_CIPHER_CTX
*) malloc(sizeof(EVP_CIPHER_CTX
));
435 //EVP_BytesToKey(cipher, EVP_md5(), NULL, buf, strlen(buf), 1, key, iv);
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);
441 s
->digest
= EVP_md_null
;
442 s
->cipher
= EVP_enc_null
;
443 EVP_CIPHER_CTX_init(s
->ctx
);
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
);
451 EVP_DigestFinal(s
->md
, iv
, &len
);
453 // mlock on state info...
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
);
460 #endif /* HAVE_OPENSSL */
468 * Factory. The cipher and digestnames should be read from a localized
471 * TODO: indicate error if unknown cipher or digest.
474 *transformation_ssl_factory(int enc
, int complvl
, const char *ciphername
, const char *digestname
)
479 t
= (Transformation
*) malloc(sizeof (Transformation
));
480 mlock(t
, sizeof(Transformation
));
482 OpenSSL_add_all_ciphers();
483 OpenSSL_add_all_digests();
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
;
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
;
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);
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
);
515 // how do we get keys?