moving sha256 arround

This commit is contained in:
bg 2011-10-10 18:55:59 +02:00
parent 81c98b4526
commit 38d2de57df
6 changed files with 197 additions and 168 deletions

View File

@ -4,9 +4,9 @@ ALGO_NAME := SHA256_C
# comment out the following line for removement of SHA256 from the build process
HASHES += $(ALGO_NAME)
$(ALGO_NAME)_DIR := sha256/
$(ALGO_NAME)_DIR := sha2/
$(ALGO_NAME)_INCDIR := hfal/
$(ALGO_NAME)_OBJ := sha256.o
$(ALGO_NAME)_OBJ := sha256.o sha2_small_common.o
$(ALGO_NAME)_TESTBIN := main-sha256-test.o $(CLI_STD) $(HFAL_STD) hfal_sha256.o
$(ALGO_NAME)_NESSIE_TEST := "nessie"
$(ALGO_NAME)_PERFORMANCE_TEST := "performance"

127
sha2/sha256.c Normal file
View File

@ -0,0 +1,127 @@
/* sha256.c */
/*
This file is part of the ARM-Crypto-Lib.
Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de)
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 3 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, see <http://www.gnu.org/licenses/>.
*/
/**
* \file sha256.c
* \author Daniel Otte
* \date 16.05.2006
*
* \par License:
* GPL
*
* \brief SHA-256 implementation.
*
*
*/
#include <stdint.h>
#include <string.h> /* for memcpy, memmove, memset */
#include "sha2_small_common.h"
#include "sha256.h"
#define LITTLE_ENDIAN
#if defined LITTLE_ENDIAN
#elif defined BIG_ENDIAN
#else
#error specify endianess!!!
#endif
/*************************************************************************/
const
uint32_t sha256_init_vector[]={
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
/*************************************************************************/
/**
* \brief \c sh256_init initialises a sha256 context for hashing.
* \c sh256_init c initialises the given sha256 context for hashing
* @param state pointer to a sha256 context
* @return none
*/
void sha256_init(sha256_ctx_t *state){
state->length=0;
memcpy(state->h, sha256_init_vector, 8*4);
}
/*************************************************************************/
void sha256_nextBlock (sha256_ctx_t *state, const void* block){
sha2_small_common_nextBlock(state, block);
}
/*************************************************************************/
void sha256_lastBlock (sha256_ctx_t *state, const void* block, uint16_t length_b){
sha2_small_common_lastBlock(state, block, length_b);
}
/*************************************************************************/
/**
* \brief function to process the last block being hashed
* @param state Pointer to the context in which this block should be processed.
* @param block Pointer to the message wich should be hashed.
* @param length is the length of only THIS block in BITS not in bytes!
* bits are big endian, meaning high bits come first.
* if you have a message with bits at the end, the byte must be padded with zeros
*/
/*************************************************************************/
/*
* length in bits!
*/
void sha256(void* dest, const void* msg, uint32_t length_b){ /* length could be choosen longer but this is for µC */
sha256_ctx_t s;
sha256_init(&s);
while(length_b >= SHA256_BLOCK_BITS){
sha256_nextBlock(&s, msg);
msg = (uint8_t*)msg + SHA256_BLOCK_BITS/8;
length_b -= SHA256_BLOCK_BITS;
}
sha256_lastBlock(&s, msg, length_b);
sha256_ctx2hash(dest,&s);
}
/*************************************************************************/
void sha256_ctx2hash(void* dest, const sha256_ctx_t *state){
#if defined LITTLE_ENDIAN
uint8_t i, j, *s=(uint8_t*)(state->h);
i=8;
do{
j=3;
do{
*((uint8_t*)dest) = s[j];
dest = (uint8_t*)dest + 1;
}while(j--);
s += 4;
}while(--i);
#elif BIG_ENDIAN
memcpy(dest, state->h, 32);
#else
# error unsupported endian type!
#endif
}

View File

@ -28,7 +28,7 @@
#define SHA256_H_
#include <stdint.h>
#include "sha2_small_common.h"
/** \def SHA256_HASH_BITS
* defines the size of a SHA-256 hash value in bits
*/
@ -55,18 +55,7 @@
*
* A variable of this type may hold the state of a SHA-256 hashing process
*/
typedef struct {
uint32_t h[8];
uint64_t length;
} sha256_ctx_t;
/** \typedef sha256_hash_t
* \brief SHA-256 hash value type
*
* A variable of this type may hold the hash value produced by the
* sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state) function.
*/
typedef uint8_t sha256_hash_t[SHA256_HASH_BYTES];
typedef sha2_small_common_ctx_t sha256_ctx_t;
/** \fn void sha256_init(sha256_ctx_t *state)
* \brief initialize a SHA-256 context
@ -103,7 +92,7 @@ void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b)
* \param dest pointer to the location where the hash value should be written
* \param state pointer to the SHA-256 hash context
*/
void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state);
void sha256_ctx2hash(void* dest, const sha256_ctx_t* state);
/** \fn void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b)
* \brief simple SHA-256 hashing function for direct hashing
@ -114,6 +103,6 @@ void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state);
* \param msg pointer to the message thats going to be hashed
* \param length_b length of the message in bits
*/
void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b);
void sha256(void* dest, const void* msg, uint32_t length_b);
#endif /*SHA256_H_*/

