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@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 */
28int 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