/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/



/*
 * Implementation of the AES-GCM Encryption/Authentication
 *
 * Some restrictions..
 * 1. Only for use with AES
 * 2. Returned tag is always 128-bits. Truncate at your own risk.
 * 3. The order of function calls must follow some rules
 *
 * Typical sequence of calls..
 * 1. call GCM_init
 * 2. call GCM_add_header any number of times, as long as length of header is multiple of 16 bytes (block size)
 * 3. call GCM_add_header one last time with any length of header
 * 4. call GCM_add_cipher any number of times, as long as length of cipher/plaintext is multiple of 16 bytes
 * 5. call GCM_add_cipher one last time with any length of cipher/plaintext
 * 6. call GCM_finish to extract the tag.
 *
 * See http://www.mindspring.com/~dmcgrew/gcm-nist-6.pdf
 */
/* SU=m, m is Stack Usage */

#include <stdlib.h>
#include <string.h>
#include "amcl.h"

#define NB 4
#define MR_TOBYTE(x) ((uchar)((x)))

static unsign32 pack(const uchar *b)
{ /* pack bytes into a 32-bit Word */
    return ((unsign32)b[0]<<24)|((unsign32)b[1]<<16)|((unsign32)b[2]<<8)|(unsign32)b[3];
}

static void unpack(unsign32 a,uchar *b)
{ /* unpack bytes from a word */
    b[3]=MR_TOBYTE(a);
    b[2]=MR_TOBYTE(a>>8);
    b[1]=MR_TOBYTE(a>>16);
    b[0]=MR_TOBYTE(a>>24);
}

static void precompute(gcm *g,uchar *H)
{ /* precompute small 2k bytes gf2m table of x^n.H */
	int i,j;
	unsign32 *last,*next,b;

	for (i=j=0;i<NB;i++,j+=4) g->table[0][i]=pack((uchar *)&H[j]);

	for (i=1;i<128;i++)
	{
		next=g->table[i]; last=g->table[i-1]; b=0;
		for (j=0;j<NB;j++) {next[j]=b|(last[j])>>1; b=last[j]<<31;}
		if (b) next[0]^=0xE1000000; /* irreducible polynomial */
	}
}

/* SU= 32 */
static void gf2mul(gcm *g)
{ /* gf2m mul - Z=H*X mod 2^128 */
	int i,j,m,k;
	unsign32 P[4];
	uchar b;

	P[0]=P[1]=P[2]=P[3]=0;
	j=8; m=0;
	for (i=0;i<128;i++)
	{
		b=(g->stateX[m]>>(--j))&1;
		if (b) for (k=0;k<NB;k++) P[k]^=g->table[i][k];
		if (j==0)
		{
			j=8; m++;
			if (m==16) break;
		}
	}
	for (i=j=0;i<NB;i++,j+=4) unpack(P[i],(uchar *)&g->stateX[j]);
}

/* SU= 32 */
static void GCM_wrap(gcm *g)
{ /* Finish off GHASH */
	int i,j;
	unsign32 F[4];
	uchar L[16];

/* convert lengths from bytes to bits */
	F[0]=(g->lenA[0]<<3)|(g->lenA[1]&0xE0000000)>>29;
	F[1]=g->lenA[1]<<3;
	F[2]=(g->lenC[0]<<3)|(g->lenC[1]&0xE0000000)>>29;
	F[3]=g->lenC[1]<<3;
	for (i=j=0;i<NB;i++,j+=4) unpack(F[i],(uchar *)&L[j]);

	for (i=0;i<16;i++) g->stateX[i]^=L[i];
	gf2mul(g);
}

static int GCM_ghash(gcm *g,char *plain,int len)
{
	int i,j=0;
	unsign32 counter;
	uchar B[16];
	if (g->status==GCM_ACCEPTING_HEADER) g->status=GCM_ACCEPTING_CIPHER;
	if (g->status!=GCM_ACCEPTING_CIPHER) return 0;

	while (j<len)
	{
		for (i=0;i<16 && j<len;i++)
		{
			g->stateX[i]^=plain[j++];
			g->lenC[1]++; if (g->lenC[1]==0) g->lenC[0]++;
		}
		gf2mul(g);
	}
	if (len%16!=0) g->status=GCM_NOT_ACCEPTING_MORE;
	return 1;
}

