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 --- include/linux/sunrpc/gss_krb5.h | 4 ++-- net/sunrpc/auth_gss/gss_krb5_crypto.c | 15 +++++++++++---- net/sunrpc/auth_gss/gss_krb5_seal.c | 13 +++++++++---- net/sunrpc/auth_gss/gss_krb5_unseal.c | 12 ++++++++---- net/sunrpc/auth_gss/gss_krb5_wrap.c | 4 ++-- 5 files changed, 32 insertions(+), 16 deletions(-) diff -up linux-2.6.29.noarch/include/linux/sunrpc/gss_krb5.h.orig linux-2.6.29.noarch/include/linux/sunrpc/gss_krb5.h --- linux-2.6.29.noarch/include/linux/sunrpc/gss_krb5.h.orig 2009-04-30 16:04:24.038137000 -0400 +++ linux-2.6.29.noarch/include/linux/sunrpc/gss_krb5.h 2009-04-30 16:07:52.464378000 -0400 @@ -235,12 +235,12 @@ enum seal_alg { 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 -up linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_crypto.c.orig linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_crypto.c --- linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_crypto.c.orig 2009-04-30 16:04:24.049134000 -0400 +++ linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_crypto.c 2009-04-30 16:07:52.472369000 -0400 @@ -133,7 +133,7 @@ checksummer(struct scatterlist *sg, void 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]; @@ -209,7 +209,7 @@ out: 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]; @@ -556,15 +556,18 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kc 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); @@ -609,7 +612,8 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kc 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; @@ -673,15 +677,18 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kc 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); @@ -724,7 +731,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kc 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 -up linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_seal.c.orig linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_seal.c --- linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_seal.c.orig 2009-04-30 16:01:00.776532000 -0400 +++ linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_seal.c 2009-04-30 16:07:52.481360000 -0400 @@ -143,7 +143,8 @@ gss_get_mic_v1(struct krb5_ctx *ctx, str 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); @@ -171,6 +172,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, str s32 now; u64 seq_send; u8 *cksumkey; + unsigned int cksum_usage; dprintk("RPC: %s\n", __func__); BUG_ON(ctx == NULL); @@ -184,13 +186,16 @@ gss_get_mic_v2(struct krb5_ctx *ctx, str 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 -up linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_unseal.c.orig linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_unseal.c --- linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_unseal.c.orig 2009-04-30 16:01:00.783534000 -0400 +++ linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_unseal.c 2009-04-30 16:07:52.489352000 -0400 @@ -116,7 +116,7 @@ gss_verify_mic_v1(struct krb5_ctx *ctx, 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, @@ -155,6 +155,7 @@ gss_verify_mic_v2(struct krb5_ctx *ctx, u8 *cksumkey; u8 flags; int i; + unsigned int cksum_usage; dprintk("RPC: %s\n", __func__); @@ -175,13 +176,16 @@ gss_verify_mic_v2(struct krb5_ctx *ctx, 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 -up linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_wrap.c.orig linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_wrap.c --- linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_wrap.c.orig 2009-04-30 16:04:24.074134000 -0400 +++ linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_wrap.c 2009-04-30 16:07:52.497344000 -0400 @@ -217,7 +217,7 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kc 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; @@ -300,7 +300,7 @@ gss_unwrap_kerberos_v1(struct krb5_ctx * 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,