[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