struct ecryptfs_crypt_stat *crypt_stat,
                                  char *src, int len)
 {
-       int rc = 0;
        struct scatterlist sg;
+       struct hash_desc desc = {
+               .tfm = crypt_stat->hash_tfm,
+               .flags = CRYPTO_TFM_REQ_MAY_SLEEP
+       };
+       int rc = 0;
 
-       mutex_lock(&crypt_stat->cs_md5_tfm_mutex);
+       mutex_lock(&crypt_stat->cs_hash_tfm_mutex);
        sg_init_one(&sg, (u8 *)src, len);
-       if (!crypt_stat->md5_tfm) {
-               crypt_stat->md5_tfm =
-                       crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP);
-               if (!crypt_stat->md5_tfm) {
-                       rc = -ENOMEM;
+       if (!desc.tfm) {
+               desc.tfm = crypto_alloc_hash(ECRYPTFS_DEFAULT_HASH, 0,
+                                            CRYPTO_ALG_ASYNC);
+               if (IS_ERR(desc.tfm)) {
+                       rc = PTR_ERR(desc.tfm);
                        ecryptfs_printk(KERN_ERR, "Error attempting to "
-                                       "allocate crypto context\n");
+                                       "allocate crypto context; rc = [%d]\n",
+                                       rc);
                        goto out;
                }
+               crypt_stat->hash_tfm = desc.tfm;
        }
-       crypto_digest_init(crypt_stat->md5_tfm);
-       crypto_digest_update(crypt_stat->md5_tfm, &sg, 1);
-       crypto_digest_final(crypt_stat->md5_tfm, dst);
-       mutex_unlock(&crypt_stat->cs_md5_tfm_mutex);
+       crypto_hash_init(&desc);
+       crypto_hash_update(&desc, &sg, len);
+       crypto_hash_final(&desc, dst);
+       mutex_unlock(&crypt_stat->cs_hash_tfm_mutex);
 out:
        return rc;
 }
        memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
        mutex_init(&crypt_stat->cs_mutex);
        mutex_init(&crypt_stat->cs_tfm_mutex);
-       mutex_init(&crypt_stat->cs_md5_tfm_mutex);
+       mutex_init(&crypt_stat->cs_hash_tfm_mutex);
        ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED);
 }
 
 {
        if (crypt_stat->tfm)
                crypto_free_tfm(crypt_stat->tfm);
-       if (crypt_stat->md5_tfm)
-               crypto_free_tfm(crypt_stat->md5_tfm);
+       if (crypt_stat->hash_tfm)
+               crypto_free_hash(crypt_stat->hash_tfm);
        memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
 }
 
 
 #define ECRYPTFS_DEFAULT_CIPHER "aes"
 #define ECRYPTFS_DEFAULT_KEY_BYTES 16
 #define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC
+#define ECRYPTFS_DEFAULT_HASH "md5"
 #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C
 #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED
 #define MD5_DIGEST_SIZE 16
        unsigned int extent_mask;
        struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
        struct crypto_tfm *tfm;
-       struct crypto_tfm *md5_tfm; /* Crypto context for generating
-                                    * the initialization vectors */
+       struct crypto_hash *hash_tfm; /* Crypto context for generating
+                                      * the initialization vectors */
        unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE];
        unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
        unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
        unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX];
        struct mutex cs_tfm_mutex;
-       struct mutex cs_md5_tfm_mutex;
+       struct mutex cs_hash_tfm_mutex;
        struct mutex cs_mutex;
 };