View File

@ -1,7 +1,7 @@
/* sha256.c */
/* sha2_small_common.c */
/*
This file is part of the ARM-Crypto-Lib.
Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de)
Copyright (C) 2006-2011 Daniel Otte (daniel.otte@rub.de)
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
@ -16,55 +16,13 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file sha256.c
* \author Daniel Otte
* \date 16.05.2006
*
* \par License:
* GPL
*
* \brief SHA-256 implementation.
*
*
*/
#include <stdint.h>
#include <string.h> /* for memcpy, memmove, memset */
#include "sha256.h"
#include <string.h>
#include "sha2_small_common.h"
#define LITTLE_ENDIAN
#if defined LITTLE_ENDIAN
#elif defined BIG_ENDIAN
#else
#error specify endianess!!!
#endif
/*************************************************************************/
const
uint32_t sha256_init_vector[]={
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
/*************************************************************************/
/**
* \brief \c sh256_init initialises a sha256 context for hashing.
* \c sh256_init c initialises the given sha256 context for hashing
* @param state pointer to a sha256 context
* @return none
*/
void sha256_init(sha256_ctx_t *state){
state->length=0;
memcpy(state->h, sha256_init_vector, 8*4);
}
/*************************************************************************/
/**
* rotate x right by n positions
*/
@ -78,6 +36,7 @@ uint32_t rotl32( uint32_t x, uint8_t n){
return ((x<<n) | (x>>(32-n)));
}
/*************************************************************************/
// #define CHANGE_ENDIAN32(x) (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8))
@ -87,8 +46,6 @@ uint32_t change_endian32(uint32_t x){
}
/*************************************************************************/
/* sha256 functions as macros for speed and size, cause they are called only once */
#define CH(x,y,z) (((x)&(y)) ^ ((~(x))&(z)))
@ -112,12 +69,11 @@ uint32_t k[]={
};
/*************************************************************************/
/**
* block must be, 512, Bit = 64, Byte, long !!!
*/
void sha256_nextBlock (sha256_ctx_t *state, const void* block){
void sha2_small_common_nextBlock (sha2_small_common_ctx_t *state, const void* block){
uint32_t w[64]; /* this is 256, byte, large, */
uint8_t i;
uint32_t a[8],t1,t2;
@ -154,43 +110,34 @@ void sha256_nextBlock (sha256_ctx_t *state, const void* block){
}
/*************************************************************************/
/**
* \brief function to process the last block being hashed
* @param state Pointer to the context in which this block should be processed.
* @param block Pointer to the message wich should be hashed.
* @param length is the length of only THIS block in BITS not in bytes!
* bits are big endian, meaning high bits come first.
* if you have a message with bits at the end, the byte must be padded with zeros
*/
void sha256_lastBlock(sha256_ctx_t *state, const void* block, uint16_t length){
uint8_t lb[SHA256_BLOCK_BITS/8]; /* local block */
while(length>=SHA256_BLOCK_BITS){
sha256_nextBlock(state, block);
length -= SHA256_BLOCK_BITS;
block = (uint8_t*)block+SHA256_BLOCK_BYTES;
void sha2_small_common_lastBlock(sha2_small_common_ctx_t *state, const void* block, uint16_t length_b){
uint8_t lb[512/8]; /* local block */
// uint64_t len;
while(length_b>=512){
sha2_small_common_nextBlock(state, block);
length_b -= 512;
block = (uint8_t*)block+64;
}
state->length += length;
memcpy (&(lb[0]), block, length/8);
state->length += length_b;
memcpy (&(lb[0]), block, length_b/8);
/* set the final one bit */
if (length & 0x7){ // if we have single bits at the end
lb[length/8] = ((uint8_t*)(block))[length/8];
if (length_b & 0x7){ // if we have single bits at the end
lb[length_b/8] = ((uint8_t*)(block))[length_b/8];
} else {
lb[length/8] = 0;
lb[length_b/8] = 0;
}
lb[length/8] |= 0x80>>(length & 0x7);
length =(length >> 3) + 1; /* from now on length contains the number of BYTES in lb*/
lb[length_b/8] |= 0x80>>(length_b & 0x7);
length_b =(length_b >> 3) + 1; /* from now on length contains the number of BYTES in lb*/
/* pad with zeros */
if (length>64-8){ /* not enouth space for 64bit length value */
memset((void*)(&(lb[length])), 0, 64-length);
sha256_nextBlock(state, lb);
if (length_b>64-8){ /* not enouth space for 64bit length value */
memset((void*)(&(lb[length_b])), 0, 64-length_b);
sha2_small_common_nextBlock(state, lb);
state->length -= 512;
length = 0;
length_b = 0;
}
memset((void*)(&(lb[length])), 0, 56-length);
memset((void*)(&(lb[length_b])), 0, 56-length_b);
/* store the 64bit length value */
#if defined LITTLE_ENDIAN
/* this is now rolled up */
@ -201,43 +148,6 @@ void sha256_lastBlock(sha256_ctx_t *state, const void* block, uint16_t length){
#elif defined BIG_ENDIAN
*((uint64_t)&(lb[56])) = state->length;
#endif
sha256_nextBlock(state, lb);
sha2_small_common_nextBlock(state, lb);
}
/*************************************************************************/
/*
* length in bits!
*/
void sha256(sha256_hash_t *dest, const void* msg, uint32_t length){ /* length could be choosen longer but this is for µC */
sha256_ctx_t s;
sha256_init(&s);
while(length >= SHA256_BLOCK_BITS){
sha256_nextBlock(&s, msg);
msg = (uint8_t*)msg + SHA256_BLOCK_BITS/8;
length -= SHA256_BLOCK_BITS;
}
sha256_lastBlock(&s, msg, length);
sha256_ctx2hash(dest,&s);
}
/*************************************************************************/
void sha256_ctx2hash(sha256_hash_t *dest, const sha256_ctx_t *state){
#if defined LITTLE_ENDIAN
uint8_t i;
for(i=0; i<8; ++i){
((uint32_t*)dest)[i] = change_endian32(state->h[i]);
}
#elif BIG_ENDIAN
if (dest != state->h)
memcpy(dest, state->h, SHA256_HASH_BITS/8);
#else
# error unsupported endian type!
#endif
}

31
sha2/sha2_small_common.h Normal file
View File

@ -0,0 +1,31 @@
/* sha2_small_common.h */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2011 Daniel Otte (daniel.otte@rub.de)
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef SHA2_SMALL_COMMON_H_
#define SHA2_SMALL_COMMON_H_
typedef struct {
uint32_t h[8];
uint64_t length;
} sha2_small_common_ctx_t;
void sha2_small_common_nextBlock(sha2_small_common_ctx_t* state, const void* block);
void sha2_small_common_lastBlock(sha2_small_common_ctx_t* state, const void* block, uint16_t length_b);
#endif /* SHA2_SMALL_COMMON_H_ */

View File

@ -21,15 +21,7 @@
*
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "cli.h"
#include "dump.h"
#include "uart_lowlevel.h"
#include "sysclock.h"
#include "hw_gptm.h"
#include "main-test-common.h"
#include "shavs.h"
#include "nessie_hash_test.h"
@ -41,14 +33,6 @@
#include "sha256.h"
#include "hfal_sha256.h"
void uart0_putc(char byte){
uart_putc(UART_0, byte);
}
char uart0_getc(void){
return uart_getc(UART_0);
}
const char* algo_name = "SHA-256";
const hfdesc_t* algolist[] = {
@ -97,10 +81,10 @@ void test_monte(void){
0x38, 0xF0, 0xDF, 0x70, 0x1D, 0xA9, 0x3C, 0x3B,
0xF2, 0xC9, 0xC8, 0x68, 0x96, 0xE7, 0xE6, 0xC7 };
uint8_t hash[SHA256_HASH_BYTES];
sha256((sha256_hash_t*)hash, data1, 3*32*8);
sha256(hash, data1, 3*32*8);
cli_putstr("\r\n hash(data1) = ");
cli_hexdump(hash, 32);
sha256((sha256_hash_t*)hash, data2, 3*32*8);
sha256(hash, data2, 3*32*8);
cli_putstr("\r\n hash(data2) = ");
cli_hexdump(hash, 32);
}
@ -125,7 +109,7 @@ void test_monte2(void){
0x39, 0xd8, 0x35, 0xa7, 0x24, 0xe2, 0xfa, 0xe7 };
uint8_t hash[SHA256_HASH_BYTES];
sha256((sha256_hash_t*)hash, data, 1024);
sha256(hash, data, 1024);
cli_putstr("\r\n hash(data) = ");
cli_hexdump(hash, 32);
}
@ -164,26 +148,14 @@ const cmdlist_entry_t cmdlist[] = {
};
int main(void) {
sysclk_set_freq(SYS_FREQ);
sysclk_mosc_verify_enable();
uart_init(UART_0, 115200, 8, UART_PARATY_NONE, UART_STOPBITS_ONE);
gptm_set_timer_32periodic(TIMER0);
cli_rx = uart0_getc;
cli_tx = uart0_putc;
main_setup();
shavs_algolist=(hfdesc_t**)algolist;
shavs_algo=(hfdesc_t*)&sha256_desc;
for(;;){
cli_putstr("\r\n\r\nARM-Crypto-Lib VS (");
cli_putstr(algo_name);
cli_putstr("; ");
cli_putstr(__DATE__);
cli_putc(' ');
cli_putstr(__TIME__);
cli_putstr(")\r\nloaded and running\r\n");
cmd_interface(cmdlist);
welcome_msg(algo_name);
cmd_interface(cmdlist);
}
}