/* SU= 48 */
/* Initialize GCM mode */
void GCM_init(gcm* g,char *key,int niv,char *iv)
{ /* iv size niv is usually 12 bytes (96 bits). AES key is 16 bytes */
	int i;
	uchar H[16];
	for (i=0;i<16;i++) {H[i]=0; g->stateX[i]=0;}

	AES_init(&(g->a),ECB,key,iv);
	AES_ecb_encrypt(&(g->a),H);     /* E(K,0) */
	precompute(g,H);

	g->lenA[0]=g->lenC[0]=g->lenA[1]=g->lenC[1]=0;
	if (niv==12)
	{
		for (i=0;i<12;i++) g->a.f[i]=iv[i];
		unpack((unsign32)1,(uchar *)&(g->a.f[12]));  /* initialise IV */
		for (i=0;i<16;i++) g->Y_0[i]=g->a.f[i];
	}
	else
	{
		g->status=GCM_ACCEPTING_CIPHER;
		GCM_ghash(g,iv,niv); /* GHASH(H,0,IV) */
		GCM_wrap(g);
		for (i=0;i<16;i++) {g->a.f[i]=g->stateX[i];g->Y_0[i]=g->a.f[i];g->stateX[i]=0;}
		g->lenA[0]=g->lenC[0]=g->lenA[1]=g->lenC[1]=0;
	}
	g->status=GCM_ACCEPTING_HEADER;
}

/* SU= 24 */
/* Add Header data - included but not encrypted */
int GCM_add_header(gcm* g,char *header,int len)
{ /* Add some header. Won't be encrypted, but will be authenticated. len is length of header */
	int i,j=0;
	if (g->status!=GCM_ACCEPTING_HEADER) return 0;

	while (j<len)
	{
		for (i=0;i<16 && j<len;i++)
		{
			g->stateX[i]^=header[j++];
			g->lenA[1]++; if (g->lenA[1]==0) g->lenA[0]++;
		}
		gf2mul(g);
	}
	if (len%16!=0) g->status=GCM_ACCEPTING_CIPHER;
	return 1;
}

/* SU= 48 */
/* Add Plaintext - included and encrypted */
int GCM_add_plain(gcm *g,char *cipher,char *plain,int len)
{ /* Add plaintext to extract ciphertext, len is length of plaintext.  */
	int i,j=0;
	unsign32 counter;
	uchar B[16];
	if (g->status==GCM_ACCEPTING_HEADER) g->status=GCM_ACCEPTING_CIPHER;
	if (g->status!=GCM_ACCEPTING_CIPHER) return 0;

	while (j<len)
	{
		counter=pack((uchar *)&(g->a.f[12]));
		counter++;
		unpack(counter,(uchar *)&(g->a.f[12]));  /* increment counter */
		for (i=0;i<16;i++) B[i]=g->a.f[i];
		AES_ecb_encrypt(&(g->a),B);        /* encrypt it  */

		for (i=0;i<16 && j<len;i++)
		{
			cipher[j]=plain[j]^B[i];
			g->stateX[i]^=cipher[j++];
			g->lenC[1]++; if (g->lenC[1]==0) g->lenC[0]++;
		}
		gf2mul(g);
	}
	if (len%16!=0) g->status=GCM_NOT_ACCEPTING_MORE;
	return 1;
}

/* SU= 48 */
/* Add Ciphertext - decrypts to plaintext */
int GCM_add_cipher(gcm *g,char *plain,char *cipher,int len)
{ /* Add ciphertext to extract plaintext, len is length of ciphertext. */
	int i,j=0;
	unsign32 counter;
	uchar B[16];
	if (g->status==GCM_ACCEPTING_HEADER) g->status=GCM_ACCEPTING_CIPHER;
	if (g->status!=GCM_ACCEPTING_CIPHER) return 0;

	while (j<len)
	{
		counter=pack((uchar *)&(g->a.f[12]));
		counter++;
		unpack(counter,(uchar *)&(g->a.f[12]));  /* increment counter */
		for (i=0;i<16;i++) B[i]=g->a.f[i];
		AES_ecb_encrypt(&(g->a),B);        /* encrypt it  */
		for (i=0;i<16 && j<len;i++)
		{
			plain[j]=cipher[j]^B[i];
			g->stateX[i]^=cipher[j++];
			g->lenC[1]++; if (g->lenC[1]==0) g->lenC[0]++;
		}
		gf2mul(g);
	}
	if (len%16!=0) g->status=GCM_NOT_ACCEPTING_MORE;
	return 1;
}

