~ecryptfs/ecryptfs/trunk

« back to all changes in this revision

Viewing changes to src/libecryptfs/key_management.c

  • Committer: Dustin Kirkland
  • Date: 2016-02-27 00:00:23 UTC
  • Revision ID: kirkland@ubuntu.com-20160227000023-h0e4oui5y1vbaurd
openingĀ 112

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
2
 * Copyright (C) 2006 International Business Machines
 
3
 * Copyright (C) 2011 Gazzang, Inc
3
4
 * Author(s): Michael C. Thompson <mcthomps@us.ibm.com>
 
5
 *            Dustin Kirkland <dustin.kirkland@gazzang.com>
4
6
 *
5
7
 * This program is free software; you can redistribute it and/or
6
8
 * modify it under the terms of the GNU General Public License as
18
20
 * 02111-1307, USA.
19
21
 */
20
22
 
21
 
#include "config.h"
22
23
#include <errno.h>
23
24
#include <nss.h>
24
25
#include <pk11func.h>
36
37
#include <sys/types.h>
37
38
#include <sys/stat.h>
38
39
#include <pwd.h>
 
40
#include <inttypes.h>
39
41
#include "../include/ecryptfs.h"
40
42
 
41
43
#ifndef ENOKEY
75
77
        if (rc) {
76
78
                syslog(LOG_ERR, "Error generating payload for auth tok key; "
77
79
                       "rc = [%d]\n", rc);
 
80
                memset(*auth_tok, 0, sizeof(struct ecryptfs_auth_tok));
 
81
                free(*auth_tok);
 
82
                *auth_tok = NULL;
78
83
                rc = (rc < 0) ? rc : rc * -1;
79
84
                goto out;
80
85
        }
234
239
        }
235
240
out:
236
241
        if (auth_tok) {
237
 
                memset(auth_tok, 0, sizeof(auth_tok));
 
242
                memset(auth_tok, 0, sizeof(*auth_tok));
238
243
                free(auth_tok);
239
244
        }
240
245
        return rc;
241
246
}
242
247
 
 
248
/**
 
249
 * A wrapper around write(2) that handles short and interrupted writes.
 
250
 *
 
251
 * Returns the number of bytes written or -1 with errno set on failure.
 
252
 */
 
253
static ssize_t do_write(int fd, const void *buf, size_t count)
 
254
{
 
255
        ssize_t rc = 0;
 
256
 
 
257
        do {
 
258
                ssize_t bytes = write(fd, buf + rc, count - rc);
 
259
 
 
260
                if (bytes == -1) {
 
261
                        if (errno == EINTR)
 
262
                                continue;
 
263
                        return -1;
 
264
                }
 
265
 
 
266
                rc += bytes;
 
267
        } while (rc < count);
 
268
 
 
269
        return rc;
 
270
}
 
271
 
 
272
/**
 
273
 * A wrapper around read(2) that handles short and interrupted reads.
 
274
 *
 
275
 * Returns the number of bytes read or -1 with errno set on failure.
 
276
 */
 
277
static ssize_t do_read(int fd, void *buf, size_t count)
 
278
{
 
279
        ssize_t rc = 0;
 
280
 
 
281
        do {
 
282
                ssize_t bytes = read(fd, buf + rc, count - rc);
 
283
 
 
284
                if (bytes == 0) {
 
285
                        break;
 
286
                } else if (bytes == -1) {
 
287
                        if (errno == EINTR)
 
288
                                continue;
 
289
 
 
290
                        return -1;
 
291
                }
 
292
 
 
293
                rc += bytes;
 
294
        } while (rc < count);
 
295
 
 
296
        return rc;
 
297
}
 
298
 
 
299
/**
 
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
 
303
 *
 
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'.
 
308
 *
 
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).
 
313
 */
 
314
static int read_wrapped_passphrase_file_version(int fd, uint8_t *version)
 
