Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 10010
b: refs/heads/master
c: 14ae162
h: refs/heads/master
v: v3
  • Loading branch information
J. Bruce Fields authored and Trond Myklebust committed Oct 19, 2005
1 parent 7818e1f commit da3e212
Show file tree
Hide file tree
Showing 8 changed files with 553 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bfa91516b57483fc9c81d8d90325fd2c3c16ac48
refs/heads/master: 14ae162c24d985593d5b19437d7f3d8fd0062b59
18 changes: 17 additions & 1 deletion trunk/include/linux/sunrpc/gss_krb5.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ enum seal_alg {

s32
make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
struct xdr_netobj *cksum);
int body_offset, struct xdr_netobj *cksum);

u32
krb5_make_token(struct krb5_ctx *context_handle, int qop_req,
Expand All @@ -128,6 +128,15 @@ krb5_read_token(struct krb5_ctx *context_handle,
struct xdr_netobj *input_token_buffer,
struct xdr_buf *message_buffer, int *qop_state);

u32
gss_wrap_kerberos(struct gss_ctx *ctx_id, u32 qop, int offset,
struct xdr_buf *outbuf, struct page **pages);

u32
gss_unwrap_kerberos(struct gss_ctx *ctx_id, u32 *qop, int offset,
struct xdr_buf *buf);


u32
krb5_encrypt(struct crypto_tfm * key,
void *iv, void *in, void *out, int length);
Expand All @@ -136,6 +145,13 @@ u32
krb5_decrypt(struct crypto_tfm * key,
void *iv, void *in, void *out, int length);

int
gss_encrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *outbuf, int offset,
struct page **pages);

int
gss_decrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *inbuf, int offset);

s32
krb5_make_seq_num(struct crypto_tfm * key,
int direction,
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/sunrpc/auth_gss/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ auth_rpcgss-objs := auth_gss.o gss_generic_token.o \
obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o

rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \
gss_krb5_seqnum.o
gss_krb5_seqnum.o gss_krb5_wrap.o

obj-$(CONFIG_RPCSEC_GSS_SPKM3) += rpcsec_gss_spkm3.o

Expand Down
156 changes: 154 additions & 2 deletions trunk/net/sunrpc/auth_gss/gss_krb5_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ checksummer(struct scatterlist *sg, void *data)
/* checksum the plaintext data and hdrlen bytes of the token header */
s32
make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
struct xdr_netobj *cksum)
int body_offset, struct xdr_netobj *cksum)
{
char *cksumname;
struct crypto_tfm *tfm = NULL; /* XXX add to ctx? */
Expand All @@ -243,7 +243,8 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
crypto_digest_init(tfm);
buf_to_sg(sg, header, hdrlen);
crypto_digest_update(tfm, sg, 1);
process_xdr_buf(body, 0, body->len, checksummer, tfm);
process_xdr_buf(body, body_offset, body->len - body_offset,
checksummer, tfm);
crypto_digest_final(tfm, cksum->data);
code = 0;
out:
Expand All @@ -252,3 +253,154 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
}

EXPORT_SYMBOL(make_checksum);

struct encryptor_desc {
u8 iv[8]; /* XXX hard-coded blocksize */
struct crypto_tfm *tfm;
int pos;
struct xdr_buf *outbuf;
struct page **pages;
struct scatterlist infrags[4];
struct scatterlist outfrags[4];
int fragno;
int fraglen;
};

static int
encryptor(struct scatterlist *sg, void *data)
{
struct encryptor_desc *desc = data;
struct xdr_buf *outbuf = desc->outbuf;
struct page *in_page;
int thislen = desc->fraglen + sg->length;
int fraglen, ret;
int page_pos;

/* Worst case is 4 fragments: head, end of page 1, start
* of page 2, tail. Anything more is a bug. */
BUG_ON(desc->fragno > 3);
desc->infrags[desc->fragno] = *sg;
desc->outfrags[desc->fragno] = *sg;

page_pos = desc->pos - outbuf->head[0].iov_len;
if (page_pos >= 0 && page_pos < outbuf->page_len) {
/* pages are not in place: */
int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
in_page = desc->pages[i];
} else {
in_page = sg->page;
}
desc->infrags[desc->fragno].page = in_page;
desc->fragno++;
desc->fraglen += sg->length;
desc->pos += sg->length;

fraglen = thislen & 7; /* XXX hardcoded blocksize */
thislen -= fraglen;

if (thislen == 0)
return 0;

ret = crypto_cipher_encrypt_iv(desc->tfm, desc->outfrags, desc->infrags,
thislen, desc->iv);
if (ret)
return ret;
if (fraglen) {
desc->outfrags[0].page = sg->page;
desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
desc->outfrags[0].length = fraglen;
desc->infrags[0] = desc->outfrags[0];
desc->infrags[0].page = in_page;
desc->fragno = 1;
desc->fraglen = fraglen;
} else {
desc->fragno = 0;
desc->fraglen = 0;
}
return 0;
}

