gss_krb5: Use confounder length in wrap code
All encryption types use a confounder at the beginning of the
wrap token. In all encryption types except arcfour-hmac, the
confounder is the same as the blocksize. arcfour-hmac has a
blocksize of one, but uses an eight byte confounder.
Add an entry to the crypto framework definitions for the
confounder length and change the wrap/unwrap code to use
the confounder length rather than assuming it is always
the blocksize.
Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>
Signed-off-by: Steve Dickson <steved@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 33ae702..ed4106a 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -554,9 +554,9 @@
/* hide the gss token header and insert the confounder */
offset += GSS_KRB5_TOK_HDR_LEN;
- if (xdr_extend_head(buf, offset, blocksize))
+ if (xdr_extend_head(buf, offset, kctx->gk5e->conflen))
return GSS_S_FAILURE;
- gss_krb5_make_confounder(buf->head[0].iov_base + offset, blocksize);
+ gss_krb5_make_confounder(buf->head[0].iov_base + offset, kctx->gk5e->conflen);
offset -= GSS_KRB5_TOK_HDR_LEN;
if (buf->tail[0].iov_base != NULL) {
@@ -726,7 +726,7 @@
ret = GSS_S_BAD_SIG;
goto out_err;
}
- *headskip = crypto_blkcipher_blocksize(cipher);
+ *headskip = kctx->gk5e->conflen;
*tailskip = kctx->gk5e->cksumlength;
out_err:
if (ret && ret != GSS_S_BAD_SIG)
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 893fad7..ef6b313 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -68,6 +68,7 @@
.keybytes = 7,
.keylength = 8,
.blocksize = 8,
+ .conflen = 8,
.cksumlength = 8,
.keyed_cksum = 0,
},
@@ -88,6 +89,7 @@
.keybytes = 21,
.keylength = 24,
.blocksize = 8,
+ .conflen = 8,
.cksumlength = 20,
.keyed_cksum = 1,
},
@@ -110,6 +112,7 @@
.keybytes = 16,
.keylength = 16,
.blocksize = 16,
+ .conflen = 16,
.cksumlength = 12,
.keyed_cksum = 1,
},
@@ -132,6 +135,7 @@
.keybytes = 32,
.keylength = 32,
.blocksize = 16,
+ .conflen = 16,
.cksumlength = 12,
.keyed_cksum = 1,
},
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index a95e7e0a..383db89 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -168,6 +168,7 @@
struct page **tmp_pages;
u32 seq_send;
u8 *cksumkey;
+ u32 conflen = kctx->gk5e->conflen;
dprintk("RPC: %s\n", __func__);
@@ -176,7 +177,7 @@
blocksize = crypto_blkcipher_blocksize(kctx->enc);
gss_krb5_add_padding(buf, offset, blocksize);
BUG_ON((buf->len - offset) % blocksize);
- plainlen = blocksize + buf->len - offset;
+ plainlen = conflen + buf->len - offset;
headlen = g_token_size(&kctx->mech_used,
GSS_KRB5_TOK_HDR_LEN + kctx->gk5e->cksumlength + plainlen) -
@@ -204,7 +205,7 @@
memset(ptr + 4, 0xff, 4);
*(__be16 *)(ptr + 4) = cpu_to_le16(kctx->gk5e->sealalg);
- gss_krb5_make_confounder(msg_start, blocksize);
+ gss_krb5_make_confounder(msg_start, conflen);
if (kctx->gk5e->keyed_cksum)
cksumkey = kctx->cksum;
@@ -214,7 +215,7 @@
/* XXXJBF: UGH!: */
tmp_pages = buf->pages;
buf->pages = pages;
- if (make_checksum(kctx, ptr, 8, buf, offset + headlen - blocksize,
+ if (make_checksum(kctx, ptr, 8, buf, offset + headlen - conflen,
cksumkey, KG_USAGE_SEAL, &md5cksum))
return GSS_S_FAILURE;
buf->pages = tmp_pages;
@@ -231,7 +232,7 @@
seq_send, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8)))
return GSS_S_FAILURE;
- if (gss_encrypt_xdr_buf(kctx->enc, buf, offset + headlen - blocksize,
+ if (gss_encrypt_xdr_buf(kctx->enc, buf, offset + headlen - conflen,
pages))
return GSS_S_FAILURE;
@@ -254,6 +255,7 @@
void *data_start, *orig_start;
int data_len;
int blocksize;
+ u32 conflen = kctx->gk5e->conflen;
int crypt_offset;
u8 *cksumkey;
@@ -327,7 +329,7 @@
blocksize = crypto_blkcipher_blocksize(kctx->enc);
data_start = ptr + (GSS_KRB5_TOK_HDR_LEN + kctx->gk5e->cksumlength) +
- blocksize;
+ conflen;
orig_start = buf->head[0].iov_base + offset;
data_len = (buf->head[0].iov_base + buf->head[0].iov_len) - data_start;
memmove(orig_start, data_start, data_len);