315
{
 
316
        char buf[ECRYPTFS_SIG_SIZE_HEX];
 
317
        int bytes_read, i;
 
318
 
 
319
        memset(buf, 0, sizeof(buf));
 
320
 
 
321
        if (lseek(fd, 0, SEEK_SET) != 0)
 
322
                return -errno;
 
323
 
 
324
        bytes_read = do_read(fd, buf, sizeof(buf));
 
325
        if (bytes_read < 0)
 
326
                return -errno;
 
327
        else if (bytes_read != sizeof(buf))
 
328
                return -EINVAL;
 
329
 
 
330
        if (buf[0] == ':') {
 
331
                /* A leading ':' character means that this is a properly
 
332
                 * versioned wrapped passphrase file. The second octet contains
 
333
                 * the version number.
 
334
                 */
 
335
                uint8_t v = buf[1];
 
336
 
 
337
                /* Only version 2 files are currently supported */
 
338
                if (v != 2)
 
339
                        return -ENOTSUP;
 
340
 
 
341
                /* Set the offset to the beginning of the wrapping salt field */
 
342
                if (lseek(fd, 2, SEEK_SET) != 2)
 
343
                        return -errno;
 
344
 
 
345
                *version = v;
 
346
        } else {
 
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
 
349
                 * encoded values.
 
350
                 */
 
351
                for (i = 0; i < bytes_read; i++) {
 
352
                        if (!isxdigit(buf[i]))
 
353
                                return -EINVAL;
 
354
                }
 
355
 
 
356
                /* Reset the offset to 0 since there is no actual version field
 
357
                 * in version 1 files
 
358
                 */
 
359
                if (lseek(fd, 0, SEEK_SET) != 0)
 
360
                        return -errno;
 
361
 
 
362
                *version = 1;
 
363
        }
 
364
 
 
365
        return 0;
 
366
}
 
367
 
 
368
/**
 
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
 
372
 *
 
373
 * THIS FUNCTION IS NOT PART OF THE LIBECRYPTFS PUBLIC API. Code external to
 
374
 * ecryptfs-utils should not use it.
 
375
 *
 
376
 * Detects the wrapped passphrase file version of @filename.
 
377
 *
 
378
 * Returns 0 on success, sets *version to the determined wrapped-passphrase
 
379
 * file version. Returns negative on error (*version is undefined upon error).
 
380
 */
 
381
int __ecryptfs_detect_wrapped_passphrase_file_version(const char *filename,
 
382
                                                      uint8_t *version)
 
383
{
 
384
        int fd = -1;
 
385
        int rc;
 
386
 
 
387
        fd = open(filename, O_RDONLY);
 
388
        if (fd == -1) {
 
389
                rc = -errno;
 
390
                goto out;
 
391
        }
 
392
 
 
393
        rc = read_wrapped_passphrase_file_version(fd, version);
 
394
        if (rc != 0)
 
395
                goto out;
 
396
 
 
397
        rc = 0;
 
398
out:
 
399
        if (fd != -1)
 
400
                close(fd);
 
401
 
 
402
        return rc;
 
403
}
 
404
 
243
405
int ecryptfs_wrap_passphrase_file(char *dest, char *wrapping_passphrase,
244
406
                                  char *salt, char *src)
245
407
{
246
408
        int rc = 0;
247
409
        ssize_t size;
248
410
        int fd;
249
 
        int i;
250
411
        char *p = NULL;
251
412
        char decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1];
252
413
 
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",
257
417
                       src);
258
418
                rc = -EIO;
259
 
                close(fd);
260
419
                goto out;
261
420
        }
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",
266
425
                       src, size);
284
443
        return rc;
285
444
}
286
445
 
 
446
static int read_urandom(void *buf, size_t count)
 
447
{
 
448
        ssize_t bytes;
 
449
        int fd = -1;
 
450
 
 
451
        fd = open("/dev/urandom", O_RDONLY);
 
452
        if (fd == -1)
 
453
                return -1;
 
454
 
 
455
        bytes = do_read(fd, buf, count);
 
456
        close(fd);
 
457
 
 
458
        return bytes;
 
459
}
 
460
 
 
461
/**
 
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
 
468
 *
 
469
 * Writes a version 2 wrapped passphrase file containing the following format
 
470
 * described in the read_v2_wrapped_passphrase_file() function.
 
471
 *
 
472
 * Returns 0 upon success. Negative upon error.
 
473
 */
 
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)
 
479
{
 
480
        ssize_t size;
 
481
        uint8_t version = 2;
 
482
        mode_t old_umask;
 
483
        char *temp = NULL;
 
484
        int fd = -1;
 
485
        int rc;
 
486
 
 
487
        if (asprintf(&temp, "%s-XXXXXX", filename) < 0) {
 
488
                rc = -errno;
 
489
                temp = NULL;
 
490
                goto out;
 
491
        }
 
492
 
 
493
        old_umask = umask(S_IRWXG | S_IRWXO);
 
494
        fd = mkstemp(temp);
 
495
        umask(old_umask);
 
496
        if (fd == -1) {
 
497
                rc = -errno;
 
498
                goto out;
 
499
        }
 
500
 
 
501
        size = do_write(fd, ":", 1);
 
502
        if (size != 1) {
 
503
                rc = size == -1 ? -errno : -EIO;
 
504
                goto out;
 
505
        }
 
506
 
 
507
        size = do_write(fd, &version, 1);
 
508
        if (size != 1) {
 
509
                rc = size == -1 ? -errno : -EIO;
 
510
                goto out;
 
511
        }
 
512
 
 
513
        size = do_write(fd, wrapping_salt, ECRYPTFS_SALT_SIZE);
 
514
        if (size != ECRYPTFS_SALT_SIZE) {
 
515
                rc = size == -1 ? -errno : -EIO;
 
516
                goto out;
 
517
        }
 
518
 
 
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;
 
522
                goto out;
 
523
        }
 
