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#include "tomcrypt.h" 12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @file hmac_init.c 15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project HMAC support, initialize state, Tom St Denis/Dobes Vandermeer 16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_HMAC 19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize 21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Initialize an HMAC context. 24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param hmac The HMAC state 25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param hash The index of the hash you want to use 26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param key The secret key 27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param keylen The length of the secret key (octets) 28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful 29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen) 31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char *buf; 33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned long hashsize; 34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned long i, z; 35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int err; 36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(hmac != NULL); 38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(key != NULL); 39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* valid hash? */ 41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = hash_is_valid(hash)) != CRYPT_OK) { 42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project hmac->hash = hash; 45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project hashsize = hash_descriptor[hash].hashsize; 46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* valid key length? */ 48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (keylen == 0) { 49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_INVALID_KEYSIZE; 50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* allocate ram for buf */ 53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf = XMALLOC(HMAC_BLOCKSIZE); 54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (buf == NULL) { 55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_MEM; 56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* allocate memory for key */ 59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project hmac->key = XMALLOC(HMAC_BLOCKSIZE); 60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (hmac->key == NULL) { 61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project XFREE(buf); 62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_MEM; 63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* (1) make sure we have a large enough key */ 66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if(keylen > HMAC_BLOCKSIZE) { 67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project z = HMAC_BLOCKSIZE; 68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) { 69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto LBL_ERR; 70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if(hashsize < HMAC_BLOCKSIZE) { 72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project zeromem((hmac->key) + hashsize, (size_t)(HMAC_BLOCKSIZE - hashsize)); 73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project keylen = hashsize; 75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } else { 76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project XMEMCPY(hmac->key, key, (size_t)keylen); 77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if(keylen < HMAC_BLOCKSIZE) { 78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project zeromem((hmac->key) + keylen, (size_t)(HMAC_BLOCKSIZE - keylen)); 79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Create the initial vector for step (3) */ 83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for(i=0; i < HMAC_BLOCKSIZE; i++) { 84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf[i] = hmac->key[i] ^ 0x36; 85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Pre-pend that to the hash data */ 88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { 89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto LBL_ERR; 90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) { 93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto LBL_ERR; 94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto done; 96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectLBL_ERR: 97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* free the key since we failed */ 98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project XFREE(hmac->key); 99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectdone: 100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_CLEAN_STACK 101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project zeromem(buf, HMAC_BLOCKSIZE); 102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project XFREE(buf); 105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_init.c,v $ */ 111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.5 $ */ 112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/11/03 00:39:49 $ */ 113