/*
 *  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: 
 *
 */
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 - 2; 
	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:
	if (spkm3_ctx_id.data)
		kfree(spkm3_ctx_id.data);
	return ret;
}

