|
|
- /*
- * 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;
- }
|