Blame src/rijndael.c

Packit 29108b
/* Rijndael Block Cipher - rijndael.c
Packit 29108b
Packit 29108b
   Written by Mike Scott 21st April 1999
Packit 29108b
   mike@compapp.dcu.ie
Packit 29108b
Packit 29108b
   Permission for free direct or derivative use is granted subject 
Packit 29108b
   to compliance with any conditions that the originators of the 
Packit 29108b
   algorithm place on its exploitation.  
Packit 29108b
Packit 29108b
*/
Packit 29108b
Packit 29108b
Packit 29108b
#include "rijndael.h"
Packit 29108b
Packit 29108b
/* Fixed Data */
Packit 29108b
Packit 29108b
static u8 InCo[4]={0xB,0xD,0x9,0xE};  /* Inverse Coefficients */
Packit 29108b
Packit 29108b
static u8 fbsub[256];
Packit 29108b
static u8 rbsub[256];
Packit 29108b
static u8 ptab[256],ltab[256];
Packit 29108b
static u32 ftable[256];
Packit 29108b
static u32 rtable[256];
Packit 29108b
static u32 rco[30];
Packit 29108b
Packit 29108b
/* Parameter-dependent data */
Packit 29108b
Packit 29108b
static int Nk,Nb,Nr;
Packit 29108b
static u8 fi[24],ri[24];
Packit 29108b
static u32 fkey[120];
Packit 29108b
static u32 rkey[120];
Packit 29108b
Packit 29108b
static u32 pack(u8 *b)
Packit 29108b
{ /* pack bytes into a 32-bit Word */
Packit 29108b
    return ((u32)b[3]<<24)|((u32)b[2]<<16)|((u32)b[1]<<8)|(u32)b[0];
Packit 29108b
}
Packit 29108b
Packit 29108b
static void unpack(u32 a,u8 *b)
Packit 29108b
{ /* unpack bytes from a word */
Packit 29108b
    b[0]=(u8)a;
Packit 29108b
    b[1]=(u8)(a>>8);
Packit 29108b
    b[2]=(u8)(a>>16);
Packit 29108b
    b[3]=(u8)(a>>24);
Packit 29108b
}
Packit 29108b
Packit 29108b
static u8 xtime(u8 a)
Packit 29108b
{
Packit 29108b
    u8 b;
Packit 29108b
    if (a&0x80) b=0x1B;
Packit 29108b
    else        b=0;
Packit 29108b
    a<<=1;
Packit 29108b
    a^=b;
Packit 29108b
    return a;
Packit 29108b
}
Packit 29108b
Packit 29108b
static u8 bmul(u8 x,u8 y)
Packit 29108b
{ /* x.y= AntiLog(Log(x) + Log(y)) */
Packit 29108b
    if (x && y) return ptab[(ltab[x]+ltab[y])%255];
Packit 29108b
    else return 0;
Packit 29108b
}
Packit 29108b
Packit 29108b
static u32 SubByte(u32 a)
Packit 29108b
{
Packit 29108b
    u8 b[4];
Packit 29108b
    unpack(a,b);
Packit 29108b
    b[0]=fbsub[b[0]];
Packit 29108b
    b[1]=fbsub[b[1]];
Packit 29108b
    b[2]=fbsub[b[2]];
Packit 29108b
    b[3]=fbsub[b[3]];
Packit 29108b
    return pack(b);    
Packit 29108b
}
Packit 29108b
Packit 29108b
static u8 product(u32 x,u32 y)
Packit 29108b
{ /* dot product of two 4-byte arrays */
Packit 29108b
    u8 xb[4],yb[4];
Packit 29108b
    unpack(x,xb);
Packit 29108b
    unpack(y,yb); 
Packit 29108b
    return bmul(xb[0],yb[0])^bmul(xb[1],yb[1])^bmul(xb[2],yb[2])^bmul(xb[3],yb[3]);
Packit 29108b
}
Packit 29108b
Packit 29108b
static u32 InvMixCol(u32 x)
Packit 29108b
{ /* matrix Multiplication */
Packit 29108b
    u32 y,m;
Packit 29108b
    u8 b[4];
Packit 29108b
Packit 29108b
    m=pack(InCo);
Packit 29108b
    b[3]=product(m,x);
Packit 29108b
    m=ROTL24(m);
Packit 29108b
    b[2]=product(m,x);
Packit 29108b
    m=ROTL24(m);
Packit 29108b
    b[1]=product(m,x);
Packit 29108b
    m=ROTL24(m);
Packit 29108b
    b[0]=product(m,x);
Packit 29108b
    y=pack(b);
Packit 29108b
    return y;
Packit 29108b
}
Packit 29108b
Packit 29108b
static u8 ByteSub(u8 x)
Packit 29108b
{
Packit 29108b
    u8 y=ptab[255-ltab[x]];  /* multiplicative inverse */
Packit 29108b
    x=y;  x=ROTL(x);
Packit 29108b
    y^=x; x=ROTL(x);
Packit 29108b
    y^=x; x=ROTL(x);
Packit 29108b
    y^=x; x=ROTL(x);
Packit 29108b
    y^=x; y^=0x63;
Packit 29108b
    return y;
Packit 29108b
}
Packit 29108b
Packit 29108b
static void gentables(void)
Packit 29108b
{ /* generate tables */
Packit 29108b
    int i;
Packit 29108b
    u8 y,b[4];
Packit 29108b
Packit 29108b
  /* use 3 as primitive root to generate power and log tables */
Packit 29108b
Packit 29108b
    ltab[0]=0;
Packit 29108b
    ptab[0]=1;  ltab[1]=0;
Packit 29108b
    ptab[1]=3;  ltab[3]=1; 
Packit 29108b
    for (i=2;i<256;i++)
Packit 29108b
    {
Packit 29108b
        ptab[i]=ptab[i-1]^xtime(ptab[i-1]);
Packit 29108b
        ltab[ptab[i]]=i;
Packit 29108b
    }
Packit 29108b
    
Packit 29108b
  /* affine transformation:- each bit is xored with itself shifted one bit */
Packit 29108b
Packit 29108b
    fbsub[0]=0x63;
Packit 29108b
    rbsub[0x63]=0;
Packit 29108b
    for (i=1;i<256;i++)
Packit 29108b
    {
Packit 29108b
        y=ByteSub((u8)i);
Packit 29108b
        fbsub[i]=y; rbsub[y]=i;
Packit 29108b
    }
Packit 29108b
Packit 29108b
    for (i=0,y=1;i<30;i++)
Packit 29108b
    {
Packit 29108b
        rco[i]=y;
Packit 29108b
        y=xtime(y);
Packit 29108b
    }
Packit 29108b
Packit 29108b
  /* calculate forward and reverse tables */
Packit 29108b
    for (i=0;i<256;i++)
Packit 29108b
    {
Packit 29108b
        y=fbsub[i];
Packit 29108b
        b[3]=y^xtime(y); b[2]=y;
Packit 29108b
        b[1]=y;          b[0]=xtime(y);
Packit 29108b
        ftable[i]=pack(b);
Packit 29108b
Packit 29108b
        y=rbsub[i];
Packit 29108b
        b[3]=bmul(InCo[0],y); b[2]=bmul(InCo[1],y);
Packit 29108b
        b[1]=bmul(InCo[2],y); b[0]=bmul(InCo[3],y);
Packit 29108b
        rtable[i]=pack(b);
Packit 29108b
    }
Packit 29108b
}
Packit 29108b
Packit 29108b
static void gkey(int nb,int nk,char *key)
Packit 29108b
{ /* blocksize=32*nb bits. Key=32*nk bits */
Packit 29108b
  /* currently nb,bk = 4, 6 or 8          */
Packit 29108b
  /* key comes as 4*Nk bytes              */
Packit 29108b
  /* Key Scheduler. Create expanded encryption key */
Packit 29108b
    int i,j,k,m,N;
Packit 29108b
    int C1,C2,C3;
Packit 29108b
    u32 CipherKey[8];
Packit 29108b
    
Packit 29108b
    Nb=nb; Nk=nk;
Packit 29108b
Packit 29108b
  /* Nr is number of rounds */
Packit 29108b
    if (Nb>=Nk) Nr=6+Nb;
Packit 29108b
    else        Nr=6+Nk;
Packit 29108b
Packit 29108b
    C1=1;
Packit 29108b
    if (Nb<8) { C2=2; C3=3; }
Packit 29108b
    else      { C2=3; C3=4; }
Packit 29108b
Packit 29108b
  /* pre-calculate forward and reverse increments */
Packit 29108b
    for (m=j=0;j
Packit 29108b
    {
Packit 29108b
        fi[m]=(j+C1)%nb;
Packit 29108b
        fi[m+1]=(j+C2)%nb;
Packit 29108b
        fi[m+2]=(j+C3)%nb;
Packit 29108b
        ri[m]=(nb+j-C1)%nb;
Packit 29108b
        ri[m+1]=(nb+j-C2)%nb;
Packit 29108b
        ri[m+2]=(nb+j-C3)%nb;
Packit 29108b
    }
Packit 29108b
Packit 29108b
    N=Nb*(Nr+1);
Packit 29108b
    
Packit 29108b
    for (i=j=0;i
Packit 29108b
    {
Packit 29108b
        CipherKey[i]=pack((u8 *)&key[j]);
Packit 29108b
    }
Packit 29108b
    for (i=0;i
Packit 29108b
    for (j=Nk,k=0;j
Packit 29108b
    {
Packit 29108b
        fkey[j]=fkey[j-Nk]^SubByte(ROTL24(fkey[j-1]))^rco[k];
Packit 29108b
        if (Nk<=6)
Packit 29108b
        {
Packit 29108b
            for (i=1;i
Packit 29108b
                fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1];
Packit 29108b
        }
Packit 29108b
        else
Packit 29108b
        {
Packit 29108b
            for (i=1;i<4 &&(i+j)
Packit 29108b
                fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1];
Packit 29108b
            if ((j+4)
Packit 29108b
            for (i=5;i
Packit 29108b
                fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1];
Packit 29108b
        }
Packit 29108b
Packit 29108b
    }
Packit 29108b
Packit 29108b
 /* now for the expanded decrypt key in reverse order */
Packit 29108b
Packit 29108b
    for (j=0;j
Packit 29108b
    for (i=Nb;i
Packit 29108b
    {
Packit 29108b
        k=N-Nb-i;
Packit 29108b
        for (j=0;j
Packit 29108b
    }
Packit 29108b
    for (j=N-Nb;j
Packit 29108b
}
Packit 29108b
Packit 29108b
Packit 29108b
/* There is an obvious time/space trade-off possible here.     *
Packit 29108b
 * Instead of just one ftable[], I could have 4, the other     *
Packit 29108b
 * 3 pre-rotated to save the ROTL8, ROTL16 and ROTL24 overhead */ 
Packit 29108b
Packit 29108b
static void encrypt(char *buff)
Packit 29108b
{
Packit 29108b
    int i,j,k,m;
Packit 29108b
    u32 a[8],b[8],*x,*y,*t;
Packit 29108b
Packit 29108b
    for (i=j=0;i
Packit 29108b
    {
Packit 29108b
        a[i]=pack((u8 *)&buff[j]);
Packit 29108b
        a[i]^=fkey[i];
Packit 29108b
    }
Packit 29108b
    k=Nb;
Packit 29108b
    x=a; y=b;
Packit 29108b
Packit 29108b
/* State alternates between a and b */
Packit 29108b
    for (i=1;i
Packit 29108b
    { /* Nr is number of rounds. May be odd. */
Packit 29108b
Packit 29108b
/* if Nb is fixed - unroll this next 
Packit 29108b
   loop and hard-code in the values of fi[]  */
Packit 29108b
Packit 29108b
        for (m=j=0;j
Packit 29108b
        { /* deal with each 32-bit element of the State */
Packit 29108b
          /* This is the time-critical bit */
Packit 29108b
            y[j]=fkey[k++]^ftable[(u8)x[j]]^
Packit 29108b
                 ROTL8(ftable[(u8)(x[fi[m]]>>8)])^
Packit 29108b
                 ROTL16(ftable[(u8)(x[fi[m+1]]>>16)])^
Packit 29108b
                 ROTL24(ftable[x[fi[m+2]]>>24]);
Packit 29108b
        }
Packit 29108b
        t=x; x=y; y=t;      /* swap pointers */
Packit 29108b
    }
Packit 29108b
Packit 29108b
/* Last Round - unroll if possible */ 
Packit 29108b
    for (m=j=0;j
Packit 29108b
    {
Packit 29108b
        y[j]=fkey[k++]^(u32)fbsub[(u8)x[j]]^
Packit 29108b
             ROTL8((u32)fbsub[(u8)(x[fi[m]]>>8)])^
Packit 29108b
             ROTL16((u32)fbsub[(u8)(x[fi[m+1]]>>16)])^
Packit 29108b
             ROTL24((u32)fbsub[x[fi[m+2]]>>24]);
Packit 29108b
    }   
Packit 29108b
    for (i=j=0;i
Packit 29108b
    {
Packit 29108b
        unpack(y[i],(u8 *)&buff[j]);
Packit 29108b
        x[i]=y[i]=0;   /* clean up stack */
Packit 29108b
    }
Packit 29108b
    return;
Packit 29108b
}
Packit 29108b
Packit 29108b
static void decrypt(char *buff)
Packit 29108b
{
Packit 29108b
    int i,j,k,m;
Packit 29108b
    u32 a[8],b[8],*x,*y,*t;
Packit 29108b
Packit 29108b
    for (i=j=0;i
Packit 29108b
    {
Packit 29108b
        a[i]=pack((u8 *)&buff[j]);
Packit 29108b
        a[i]^=rkey[i];
Packit 29108b
    }
Packit 29108b
    k=Nb;
Packit 29108b
    x=a; y=b;
Packit 29108b
Packit 29108b
/* State alternates between a and b */
Packit 29108b
    for (i=1;i
Packit 29108b
    { /* Nr is number of rounds. May be odd. */
Packit 29108b
Packit 29108b
/* if Nb is fixed - unroll this next 
Packit 29108b
   loop and hard-code in the values of ri[]  */
Packit 29108b
Packit 29108b
        for (m=j=0;j
Packit 29108b
        { /* This is the time-critical bit */
Packit 29108b
            y[j]=rkey[k++]^rtable[(u8)x[j]]^
Packit 29108b
                 ROTL8(rtable[(u8)(x[ri[m]]>>8)])^
Packit 29108b
                 ROTL16(rtable[(u8)(x[ri[m+1]]>>16)])^
Packit 29108b
                 ROTL24(rtable[x[ri[m+2]]>>24]);
Packit 29108b
        }
Packit 29108b
        t=x; x=y; y=t;      /* swap pointers */
Packit 29108b
    }
Packit 29108b
Packit 29108b
/* Last Round - unroll if possible */ 
Packit 29108b
    for (m=j=0;j
Packit 29108b
    {
Packit 29108b
        y[j]=rkey[k++]^(u32)rbsub[(u8)x[j]]^
Packit 29108b
             ROTL8((u32)rbsub[(u8)(x[ri[m]]>>8)])^
Packit 29108b
             ROTL16((u32)rbsub[(u8)(x[ri[m+1]]>>16)])^
Packit 29108b
             ROTL24((u32)rbsub[x[ri[m+2]]>>24]);
Packit 29108b
    }        
Packit 29108b
    for (i=j=0;i
Packit 29108b
    {
Packit 29108b
        unpack(y[i],(u8 *)&buff[j]);
Packit 29108b
        x[i]=y[i]=0;   /* clean up stack */
Packit 29108b
    }
Packit 29108b
    return;
Packit 29108b
}
Packit 29108b
Packit 29108b
void aes_set_key(u8 *key) {
Packit 29108b
  gentables();
Packit 29108b
  gkey(4, 4, (char *)key);
Packit 29108b
}
Packit 29108b
Packit 29108b
/* CBC mode decryption */
Packit 29108b
void aes_decrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len) {
Packit 29108b
  u8 block[16];
Packit 29108b
  unsigned int blockno = 0, i;
Packit 29108b
Packit 29108b
  /*  debug_printf("aes_decrypt(%p, %p, %p, %lld)\n", iv, inbuf, outbuf, len); */
Packit 29108b
Packit 29108b
  for (blockno = 0; blockno <= (len / sizeof(block)); blockno++) {
Packit 29108b
    unsigned int fraction;
Packit 29108b
    u8 *ctext_ptr;
Packit 29108b
    if (blockno == (len / sizeof(block))) { /* last block */
Packit 29108b
      fraction = len % sizeof(block);
Packit 29108b
      if (fraction == 0) break;
Packit 29108b
      memset(block, 0, sizeof(block));
Packit 29108b
    } else fraction = 16;
Packit 29108b
Packit 29108b
    /*    debug_printf("block %d: fraction = %d\n", blockno, fraction); */
Packit 29108b
    memcpy(block, inbuf + blockno * sizeof(block), fraction);
Packit 29108b
    decrypt((char *)block);
Packit 29108b
    if (blockno == 0) ctext_ptr = iv;
Packit 29108b
    else ctext_ptr = inbuf + (blockno-1) * sizeof(block);
Packit 29108b
    
Packit 29108b
    for(i=0; i < fraction; i++) 
Packit 29108b
      outbuf[blockno * sizeof(block) + i] =
Packit 29108b
	ctext_ptr[i] ^ block[i];
Packit 29108b
    /*    debug_printf("Block %d output: ", blockno); */
Packit 29108b
    /*    hexdump(outbuf + blockno*sizeof(block), 16); */
Packit 29108b
  }
Packit 29108b
}
Packit 29108b
Packit 29108b
/* CBC mode encryption      */
Packit 29108b
void aes_encrypt(const u8 *initiv, u8 *inbuf, u8 *outbuf, unsigned long long len) {
Packit 29108b
  u8 block[16], iv[16];
Packit 29108b
  unsigned int blockno = 0, i;
Packit 29108b
  memcpy(iv, initiv, sizeof(iv));
Packit 29108b
Packit 29108b
  for (blockno = 0; blockno <= (len / sizeof(block)); blockno++) {
Packit 29108b
    unsigned int fraction;
Packit 29108b
    if (blockno == (len / sizeof(block))) { /* last block */
Packit 29108b
      fraction = len % sizeof(block);
Packit 29108b
      if (fraction == 0) break;
Packit 29108b
      memset(block, 0, sizeof(block));
Packit 29108b
    } else fraction = 16;
Packit 29108b
Packit 29108b
    memcpy(block, inbuf + blockno * sizeof(block), fraction);
Packit 29108b
        
Packit 29108b
    for(i=0; i < fraction; i++) 
Packit 29108b
      block[i] = inbuf[blockno * sizeof(block) + i] ^ iv[i];
Packit 29108b
    
Packit 29108b
    encrypt((char *)block);
Packit 29108b
    memcpy(iv, block, sizeof(block));
Packit 29108b
    memcpy(outbuf + blockno * sizeof(block), block, sizeof(block));
Packit 29108b
  }
Packit 29108b
}
Packit 29108b