| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 
 | ///////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sha1.h"
#include "hmac.h"
/* Convinience function */
void SHA1_Atomic(uint8_t *in, unsigned int in_len, uint8_t *out)
{
 SHA1_CTX ctx;
 SHA1Init(&ctx);
 SHA1Update(&ctx, in, in_len);
 SHA1Final(out, &ctx);
}
void HMAC_SHA1_Init(HMAC_SHA1_CTX *hmac, uint8_t *key, size_t key_len)
{
 /*
  * Why does Solaris use 4 byte value for ipad and opad?
  * is it for performnce reason?
  */
 uint8_t ipad[SHA1_HMAC_BLOCK_SIZE];
 uint8_t opad[SHA1_HMAC_BLOCK_SIZE];
 uint8_t digested_key[SHA1_DIGEST_LENGTH];
 uint8_t *keyptr;
 int i;
 /*
  * If the key is too long we need to hash the key and use that instead
  * And we don't want to modify the actual key
  */
 keyptr = key;
 /* Need to hash the key if too big */
 if (key_len > SHA1_HMAC_BLOCK_SIZE) {
  SHA1_Atomic(key, key_len, digested_key);
  keyptr = digested_key;
  key_len = SHA1_DIGEST_LENGTH;
 }
 bzero(ipad, SHA1_HMAC_BLOCK_SIZE);
 bzero(opad, SHA1_HMAC_BLOCK_SIZE);
 bcopy(keyptr, ipad, key_len);
 bcopy(keyptr, opad, key_len);
 /* XOR key with ipad and opad */
 for (i = 0; i < SHA1_HMAC_BLOCK_SIZE; i++) {
  ipad[i] ^= HMAC_IPAD;
  opad[i] ^= HMAC_OPAD;
 }
 /* Start by hashing the resulting string. */
 SHA1Init(&hmac->hc_icontext);
 SHA1Update(&hmac->hc_icontext, (uint8_t *)ipad, SHA1_HMAC_BLOCK_SIZE);
 SHA1Init(&hmac->hc_ocontext);
 SHA1Update(&hmac->hc_ocontext, (uint8_t *)opad, SHA1_HMAC_BLOCK_SIZE);
}
 
/* Do the inner SHA1 of the algorithm */
void HMAC_SHA1_Update(HMAC_SHA1_CTX *hmac, uint8_t *data, size_t data_len)
{
 SHA1Update(&hmac->hc_icontext, data, data_len);
}
 
/* Finish the inner SHA1 and compute the outer SHA1
 *
 * **Note that the argument order is different from SHA1Final
 * It made sense to me to put hmac_ctx before the pointer to the output
 * so that it's consistent with the other calls that use the hmac_ctx
 */
void HMAC_SHA1_Final(HMAC_SHA1_CTX *hmac, uint8_t *digest)
{
 /* Do a SHA1 final on the inner context */
 SHA1Final(digest, &hmac->hc_icontext);
 /*
  * Do a SHA1 final on the outer context, feeding the inner
  * digest as data
  */
 SHA1Update(&hmac->hc_ocontext, digest, SHA1_DIGEST_LENGTH);
 /* Do a SHA1 final on the outer context, storing the computing digest */
 SHA1Final(digest, &hmac->hc_ocontext);
 /* paranoid? */
 bzero(hmac, sizeof (HMAC_SHA1_CTX));
}
 
 
/* Convinience function */
void HMAC_SHA1_Atomic(uint8_t *data, size_t data_len,
 uint8_t *key, size_t key_len, uint8_t *mac)
{
 HMAC_SHA1_CTX hmac;
 HMAC_SHA1_Init(&hmac, key, key_len);
 HMAC_SHA1_Update(&hmac, data, data_len);
 HMAC_SHA1_Final(&hmac, mac);
} | 
Partager