/* SU= 16 */
/* Finish and extract Tag */
void GCM_finish(gcm *g,char *tag)
{ /* Finish off GHASH and extract tag (MAC) */
	int i;

	GCM_wrap(g);

/* extract tag */
	if (tag!=NULL)
	{
		AES_ecb_encrypt(&(g->a),g->Y_0);        /* E(K,Y0) */
		for (i=0;i<16;i++) g->Y_0[i]^=g->stateX[i];
		for (i=0;i<16;i++) {tag[i]=g->Y_0[i];g->Y_0[i]=g->stateX[i]=0;}
	}
	g->status=GCM_FINISHED;
	AES_end(&(g->a));
}


// Compile with
// gcc -O2 amcl_gcm.c amcl_aes.c -o amcl_gcm.exe
/* SU= 16
*/
/*
static void hex2bytes(char *hex,char *bin)
{
	int i;
	char v;
	int len=strlen(hex);
	for (i = 0; i < len/2; i++) {
        char c = hex[2*i];
        if (c >= '0' && c <= '9') {
            v = c - '0';
        } else if (c >= 'A' && c <= 'F') {
            v = c - 'A' + 10;
        } else if (c >= 'a' && c <= 'f') {
            v = c - 'a' + 10;
        } else {
            v = 0;
        }
        v <<= 4;
        c = hex[2*i + 1];
        if (c >= '0' && c <= '9') {
            v += c - '0';
        } else if (c >= 'A' && c <= 'F') {
            v += c - 'A' + 10;
        } else if (c >= 'a' && c <= 'f') {
            v += c - 'a' + 10;
        } else {
            v = 0;
        }
        bin[i] = v;
    }
}
*/
/*
int main()
{
	int i;

	char* KT="feffe9928665731c6d6a8f9467308308";
	char* MT="d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39";
	char* HT="feedfacedeadbeeffeedfacedeadbeefabaddad2";
//	char* NT="cafebabefacedbaddecaf888";
// Tag should be 5bc94fbc3221a5db94fae95ae7121a47
	char* NT="9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b";
// Tag should be 619cc5aefffe0bfa462af43c1699d050


	int len=strlen(MT)/2;
	int lenH=strlen(HT)/2;
	int lenK=strlen(KT)/2;
	int lenIV=strlen(NT)/2;

	char T[16];   // Tag
	char K[16];   // AES Key
	char H[64];   // Header - to be included in Authentication, but not encrypted
	char N[100];   // IV - Initialisation vector
	char M[100];  // Plaintext to be encrypted/authenticated
	char C[100];  // Ciphertext
	char P[100];  // Recovered Plaintext

	gcm g;

    hex2bytes(MT, M);
    hex2bytes(HT, H);
    hex2bytes(NT, N);
	hex2bytes(KT, K);

 	printf("Plaintext=\n");
	for (i=0;i<len;i++) printf("%02x",(unsigned char)M[i]);
	printf("\n");

	GCM_init(&g,K,lenIV,N);
	GCM_add_header(&g,H,lenH);
	GCM_add_plain(&g,C,M,len);
	GCM_finish(&g,T);

	printf("Ciphertext=\n");
	for (i=0;i<len;i++) printf("%02x",(unsigned char)C[i]);
	printf("\n");

	printf("Tag=\n");
	for (i=0;i<16;i++) printf("%02x",(unsigned char)T[i]);
	printf("\n");

	GCM_init(&g,K,lenIV,N);
	GCM_add_header(&g,H,lenH);
	GCM_add_cipher(&g,P,C,len);
	GCM_finish(&g,T);

 	printf("Plaintext=\n");
	for (i=0;i<len;i++) printf("%02x",(unsigned char)P[i]);
	printf("\n");

	printf("Tag=\n");
	for (i=0;i<16;i++) printf("%02x",(unsigned char)T[i]);
	printf("\n");
}

*/
