From b3048aeaf08d6d88210a62e4c5582830be2bb2ed Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 15 Jul 2019 11:17:51 +0100 Subject: c version of asm - now working --- sha1/test/totp1.c | 270 +++++++++++++++++++++++++++++++++++++++++++++++++ sha1/test/totp2.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++ sha1/test/totp3.c | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 825 insertions(+) create mode 100644 sha1/test/totp1.c create mode 100644 sha1/test/totp2.c create mode 100644 sha1/test/totp3.c diff --git a/sha1/test/totp1.c b/sha1/test/totp1.c new file mode 100644 index 0000000..ca74c06 --- /dev/null +++ b/sha1/test/totp1.c @@ -0,0 +1,270 @@ +/******************************************************************************* + * Teeny SHA-1 + * + * The below sha1digest() calculates a SHA-1 hash value for a + * specified data buffer and generates a hex representation of the + * result. This implementation is a re-forming of the SHA-1 code at + * https://github.com/jinqiangshou/EncryptionLibrary. + * + * Copyright (c) 2017 CTrabant + * + * License: MIT, see included LICENSE file for details. + * + * To use the sha1digest() function either copy it into an existing + * project source code file or include this file in a project and put + * the declaration (example below) in the sources files where needed. + ******************************************************************************/ + +#include +#include +#include +#include + +/* Declaration: +extern int sha1digest(uint8_t *digest, char *hexdigest, const uint8_t *data, size_t databytes); +*/ + +/******************************************************************************* + * sha1digest: https://github.com/CTrabant/teeny-sha1 + * + * Calculate the SHA-1 value for supplied data buffer and generate a + * text representation in hexadecimal. + * + * Based on https://github.com/jinqiangshou/EncryptionLibrary, credit + * goes to @jinqiangshou, all new bugs are mine. + * + * @input: + * data -- data to be hashed + * databytes -- bytes in data buffer to be hashed + * + * @output: + * digest -- the result, MUST be at least 20 bytes + * hexdigest -- the result in hex, MUST be at least 41 bytes + * + * At least one of the output buffers must be supplied. The other, if not + * desired, may be set to NULL. + * + * @return: 0 on success and non-zero on error. + ******************************************************************************/ + + +int +sha1digest(uint8_t *digest, const uint8_t *data, size_t databytes) +{ +#define SHA1ROTATELEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + + uint32_t W[80]; + uint32_t H[] = {0x67452301, + 0xEFCDAB89, + 0x98BADCFE, + 0x10325476, + 0xC3D2E1F0}; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint32_t e; + uint32_t f = 0; + uint32_t k = 0; + + uint32_t idx; + uint32_t lidx; + uint32_t widx; + uint32_t didx = 0; + + int32_t wcount; + uint32_t temp; + uint64_t databits = ((uint64_t)databytes) * 8; + uint32_t loopcount = (databytes + 8) / 64 + 1; + uint32_t tailbytes = 64 * loopcount - databytes; + uint8_t datatail[128] = {0}; + + printf("in="); + for (idx=0;idx> 56 & 0xFF); + datatail[tailbytes - 7] = (uint8_t) (databits >> 48 & 0xFF); + datatail[tailbytes - 6] = (uint8_t) (databits >> 40 & 0xFF); + datatail[tailbytes - 5] = (uint8_t) (databits >> 32 & 0xFF); + datatail[tailbytes - 4] = (uint8_t) (databits >> 24 & 0xFF); + datatail[tailbytes - 3] = (uint8_t) (databits >> 16 & 0xFF); + datatail[tailbytes - 2] = (uint8_t) (databits >> 8 & 0xFF); + datatail[tailbytes - 1] = (uint8_t) (databits >> 0 & 0xFF); + + /* Process each 512-bit chunk */ + for (lidx = 0; lidx < loopcount; lidx++) + { + /* Compute all elements in W */ + memset (W, 0, 80 * sizeof (uint32_t)); + + /* Break 512-bit chunk into sixteen 32-bit, big endian words */ + for (widx = 0; widx <= 15; widx++) + { + wcount = 24; + + /* Copy byte-per byte from specified buffer */ + while (didx < databytes && wcount >= 0) + { + W[widx] += (((uint32_t)data[didx]) << wcount); + didx++; + wcount -= 8; + } + /* Fill out W with padding as needed */ + while (wcount >= 0) + { + W[widx] += (((uint32_t)datatail[didx - databytes]) << wcount); + didx++; + wcount -= 8; + } + } + + { + uint8_t *c=(uint8_t*) W; + printf("w1="); + for (idx=0;idx<64;++idx) { + printf("%02x",c[idx]); + } + printf("\n"); + } + + + /* Extend the sixteen 32-bit words into eighty 32-bit words, with potential optimization from: + "Improving the Performance of the Secure Hash Algorithm (SHA-1)" by Max Locktyukhin */ + for (widx = 16; widx <= 31; widx++) + { + W[widx] = SHA1ROTATELEFT ((W[widx - 3] ^ W[widx - 8] ^ W[widx - 14] ^ W[widx - 16]), 1); + } + for (widx = 32; widx <= 79; widx++) + { + W[widx] = SHA1ROTATELEFT ((W[widx - 6] ^ W[widx - 16] ^ W[widx - 28] ^ W[widx - 32]), 2); + } + +{ + uint8_t *c=(uint8_t*) W; + printf("w2="); + for (idx=0;idx<320;++idx) { + printf("%02x",c[idx]); + } + printf("\n"); + } + + /* Main loop */ + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + + for (idx = 0; idx <= 79; idx++) + { + if (idx <= 19) + { + f = (b & c) | ((~b) & d); + k = 0x5A827999; + } + else if (idx >= 20 && idx <= 39) + { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } + else if (idx >= 40 && idx <= 59) + { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } + else if (idx >= 60 && idx <= 79) + { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + temp = SHA1ROTATELEFT (a, 5) + f + e + k + W[idx]; + e = d; + d = c; + c = SHA1ROTATELEFT (b, 30); + b = a; + a = temp; + } + + H[0] += a; + H[1] += b; + H[2] += c; + H[3] += d; + H[4] += e; + } + + /* Store binary digest in supplied buffer */ + if (digest) + { + for (idx = 0; idx < 5; idx++) + { + digest[idx * 4 + 0] = (uint8_t) (H[idx] >> 24); + digest[idx * 4 + 1] = (uint8_t) (H[idx] >> 16); + digest[idx * 4 + 2] = (uint8_t) (H[idx] >> 8); + digest[idx * 4 + 3] = (uint8_t) (H[idx]); + } + } + + printf("out="); + for (idx=0;idx<20;++idx) { + printf("%02x",digest[idx]); + } + printf("\n"); + + return 0; +} /* End of sha1digest() */ + + +uint8_t key[]={ 0x6e,0x38,0x0e,0x89,0xe9,0xcf,0x3c,0xbb,0xe4,0x4f}; +uint8_t data[]={ 0x00,0x00,0x00,0x00,0x00,0x00,0xa7,0xa6}; + +uint8_t buf[128]; + + +void pad_key(uint8_t *b,uint8_t v) +{ +int i; +memset(b,0,64); +memcpy(b,key,10); + +for (i=0;i<64;++i) b[i]^=v; +} + +int main(int argc,char * argv[]) +{ +int i; + +pad_key(buf,0x36); +memcpy(buf+64,data,8); + +sha1digest(buf+64,buf,64+8); + +pad_key(buf,0x5c); +sha1digest(buf,buf,64+20); + + +for (i=0;i<20;++i) +{ +printf("%02x",buf[i]); +} +printf("\n"); + + +return 0; + + + + +} + + + + + diff --git a/sha1/test/totp2.c b/sha1/test/totp2.c new file mode 100644 index 0000000..9aacd2a --- /dev/null +++ b/sha1/test/totp2.c @@ -0,0 +1,257 @@ +/******************************************************************************* + * Teeny SHA-1 + * + * The below sha1digest() calculates a SHA-1 hash value for a + * specified data buffer and generates a hex representation of the + * result. This implementation is a re-forming of the SHA-1 code at + * https://github.com/jinqiangshou/EncryptionLibrary. + * + * Copyright (c) 2017 CTrabant + * + * License: MIT, see included LICENSE file for details. + * + * To use the sha1digest() function either copy it into an existing + * project source code file or include this file in a project and put + * the declaration (example below) in the sources files where needed. + ******************************************************************************/ + +#include +#include +#include +#include + + +uint8_t key[]={ 0x89,0x0e,0x38,0x6e, 0xbb,0x3c,0xcf, 0xe9,0x00,0x00,0x4f,0xe4}; +uint8_t msg[]={ 0x00,0x00,0x00,0x00,0xa6,0xa7,0x00,0x00}; + + +uint8_t data[24]; +uint32_t data2; +uint8_t w2[16]; +uint8_t dlen; +uint32_t key_or; + +uint8_t buf[128]; + + +uint32_t get_w32_016(int idx,int loop) +{ +uint32_t t1; + +if (!loop) { + +if (idx<3) { + memcpy(&t1,&key[idx<<2],4); +} else { + memset(&t1,0,4); +} + +t1^=key_or; + + return t1; +} + + +if (idx> (32 - (bits)))) +uint32_t Wbuf[16]; + +uint32_t get_w32(int idx,int loop) +{ + int i; + uint32_t t2; + + for (i=0;i<16;++i) + Wbuf[i]=get_w32_016(i,loop); + + + if (idx<16) + return Wbuf[idx]; + + idx-=16; + + + while (1) { + t2=SHA1ROTATELEFT(Wbuf[13] ^Wbuf[8] ^ Wbuf[2] ^ Wbuf[0],1); + if (!idx) return t2; + + memmove(Wbuf,Wbuf+1,60); + Wbuf[15]=t2; + + idx--; + } +} + + + + + + + + +int +sha1digest(uint8_t *digest) +{ + + uint32_t H[] = {0x67452301, + 0xEFCDAB89, + 0x98BADCFE, + 0x10325476, + 0xC3D2E1F0}; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint32_t e; + uint32_t f = 0; + uint32_t k = 0; + + uint32_t idx; + uint32_t lidx; + uint32_t widx; + uint32_t didx = 0; + + int32_t wcount; + uint32_t temp; + uint8_t datatail[128] = {0}; + + + /* Process each 512-bit chunk */ + for (lidx = 0; lidx < 2; lidx++) + { + + { + uint32_t w;; + printf("w2="); + for (idx=0;idx<80;++idx) { + w=get_w32(idx,lidx); + printf("%02x%02x%02x%02x", + (w>>0) &0xff, + (w>>8) &0xff, + (w>>16) &0xff, + (w>>24) &0xff); + } + printf("\n"); + } + + /* Main loop */ + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + + for (idx = 0; idx <= 79; idx++) + { + if (idx <= 19) + { + f = (b & c) | ((~b) & d); + k = 0x5A827999; + } + else if (idx >= 20 && idx <= 39) + { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } + else if (idx >= 40 && idx <= 59) + { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } + else if (idx >= 60 && idx <= 79) + { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + temp = SHA1ROTATELEFT (a, 5) + f + e + k + get_w32(idx,lidx); + e = d; + d = c; + c = SHA1ROTATELEFT (b, 30); + b = a; + a = temp; + } + + H[0] += a; + H[1] += b; + H[2] += c; + H[3] += d; + H[4] += e; + } + + /* Store binary digest in supplied buffer */ + if (digest) + { + for (idx = 0; idx < 5; idx++) + { + digest[idx * 4 + 0] = (uint8_t) (H[idx] >> 0); + digest[idx * 4 + 1] = (uint8_t) (H[idx] >> 8); + digest[idx * 4 + 2] = (uint8_t) (H[idx] >> 16); + digest[idx * 4 + 3] = (uint8_t) (H[idx] >> 24); + } + } + + printf("out="); + for (idx=0;idx<20;++idx) { + printf("%02x",digest[idx]); + } + printf("\n"); + + return 0; +} /* End of sha1digest() */ + + + + +int main(int argc,char * argv[]) +{ +int i; + +memcpy(data,msg,8); +data[8]=0; +data[9]=0; +data[10]=0; +data[11]=0x80; + +data2=0x00000240; + + +key_or=0x36363636; +dlen=3; +sha1digest(data); + +data[20]=0; +data[21]=0; +data[22]=0; +data[23]=0x80; + +data2=0x000002a0; + +key_or=0x5c5c5c5c; +dlen=6; +sha1digest(buf); + + +for (i=0;i<20;++i) +{ +printf("%02x",buf[i]); +} +printf("\n"); + + +return 0; + + +} + + + + + diff --git a/sha1/test/totp3.c b/sha1/test/totp3.c new file mode 100644 index 0000000..e2e6cfd --- /dev/null +++ b/sha1/test/totp3.c @@ -0,0 +1,298 @@ +/******************************************************************************* + * Teeny SHA-1 + * + * The below sha1digest() calculates a SHA-1 hash value for a + * specified data buffer and generates a hex representation of the + * result. This implementation is a re-forming of the SHA-1 code at + * https://github.com/jinqiangshou/EncryptionLibrary. + * + * Copyright (c) 2017 CTrabant + * + * License: MIT, see included LICENSE file for details. + * + * To use the sha1digest() function either copy it into an existing + * project source code file or include this file in a project and put + * the declaration (example below) in the sources files where needed. + ******************************************************************************/ + +#include +#include +#include +#include + +#define SWAB(a) ((a>>24) | ((a & 0x00ff0000>>8)) | ((a &0x0000ff00) <<8) | (a<<24)) + + + +uint32_t key[] = { 0x6e380e89, 0xe9cf3cbb, 0xe44f0000 }; + +uint32_t k1 = 0x5A827999; +uint32_t k2 = 0x6ED9EBA1; +uint32_t k3 = 0x8F1BBCDC; +uint32_t k4 = 0xCA62C1D6; +uint32_t ffffffff = 0xffffffff; + +uint32_t va, vb, vc, vd, ve, t1, t2, zero; + +uint32_t data[6]; +uint32_t data2; +uint32_t key_or; + +uint8_t lidx; +uint8_t idx; + +uint32_t H[5]; +uint32_t Wbuf[16]; + +uint32_t HI[] = { + 0x67452301, + 0xEFCDAB89, + 0x98BADCFE, + 0x10325476, + 0xC3D2E1F0 +}; + + + +#define SHA1ROTATELEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + + +void +set_key_or (uint8_t v) +{ + key_or = v; + key_or <<= 8; + key_or |= v; + key_or <<= 8; + key_or |= v; + key_or <<= 8; + key_or |= v; +} + +void +get_w32_015_to_t2 (int idx) +{ + uint32_t t1; + + if (!lidx) + { + + if (idx < 3) + { + t2 = key[idx] + zero; + } + else + { + t2 = zero + zero; + } + + t2 = t2 ^ key_or; + return; + } + + if (idx < 6) + { + t2 = data[idx]; + return; + } + if (idx < 15) + { + t2 = 0; + return; + } + t2 = data2; +} + + +uint32_t +get_w32_to_t2 (void) +{ + int i; + + for (i = 0; i < 16; ++i) + { + get_w32_015_to_t2 (i); + Wbuf[i] = zero + t2; + } + + if (idx < 16) + { + t2 = zero + Wbuf[idx]; + return; + } + + i = idx - 16; + + while (1) + { + t2 = Wbuf[13] ^ Wbuf[8]; + t2 = t2 ^ Wbuf[2]; + t2 = t2 ^ Wbuf[0]; + + t2 = SHA1ROTATELEFT (t2, 1); + if (!i) + return; + + memmove (Wbuf, Wbuf + 1, 60); + Wbuf[15] = t2; + i--; + } +} + + + +void +do_sha1digest (void) +{ + uint32_t k; + + va = H[0]; + vb = H[1]; + vc = H[2]; + vd = H[3]; + ve = H[4]; + + for (idx = 0; idx <= 79; idx++) + { + if (idx <= 19) + { + k = k1; + t2 = vb ^ ffffffff; + t2 = t2 & vd; + + t1 = vb & vc; + t1 = t2 | t1; + + } + else if (idx >= 20 && idx <= 39) + { + k = k2; + + t1 = vb ^ vc; + t1 = t1 ^ vd; + } + else if (idx >= 40 && idx <= 59) + { + k = k3; + + t1 = vd & vb; + t2 = vc & vd; + t2 = t1 | t2; + + t1 = vb & vc; + t1 = t2 | t1; + + } + else if (idx >= 60 && idx <= 79) + { + k = k4; + + t1 = vb ^ vc; + t1 = t1 ^ vd; + } + + t1 = t1 + ve; + t1 = t1 + k; + get_w32_to_t2 (); + t1 = t1 + t2; + + ve = vd; + vd = vc; + vc = vb; + vc = SHA1ROTATELEFT (vc, 30); + vb = va; + + va = SHA1ROTATELEFT (va, 5); + va = va + t1; + } + + H[0] += va; + H[1] += vb; + H[2] += vc; + H[3] += vd; + H[4] += ve; +} + +void +show_w2 (void) +{ + printf ("w2="); + for (idx = 0; idx < 80; ++idx) + { + get_w32_to_t2 (); + printf ("%08x", SWAB (t2)); + + } + printf ("\n"); +} + +void +show_data(void) +{ + printf ("out="); + for (idx = 0; idx < 5; ++idx) + { + printf ("%08x", data[idx]); + } + printf ("\n"); +} + + +void +sha1digest (void) +{ + memcpy (H, HI, 20); + + lidx = 0; + show_w2 (); + do_sha1digest (); + + lidx = 1; + show_w2 (); + do_sha1digest (); + + memcpy(data,H,20); + + show_data(); +} /* End of sha1digest() */ + + + + +int +main (int argc, char *argv[]) +{ + uint32_t t = 0xa7a6; + int a; + + + + data[0] = 0; + data[1] = t; + data[2] = zero; + data[2] ^= 0x80000000; + data2 = 0x00000240; + data[3] = zero; + data[4] = zero; + data[5] = zero; + + set_key_or (0x36); + + + sha1digest (); + + data[5] ^= 0x80000000; + data2 = 0x000002a0; + + set_key_or (0x5c); + + sha1digest (); + + a=data[4] &0x0f; + t1=*(uint32_t*)( a+ (uint8_t *) data); + + t1&=0x7fffffff; + printf("%d\n",t1); + + return 0; +} -- cgit v1.2.3