/* Following functions are various bit meshing routines used in
* GOST R 34.11-94 algorithms */
static void swap_bytes (byte *w, byte *k)
-{
+ {
int i,j;
for (i=0;i<4;i++)
for (j=0;j<8;j++)
k[i+4*j]=w[8*i+j];
-}
+ }
+
/* was A_A */
static void circle_xor8 (const byte *w, byte *k)
-{
+ {
byte buf[8];
int i;
memcpy(buf,w,8);
- memcpy(k,w+8,24);
+ memmove(k,w+8,24);
for(i=0;i<8;i++)
k[i+24]=buf[i]^k[i];
-}
+ }
+
/* was R_R */
static void transform_3 (byte *data)
-{
+ {
unsigned short int acc;
acc=(data[0]^data[2]^data[4]^data[6]^data[24]^data[30])|
((data[1]^data[3]^data[5]^data[7]^data[25]^data[31])<<8);
memmove(data,data+2,30);
data[30]=acc&0xff;
data[31]=acc>>8;
-}
+ }
/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
static int add_blocks(int n,byte *left, const byte *right)
-{
- int i;
- int carry=0;
- int sum;
- for (i=0;i<n;i++)
- {
+ {
+ int i;
+ int carry=0;
+ int sum;
+ for (i=0;i<n;i++)
+ {
sum=(int)left[i]+(int)right[i]+carry;
left[i]=sum & 0xff;
carry=sum>>8;
- }
- return carry;
-}
+ }
+ return carry;
+ }
+
/* Xor two sequences of bytes */
-static void xor_blocks (byte *result,const byte *a,const byte *b,size_t len) {
+static void xor_blocks (byte *result,const byte *a,const byte *b,size_t len)
+ {
size_t i;
for (i=0;i<len;i++) result[i]=a[i]^b[i];
-}
+ }
/*
* Calculate H(i+1) = Hash(Hi,Mi)
* Where H and M are 32 bytes long
*/
static int hash_step(gost_ctx *c,byte *H,const byte *M)
-{
- static byte U[32],W[32],V[32],S[32],Key[32];
+ {
+ byte U[32],W[32],V[32],S[32],Key[32];
int i;
/* Compute first key */
xor_blocks(W,H,M,32);
transform_3(S);
memcpy(H,S,32);
return 1;
-}
+ }
/* Initialize gost_hash ctx - cleans up temporary structures and
* set up substitution blocks
*/
-int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block) {
+int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block)
+ {
memset(ctx,0,sizeof(gost_hash_ctx));
ctx->cipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx));
- if (!ctx->cipher_ctx) {
- return 0;
- }
+ if (!ctx->cipher_ctx)
+ {
+ return 0;
+ }
gost_init(ctx->cipher_ctx,subst_block);
return 1;
-}
+ }
+
/*
* Free cipher CTX if it is dynamically allocated. Do not use
* if cipher ctx is statically allocated as in OpenSSL implementation of
*
*/
void done_gost_hash_ctx(gost_hash_ctx *ctx)
-{
+ {
/* No need to use gost_destroy, because cipher keys are not really
* secret when hashing */
MYFREE(ctx->cipher_ctx);
-}
+ }
+
/*
* reset state of hash context to begin hashing new message
*/
-int start_hash(gost_hash_ctx *ctx) {
+int start_hash(gost_hash_ctx *ctx)
+ {
if (!ctx->cipher_ctx) return 0;
memset(&(ctx->H),0,32);
memset(&(ctx->S),0,32);
ctx->len = 0L;
ctx->left=0;
return 1;
-}
+ }
+
/*
* Hash block of arbitrary length
*
*
*/
-int hash_block(gost_hash_ctx *ctx,const byte *block, size_t length) {
- const byte *curptr=block;
- const byte *barrier=block+(length-32);/* Last byte we can safely hash*/
- gost_ctx *save_c = ctx->cipher_ctx;
- if (ctx->left) {
+int hash_block(gost_hash_ctx *ctx,const byte *block, size_t length)
+ {
+ if (ctx->left)
+ {
/*There are some bytes from previous step*/
- int add_bytes = 32-ctx->left;
- if (add_bytes>length) {
+ unsigned int add_bytes = 32-ctx->left;
+ if (add_bytes>length)
+ {
add_bytes = length;
- }
+ }
memcpy(&(ctx->remainder[ctx->left]),block,add_bytes);
ctx->left+=add_bytes;
- if (ctx->left<32) {
+ if (ctx->left<32)
+ {
return 1;
- }
- if (ctx->left>32) {
- abort();
- }
- curptr=block+add_bytes;
+ }
+ block+=add_bytes;
+ length-=add_bytes;
hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder);
- if (save_c!=ctx->cipher_ctx) {
- abort();
- }
add_blocks(32,ctx->S,ctx->remainder);
- if (save_c!=ctx->cipher_ctx) {
- abort();
- }
ctx->len+=32;
ctx->left=0;
- }
- while (curptr<=barrier)
- {
- hash_step(ctx->cipher_ctx,ctx->H,curptr);
- if (save_c!=ctx->cipher_ctx) {
- abort();
- }
+ }
+ while (length>=32)
+ {
+ hash_step(ctx->cipher_ctx,ctx->H,block);
- add_blocks(32,ctx->S,curptr);
- if (save_c!=ctx->cipher_ctx) {
- abort();
- }
+ add_blocks(32,ctx->S,block);
ctx->len+=32;
- curptr+=32;
- }
- if (curptr!=block+length) {
- ctx->left=block+length-curptr;
- if (ctx->left>32) {
- abort();
+ block+=32;
+ length-=32;
+ }
+ if (length)
+ {
+ memcpy(ctx->remainder,block,ctx->left=length);
}
- memcpy(ctx->remainder,curptr,ctx->left);
- }
return 1;
-}
+ }
+
/*
* Compute hash value from current state of ctx
* state of hash ctx becomes invalid and cannot be used for further
* hashing.
*/
-int finish_hash(gost_hash_ctx *ctx,byte *hashval) {
+int finish_hash(gost_hash_ctx *ctx,byte *hashval)
+ {
byte buf[32];
byte H[32];
byte S[32];
- long long fin_len=ctx->len;
+ ghosthash_len fin_len=ctx->len;
byte *bptr;
memcpy(H,ctx->H,32);
memcpy(S,ctx->S,32);
- if (ctx->left) {
+ if (ctx->left)
+ {
memset(buf,0,32);
memcpy(buf,ctx->remainder,ctx->left);
hash_step(ctx->cipher_ctx,H,buf);
add_blocks(32,S,buf);
fin_len+=ctx->left;
- }
+ }
memset(buf,0,32);
bptr=buf;
fin_len<<=3; /* Hash length in BITS!!*/
- while(fin_len>0) {
- *(bptr++)=fin_len&0xFF;
+ while(fin_len>0)
+ {
+ *(bptr++)=(byte)(fin_len&0xFF);
fin_len>>=8;
- };
+ };
hash_step(ctx->cipher_ctx,H,buf);
hash_step(ctx->cipher_ctx,H,S);
memcpy(hashval,H,32);
return 1;
-}
-
+ }