Add the final pieces to support the triple-des encryption type. Signed-off-by: Kevin Coffman --- fs/Kconfig | 2 + include/linux/sunrpc/gss_krb5.h | 5 +++ net/sunrpc/auth_gss/gss_krb5_crypto.c | 3 ++ net/sunrpc/auth_gss/gss_krb5_keys.c | 53 +++++++++++++++++++++++++++++++++ net/sunrpc/auth_gss/gss_krb5_mech.c | 23 ++++++++++++++ net/sunrpc/auth_gss/gss_krb5_seal.c | 1 + net/sunrpc/auth_gss/gss_krb5_unseal.c | 1 + net/sunrpc/auth_gss/gss_krb5_wrap.c | 2 + 8 files changed, 90 insertions(+), 0 deletions(-) diff -up linux-2.6.29.noarch/fs/Kconfig.orig linux-2.6.29.noarch/fs/Kconfig 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 15:50:32.569914000 -0400 +++ linux-2.6.29.noarch/include/linux/sunrpc/gss_krb5.h 2009-04-30 15:51:36.272756000 -0400 @@ -261,3 +261,8 @@ krb5_derive_key(struct gss_krb5_enctype const struct xdr_netobj *inkey, struct xdr_netobj *outkey, const struct xdr_netobj *in_constant); + +u32 +gss_krb5_des3_make_key(struct gss_krb5_enctype *gk5e, + struct xdr_netobj *randombits, + struct xdr_netobj *key); 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 15:46:42.458094000 -0400 +++ linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_crypto.c 2009-04-30 15:51:36.281756000 -0400 @@ -185,6 +185,9 @@ make_checksum(struct krb5_ctx *kctx, cha checksumdata + checksumlen - kctx->gk5e->cksumlength, kctx->gk5e->cksumlength); break; + case CKSUMTYPE_HMAC_SHA1_DES3: + memcpy(cksumout->data, checksumdata, kctx->gk5e->cksumlength); + break; default: BUG(); break; diff -up linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_keys.c.orig linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_keys.c --- linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_keys.c.orig 2009-04-30 15:48:33.688768000 -0400 +++ linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_keys.c 2009-04-30 15:51:36.288756000 -0400 @@ -250,3 +250,56 @@ err_free_cipher: err_return: return ret; } + +#define smask(step) ((1<>step)&smask(step))) +#define parity_char(x) pstep(pstep(pstep((x), 4), 2), 1) + +static void mit_des_fixup_key_parity(u8 key[8]) +{ + int i; + for (i = 0; i < 8; i++) { + key[i] &= 0xfe; + key[i] |= 1^parity_char(key[i]); + } +} + +/* + * This is the des3 key derivation postprocess function + */ +u32 gss_krb5_des3_make_key(struct gss_krb5_enctype *gk5e, + struct xdr_netobj *randombits, + struct xdr_netobj *key) +{ + int i; + u32 ret = EINVAL; + + if (key->len != 24) { + dprintk("%s: key->len is %d\n", __func__, key->len); + goto err_out; + } + if (randombits->len != 21) { + dprintk("%s: randombits->len is %d\n", + __func__, randombits->len); + goto err_out; + } + + /* take the seven bytes, move them around into the top 7 bits of the + 8 key bytes, then compute the parity bits. Do this three times. */ + + for (i = 0; i < 3; i++) { + memcpy(key->data + i*8, randombits->data + i*7, 7); + key->data[i*8+7] = (((key->data[i*8]&1)<<1) | + ((key->data[i*8+1]&1)<<2) | + ((key->data[i*8+2]&1)<<3) | + ((key->data[i*8+3]&1)<<4) | + ((key->data[i*8+4]&1)<<5) | + ((key->data[i*8+5]&1)<<6) | + ((key->data[i*8+6]&1)<<7)); + + mit_des_fixup_key_parity(key->data + i*8); + } + ret = 0; +err_out: + return(ret); +} diff -up linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_mech.c.orig linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_mech.c --- linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_mech.c.orig 2009-04-30 15:50:32.578914000 -0400 +++ linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_mech.c 2009-04-30 15:51:36.295756000 -0400 @@ -71,6 +71,26 @@ static struct gss_krb5_enctype supported .cksumlength = 8, .keyed_cksum = 0, }, + /* + * 3DES + */ + { + .etype = ENCTYPE_DES3_CBC_RAW, + .ctype = CKSUMTYPE_HMAC_SHA1_DES3, + .name = "des3-hmac-sha1", + .encrypt_name = "cbc(des3_ede)", + .cksum_name = "hmac(sha1)", + .encrypt = krb5_encrypt, + .decrypt = krb5_decrypt, + .mk_key = gss_krb5_des3_make_key, + .signalg = SGN_ALG_HMAC_SHA1_DES3_KD, + .sealalg = SEAL_ALG_DES3KD, + .keybytes = 21, + .keylength = 24, + .blocksize = 8, + .cksumlength = 20, + .keyed_cksum = 1, + }, }; static int num_supported_enctypes = ARRAY_SIZE(supported_gss_krb5_enctypes); @@ -444,6 +464,9 @@ gss_import_v2_context(const void *p, con p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype)); if (IS_ERR(p)) goto out_err; + /* Map ENCTYPE_DES3_CBC_SHA1 to ENCTYPE_DES3_CBC_RAW */ + if (ctx->enctype == ENCTYPE_DES3_CBC_SHA1) + ctx->enctype = ENCTYPE_DES3_CBC_RAW; ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); if (ctx->gk5e == NULL) { printk("gss_kerberos_mech: unsupported krb5 enctype %u\n", 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 15:46:42.474094000 -0400 +++ linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_seal.c 2009-04-30 15:51:36.303756000 -0400 @@ -143,6 +143,7 @@ gss_get_mic_kerberos(struct gss_ctx *gss default: BUG(); case ENCTYPE_DES_CBC_RAW: + case ENCTYPE_DES3_CBC_RAW: return gss_get_mic_v1(ctx, text, token); } } 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 15:46:42.480097000 -0400 +++ linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_unseal.c 2009-04-30 15:51:36.310756000 -0400 @@ -153,6 +153,7 @@ gss_verify_mic_kerberos(struct gss_ctx * default: BUG(); case ENCTYPE_DES_CBC_RAW: + case ENCTYPE_DES3_CBC_RAW: return gss_verify_mic_v1(ctx, message_buffer, read_token); } } 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 15:46:42.489094000 -0400 +++ linux-2.6.29.noarch/net/sunrpc/auth_gss/gss_krb5_wrap.c 2009-04-30 15:51:36.316759000 -0400 @@ -352,6 +352,7 @@ gss_wrap_kerberos(struct gss_ctx *gctx, default: BUG(); case ENCTYPE_DES_CBC_RAW: + case ENCTYPE_DES3_CBC_RAW: return gss_wrap_kerberos_v1(kctx, offset, buf, pages); } } @@ -365,6 +366,7 @@ gss_unwrap_kerberos(struct gss_ctx *gctx default: BUG(); case ENCTYPE_DES_CBC_RAW: + case ENCTYPE_DES3_CBC_RAW: return gss_unwrap_kerberos_v1(kctx, offset, buf); } }