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.c101
1 files changed, 67 insertions, 34 deletions
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index bc706d33559a..c3746f56d162 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -458,14 +458,16 @@ out:
458static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, 458static 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,22 +484,32 @@ 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 }
506 crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
495 } 507 }
496 if (tfm_mutex) 508 if (tfm_mutex)
497 mutex_lock(tfm_mutex); 509 mutex_lock(tfm_mutex);
498 rc = crypto_cipher_setkey(tfm, 510 rc = crypto_blkcipher_setkey(desc.tfm,
499 password_s_ptr->session_key_encryption_key, 511 password_s_ptr->session_key_encryption_key,
500 crypt_stat->key_size); 512 crypt_stat->key_size);
501 if (rc < 0) { 513 if (rc < 0) {
502 printk(KERN_ERR "Error setting key for crypto context\n"); 514 printk(KERN_ERR "Error setting key for crypto context\n");
503 rc = -EINVAL; 515 rc = -EINVAL;
@@ -528,9 +540,12 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
528 auth_tok->session_key.decrypted_key_size = 540 auth_tok->session_key.decrypted_key_size =
529 auth_tok->session_key.encrypted_key_size; 541 auth_tok->session_key.encrypted_key_size;
530 dst_sg[0].length = auth_tok->session_key.encrypted_key_size; 542 dst_sg[0].length = auth_tok->session_key.encrypted_key_size;
531 /* TODO: Handle error condition */ 543 rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg,
532 crypto_cipher_decrypt(tfm, dst_sg, src_sg, 544 auth_tok->session_key.encrypted_key_size);
533 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 }
534 auth_tok->session_key.decrypted_key_size = 549 auth_tok->session_key.decrypted_key_size =
535 auth_tok->session_key.encrypted_key_size; 550 auth_tok->session_key.encrypted_key_size;
536 memcpy(auth_tok->session_key.decrypted_key, session_key, 551 memcpy(auth_tok->session_key.decrypted_key, session_key,
@@ -543,6 +558,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
543 if (ecryptfs_verbosity > 0) 558 if (ecryptfs_verbosity > 0)
544 ecryptfs_dump_hex(crypt_stat->key, 559 ecryptfs_dump_hex(crypt_stat->key,
545 crypt_stat->key_size); 560 crypt_stat->key_size);
561out_free_memory:
546 memset(encrypted_session_key, 0, PAGE_CACHE_SIZE); 562 memset(encrypted_session_key, 0, PAGE_CACHE_SIZE);
547 free_page((unsigned long)encrypted_session_key); 563 free_page((unsigned long)encrypted_session_key);
548 memset(session_key, 0, PAGE_CACHE_SIZE); 564 memset(session_key, 0, PAGE_CACHE_SIZE);
@@ -551,7 +567,7 @@ out_free_tfm:
551 if (tfm_mutex) 567 if (tfm_mutex)
552 mutex_unlock(tfm_mutex); 568 mutex_unlock(tfm_mutex);
553 else 569 else
554 crypto_free_tfm(tfm); 570 crypto_free_blkcipher(desc.tfm);
555out: 571out:
556 return rc; 572 return rc;
557} 573}
@@ -800,19 +816,21 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
800 struct ecryptfs_crypt_stat *crypt_stat, 816 struct ecryptfs_crypt_stat *crypt_stat,
801 struct ecryptfs_key_record *key_rec, size_t *packet_size) 817 struct ecryptfs_key_record *key_rec, size_t *packet_size)
802{ 818{
803 int rc = 0;
804
805 size_t i; 819 size_t i;
806 size_t signature_is_valid = 0; 820 size_t signature_is_valid = 0;
807 size_t encrypted_session_key_valid = 0; 821 size_t encrypted_session_key_valid = 0;
808 char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; 822 char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
809 struct scatterlist dest_sg[2]; 823 struct scatterlist dest_sg[2];
810 struct scatterlist src_sg[2]; 824 struct scatterlist src_sg[2];
811 struct crypto_tfm *tfm = NULL;
812 struct mutex *tfm_mutex = NULL; 825 struct mutex *tfm_mutex = NULL;
813 size_t key_rec_size; 826 size_t key_rec_size;
814 size_t packet_size_length; 827 size_t packet_size_length;
815 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;
816 834
817 (*packet_size) = 0; 835 (*packet_size) = 0;
818 /* Check for a valid signature on the auth_tok */ 836 /* Check for a valid signature on the auth_tok */
@@ -879,33 +897,48 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
879 if (!strcmp(crypt_stat->cipher, 897 if (!strcmp(crypt_stat->cipher,
880 crypt_stat->mount_crypt_stat->global_default_cipher_name) 898 crypt_stat->mount_crypt_stat->global_default_cipher_name)
881 && crypt_stat->mount_crypt_stat->global_key_tfm) { 899 && crypt_stat->mount_crypt_stat->global_key_tfm) {
882 tfm = crypt_stat->mount_crypt_stat->global_key_tfm; 900 desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
883 tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; 901 tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
884 } else 902 } else {
885 tfm = crypto_alloc_tfm(crypt_stat->cipher, 0); 903 char *full_alg_name;
886 if (!tfm) { 904
887 ecryptfs_printk(KERN_ERR, "Could not initialize crypto " 905 rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
888 "context for cipher [%s]\n", 906 crypt_stat->cipher,
889 crypt_stat->cipher); 907 "ecb");
890 rc = -EINVAL; 908 if (rc)
891 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);
892 } 921 }
893 if (tfm_mutex) 922 if (tfm_mutex)
894 mutex_lock(tfm_mutex); 923 mutex_lock(tfm_mutex);
895 rc = crypto_cipher_setkey(tfm, session_key_encryption_key, 924 rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key,
896 crypt_stat->key_size); 925 crypt_stat->key_size);
897 if (rc < 0) { 926 if (rc < 0) {
898 if (tfm_mutex) 927 if (tfm_mutex)
899 mutex_unlock(tfm_mutex); 928 mutex_unlock(tfm_mutex);
900 ecryptfs_printk(KERN_ERR, "Error setting key for crypto " 929 ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
901 "context\n"); 930 "context; rc = [%d]\n", rc);
902 goto out; 931 goto out;
903 } 932 }
904 rc = 0; 933 rc = 0;
905 ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", 934 ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
906 crypt_stat->key_size); 935 crypt_stat->key_size);
907 crypto_cipher_encrypt(tfm, dest_sg, src_sg, 936 rc = crypto_blkcipher_encrypt(&desc, dest_sg, src_sg,
908 (*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 }
909 if (tfm_mutex) 942 if (tfm_mutex)
910 mutex_unlock(tfm_mutex); 943 mutex_unlock(tfm_mutex);
911 ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); 944 ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
@@ -968,8 +1001,8 @@ encrypted_session_key_set:
968 (*key_rec).enc_key_size); 1001 (*key_rec).enc_key_size);
969 (*packet_size) += (*key_rec).enc_key_size; 1002 (*packet_size) += (*key_rec).enc_key_size;
970out: 1003out:
971 if (tfm && !tfm_mutex) 1004 if (desc.tfm && !tfm_mutex)
972 crypto_free_tfm(tfm); 1005 crypto_free_blkcipher(desc.tfm);
973 if (rc) 1006 if (rc)
974 (*packet_size) = 0; 1007 (*packet_size) = 0;
975 return rc; 1008 return rc;