VUSB-Firmware for Attiny85 implementing HMAC one time password authentication
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
hmac-otp/sha1.c

136 lines
2.5 KiB

#include "sha1.h"
#define H1 0x67452301
#define H2 0xEFCDAB89
#define H3 0x98BADCFE
#define H4 0x10325476
#define H5 0xC3D2E1F0
#define K1 0x5A827999
#define K2 0x6ED9EBA1
#define K3 0x8F1BBCDC
#define K4 0xCA62C1D6
#define _LROT32(x,n) (( (uint32_t)(x) << n ) | ( (uint32_t)(x) >>(32-n) ))
#define _W(n) (n>=16 ? chunk_e[n-16] : chunk[n])
static uint32_t chunk[16];
static uint8_t chunk_cnt;
void sha1_addbyte(uint8_t c){
uint8_t* p=(uint8_t*)chunk;
uint8_t i;
p[chunk_cnt]=c;
chunk_cnt++;
if(chunk_cnt==64){
/*chunk extension*/
uint32_t a,b,c,d,e,chunk_e[64];
#ifdef TO_LITTLE_ENDIAN32
for(i=0; i<16; i++){
chunk[i]=TO_LITTLE_ENDIAN32(chunk[i]);
//printf("%08x",chunk[i]);
}
//printf("\n");
#endif //TO_LITTLE_ENDIAN32
for(i=0; i<64; i++){
chunk_e[i]= _LROT32( _W(i+16-3) ^ _W(i+16-8) ^ _W(i+16-14) ^ _W(i+16-16), 1 );
}
a=sha1_digest[0];
b=sha1_digest[1];
c=sha1_digest[2];
d=sha1_digest[3];
e=sha1_digest[4];
/*main loop*/
for(i=0;i<80;i++){
uint32_t f,k,temp;
if(i<20){
k=K1;
f=(b & c) | ((~b) & d);
}else if(i<40){
k=K2;
f=b ^ c ^ d;
}else if(i<60){
k=K3;
f=(b & c) | (b & d) | (c & d);
}else{
k=K4;
f=b ^ c ^ d;
}
temp = e + _LROT32(a,5) + f + k + _W(i);
e = d;
d = c;
c = _LROT32(b,30);
b = a;
a = temp;
}
sha1_digest[0]+=a;
sha1_digest[1]+=b;
sha1_digest[2]+=c;
sha1_digest[3]+=d;
sha1_digest[4]+=e;
chunk_cnt=0;
}
}
void sha1_fill(int32_t len){
/*"append a 1-bit to the message"*/
/*"append 0-bits to the message to obtain a length of len%512=448"*/
/*"append length of message in bits as 64-bit integer"*/
uint8_t j;
for(j=0;j<(120-(len-(len/64)*64+1))%64+1;j++){
if(j==0){
sha1_addbyte(0x80);
}else{
sha1_addbyte(0x00);
}
}
{
uint64_t l=len*8;
/*pay attention to the endiness here*/
sha1_addbyte( ((char*)(&l))[7]);
sha1_addbyte( ((char*)(&l))[6]);
sha1_addbyte( ((char*)(&l))[5]);
sha1_addbyte( ((char*)(&l))[4]);
sha1_addbyte( ((char*)(&l))[3]);
sha1_addbyte( ((char*)(&l))[2]);
sha1_addbyte( ((char*)(&l))[1]);
sha1_addbyte( ((char*)(&l))[0]);
}
}
void sha1(char* msg, int32_t len){
int32_t i;
uint8_t j;
sha1_init();
for(i=0; i<=len; i+=64){
if(i+64>=len){
for(j=0;j<len-i;j++){
sha1_addbyte(msg[i+j]);
}
sha1_fill(len);
continue;
}
for(j=0;j<64;j++){
sha1_addbyte(msg[i+j]);
}
}
}
void sha1_init(void){
chunk_cnt=0;
sha1_digest[0]=H1;
sha1_digest[1]=H2;
sha1_digest[2]=H3;
sha1_digest[3]=H4;
sha1_digest[4]=H5;
}