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