Skip to content

Commit

Permalink
rpc: spkm3 update
Browse files Browse the repository at this point in the history
This updates the spkm3 code to bring it up to date with our current
understanding of the spkm3 spec.

In doing so, we're changing the downcall format used by gssd in the spkm3 case,
which will cause an incompatilibity with old userland spkm3 support.  Since the
old code a) didn't implement the protocol correctly, and b) was never
distributed except in the form of some experimental patches from the citi web
site, we're assuming this is OK.

We do detect the old downcall format and print warning (and fail).  We also
include a version number in the new downcall format, to be used in the
future in case any further change is required.

In some more detail:

	- fix integrity support
	- removed dependency on NIDs. instead OIDs are used
	- known OID values for algorithms added.
	- fixed some context fields and types

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
Olga Kornievskaia authored and Trond Myklebust committed Dec 6, 2006
1 parent 37a4e6c commit adeb813
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 182 deletions.
34 changes: 14 additions & 20 deletions include/linux/sunrpc/gss_spkm3.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,19 @@
#include <linux/sunrpc/gss_asn1.h>

struct spkm3_ctx {
struct xdr_netobj ctx_id; /* per message context id */
int qop; /* negotiated qop */
struct xdr_netobj ctx_id; /* per message context id */
int endtime; /* endtime of the context */
struct xdr_netobj mech_used;
unsigned int ret_flags ;
unsigned int req_flags ;
struct xdr_netobj share_key;
int conf_alg;
struct crypto_blkcipher *derived_conf_key;
int intg_alg;
struct crypto_blkcipher *derived_integ_key;
int keyestb_alg; /* alg used to get share_key */
int owf_alg; /* one way function */
struct xdr_netobj conf_alg;
struct xdr_netobj derived_conf_key;
struct xdr_netobj intg_alg;
struct xdr_netobj derived_integ_key;
};

/* from openssl/objects.h */
/* XXX need SEAL_ALG_NONE */
#define NID_md5 4
#define NID_dhKeyAgreement 28
#define NID_des_cbc 31
#define NID_sha1 64
#define NID_cast5_cbc 108
/* OIDs declarations for K-ALG, I-ALG, C-ALG, and OWF-ALG */
extern const struct xdr_netobj hmac_md5_oid;
extern const struct xdr_netobj cast5_cbc_oid;

/* SPKM InnerContext Token types */

Expand All @@ -46,11 +38,13 @@ u32 spkm3_make_token(struct spkm3_ctx *ctx, struct xdr_buf * text, struct xdr_ne
u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int toktype);

#define CKSUMTYPE_RSA_MD5 0x0007
#define CKSUMTYPE_HMAC_MD5 0x0008

s32 make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
int body_offset, struct xdr_netobj *cksum);
s32 make_spkm3_checksum(s32 cksumtype, struct xdr_netobj *key, char *header,
unsigned int hdrlen, struct xdr_buf *body,
unsigned int body_offset, struct xdr_netobj *cksum);
void asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits);
int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen,
int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen,
int explen);
void spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen,
unsigned char *ctxhdr, int elen, int zbit);
Expand Down
2 changes: 1 addition & 1 deletion net/sunrpc/auth_gss/auth_gss.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static struct rpc_credops gss_credops;
#define GSS_CRED_SLACK 1024 /* XXX: unused */
/* length of a krb5 verifier (48), plus data added before arguments when
* using integrity (two 4-byte integers): */
#define GSS_VERF_SLACK 56
#define GSS_VERF_SLACK 100

/* XXX this define must match the gssd define
* as it is passed to gssd to signal the use of
Expand Down
131 changes: 36 additions & 95 deletions net/sunrpc/auth_gss/gss_spkm3_mech.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,133 +82,73 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
return q;
}

static inline const void *
get_key(const void *p, const void *end, struct crypto_blkcipher **res,
int *resalg)
{
struct xdr_netobj key = { 0 };
int setkey = 0;
char *alg_name;

p = simple_get_bytes(p, end, resalg, sizeof(*resalg));
if (IS_ERR(p))
goto out_err;
p = simple_get_netobj(p, end, &key);
if (IS_ERR(p))
goto out_err;

switch (*resalg) {
case NID_des_cbc:
alg_name = "cbc(des)";
setkey = 1;
break;
case NID_cast5_cbc:
/* XXXX here in name only, not used */
alg_name = "cbc(cast5)";
setkey = 0; /* XXX will need to set to 1 */
break;
case NID_md5:
if (key.len == 0) {
dprintk("RPC: SPKM3 get_key: NID_md5 zero Key length\n");
}
alg_name = "md5";
setkey = 0;
break;
default:
dprintk("gss_spkm3_mech: unsupported algorithm %d\n", *resalg);
goto out_err_free_key;
}
*res = crypto_alloc_blkcipher(alg_name, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(*res)) {
printk("gss_spkm3_mech: unable to initialize crypto algorthm %s\n", alg_name);
*res = NULL;
goto out_err_free_key;
}
if (setkey) {
if (crypto_blkcipher_setkey(*res, key.data, key.len)) {
printk("gss_spkm3_mech: error setting key for crypto algorthm %s\n", alg_name);
goto out_err_free_tfm;
}
}

if(key.len > 0)
kfree(key.data);
return p;

