1 /**********************************************************************
3 * Copyright (c) 2005-2006 Cryptocom LTD *
4 * This file is distributed under the same license as OpenSSL *
6 * Implementation of GOST R 34.11-94 hash function *
7 * uses on gost89.c and gost89.h Doesn't need OpenSSL *
8 **********************************************************************/
15 /* Use OPENSSL_malloc for memory allocation if compiled with
16 * -DOPENSSL_BUILD, and libc malloc otherwise
20 # include <openssl/crypto.h>
21 # define MYALLOC(size) OPENSSL_malloc(size)
22 # define MYFREE(ptr) OPENSSL_free(ptr)
24 # define MYALLOC(size) malloc(size)
25 # define MYFREE(ptr) free(ptr)
28 /* Following functions are various bit meshing routines used in
29 * GOST R 34.11-94 algorithms */
30 static void swap_bytes (byte
*w
, byte
*k
)
40 static void circle_xor8 (const byte
*w
, byte
*k
)
51 static void transform_3 (byte
*data
)
53 unsigned short int acc
;
54 acc
=(data
[0]^data
[2]^data
[4]^data
[6]^data
[24]^data
[30])|
55 ((data
[1]^data
[3]^data
[5]^data
[7]^data
[25]^data
[31])<<8);
56 memmove(data
,data
+2,30);
61 /* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
62 static int add_blocks(int n
,byte
*left
, const byte
*right
)
69 sum
=(int)left
[i
]+(int)right
[i
]+carry
;
76 /* Xor two sequences of bytes */
77 static void xor_blocks (byte
*result
,const byte
*a
,const byte
*b
,size_t len
)
80 for (i
=0;i
<len
;i
++) result
[i
]=a
[i
]^b
[i
];
84 * Calculate H(i+1) = Hash(Hi,Mi)
85 * Where H and M are 32 bytes long
87 static int hash_step(gost_ctx
*c
,byte
*H
,const byte
*M
)
89 byte U
[32],W
[32],V
[32],S
[32],Key
[32];
91 /* Compute first key */
94 /* Encrypt first 8 bytes of H with first key*/
95 gost_enc_with_key(c
,Key
,H
,S
);
96 /* Compute second key*/
100 xor_blocks(W
,U
,V
,32);
102 /* encrypt second 8 bytes of H with second key*/
103 gost_enc_with_key(c
,Key
,H
+8,S
+8);
104 /* compute third key */
106 U
[31]=~U
[31]; U
[29]=~U
[29]; U
[28]=~U
[28]; U
[24]=~U
[24];
107 U
[23]=~U
[23]; U
[20]=~U
[20]; U
[18]=~U
[18]; U
[17]=~U
[17];
108 U
[14]=~U
[14]; U
[12]=~U
[12]; U
[10]=~U
[10]; U
[ 8]=~U
[ 8];
109 U
[ 7]=~U
[ 7]; U
[ 5]=~U
[ 5]; U
[ 3]=~U
[ 3]; U
[ 1]=~U
[ 1];
112 xor_blocks(W
,U
,V
,32);
114 /* encrypt third 8 bytes of H with third key*/
115 gost_enc_with_key(c
,Key
,H
+16,S
+16);
116 /* Compute fourth key */
120 xor_blocks(W
,U
,V
,32);
122 /* Encrypt last 8 bytes with fourth key */
123 gost_enc_with_key(c
,Key
,H
+24,S
+24);
126 xor_blocks(S
,S
,M
,32);
128 xor_blocks(S
,S
,H
,32);
135 /* Initialize gost_hash ctx - cleans up temporary structures and
136 * set up substitution blocks
138 int init_gost_hash_ctx(gost_hash_ctx
*ctx
, const gost_subst_block
*subst_block
)
140 memset(ctx
,0,sizeof(gost_hash_ctx
));
141 ctx
->cipher_ctx
= (gost_ctx
*)MYALLOC(sizeof(gost_ctx
));
142 if (!ctx
->cipher_ctx
)
146 gost_init(ctx
->cipher_ctx
,subst_block
);
151 * Free cipher CTX if it is dynamically allocated. Do not use
152 * if cipher ctx is statically allocated as in OpenSSL implementation of
153 * GOST hash algroritm
156 void done_gost_hash_ctx(gost_hash_ctx
*ctx
)
158 /* No need to use gost_destroy, because cipher keys are not really
159 * secret when hashing */
160 MYFREE(ctx
->cipher_ctx
);
164 * reset state of hash context to begin hashing new message
166 int start_hash(gost_hash_ctx
*ctx
)
168 if (!ctx
->cipher_ctx
) return 0;
169 memset(&(ctx
->H
),0,32);
170 memset(&(ctx
->S
),0,32);
177 * Hash block of arbitrary length
181 int hash_block(gost_hash_ctx
*ctx
,const byte
*block
, size_t length
)
183 const byte
*curptr
=block
;
184 const byte
*barrier
=block
+(length
-32);/* Last byte we can safely hash*/
187 /*There are some bytes from previous step*/
188 unsigned int add_bytes
= 32-ctx
->left
;
189 if (add_bytes
>length
)
193 memcpy(&(ctx
->remainder
[ctx
->left
]),block
,add_bytes
);
194 ctx
->left
+=add_bytes
;
199 curptr
=block
+add_bytes
;
200 hash_step(ctx
->cipher_ctx
,ctx
->H
,ctx
->remainder
);
201 add_blocks(32,ctx
->S
,ctx
->remainder
);
205 while (curptr
<=barrier
)
207 hash_step(ctx
->cipher_ctx
,ctx
->H
,curptr
);
209 add_blocks(32,ctx
->S
,curptr
);
213 if (curptr
!=block
+length
)
215 ctx
->left
=block
+length
-curptr
;
216 memcpy(ctx
->remainder
,curptr
,ctx
->left
);
222 * Compute hash value from current state of ctx
223 * state of hash ctx becomes invalid and cannot be used for further
226 int finish_hash(gost_hash_ctx
*ctx
,byte
*hashval
)
231 ghosthash_len fin_len
=ctx
->len
;
238 memcpy(buf
,ctx
->remainder
,ctx
->left
);
239 hash_step(ctx
->cipher_ctx
,H
,buf
);
240 add_blocks(32,S
,buf
);
245 fin_len
<<=3; /* Hash length in BITS!!*/
248 *(bptr
++)=(byte
)(fin_len
&0xFF);
251 hash_step(ctx
->cipher_ctx
,H
,buf
);
252 hash_step(ctx
->cipher_ctx
,H
,S
);
253 memcpy(hashval
,H
,32);