• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * ntfsdecrypt - Decrypt ntfs encrypted files.  Part of the Linux-NTFS project.
3  *
4  * Copyright (c) 2005 Yuval Fledel
5  * Copyright (c) 2005-2007 Anton Altaparmakov
6  * Copyright (c) 2007 Yura Pakhuchiy
7  * Copyright (c) 2014-2015 Jean-Pierre Andre
8  *
9  * This utility will decrypt files and print the decrypted data on the standard
10  * output.
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program (in the main directory of the Linux-NTFS
24  * distribution in the file COPYING); if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27 
28 #include "config.h"
29 
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
32 #endif
33 #ifdef HAVE_SYS_STAT_H
34 #include <sys/stat.h>
35 #endif
36 #ifdef HAVE_FCNTL_H
37 #include <fcntl.h>
38 #endif
39 #ifdef HAVE_STDIO_H
40 #include <stdio.h>
41 #endif
42 #ifdef HAVE_GETOPT_H
43 #include <getopt.h>
44 #endif
45 #ifdef HAVE_STDLIB_H
46 #include <stdlib.h>
47 #endif
48 #ifdef HAVE_STRING_H
49 #include <string.h>
50 #endif
51 #ifdef HAVE_UNISTD_H
52 #include <unistd.h>
53 #endif
54 #ifdef HAVE_ERRNO_H
55 #include <errno.h>
56 #endif
57 #include <gcrypt.h>
58 #include <gnutls/pkcs12.h>
59 
60 #include "types.h"
61 #include "attrib.h"
62 #include "utils.h"
63 #include "volume.h"
64 #include "debug.h"
65 #include "dir.h"
66 #include "layout.h"
67 /* #include "version.h" */
68 #include "misc.h"
69 
70 typedef gcry_sexp_t ntfs_rsa_private_key;
71 
72 #define NTFS_SHA1_THUMBPRINT_SIZE 0x14
73 
74 #define NTFS_CRED_TYPE_CERT_THUMBPRINT const_cpu_to_le32(3)
75 
76 #define NTFS_EFS_CERT_PURPOSE_OID_DDF "1.3.6.1.4.1.311.10.3.4" /* decryption */
77 #define NTFS_EFS_CERT_PURPOSE_OID_DRF "1.3.6.1.4.1.311.10.3.4.1" /* recovery */
78 
79 typedef enum {
80 	DF_TYPE_UNKNOWN,
81 	DF_TYPE_DDF, /* decryption */
82 	DF_TYPE_DRF, /* recovery */
83 } NTFS_DF_TYPES;
84 
85 /**
86  * enum NTFS_CRYPTO_ALGORITHMS - List of crypto algorithms used by EFS (32 bit)
87  *
88  * To choose which one is used in Windows, create or set the REG_DWORD registry
89  * key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\EFS\
90  * AlgorithmID to the value of your chosen crypto algorithm, e.g. to use DesX,
91  * set AlgorithmID to 0x6604.
92  *
93  * Note that the Windows versions I have tried so far (all are high crypto
94  * enabled) ignore the AlgorithmID value if it is not one of CALG_3DES,
95  * CALG_DESX, or CALG_AES_256, i.e. you cannot select CALG_DES at all using
96  * this registry key.  It would be interesting to check out encryption on one
97  * of the "crippled" crypto Windows versions...
98  */
99 typedef enum {
100 	CALG_DES	= const_cpu_to_le32(0x6601),
101 	/* If not one of the below three, fall back to standard Des. */
102 	CALG_3DES	= const_cpu_to_le32(0x6603),
103 	CALG_DESX	= const_cpu_to_le32(0x6604),
104 	CALG_AES_256	= const_cpu_to_le32(0x6610),
105 } NTFS_CRYPTO_ALGORITHMS;
106 
107 typedef struct {
108 	u64 in_whitening, out_whitening;
109 	u8 des_key[8];
110 	u64 prev_blk;
111 } ntfs_desx_ctx;
112 
113 /**
114  * struct ntfs_fek - Decrypted, in-memory file encryption key.
115  */
116 
117 typedef struct {
118 	gcry_cipher_hd_t gcry_cipher_hd;
119 	le32 alg_id;
120 	u8 *key_data;
121 	gcry_cipher_hd_t *des_gcry_cipher_hd_ptr;
122 	ntfs_desx_ctx desx_ctx;
123 } ntfs_fek;
124 
125 struct options {
126 	char *keyfile;	/* .pfx file containing the user's private key. */
127 	char *device;		/* Device/File to work with */
128 	char *file;		/* File to display */
129 	s64 inode;		/* Inode to work with */
130 	ATTR_TYPES attr;	/* Attribute type to display */
131 	int force;		/* Override common sense */
132 	int quiet;		/* Less output */
133 	int verbose;		/* Extra output */
134 	int encrypt;		/* Encrypt */
135 };
136 
137 static const char *EXEC_NAME = "ntfsdecrypt";
138 static struct options opts;
139 
140 static ntfschar EFS[5] = {
141 	const_cpu_to_le16('$'), const_cpu_to_le16('E'), const_cpu_to_le16('F'),
142 	const_cpu_to_le16('S'), const_cpu_to_le16('\0')
143 };
144 
145 /**
146  * version - Print version information about the program
147  *
148  * Print a copyright statement and a brief description of the program.
149  *
150  * Return:  none
151  */
version(void)152 static void version(void)
153 {
154 	ntfs_log_info("\n%s v%s (libntfs-3g) - Decrypt files and print on the "
155 			"standard output.\n\n", EXEC_NAME, VERSION);
156 	ntfs_log_info("Copyright (c) 2005 Yuval Fledel\n");
157 	ntfs_log_info("Copyright (c) 2005 Anton Altaparmakov\n");
158 	ntfs_log_info("Copyright (c) 2014-2015 Jean-Pierre Andre\n");
159 	ntfs_log_info("\n%s\n%s%s\n", ntfs_gpl, ntfs_bugs, ntfs_home);
160 }
161 
162 /**
163  * usage - Print a list of the parameters to the program
164  *
165  * Print a list of the parameters and options for the program.
166  *
167  * Return:  none
168  */
usage(void)169 static void usage(void)
170 {
171 	ntfs_log_info("\nUsage: %s [options] -k name.pfx device [file]\n\n"
172 	       "    -i, --inode num         Display this inode\n\n"
173 	       "    -k  --keyfile name.pfx  Use file name as the user's private key file.\n"
174 	       "    -e  --encrypt           Update an encrypted file\n"
175 	       "    -f  --force             Use less caution\n"
176 	       "    -h  --help              Print this help\n"
177 	       "    -q  --quiet             Less output\n"
178 	       "    -V  --version           Version information\n"
179 	       "    -v  --verbose           More output\n\n",
180 	       EXEC_NAME);
181 	ntfs_log_info("%s%s\n", ntfs_bugs, ntfs_home);
182 }
183 
184 /**
185  * parse_options - Read and validate the programs command line
186  *
187  * Read the command line, verify the syntax and parse the options.
188  * This function is very long, but quite simple.
189  *
190  * Return:  1 Success
191  *	    0 Error, one or more problems
192  */
parse_options(int argc,char ** argv)193 static int parse_options(int argc, char **argv)
194 {
195 	static const char *sopt = "-fh?ei:k:qVv";
196 	static const struct option lopt[] = {
197 		{"encrypt", no_argument, NULL, 'e'},
198 		{"force", no_argument, NULL, 'f'},
199 		{"help", no_argument, NULL, 'h'},
200 		{"inode", required_argument, NULL, 'i'},
201 		{"keyfile", required_argument, NULL, 'k'},
202 		{"quiet", no_argument, NULL, 'q'},
203 		{"version", no_argument, NULL, 'V'},
204 		{"verbose", no_argument, NULL, 'v'},
205 		{NULL, 0, NULL, 0}
206 	};
207 
208 	int c = -1;
209 	int err = 0;
210 	int ver = 0;
211 	int help = 0;
212 
213 	opterr = 0;		/* We'll handle the errors, thank you. */
214 
215 	opts.inode = -1;
216 
217 	while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) {
218 		switch (c) {
219 		case 1:	/* A non-option argument */
220 			if (!opts.device)
221 				opts.device = argv[optind - 1];
222 			else if (!opts.file)
223 				opts.file = argv[optind - 1];
224 			else {
225 				ntfs_log_error("You must specify exactly one "
226 					"file.\n");
227 				err++;
228 			}
229 			break;
230 		case 'e':
231 			opts.encrypt++;
232 			break;
233 		case 'f':
234 			opts.force++;
235 			break;
236 		case 'h':
237 			help++;
238 			break;
239 		case 'k':
240 			if (!opts.keyfile)
241 				opts.keyfile = argv[optind - 1];
242 			else {
243 				ntfs_log_error("You must specify exactly one "
244 						"key file.\n");
245 				err++;
246 			}
247 			break;
248 		case 'i':
249 			if (opts.inode != -1)
250 				ntfs_log_error("You must specify exactly one "
251 						"inode.\n");
252 			else if (utils_parse_size(optarg, &opts.inode, FALSE))
253 				break;
254 			else
255 				ntfs_log_error("Couldn't parse inode number.\n");
256 			err++;
257 			break;
258 		case 'q':
259 			opts.quiet++;
260 			ntfs_log_clear_levels(NTFS_LOG_LEVEL_QUIET);
261 			break;
262 		case 'V':
263 			ver++;
264 			break;
265 		case 'v':
266 			opts.verbose++;
267 			ntfs_log_set_levels(NTFS_LOG_LEVEL_VERBOSE);
268 			break;
269 		case '?':
270 		default:
271 			ntfs_log_error("Unknown option '%s'.\n",
272 				argv[optind - 1]);
273 			err++;
274 			break;
275 		}
276 	}
277 
278 	if (help || ver) {
279 		opts.quiet = 0;
280 		ntfs_log_set_levels(NTFS_LOG_LEVEL_QUIET);
281 	} else {
282 		if (!opts.keyfile) {
283 			ntfs_log_error("You must specify a key file.\n");
284 			err++;
285 		} else if (opts.device == NULL) {
286 			ntfs_log_error("You must specify a device.\n");
287 			err++;
288 		} else if (opts.file == NULL && opts.inode == -1) {
289 			ntfs_log_error("You must specify a file or inode with "
290 				"the -i option.\n");
291 			err++;
292 		} else if (opts.file != NULL && opts.inode != -1) {
293 			ntfs_log_error("You can't specify both a file and "
294 				"inode.\n");
295 			err++;
296 		}
297 		if (opts.quiet && opts.verbose) {
298 			ntfs_log_error("You may not use --quiet and --verbose "
299 				"at the same time.\n");
300 			err++;
301 		}
302 	}
303 
304 	if (ver)
305 		version();
306 	if (help || err)
307 		usage();
308 
309 		/* tri-state 0 : done, 1 : error, -1 : proceed */
310 	return (err ? 1 : (help || ver ? 0 : -1));
311 }
312 
313 /**
314  * ntfs_pkcs12_load_pfxfile
315  */
ntfs_pkcs12_load_pfxfile(const char * keyfile,u8 ** pfx,unsigned * pfx_size)316 static int ntfs_pkcs12_load_pfxfile(const char *keyfile, u8 **pfx,
317 		unsigned *pfx_size)
318 {
319 	int f, to_read, total, attempts, br;
320 	struct stat key_stat;
321 
322 	if (!keyfile || !pfx || !pfx_size) {
323 		ntfs_log_error("You have to specify the key file, a pointer "
324 				"to hold the key file contents, and a pointer "
325 				"to hold the size of the key file contents.\n");
326 		return -1;
327 	}
328 	f = open(keyfile, O_RDONLY);
329 	if (f == -1) {
330 		ntfs_log_perror("Failed to open key file");
331 		return -1;
332 	}
333 	if (fstat(f, &key_stat) == -1) {
334 		ntfs_log_perror("Failed to stat key file");
335 		goto file_out;
336 	}
337 	if (!S_ISREG(key_stat.st_mode)) {
338 		ntfs_log_error("Key file is not a regular file, cannot read "
339 				"it.\n");
340 		goto file_out;
341 	}
342 	if (!key_stat.st_size) {
343 		ntfs_log_error("Key file has zero size.\n");
344 		goto file_out;
345 	}
346 	*pfx = malloc(key_stat.st_size + 1);
347 	if (!*pfx) {
348 		ntfs_log_perror("Failed to allocate buffer for key file "
349 			"contents");
350 		goto file_out;
351 	}
352 	to_read = key_stat.st_size;
353 	total = attempts = 0;
354 	do {
355 		br = read(f, *pfx + total, to_read);
356 		if (br == -1) {
357 			ntfs_log_perror("Failed to read from key file");
358 			goto free_out;
359 		}
360 		if (!br)
361 			attempts++;
362 		to_read -= br;
363 		total += br;
364 	} while (to_read > 0 && attempts < 3);
365 	close(f);
366 	/* Make sure it is zero terminated. */
367 	(*pfx)[key_stat.st_size] = 0;
368 	*pfx_size = key_stat.st_size;
369 	return 0;
370 free_out:
371 	free(*pfx);
372 file_out:
373 	close(f);
374 	return -1;
375 }
376 
377 /**
378  * ntfs_crypto_init
379  */
ntfs_crypto_init(void)380 static int ntfs_crypto_init(void)
381 {
382 	int err;
383 
384 	/* Initialize gcrypt library.  Note: Must come before GNU TLS init. */
385 	if (gcry_control(GCRYCTL_DISABLE_SECMEM, 0) != GPG_ERR_NO_ERROR) {
386 		ntfs_log_error("Failed to initialize the gcrypt library.\n");
387 		return -1;
388 	}
389 	/* Initialize GNU TLS library.  Note: Must come after libgcrypt init. */
390 	err = gnutls_global_init();
391 	if (err < 0) {
392 		ntfs_log_error("Failed to initialize GNU TLS library: %s\n",
393 				gnutls_strerror(err));
394 		return -1;
395 	}
396 	return 0;
397 }
398 
399 /**
400  * ntfs_crypto_deinit
401  */
ntfs_crypto_deinit(void)402 static void ntfs_crypto_deinit(void)
403 {
404 	gnutls_global_deinit();
405 }
406 
407 /**
408  * ntfs_rsa_private_key_import_from_gnutls
409  */
ntfs_rsa_private_key_import_from_gnutls(gnutls_x509_privkey_t priv_key)410 static ntfs_rsa_private_key ntfs_rsa_private_key_import_from_gnutls(
411 		gnutls_x509_privkey_t priv_key)
412 {
413 	int i, j;
414 	size_t tmp_size;
415 	gnutls_datum_t rd[6];
416 	gcry_mpi_t rm[6];
417 	gcry_sexp_t rsa_key;
418 
419 	/* Extract the RSA parameters from the GNU TLS private key. */
420 	if (gnutls_x509_privkey_export_rsa_raw(priv_key, &rd[0], &rd[1],
421 			&rd[2], &rd[3], &rd[4], &rd[5])) {
422 		ntfs_log_error("Failed to export rsa parameters.  (Is the "
423 				"key an RSA private key?)\n");
424 		return NULL;
425 	}
426 	/* Convert each RSA parameter to mpi format. */
427 	for (i = 0; i < 6; i++) {
428 		if (gcry_mpi_scan(&rm[i], GCRYMPI_FMT_USG, rd[i].data,
429 				rd[i].size, &tmp_size) != GPG_ERR_NO_ERROR) {
430 			ntfs_log_error("Failed to convert RSA parameter %i "
431 					"to mpi format (size %d)\n", i,
432 					rd[i].size);
433 			rsa_key = NULL;
434 			break;
435 		}
436 	}
437 	/* Release the no longer needed datum values. */
438 	for (j = 0; j < 6; j++) {
439 		if (rd[j].data && rd[j].size)
440 			gnutls_free(rd[j].data);
441 	}
442 	/*
443 	 * Build the gcrypt private key, note libgcrypt uses p and q inversed
444 	 * to what gnutls uses.
445 	 */
446 	if (i == 6 && gcry_sexp_build(&rsa_key, NULL,
447 			"(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
448 			rm[0], rm[1], rm[2], rm[4], rm[3], rm[5]) !=
449 			GPG_ERR_NO_ERROR) {
450 		ntfs_log_error("Failed to build RSA private key s-exp.\n");
451 		rsa_key = NULL;
452 	}
453 	/* Release the no longer needed mpi values. */
454 	for (j = 0; j < i; j++)
455 		gcry_mpi_release(rm[j]);
456 	return (ntfs_rsa_private_key)rsa_key;
457 }
458 
459 /**
460  * ntfs_rsa_private_key_release
461  */
ntfs_rsa_private_key_release(ntfs_rsa_private_key rsa_key)462 static void ntfs_rsa_private_key_release(ntfs_rsa_private_key rsa_key)
463 {
464 	gcry_sexp_release((gcry_sexp_t)rsa_key);
465 }
466 
467 /**
468  * ntfs_pkcs12_extract_rsa_key
469  */
ntfs_pkcs12_extract_rsa_key(u8 * pfx,int pfx_size,char * password,char * thumbprint,int thumbprint_size,NTFS_DF_TYPES * df_type)470 static ntfs_rsa_private_key ntfs_pkcs12_extract_rsa_key(u8 *pfx, int pfx_size,
471 		char *password, char *thumbprint, int thumbprint_size,
472 		NTFS_DF_TYPES *df_type)
473 {
474 	int err, bag_index, flags;
475 	gnutls_datum_t dpfx, dkey;
476 	gnutls_pkcs12_t pkcs12 = NULL;
477 	gnutls_pkcs12_bag_t bag = NULL;
478 	gnutls_x509_privkey_t pkey = NULL;
479 	gnutls_x509_crt_t crt = NULL;
480 	ntfs_rsa_private_key rsa_key = NULL;
481 	char purpose_oid[100];
482 	size_t purpose_oid_size = sizeof(purpose_oid);
483 	int oid_index;
484 	size_t tp_size = thumbprint_size;
485 	BOOL have_thumbprint = FALSE;
486 
487 	*df_type = DF_TYPE_UNKNOWN;
488 	/* Create a pkcs12 structure. */
489 	err = gnutls_pkcs12_init(&pkcs12);
490 	if (err) {
491 		ntfs_log_error("Failed to initialize PKCS#12 structure: %s\n",
492 				gnutls_strerror(err));
493 		return NULL;
494 	}
495 	/* Convert the PFX file (DER format) to native pkcs12 format. */
496 	dpfx.data = pfx;
497 	dpfx.size = pfx_size;
498 	err = gnutls_pkcs12_import(pkcs12, &dpfx, GNUTLS_X509_FMT_DER, 0);
499 	if (err) {
500 		ntfs_log_error("Failed to convert the PFX file from DER to "
501 				"native PKCS#12 format: %s\n",
502 				gnutls_strerror(err));
503 		goto err;
504 	}
505 	/*
506 	 * Verify that the password is correct and that the key file has not
507 	 * been tampered with.  Note if the password has zero length and the
508 	 * verification fails, retry with password set to NULL.  This is needed
509 	 * to get passwordless .pfx files generated with Windows XP SP1 (and
510 	 * probably earlier versions of Windows) to work.
511 	 */
512 retry_verify:
513 	err = gnutls_pkcs12_verify_mac(pkcs12, password);
514 	if (err) {
515 		if (err == GNUTLS_E_MAC_VERIFY_FAILED &&
516 				password && !strlen(password)) {
517 			password = NULL;
518 			goto retry_verify;
519 		}
520 		ntfs_log_error("Failed to verify the MAC: %s  Is the "
521 				"password correct?\n", gnutls_strerror(err));
522 		goto err;
523 	}
524 	for (bag_index = 0; ; bag_index++) {
525 		err = gnutls_pkcs12_bag_init(&bag);
526 		if (err) {
527 			ntfs_log_error("Failed to initialize PKCS#12 Bag "
528 					"structure: %s\n",
529 					gnutls_strerror(err));
530 			goto err;
531 		}
532 		err = gnutls_pkcs12_get_bag(pkcs12, bag_index, bag);
533 		if (err) {
534 			if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
535 				err = 0;
536 				break;
537 			}
538 			ntfs_log_error("Failed to obtain Bag from PKCS#12 "
539 					"structure: %s\n",
540 					gnutls_strerror(err));
541 			goto err;
542 		}
543 check_again:
544 		err = gnutls_pkcs12_bag_get_count(bag);
545 		if (err < 0) {
546 			ntfs_log_error("Failed to obtain Bag count: %s\n",
547 					gnutls_strerror(err));
548 			goto err;
549 		}
550 		err = gnutls_pkcs12_bag_get_type(bag, 0);
551 		if (err < 0) {
552 			ntfs_log_error("Failed to determine Bag type: %s\n",
553 					gnutls_strerror(err));
554 			goto err;
555 		}
556 		flags = 0;
557 		switch (err) {
558 		case GNUTLS_BAG_PKCS8_KEY:
559 			flags = GNUTLS_PKCS_PLAIN;
560 			/* FALLTHRU */
561 		case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
562 			err = gnutls_pkcs12_bag_get_data(bag, 0, &dkey);
563 			if (err < 0) {
564 				ntfs_log_error("Failed to obtain Bag data: "
565 						"%s\n", gnutls_strerror(err));
566 				goto err;
567 			}
568 			err = gnutls_x509_privkey_init(&pkey);
569 			if (err) {
570 				ntfs_log_error("Failed to initialized "
571 						"private key structure: %s\n",
572 						gnutls_strerror(err));
573 				goto err;
574 			}
575 			/* Decrypt the private key into GNU TLS format. */
576 			err = gnutls_x509_privkey_import_pkcs8(pkey, &dkey,
577 					GNUTLS_X509_FMT_DER, password, flags);
578 			if (err) {
579 				ntfs_log_error("Failed to convert private "
580 						"key from DER to GNU TLS "
581 						"format: %s\n",
582 						gnutls_strerror(err));
583 				goto err;
584 			}
585 #if 0
586 			/*
587 			 * Export the key again, but unencrypted, and output it
588 			 * to stderr.  Note the output has an RSA header so to
589 			 * compare to openssl pkcs12 -nodes -in myfile.pfx
590 			 * output need to ignore the part of the key between
591 			 * the first "MII..." up to the second "MII...".  The
592 			 * actual RSA private key begins at the second "MII..."
593 			 * and in my testing at least was identical to openssl
594 			 * output and was also identical both on big and little
595 			 * endian so gnutls should be endianness safe.
596 			 */
597 			char *buf = malloc(8192);
598 			size_t bufsize = 8192;
599 			err = gnutls_x509_privkey_export_pkcs8(pkey,
600 				GNUTLS_X509_FMT_PEM, "", GNUTLS_PKCS_PLAIN, buf,
601 				&bufsize);
602 			if (err) {
603 				ntfs_log_error("eek1\n");
604 				exit(1);
605 			}
606 			ntfs_log_error("%s\n", buf);
607 			free(buf);
608 #endif
609 			/* Convert the private key to our internal format. */
610 			rsa_key = ntfs_rsa_private_key_import_from_gnutls(pkey);
611 			if (!rsa_key)
612 				goto err;
613 			break;
614 		case GNUTLS_BAG_ENCRYPTED:
615 			err = gnutls_pkcs12_bag_decrypt(bag, password);
616 			if (err) {
617 				ntfs_log_error("Failed to decrypt Bag: %s\n",
618 						gnutls_strerror(err));
619 				goto err;
620 			}
621 			goto check_again;
622 		case GNUTLS_BAG_CERTIFICATE:
623 			err = gnutls_pkcs12_bag_get_data(bag, 0, &dkey);
624 			if (err < 0) {
625 				ntfs_log_error("Failed to obtain Bag data: "
626 						"%s\n", gnutls_strerror(err));
627 				goto err;
628 			}
629 			err = gnutls_x509_crt_init(&crt);
630 			if (err) {
631 				ntfs_log_error("Failed to initialize "
632 						"certificate structure: %s\n",
633 						gnutls_strerror(err));
634 				goto err;
635 			}
636 			err = gnutls_x509_crt_import(crt, &dkey,
637 					GNUTLS_X509_FMT_DER);
638 			if (err) {
639 				ntfs_log_error("Failed to convert certificate "
640 						"from DER to GNU TLS format: "
641 						"%s\n", gnutls_strerror(err));
642 				goto err;
643 			}
644 			oid_index = 0;
645 				/*
646 				 * Search in the key purposes for an EFS
647 				 * encryption purpose or an EFS recovery
648 				 * purpose, and use the first one found.
649 				 */
650 			do {
651 				purpose_oid_size = sizeof(purpose_oid);
652 				err = gnutls_x509_crt_get_key_purpose_oid(crt,
653 					oid_index,
654 					purpose_oid, &purpose_oid_size, NULL);
655 				if (!err) {
656 					purpose_oid[purpose_oid_size - 1]
657 							= '\0';
658 					if (!strcmp(purpose_oid,
659 						NTFS_EFS_CERT_PURPOSE_OID_DRF))
660 					*df_type = DF_TYPE_DRF;
661 					else if (!strcmp(purpose_oid,
662 						NTFS_EFS_CERT_PURPOSE_OID_DDF))
663 						*df_type = DF_TYPE_DDF;
664 					else
665 						oid_index++;
666 				}
667 			} while (!err && (*df_type == DF_TYPE_UNKNOWN));
668 			if (*df_type == DF_TYPE_UNKNOWN) {
669 				/* End of list reached ? */
670 				if (err
671 				    == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
672 					ntfs_log_error("Key does not have an "
673 						"EFS purpose OID\n");
674 				else
675 					ntfs_log_error("Failed to get a key "
676 							"purpose OID : %s ",
677 							gnutls_strerror(err));
678 				goto err;
679 			}
680 			/* Return the thumbprint to the caller. */
681 			err = gnutls_x509_crt_get_fingerprint(crt,
682 					GNUTLS_DIG_SHA1, thumbprint, &tp_size);
683 			if (err) {
684 				ntfs_log_error("Failed to get thumbprint: "
685 						"%s\n", gnutls_strerror(err));
686 				goto err;
687 			}
688 			if (tp_size != NTFS_SHA1_THUMBPRINT_SIZE) {
689 				ntfs_log_error("Invalid thumbprint size %zd.  "
690 						"Should be %d.\n", tp_size,
691 						thumbprint_size);
692 				err = EINVAL;
693 				goto err;
694 			}
695 			have_thumbprint = TRUE;
696 			gnutls_x509_crt_deinit(crt);
697 			crt = NULL;
698 			break;
699 		default:
700 			/* We do not care about other types. */
701 			break;
702 		}
703 		gnutls_pkcs12_bag_deinit(bag);
704 	}
705 err:
706 	if (rsa_key && (err || *df_type == DF_TYPE_UNKNOWN ||
707 			!have_thumbprint)) {
708 		if (!err)
709 			ntfs_log_error("Key type or thumbprint not found, "
710 					"aborting.\n");
711 		ntfs_rsa_private_key_release(rsa_key);
712 		rsa_key = NULL;
713 	}
714 	if (crt)
715 		gnutls_x509_crt_deinit(crt);
716 	if (pkey)
717 		gnutls_x509_privkey_deinit(pkey);
718 	if (bag)
719 		gnutls_pkcs12_bag_deinit(bag);
720 	if (pkcs12)
721 		gnutls_pkcs12_deinit(pkcs12);
722 	return rsa_key;
723 }
724 
725 /**
726  * ntfs_buffer_reverse -
727  *
728  * This is a utility function for reversing the order of a buffer in place.
729  * Users of this function should be very careful not to sweep byte order
730  * problems under the rug.
731  */
ntfs_buffer_reverse(u8 * buf,unsigned buf_size)732 static inline void ntfs_buffer_reverse(u8 *buf, unsigned buf_size)
733 {
734 	unsigned i;
735 	u8 t;
736 
737 	for (i = 0; i < buf_size / 2; i++) {
738 		t = buf[i];
739 		buf[i] = buf[buf_size - i - 1];
740 		buf[buf_size - i - 1] = t;
741 	}
742 }
743 
744 #ifndef HAVE_STRNLEN
745 /**
746  * strnlen - strnlen is a gnu extension so emulate it if not present
747  */
strnlen(const char * s,size_t maxlen)748 static size_t strnlen(const char *s, size_t maxlen)
749 {
750 	const char *p, *end;
751 
752 	/* Look for a '\0' character. */
753 	for (p = s, end = s + maxlen; p < end && *p; p++)
754 		;
755 	return p - s;
756 }
757 #endif /* ! HAVE_STRNLEN */
758 
759 /**
760  * ntfs_raw_fek_decrypt -
761  *
762  * Note: decrypting into the input buffer.
763  */
ntfs_raw_fek_decrypt(u8 * fek,u32 fek_size,ntfs_rsa_private_key rsa_key)764 static unsigned ntfs_raw_fek_decrypt(u8 *fek, u32 fek_size,
765 		ntfs_rsa_private_key rsa_key)
766 {
767 	gcry_mpi_t fek_mpi;
768 	gcry_sexp_t fek_sexp, fek_sexp2;
769 	gcry_error_t err;
770 	size_t size, padding;
771 
772 	/* Reverse the raw FEK. */
773 	ntfs_buffer_reverse(fek, fek_size);
774 	/* Convert the FEK to internal MPI format. */
775 	err = gcry_mpi_scan(&fek_mpi, GCRYMPI_FMT_USG, fek, fek_size, NULL);
776 	if (err != GPG_ERR_NO_ERROR) {
777 		ntfs_log_error("Failed to convert file encryption key to "
778 				"internal MPI format: %s\n",
779 				gcry_strerror(err));
780 		return 0;
781 	}
782 	/* Create an internal S-expression from the FEK. */
783 	err = gcry_sexp_build(&fek_sexp, NULL,
784 			"(enc-val (flags) (rsa (a %m)))", fek_mpi);
785 	gcry_mpi_release(fek_mpi);
786 	if (err != GPG_ERR_NO_ERROR) {
787 		ntfs_log_error("Failed to create internal S-expression of "
788 				"the file encryption key: %s\n",
789 				gcry_strerror(err));
790 		return 0;
791 	}
792 	/* Decrypt the FEK. */
793 	err = gcry_pk_decrypt(&fek_sexp2, fek_sexp, (gcry_sexp_t)rsa_key);
794 	gcry_sexp_release(fek_sexp);
795 	if (err != GPG_ERR_NO_ERROR) {
796 		ntfs_log_error("Failed to decrypt the file encryption key: "
797 				"%s\n", gcry_strerror(err));
798 		return 0;
799 	}
800 	/* Extract the actual FEK from the decrypted raw S-expression. */
801 	fek_sexp = gcry_sexp_find_token(fek_sexp2, "value", 0);
802 	gcry_sexp_release(fek_sexp2);
803 	if (!fek_sexp) {
804 		ntfs_log_error("Failed to find the decrypted file encryption "
805 				"key in the internal S-expression.\n");
806 		return 0;
807 	}
808 	/* Convert the decrypted FEK S-expression into MPI format. */
809 	fek_mpi = gcry_sexp_nth_mpi(fek_sexp, 1, GCRYMPI_FMT_USG);
810 	gcry_sexp_release(fek_sexp);
811 	if (!fek_mpi) {
812 		ntfs_log_error("Failed to convert the decrypted file "
813 				"encryption key S-expression to internal MPI "
814 				"format.\n");
815 		return 0;
816 	}
817 	/* Convert the decrypted FEK from MPI format to binary data. */
818 	err = gcry_mpi_print(GCRYMPI_FMT_USG, fek, fek_size, &size, fek_mpi);
819 	gcry_mpi_release(fek_mpi);
820 	if (err != GPG_ERR_NO_ERROR || !size) {
821 		ntfs_log_error("Failed to convert decrypted file encryption "
822 				"key from internal MPI format to binary data: "
823 				"%s\n", gcry_strerror(err));
824 		return 0;
825 	}
826 	/*
827 	 * Finally, remove the PKCS#1 padding and return the size of the
828 	 * decrypted FEK.
829 	 */
830 	padding = strnlen((char *)fek, size) + 1;
831 	if (padding > size) {
832 		ntfs_log_error("Failed to remove PKCS#1 padding from "
833 				"decrypted file encryption key.\n");
834 		return 0;
835 	}
836 	size -= padding;
837 	memmove(fek, fek + padding, size);
838 	return size;
839 }
840 
841 /**
842  * ntfs_desx_key_expand - expand a 128-bit desx key to the needed 192-bit key
843  * @src:	source buffer containing 128-bit key
844  *
845  * Expands the on-disk 128-bit desx key to the needed des key, the in-, and the
846  * out-whitening keys required to perform desx {de,en}cryption.
847  */
ntfs_desx_key_expand(const u8 * src,u32 * des_key,u64 * out_whitening,u64 * in_whitening)848 static gcry_error_t ntfs_desx_key_expand(const u8 *src, u32 *des_key,
849 		u64 *out_whitening, u64 *in_whitening)
850 {
851 	static const u8 *salt1 = (const u8*)"Dan Simon  ";
852 	static const u8 *salt2 = (const u8*)"Scott Field";
853 	static const int salt_len = 12;
854 	gcry_md_hd_t hd1, hd2;
855 	u32 *md;
856 	gcry_error_t err;
857 
858 	err = gcry_md_open(&hd1, GCRY_MD_MD5, 0);
859 	if (err != GPG_ERR_NO_ERROR) {
860 		ntfs_log_error("Failed to open MD5 digest.\n");
861 		return err;
862 	}
863 	/* Hash the on-disk key. */
864 	gcry_md_write(hd1, src, 128 / 8);
865 	/* Copy the current hash for efficiency. */
866 	err = gcry_md_copy(&hd2, hd1);
867 	if (err != GPG_ERR_NO_ERROR) {
868 		ntfs_log_error("Failed to copy MD5 digest object.\n");
869 		goto out;
870 	}
871 	/* Hash with the first salt and store the result. */
872 	gcry_md_write(hd1, salt1, salt_len);
873 	md = (u32*)gcry_md_read(hd1, 0);
874 	des_key[0] = md[0] ^ md[1];
875 	des_key[1] = md[2] ^ md[3];
876 	/* Hash with the second salt and store the result. */
877 	gcry_md_write(hd2, salt2, salt_len);
878 	md = (u32*)gcry_md_read(hd2, 0);
879 	*out_whitening = *(u64*)md;
880 	*in_whitening = *(u64*)(md + 2);
881 	gcry_md_close(hd2);
882 out:
883 	gcry_md_close(hd1);
884 	return err;
885 }
886 
887 /**
888  * ntfs_desx_decrypt
889  */
ntfs_desx_decrypt(ntfs_fek * fek,u8 * outbuf,const u8 * inbuf)890 static gcry_error_t ntfs_desx_decrypt(ntfs_fek *fek, u8 *outbuf,
891 				const u8 *inbuf)
892 {
893 	gcry_error_t err;
894 	u64 curr_blk;
895 	ntfs_desx_ctx *ctx = &fek->desx_ctx;
896 
897 	curr_blk = *(const u64*)inbuf;
898 	*(u64*)outbuf = curr_blk ^ ctx->out_whitening;
899 	err = gcry_cipher_encrypt(fek->gcry_cipher_hd, outbuf, 8, NULL, 0);
900 	if (err != GPG_ERR_NO_ERROR)
901 		ntfs_log_error("Des decryption failed (error 0x%x).\n", err);
902 	*(u64*)outbuf ^= ctx->in_whitening ^ ctx->prev_blk;
903 	ctx->prev_blk = curr_blk;
904 	return (err);
905 }
906 
907 /**
908  * ntfs_desx_encrypt
909  */
ntfs_desx_encrypt(ntfs_fek * fek,u8 * outbuf,const u8 * inbuf)910 static gcry_error_t ntfs_desx_encrypt(ntfs_fek *fek, u8 *outbuf,
911 				const u8 *inbuf)
912 {
913 	gcry_error_t err;
914 	ntfs_desx_ctx *ctx = &fek->desx_ctx;
915 
916 	*(u64*)outbuf = *(const u64*)inbuf ^ ctx->in_whitening ^ ctx->prev_blk;
917 	err = gcry_cipher_decrypt(fek->gcry_cipher_hd, outbuf, 8, NULL, 0);
918 	if (err != GPG_ERR_NO_ERROR)
919 		ntfs_log_error("Des decryption failed (error 0x%x).\n", err);
920 	*(u64*)outbuf ^= ctx->out_whitening;
921 	ctx->prev_blk = *(u64*)outbuf;
922 	return (err);
923 }
924 
925 //#define DO_CRYPTO_TESTS 1
926 
927 #ifdef DO_CRYPTO_TESTS
928 
929 /* Do not remove this test code from this file! AIA */
930 /**
931  * ntfs_desx_key_expand_test
932  */
ntfs_desx_key_expand_test(void)933 static BOOL ntfs_desx_key_expand_test(void)
934 {
935 	const u8 known_desx_on_disk_key[16] = {
936 		0xa1, 0xf9, 0xe0, 0xb2, 0x53, 0x23, 0x9e, 0x8f,
937 		0x0f, 0x91, 0x45, 0xd9, 0x8e, 0x20, 0xec, 0x30
938 	};
939 	const u8 known_des_key[8] = {
940 		0x27, 0xd1, 0x93, 0x09, 0xcb, 0x78, 0x93, 0x1f,
941 	};
942 	const u8 known_out_whitening[8] = {
943 		0xed, 0xda, 0x4c, 0x47, 0x60, 0x49, 0xdb, 0x8d,
944 	};
945 	const u8 known_in_whitening[8] = {
946 		0x75, 0xf6, 0xa0, 0x1a, 0xc0, 0xca, 0x28, 0x1e
947 	};
948 	u64 test_out_whitening, test_in_whitening;
949 	union {
950 		u64 u64;
951 		u32 u32[2];
952 	} test_des_key;
953 	gcry_error_t err;
954 	BOOL res;
955 
956 	err = ntfs_desx_key_expand(known_desx_on_disk_key, test_des_key.u32,
957 			&test_out_whitening, &test_in_whitening);
958 	if (err != GPG_ERR_NO_ERROR)
959 		res = FALSE;
960 	else
961 		res = test_des_key.u64 == *(u64*)known_des_key &&
962 				test_out_whitening ==
963 				*(u64*)known_out_whitening &&
964 				test_in_whitening ==
965 				*(u64*)known_in_whitening;
966 	ntfs_log_error("Testing whether ntfs_desx_key_expand() works: %s\n",
967 			res ? "SUCCESS" : "FAILED");
968 	return res;
969 }
970 
971 /**
972  * ntfs_des_test
973  */
ntfs_des_test(void)974 static BOOL ntfs_des_test(void)
975 {
976 	const u8 known_des_key[8] = {
977 		0x27, 0xd1, 0x93, 0x09, 0xcb, 0x78, 0x93, 0x1f
978 	};
979 	const u8 known_des_encrypted_data[8] = {
980 		0xdc, 0xf7, 0x68, 0x2a, 0xaf, 0x48, 0x53, 0x0f
981 	};
982 	const u8 known_decrypted_data[8] = {
983 		0xd8, 0xd9, 0x15, 0x23, 0x5b, 0x88, 0x0e, 0x09
984 	};
985 	u8 test_decrypted_data[8];
986 	int res;
987 	gcry_error_t err;
988 	gcry_cipher_hd_t gcry_cipher_hd;
989 
990 	err = gcry_cipher_open(&gcry_cipher_hd, GCRY_CIPHER_DES,
991 			GCRY_CIPHER_MODE_ECB, 0);
992 	if (err != GPG_ERR_NO_ERROR) {
993 		ntfs_log_error("Failed to open des cipher (error 0x%x).\n",
994 				err);
995 		return FALSE;
996 	}
997 	err = gcry_cipher_setkey(gcry_cipher_hd, known_des_key,
998 			sizeof(known_des_key));
999 	if (err != GPG_ERR_NO_ERROR) {
1000 		ntfs_log_error("Failed to set des key (error 0x%x.\n", err);
1001 		gcry_cipher_close(gcry_cipher_hd);
1002 		return FALSE;
1003 	}
1004 	/*
1005 	 * Apply DES decryption (ntfs actually uses encryption when decrypting).
1006 	 */
1007 	err = gcry_cipher_encrypt(gcry_cipher_hd, test_decrypted_data,
1008 			sizeof(test_decrypted_data), known_des_encrypted_data,
1009 			sizeof(known_des_encrypted_data));
1010 	gcry_cipher_close(gcry_cipher_hd);
1011 	if (err) {
1012 		ntfs_log_error("Failed to des decrypt test data (error "
1013 				"0x%x).\n", err);
1014 		return FALSE;
1015 	}
1016 	res = !memcmp(test_decrypted_data, known_decrypted_data,
1017 			sizeof(known_decrypted_data));
1018 	ntfs_log_error("Testing whether des decryption works: %s\n",
1019 			res ? "SUCCESS" : "FAILED");
1020 	return res;
1021 }
1022 
1023 #else /* !defined(DO_CRYPTO_TESTS) */
1024 
1025 /**
1026  * ntfs_desx_key_expand_test
1027  */
ntfs_desx_key_expand_test(void)1028 static inline BOOL ntfs_desx_key_expand_test(void)
1029 {
1030 	return TRUE;
1031 }
1032 
1033 /**
1034  * ntfs_des_test
1035  */
ntfs_des_test(void)1036 static inline BOOL ntfs_des_test(void)
1037 {
1038 	return TRUE;
1039 }
1040 
1041 #endif /* !defined(DO_CRYPTO_TESTS) */
1042 
1043 /**
1044  * ntfs_fek_import_from_raw
1045  */
ntfs_fek_import_from_raw(u8 * fek_buf,unsigned fek_size)1046 static ntfs_fek *ntfs_fek_import_from_raw(u8 *fek_buf, unsigned fek_size)
1047 {
1048 	ntfs_fek *fek;
1049 	u32 key_size, wanted_key_size, gcry_algo;
1050 	int gcry_mode;
1051 	gcry_error_t err;
1052 	ntfs_desx_ctx *ctx;
1053 
1054 	key_size = le32_to_cpup((le32*) fek_buf);
1055 	ntfs_log_debug("key_size 0x%x\n", key_size);
1056 	if (key_size + 16 > fek_size) {
1057 		ntfs_log_debug("Invalid FEK.  It was probably decrypted with "
1058 				"the incorrect RSA key.");
1059 		errno = EINVAL;
1060 		return NULL;
1061 	}
1062 	fek = malloc(((((sizeof(*fek) + 7) & ~7) + key_size + 7) & ~7) +
1063 			sizeof(gcry_cipher_hd_t));
1064 	if (!fek) {
1065 		errno = ENOMEM;
1066 		return NULL;
1067 	}
1068 	ctx = &fek->desx_ctx;
1069 	fek->alg_id = *(le32*)(fek_buf + 8);
1070 	//ntfs_log_debug("alg_id 0x%x\n", le32_to_cpu(fek->alg_id));
1071 	fek->key_data = (u8*)fek + ((sizeof(*fek) + 7) & ~7);
1072 	memcpy(fek->key_data, fek_buf + 16, key_size);
1073 	fek->des_gcry_cipher_hd_ptr = NULL;
1074 	*(gcry_cipher_hd_t***)(fek->key_data + ((key_size + 7) & ~7)) =
1075 			&fek->des_gcry_cipher_hd_ptr;
1076 	switch (fek->alg_id) {
1077 	case CALG_DESX:
1078 		wanted_key_size = 16;
1079 		gcry_algo = GCRY_CIPHER_DES;
1080 		gcry_mode = GCRY_CIPHER_MODE_ECB;
1081 		break;
1082 	case CALG_3DES:
1083 		wanted_key_size = 24;
1084 		gcry_algo = GCRY_CIPHER_3DES;
1085 		gcry_mode = GCRY_CIPHER_MODE_CBC;
1086 		break;
1087 	case CALG_AES_256:
1088 		wanted_key_size = 32;
1089 		gcry_algo = GCRY_CIPHER_AES256;
1090 		gcry_mode = GCRY_CIPHER_MODE_CBC;
1091 		break;
1092 	default:
1093 		wanted_key_size = 8;
1094 		gcry_algo = GCRY_CIPHER_DES;
1095 		gcry_mode = GCRY_CIPHER_MODE_CBC;
1096 		if (fek->alg_id == CALG_DES)
1097 			ntfs_log_error("DES is not supported at present\n");
1098 		else
1099 			ntfs_log_error("Unknown crypto algorithm 0x%x\n",
1100 					le32_to_cpu(fek->alg_id));
1101 		ntfs_log_error(".  Please email %s and say that you saw this "
1102 				"message.  We will then try to implement "
1103 				"support for this algorithm.\n", NTFS_DEV_LIST);
1104 		err = EOPNOTSUPP;
1105 		goto out;
1106 	}
1107 	if (key_size != wanted_key_size) {
1108 		ntfs_log_error("%s key of %u bytes but needed size is %u "
1109 				"bytes, assuming corrupt or incorrect key.  "
1110 				"Aborting.\n",
1111 				gcry_cipher_algo_name(gcry_algo),
1112 				(unsigned)key_size, (unsigned)wanted_key_size);
1113 		err = EIO;
1114 		goto out;
1115 	}
1116 	err = gcry_cipher_open(&fek->gcry_cipher_hd, gcry_algo,
1117 				gcry_mode, 0);
1118 
1119 	if (err != GPG_ERR_NO_ERROR) {
1120 		ntfs_log_error("gcry_cipher_open() failed: %s\n",
1121 				gcry_strerror(err));
1122 		err = EINVAL;
1123 		goto out;
1124 	}
1125 	if (fek->alg_id == CALG_DESX) {
1126 		err = ntfs_desx_key_expand(fek->key_data, (u32*)ctx->des_key,
1127 				&ctx->out_whitening, &ctx->in_whitening);
1128 		if (err == GPG_ERR_NO_ERROR)
1129 			err = gcry_cipher_setkey(fek->gcry_cipher_hd,
1130 							ctx->des_key, 8);
1131 	} else {
1132 		err = gcry_cipher_setkey(fek->gcry_cipher_hd, fek->key_data,
1133 							key_size);
1134 	}
1135 	if (err != GPG_ERR_NO_ERROR) {
1136 		ntfs_log_error("gcry_cipher_setkey() failed: %s\n",
1137 				gcry_strerror(err));
1138 		gcry_cipher_close(fek->gcry_cipher_hd);
1139 		err = EINVAL;
1140 		goto out;
1141 	}
1142 	return fek;
1143 out:
1144 	free(fek);
1145 	errno = err;
1146 	return NULL;
1147 }
1148 
1149 /**
1150  * ntfs_fek_release
1151  */
ntfs_fek_release(ntfs_fek * fek)1152 static void ntfs_fek_release(ntfs_fek *fek)
1153 {
1154 	if (fek->des_gcry_cipher_hd_ptr)
1155 		gcry_cipher_close(*fek->des_gcry_cipher_hd_ptr);
1156 	gcry_cipher_close(fek->gcry_cipher_hd);
1157 	free(fek);
1158 }
1159 
1160 /**
1161  * ntfs_df_array_fek_get
1162  */
ntfs_df_array_fek_get(EFS_DF_ARRAY_HEADER * df_array,ntfs_rsa_private_key rsa_key,char * thumbprint,int thumbprint_size)1163 static ntfs_fek *ntfs_df_array_fek_get(EFS_DF_ARRAY_HEADER *df_array,
1164 		ntfs_rsa_private_key rsa_key, char *thumbprint,
1165 		int thumbprint_size)
1166 {
1167 	EFS_DF_HEADER *df_header;
1168 	EFS_DF_CREDENTIAL_HEADER *df_cred;
1169 	EFS_DF_CERT_THUMBPRINT_HEADER *df_cert;
1170 	u8 *fek_buf;
1171 	ntfs_fek *fek;
1172 	u32 df_count, fek_size;
1173 	unsigned i;
1174 
1175 	df_count = le32_to_cpu(df_array->df_count);
1176 	if (!df_count)
1177 		ntfs_log_error("There are no elements in the DF array.\n");
1178 	df_header = (EFS_DF_HEADER*)(df_array + 1);
1179 	for (i = 0; i < df_count; i++, df_header = (EFS_DF_HEADER*)(
1180 			(u8*)df_header + le32_to_cpu(df_header->df_length))) {
1181 		df_cred = (EFS_DF_CREDENTIAL_HEADER*)((u8*)df_header +
1182 				le32_to_cpu(df_header->cred_header_offset));
1183 		if (df_cred->type != NTFS_CRED_TYPE_CERT_THUMBPRINT) {
1184 			ntfs_log_debug("Credential type is not certificate "
1185 					"thumbprint, skipping DF entry.\n");
1186 			continue;
1187 		}
1188 		df_cert = (EFS_DF_CERT_THUMBPRINT_HEADER*)((u8*)df_cred +
1189 				le32_to_cpu(
1190 				df_cred->cert_thumbprint_header_offset));
1191 		if ((int)le32_to_cpu(df_cert->thumbprint_size)
1192 						!= thumbprint_size) {
1193 			ntfs_log_error("Thumbprint size %d is not valid "
1194 					"(should be %d), skipping this DF "
1195 					"entry.\n",
1196 					le32_to_cpu(df_cert->thumbprint_size),
1197 					thumbprint_size);
1198 			continue;
1199 		}
1200 		if (memcmp((u8*)df_cert +
1201 				le32_to_cpu(df_cert->thumbprint_offset),
1202 				thumbprint, thumbprint_size)) {
1203 			ntfs_log_debug("Thumbprints do not match, skipping "
1204 					"this DF entry.\n");
1205 			continue;
1206 		}
1207 		/*
1208 		 * The thumbprints match so this is probably the DF entry
1209 		 * matching the RSA key.  Try to decrypt the FEK with it.
1210 		 */
1211 		fek_size = le32_to_cpu(df_header->fek_size);
1212 		fek_buf = (u8*)df_header + le32_to_cpu(df_header->fek_offset);
1213 		/* Decrypt the FEK.  Note: This is done in place. */
1214 		fek_size = ntfs_raw_fek_decrypt(fek_buf, fek_size, rsa_key);
1215 		if (fek_size) {
1216 			/* Convert the FEK to our internal format. */
1217 			fek = ntfs_fek_import_from_raw(fek_buf, fek_size);
1218 			if (fek)
1219 				return fek;
1220 			ntfs_log_error("Failed to convert the decrypted file "
1221 					"encryption key to internal format.\n");
1222 		} else
1223 			ntfs_log_error("Failed to decrypt the file "
1224 					"encryption key.\n");
1225 	}
1226 	return NULL;
1227 }
1228 
1229 /**
1230  * ntfs_inode_fek_get -
1231  */
ntfs_inode_fek_get(ntfs_inode * inode,ntfs_rsa_private_key rsa_key,char * thumbprint,int thumbprint_size,NTFS_DF_TYPES df_type)1232 static ntfs_fek *ntfs_inode_fek_get(ntfs_inode *inode,
1233 		ntfs_rsa_private_key rsa_key, char *thumbprint,
1234 		int thumbprint_size, NTFS_DF_TYPES df_type)
1235 {
1236 	EFS_ATTR_HEADER *efs;
1237 	EFS_DF_ARRAY_HEADER *df_array = NULL;
1238 	ntfs_fek *fek = NULL;
1239 
1240 	/* Obtain the $EFS contents. */
1241 	efs = ntfs_attr_readall(inode, AT_LOGGED_UTILITY_STREAM, EFS, 4, NULL);
1242 	if (!efs) {
1243 		ntfs_log_perror("Failed to read $EFS attribute");
1244 		return NULL;
1245 	}
1246 	/*
1247 	 * Depending on whether the key is a normal key or a data recovery key,
1248 	 * iterate through the DDF or DRF array, respectively.
1249 	 */
1250 	if (df_type == DF_TYPE_DDF) {
1251 		if (efs->offset_to_ddf_array)
1252 			df_array = (EFS_DF_ARRAY_HEADER*)((u8*)efs +
1253 					le32_to_cpu(efs->offset_to_ddf_array));
1254 		else
1255 			ntfs_log_error("There are no entries in the DDF "
1256 					"array.\n");
1257 	} else if (df_type == DF_TYPE_DRF) {
1258 		if (efs->offset_to_drf_array)
1259 			df_array = (EFS_DF_ARRAY_HEADER*)((u8*)efs +
1260 					le32_to_cpu(efs->offset_to_drf_array));
1261 		else
1262 			ntfs_log_error("There are no entries in the DRF "
1263 					"array.\n");
1264 	} else
1265 		ntfs_log_error("Invalid DF type.\n");
1266 	if (df_array)
1267 		fek = ntfs_df_array_fek_get(df_array, rsa_key, thumbprint,
1268 				thumbprint_size);
1269 	free(efs);
1270 	return fek;
1271 }
1272 
1273 /**
1274  * ntfs_fek_decrypt_sector
1275  */
ntfs_fek_decrypt_sector(ntfs_fek * fek,u8 * data,const u64 offset)1276 static int ntfs_fek_decrypt_sector(ntfs_fek *fek, u8 *data, const u64 offset)
1277 {
1278 	gcry_error_t err;
1279 
1280 	err = gcry_cipher_reset(fek->gcry_cipher_hd);
1281 	if (err != GPG_ERR_NO_ERROR) {
1282 		ntfs_log_error("Failed to reset cipher: %s\n",
1283 				gcry_strerror(err));
1284 		return -1;
1285 	}
1286 	/*
1287 	 * Note: You may wonder why we are not calling gcry_cipher_setiv() here
1288 	 * instead of doing it by hand after the decryption.  The answer is
1289 	 * that gcry_cipher_setiv() wants an iv of length 8 bytes but we give
1290 	 * it a length of 16 for AES256 so it does not like it.
1291 	 */
1292 	if (fek->alg_id == CALG_DESX) {
1293 		int k;
1294 
1295 		fek->desx_ctx.prev_blk = 0;
1296 		for (k=0; (k < 512) && (err == GPG_ERR_NO_ERROR); k+=8) {
1297 			err = ntfs_desx_decrypt(fek, &data[k], &data[k]);
1298 		}
1299 	} else
1300 		err = gcry_cipher_decrypt(fek->gcry_cipher_hd, data, 512, NULL, 0);
1301 	if (err != GPG_ERR_NO_ERROR) {
1302 		ntfs_log_error("Decryption failed: %s\n", gcry_strerror(err));
1303 		return -1;
1304 	}
1305 	/* Apply the IV. */
1306 	if (fek->alg_id == CALG_AES_256) {
1307 		((le64*)data)[0] ^= cpu_to_le64(0x5816657be9161312ULL + offset);
1308 		((le64*)data)[1] ^= cpu_to_le64(0x1989adbe44918961ULL + offset);
1309 	} else {
1310 		/* All other algos (Des, 3Des, DesX) use the same IV. */
1311 		((le64*)data)[0] ^= cpu_to_le64(0x169119629891ad13ULL + offset);
1312 	}
1313 	return 512;
1314 }
1315 
1316 /**
1317  * ntfs_fek_encrypt_sector
1318  */
ntfs_fek_encrypt_sector(ntfs_fek * fek,u8 * data,const u64 offset)1319 static int ntfs_fek_encrypt_sector(ntfs_fek *fek, u8 *data, const u64 offset)
1320 {
1321 	gcry_error_t err;
1322 
1323 	err = gcry_cipher_reset(fek->gcry_cipher_hd);
1324 	if (err != GPG_ERR_NO_ERROR) {
1325 		ntfs_log_error("Failed to reset cipher: %s\n",
1326 				gcry_strerror(err));
1327 		return -1;
1328 	}
1329 	/*
1330 	 * Note: You may wonder why we are not calling gcry_cipher_setiv() here
1331 	 * instead of doing it by hand after the decryption.  The answer is
1332 	 * that gcry_cipher_setiv() wants an iv of length 8 bytes but we give
1333 	 * it a length of 16 for AES256 so it does not like it.
1334 	 */
1335 	/* Apply the IV. */
1336 	if (fek->alg_id == CALG_AES_256) {
1337 		((le64*)data)[0] ^= cpu_to_le64(0x5816657be9161312ULL + offset);
1338 		((le64*)data)[1] ^= cpu_to_le64(0x1989adbe44918961ULL + offset);
1339 	} else {
1340 		/* All other algos (Des, 3Des, DesX) use the same IV. */
1341 		((le64*)data)[0] ^= cpu_to_le64(0x169119629891ad13ULL + offset);
1342 	}
1343 	if (fek->alg_id == CALG_DESX) {
1344 		int k;
1345 
1346 		fek->desx_ctx.prev_blk = 0;
1347 		for (k=0; (k < 512) && (err == GPG_ERR_NO_ERROR); k+=8) {
1348 			err = ntfs_desx_encrypt(fek, &data[k], &data[k]);
1349 		}
1350 	} else
1351 		err = gcry_cipher_encrypt(fek->gcry_cipher_hd, data, 512, NULL, 0);
1352 	if (err != GPG_ERR_NO_ERROR) {
1353 		ntfs_log_error("Encryption failed: %s\n", gcry_strerror(err));
1354 		return -1;
1355 	}
1356 	return 512;
1357 }
1358 
1359 /**
1360  * ntfs_cat_decrypt - Decrypt the contents of an encrypted file to stdout.
1361  * @inode:	An encrypted file's inode structure, as obtained by
1362  * 		ntfs_inode_open().
1363  * @fek:	A file encryption key. As obtained by ntfs_inode_fek_get().
1364  */
ntfs_cat_decrypt(ntfs_inode * inode,ntfs_fek * fek)1365 static int ntfs_cat_decrypt(ntfs_inode *inode, ntfs_fek *fek)
1366 {
1367 	int bufsize = 512;
1368 	unsigned char *buffer;
1369 	ntfs_attr *attr;
1370 	s64 bytes_read, written, offset, total;
1371 	s64 old_data_size, old_initialized_size;
1372 	int i;
1373 
1374 	buffer = malloc(bufsize);
1375 	if (!buffer)
1376 		return 1;
1377 	attr = ntfs_attr_open(inode, AT_DATA, NULL, 0);
1378 	if (!attr) {
1379 		ntfs_log_error("Cannot cat a directory.\n");
1380 		free(buffer);
1381 		return 1;
1382 	}
1383 	total = attr->data_size;
1384 
1385 	// hack: make sure attr will not be commited to disk if you use this.
1386 	// clear the encrypted bit, otherwise the library won't allow reading.
1387 	NAttrClearEncrypted(attr);
1388 	// extend the size, we may need to read past the end of the stream.
1389 	old_data_size = attr->data_size;
1390 	old_initialized_size = attr->initialized_size;
1391 	attr->data_size = attr->initialized_size = attr->allocated_size;
1392 
1393 	offset = 0;
1394 	while (total > 0) {
1395 		bytes_read = ntfs_attr_pread(attr, offset, 512, buffer);
1396 		if (bytes_read == -1) {
1397 			ntfs_log_perror("ERROR: Couldn't read file");
1398 			break;
1399 		}
1400 		if (!bytes_read)
1401 			break;
1402 		if ((i = ntfs_fek_decrypt_sector(fek, buffer, offset)) <
1403 				bytes_read) {
1404 			ntfs_log_perror("ERROR: Couldn't decrypt all data!");
1405 			ntfs_log_error("%u/%lld/%lld/%lld\n", i,
1406 				(long long)bytes_read, (long long)offset,
1407 				(long long)total);
1408 			break;
1409 		}
1410 		if (bytes_read > total)
1411 			bytes_read = total;
1412 		written = fwrite(buffer, 1, bytes_read, stdout);
1413 		if (written != bytes_read) {
1414 			ntfs_log_perror("ERROR: Couldn't output all data!");
1415 			break;
1416 		}
1417 		offset += bytes_read;
1418 		total -= bytes_read;
1419 	}
1420 	attr->data_size = old_data_size;
1421 	attr->initialized_size = old_initialized_size;
1422 	NAttrSetEncrypted(attr);
1423 	ntfs_attr_close(attr);
1424 	free(buffer);
1425 	return 0;
1426 }
1427 
1428 /**
1429  * ntfs_feed_encrypt - Encrypt the contents of stdin to an encrypted file
1430  * @inode:	An encrypted file's inode structure, as obtained by
1431  * 		ntfs_inode_open().
1432  * @fek:	A file encryption key. As obtained by ntfs_inode_fek_get().
1433  */
ntfs_feed_encrypt(ntfs_inode * inode,ntfs_fek * fek)1434 static int ntfs_feed_encrypt(ntfs_inode *inode, ntfs_fek *fek)
1435 {
1436 	const int bufsize = 512;
1437 	unsigned char *buffer;
1438 	ntfs_attr *attr;
1439 	s64 bytes_read, written, offset, total;
1440 	unsigned char *b;
1441 	long val;
1442 	int count;
1443 	int i;
1444 
1445 	buffer = (unsigned char*)malloc(bufsize);
1446 	if (!buffer)
1447 		return 1;
1448 	attr = ntfs_attr_open(inode, AT_DATA, NULL, 0);
1449 	if (!attr) {
1450 		ntfs_log_error("Cannot feed into a directory.\n");
1451 		goto rejected;
1452 	}
1453 	total = 0;
1454 
1455 	if (!(attr->data_flags & ATTR_IS_ENCRYPTED)) {
1456 		ntfs_log_error("The data stream was not encrypted\n");
1457 		goto rejected;
1458 	}
1459 	inode->vol->efs_raw = TRUE;
1460 
1461 	if (ntfs_attr_truncate(attr, 0)) {
1462 		ntfs_log_error("Failed to truncate the data stream\n");
1463 		goto rejected;
1464 	}
1465 	offset = 0;
1466 	do {
1467 		bytes_read = fread(buffer, 1, bufsize, stdin);
1468 		if (bytes_read <= 0) {
1469 			if (bytes_read < 0)
1470 				ntfs_log_perror("ERROR: Couldn't read data");
1471 		} else {
1472 			if (bytes_read < bufsize) {
1473 				/* Fill with random data */
1474 				srandom((unsigned int)(sle64_to_cpu(
1475 					inode->last_data_change_time)
1476 					/100000000));
1477 				count = bufsize - bytes_read;
1478 				b = &buffer[bytes_read];
1479 				do {
1480 					val = random();
1481 					switch (count) {
1482 						default :
1483 							*b++ = val;
1484 							val >>= 8;
1485 							/* FALLTHRU */
1486 						case 3 :
1487 							*b++ = val;
1488 							val >>= 8;
1489 							/* FALLTHRU */
1490 						case 2 :
1491 							*b++ = val;
1492 							val >>= 8;
1493 							/* FALLTHRU */
1494 						case 1 :
1495 							*b++ = val;
1496 							val >>= 8;
1497 					}
1498 					count -= 4;
1499 				} while (count > 0);
1500 			}
1501 			if ((i = ntfs_fek_encrypt_sector(fek, buffer, offset))
1502 					< bufsize) {
1503 				ntfs_log_perror("ERROR: Couldn't encrypt all data!");
1504 				ntfs_log_error("%u/%lld/%lld/%lld\n", i,
1505 					(long long)bytes_read, (long long)offset,
1506 					(long long)total);
1507 				break;
1508 			}
1509 		written = ntfs_attr_pwrite(attr, offset, bufsize, buffer);
1510 		if (written != bufsize) {
1511 			ntfs_log_perror("ERROR: Couldn't output all data!");
1512 			break;
1513 		}
1514 		offset += bufsize;
1515 		total += bytes_read;
1516 		}
1517 	} while (bytes_read == bufsize);
1518 	ntfs_attr_truncate(attr, total);
1519 	inode->last_data_change_time = ntfs_current_time();
1520 	NAttrSetEncrypted(attr);
1521 	ntfs_attr_close(attr);
1522 	free(buffer);
1523 	return 0;
1524 rejected :
1525 	free(buffer);
1526 	return (-1);
1527 }
1528 
1529 /**
1530  * main - Begin here
1531  *
1532  * Start from here.
1533  *
1534  * Return:  0  Success, the program worked
1535  *	    1  Error, something went wrong
1536  */
main(int argc,char * argv[])1537 int main(int argc, char *argv[])
1538 {
1539 	u8 *pfx_buf;
1540 	char *password;
1541 	ntfs_rsa_private_key rsa_key;
1542 	ntfs_volume *vol;
1543 	ntfs_inode *inode;
1544 	ntfs_fek *fek;
1545 	unsigned pfx_size;
1546 	int res;
1547 	NTFS_DF_TYPES df_type;
1548 	char thumbprint[NTFS_SHA1_THUMBPRINT_SIZE];
1549 
1550 	ntfs_log_set_handler(ntfs_log_handler_stderr);
1551 
1552 	res = parse_options(argc, argv);
1553 	if (res >= 0)
1554 		return (res);
1555 	utils_set_locale();
1556 
1557 	/* Initialize crypto in ntfs. */
1558 	if (ntfs_crypto_init()) {
1559 		ntfs_log_error("Failed to initialize crypto.  Aborting.\n");
1560 		return 1;
1561 	}
1562 	/* Load the PKCS#12 (.pfx) file containing the user's private key. */
1563 	if (ntfs_pkcs12_load_pfxfile(opts.keyfile, &pfx_buf, &pfx_size)) {
1564 		ntfs_log_error("Failed to load key file.  Aborting.\n");
1565 		ntfs_crypto_deinit();
1566 		return 1;
1567 	}
1568 	/* Ask the user for their password. */
1569 	password = getpass("Enter the password with which the private key was "
1570 			"encrypted: ");
1571 	if (!password) {
1572 		ntfs_log_perror("Failed to obtain user password");
1573 		free(pfx_buf);
1574 		ntfs_crypto_deinit();
1575 		return 1;
1576 	}
1577 	/* Obtain the user's private RSA key from the key file. */
1578 	rsa_key = ntfs_pkcs12_extract_rsa_key(pfx_buf, pfx_size, password,
1579 			thumbprint, sizeof(thumbprint), &df_type);
1580 	/* Destroy the password. */
1581 	memset(password, 0, strlen(password));
1582 	/* No longer need the pfx file contents. */
1583 	free(pfx_buf);
1584 	if (!rsa_key) {
1585 		ntfs_log_error("Failed to extract the private RSA key.\n");
1586 		ntfs_crypto_deinit();
1587 		return 1;
1588 	}
1589 	/* Mount the ntfs volume. */
1590 	vol = utils_mount_volume(opts.device,
1591 			(opts.encrypt ? 0 :  NTFS_MNT_RDONLY) |
1592 			(opts.force ? NTFS_MNT_RECOVER : 0));
1593 	if (!vol) {
1594 		ntfs_log_error("Failed to mount ntfs volume.  Aborting.\n");
1595 		ntfs_rsa_private_key_release(rsa_key);
1596 		ntfs_crypto_deinit();
1597 		return 1;
1598 	}
1599 	/* Open the encrypted ntfs file. */
1600 	if (opts.inode != -1)
1601 		inode = ntfs_inode_open(vol, opts.inode);
1602 	else
1603 		inode = ntfs_pathname_to_inode(vol, NULL, opts.file);
1604 	if (!inode) {
1605 		ntfs_log_error("Failed to open encrypted file.  Aborting.\n");
1606 		ntfs_umount(vol, FALSE);
1607 		ntfs_rsa_private_key_release(rsa_key);
1608 		ntfs_crypto_deinit();
1609 		return 1;
1610 	}
1611 	/* Obtain the file encryption key of the encrypted file. */
1612 	fek = ntfs_inode_fek_get(inode, rsa_key, thumbprint,
1613 			sizeof(thumbprint), df_type);
1614 	ntfs_rsa_private_key_release(rsa_key);
1615 	if (fek) {
1616 		if (opts.encrypt)
1617 			res = ntfs_feed_encrypt(inode, fek);
1618 		else
1619 			res = ntfs_cat_decrypt(inode, fek);
1620 		ntfs_fek_release(fek);
1621 	} else {
1622 		ntfs_log_error("Failed to obtain file encryption key.  "
1623 				"Aborting.\n");
1624 		res = 1;
1625 	}
1626 	ntfs_inode_close(inode);
1627 	ntfs_umount(vol, FALSE);
1628 	ntfs_crypto_deinit();
1629 	return res;
1630 }
1631