crypto-algorithms.c

Basic implementations of standard cryptography algorithms, like AES and SHA-1
git clone git://git.finwo.net/lib/crypto-algorithms.c
Log | Files | Refs | README

sha1.c (3941B)


      1 /*********************************************************************
      2 * Filename:   sha1.c
      3 * Author:     Brad Conte (brad AT bradconte.com)
      4 * Copyright:
      5 * Disclaimer: This code is presented "as is" without any guarantees.
      6 * Details:    Implementation of the SHA1 hashing algorithm.
      7               Algorithm specification can be found here:
      8                * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
      9               This implementation uses little endian byte order.
     10 *********************************************************************/
     11 
     12 /*************************** HEADER FILES ***************************/
     13 #include <stdlib.h>
     14 #include <memory.h>
     15 #include "sha1.h"
     16 
     17 /****************************** MACROS ******************************/
     18 #define ROTLEFT(a, b) ((a << b) | (a >> (32 - b)))
     19 
     20 /*********************** FUNCTION DEFINITIONS ***********************/
     21 void sha1_transform(SHA1_CTX *ctx, const BYTE data[])
     22 {
     23 	WORD a, b, c, d, e, i, j, t, m[80];
     24 
     25 	for (i = 0, j = 0; i < 16; ++i, j += 4)
     26 		m[i] = (data[j] << 24) + (data[j + 1] << 16) + (data[j + 2] << 8) + (data[j + 3]);
     27 	for ( ; i < 80; ++i) {
     28 		m[i] = (m[i - 3] ^ m[i - 8] ^ m[i - 14] ^ m[i - 16]);
     29 		m[i] = (m[i] << 1) | (m[i] >> 31);
     30 	}
     31 
     32 	a = ctx->state[0];
     33 	b = ctx->state[1];
     34 	c = ctx->state[2];
     35 	d = ctx->state[3];
     36 	e = ctx->state[4];
     37 
     38 	for (i = 0; i < 20; ++i) {
     39 		t = ROTLEFT(a, 5) + ((b & c) ^ (~b & d)) + e + ctx->k[0] + m[i];
     40 		e = d;
     41 		d = c;
     42 		c = ROTLEFT(b, 30);
     43 		b = a;
     44 		a = t;
     45 	}
     46 	for ( ; i < 40; ++i) {
     47 		t = ROTLEFT(a, 5) + (b ^ c ^ d) + e + ctx->k[1] + m[i];
     48 		e = d;
     49 		d = c;
     50 		c = ROTLEFT(b, 30);
     51 		b = a;
     52 		a = t;
     53 	}
     54 	for ( ; i < 60; ++i) {
     55 		t = ROTLEFT(a, 5) + ((b & c) ^ (b & d) ^ (c & d))  + e + ctx->k[2] + m[i];
     56 		e = d;
     57 		d = c;
     58 		c = ROTLEFT(b, 30);
     59 		b = a;
     60 		a = t;
     61 	}
     62 	for ( ; i < 80; ++i) {
     63 		t = ROTLEFT(a, 5) + (b ^ c ^ d) + e + ctx->k[3] + m[i];
     64 		e = d;
     65 		d = c;
     66 		c = ROTLEFT(b, 30);
     67 		b = a;
     68 		a = t;
     69 	}
     70 
     71 	ctx->state[0] += a;
     72 	ctx->state[1] += b;
     73 	ctx->state[2] += c;
     74 	ctx->state[3] += d;
     75 	ctx->state[4] += e;
     76 }
     77 
     78 void sha1_init(SHA1_CTX *ctx)
     79 {
     80 	ctx->datalen = 0;
     81 	ctx->bitlen = 0;
     82 	ctx->state[0] = 0x67452301;
     83 	ctx->state[1] = 0xEFCDAB89;
     84 	ctx->state[2] = 0x98BADCFE;
     85 	ctx->state[3] = 0x10325476;
     86 	ctx->state[4] = 0xc3d2e1f0;
     87 	ctx->k[0] = 0x5a827999;
     88 	ctx->k[1] = 0x6ed9eba1;
     89 	ctx->k[2] = 0x8f1bbcdc;
     90 	ctx->k[3] = 0xca62c1d6;
     91 }
     92 
     93 void sha1_update(SHA1_CTX *ctx, const BYTE data[], size_t len)
     94 {
     95 	size_t i;
     96 
     97 	for (i = 0; i < len; ++i) {
     98 		ctx->data[ctx->datalen] = data[i];
     99 		ctx->datalen++;
    100 		if (ctx->datalen == 64) {
    101 			sha1_transform(ctx, ctx->data);
    102 			ctx->bitlen += 512;
    103 			ctx->datalen = 0;
    104 		}
    105 	}
    106 }
    107 
    108 void sha1_final(SHA1_CTX *ctx, BYTE hash[])
    109 {
    110 	WORD i;
    111 
    112 	i = ctx->datalen;
    113 
    114 	// Pad whatever data is left in the buffer.
    115 	if (ctx->datalen < 56) {
    116 		ctx->data[i++] = 0x80;
    117 		while (i < 56)
    118 			ctx->data[i++] = 0x00;
    119 	}
    120 	else {
    121 		ctx->data[i++] = 0x80;
    122 		while (i < 64)
    123 			ctx->data[i++] = 0x00;
    124 		sha1_transform(ctx, ctx->data);
    125 		memset(ctx->data, 0, 56);
    126 	}
    127 
    128 	// Append to the padding the total message's length in bits and transform.
    129 	ctx->bitlen += ctx->datalen * 8;
    130 	ctx->data[63] = ctx->bitlen;
    131 	ctx->data[62] = ctx->bitlen >> 8;
    132 	ctx->data[61] = ctx->bitlen >> 16;
    133 	ctx->data[60] = ctx->bitlen >> 24;
    134 	ctx->data[59] = ctx->bitlen >> 32;
    135 	ctx->data[58] = ctx->bitlen >> 40;
    136 	ctx->data[57] = ctx->bitlen >> 48;
    137 	ctx->data[56] = ctx->bitlen >> 56;
    138 	sha1_transform(ctx, ctx->data);
    139 
    140 	// Since this implementation uses little endian byte ordering and MD uses big endian,
    141 	// reverse all the bytes when copying the final state to the output hash.
    142 	for (i = 0; i < 4; ++i) {
    143 		hash[i]      = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
    144 		hash[i + 4]  = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
    145 		hash[i + 8]  = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
    146 		hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
    147 		hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
    148 	}
    149 }