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 */
gcm_init(gcm_state * gcm,int cipher,const unsigned char * key,int keylen)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