int
gss_encrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *buf, int offset,
struct page **pages)
{
int ret;
struct encryptor_desc desc;

BUG_ON((buf->len - offset) % crypto_tfm_alg_blocksize(tfm) != 0);

memset(desc.iv, 0, sizeof(desc.iv));
desc.tfm = tfm;
desc.pos = offset;
desc.outbuf = buf;
desc.pages = pages;
desc.fragno = 0;
desc.fraglen = 0;

ret = process_xdr_buf(buf, offset, buf->len - offset, encryptor, &desc);
return ret;
}

EXPORT_SYMBOL(gss_encrypt_xdr_buf);

struct decryptor_desc {
u8 iv[8]; /* XXX hard-coded blocksize */
struct crypto_tfm *tfm;
struct scatterlist frags[4];
int fragno;
int fraglen;
};

static int
decryptor(struct scatterlist *sg, void *data)
{
struct decryptor_desc *desc = data;
int thislen = desc->fraglen + sg->length;
int fraglen, ret;

/* Worst case is 4 fragments: head, end of page 1, start
* of page 2, tail. Anything more is a bug. */
BUG_ON(desc->fragno > 3);
desc->frags[desc->fragno] = *sg;
desc->fragno++;
desc->fraglen += sg->length;

fraglen = thislen & 7; /* XXX hardcoded blocksize */
thislen -= fraglen;

if (thislen == 0)
return 0;

ret = crypto_cipher_decrypt_iv(desc->tfm, desc->frags, desc->frags,
thislen, desc->iv);
if (ret)
return ret;
if (fraglen) {
desc->frags[0].page = sg->page;
desc->frags[0].offset = sg->offset + sg->length - fraglen;
desc->frags[0].length = fraglen;
desc->fragno = 1;
desc->fraglen = fraglen;
} else {
desc->fragno = 0;
desc->fraglen = 0;
}
return 0;
}

int
gss_decrypt_xdr_buf(struct crypto_tfm *tfm, struct xdr_buf *buf, int offset)
{
struct decryptor_desc desc;

/* XXXJBF: */
BUG_ON((buf->len - offset) % crypto_tfm_alg_blocksize(tfm) != 0);

memset(desc.iv, 0, sizeof(desc.iv));
desc.tfm = tfm;
desc.fragno = 0;
desc.fraglen = 0;
return process_xdr_buf(buf, offset, buf->len - offset, decryptor, &desc);
}

EXPORT_SYMBOL(gss_decrypt_xdr_buf);
7 changes: 7 additions & 0 deletions trunk/net/sunrpc/auth_gss/gss_krb5_mech.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ static struct gss_api_ops gss_kerberos_ops = {
.gss_import_sec_context = gss_import_sec_context_kerberos,
.gss_get_mic = gss_get_mic_kerberos,
.gss_verify_mic = gss_verify_mic_kerberos,
.gss_wrap = gss_wrap_kerberos,
.gss_unwrap = gss_unwrap_kerberos,
.gss_delete_sec_context = gss_delete_sec_context_kerberos,
};

Expand All @@ -240,6 +242,11 @@ static struct pf_desc gss_kerberos_pfs[] = {
.service = RPC_GSS_SVC_INTEGRITY,
.name = "krb5i",
},
[2] = {
.pseudoflavor = RPC_AUTH_GSS_KRB5P,
.service = RPC_GSS_SVC_PRIVACY,
.name = "krb5p",
},
};

static struct gss_api_mech gss_kerberos_mech = {
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/sunrpc/auth_gss/gss_krb5_seal.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ krb5_make_token(struct krb5_ctx *ctx, int qop_req,
*(u16 *)(krb5_hdr + 2) = htons(ctx->signalg);
memset(krb5_hdr + 4, 0xff, 4);

if (make_checksum(checksum_type, krb5_hdr, 8, text, &md5cksum))
goto out_err;
if (make_checksum(checksum_type, krb5_hdr, 8, text, 0, &md5cksum))
goto out_err;

switch (ctx->signalg) {
case SGN_ALG_DES_MAC_MD5:
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/sunrpc/auth_gss/gss_krb5_unseal.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ krb5_read_token(struct krb5_ctx *ctx,
switch (signalg) {
case SGN_ALG_DES_MAC_MD5:
ret = make_checksum(checksum_type, ptr - 2, 8,
message_buffer, &md5cksum);
message_buffer, 0, &md5cksum);
if (ret)
goto out;

Expand Down
Loading

0 comments on commit da3e212

Please sign in to comment.