SHA-1 - an implementation of the Secure Hash Algorithm in C
HMAC-SHA-1 - an implementation of the HMAC message authentication
Version as of March 4th 2007

Copyright (C) 2006-2007 CHZ-Soft, Christian Zietz, <czietz@gmx.net>
Licensed under GPL. See COPYING file for more information.


sha1.c and hmac.c contain implementations of the Secure Hash 
Algorithm (SHA-1) [1] and the keyed-hash message authentication code
(HMAC) [2] respectively. They are optimized for fairly low code size 
and RAM usage, i.e. they are suitable for use on a microcontroller. 
They have been tested on an AVR 8-bit MCU using AVR-GCC [3] as C 
compiler.


--- SHA-1 ---
(see below for HMAC-SHA-1)

Usage: 

Include sha1.h, compile sha1.c and link your program against
the resulting object file. 
If your target architecture/compiler is little endian (AVR-GCC is) 
then SHA_LITTLE_ENDIAN must be defined at the beginning of sha1.c.
If you need to process more than 65535 bytes for one digest, you 
have to define SHA_BIG_DATA in sha1.c. This will slightly increase 
the code size and the RAM usage .


Limitations:

If SHA_BIG_DATA is not defined (see 'Usage'), the maximum amount of 
data that can be hashed to one digest is 65535 (=2^16-1) bytes. 
Otherwise it is 2^29-1 bytes.
Data must be hashed either in one block or in blocks sized 64 bytes 
with the exception of the last block. See 'Functions and variables' 
for further information.


Functions and variables:

void SHA1Init(void);
Initializes the internal data structures. Call it before hashing
data using the following functions.

void SHA1Block(const unsigned char* data, const uint8_t len);
Hashes a block of data. 'data' points to the data to hash, 'len' is
the length of the block in bytes. Call the function repeatedly until
all of your data is processed. See 'Limitations' for the maximum 
amount of data than can be hashed.
All blocks with the exception of the last one MUST be 64 bytes long. 
The last block MUST be smaller than 64 bytes because padding has to 
be applied. If your last data block is 64 bytes long, then you have 
to call SHA1Block again with a 'len' of 0 to finalize the hashing.

void SHA1Done(void);
Terminates the calculation. A global variable 'shadigest' (see 
below) will contain the digest.

void SHA1Once(const unsigned char* data, int len);
Initializes the data structures, hashes data and outputs the digest
in 'shadigest'. 'data' points to the data, 'len' is the length which
can be any value up to the maximum data size supported (see 
'Limitations'). The function automatically splits the data into 
blocks which are suitable for processing.

unsigned char shadigest[20];
This global variable will contain the SHA-1 digest (160 bits long) 
after SHA1Done or SHA1Once.


--- HMAC-SHA-1 ---

Usage: 

Include hmac.h, compile sha1.c and hmac.c and link your program against
the resulting object files. Note that SHA_LITTLE_ENDIAN must be set in
sha1.c if you want to do HMAC on a little endian architecture 
(see above).


Limitations:

The limitations mentioned for SHA-1 also apply for HMAC. Maximum 
supported data size for HMAC is 64 bytes smaller than for SHA-1. 
Additionally the maximum key size supported by this implementation is 
64 bytes.


Functions and variables:

void HMACInit(const unsigned char* key, const uint8_t len);
Initializes the internal data structures and sets the key to be used.
'key' points to the key, 'len' is its length (<=64 bytes).
Note that since HMAC is based on SHA-1 it will reuse its internal 
data structures and any results from a previous SHA-1 calculation 
will be overwritten.

void HMACBlock(const unsigned char* data, const uint8_t len);
Authenticates a block of data. See the description of SHA1Block for 
any further information. Note that the limitations concerning the 
allowed block sizes also apply for HMAC.

void HMACDone(void);
Finishes the message authentication. The global variable hmacdigest 
will then contain the digest.

void HMACOnce(const unsigned char* key, const uint8_t klen, 
              const unsigned char* data, int len);
Authenticates an arbitrarily sized block of data. 'key' points to 
the key to use, 'klen' is the key size (<=64 bytes), 'data' points to 
the data to authenticate, 'len' is the size of data (cf. 'Limitations').
The result is stored in hmacdigest.

unsigned char hmacdigest[20];
This is actually just another name for 'shadigest'. It will contain 
the calculated HMAC digest.


--- Appendix ---

Performance:

Using AVR-GCC to compile the code for an ATMega169 the SHA-1 code 
occupies roughly 1.7kiByte of Flash and 150 bytes of RAM for global 
variables and stack. Its thoughput is about 8kiByte/s at 8MHz.
HMAC and SHA-1 together occupy about 2kiByte of Flash.


Links:

[1] Secure Hash Algorithm: http://www.itl.nist.gov/fipspubs/fip180-1.htm
[2] HMAC: http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
[3] AVR-GCC for Microsoft Windows: http://winavr.sourceforge.net/
