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