Home | History | Annotate | Download | only in gcm
      1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
      2  *
      3  * LibTomCrypt is a library that provides various cryptographic
      4  * algorithms in a highly modular and flexible manner.
      5  *
      6  * The library is free for all purposes without any express
      7  * guarantee it works.
      8  *
      9  * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com
     10  */
     11 
     12 /**
     13    @file gcm_init.c
     14    GCM implementation, initialize state, by Tom St Denis
     15 */
     16 #include "tomcrypt.h"
     17 
     18 #ifdef GCM_MODE
     19 
     20 /**
     21   Initialize a GCM state
     22   @param gcm     The GCM state to initialize
     23   @param cipher  The index of the cipher to use
     24   @param key     The secret key
     25   @param keylen  The length of the secret key
     26   @return CRYPT_OK on success
     27  */
     28 int gcm_init(gcm_state *gcm, int cipher,
     29              const unsigned char *key,  int keylen)
     30 {
     31    int           err;
     32    unsigned char B[16];
     33 #ifdef GCM_TABLES
     34    int           x, y, z, t;
     35 #endif
     36 
     37    LTC_ARGCHK(gcm != NULL);
     38    LTC_ARGCHK(key != NULL);
     39 
     40 #ifdef LTC_FAST
     41    if (16 % sizeof(LTC_FAST_TYPE)) {
     42       return CRYPT_INVALID_ARG;
     43    }
     44 #endif
     45 
     46    /* is cipher valid? */
     47    if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
     48       return err;
     49    }
     50    if (cipher_descriptor[cipher].block_length != 16) {
     51       return CRYPT_INVALID_CIPHER;
     52    }
     53 
     54    /* schedule key */
     55    if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) {
     56       return err;
     57    }
     58 
     59    /* H = E(0) */
     60    zeromem(B, 16);
     61    if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) {
     62       return err;
     63    }
     64 
     65    /* setup state */
     66    zeromem(gcm->buf, sizeof(gcm->buf));
     67    zeromem(gcm->X,   sizeof(gcm->X));
     68    gcm->cipher   = cipher;
     69    gcm->mode     = GCM_MODE_IV;
     70    gcm->ivmode   = 0;
     71    gcm->buflen   = 0;
     72    gcm->totlen   = 0;
     73    gcm->pttotlen = 0;
     74 
     75 #ifdef GCM_TABLES
     76    /* setup tables */
     77 
     78    /* generate the first table as it has no shifting (from which we make the other tables) */
     79    zeromem(B, 16);
     80    for (y = 0; y < 256; y++) {
     81         B[0] = y;
     82         gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]);
     83    }
     84 
     85    /* now generate the rest of the tables based the previous table */
     86    for (x = 1; x < 16; x++) {
     87       for (y = 0; y < 256; y++) {
     88          /* now shift it right by 8 bits */
     89          t = gcm->PC[x-1][y][15];
     90          for (z = 15; z > 0; z--) {
     91              gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1];
     92          }
     93          gcm->PC[x][y][0] = gcm_shift_table[t<<1];
     94          gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1];
     95      }
     96   }
     97 
     98 #endif
     99 
    100    return CRYPT_OK;
    101 }
    102 
    103 #endif
    104 
    105 /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_init.c,v $ */
    106 /* $Revision: 1.18 $ */
    107 /* $Date: 2006/03/31 14:15:35 $ */
    108