524
 
 
525
        size = do_write(fd, encrypted_passphrase, encrypted_passphrase_bytes);
 
526
        if (size != encrypted_passphrase_bytes) {
 
527
                rc = size == -1 ? -errno : -EIO;
 
528
                goto out;
 
529
        }
 
530
 
 
531
        if (fsync(fd) == -1) {
 
532
                rc = -errno;
 
533
                goto out;
 
534
        }
 
535
 
 
536
        close(fd);
 
537
        fd = -1;
 
538
 
 
539
        if (rename(temp, filename) == -1) {
 
540
                rc = -errno;
 
541
                goto out;
 
542
        }
 
543
 
 
544
        rc = 0;
 
545
out:
 
546
        if (fd != -1)
 
547
                close(fd);
 
548
        free(temp);
 
549
 
 
550
        return rc;
 
551
}
 
552
 
 
553
/**
 
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
 
560
 *
 
561
 * Returns 0 upon success. Negative upon error.
 
562
 */
287
563
int ecryptfs_wrap_passphrase(char *filename, char *wrapping_passphrase,
288
 
                             char *wrapping_salt, char *decrypted_passphrase)
 
564
                             char *unused, char *decrypted_passphrase)
289
565
{
 
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 +
310
587
        int rc;
311
588
 
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);
317
594
                rc = -EIO;
318
595
                goto out;
319
596
        }
 
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",
 
601
                       strerror(-rc));
 
602
                goto out;
 
603
        }
320
604
        rc = generate_passphrase_sig(wrapping_auth_tok_sig, wrapping_key,
321
605
                                     wrapping_salt, wrapping_passphrase);
322
606
        if (rc) {
394
678
                rc = - EIO;
395
679
                goto out;
396
680
        }
397
 
        unlink(filename);
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);
 
685
        if (rc)
 
686
                goto out;
 
687
        rc = 0;
 
688
out:
 
689
        return rc;
 
690
}
 
691
 
 
692
/**
 
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
 
701
 *
 
702
 * Reads a version 1 wrapped passphrase file containing the following format:
 
703
 *
 
704
 *   Octets 0-15:   Signature of wrapping key
 
705
 *   Octets 16-79:  Variable length field containing the encrypted
 
706
 *                  passphrase.
 
707
 *
 
708
 * Returns 0 upon success with the size of the encrypted passphrase returned in
 
709
 * *encrypted_passphrase_bytes. Returns negative upon failure.
 
710
 */
 
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)
 
715
{
 
716
        ssize_t size;
 
717
        int fd;
 
718
        int rc;
 
719
 
 
720
        *encrypted_passphrase_bytes = 0;
 
721
 
 
722
        if ((fd = open(filename, O_RDONLY)) == -1) {
 
723
                syslog(LOG_ERR, "Error attempting to open [%s] for reading\n",
401
724
                       filename);
402
725
                rc = -EIO;
403
726
                goto out;
404
727
        }
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);
410
 
                rc = -EIO;
411
 
                close(fd);
412
 
                goto out;
413
 
        }
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);
419
 
                rc = -EIO;
420
 
                close(fd);
421
 
                goto out;
422
 
        }
423
 
        close(fd);
424
 
        rc = 0;
425
 
out:
 
728
 
 
729
        if ((size = do_read(fd, wrapping_key_sig,
 
730
                            ECRYPTFS_SIG_SIZE_HEX)) < ECRYPTFS_SIG_SIZE_HEX) {
 
731
                syslog(LOG_ERR,
 
732
                       "Error attempting to read encrypted passphrase from file [%s]; size = [%zu]\n",
 
733
                       filename, size);
 
734
                rc = -EIO;
 
735
                goto out;
 
736
        }
 
