237
memset(auth_tok, 0, sizeof(auth_tok));
242
memset(auth_tok, 0, sizeof(*auth_tok));
249
* A wrapper around write(2) that handles short and interrupted writes.
251
* Returns the number of bytes written or -1 with errno set on failure.
253
static ssize_t do_write(int fd, const void *buf, size_t count)
258
ssize_t bytes = write(fd, buf + rc, count - rc);
267
} while (rc < count);
273
* A wrapper around read(2) that handles short and interrupted reads.
275
* Returns the number of bytes read or -1 with errno set on failure.
277
static ssize_t do_read(int fd, void *buf, size_t count)
282
ssize_t bytes = read(fd, buf + rc, count - rc);
286
} else if (bytes == -1) {
294
} while (rc < count);
300
* read_wrapped_passphrase_file_version
301
* @fd: A file descriptor, opened for reading, of a wrapped passphrase file
302
* @version: On success, *version is set to the detected file version
304
* Sets the fd offset to 0 and attempts to determine the version number of the
305
* opened wrapped-passphrase file. If a versioned wrapped-passphrase file is
306
* not found and the first 16 bytes of the file are hex encoded values, then
307
* the version is assumed to be '1'.
309
* Returns 0 on success, sets *version to the determined wrapped-passphrase
310
* file version, and ensures that the fd offset is appropriately set for
311
* reading the next field in the wrapped passphrase file. Returns negative on
312
* error (*version and the fd offset is undefined upon error).
314
static int read_wrapped_passphrase_file_version(int fd, uint8_t *version)
316
char buf[ECRYPTFS_SIG_SIZE_HEX];
319
memset(buf, 0, sizeof(buf));
321
if (lseek(fd, 0, SEEK_SET) != 0)
324
bytes_read = do_read(fd, buf, sizeof(buf));
327
else if (bytes_read != sizeof(buf))
331
/* A leading ':' character means that this is a properly
332
* versioned wrapped passphrase file. The second octet contains
333
* the version number.
337
/* Only version 2 files are currently supported */
341
/* Set the offset to the beginning of the wrapping salt field */
342
if (lseek(fd, 2, SEEK_SET) != 2)
347
/* This wrapped passphrase file isn't versioned. We can assume
348
* that it is a "version 1" file if the first 16 bytes are hex
351
for (i = 0; i < bytes_read; i++) {
352
if (!isxdigit(buf[i]))
356
/* Reset the offset to 0 since there is no actual version field
359
if (lseek(fd, 0, SEEK_SET) != 0)
369
* __ecryptfs_detect_wrapped_passphrase_file_version
370
* @filename: The path of a wrapped passphrase file
371
* @version: On success, *version is set to the detected file version
373
* THIS FUNCTION IS NOT PART OF THE LIBECRYPTFS PUBLIC API. Code external to
374
* ecryptfs-utils should not use it.
376
* Detects the wrapped passphrase file version of @filename.
378
* Returns 0 on success, sets *version to the determined wrapped-passphrase
379
* file version. Returns negative on error (*version is undefined upon error).
381
int __ecryptfs_detect_wrapped_passphrase_file_version(const char *filename,
387
fd = open(filename, O_RDONLY);
393
rc = read_wrapped_passphrase_file_version(fd, version);
243
405
int ecryptfs_wrap_passphrase_file(char *dest, char *wrapping_passphrase,
244
406
char *salt, char *src)
251
412
char decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1];
253
for (i=0; i<ECRYPTFS_MAX_PASSPHRASE_BYTES+1; i++)
254
decrypted_passphrase[i] = '\0';
414
memset(decrypted_passphrase, 0, sizeof(decrypted_passphrase));
255
415
if ((fd = open(src, O_RDONLY)) == -1) {
256
416
syslog(LOG_ERR, "Error attempting to open [%s] for reading\n",
262
if ((size = read(fd, decrypted_passphrase,
263
ECRYPTFS_MAX_PASSPHRASE_BYTES)) <= 0) {
421
if ((size = do_read(fd, decrypted_passphrase,
422
ECRYPTFS_MAX_PASSPHRASE_BYTES)) <= 0) {
264
423
syslog(LOG_ERR, "Error attempting to read encrypted "
265
424
"passphrase from file [%s]; size = [%zd]\n",
446
static int read_urandom(void *buf, size_t count)
451
fd = open("/dev/urandom", O_RDONLY);
455
bytes = do_read(fd, buf, count);
462
* write_v2_wrapped_passphrase_file
463
* @filename: Path to the wrapped passphrase file
464
* @wrapping_salt: The salt to be used with the wrapping passphrase
465
* @wrapping_key_sig: The signature of the wrapping key
466
* @encrypted_passphrase: The encrypted passphrase
467
* @encrypted_passphrase_bytes: The size of the encrypted passphrase
469
* Writes a version 2 wrapped passphrase file containing the following format
470
* described in the read_v2_wrapped_passphrase_file() function.
472
* Returns 0 upon success. Negative upon error.
474
static int write_v2_wrapped_passphrase_file(const char *filename,
475
const char wrapping_salt[ECRYPTFS_SALT_SIZE],
476
const char wrapping_key_sig[ECRYPTFS_SIG_SIZE_HEX],
477
const char *encrypted_passphrase,
478
int encrypted_passphrase_bytes)
487
if (asprintf(&temp, "%s-XXXXXX", filename) < 0) {
493
old_umask = umask(S_IRWXG | S_IRWXO);
501
size = do_write(fd, ":", 1);
503
rc = size == -1 ? -errno : -EIO;
507
size = do_write(fd, &version, 1);
509
rc = size == -1 ? -errno : -EIO;
513
size = do_write(fd, wrapping_salt, ECRYPTFS_SALT_SIZE);
514
if (size != ECRYPTFS_SALT_SIZE) {
515
rc = size == -1 ? -errno : -EIO;
519
size = do_write(fd, wrapping_key_sig, ECRYPTFS_SIG_SIZE_HEX);
520
if (size != ECRYPTFS_SIG_SIZE_HEX) {
521
rc = size == -1 ? -errno : -EIO;
525
size = do_write(fd, encrypted_passphrase, encrypted_passphrase_bytes);
526
if (size != encrypted_passphrase_bytes) {
527
rc = size == -1 ? -errno : -EIO;
531
if (fsync(fd) == -1) {
539
if (rename(temp, filename) == -1) {
554
* ecryptfs_wrap_passphrase
555
* @filename: Path to the wrapped passphrase file
556
* @wrapping_passphrase: The passphrase used for wrapping the @decrypted_passphrase
557
* @unused: Previously used for specifying a wrapping salt. It is now randomly
558
* generated so @unused is no longer used.
559
* @decrypted_passphrase: The passphrase to be wrapped
561
* Returns 0 upon success. Negative upon error.
287
563
int ecryptfs_wrap_passphrase(char *filename, char *wrapping_passphrase,
288
char *wrapping_salt, char *decrypted_passphrase)
564
char *unused, char *decrypted_passphrase)
566
char wrapping_salt[ECRYPTFS_SALT_SIZE];
290
567
char wrapping_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
291
568
char wrapping_key[ECRYPTFS_MAX_KEY_BYTES];
292
569
char padded_decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES +
312
589
decrypted_passphrase_bytes = strlen(decrypted_passphrase);
313
if (decrypted_passphrase_bytes > ECRYPTFS_MAX_PASSPHRASE_BYTES) {
314
syslog(LOG_ERR, "Decrypted passphrase is [%d] bytes long; "
315
"[%d] is the max\n", decrypted_passphrase_bytes,
590
if (decrypted_passphrase_bytes < 1 ||
591
decrypted_passphrase_bytes > ECRYPTFS_MAX_PASSPHRASE_BYTES) {
592
syslog(LOG_ERR, "Decrypted passphrase size is invalid; [1] to [%d] is the valid range\n",
316
593
ECRYPTFS_MAX_PASSPHRASE_BYTES);
597
rc = read_urandom(wrapping_salt, ECRYPTFS_SALT_SIZE);
598
if (rc != ECRYPTFS_SALT_SIZE) {
599
rc = rc == -1 ? -errno : -EIO;
600
syslog(LOG_ERR, "Error generating random salt: %s\n",
320
604
rc = generate_passphrase_sig(wrapping_auth_tok_sig, wrapping_key,
321
605
wrapping_salt, wrapping_passphrase);
398
if ((fd = open(filename, (O_WRONLY | O_CREAT | O_EXCL),
399
(S_IRUSR | S_IWUSR))) == -1) {
400
syslog(LOG_ERR, "Error attempting to open [%s] for writing\n",
681
rc = write_v2_wrapped_passphrase_file(filename, wrapping_salt,
682
wrapping_auth_tok_sig,
683
encrypted_passphrase,
684
encrypted_passphrase_bytes);
693
* read_v1_wrapped_passphrase_file - Reads a v1 wrapped passphrase file
694
* @filename: Path to the wrapped passphrase file
695
* @wrapping_key_sig: Will contain the parsed wrapping key sig upon success.
696
* MUST be zeroed prior to calling this function.
697
* @encrypted_passphrase: Will contain the parsed encrypted passphrase upon
698
* success. MUST be zeroed prior to calling this function.
699
* @encrypted_passphrase_bytes: Will contain the size of the parsed encrypted
700
* passphrase upon success
702
* Reads a version 1 wrapped passphrase file containing the following format:
704
* Octets 0-15: Signature of wrapping key
705
* Octets 16-79: Variable length field containing the encrypted
708
* Returns 0 upon success with the size of the encrypted passphrase returned in
709
* *encrypted_passphrase_bytes. Returns negative upon failure.
711
static int read_v1_wrapped_passphrase_file(const char *filename,
712
char wrapping_key_sig[ECRYPTFS_SIG_SIZE_HEX],
713
char encrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES],
714
int *encrypted_passphrase_bytes)
720
*encrypted_passphrase_bytes = 0;
722
if ((fd = open(filename, O_RDONLY)) == -1) {
723
syslog(LOG_ERR, "Error attempting to open [%s] for reading\n",
405
if ((size = write(fd, wrapping_auth_tok_sig,
406
ECRYPTFS_SIG_SIZE_HEX)) <= 0) {
407
syslog(LOG_ERR, "Error attempting to write encrypted "
408
"passphrase ([%d] bytes) to file [%s]; size = [%zu]\n",
409
encrypted_passphrase_bytes, filename, size);
414
if ((size = write(fd, encrypted_passphrase,
415
encrypted_passphrase_bytes)) <= 0) {
416
syslog(LOG_ERR, "Error attempting to write encrypted "
417
"passphrase ([%d] bytes) to file [%s]; size = [%zu]\n",
418
encrypted_passphrase_bytes, filename, size);
729
if ((size = do_read(fd, wrapping_key_sig,
730
ECRYPTFS_SIG_SIZE_HEX)) < ECRYPTFS_SIG_SIZE_HEX) {
732
"Error attempting to read encrypted passphrase from file [%s]; size = [%zu]\n",
738
if ((size = do_read(fd, encrypted_passphrase,
739
ECRYPTFS_MAX_PASSPHRASE_BYTES)) <= 0) {
741
"Error attempting to read encrypted passphrase from file [%s]; size = [%zu]\n",
747
*encrypted_passphrase_bytes = size;
757
* read_v2_wrapped_passphrase_file - Reads a v2 wrapped passphrase file
758
* @filename: Path to the wrapped passphrase file
759
* @wrapping_salt: Will contain the parsed wrapping salt upon success. MUST be
760
* zeroed prior to calling this function.
761
* @wrapping_key_sig: Will contain the parsed wrapping key sig upon success.
762
* MUST be zeroed prior to calling this function.
763
* @encrypted_passphrase: Will contain the parsed encrypted passphrase upon
764
* success. MUST be zeroed prior to calling this function.
765
* @encrypted_passphrase_bytes: Will contain the size of the parsed encrypted
766
* passphrase upon success
768
* Reads a version 2 wrapped passphrase file containing the following format:
770
* Octet 0: A ':' character
771
* Octet 1: uint8_t value indicating file version (MUST be 0x02)
772
* Octets 2-9: Wrapping salt
773
* Octets 10-25: Signature of wrapping key (16 octets)
774
* Octets 26-N1: Variable length field containing the encrypted
775
* passphrase. (Up to 64 octets. Must be non-empty.)
777
* Returns 0 upon success with the size of the encrypted passphrase returned in
778
* *encrypted_passphrase_bytes. Returns negative upon failure.
780
static int read_v2_wrapped_passphrase_file(const char *filename,
781
char wrapping_salt[ECRYPTFS_SALT_SIZE],
782
char wrapping_key_sig[ECRYPTFS_SIG_SIZE_HEX],
783
char encrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES],
784
int *encrypted_passphrase_bytes)
787
uint8_t salt_len = 0;
792
*encrypted_passphrase_bytes = 0;
794
if ((fd = open(filename, O_RDONLY)) == -1) {
799
/* Parse file version (must be 2) */
800
rc = read_wrapped_passphrase_file_version(fd, &version);
803
} else if (version != 2) {
808
/* Parse the wrapping salt */
809
size = do_read(fd, wrapping_salt, ECRYPTFS_SALT_SIZE);
810
if (size != ECRYPTFS_SALT_SIZE) {
811
rc = size == -1 ? errno : -EINVAL;
815
/* Parse the wrapping key signature */
816
size = do_read(fd, wrapping_key_sig, ECRYPTFS_SIG_SIZE_HEX);
817
if (size != ECRYPTFS_SIG_SIZE_HEX) {
818
rc = size == -1 ? errno : -EINVAL;
822
/* Parse the encrypted passphrase */
823
size = do_read(fd, encrypted_passphrase, ECRYPTFS_MAX_PASSPHRASE_BYTES);
827
} else if(size == 0) {
832
*encrypted_passphrase_bytes = size;
447
860
PK11SlotInfo *slot = NULL;
448
861
PK11Context *enc_ctx = NULL;
449
862
SECItem *sec_param = NULL;
450
864
int encrypted_passphrase_bytes;
867
memset(wrapping_auth_tok_sig_from_file, 0,
868
sizeof(wrapping_auth_tok_sig_from_file));
869
memset(encrypted_passphrase, 0, sizeof(encrypted_passphrase));
871
rc = __ecryptfs_detect_wrapped_passphrase_file_version(filename,
875
"Failed to detect wrapped passphrase version: %s\n",
881
rc = read_v1_wrapped_passphrase_file(filename,
882
wrapping_auth_tok_sig_from_file,
883
encrypted_passphrase,
884
&encrypted_passphrase_bytes);
887
} else if (version == 2) {
888
rc = read_v2_wrapped_passphrase_file(filename,
890
wrapping_auth_tok_sig_from_file,
891
encrypted_passphrase,
892
&encrypted_passphrase_bytes);
897
* Version 2 wrapped passphrase self-contains the wrapping salt.
898
* The passed in @wrapping_salt buffer is ignored and the
899
* parsed wrapping salt is used instead.
901
wrapping_salt = v2_wrapping_salt;
904
"Unsupported wrapped passphrase file version: %u\n",
455
910
rc = generate_passphrase_sig(wrapping_auth_tok_sig, wrapping_key,
456
911
wrapping_salt, wrapping_passphrase);
460
915
rc = (rc < 0) ? rc : rc * -1;
463
if ((fd = open(filename, O_RDONLY)) == -1) {
464
syslog(LOG_ERR, "Error attempting to open [%s] for reading\n",
469
if ((size = read(fd, wrapping_auth_tok_sig_from_file,
470
ECRYPTFS_SIG_SIZE_HEX)) <= 0) {
471
syslog(LOG_ERR, "Error attempting to read encrypted "
472
"passphrase from file [%s]; size = [%zu]\n",
478
if ((size = read(fd, encrypted_passphrase,
479
ECRYPTFS_MAX_PASSPHRASE_BYTES)) <= 0) {
480
syslog(LOG_ERR, "Error attempting to read encrypted "
481
"passphrase from file [%s]; size = [%zu]\n",
488
919
if (memcmp(wrapping_auth_tok_sig_from_file, wrapping_auth_tok_sig,
489
920
ECRYPTFS_SIG_SIZE_HEX) != 0) {
490
921
syslog(LOG_ERR, "Incorrect wrapping key for file [%s]\n",
583
/* If the kernel supports filename encryption, add the associated
584
* filename encryption key to the keyring as well
586
if (ecryptfs_get_version(&version) == 0 &&
587
ecryptfs_supports_filename_encryption(version)) {
588
if ((rc = ecryptfs_add_passphrase_key_to_keyring(
1012
if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig,
590
1013
decrypted_passphrase,
591
ECRYPTFS_DEFAULT_SALT_FNEK_HEX)) != 0) {
593
"Error attempting to add filename encryption key to "
594
"user session keyring; rc = [%d]\n", rc);
1014
ECRYPTFS_DEFAULT_SALT_FNEK_HEX)) < 0) {
1015
syslog(LOG_ERR, "Error attempting to add filename encryption "
1016
"key to user session keyring; rc = [%d]\n", rc);
598
1019
if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig,
599
1020
decrypted_passphrase,
601
1022
syslog(LOG_ERR, "Error attempting to add passphrase key to "
602
1023
"user session keyring; rc = [%d]\n", rc);