/*
 *  linux/net/sunrpc/gss_spkm3_token.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/slab.h>
#include <linux/jiffies.h>
#include <linux/sunrpc/gss_spkm3.h>
#include <linux/random.h>
#include <linux/crypto.h>

#ifdef RPC_DEBUG
# define RPCDBG_FACILITY        RPCDBG_AUTH
#endif

/*
 * asn1_bitstring_len()
 *
 * calculate the asn1 bitstring length of the xdr_netobject
 */
void
asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits)
{
	int i, zbit = 0,elen = in->len;
	char *ptr;

	ptr = &in->data[in->len -1];

	/* count trailing 0's */
	for(i = in->len; i > 0; i--) {
		if (*ptr == 0) { 
			ptr--;
			elen--;
		} else
			break;
	}

	/* count number of 0 bits in final octet */
	ptr = &in->data[elen - 1];
	for(i = 0; i < 8; i++) {
		short mask = 0x01;

		if (!((mask << i) & *ptr))
			zbit++;
		else
			break;
	}
	*enclen = elen;
	*zerobits = zbit;
}

/*
 * decode_asn1_bitstring()
 * 
 * decode a bitstring into a buffer of the expected length.
 * enclen = bit string length
 * explen = expected length (define in rfc)
 */
int
decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, int explen)
{
	if (!(out->data = kmalloc(explen,GFP_KERNEL)))
		return 0;
	out->len = explen;
	memset(out->data, 0, explen);
	memcpy(out->data, in, enclen);
	return 1;
}

/* 
 * SPKMInnerContextToken choice SPKM_MIC asn1 token layout
 * 
 * contextid is always 16 bytes plain data. max asn1 bitstring len = 17.
 *
 * tokenlen = pos[0] to end of token (max pos[45] with MD5 cksum)
 *
 * pos  value
 * ----------
 * [0]	a4  SPKM-MIC tag
 * [1]	??  innertoken length  (max 44) 
 * 
 * 
 * tok_hdr piece of checksum data starts here 
 *
 * the maximum mic-header len = 9 + 17 = 26 
 *	mic-header
 *	----------
 * [2]	30      SEQUENCE tag  
 * [3]	??	mic-header length: (max 23) = TokenID + ContextID 
 *
 *		TokenID  - all fields constant and can be hardcoded
 *		-------
 * [4]	  02	Type 2
 * [5]	  02	Length 2 
 * [6][7] 01 01	TokenID (SPKM_MIC_TOK)
 *
 *		ContextID  - encoded length not constant, calculated
 *		---------
 * [8]	03	Type 3
 * [9]	??	encoded length
 * [10]	??	ctxzbit
 * [11]	 	contextid
 *
 * mic_header piece of checksum data ends here. 
 *
 *	int-cksum - encoded length not constant, calculated
 *	---------
 * [??]	03	Type 3
 * [??]	??	encoded length 
 * [??]	??	md5zbit		
 * [??]	 	int-cksum (NID_md5 = 16)
 *
 * maximum SPKM-MIC innercontext token length = 
 *	 10 + encoded contextid_size(17 max) + 2 + encoded  
 *       cksum_size (17 maxfor NID_md5) = 46
 */

/*
 * spkm3_mic_header()
 *
 * Prepare the SPKM_MIC_TOK mic-header for check-sum calculation
 * elen: 16 byte context id asn1 bitstring encoded length
 */
void
spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen, unsigned char *ctxdata, int elen, int zbit)
{
	char *hptr = *hdrbuf;
	char *top = *hdrbuf;

	*(u8 *)hptr++ = 0x30;
	*(u8 *)hptr++ = elen + 7;  /* on the wire header length */

	/* tokenid */
	*(u8 *)hptr++ = 0x02;
	*(u8 *)hptr++ = 0x02;
	*(u8 *)hptr++ = 0x01;
	*(u8 *)hptr++ = 0x01;

	/* coniextid */
	*(u8 *)hptr++ = 0x03;
	*(u8 *)hptr++ = elen + 1; /* add 1 to include zbit */
	*(u8 *)hptr++ = zbit;
	memcpy(hptr, ctxdata, elen);
	hptr += elen;
	*hdrlen = hptr - top; 
}
		
/* 
 * spkm3_mic_innercontext_token()
 *
 * *tokp points to the beginning of the SPKM_MIC token  described 
 * in rfc 2025, section 3.2.1: 
 *
 * toklen is the inner token length
 */
void
spkm3_make_mic_token(unsigned char **tokp, int toklen, struct xdr_netobj *mic_hdr, struct xdr_netobj *md5cksum, int md5elen, int md5zbit)
{
	unsigned char *ict = *tokp;

	*(u8 *)ict++ = 0xa4;
	*(u8 *)ict++ = toklen;
	memcpy(ict, mic_hdr->data, mic_hdr->len);
	ict += mic_hdr->len;

	*(u8 *)ict++ = 0x03;
	*(u8 *)ict++ = md5elen + 1; /* add 1 to include zbit */
	*(u8 *)ict++ = md5zbit;
	memcpy(ict, md5cksum->data, md5elen);
}

u32
spkm3_verify_mic_token(unsigned char **tokp, int *mic_hdrlen, unsigned char **cksum)
{
	struct xdr_netobj       spkm3_ctx_id = {.len =0, .data = NULL};
	unsigned char 		*ptr = *tokp;
	int 			ctxelen;
	u32     		ret = GSS_S_DEFECTIVE_TOKEN;

	/* spkm3 innercontext token preamble */
	if ((ptr[0] != 0xa4) || (ptr[2] != 0x30)) {
		dprintk("RPC: BAD SPKM ictoken preamble\n"); 
		goto out;
	}

	*mic_hdrlen = ptr[3];

	/* token type */
	if ((ptr[4] != 0x02) || (ptr[5] != 0x02)) {
		dprintk("RPC: BAD asn1 SPKM3 token type\n");
		goto out;
	}

	/* only support SPKM_MIC_TOK */
	if((ptr[6] != 0x01) || (ptr[7] != 0x01)) {
		dprintk("RPC: ERROR unsupported SPKM3 token \n");
		goto out;
	}

	/* contextid */
	if (ptr[8] != 0x03) {
		dprintk("RPC: BAD SPKM3 asn1 context-id type\n");
		goto out;
	}

	ctxelen = ptr[9];
	if (ctxelen > 17) {  /* length includes asn1 zbit octet */
		dprintk("RPC: BAD SPKM3 contextid len %d\n", ctxelen);
		goto out;
	}

	/* ignore ptr[10] */

	if(!decode_asn1_bitstring(&spkm3_ctx_id, &ptr[11], ctxelen - 1, 16))
		goto out;

	/*
	* in the current implementation: the optional int-alg is not present 
	* so the default int-alg (md5) is used the optional snd-seq field is 
	* also not present 
	*/

	if (*mic_hdrlen != 6 + ctxelen) {
		dprintk("RPC: BAD SPKM_ MIC_TOK header len %d: we only support default int-alg (should be absent) and do not support snd-seq\n", *mic_hdrlen);
		goto out;
	}
	/* checksum */
        *cksum = (&ptr[10] + ctxelen); /* ctxelen includes ptr[10] */

	ret = GSS_S_COMPLETE;
out:
	kfree(spkm3_ctx_id.data);
	return ret;
}

