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