A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

hmac/hmac-sha1.c

Committer:
andrewboyson
Date:
2019-09-05
Revision:
7:94ef5824c3c0
Child:
9:f354b4859b0b

File content as of revision 7:94ef5824c3c0:

#include <stdint.h>

#include "hmac-sha1.h"
#include "sha1.h"

#define BLOCK_SIZE 64
#define  HASH_SIZE 20

void HmacSha1(const uint8_t* key, int keyLength, const uint8_t* message, int messageLength, uint8_t* mac)
{
    uint8_t hmacKey[BLOCK_SIZE];
    
    //Make the key BLOCK_SIZE bytes long by hashing longer ones or padding shorter one with 0s
    if (keyLength > BLOCK_SIZE)
    {
        Sha1(key, keyLength, hmacKey);
        for (int i = HASH_SIZE; i < BLOCK_SIZE; i++) hmacKey[i] = 0;
    }
    else
    {
        for (int i = 0;         i < keyLength;  i++) hmacKey[i] = key[i];
        for (int i = keyLength; i < BLOCK_SIZE; i++) hmacKey[i] = 0;
    }
    
    //Make the inner and outer padded keys
    uint8_t oKeyPad[BLOCK_SIZE];
    uint8_t iKeyPad[BLOCK_SIZE];
    for (int i = 0; i < BLOCK_SIZE; i++)
    {
        oKeyPad[i] = hmacKey[i] ^ 0x5c; //Outer padded key
        iKeyPad[i] = hmacKey[i] ^ 0x36; //Inner padded key
    }
    
    //hash(o_key_pad + hash(i_key_pad + message) where + is concatenation
    uint8_t* tempi = alloca(BLOCK_SIZE + messageLength);
    for (int i = 0; i < BLOCK_SIZE;    i++) tempi[i             ] = iKeyPad[i];
    for (int i = 0; i < messageLength; i++) tempi[i + BLOCK_SIZE] = message[i];
    uint8_t tmpHash[HASH_SIZE];
    Sha1(tempi, BLOCK_SIZE + messageLength, tmpHash);
    
    uint8_t tmpMsg[BLOCK_SIZE + HASH_SIZE];
    for (int i = 0; i < BLOCK_SIZE; i++) tmpMsg[i             ] = oKeyPad[i];
    for (int i = 0; i <  HASH_SIZE; i++) tmpMsg[i + BLOCK_SIZE] = tmpHash[i];
    Sha1(tmpMsg, BLOCK_SIZE + HASH_SIZE, mac);
}
void HmacSha1Start(struct HmacSha1Struct* md, const uint8_t* key, int keyLength)
{
    //Make the key BLOCK_SIZE bytes long by hashing longer ones or padding shorter one with 0s
    if (keyLength > BLOCK_SIZE)
    {
        Sha1(key, keyLength, md->hmacKey);
        for (int i = HASH_SIZE; i < BLOCK_SIZE; i++) md->hmacKey[i] = 0;
    }
    else
    {
        for (int i = 0;         i < keyLength;  i++) md->hmacKey[i] = key[i];
        for (int i = keyLength; i < BLOCK_SIZE; i++) md->hmacKey[i] = 0;
    }
    Sha1Start(&md->shaStruct);
    
    //Make the inner and outer padded keys
    uint8_t iKeyPad[BLOCK_SIZE];
    for (int i = 0; i < BLOCK_SIZE; i++)
    {
        iKeyPad[i] = md->hmacKey[i] ^ 0x36; //Inner padded key
    }
    Sha1Add(&md->shaStruct, iKeyPad, BLOCK_SIZE);
}
void HmacSha1Add(struct HmacSha1Struct* md, const uint8_t* message, int messageLength)
{
    Sha1Add(&md->shaStruct, message, messageLength);
}
void HmacSha1Finish(struct HmacSha1Struct* md, uint8_t* mac)
{
    //Make the inner and outer padded keys
    uint8_t oKeyPad[BLOCK_SIZE];
    for (int i = 0; i < BLOCK_SIZE; i++)
    {
        oKeyPad[i] = md->hmacKey[i] ^ 0x5c; //Outer padded key
    }
    
    uint8_t innerHash[HASH_SIZE];
    Sha1Finish(&md->shaStruct, innerHash);
    
    Sha1Start(&md->shaStruct);
    Sha1Add(&md->shaStruct, oKeyPad, BLOCK_SIZE);
    Sha1Add(&md->shaStruct, innerHash, HASH_SIZE);
    
    Sha1Finish(&md->shaStruct, mac);
}