diff options
Diffstat (limited to 'fs/ecryptfs/keystore.c')
-rw-r--r-- | fs/ecryptfs/keystore.c | 114 |
1 files changed, 72 insertions, 42 deletions
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index ba454785a0c5..c3746f56d162 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -458,14 +458,16 @@ out: | |||
458 | static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | 458 | static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, |
459 | struct ecryptfs_crypt_stat *crypt_stat) | 459 | struct ecryptfs_crypt_stat *crypt_stat) |
460 | { | 460 | { |
461 | int rc = 0; | ||
462 | struct ecryptfs_password *password_s_ptr; | 461 | struct ecryptfs_password *password_s_ptr; |
463 | struct crypto_tfm *tfm = NULL; | ||
464 | struct scatterlist src_sg[2], dst_sg[2]; | 462 | struct scatterlist src_sg[2], dst_sg[2]; |
465 | struct mutex *tfm_mutex = NULL; | 463 | struct mutex *tfm_mutex = NULL; |
466 | /* TODO: Use virt_to_scatterlist for these */ | 464 | /* TODO: Use virt_to_scatterlist for these */ |
467 | char *encrypted_session_key; | 465 | char *encrypted_session_key; |
468 | char *session_key; | 466 | char *session_key; |
467 | struct blkcipher_desc desc = { | ||
468 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | ||
469 | }; | ||
470 | int rc = 0; | ||
469 | 471 | ||
470 | password_s_ptr = &auth_tok->token.password; | 472 | password_s_ptr = &auth_tok->token.password; |
471 | if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags, | 473 | if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags, |
@@ -482,30 +484,37 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
482 | if (!strcmp(crypt_stat->cipher, | 484 | if (!strcmp(crypt_stat->cipher, |
483 | crypt_stat->mount_crypt_stat->global_default_cipher_name) | 485 | crypt_stat->mount_crypt_stat->global_default_cipher_name) |
484 | && crypt_stat->mount_crypt_stat->global_key_tfm) { | 486 | && crypt_stat->mount_crypt_stat->global_key_tfm) { |
485 | tfm = crypt_stat->mount_crypt_stat->global_key_tfm; | 487 | desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm; |
486 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; | 488 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; |
487 | } else { | 489 | } else { |
488 | tfm = crypto_alloc_tfm(crypt_stat->cipher, | 490 | char *full_alg_name; |
489 | CRYPTO_TFM_REQ_WEAK_KEY); | 491 | |
490 | if (!tfm) { | 492 | rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, |
491 | printk(KERN_ERR "Error allocating crypto context\n"); | 493 | crypt_stat->cipher, |
492 | rc = -ENOMEM; | 494 | "ecb"); |
495 | if (rc) | ||
496 | goto out; | ||
497 | desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0, | ||
498 | CRYPTO_ALG_ASYNC); | ||
499 | kfree(full_alg_name); | ||
500 | if (IS_ERR(desc.tfm)) { | ||
501 | rc = PTR_ERR(desc.tfm); | ||
502 | printk(KERN_ERR "Error allocating crypto context; " | ||
503 | "rc = [%d]\n", rc); | ||
493 | goto out; | 504 | goto out; |
494 | } | 505 | } |
495 | } | 506 | crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
496 | if (password_s_ptr->session_key_encryption_key_bytes | ||
497 | < crypto_tfm_alg_min_keysize(tfm)) { | ||
498 | printk(KERN_WARNING "Session key encryption key is [%d] bytes; " | ||
499 | "minimum keysize for selected cipher is [%d] bytes.\n", | ||
500 | password_s_ptr->session_key_encryption_key_bytes, | ||
501 | crypto_tfm_alg_min_keysize(tfm)); | ||
502 | rc = -EINVAL; | ||
503 | goto out; | ||
504 | } | 507 | } |
505 | if (tfm_mutex) | 508 | if (tfm_mutex) |
506 | mutex_lock(tfm_mutex); | 509 | mutex_lock(tfm_mutex); |
507 | crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key, | 510 | rc = crypto_blkcipher_setkey(desc.tfm, |
508 | crypt_stat->key_size); | 511 | password_s_ptr->session_key_encryption_key, |
512 | crypt_stat->key_size); | ||
513 | if (rc < 0) { | ||
514 | printk(KERN_ERR "Error setting key for crypto context\n"); | ||
515 | rc = -EINVAL; | ||
516 | goto out_free_tfm; | ||
517 | } | ||
509 | /* TODO: virt_to_scatterlist */ | 518 | /* TODO: virt_to_scatterlist */ |
510 | encrypted_session_key = (char *)__get_free_page(GFP_KERNEL); | 519 | encrypted_session_key = (char *)__get_free_page(GFP_KERNEL); |
511 | if (!encrypted_session_key) { | 520 | if (!encrypted_session_key) { |
@@ -531,9 +540,12 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
531 | auth_tok->session_key.decrypted_key_size = | 540 | auth_tok->session_key.decrypted_key_size = |
532 | auth_tok->session_key.encrypted_key_size; | 541 | auth_tok->session_key.encrypted_key_size; |
533 | dst_sg[0].length = auth_tok->session_key.encrypted_key_size; | 542 | dst_sg[0].length = auth_tok->session_key.encrypted_key_size; |
534 | /* TODO: Handle error condition */ | 543 | rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg, |
535 | crypto_cipher_decrypt(tfm, dst_sg, src_sg, | 544 | auth_tok->session_key.encrypted_key_size); |
536 | auth_tok->session_key.encrypted_key_size); | 545 | if (rc) { |
546 | printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc); | ||
547 | goto out_free_memory; | ||
548 | } | ||
537 | auth_tok->session_key.decrypted_key_size = | 549 | auth_tok->session_key.decrypted_key_size = |
538 | auth_tok->session_key.encrypted_key_size; | 550 | auth_tok->session_key.encrypted_key_size; |
539 | memcpy(auth_tok->session_key.decrypted_key, session_key, | 551 | memcpy(auth_tok->session_key.decrypted_key, session_key, |
@@ -546,6 +558,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
546 | if (ecryptfs_verbosity > 0) | 558 | if (ecryptfs_verbosity > 0) |
547 | ecryptfs_dump_hex(crypt_stat->key, | 559 | ecryptfs_dump_hex(crypt_stat->key, |
548 | crypt_stat->key_size); | 560 | crypt_stat->key_size); |
561 | out_free_memory: | ||
549 | memset(encrypted_session_key, 0, PAGE_CACHE_SIZE); | 562 | memset(encrypted_session_key, 0, PAGE_CACHE_SIZE); |
550 | free_page((unsigned long)encrypted_session_key); | 563 | free_page((unsigned long)encrypted_session_key); |
551 | memset(session_key, 0, PAGE_CACHE_SIZE); | 564 | memset(session_key, 0, PAGE_CACHE_SIZE); |
@@ -554,7 +567,7 @@ out_free_tfm: | |||
554 | if (tfm_mutex) | 567 | if (tfm_mutex) |
555 | mutex_unlock(tfm_mutex); | 568 | mutex_unlock(tfm_mutex); |
556 | else | 569 | else |
557 | crypto_free_tfm(tfm); | 570 | crypto_free_blkcipher(desc.tfm); |
558 | out: | 571 | out: |
559 | return rc; | 572 | return rc; |
560 | } | 573 | } |
@@ -803,19 +816,21 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
803 | struct ecryptfs_crypt_stat *crypt_stat, | 816 | struct ecryptfs_crypt_stat *crypt_stat, |
804 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | 817 | struct ecryptfs_key_record *key_rec, size_t *packet_size) |
805 | { | 818 | { |
806 | int rc = 0; | ||
807 | |||
808 | size_t i; | 819 | size_t i; |
809 | size_t signature_is_valid = 0; | 820 | size_t signature_is_valid = 0; |
810 | size_t encrypted_session_key_valid = 0; | 821 | size_t encrypted_session_key_valid = 0; |
811 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; | 822 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; |
812 | struct scatterlist dest_sg[2]; | 823 | struct scatterlist dest_sg[2]; |
813 | struct scatterlist src_sg[2]; | 824 | struct scatterlist src_sg[2]; |
814 | struct crypto_tfm *tfm = NULL; | ||
815 | struct mutex *tfm_mutex = NULL; | 825 | struct mutex *tfm_mutex = NULL; |
816 | size_t key_rec_size; | 826 | size_t key_rec_size; |
817 | size_t packet_size_length; | 827 | size_t packet_size_length; |
818 | size_t cipher_code; | 828 | size_t cipher_code; |
829 | struct blkcipher_desc desc = { | ||
830 | .tfm = NULL, | ||
831 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | ||
832 | }; | ||
833 | int rc = 0; | ||
819 | 834 | ||
820 | (*packet_size) = 0; | 835 | (*packet_size) = 0; |
821 | /* Check for a valid signature on the auth_tok */ | 836 | /* Check for a valid signature on the auth_tok */ |
@@ -882,33 +897,48 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
882 | if (!strcmp(crypt_stat->cipher, | 897 | if (!strcmp(crypt_stat->cipher, |
883 | crypt_stat->mount_crypt_stat->global_default_cipher_name) | 898 | crypt_stat->mount_crypt_stat->global_default_cipher_name) |
884 | && crypt_stat->mount_crypt_stat->global_key_tfm) { | 899 | && crypt_stat->mount_crypt_stat->global_key_tfm) { |
885 | tfm = crypt_stat->mount_crypt_stat->global_key_tfm; | 900 | desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm; |
886 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; | 901 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; |
887 | } else | 902 | } else { |
888 | tfm = crypto_alloc_tfm(crypt_stat->cipher, 0); | 903 | char *full_alg_name; |
889 | if (!tfm) { | 904 | |
890 | ecryptfs_printk(KERN_ERR, "Could not initialize crypto " | 905 | rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, |
891 | "context for cipher [%s]\n", | 906 | crypt_stat->cipher, |
892 | crypt_stat->cipher); | 907 | "ecb"); |
893 | rc = -EINVAL; | 908 | if (rc) |
894 | goto out; | 909 | goto out; |
910 | desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0, | ||
911 | CRYPTO_ALG_ASYNC); | ||
912 | kfree(full_alg_name); | ||
913 | if (IS_ERR(desc.tfm)) { | ||
914 | rc = PTR_ERR(desc.tfm); | ||
915 | ecryptfs_printk(KERN_ERR, "Could not initialize crypto " | ||
916 | "context for cipher [%s]; rc = [%d]\n", | ||
917 | crypt_stat->cipher, rc); | ||
918 | goto out; | ||
919 | } | ||
920 | crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY); | ||
895 | } | 921 | } |
896 | if (tfm_mutex) | 922 | if (tfm_mutex) |
897 | mutex_lock(tfm_mutex); | 923 | mutex_lock(tfm_mutex); |
898 | rc = crypto_cipher_setkey(tfm, session_key_encryption_key, | 924 | rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key, |
899 | crypt_stat->key_size); | 925 | crypt_stat->key_size); |
900 | if (rc < 0) { | 926 | if (rc < 0) { |
901 | if (tfm_mutex) | 927 | if (tfm_mutex) |
902 | mutex_unlock(tfm_mutex); | 928 | mutex_unlock(tfm_mutex); |
903 | ecryptfs_printk(KERN_ERR, "Error setting key for crypto " | 929 | ecryptfs_printk(KERN_ERR, "Error setting key for crypto " |
904 | "context\n"); | 930 | "context; rc = [%d]\n", rc); |
905 | goto out; | 931 | goto out; |
906 | } | 932 | } |
907 | rc = 0; | 933 | rc = 0; |
908 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", | 934 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", |
909 | crypt_stat->key_size); | 935 | crypt_stat->key_size); |
910 | crypto_cipher_encrypt(tfm, dest_sg, src_sg, | 936 | rc = crypto_blkcipher_encrypt(&desc, dest_sg, src_sg, |
911 | (*key_rec).enc_key_size); | 937 | (*key_rec).enc_key_size); |
938 | if (rc) { | ||
939 | printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc); | ||
940 | goto out; | ||
941 | } | ||
912 | if (tfm_mutex) | 942 | if (tfm_mutex) |
913 | mutex_unlock(tfm_mutex); | 943 | mutex_unlock(tfm_mutex); |
914 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); | 944 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); |
@@ -971,8 +1001,8 @@ encrypted_session_key_set: | |||
971 | (*key_rec).enc_key_size); | 1001 | (*key_rec).enc_key_size); |
972 | (*packet_size) += (*key_rec).enc_key_size; | 1002 | (*packet_size) += (*key_rec).enc_key_size; |
973 | out: | 1003 | out: |
974 | if (tfm && !tfm_mutex) | 1004 | if (desc.tfm && !tfm_mutex) |
975 | crypto_free_tfm(tfm); | 1005 | crypto_free_blkcipher(desc.tfm); |
976 | if (rc) | 1006 | if (rc) |
977 | (*packet_size) = 0; | 1007 | (*packet_size) = 0; |
978 | return rc; | 1008 | return rc; |