Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
feudalnate committed Aug 23, 2019
1 parent 06cc042 commit 223d537
Show file tree
Hide file tree
Showing 32 changed files with 4,817 additions and 0 deletions.
3 changes: 3 additions & 0 deletions C/SHA1/hmac.h
@@ -0,0 +1,3 @@
#include "sha.h"

void hmac_sha1(const uint8_t *key, size_t keyLen, const uint8_t *data, size_t dataLen, uint8_t *out_hash);
60 changes: 60 additions & 0 deletions C/SHA1/hmac_sha1.c
@@ -0,0 +1,60 @@
#include <string.h>
#include <stdint.h>
#include "sha.h"

#define SHA_BLOCKSIZE (64)

/**
* Function to compute the digest
*
* @param key Secret key
* @param keyLen Length of the key in bytes
* @param data Data
* @param dataLen Length of data in bytes
* @param out_hash Digest output
*/
void hmac_sha1(const uint8_t *key, size_t keyLen, const uint8_t *data, size_t dataLen, uint8_t *out_hash) {

SHA_CTX ictx, octx;
uint8_t isha[SHA_DIGEST_LENGTH], osha[SHA_DIGEST_LENGTH];
uint8_t keybuf[SHA_DIGEST_LENGTH];
uint8_t buf[SHA_BLOCKSIZE];
size_t i;

if (keyLen > SHA_BLOCKSIZE) {
SHA_CTX tctx;
SHA1_Init(&tctx);
SHA1_Update(&tctx, key, keyLen);
SHA1_Final(keybuf, &tctx);
key = keybuf;
keyLen = SHA_DIGEST_LENGTH;
}

/**** Inner Digest ****/

SHA1_Init(&ictx);

/* Pad the key for inner digest */
for (i = 0; i < keyLen; ++i) buf[i] = key[i] ^ 0x36;
for (i = keyLen; i < SHA_BLOCKSIZE; ++i) buf[i] = 0x36;

SHA1_Update(&ictx, buf, SHA_BLOCKSIZE);
SHA1_Update(&ictx, data, dataLen);
SHA1_Final(isha, &ictx);

/**** Outer Digest ****/

SHA1_Init(&octx);

/* Pad the key for outter digest */

for (i = 0; i < keyLen; ++i) buf[i] = key[i] ^ 0x5c;
for (i = keyLen; i < SHA_BLOCKSIZE; ++i) buf[i] = 0x5c;

SHA1_Update(&octx, buf, SHA_BLOCKSIZE);
SHA1_Update(&octx, isha, SHA_DIGEST_LENGTH);
SHA1_Final(osha, &octx);

/* truncate and print the results */
memcpy(out_hash, osha, SHA_DIGEST_LENGTH);
}
21 changes: 21 additions & 0 deletions C/SHA1/sha.h
@@ -0,0 +1,21 @@
// SHA-1 Context
typedef struct {
uint32_t state[5];
//Context state
uint32_t count[2];
//Counter
uint8_t buffer[64]; //SHA-1 buffer
} SHA1_CTX;

typedef SHA1_CTX SHA_CTX;

// SHA-1 Digest size in bytes
#define SHA1_DIGEST_SIZE 20
// SHA-1 Digest size in bytes
#define SHA_DIGEST_LENGTH SHA1_DIGEST_SIZE

void SHA1_Init(SHA1_CTX *context);

void SHA1_Update(SHA1_CTX *context, const void *p, size_t len);

void SHA1_Final(uint8_t digest[SHA1_DIGEST_SIZE], SHA1_CTX *context);
242 changes: 242 additions & 0 deletions C/SHA1/sha1.c
@@ -0,0 +1,242 @@
#define SHA1HANDSOFF (1)

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "sha.h"

void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);

#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))

#if defined (BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
#define WORDS_BIGENDIAN 1
#endif
#ifdef _BIG_ENDIAN
#define WORDS_BIGENDIAN 1
#endif


/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
/* FIXME: can we do this in an endian-proof way? */
#ifdef WORDS_BIGENDIAN
#define blk0(i) block->l[i]
#else
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xff00ff00) \
|(rol(block->l[i],8)&0x00ff00ff))
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))

/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v, w, x, y, z, i) \
z+=((w&(x^y))^y)+blk0(i)+0x5a827999+rol(v,5);w=rol(w,30);
#define R1(v, w, x, y, z, i) \
z+=((w&(x^y))^y)+blk(i)+0x5a827999+rol(v,5);w=rol(w,30);
#define R2(v, w, x, y, z, i) \
z+=(w^x^y)+blk(i)+0x6ed9eba1+rol(v,5);w=rol(w,30);
#define R3(v, w, x, y, z, i) \
z+=(((w|x)&y)|(w&x))+blk(i)+0x8f1bbcdc+rol(v,5);w=rol(w,30);
#define R4(v, w, x, y, z, i) \
z+=(w^x^y)+blk(i)+0xca62c1d6+rol(v,5);w=rol(w,30);


/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]) {
uint32_t a, b, c, d, e;
typedef union {
uint8_t c[64];
uint32_t l[16];
} CHAR64LONG16;
CHAR64LONG16 *block;

#ifdef SHA1HANDSOFF
CHAR64LONG16 workspace;
block = &workspace;
memcpy(block, buffer, 64);
#else
block = (CHAR64LONG16*)buffer;
#endif

/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];

