[PATCH 23/28] gss_krb5: preallocate cbc(aes) cipher during context creation

Kevin Coffman kwc at citi.umich.edu
Mon Mar 31 10:32:50 EDT 2008


Rather than allocating and deleting the cbc(aes) cipher each time it
is needed, pre-allocate the cipher during context creation.

Signed-off-by: Kevin Coffman <kwc at citi.umich.edu>
---

 include/linux/sunrpc/gss_krb5.h       |    2 ++
 net/sunrpc/auth_gss/gss_krb5_crypto.c |   44 ++++++++-------------------------
 net/sunrpc/auth_gss/gss_krb5_mech.c   |   40 +++++++++++++++++++++++-------
 3 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
index a408643..356be4e 100644
--- a/include/linux/sunrpc/gss_krb5.h
+++ b/include/linux/sunrpc/gss_krb5.h
@@ -99,6 +99,8 @@ struct krb5_ctx {
 	struct crypto_blkcipher	*seq;
 	struct crypto_blkcipher *acceptor_enc;
 	struct crypto_blkcipher *initiator_enc;
+	struct crypto_blkcipher *acceptor_enc_aux;
+	struct crypto_blkcipher *initiator_enc_aux;
 	u8			cksum[GSS_KRB5_MAX_KEYLEN];
 	s32			endtime;
 	u32			seq_send;
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 55a3995..950a29a 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -503,9 +503,9 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
 {
 	u32 err;
 	struct xdr_netobj hmac;
-	u8 *cksumkey, *enckey;
+	u8 *cksumkey;
 	u8 *ecptr;
-	struct crypto_blkcipher *cipher, *cbc = NULL;
+	struct crypto_blkcipher *cipher, *aux_cipher;
 	int blocksize;
 	struct page **save_pages;
 	int nblocks, nbytes;
@@ -514,11 +514,11 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
 
 	if (kctx->initiate) {
 		cipher = kctx->initiator_enc;
-		enckey = kctx->initiator_seal;
+		aux_cipher = kctx->initiator_enc_aux;
 		cksumkey = kctx->initiator_integ;
 	} else {
 		cipher = kctx->acceptor_enc;
-		enckey = kctx->acceptor_seal;
+		aux_cipher = kctx->acceptor_enc_aux;
 		cksumkey = kctx->acceptor_integ;
 	}
 	blocksize = crypto_blkcipher_blocksize(cipher);
@@ -577,15 +577,6 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
 	memset(desc.iv, 0, sizeof(desc.iv));
 
 	if (cbcbytes) {
-		/* XXX This does a kzalloc, may need to pre-allocate this! */
-		cbc = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
-		if (cbc == NULL)
-			return GSS_S_FAILURE;
-		err = crypto_blkcipher_setkey(cbc, enckey,
-					      kctx->gk5e->keylength);
-		if (err)
-			goto out_err;
-
 		desc.pos = offset + 16;
 		desc.fragno = 0;
 		desc.fraglen = 0;
@@ -593,7 +584,7 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
 		desc.outbuf = buf;
 		desc.desc.info = desc.iv;
 		desc.desc.flags = 0;
-		desc.desc.tfm = cbc;
+		desc.desc.tfm = aux_cipher;
 
 		sg_init_table(desc.infrags, 4);
 		sg_init_table(desc.outfrags, 4);
@@ -617,8 +608,6 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
 	buf->len += kctx->gk5e->cksumlength;
 
 out_err:
-	if (cbc != NULL)
-		crypto_free_blkcipher(cbc);
 	if (err)
 		err = GSS_S_FAILURE;
 	return err;
@@ -630,8 +619,8 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf,
 {
 	struct xdr_buf subbuf;
 	u32 ret = 0;
-	u8 *cksum_key, *enckey;
-	struct crypto_blkcipher *cipher, *cbc = NULL;
+	u8 *cksum_key;
+	struct crypto_blkcipher *cipher, *aux_cipher;
 	struct xdr_netobj our_hmac_obj;
 	u8 our_hmac[GSS_KRB5_MAX_CKSUM_LEN];
 	u8 pkt_hmac[GSS_KRB5_MAX_CKSUM_LEN];
@@ -640,11 +629,11 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf,
 
 	if (kctx->initiate) {
 		cipher = kctx->acceptor_enc;
-		enckey = kctx->acceptor_seal;
+		aux_cipher = kctx->acceptor_enc_aux;
 		cksum_key = kctx->acceptor_integ;
 	} else {
 		cipher = kctx->initiator_enc;
-		enckey = kctx->initiator_seal;
+		aux_cipher = kctx->initiator_enc_aux;
 		cksum_key = kctx->initiator_integ;
 	}
 	blocksize = crypto_blkcipher_blocksize(cipher);
@@ -663,22 +652,11 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf,
 	memset(desc.iv, 0, sizeof(desc.iv));
 
 	if (cbcbytes) {
-		/* XXX This does a kzalloc, may need to pre-allocate this! */
-		cbc = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
-		if (cbc == NULL) {
-			ret = GSS_S_FAILURE;
-			goto out_err;
-		}
-		ret = crypto_blkcipher_setkey(cbc, enckey,
-					      kctx->gk5e->keylength);
-		if (ret)
-			goto out_err;
-
 		desc.fragno = 0;
 		desc.fraglen = 0;
 		desc.desc.info = desc.iv;
 		desc.desc.flags = 0;
-		desc.desc.tfm = cbc;
+		desc.desc.tfm = aux_cipher;
 
 		sg_init_table(desc.frags, 4);
 
@@ -715,8 +693,6 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf,
 	*headskip = crypto_blkcipher_blocksize(cipher);
 	*tailskip = kctx->gk5e->cksumlength;
 out_err:
-	if (cbc != NULL)
-		crypto_free_blkcipher(cbc);
 	if (ret && ret != GSS_S_BAD_SIG)
 		ret = GSS_S_FAILURE;
 	return ret;
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 7e52ccd..72adbec 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -312,20 +312,19 @@ out_err:
 }
 
 struct crypto_blkcipher *
-context_v2_alloc_cipher(struct krb5_ctx *ctx, u8 *key)
+context_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key)
 {
 	struct crypto_blkcipher *cp;
 
-	cp = crypto_alloc_blkcipher(ctx->gk5e->encrypt_name,
-					0, CRYPTO_ALG_ASYNC);
+	cp = crypto_alloc_blkcipher(cname, 0, CRYPTO_ALG_ASYNC);
 	if (IS_ERR(cp)) {
 		printk("gss_kerberos_mech: unable to initialize "
-			"crypto algorithm %s\n", ctx->gk5e->encrypt_name);
+			"crypto algorithm %s\n", cname);
 		return NULL;
 	}
 	if (crypto_blkcipher_setkey(cp, key, ctx->gk5e->keylength)) {
 		printk("gss_kerberos_mech: error setting key for "
-			"crypto algorithm %s\n", ctx->gk5e->encrypt_name);
+			"crypto algorithm %s\n", cname);
 		crypto_free_blkcipher(cp);
 		return NULL;
 	}
@@ -357,11 +356,11 @@ context_derive_keys_des3(struct krb5_ctx *ctx, u8 *rawkey, u32 keylen)
 	keyout.len = keylen;
 
 	/* seq uses the raw key */
-	ctx->seq = context_v2_alloc_cipher(ctx, rawkey);
+	ctx->seq = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, rawkey);
 	if (ctx->seq == NULL)
 		goto out_err;
 
-	ctx->enc = context_v2_alloc_cipher(ctx, rawkey);
+	ctx->enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, rawkey);
 	if (ctx->enc == NULL)
 		goto out_free_seq;
 
