/*
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 "arch.h"
#include "amcl.h"

using namespace amcl;

#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];
    unsign32 b;

    P[0]=P[1]=P[2]=P[3]=0;
    j=8;
    m=0;
    for (i=0; i<128; i++)
    {
        b=(unsign32)(g->stateX[m]>>(--j))&1;
        b=~b+1;
        for (k=0; k<NB; k++) P[k]^=(g->table[i][k]&b);
        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;
    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 amcl::GCM_init(gcm* g,int nk,char *key,int niv,char *iv)
{
    /* iv size niv is usually 12 bytes (96 bits). AES key size nk can be 16,24 or 32 bytes */
    int i;
    uchar H[16];
    for (i=0; i<16; i++)
    {
        H[i]=0;
        g->stateX[i]=0;
    }

    AES_init(&(g->a),ECB,nk,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 amcl::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 amcl::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 amcl::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;
    char oc;
    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++)
        {
            oc=cipher[j];
            plain[j]=cipher[j]^B[i];
            g->stateX[i]^=oc;
            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 amcl::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 gcm.c aes.c -o 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

  char* KT="6dfb5dc68af6ae2f3242e9184f100918";
  char* MT="47809d16c2c6ec685962c90e53fe1bba";
  char* HT="dd0fa6e494031139d71ee45f00d56fa4";
  char* NT="37d36f5c54d53479d4745dd1";


	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("lenK= %d\n",lenK);

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

	GCM_init(&g,16,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,16,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");
}

*/