/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a, b, c, d, e, 0);
R0(e, a, b, c, d, 1);
R0(d, e, a, b, c, 2);
R0(c, d, e, a, b, 3);
R0(b, c, d, e, a, 4);
R0(a, b, c, d, e, 5);
R0(e, a, b, c, d, 6);
R0(d, e, a, b, c, 7);
R0(c, d, e, a, b, 8);
R0(b, c, d, e, a, 9);
R0(a, b, c, d, e, 10);
R0(e, a, b, c, d, 11);
R0(d, e, a, b, c, 12);
R0(c, d, e, a, b, 13);
R0(b, c, d, e, a, 14);
R0(a, b, c, d, e, 15);
R1(e, a, b, c, d, 16);
R1(d, e, a, b, c, 17);
R1(c, d, e, a, b, 18);
R1(b, c, d, e, a, 19);
R2(a, b, c, d, e, 20);
R2(e, a, b, c, d, 21);
R2(d, e, a, b, c, 22);
R2(c, d, e, a, b, 23);
R2(b, c, d, e, a, 24);
R2(a, b, c, d, e, 25);
R2(e, a, b, c, d, 26);
R2(d, e, a, b, c, 27);
R2(c, d, e, a, b, 28);
R2(b, c, d, e, a, 29);
R2(a, b, c, d, e, 30);
R2(e, a, b, c, d, 31);
R2(d, e, a, b, c, 32);
R2(c, d, e, a, b, 33);
R2(b, c, d, e, a, 34);
R2(a, b, c, d, e, 35);
R2(e, a, b, c, d, 36);
R2(d, e, a, b, c, 37);
R2(c, d, e, a, b, 38);
R2(b, c, d, e, a, 39);
R3(a, b, c, d, e, 40);
R3(e, a, b, c, d, 41);
R3(d, e, a, b, c, 42);
R3(c, d, e, a, b, 43);
R3(b, c, d, e, a, 44);
R3(a, b, c, d, e, 45);
R3(e, a, b, c, d, 46);
R3(d, e, a, b, c, 47);
R3(c, d, e, a, b, 48);
R3(b, c, d, e, a, 49);
R3(a, b, c, d, e, 50);
R3(e, a, b, c, d, 51);
R3(d, e, a, b, c, 52);
R3(c, d, e, a, b, 53);
R3(b, c, d, e, a, 54);
R3(a, b, c, d, e, 55);
R3(e, a, b, c, d, 56);
R3(d, e, a, b, c, 57);
R3(c, d, e, a, b, 58);
R3(b, c, d, e, a, 59);
R4(a, b, c, d, e, 60);
R4(e, a, b, c, d, 61);
R4(d, e, a, b, c, 62);
R4(c, d, e, a, b, 63);
R4(b, c, d, e, a, 64);
R4(a, b, c, d, e, 65);
R4(e, a, b, c, d, 66);
R4(d, e, a, b, c, 67);
R4(c, d, e, a, b, 68);
R4(b, c, d, e, a, 69);
R4(a, b, c, d, e, 70);
R4(e, a, b, c, d, 71);
R4(d, e, a, b, c, 72);
R4(c, d, e, a, b, 73);
R4(b, c, d, e, a, 74);
R4(a, b, c, d, e, 75);
R4(e, a, b, c, d, 76);
R4(d, e, a, b, c, 77);
R4(c, d, e, a, b, 78);
R4(b, c, d, e, a, 79);

/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;

/* Wipe variables */
a = b = c = d = e = 0;
}


/**
* Initialize new context
*
* @param context SHA1-Context
*/
void SHA1_Init(SHA1_CTX *context) {
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
context->state[4] = 0xc3d2e1f0;
context->count[0] = context->count[1] = 0;
}


/**
* Run your data through this
*
* @param context SHA1-Context
* @param p Buffer to run SHA1 on
* @param len Number of bytes
*/
void SHA1_Update(SHA1_CTX *context, const void *p, size_t len) {
const uint8_t *data = p;
size_t i, j;

j = (context->count[0] >> 3) & 63;
if ((context->count[0] += (uint32_t) (len << 3)) < (len << 3)) {
context->count[1]++;
}
context->count[1] += (uint32_t) (len >> 29);
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64 - j));
SHA1_Transform(context->state, context->buffer);
for (; i + 63 < len; i += 64) {
SHA1_Transform(context->state, data + i);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}


/**
* Add padding and return the message digest
*
* @param digest Generated message digest
* @param context SHA1-Context
*/
void SHA1_Final(uint8_t digest[SHA1_DIGEST_SIZE], SHA1_CTX *context) {
uint32_t i;
uint8_t finalcount[8];

for (i = 0; i < 8; i++) {
finalcount[i] = (uint8_t) ((context->count[(i >= 4 ? 0 : 1)]
>> ((3 - (i & 3)) * 8)) & 255);
}
SHA1_Update(context, (uint8_t *) "\200", 1);
while ((context->count[0] & 504) != 448) {
SHA1_Update(context, (uint8_t *) "\0", 1);
}
SHA1_Update(context, finalcount, 8); /* Should cause SHA1_Transform */
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
digest[i] = (uint8_t)
((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
}

/* Wipe variables */
i = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(finalcount, 0, 8); /* SWR */

#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
SHA1_Transform(context->state, context->buffer);
#endif
}

0 comments on commit 223d537

Please sign in to comment.