737
 
 
738
        if ((size = do_read(fd, encrypted_passphrase,
 
739
                            ECRYPTFS_MAX_PASSPHRASE_BYTES)) <= 0) {
 
740
                syslog(LOG_ERR,
 
741
                       "Error attempting to read encrypted passphrase from file [%s]; size = [%zu]\n",
 
742
                       filename, size);
 
743
                rc = -EIO;
 
744
                goto out;
 
745
        }
 
746
 
 
747
        *encrypted_passphrase_bytes = size;
 
748
        rc = 0;
 
749
out:
 
750
        if (fd != -1)
 
751
                close(fd);
 
752
 
 
753
        return rc;
 
754
}
 
755
 
 
756
/**
 
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
 
767
 *
 
768
 * Reads a version 2 wrapped passphrase file containing the following format:
 
769
 *
 
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.)
 
776
 *
 
777
 * Returns 0 upon success with the size of the encrypted passphrase returned in
 
778
 * *encrypted_passphrase_bytes. Returns negative upon failure.
 
779
 */
 
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)
 
785
{
 
786
        uint8_t version = 0;
 
787
        uint8_t salt_len = 0;
 
788
        ssize_t size;
 
789
        int fd = -1;
 
790
        int rc;
 
791
 
 
792
        *encrypted_passphrase_bytes = 0;
 
793
 
 
794
        if ((fd = open(filename, O_RDONLY)) == -1) {
 
795
                rc = -errno;
 
796
                goto out;
 
797
        }
 
798
 
 
799
        /* Parse file version (must be 2) */
 
800
        rc = read_wrapped_passphrase_file_version(fd, &version);
 
801
        if (rc != 0) {
 
802
                goto out;
 
803
        } else if (version != 2) {
 
804
                rc = -EINVAL;
 
805
                goto out;
 
806
        }
 
807
 
 
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;
 
812
                goto out;
 
813
        }
 
814
 
 
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;
 
819
                goto out;
 
820
        }
 
821
 
 
822
        /* Parse the encrypted passphrase */
 
823
        size = do_read(fd, encrypted_passphrase, ECRYPTFS_MAX_PASSPHRASE_BYTES);
 
824
        if (size < 0) {
 
825
                rc = size;
 
826
                goto out;
 
827
        } else if(size == 0) {
 
828
                rc = -EINVAL;
 
829
                goto out;
 
830
        }
 
831
 
 
832
        *encrypted_passphrase_bytes = size;
 
833
        rc = 0;
 
834
out:
 
835
        if (fd != -1)
 
836
                close(fd);
 
837
 
426
838
        return rc;
427
839
}
428
840
 
433
845
int ecryptfs_unwrap_passphrase(char *decrypted_passphrase, char *filename,
434
846
                               char *wrapping_passphrase, char *wrapping_salt)
435
847
{
 
848
        char v2_wrapping_salt[ECRYPTFS_SALT_SIZE];
436
849
        char wrapping_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
437
850
        char wrapping_auth_tok_sig_from_file[ECRYPTFS_SIG_SIZE_HEX + 1];
438
851
        char wrapping_key[ECRYPTFS_MAX_KEY_BYTES];
447
860
        PK11SlotInfo *slot = NULL;
448
861
        PK11Context *enc_ctx = NULL;
449
862
        SECItem *sec_param = NULL;
 
863
        uint8_t version = 0;
450
864
        int encrypted_passphrase_bytes;
451
 
        int fd;
452
 
        ssize_t size;
453
865
        int rc;
454
866
 
 
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));
 
870
 
 
871
        rc = __ecryptfs_detect_wrapped_passphrase_file_version(filename,
 
872
                                                               &version);
 
873
        if (rc) {
 
874
                syslog(LOG_ERR,
 
875
                       "Failed to detect wrapped passphrase version: %s\n",
 
876
                       strerror(-rc));
 
877
                goto out;
 
878
        }
 
879
 
 
880
        if (version == 1) {
 
881
                rc = read_v1_wrapped_passphrase_file(filename,
 
882
                                                wrapping_auth_tok_sig_from_file,
 
883
                                                encrypted_passphrase,
 
884
                                                &encrypted_passphrase_bytes);
 
885
                if (rc)
 
886
                        goto out;
 
887
        } else if (version == 2) {
 
888
                rc = read_v2_wrapped_passphrase_file(filename,
 
889
                                                v2_wrapping_salt,
 
890
                                                wrapping_auth_tok_sig_from_file,
 
891
                                                encrypted_passphrase,
 
892
                                                &encrypted_passphrase_bytes);
 
893
                if (rc)
 
894
                        goto out;
 
895
 
 
896
                /**
 
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.
 
900
                 */
 
901
                wrapping_salt = v2_wrapping_salt;
 
902
        } else {
 
903
                syslog(LOG_ERR,
 
904
                       "Unsupported wrapped passphrase file version: %u\n",
 
905
                       version);
 
906
                rc = -ENOTSUP;
 
907
                goto out;
 
908
        }
 
