sessmgr/sha256.c

181 řádky
5.0 KiB
C
Surový Normální zobrazení Historie

2013-06-28 18:36:45 +02:00
/*
* sha256.c - Implementation of the Secure Hash Algorithm-256 (SHA-256).
*
* Implemented from the description on the NIST Web site:
* http://csrc.nist.gov/cryptval/shs.html
*
*
* Copyright (C) 2012 Rafal Kupiec (customized for sessmgr)
* Copyright (C) 2009 Eric Bishop (adapted as standalone utility)
* Copyright (C) 2002 Southern Storm Software, Pty Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "sha256.h"
static void ProcessBlock(SHA256Context *sha, const unsigned char *block) {
u_int32_t W[64];
u_int32_t a, b, c, d, e, f, g, h;
u_int32_t temp, temp2;
int t;
for(t = 0; t < 16; ++t) {
W[t] = (((u_int32_t) (block[t * 4 + 0])) << 24) | (((u_int32_t) (block[t * 4 + 1])) << 16) | (((u_int32_t) (block[t * 4 + 2])) << 8) | ((u_int32_t) (block[t * 4 + 3]));
}
for(t = 16; t < 64; ++t) {
W[t] = TRUNCLONG(RHO1(W[t - 2]) + W[t - 7] + RHO0(W[t - 15]) + W[t - 16]);
}
a = sha->A;
b = sha->B;
c = sha->C;
d = sha->D;
e = sha->E;
f = sha->F;
g = sha->G;
h = sha->H;
for(t = 0; t < 64; ++t) {
temp = TRUNCLONG(h + SUM1(e) + CH(e, f, g) + K[t] + W[t]);
temp2 = TRUNCLONG(SUM0(a) + MAJ(a, b, c));
h = g;
g = f;
f = e;
e = TRUNCLONG(d + temp);
d = c;
c = b;
b = a;
a = TRUNCLONG(temp + temp2);
}
sha->A = TRUNCLONG(sha->A + a);
sha->B = TRUNCLONG(sha->B + b);
sha->C = TRUNCLONG(sha->C + c);
sha->D = TRUNCLONG(sha->D + d);
sha->E = TRUNCLONG(sha->E + e);
sha->F = TRUNCLONG(sha->F + f);
sha->G = TRUNCLONG(sha->G + g);
sha->H = TRUNCLONG(sha->H + h);
DoMemZero(W, sizeof(u_int32_t) * 64);
a = b = c = d = e = f = g = h = temp = temp2 = 0;
}
void SHA256Data(SHA256Context *sha, const void *buffer, unsigned long len) {
unsigned long templen;
sha->totalLen += (u_int64_t)len;
while(len > 0) {
if(!(sha->inputLen) && len >= 64) {
ProcessBlock(sha, (const unsigned char *) buffer);
buffer = (const void *) (((const unsigned char *) buffer) + 64);
len -= 64;
} else {
templen = len;
if(templen > (64 - sha->inputLen)) {
templen = 64 - sha->inputLen;
}
memcpy(sha->input + sha->inputLen, buffer, templen);
if((sha->inputLen += templen) >= 64) {
ProcessBlock(sha, sha->input);
sha->inputLen = 0;
}
buffer = (const void *) (((const unsigned char *) buffer) + templen);
len -= templen;
}
}
}
void SHA256Finalize(SHA256Context *sha, unsigned char hash[SHA256_HASH_SIZE]) {
u_int64_t totalBits;
if(hash) {
if(sha->inputLen >= 56) {
sha->input[(sha->inputLen)++] = (unsigned char) 0x80;
while(sha->inputLen < 64) {
sha->input[(sha->inputLen)++] = (unsigned char) 0x00;
}
ProcessBlock(sha, sha->input);
sha->inputLen = 0;
} else {
sha->input[(sha->inputLen)++] = (unsigned char) 0x80;
}
while(sha->inputLen < 56) {
sha->input[(sha->inputLen)++] = (unsigned char) 0x00;
}
totalBits = (sha->totalLen << 3);
WriteLong(sha->input + 56, (u_int32_t) (totalBits >> 32));
WriteLong(sha->input + 60, (u_int32_t) totalBits);
ProcessBlock(sha, sha->input);
WriteLong(hash, sha->A);
WriteLong(hash + 4, sha->B);
WriteLong(hash + 8, sha->C);
WriteLong(hash + 12, sha->D);
WriteLong(hash + 16, sha->E);
WriteLong(hash + 20, sha->F);
WriteLong(hash + 24, sha->G);
WriteLong(hash + 28, sha->H);
}
DoMemZero(sha, sizeof(SHA256Context));
}
void SHA256Init(SHA256Context *sha) {
sha->inputLen = 0;
sha->A = 0x6a09e667;
sha->B = 0xbb67ae85;
sha->C = 0x3c6ef372;
sha->D = 0xa54ff53a;
sha->E = 0x510e527f;
sha->F = 0x9b05688c;
sha->G = 0x1f83d9ab;
sha->H = 0x5be0cd19;
sha->totalLen = 0;
}
static void WriteLong(unsigned char *buf, u_int32_t value) {
buf[0] = (unsigned char)(value >> 24);
buf[1] = (unsigned char)(value >> 16);
buf[2] = (unsigned char)(value >> 8);
buf[3] = (unsigned char)value;
}
unsigned char* get_sha256_hash(const char* unhashed) {
SHA256Context sha;
unsigned char* hash = (unsigned char*) malloc(32);
SHA256Init(&sha);
SHA256Data(&sha, unhashed, strlen(unhashed));
SHA256Finalize(&sha, hash);
return hash;
}
char* get_sha256_hash_hex_str(const char* unhashed) {
unsigned char* hashed = get_sha256_hash(unhashed);
char* hashed_hex = (char*) malloc(65);
char next_hex[3];
int index =0;
hashed_hex[0] = '\0';
for(index=0; index < 32; index++) {
sprintf(next_hex, "%02X", hashed[index]);
strcat(hashed_hex, next_hex);
}
free(hashed);
return hashed_hex;
}