Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e7af1b8 authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

nfsd4: remove spkm3



Unfortunately, spkm3 never got very far; while interoperability with one
other implementation was demonstrated at some point, problems were found
with the spec that were deemed not worth fixing.

The kernel code is useless on its own without nfs-utils patches which
were never merged into nfs-utils, and were only ever available from
citi.umich.edu.  They appear not to have been updated since 2005.

Therefore it seems safe to assume that this code has no users, and never
will.

Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 277f68db
Loading
Loading
Loading
Loading

include/linux/sunrpc/gss_spkm3.h

deleted100644 → 0
+0 −55
Original line number Diff line number Diff line
/*
 *  linux/include/linux/sunrpc/gss_spkm3.h
 *
 *  Copyright (c) 2000 The Regents of the University of Michigan.
 *  All rights reserved.
 *
 *  Andy Adamson   <andros@umich.edu>
 */

#include <linux/sunrpc/auth_gss.h>
#include <linux/sunrpc/gss_err.h>
#include <linux/sunrpc/gss_asn1.h>

struct spkm3_ctx {
	struct xdr_netobj	ctx_id;  /* per message context id */
	int			endtime; /* endtime of the context */
	struct xdr_netobj	mech_used;
	unsigned int		ret_flags ;
	struct xdr_netobj	conf_alg;
	struct xdr_netobj	derived_conf_key;
	struct xdr_netobj	intg_alg;
	struct xdr_netobj 	derived_integ_key;
};

/* 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 */

#define SPKM_ERROR_TOK	3
#define SPKM_MIC_TOK	4
#define SPKM_WRAP_TOK	5
#define SPKM_DEL_TOK	6

u32 spkm3_make_token(struct spkm3_ctx *ctx, struct xdr_buf * text, struct xdr_netobj * token, int toktype);

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_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 explen);
void spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen, 
                   unsigned char *ctxhdr, int elen, int zbit);
void spkm3_make_mic_token(unsigned  char **tokp, int toklen, 
                   struct xdr_netobj *mic_hdr,
                   struct xdr_netobj *md5cksum, int md5elen, int md5zbit);
u32 spkm3_verify_mic_token(unsigned char **tokp, int *mic_hdrlen, 
                   unsigned char **cksum);
+0 −19
Original line number Diff line number Diff line
@@ -36,22 +36,3 @@ config RPCSEC_GSS_KRB5
	  Kerberos support should be installed.

	  If unsure, say Y.

config RPCSEC_GSS_SPKM3
	tristate "Secure RPC: SPKM3 mechanism (EXPERIMENTAL)"
	depends on SUNRPC && EXPERIMENTAL
	select SUNRPC_GSS
	select CRYPTO
	select CRYPTO_MD5
	select CRYPTO_DES
	select CRYPTO_CAST5
	select CRYPTO_CBC
	help
	  Choose Y here to enable Secure RPC using the SPKM3 public key
	  GSS-API mechanism (RFC 2025).

	  Secure RPC calls with SPKM3 require an auxiliary userspace
	  daemon which may be found in the Linux nfs-utils package
	  available from http://linux-nfs.org/.

	  If unsure, say N.
+0 −5
Original line number Diff line number Diff line
@@ -11,8 +11,3 @@ 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_wrap.o gss_krb5_crypto.o gss_krb5_keys.o

obj-$(CONFIG_RPCSEC_GSS_SPKM3) += rpcsec_gss_spkm3.o

rpcsec_gss_spkm3-objs := gss_spkm3_mech.o gss_spkm3_seal.o gss_spkm3_unseal.o \
	gss_spkm3_token.o