out_err_free_tfm:
crypto_free_blkcipher(*res);
out_err_free_key:
if(key.len > 0)
kfree(key.data);
p = ERR_PTR(-EINVAL);
out_err:
return p;
}

static int
gss_import_sec_context_spkm3(const void *p, size_t len,
struct gss_ctx *ctx_id)
{
const void *end = (const void *)((const char *)p + len);
struct spkm3_ctx *ctx;
int version;

if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL)))
goto out_err;

p = simple_get_bytes(p, end, &version, sizeof(version));
if (IS_ERR(p))
goto out_err_free_ctx;
if (version != 1) {
dprintk("RPC: unknown spkm3 token format: obsolete nfs-utils?\n");
goto out_err_free_ctx;
}

p = simple_get_netobj(p, end, &ctx->ctx_id);
if (IS_ERR(p))
goto out_err_free_ctx;

p = simple_get_bytes(p, end, &ctx->qop, sizeof(ctx->qop));
p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
if (IS_ERR(p))
goto out_err_free_ctx_id;

p = simple_get_netobj(p, end, &ctx->mech_used);
if (IS_ERR(p))
goto out_err_free_mech;
goto out_err_free_ctx_id;

p = simple_get_bytes(p, end, &ctx->ret_flags, sizeof(ctx->ret_flags));
if (IS_ERR(p))
goto out_err_free_mech;

p = simple_get_bytes(p, end, &ctx->req_flags, sizeof(ctx->req_flags));
p = simple_get_netobj(p, end, &ctx->conf_alg);
if (IS_ERR(p))
goto out_err_free_mech;

p = simple_get_netobj(p, end, &ctx->share_key);
if (IS_ERR(p))
goto out_err_free_s_key;

p = get_key(p, end, &ctx->derived_conf_key, &ctx->conf_alg);
p = simple_get_netobj(p, end, &ctx->derived_conf_key);
if (IS_ERR(p))
goto out_err_free_s_key;
goto out_err_free_conf_alg;

p = get_key(p, end, &ctx->derived_integ_key, &ctx->intg_alg);
p = simple_get_netobj(p, end, &ctx->intg_alg);
if (IS_ERR(p))
goto out_err_free_key1;
goto out_err_free_conf_key;

p = simple_get_bytes(p, end, &ctx->keyestb_alg, sizeof(ctx->keyestb_alg));
p = simple_get_netobj(p, end, &ctx->derived_integ_key);
if (IS_ERR(p))
goto out_err_free_key2;

p = simple_get_bytes(p, end, &ctx->owf_alg, sizeof(ctx->owf_alg));
if (IS_ERR(p))
goto out_err_free_key2;
goto out_err_free_intg_alg;

if (p != end)
goto out_err_free_key2;
goto out_err_free_intg_key;

ctx_id->internal_ctx_id = ctx;

dprintk("Successfully imported new spkm context.\n");
return 0;

out_err_free_key2:
crypto_free_blkcipher(ctx->derived_integ_key);
out_err_free_key1:
crypto_free_blkcipher(ctx->derived_conf_key);
out_err_free_s_key:
kfree(ctx->share_key.data);
out_err_free_intg_key:
kfree(ctx->derived_integ_key.data);
out_err_free_intg_alg:
kfree(ctx->intg_alg.data);
out_err_free_conf_key:
kfree(ctx->derived_conf_key.data);
out_err_free_conf_alg:
kfree(ctx->conf_alg.data);
out_err_free_mech:
kfree(ctx->mech_used.data);
out_err_free_ctx_id:
Expand All @@ -220,13 +160,16 @@ gss_import_sec_context_spkm3(const void *p, size_t len,
}

static void
gss_delete_sec_context_spkm3(void *internal_ctx) {
gss_delete_sec_context_spkm3(void *internal_ctx)
{
struct spkm3_ctx *sctx = internal_ctx;

crypto_free_blkcipher(sctx->derived_integ_key);
crypto_free_blkcipher(sctx->derived_conf_key);
kfree(sctx->share_key.data);
kfree(sctx->derived_integ_key.data);
kfree(sctx->intg_alg.data);
kfree(sctx->derived_conf_key.data);
kfree(sctx->conf_alg.data);
kfree(sctx->mech_used.data);
kfree(sctx->ctx_id.data);
kfree(sctx);
}

Expand All @@ -238,7 +181,6 @@ gss_verify_mic_spkm3(struct gss_ctx *ctx,
u32 maj_stat = 0;
struct spkm3_ctx *sctx = ctx->internal_ctx_id;

dprintk("RPC: gss_verify_mic_spkm3 calling spkm3_read_token\n");
maj_stat = spkm3_read_token(sctx, checksum, signbuf, SPKM_MIC_TOK);

dprintk("RPC: gss_verify_mic_spkm3 returning %d\n", maj_stat);
Expand All @@ -253,10 +195,9 @@ gss_get_mic_spkm3(struct gss_ctx *ctx,
u32 err = 0;
struct spkm3_ctx *sctx = ctx->internal_ctx_id;

dprintk("RPC: gss_get_mic_spkm3\n");

err = spkm3_make_token(sctx, message_buffer,
message_token, SPKM_MIC_TOK);
message_token, SPKM_MIC_TOK);
dprintk("RPC: gss_get_mic_spkm3 returning %d\n", err);
return err;
}

Expand Down
Loading

0 comments on commit adeb813

Please sign in to comment.