gosthash.c revision 238384
1238384Sjkim/**********************************************************************
2238384Sjkim *                          gosthash.c                                *
3238384Sjkim *             Copyright (c) 2005-2006 Cryptocom LTD                  *
4238384Sjkim *         This file is distributed under the same license as OpenSSL *
5238384Sjkim *                                                                    *
6238384Sjkim *    Implementation of GOST R 34.11-94 hash function                 *
7238384Sjkim *       uses on gost89.c and gost89.h Doesn't need OpenSSL           *
8238384Sjkim **********************************************************************/
9238384Sjkim#include <string.h>
10238384Sjkim
11238384Sjkim#include "gost89.h"
12238384Sjkim#include "gosthash.h"
13238384Sjkim
14238384Sjkim
15238384Sjkim/* Use OPENSSL_malloc for memory allocation if compiled with
16238384Sjkim * -DOPENSSL_BUILD, and libc malloc otherwise
17238384Sjkim */
18238384Sjkim#ifndef MYALLOC
19238384Sjkim# ifdef OPENSSL_BUILD
20238384Sjkim#  include <openssl/crypto.h>
21238384Sjkim#  define MYALLOC(size) OPENSSL_malloc(size)
22238384Sjkim#  define MYFREE(ptr) OPENSSL_free(ptr)
23238384Sjkim# else
24238384Sjkim#  define MYALLOC(size) malloc(size)
25238384Sjkim#  define MYFREE(ptr) free(ptr)
26238384Sjkim# endif
27238384Sjkim#endif
28238384Sjkim/* Following functions are various bit meshing routines used in
29238384Sjkim * GOST R 34.11-94 algorithms */
30238384Sjkimstatic void swap_bytes (byte *w, byte *k)
31238384Sjkim	{
32238384Sjkim	int i,j;
33238384Sjkim	for (i=0;i<4;i++)
34238384Sjkim		for (j=0;j<8;j++)
35238384Sjkim			k[i+4*j]=w[8*i+j];
36238384Sjkim
37238384Sjkim	}
38238384Sjkim
39238384Sjkim/* was A_A */
40238384Sjkimstatic void circle_xor8 (const byte *w, byte *k)
41238384Sjkim	{
42238384Sjkim	byte buf[8];
43238384Sjkim	int i;
44238384Sjkim	memcpy(buf,w,8);
45238384Sjkim	memcpy(k,w+8,24);
46238384Sjkim	for(i=0;i<8;i++)
47238384Sjkim		k[i+24]=buf[i]^k[i];
48238384Sjkim	}
49238384Sjkim
50238384Sjkim/* was R_R */
51238384Sjkimstatic void transform_3 (byte *data)
52238384Sjkim	{
53238384Sjkim	unsigned short int acc;
54238384Sjkim	acc=(data[0]^data[2]^data[4]^data[6]^data[24]^data[30])|
55238384Sjkim		((data[1]^data[3]^data[5]^data[7]^data[25]^data[31])<<8);
56238384Sjkim	memmove(data,data+2,30);
57238384Sjkim	data[30]=acc&0xff;
58238384Sjkim	data[31]=acc>>8;
59238384Sjkim	}
60238384Sjkim
61238384Sjkim/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
62238384Sjkimstatic int add_blocks(int n,byte *left, const byte *right)
63238384Sjkim	{
64238384Sjkim	int i;
65238384Sjkim	int carry=0;
66238384Sjkim	int sum;
67238384Sjkim	for (i=0;i<n;i++)
68238384Sjkim		{
69238384Sjkim	   	sum=(int)left[i]+(int)right[i]+carry;
70238384Sjkim		left[i]=sum & 0xff;
71238384Sjkim		carry=sum>>8;
72238384Sjkim		}
73238384Sjkim	return carry;
74238384Sjkim	}
75238384Sjkim
76238384Sjkim/* Xor two sequences of bytes */
77238384Sjkimstatic void xor_blocks (byte *result,const byte *a,const byte *b,size_t len)
78238384Sjkim	{
79238384Sjkim	size_t i;
80238384Sjkim	for (i=0;i<len;i++) result[i]=a[i]^b[i];
81238384Sjkim	}
82238384Sjkim
83238384Sjkim/*
84238384Sjkim * 	Calculate H(i+1) = Hash(Hi,Mi)
85238384Sjkim * 	Where H and M are 32 bytes long
86238384Sjkim */
87238384Sjkimstatic int hash_step(gost_ctx *c,byte *H,const byte *M)
88238384Sjkim	{
89238384Sjkim	byte U[32],W[32],V[32],S[32],Key[32];
90238384Sjkim	int i;
91238384Sjkim	/* Compute first key */
92238384Sjkim	xor_blocks(W,H,M,32);
93238384Sjkim	swap_bytes(W,Key);
94238384Sjkim	/* Encrypt first 8 bytes of H with first key*/
95238384Sjkim	gost_enc_with_key(c,Key,H,S);
96238384Sjkim	/* Compute second key*/
97238384Sjkim	circle_xor8(H,U);
98238384Sjkim	circle_xor8(M,V);
99238384Sjkim	circle_xor8(V,V);
100238384Sjkim	xor_blocks(W,U,V,32);
101238384Sjkim	swap_bytes(W,Key);
102238384Sjkim	/* encrypt second 8 bytes of H with second key*/
103238384Sjkim	gost_enc_with_key(c,Key,H+8,S+8);
104238384Sjkim	/* compute third key */
105238384Sjkim	circle_xor8(U,U);
106238384Sjkim	U[31]=~U[31]; U[29]=~U[29]; U[28]=~U[28]; U[24]=~U[24];
107238384Sjkim	U[23]=~U[23]; U[20]=~U[20]; U[18]=~U[18]; U[17]=~U[17];
108238384Sjkim	U[14]=~U[14]; U[12]=~U[12]; U[10]=~U[10]; U[ 8]=~U[ 8];
109238384Sjkim	U[ 7]=~U[ 7]; U[ 5]=~U[ 5]; U[ 3]=~U[ 3]; U[ 1]=~U[ 1];
110238384Sjkim	circle_xor8(V,V);
111238384Sjkim	circle_xor8(V,V);
112238384Sjkim	xor_blocks(W,U,V,32);
113238384Sjkim	swap_bytes(W,Key);
114238384Sjkim	/* encrypt third 8 bytes of H with third key*/
115238384Sjkim	gost_enc_with_key(c,Key,H+16,S+16);
116238384Sjkim	/* Compute fourth key */
117238384Sjkim	circle_xor8(U,U);
118238384Sjkim	circle_xor8(V,V);
119238384Sjkim	circle_xor8(V,V);
120238384Sjkim	xor_blocks(W,U,V,32);
121238384Sjkim	swap_bytes(W,Key);
122238384Sjkim	/* Encrypt last 8 bytes with fourth key */
123238384Sjkim	gost_enc_with_key(c,Key,H+24,S+24);
124238384Sjkim	for (i=0;i<12;i++)
125238384Sjkim		transform_3(S);
126238384Sjkim	xor_blocks(S,S,M,32);
127238384Sjkim	transform_3(S);
128238384Sjkim	xor_blocks(S,S,H,32);
129238384Sjkim	for (i=0;i<61;i++)
130238384Sjkim		transform_3(S);
131238384Sjkim	memcpy(H,S,32);
132238384Sjkim	return 1;
133238384Sjkim	}
134238384Sjkim
135238384Sjkim/* Initialize gost_hash ctx - cleans up temporary structures and
136238384Sjkim * set up substitution blocks
137238384Sjkim */
138238384Sjkimint init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block)
139238384Sjkim	{
140238384Sjkim	memset(ctx,0,sizeof(gost_hash_ctx));
141238384Sjkim	ctx->cipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx));
142238384Sjkim	if (!ctx->cipher_ctx)
143238384Sjkim		{
144238384Sjkim		return 0;
145238384Sjkim		}
146238384Sjkim	gost_init(ctx->cipher_ctx,subst_block);
147238384Sjkim	return 1;
148238384Sjkim	}
149238384Sjkim
150238384Sjkim/*
151238384Sjkim * Free cipher CTX if it is dynamically allocated. Do not use
152238384Sjkim * if cipher ctx is statically allocated as in OpenSSL implementation of
153238384Sjkim * GOST hash algroritm
154238384Sjkim *
155238384Sjkim */
156238384Sjkimvoid done_gost_hash_ctx(gost_hash_ctx *ctx)
157238384Sjkim	{
158238384Sjkim	/* No need to use gost_destroy, because cipher keys are not really
159238384Sjkim	 * secret when hashing */
160238384Sjkim	MYFREE(ctx->cipher_ctx);
161238384Sjkim	}
162238384Sjkim
163238384Sjkim/*
164238384Sjkim * reset state of hash context to begin hashing new message
165238384Sjkim */
166238384Sjkimint start_hash(gost_hash_ctx *ctx)
167238384Sjkim	{
168238384Sjkim	if (!ctx->cipher_ctx) return 0;
169238384Sjkim	memset(&(ctx->H),0,32);
170238384Sjkim	memset(&(ctx->S),0,32);
171238384Sjkim	ctx->len = 0L;
172238384Sjkim	ctx->left=0;
173238384Sjkim	return 1;
174238384Sjkim	}
175238384Sjkim
176238384Sjkim/*
177238384Sjkim * Hash block of arbitrary length
178238384Sjkim *
179238384Sjkim *
180238384Sjkim */
181238384Sjkimint hash_block(gost_hash_ctx *ctx,const byte *block, size_t length)
182238384Sjkim	{
183238384Sjkim	const byte *curptr=block;
184238384Sjkim	const byte *barrier=block+(length-32);/* Last byte we can safely hash*/
185238384Sjkim	if (ctx->left)
186238384Sjkim		{
187238384Sjkim		/*There are some bytes from previous step*/
188238384Sjkim		unsigned int add_bytes = 32-ctx->left;
189238384Sjkim		if (add_bytes>length)
190238384Sjkim			{
191238384Sjkim			add_bytes = length;
192238384Sjkim			}
193238384Sjkim		memcpy(&(ctx->remainder[ctx->left]),block,add_bytes);
194238384Sjkim		ctx->left+=add_bytes;
195238384Sjkim		if (ctx->left<32)
196238384Sjkim			{
197238384Sjkim			return 1;
198238384Sjkim			}
199238384Sjkim		curptr=block+add_bytes;
200238384Sjkim		hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder);
201238384Sjkim		add_blocks(32,ctx->S,ctx->remainder);
202238384Sjkim		ctx->len+=32;
203238384Sjkim		ctx->left=0;
204238384Sjkim		}
205238384Sjkim	while (curptr<=barrier)
206238384Sjkim		{
207238384Sjkim		hash_step(ctx->cipher_ctx,ctx->H,curptr);
208238384Sjkim
209238384Sjkim		add_blocks(32,ctx->S,curptr);
210238384Sjkim		ctx->len+=32;
211238384Sjkim		curptr+=32;
212238384Sjkim		}
213238384Sjkim	if (curptr!=block+length)
214238384Sjkim		{
215238384Sjkim		ctx->left=block+length-curptr;
216238384Sjkim		memcpy(ctx->remainder,curptr,ctx->left);
217238384Sjkim		}
218238384Sjkim	return 1;
219238384Sjkim	}
220238384Sjkim
221238384Sjkim/*
222238384Sjkim * Compute hash value from current state of ctx
223238384Sjkim * state of hash ctx becomes invalid and cannot be used for further
224238384Sjkim * hashing.
225238384Sjkim */
226238384Sjkimint finish_hash(gost_hash_ctx *ctx,byte *hashval)
227238384Sjkim	{
228238384Sjkim	byte buf[32];
229238384Sjkim	byte H[32];
230238384Sjkim	byte S[32];
231238384Sjkim	ghosthash_len fin_len=ctx->len;
232238384Sjkim	byte *bptr;
233238384Sjkim	memcpy(H,ctx->H,32);
234238384Sjkim	memcpy(S,ctx->S,32);
235238384Sjkim	if (ctx->left)
236238384Sjkim		{
237238384Sjkim		memset(buf,0,32);
238238384Sjkim		memcpy(buf,ctx->remainder,ctx->left);
239238384Sjkim		hash_step(ctx->cipher_ctx,H,buf);
240238384Sjkim		add_blocks(32,S,buf);
241238384Sjkim		fin_len+=ctx->left;
242238384Sjkim		}
243238384Sjkim	memset(buf,0,32);
244238384Sjkim	bptr=buf;
245238384Sjkim	fin_len<<=3; /* Hash length in BITS!!*/
246238384Sjkim	while(fin_len>0)
247238384Sjkim		{
248238384Sjkim		*(bptr++)=(byte)(fin_len&0xFF);
249238384Sjkim		fin_len>>=8;
250238384Sjkim		};
251238384Sjkim	hash_step(ctx->cipher_ctx,H,buf);
252238384Sjkim	hash_step(ctx->cipher_ctx,H,S);
253238384Sjkim	memcpy(hashval,H,32);
254238384Sjkim	return 1;
255238384Sjkim	}
256