+0 −247
Original line number Diff line number Diff line
/*
 *  linux/net/sunrpc/gss_spkm3_mech.c
 *
 *  Copyright (c) 2003 The Regents of the University of Michigan.
 *  All rights reserved.
 *
 *  Andy Adamson <andros@umich.edu>
 *  J. Bruce Fields <bfields@umich.edu>
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the University nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/sunrpc/auth.h>
#include <linux/in.h>
#include <linux/sunrpc/svcauth_gss.h>
#include <linux/sunrpc/gss_spkm3.h>
#include <linux/sunrpc/xdr.h>
#include <linux/crypto.h>

#ifdef RPC_DEBUG
# define RPCDBG_FACILITY	RPCDBG_AUTH
#endif

static const void *
simple_get_bytes(const void *p, const void *end, void *res, int len)
{
	const void *q = (const void *)((const char *)p + len);
	if (unlikely(q > end || q < p))
		return ERR_PTR(-EFAULT);
	memcpy(res, p, len);
	return q;
}

static const void *
simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
{
	const void *q;
	unsigned int len;
	p = simple_get_bytes(p, end, &len, sizeof(len));
	if (IS_ERR(p))
		return p;
	res->len = len;
	if (len == 0) {
		res->data = NULL;
		return p;
	}
	q = (const void *)((const char *)p + len);
	if (unlikely(q > end || q < p))
		return ERR_PTR(-EFAULT);
	res->data = kmemdup(p, len, GFP_NOFS);
	if (unlikely(res->data == NULL))
		return ERR_PTR(-ENOMEM);
	return q;
}

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

	if (!(ctx = kzalloc(sizeof(*ctx), gfp_mask)))
		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");
		p = ERR_PTR(-EINVAL);
		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->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_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_netobj(p, end, &ctx->conf_alg);
	if (IS_ERR(p))
		goto out_err_free_mech;

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

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

	p = simple_get_netobj(p, end, &ctx->derived_integ_key);
	if (IS_ERR(p))
		goto out_err_free_intg_alg;

	if (p != end) {
		p = ERR_PTR(-EFAULT);
		goto out_err_free_intg_key;
	}

	ctx_id->internal_ctx_id = ctx;

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

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:
	kfree(ctx->ctx_id.data);
out_err_free_ctx:
	kfree(ctx);
out_err:
	return PTR_ERR(p);
}

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

	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);
}

static u32
gss_verify_mic_spkm3(struct gss_ctx		*ctx,
			struct xdr_buf		*signbuf,
			struct xdr_netobj	*checksum)
{
	u32 maj_stat = 0;
	struct spkm3_ctx *sctx = ctx->internal_ctx_id;

	maj_stat = spkm3_read_token(sctx, checksum, signbuf, SPKM_MIC_TOK);

	dprintk("RPC:       gss_verify_mic_spkm3 returning %d\n", maj_stat);
	return maj_stat;
}

static u32
gss_get_mic_spkm3(struct gss_ctx	*ctx,
		     struct xdr_buf	*message_buffer,
		     struct xdr_netobj	*message_token)
{
	u32 err = 0;
	struct spkm3_ctx *sctx = ctx->internal_ctx_id;

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

static const struct gss_api_ops gss_spkm3_ops = {
	.gss_import_sec_context	= gss_import_sec_context_spkm3,
	.gss_get_mic		= gss_get_mic_spkm3,
	.gss_verify_mic		= gss_verify_mic_spkm3,
	.gss_delete_sec_context	= gss_delete_sec_context_spkm3,
};

static struct pf_desc gss_spkm3_pfs[] = {
	{RPC_AUTH_GSS_SPKM, RPC_GSS_SVC_NONE, "spkm3"},
	{RPC_AUTH_GSS_SPKMI, RPC_GSS_SVC_INTEGRITY, "spkm3i"},
};

static struct gss_api_mech gss_spkm3_mech = {
	.gm_name	= "spkm3",
	.gm_owner	= THIS_MODULE,
	.gm_oid		= {7, "\053\006\001\005\005\001\003"},
	.gm_ops		= &gss_spkm3_ops,
	.gm_pf_num	= ARRAY_SIZE(gss_spkm3_pfs),
	.gm_pfs		= gss_spkm3_pfs,
};

static int __init init_spkm3_module(void)
{
	int status;

	status = gss_mech_register(&gss_spkm3_mech);
	if (status)
		printk("Failed to register spkm3 gss mechanism!\n");
	return status;
}

static void __exit cleanup_spkm3_module(void)
{
	gss_mech_unregister(&gss_spkm3_mech);
}

MODULE_LICENSE("GPL");
module_init(init_spkm3_module);
module_exit(cleanup_spkm3_module);
+0 −186
Original line number Diff line number Diff line
/*
 *  linux/net/sunrpc/gss_spkm3_seal.c
 *
 *  Copyright (c) 2003 The Regents of the University of Michigan.
 *  All rights reserved.
 *
 *  Andy Adamson <andros@umich.edu>
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the University nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <linux/types.h>
#include <linux/jiffies.h>
#include <linux/sunrpc/gss_spkm3.h>
#include <linux/random.h>
#include <linux/crypto.h>
#include <linux/pagemap.h>
#include <linux/scatterlist.h>
#include <linux/sunrpc/xdr.h>

#ifdef RPC_DEBUG
# define RPCDBG_FACILITY        RPCDBG_AUTH
#endif

const struct xdr_netobj hmac_md5_oid = { 8, "\x2B\x06\x01\x05\x05\x08\x01\x01"};
const struct xdr_netobj cast5_cbc_oid = {9, "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0A"};

/*
 * spkm3_make_token()
 *
 * Only SPKM_MIC_TOK with md5 intg-alg is supported
 */