909
 
455
910
        rc = generate_passphrase_sig(wrapping_auth_tok_sig, wrapping_key,
456
911
                                     wrapping_salt, wrapping_passphrase);
457
912
        if (rc) {
460
915
                rc = (rc < 0) ? rc : rc * -1;
461
916
                goto out;
462
917
        }
463
 
        if ((fd = open(filename, O_RDONLY)) == -1) {
464
 
                syslog(LOG_ERR, "Error attempting to open [%s] for reading\n",
465
 
                       filename);
466
 
                rc = -EIO;
467
 
                goto out;
468
 
        }
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",
473
 
                       filename, size);
474
 
                rc = -EIO;
475
 
                close(fd);
476
 
                goto out;
477
 
        }
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",
482
 
                       filename, size);
483
 
                rc = -EIO;
484
 
                close(fd);
485
 
                goto out;
486
 
        }
487
 
        close(fd);
 
918
 
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",
492
923
                rc = -EIO;
493
924
                goto out;
494
925
        }
495
 
        encrypted_passphrase_bytes = size;
496
926
        NSS_NoDB_Init(NULL);
497
927
        slot = PK11_GetBestSlot(CKM_AES_ECB, NULL);
498
928
        key_item.data = (unsigned char *)wrapping_key;
570
1000
        char *salt)
571
1001
{
572
1002
        char decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1] ;
573
 
        uint32_t version;
574
 
        int rc;
 
1003
        int rc = 0;
575
1004
 
576
1005
        if ((rc = ecryptfs_unwrap_passphrase(decrypted_passphrase, filename,
577
1006
                                             wrapping_passphrase, salt))) {
580
1009
                rc = -EIO;
581
1010
                goto out;
582
1011
        }
583
 
        /* If the kernel supports filename encryption, add the associated
584
 
         * filename encryption key to the keyring as well
585
 
         */
586
 
        if (ecryptfs_get_version(&version) == 0 &&
587
 
            ecryptfs_supports_filename_encryption(version)) {
588
 
                if ((rc = ecryptfs_add_passphrase_key_to_keyring(
589
 
                                        auth_tok_sig,
 
1012
        if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig,
590
1013
                                        decrypted_passphrase,
591
 
                                        ECRYPTFS_DEFAULT_SALT_FNEK_HEX)) != 0) {
592
 
                        syslog(LOG_ERR,
593
 
                           "Error attempting to add filename encryption key to "
594
 
                           "user session keyring; rc = [%d]\n", rc);
595
 
                        goto out;
596
 
                }
 
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);
 
1017
                goto out;
597
1018
        }
598
1019
        if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig,
599
1020
                                                         decrypted_passphrase,
600
 
                                                         salt)) != 0) {
 
1021
                                                         salt)) < 0) {
601
1022
                syslog(LOG_ERR, "Error attempting to add passphrase key to "
602
1023
                       "user session keyring; rc = [%d]\n", rc);
603
 
        } else
604
 
                rc = 0;
 
1024
        }
605
1025
out:
606
1026
        return rc;
607
1027
}
682
1102
        memset(&nvp_list_head, 0, sizeof(struct ecryptfs_name_val_pair));
683
1103
        rc = ecryptfs_parse_rc_file(&nvp_list_head);
684
1104
        if (rc) {
685
 
                if (rc != -ENOENT) {
 
1105
                if (rc != -ENOENT && rc != -EACCES) {
686
1106
                        syslog(LOG_WARNING,
687
1107
                                "Error attempting to parse .ecryptfsrc file; "
688
1108
                                "rc = [%d]", rc);
720
1140
        ssize_t size;
721
1141
        int rc = 0;
722
1142
 
 
1143
        memset(tmp, 0, sizeof(tmp));
723
1144
        (*flags) &= ~ECRYPTFS_SIG_FLAG_NOENT;
724
1145
        fd = open(sig_cache_filename, O_RDONLY);
725
1146
        if (fd == -1) {
733
1154
                        close(fd);
734
1155
                        goto out;
735
1156
                }
 
1157
                memset(tmp, 0, sizeof(tmp));
736
1158
        }
737
1159
        close(fd);
738
1160
        (*flags) |= ECRYPTFS_SIG_FLAG_NOENT;