diff options
Diffstat (limited to 'fs/ecryptfs/keystore.c')
-rw-r--r-- | fs/ecryptfs/keystore.c | 101 |
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: | |||
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,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); |
561 | out_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); |
555 | out: | 571 | out: |
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; |
970 | out: | 1003 | out: |
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; |