1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 /**
5    @file gcm_init.c
6    GCM implementation, initialize state, by Tom St Denis
7 */
8 #include "tomcrypt_private.h"
9 
10 #ifdef LTC_GCM_MODE
11 
12 /**
13   Initialize a GCM state
14   @param gcm     The GCM state to initialize
15   @param cipher  The index of the cipher to use
16   @param key     The secret key
17   @param keylen  The length of the secret key
18   @return CRYPT_OK on success
19  */
gcm_init(gcm_state * gcm,int cipher,const unsigned char * key,int keylen)20 int gcm_init(gcm_state *gcm, int cipher,
21              const unsigned char *key,  int keylen)
22 {
23    int           err;
24    unsigned char B[16];
25 #ifdef LTC_GCM_TABLES
26    int           x, y, z, t;
27 #endif
28 
29    LTC_ARGCHK(gcm != NULL);
30    LTC_ARGCHK(key != NULL);
31 
32 #ifdef LTC_FAST
33    if (16 % sizeof(LTC_FAST_TYPE)) {
34       return CRYPT_INVALID_ARG;
35    }
36 #endif
37 
38    /* is cipher valid? */
39    if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
40       return err;
41    }
42    if (cipher_descriptor[cipher]->block_length != 16) {
43       return CRYPT_INVALID_CIPHER;
44    }
45 
46    /* schedule key */
47    if ((err = cipher_descriptor[cipher]->setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) {
48       return err;
49    }
50 
51    /* H = E(0) */
52    zeromem(B, 16);
53    if ((err = cipher_descriptor[cipher]->ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) {
54       return err;
55    }
56 
57    /* setup state */
58    zeromem(gcm->buf, sizeof(gcm->buf));
59    zeromem(gcm->X,   sizeof(gcm->X));
60    gcm->cipher   = cipher;
61    gcm->mode     = LTC_GCM_MODE_IV;
62    gcm->ivmode   = 0;
63    gcm->buflen   = 0;
64    gcm->totlen   = 0;
65    gcm->pttotlen = 0;
66 
67 #ifdef LTC_GCM_TABLES
68    /* setup tables */
69 
70    /* generate the first table as it has no shifting (from which we make the other tables) */
71    zeromem(B, 16);
72    for (y = 0; y < 256; y++) {
73         B[0] = y;
74         gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]);
75    }
76 
77    /* now generate the rest of the tables based the previous table */
78    for (x = 1; x < 16; x++) {
79       for (y = 0; y < 256; y++) {
80          /* now shift it right by 8 bits */
81          t = gcm->PC[x-1][y][15];
82          for (z = 15; z > 0; z--) {
83              gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1];
84          }
85          gcm->PC[x][y][0] = gcm_shift_table[t<<1];
86          gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1];
87       }
88    }
89 
90 #endif
91 
92    return CRYPT_OK;
93 }
94 
95 #endif
96