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