gssd_krb5: arcfour-hmac support
For arcfour-hmac support, the make_checksum function needs a usage
field to correctly calculate the checksum differently for MIC and
WRAP tokens.
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/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
index 43148ec..633f41f 100644
--- a/include/linux/sunrpc/gss_krb5.h
+++ b/include/linux/sunrpc/gss_krb5.h
@@ -235,12 +235,12 @@
u32
make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen,
struct xdr_buf *body, int body_offset, u8 *cksumkey,
- struct xdr_netobj *cksumout);
+ unsigned int usage, struct xdr_netobj *cksumout);
u32
make_checksum_v2(struct krb5_ctx *, char *header, int hdrlen,
struct xdr_buf *body, int body_offset, u8 *key,
- struct xdr_netobj *cksum);
+ unsigned int usage, struct xdr_netobj *cksum);
u32 gss_get_mic_kerberos(struct gss_ctx *, struct xdr_buf *,
struct xdr_netobj *);
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 967484a..33ae702 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -132,7 +132,7 @@
u32
make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen,
struct xdr_buf *body, int body_offset, u8 *cksumkey,
- struct xdr_netobj *cksumout)
+ unsigned int usage, struct xdr_netobj *cksumout)
{
struct hash_desc desc;
struct scatterlist sg[1];
@@ -208,7 +208,7 @@
u32
make_checksum_v2(struct krb5_ctx *kctx, char *header, int hdrlen,
struct xdr_buf *body, int body_offset, u8 *cksumkey,
- struct xdr_netobj *cksumout)
+ unsigned int usage, struct xdr_netobj *cksumout)
{
struct hash_desc desc;
struct scatterlist sg[1];
@@ -537,15 +537,18 @@
int nblocks, nbytes;
struct encryptor_desc desc;
u32 cbcbytes;
+ unsigned int usage;
if (kctx->initiate) {
cipher = kctx->initiator_enc;
aux_cipher = kctx->initiator_enc_aux;
cksumkey = kctx->initiator_integ;
+ usage = KG_USAGE_INITIATOR_SEAL;
} else {
cipher = kctx->acceptor_enc;
aux_cipher = kctx->acceptor_enc_aux;
cksumkey = kctx->acceptor_integ;
+ usage = KG_USAGE_ACCEPTOR_SEAL;
}
blocksize = crypto_blkcipher_blocksize(cipher);
@@ -590,7 +593,8 @@
buf->pages = pages;
err = make_checksum_v2(kctx, NULL, 0, buf,
- offset + GSS_KRB5_TOK_HDR_LEN, cksumkey, &hmac);
+ offset + GSS_KRB5_TOK_HDR_LEN,
+ cksumkey, usage, &hmac);
buf->pages = save_pages;
if (err)
return GSS_S_FAILURE;
@@ -654,15 +658,18 @@
u8 pkt_hmac[GSS_KRB5_MAX_CKSUM_LEN];
int nblocks, blocksize, cbcbytes;
struct decryptor_desc desc;
+ unsigned int usage;
if (kctx->initiate) {
cipher = kctx->acceptor_enc;
aux_cipher = kctx->acceptor_enc_aux;
cksum_key = kctx->acceptor_integ;
+ usage = KG_USAGE_ACCEPTOR_SEAL;
} else {
cipher = kctx->initiator_enc;
aux_cipher = kctx->initiator_enc_aux;
cksum_key = kctx->initiator_integ;
+ usage = KG_USAGE_INITIATOR_SEAL;
}
blocksize = crypto_blkcipher_blocksize(cipher);
@@ -705,7 +712,7 @@
our_hmac_obj.data = our_hmac;
ret = make_checksum_v2(kctx, NULL, 0, &subbuf, 0,
- cksum_key, &our_hmac_obj);
+ cksum_key, usage, &our_hmac_obj);
if (ret)
goto out_err;
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index 477a546..e22fed3d 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -142,7 +142,8 @@
else
cksumkey = NULL;
- if (make_checksum(ctx, ptr, 8, text, 0, cksumkey, &md5cksum))
+ if (make_checksum(ctx, ptr, 8, text, 0, cksumkey,
+ KG_USAGE_SIGN, &md5cksum))
return GSS_S_FAILURE;
memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len);
@@ -170,6 +171,7 @@
s32 now;
u64 seq_send;
u8 *cksumkey;
+ unsigned int cksum_usage;
dprintk("RPC: %s\n", __func__);
@@ -182,13 +184,16 @@
spin_unlock(&krb5_seq_lock);
*((u64 *)(krb5_hdr + 8)) = cpu_to_be64(seq_send);
- if (ctx->initiate)
+ if (ctx->initiate) {
cksumkey = ctx->initiator_sign;
- else
+ cksum_usage = KG_USAGE_INITIATOR_SIGN;
+ } else {
cksumkey = ctx->acceptor_sign;
+ cksum_usage = KG_USAGE_ACCEPTOR_SIGN;
+ }
if (make_checksum_v2(ctx, krb5_hdr, GSS_KRB5_TOK_HDR_LEN,
- text, 0, cksumkey, &cksumobj))
+ text, 0, cksumkey, cksum_usage, &cksumobj))
return GSS_S_FAILURE;
memcpy(krb5_hdr + GSS_KRB5_TOK_HDR_LEN, cksumobj.data, cksumobj.len);
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index 4ede4cc..ef91366 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -115,7 +115,7 @@
cksumkey = NULL;
if (make_checksum(ctx, ptr, 8, message_buffer, 0,
- cksumkey, &md5cksum))
+ cksumkey, KG_USAGE_SIGN, &md5cksum))
return GSS_S_FAILURE;
if (memcmp(md5cksum.data, ptr + GSS_KRB5_TOK_HDR_LEN,
@@ -154,6 +154,7 @@
u8 *cksumkey;
u8 flags;
int i;
+ unsigned int cksum_usage;
dprintk("RPC: %s\n", __func__);
@@ -174,13 +175,16 @@
if (ptr[i] != 0xff)
return GSS_S_DEFECTIVE_TOKEN;
- if (ctx->initiate)
+ if (ctx->initiate) {
cksumkey = ctx->acceptor_sign;
- else
+ cksum_usage = KG_USAGE_ACCEPTOR_SIGN;
+ } else {
cksumkey = ctx->initiator_sign;
+ cksum_usage = KG_USAGE_INITIATOR_SIGN;
+ }
if (make_checksum_v2(ctx, ptr, GSS_KRB5_TOK_HDR_LEN, message_buffer, 0,
- cksumkey, &cksumobj))
+ cksumkey, cksum_usage, &cksumobj))
return GSS_S_FAILURE;
if (memcmp(cksumobj.data, ptr + GSS_KRB5_TOK_HDR_LEN,
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index a1a3585..097cc27 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -215,7 +215,7 @@
tmp_pages = buf->pages;
buf->pages = pages;
if (make_checksum(kctx, ptr, 8, buf, offset + headlen - blocksize,
- cksumkey, &md5cksum))
+ cksumkey, KG_USAGE_SEAL, &md5cksum))
return GSS_S_FAILURE;
buf->pages = tmp_pages;
@@ -298,7 +298,7 @@
cksumkey = NULL;
if (make_checksum(kctx, ptr, 8, buf, crypt_offset,
- cksumkey, &md5cksum))
+ cksumkey, KG_USAGE_SEAL, &md5cksum))
return GSS_S_FAILURE;
if (memcmp(md5cksum.data, ptr + GSS_KRB5_TOK_HDR_LEN,