@@ -408,7 +407,9 @@ context_derive_keys_new(struct krb5_ctx *ctx, u8 *rawkey, u32 keylen)
 			__func__, err);
 		goto out_err;
 	}
-	ctx->initiator_enc = context_v2_alloc_cipher(ctx, ctx->initiator_seal);
+	ctx->initiator_enc = context_v2_alloc_cipher(ctx,
+						     ctx->gk5e->encrypt_name,
+						     ctx->initiator_seal);
 	if (ctx->initiator_enc == NULL)
 		goto out_err;
 
@@ -421,7 +422,9 @@ context_derive_keys_new(struct krb5_ctx *ctx, u8 *rawkey, u32 keylen)
 			__func__, err);
 		goto out_free_initiator_enc;
 	}
-	ctx->acceptor_enc = context_v2_alloc_cipher(ctx, ctx->acceptor_seal);
+	ctx->acceptor_enc = context_v2_alloc_cipher(ctx,
+						    ctx->gk5e->encrypt_name,
+						    ctx->acceptor_seal);
 	if (ctx->acceptor_enc == NULL)
 		goto out_free_initiator_enc;
 
@@ -465,6 +468,23 @@ context_derive_keys_new(struct krb5_ctx *ctx, u8 *rawkey, u32 keylen)
 		goto out_free_acceptor_enc;
 	}
 
+	switch (ctx->enctype) {
+	case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+	case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
+		ctx->initiator_enc_aux =
+			context_v2_alloc_cipher(ctx, "cbc(aes)",
+						ctx->initiator_seal);
+		if (ctx->initiator_enc_aux == NULL)
+			goto out_free_acceptor_enc;
+		ctx->acceptor_enc_aux =
+			context_v2_alloc_cipher(ctx, "cbc(aes)",
+						ctx->acceptor_seal);
+		if (ctx->acceptor_enc_aux == NULL) {
+			crypto_free_blkcipher(ctx->initiator_enc_aux);
+			goto out_free_acceptor_enc;
+		}
+	}
+	    
 	return 0;
 
 out_free_acceptor_enc:
@@ -572,6 +592,8 @@ gss_delete_sec_context_kerberos(void *internal_ctx) {
 	crypto_free_blkcipher(kctx->enc);
 	crypto_free_blkcipher(kctx->acceptor_enc);
 	crypto_free_blkcipher(kctx->initiator_enc);
+	crypto_free_blkcipher(kctx->acceptor_enc_aux);
+	crypto_free_blkcipher(kctx->initiator_enc_aux);
 	kfree(kctx->mech_used.data);
 	kfree(kctx);
 }



More information about the NFSv4 mailing list