u32
spkm3_make_token(struct spkm3_ctx *ctx,
		   struct xdr_buf * text, struct xdr_netobj * token,
		   int toktype)
{
	s32			checksum_type;
	char			tokhdrbuf[25];
	char			cksumdata[16];
	struct xdr_netobj	md5cksum = {.len = 0, .data = cksumdata};
	struct xdr_netobj	mic_hdr = {.len = 0, .data = tokhdrbuf};
	int			tokenlen = 0;
	unsigned char		*ptr;
	s32			now;
	int			ctxelen = 0, ctxzbit = 0;
	int			md5elen = 0, md5zbit = 0;

	now = jiffies;

	if (ctx->ctx_id.len != 16) {
		dprintk("RPC:       spkm3_make_token BAD ctx_id.len %d\n",
				ctx->ctx_id.len);
		goto out_err;
	}

	if (!g_OID_equal(&ctx->intg_alg, &hmac_md5_oid)) {
		dprintk("RPC:       gss_spkm3_seal: unsupported I-ALG "
				"algorithm.  only support hmac-md5 I-ALG.\n");
		goto out_err;
	} else
		checksum_type = CKSUMTYPE_HMAC_MD5;

	if (!g_OID_equal(&ctx->conf_alg, &cast5_cbc_oid)) {
		dprintk("RPC:       gss_spkm3_seal: unsupported C-ALG "
				"algorithm\n");
		goto out_err;
	}

	if (toktype == SPKM_MIC_TOK) {
		/* Calculate checksum over the mic-header */
		asn1_bitstring_len(&ctx->ctx_id, &ctxelen, &ctxzbit);
		spkm3_mic_header(&mic_hdr.data, &mic_hdr.len, ctx->ctx_id.data,
				ctxelen, ctxzbit);
		if (make_spkm3_checksum(checksum_type, &ctx->derived_integ_key,
					(char *)mic_hdr.data, mic_hdr.len,
					text, 0, &md5cksum))
			goto out_err;

		asn1_bitstring_len(&md5cksum, &md5elen, &md5zbit);
		tokenlen = 10 + ctxelen + 1 + md5elen + 1;

		/* Create token header using generic routines */
		token->len = g_token_size(&ctx->mech_used, tokenlen + 2);

		ptr = token->data;
		g_make_token_header(&ctx->mech_used, tokenlen + 2, &ptr);

		spkm3_make_mic_token(&ptr, tokenlen, &mic_hdr, &md5cksum, md5elen, md5zbit);
	} else if (toktype == SPKM_WRAP_TOK) { /* Not Supported */
		dprintk("RPC:       gss_spkm3_seal: SPKM_WRAP_TOK "
				"not supported\n");
		goto out_err;
	}

	/* XXX need to implement sequence numbers, and ctx->expired */

	return  GSS_S_COMPLETE;
out_err:
	token->data = NULL;
	token->len = 0;
	return GSS_S_FAILURE;
}

static int
spkm3_checksummer(struct scatterlist *sg, void *data)
{
	struct hash_desc *desc = data;

	return crypto_hash_update(desc, sg, sg->length);
}

/* checksum the plaintext data and hdrlen bytes of the token header */
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)
{
	char				*cksumname;
	struct hash_desc		desc; /* XXX add to ctx? */
	struct scatterlist		sg[1];
	int err;

	switch (cksumtype) {
		case CKSUMTYPE_HMAC_MD5:
			cksumname = "hmac(md5)";
			break;
		default:
			dprintk("RPC:       spkm3_make_checksum:"
					" unsupported checksum %d", cksumtype);
			return GSS_S_FAILURE;
	}

	if (key->data == NULL || key->len <= 0) return GSS_S_FAILURE;

	desc.tfm = crypto_alloc_hash(cksumname, 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(desc.tfm))
		return GSS_S_FAILURE;
	cksum->len = crypto_hash_digestsize(desc.tfm);
	desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;

	err = crypto_hash_setkey(desc.tfm, key->data, key->len);
	if (err)
		goto out;

	err = crypto_hash_init(&desc);
	if (err)
		goto out;

	sg_init_one(sg, header, hdrlen);
	crypto_hash_update(&desc, sg, sg->length);

	xdr_process_buf(body, body_offset, body->len - body_offset,
			spkm3_checksummer, &desc);
	crypto_hash_final(&desc, cksum->data);

out:
	crypto_free_hash(desc.tfm);

	return err ? GSS_S_FAILURE : 0;
}
Loading