aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Coffman <kwc@citi.umich.edu>2010-03-17 13:02:46 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-05-14 15:09:15 -0400
commit725f2865d4df31ac0768b13ae763beadc4bb8ce9 (patch)
tree20b2da47713e7f38a61d37cbb2c95ad52c88609f
parent4fc4c3ce0dc1096cbd0daa3fe8f6905cbec2b87e (diff)
gss_krb5: Introduce encryption type framework
Make the client and server code consistent regarding the extra buffer space made available for the auth code when wrapping data. Add some comments/documentation about the available buffer space in the xdr_buf head and tail when gss_wrap is called. Add a compile-time check to make sure we are not exceeding the available buffer space. Add a central function to shift head data. 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>
-rw-r--r--include/linux/sunrpc/gss_krb5.h25
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c38
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c6
4 files changed, 66 insertions, 5 deletions
diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
index e7bbdba474d5..31bb8a538bf1 100644
--- a/include/linux/sunrpc/gss_krb5.h
+++ b/include/linux/sunrpc/gss_krb5.h
@@ -40,6 +40,12 @@
40#include <linux/sunrpc/gss_err.h> 40#include <linux/sunrpc/gss_err.h>
41#include <linux/sunrpc/gss_asn1.h> 41#include <linux/sunrpc/gss_asn1.h>
42 42
43/* Maximum checksum function output for the supported crypto algorithms */
44#define GSS_KRB5_MAX_CKSUM_LEN (20)
45
46/* Maximum blocksize for the supported crypto algorithms */
47#define GSS_KRB5_MAX_BLOCKSIZE (16)
48
43struct krb5_ctx { 49struct krb5_ctx {
44 int initiate; /* 1 = initiating, 0 = accepting */ 50 int initiate; /* 1 = initiating, 0 = accepting */
45 struct crypto_blkcipher *enc; 51 struct crypto_blkcipher *enc;
@@ -113,6 +119,22 @@ enum seal_alg {
113#define ENCTYPE_DES3_CBC_SHA1 0x0010 119#define ENCTYPE_DES3_CBC_SHA1 0x0010
114#define ENCTYPE_UNKNOWN 0x01ff 120#define ENCTYPE_UNKNOWN 0x01ff
115 121
122/*
123 * This compile-time check verifies that we will not exceed the
124 * slack space allotted by the client and server auth_gss code
125 * before they call gss_wrap().
126 */
127#define GSS_KRB5_MAX_SLACK_NEEDED \
128 (GSS_KRB5_TOK_HDR_LEN /* gss token header */ \
129 + GSS_KRB5_MAX_CKSUM_LEN /* gss token checksum */ \
130 + GSS_KRB5_MAX_BLOCKSIZE /* confounder */ \
131 + GSS_KRB5_MAX_BLOCKSIZE /* possible padding */ \
132 + GSS_KRB5_TOK_HDR_LEN /* encrypted hdr in v2 token */\
133 + GSS_KRB5_MAX_CKSUM_LEN /* encryption hmac */ \
134 + 4 + 4 /* RPC verifier */ \
135 + GSS_KRB5_TOK_HDR_LEN \
136 + GSS_KRB5_MAX_CKSUM_LEN)
137
116s32 138s32
117make_checksum(char *, char *header, int hdrlen, struct xdr_buf *body, 139make_checksum(char *, char *header, int hdrlen, struct xdr_buf *body,
118 int body_offset, struct xdr_netobj *cksum); 140 int body_offset, struct xdr_netobj *cksum);
@@ -157,3 +179,6 @@ s32
157krb5_get_seq_num(struct crypto_blkcipher *key, 179krb5_get_seq_num(struct crypto_blkcipher *key,
158 unsigned char *cksum, 180 unsigned char *cksum,
159 unsigned char *buf, int *direction, u32 *seqnum); 181 unsigned char *buf, int *direction, u32 *seqnum);
182
183int
184xdr_extend_head(struct xdr_buf *buf, unsigned int base, unsigned int shiftlen);
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index c389ccf6437d..75602ece58eb 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -61,7 +61,7 @@ static const struct rpc_credops gss_nullops;
61# define RPCDBG_FACILITY RPCDBG_AUTH 61# define RPCDBG_FACILITY RPCDBG_AUTH
62#endif 62#endif
63 63
64#define GSS_CRED_SLACK 1024 64#define GSS_CRED_SLACK (RPC_MAX_AUTH_SIZE * 2)
65/* length of a krb5 verifier (48), plus data added before arguments when 65/* length of a krb5 verifier (48), plus data added before arguments when
66 * using integrity (two 4-byte integers): */ 66 * using integrity (two 4-byte integers): */
67#define GSS_VERF_SLACK 100 67#define GSS_VERF_SLACK 100
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index e9b636176687..746b3e139aed 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -325,3 +325,41 @@ gss_decrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
325 325
326 return xdr_process_buf(buf, offset, buf->len - offset, decryptor, &desc); 326 return xdr_process_buf(buf, offset, buf->len - offset, decryptor, &desc);
327} 327}
328
329/*
330 * This function makes the assumption that it was ultimately called
331 * from gss_wrap().
332 *
333 * The client auth_gss code moves any existing tail data into a
334 * separate page before calling gss_wrap.
335 * The server svcauth_gss code ensures that both the head and the
336 * tail have slack space of RPC_MAX_AUTH_SIZE before calling gss_wrap.
337 *
338 * Even with that guarantee, this function may be called more than
339 * once in the processing of gss_wrap(). The best we can do is
340 * verify at compile-time (see GSS_KRB5_SLACK_CHECK) that the
341 * largest expected shift will fit within RPC_MAX_AUTH_SIZE.
342 * At run-time we can verify that a single invocation of this
343 * function doesn't attempt to use more the RPC_MAX_AUTH_SIZE.
344 */
345
346int
347xdr_extend_head(struct xdr_buf *buf, unsigned int base, unsigned int shiftlen)
348{
349 u8 *p;
350
351 if (shiftlen == 0)
352 return 0;
353
354 BUILD_BUG_ON(GSS_KRB5_MAX_SLACK_NEEDED > RPC_MAX_AUTH_SIZE);
355 BUG_ON(shiftlen > RPC_MAX_AUTH_SIZE);
356
357 p = buf->head[0].iov_base + base;
358
359 memmove(p + shiftlen, p, buf->head[0].iov_len - base);
360
361 buf->head[0].iov_len += shiftlen;
362 buf->len += shiftlen;
363
364 return 0;
365}
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index a6e905637e03..496281fabb91 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -155,11 +155,9 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
155 155
156 ptr = buf->head[0].iov_base + offset; 156 ptr = buf->head[0].iov_base + offset;
157 /* shift data to make room for header. */ 157 /* shift data to make room for header. */
158 xdr_extend_head(buf, offset, headlen);
159
158 /* XXX Would be cleverer to encrypt while copying. */ 160 /* XXX Would be cleverer to encrypt while copying. */
159 /* XXX bounds checking, slack, etc. */
160 memmove(ptr + headlen, ptr, buf->head[0].iov_len - offset);
161 buf->head[0].iov_len += headlen;
162 buf->len += headlen;
163 BUG_ON((buf->len - offset - headlen) % blocksize); 161 BUG_ON((buf->len - offset - headlen) % blocksize);
164 162
165 g_make_token_header(&kctx->mech_used, 163 g_make_token_header(&kctx->mech_used,