aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/keystore.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ecryptfs/keystore.c')
-rw-r--r--fs/ecryptfs/keystore.c272
1 files changed, 171 insertions, 101 deletions
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index c1436cff6f2d..03e609c45012 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -65,6 +65,24 @@ static int process_request_key_err(long err_code)
65 return rc; 65 return rc;
66} 66}
67 67
68static int process_find_global_auth_tok_for_sig_err(int err_code)
69{
70 int rc = err_code;
71
72 switch (err_code) {
73 case -ENOENT:
74 ecryptfs_printk(KERN_WARNING, "Missing auth tok\n");
75 break;
76 case -EINVAL:
77 ecryptfs_printk(KERN_WARNING, "Invalid auth tok\n");
78 break;
79 default:
80 rc = process_request_key_err(err_code);
81 break;
82 }
83 return rc;
84}
85
68/** 86/**
69 * ecryptfs_parse_packet_length 87 * ecryptfs_parse_packet_length
70 * @data: Pointer to memory containing length at offset 88 * @data: Pointer to memory containing length at offset
@@ -403,27 +421,120 @@ out:
403 return rc; 421 return rc;
404} 422}
405 423
424/**
425 * ecryptfs_verify_version
426 * @version: The version number to confirm
427 *
428 * Returns zero on good version; non-zero otherwise
429 */
430static int ecryptfs_verify_version(u16 version)
431{
432 int rc = 0;
433 unsigned char major;
434 unsigned char minor;
435
436 major = ((version >> 8) & 0xFF);
437 minor = (version & 0xFF);
438 if (major != ECRYPTFS_VERSION_MAJOR) {
439 ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
440 "Expected [%d]; got [%d]\n",
441 ECRYPTFS_VERSION_MAJOR, major);
442 rc = -EINVAL;
443 goto out;
444 }
445 if (minor != ECRYPTFS_VERSION_MINOR) {
446 ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
447 "Expected [%d]; got [%d]\n",
448 ECRYPTFS_VERSION_MINOR, minor);
449 rc = -EINVAL;
450 goto out;
451 }
452out:
453 return rc;
454}
455
456/**
457 * ecryptfs_verify_auth_tok_from_key
458 * @auth_tok_key: key containing the authentication token
459 * @auth_tok: authentication token
460 *
461 * Returns zero on valid auth tok; -EINVAL otherwise
462 */
463static int
464ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
465 struct ecryptfs_auth_tok **auth_tok)
466{
467 int rc = 0;
468
469 (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key);
470 if (ecryptfs_verify_version((*auth_tok)->version)) {
471 printk(KERN_ERR "Data structure version mismatch. Userspace "
472 "tools must match eCryptfs kernel module with major "
473 "version [%d] and minor version [%d]\n",
474 ECRYPTFS_VERSION_MAJOR, ECRYPTFS_VERSION_MINOR);
475 rc = -EINVAL;
476 goto out;
477 }
478 if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD
479 && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) {
480 printk(KERN_ERR "Invalid auth_tok structure "
481 "returned from key query\n");
482 rc = -EINVAL;
483 goto out;
484 }
485out:
486 return rc;
487}
488
406static int 489static int
407ecryptfs_find_global_auth_tok_for_sig( 490ecryptfs_find_global_auth_tok_for_sig(
408 struct ecryptfs_global_auth_tok **global_auth_tok, 491 struct key **auth_tok_key,
492 struct ecryptfs_auth_tok **auth_tok,
409 struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) 493 struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig)
410{ 494{
411 struct ecryptfs_global_auth_tok *walker; 495 struct ecryptfs_global_auth_tok *walker;
412 int rc = 0; 496 int rc = 0;
413 497
414 (*global_auth_tok) = NULL; 498 (*auth_tok_key) = NULL;
499 (*auth_tok) = NULL;
415 mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); 500 mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
416 list_for_each_entry(walker, 501 list_for_each_entry(walker,
417 &mount_crypt_stat->global_auth_tok_list, 502 &mount_crypt_stat->global_auth_tok_list,
418 mount_crypt_stat_list) { 503 mount_crypt_stat_list) {
419 if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) { 504 if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX))
420 rc = key_validate(walker->global_auth_tok_key); 505 continue;
421 if (!rc) 506
422 (*global_auth_tok) = walker; 507 if (walker->flags & ECRYPTFS_AUTH_TOK_INVALID) {
508 rc = -EINVAL;
423 goto out; 509 goto out;
424 } 510 }
511
512 rc = key_validate(walker->global_auth_tok_key);
513 if (rc) {
514 if (rc == -EKEYEXPIRED)
515 goto out;
516 goto out_invalid_auth_tok;
517 }
518
519 down_write(&(walker->global_auth_tok_key->sem));
520 rc = ecryptfs_verify_auth_tok_from_key(
521 walker->global_auth_tok_key, auth_tok);
522 if (rc)
523 goto out_invalid_auth_tok_unlock;
524
525 (*auth_tok_key) = walker->global_auth_tok_key;
526 key_get(*auth_tok_key);
527 goto out;
425 } 528 }
426 rc = -EINVAL; 529 rc = -ENOENT;
530 goto out;
531out_invalid_auth_tok_unlock:
532 up_write(&(walker->global_auth_tok_key->sem));
533out_invalid_auth_tok:
534 printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig);
535 walker->flags |= ECRYPTFS_AUTH_TOK_INVALID;
536 key_put(walker->global_auth_tok_key);
537 walker->global_auth_tok_key = NULL;
427out: 538out:
428 mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); 539 mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
429 return rc; 540 return rc;
@@ -451,14 +562,11 @@ ecryptfs_find_auth_tok_for_sig(
451 struct ecryptfs_mount_crypt_stat *mount_crypt_stat, 562 struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
452 char *sig) 563 char *sig)
453{ 564{
454 struct ecryptfs_global_auth_tok *global_auth_tok;
455 int rc = 0; 565 int rc = 0;
456 566
457 (*auth_tok_key) = NULL; 567 rc = ecryptfs_find_global_auth_tok_for_sig(auth_tok_key, auth_tok,
458 (*auth_tok) = NULL; 568 mount_crypt_stat, sig);
459 if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, 569 if (rc == -ENOENT) {
460 mount_crypt_stat, sig)) {
461
462 /* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the 570 /* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the
463 * mount_crypt_stat structure, we prevent to use auth toks that 571 * mount_crypt_stat structure, we prevent to use auth toks that
464 * are not inserted through the ecryptfs_add_global_auth_tok 572 * are not inserted through the ecryptfs_add_global_auth_tok
@@ -470,8 +578,7 @@ ecryptfs_find_auth_tok_for_sig(
470 578
471 rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok, 579 rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok,
472 sig); 580 sig);
473 } else 581 }
474 (*auth_tok) = global_auth_tok->global_auth_tok;
475 return rc; 582 return rc;
476} 583}
477 584
@@ -531,6 +638,16 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
531 } 638 }
532 s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; 639 s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
533 (*packet_size) = 0; 640 (*packet_size) = 0;
641 rc = ecryptfs_find_auth_tok_for_sig(
642 &auth_tok_key,
643 &s->auth_tok, mount_crypt_stat,
644 mount_crypt_stat->global_default_fnek_sig);
645 if (rc) {
646 printk(KERN_ERR "%s: Error attempting to find auth tok for "
647 "fnek sig [%s]; rc = [%d]\n", __func__,
648 mount_crypt_stat->global_default_fnek_sig, rc);
649 goto out;
650 }
534 rc = ecryptfs_get_tfm_and_mutex_for_cipher_name( 651 rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(
535 &s->desc.tfm, 652 &s->desc.tfm,
536 &s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name); 653 &s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name);
@@ -616,16 +733,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
616 goto out_free_unlock; 733 goto out_free_unlock;
617 } 734 }
618 dest[s->i++] = s->cipher_code; 735 dest[s->i++] = s->cipher_code;
619 rc = ecryptfs_find_auth_tok_for_sig(
620 &auth_tok_key,
621 &s->auth_tok, mount_crypt_stat,
622 mount_crypt_stat->global_default_fnek_sig);
623 if (rc) {
624 printk(KERN_ERR "%s: Error attempting to find auth tok for "
625 "fnek sig [%s]; rc = [%d]\n", __func__,
626 mount_crypt_stat->global_default_fnek_sig, rc);
627 goto out_free_unlock;
628 }
629 /* TODO: Support other key modules than passphrase for 736 /* TODO: Support other key modules than passphrase for
630 * filename encryption */ 737 * filename encryption */
631 if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { 738 if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) {
@@ -765,8 +872,10 @@ out_free_unlock:
765out_unlock: 872out_unlock:
766 mutex_unlock(s->tfm_mutex); 873 mutex_unlock(s->tfm_mutex);
767out: 874out:
768 if (auth_tok_key) 875 if (auth_tok_key) {
876 up_write(&(auth_tok_key->sem));
769 key_put(auth_tok_key); 877 key_put(auth_tok_key);
878 }
770 kfree(s); 879 kfree(s);
771 return rc; 880 return rc;
772} 881}
@@ -879,6 +988,15 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
879 __func__, s->cipher_code); 988 __func__, s->cipher_code);
880 goto out; 989 goto out;
881 } 990 }
991 rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key,
992 &s->auth_tok, mount_crypt_stat,
993 s->fnek_sig_hex);
994 if (rc) {
995 printk(KERN_ERR "%s: Error attempting to find auth tok for "
996 "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex,
997 rc);
998 goto out;
999 }
882 rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm, 1000 rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm,
883 &s->tfm_mutex, 1001 &s->tfm_mutex,
884 s->cipher_string); 1002 s->cipher_string);
@@ -925,15 +1043,6 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
925 * >= ECRYPTFS_MAX_IV_BYTES. */ 1043 * >= ECRYPTFS_MAX_IV_BYTES. */
926 memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); 1044 memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES);
927 s->desc.info = s->iv; 1045 s->desc.info = s->iv;
928 rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key,
929 &s->auth_tok, mount_crypt_stat,
930 s->fnek_sig_hex);
931 if (rc) {
932 printk(KERN_ERR "%s: Error attempting to find auth tok for "
933 "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex,
934 rc);
935 goto out_free_unlock;
936 }
937 /* TODO: Support other key modules than passphrase for 1046 /* TODO: Support other key modules than passphrase for
938 * filename encryption */ 1047 * filename encryption */
939 if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { 1048 if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) {
@@ -1002,8 +1111,10 @@ out:
1002 (*filename_size) = 0; 1111 (*filename_size) = 0;
1003 (*filename) = NULL; 1112 (*filename) = NULL;
1004 } 1113 }
1005 if (auth_tok_key) 1114 if (auth_tok_key) {
1115 up_write(&(auth_tok_key->sem));
1006 key_put(auth_tok_key); 1116 key_put(auth_tok_key);
1117 }
1007 kfree(s); 1118 kfree(s);
1008 return rc; 1119 return rc;
1009} 1120}
@@ -1520,38 +1631,6 @@ out:
1520 return rc; 1631 return rc;
1521} 1632}
1522 1633
1523/**
1524 * ecryptfs_verify_version
1525 * @version: The version number to confirm
1526 *
1527 * Returns zero on good version; non-zero otherwise
1528 */
1529static int ecryptfs_verify_version(u16 version)
1530{
1531 int rc = 0;
1532 unsigned char major;
1533 unsigned char minor;
1534
1535 major = ((version >> 8) & 0xFF);
1536 minor = (version & 0xFF);
1537 if (major != ECRYPTFS_VERSION_MAJOR) {
1538 ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
1539 "Expected [%d]; got [%d]\n",
1540 ECRYPTFS_VERSION_MAJOR, major);
1541 rc = -EINVAL;
1542 goto out;
1543 }
1544 if (minor != ECRYPTFS_VERSION_MINOR) {
1545 ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
1546 "Expected [%d]; got [%d]\n",
1547 ECRYPTFS_VERSION_MINOR, minor);
1548 rc = -EINVAL;
1549 goto out;
1550 }
1551out:
1552 return rc;
1553}
1554
1555int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, 1634int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
1556 struct ecryptfs_auth_tok **auth_tok, 1635 struct ecryptfs_auth_tok **auth_tok,
1557 char *sig) 1636 char *sig)
@@ -1563,31 +1642,16 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
1563 printk(KERN_ERR "Could not find key with description: [%s]\n", 1642 printk(KERN_ERR "Could not find key with description: [%s]\n",
1564 sig); 1643 sig);
1565 rc = process_request_key_err(PTR_ERR(*auth_tok_key)); 1644 rc = process_request_key_err(PTR_ERR(*auth_tok_key));
1645 (*auth_tok_key) = NULL;
1566 goto out; 1646 goto out;
1567 } 1647 }
1568 (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key); 1648 down_write(&(*auth_tok_key)->sem);
1569 if (ecryptfs_verify_version((*auth_tok)->version)) { 1649 rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok);
1570 printk(KERN_ERR
1571 "Data structure version mismatch. "
1572 "Userspace tools must match eCryptfs "
1573 "kernel module with major version [%d] "
1574 "and minor version [%d]\n",
1575 ECRYPTFS_VERSION_MAJOR,
1576 ECRYPTFS_VERSION_MINOR);
1577 rc = -EINVAL;
1578 goto out_release_key;
1579 }
1580 if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD
1581 && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) {
1582 printk(KERN_ERR "Invalid auth_tok structure "
1583 "returned from key query\n");
1584 rc = -EINVAL;
1585 goto out_release_key;
1586 }
1587out_release_key:
1588 if (rc) { 1650 if (rc) {
1651 up_write(&(*auth_tok_key)->sem);
1589 key_put(*auth_tok_key); 1652 key_put(*auth_tok_key);
1590 (*auth_tok_key) = NULL; 1653 (*auth_tok_key) = NULL;
1654 goto out;
1591 } 1655 }
1592out: 1656out:
1593 return rc; 1657 return rc;
@@ -1809,6 +1873,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
1809find_next_matching_auth_tok: 1873find_next_matching_auth_tok:
1810 found_auth_tok = 0; 1874 found_auth_tok = 0;
1811 if (auth_tok_key) { 1875 if (auth_tok_key) {
1876 up_write(&(auth_tok_key->sem));
1812 key_put(auth_tok_key); 1877 key_put(auth_tok_key);
1813 auth_tok_key = NULL; 1878 auth_tok_key = NULL;
1814 } 1879 }
@@ -1895,8 +1960,10 @@ found_matching_auth_tok:
1895out_wipe_list: 1960out_wipe_list:
1896 wipe_auth_tok_list(&auth_tok_list); 1961 wipe_auth_tok_list(&auth_tok_list);
1897out: 1962out:
1898 if (auth_tok_key) 1963 if (auth_tok_key) {
1964 up_write(&(auth_tok_key->sem));
1899 key_put(auth_tok_key); 1965 key_put(auth_tok_key);
1966 }
1900 return rc; 1967 return rc;
1901} 1968}
1902 1969
@@ -2324,7 +2391,7 @@ ecryptfs_generate_key_packet_set(char *dest_base,
2324 size_t max) 2391 size_t max)
2325{ 2392{
2326 struct ecryptfs_auth_tok *auth_tok; 2393 struct ecryptfs_auth_tok *auth_tok;
2327 struct ecryptfs_global_auth_tok *global_auth_tok; 2394 struct key *auth_tok_key = NULL;
2328 struct ecryptfs_mount_crypt_stat *mount_crypt_stat = 2395 struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
2329 &ecryptfs_superblock_to_private( 2396 &ecryptfs_superblock_to_private(
2330 ecryptfs_dentry->d_sb)->mount_crypt_stat; 2397 ecryptfs_dentry->d_sb)->mount_crypt_stat;
@@ -2343,21 +2410,16 @@ ecryptfs_generate_key_packet_set(char *dest_base,
2343 list_for_each_entry(key_sig, &crypt_stat->keysig_list, 2410 list_for_each_entry(key_sig, &crypt_stat->keysig_list,
2344 crypt_stat_list) { 2411 crypt_stat_list) {
2345 memset(key_rec, 0, sizeof(*key_rec)); 2412 memset(key_rec, 0, sizeof(*key_rec));
2346 rc = ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, 2413 rc = ecryptfs_find_global_auth_tok_for_sig(&auth_tok_key,
2414 &auth_tok,
2347 mount_crypt_stat, 2415 mount_crypt_stat,
2348 key_sig->keysig); 2416 key_sig->keysig);
2349 if (rc) { 2417 if (rc) {
2350 printk(KERN_ERR "Error attempting to get the global " 2418 printk(KERN_WARNING "Unable to retrieve auth tok with "
2351 "auth_tok; rc = [%d]\n", rc); 2419 "sig = [%s]\n", key_sig->keysig);
2420 rc = process_find_global_auth_tok_for_sig_err(rc);
2352 goto out_free; 2421 goto out_free;
2353 } 2422 }
2354 if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID) {
2355 printk(KERN_WARNING
2356 "Skipping invalid auth tok with sig = [%s]\n",
2357 global_auth_tok->sig);
2358 continue;
2359 }
2360 auth_tok = global_auth_tok->global_auth_tok;
2361 if (auth_tok->token_type == ECRYPTFS_PASSWORD) { 2423 if (auth_tok->token_type == ECRYPTFS_PASSWORD) {
2362 rc = write_tag_3_packet((dest_base + (*len)), 2424 rc = write_tag_3_packet((dest_base + (*len)),
2363 &max, auth_tok, 2425 &max, auth_tok,
@@ -2395,6 +2457,9 @@ ecryptfs_generate_key_packet_set(char *dest_base,
2395 rc = -EINVAL; 2457 rc = -EINVAL;
2396 goto out_free; 2458 goto out_free;
2397 } 2459 }
2460 up_write(&(auth_tok_key->sem));
2461 key_put(auth_tok_key);
2462 auth_tok_key = NULL;
2398 } 2463 }
2399 if (likely(max > 0)) { 2464 if (likely(max > 0)) {
2400 dest_base[(*len)] = 0x00; 2465 dest_base[(*len)] = 0x00;
@@ -2407,6 +2472,11 @@ out_free:
2407out: 2472out:
2408 if (rc) 2473 if (rc)
2409 (*len) = 0; 2474 (*len) = 0;
2475 if (auth_tok_key) {
2476 up_write(&(auth_tok_key->sem));
2477 key_put(auth_tok_key);
2478 }
2479
2410 mutex_unlock(&crypt_stat->keysig_list_mutex); 2480 mutex_unlock(&crypt_stat->keysig_list_mutex);
2411 return rc; 2481 return rc;
2412} 2482}
@@ -2424,6 +2494,7 @@ int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig)
2424 return -ENOMEM; 2494 return -ENOMEM;
2425 } 2495 }
2426 memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX); 2496 memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX);
2497 new_key_sig->keysig[ECRYPTFS_SIG_SIZE_HEX] = '\0';
2427 /* Caller must hold keysig_list_mutex */ 2498 /* Caller must hold keysig_list_mutex */
2428 list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list); 2499 list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list);
2429 2500
@@ -2453,7 +2524,6 @@ ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
2453 mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); 2524 mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
2454 list_add(&new_auth_tok->mount_crypt_stat_list, 2525 list_add(&new_auth_tok->mount_crypt_stat_list,
2455 &mount_crypt_stat->global_auth_tok_list); 2526 &mount_crypt_stat->global_auth_tok_list);
2456 mount_crypt_stat->num_global_auth_toks++;
2457 mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); 2527 mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
2458out: 2528out:
2459 return rc; 2529 return rc;