~ubuntu-branches/ubuntu/utopic/openssl/utopic

« back to all changes in this revision

Viewing changes to engines/ccgost/gosthash.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2011-04-02 13:19:19 UTC
  • mfrom: (1.2.1 upstream) (11.2.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 55.
  • Revision ID: james.westby@ubuntu.com-20110402131919-anszuslper64ey9e
Tags: 1.0.0d-1
* New upstream version
  - Fixes CVE-2011-0014
* Make libssl-doc Replaces/Breaks with old libssl-dev packages
  (Closes: #607609)
* Only export the symbols we should, instead of all.
* Add symbol file.
* Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**********************************************************************
 
2
 *                          gosthash.c                                *
 
3
 *             Copyright (c) 2005-2006 Cryptocom LTD                  *
 
4
 *         This file is distributed under the same license as OpenSSL *
 
5
 *                                                                    *
 
6
 *    Implementation of GOST R 34.11-94 hash function                 *
 
7
 *       uses on gost89.c and gost89.h Doesn't need OpenSSL           *
 
8
 **********************************************************************/
 
9
#include <string.h>
 
10
 
 
11
#include "gost89.h"
 
12
#include "gosthash.h"
 
13
 
 
14
 
 
15
/* Use OPENSSL_malloc for memory allocation if compiled with 
 
16
 * -DOPENSSL_BUILD, and libc malloc otherwise
 
17
 */
 
18
#ifndef MYALLOC
 
19
# ifdef OPENSSL_BUILD
 
20
#  include <openssl/crypto.h>
 
21
#  define MYALLOC(size) OPENSSL_malloc(size)
 
22
#  define MYFREE(ptr) OPENSSL_free(ptr)
 
23
# else
 
24
#  define MYALLOC(size) malloc(size)
 
25
#  define MYFREE(ptr) free(ptr)
 
26
# endif
 
27
#endif
 
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) 
 
31
        {
 
32
        int i,j;
 
33
        for (i=0;i<4;i++)       
 
34
                for (j=0;j<8;j++) 
 
35
                        k[i+4*j]=w[8*i+j];
 
36
 
 
37
        }
 
38
 
 
39
/* was A_A */
 
40
static void circle_xor8 (const byte *w, byte *k) 
 
41
        {
 
42
        byte buf[8];
 
43
        int i;
 
44
        memcpy(buf,w,8);
 
45
        memcpy(k,w+8,24);
 
46
        for(i=0;i<8;i++) 
 
47
                k[i+24]=buf[i]^k[i];
 
48
        }
 
49
 
 
50
/* was R_R */
 
51
static void transform_3 (byte *data) 
 
52
        {
 
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);
 
57
        data[30]=acc&0xff;
 
58
        data[31]=acc>>8;
 
59
        }
 
60
 
 
61
/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
 
62
static int add_blocks(int n,byte *left, const byte *right) 
 
63
        {
 
64
        int i;
 
65
        int carry=0;
 
66
        int sum;
 
67
        for (i=0;i<n;i++) 
 
68
                {
 
69
                sum=(int)left[i]+(int)right[i]+carry;
 
70
                left[i]=sum & 0xff;
 
71
                carry=sum>>8;
 
72
                }
 
73
        return carry;
 
74
        } 
 
75
 
 
76
/* Xor two sequences of bytes */
 
77
static void xor_blocks (byte *result,const byte *a,const byte *b,size_t len)
 
78
        {
 
79
        size_t i;
 
80
        for (i=0;i<len;i++) result[i]=a[i]^b[i];
 
81
        }       
 
82
 
 
83
/* 
 
84
 *      Calculate H(i+1) = Hash(Hi,Mi) 
 
85
 *      Where H and M are 32 bytes long
 
86
 */
 
87
static int hash_step(gost_ctx *c,byte *H,const byte *M) 
 
88
        {
 
89
        byte U[32],W[32],V[32],S[32],Key[32];
 
90
        int i;
 
91
        /* Compute first key */
 
92
        xor_blocks(W,H,M,32);
 
93
        swap_bytes(W,Key);
 
94
        /* Encrypt first 8 bytes of H with first key*/
 
95
        gost_enc_with_key(c,Key,H,S);
 
96
        /* Compute second key*/
 
97
        circle_xor8(H,U);
 
98
        circle_xor8(M,V);
 
99
        circle_xor8(V,V);
 
100
        xor_blocks(W,U,V,32);
 
101
        swap_bytes(W,Key);
 
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 */
 
105
        circle_xor8(U,U);
 
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];
 
110
        circle_xor8(V,V);
 
111
        circle_xor8(V,V);
 
112
        xor_blocks(W,U,V,32);
 
113
        swap_bytes(W,Key);
 
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 */
 
117
        circle_xor8(U,U);
 
118
        circle_xor8(V,V);
 
119
        circle_xor8(V,V);
 
120
        xor_blocks(W,U,V,32);
 
121
        swap_bytes(W,Key);
 
122
        /* Encrypt last 8 bytes with fourth key */
 
123
        gost_enc_with_key(c,Key,H+24,S+24);
 
124
        for (i=0;i<12;i++) 
 
125
                transform_3(S);
 
126
        xor_blocks(S,S,M,32);
 
127
        transform_3(S);
 
128
        xor_blocks(S,S,H,32);
 
129
        for (i=0;i<61;i++) 
 
130
                transform_3(S);
 
131
        memcpy(H,S,32);
 
132
        return 1;
 
133
        }
 
134
 
 
135
/* Initialize gost_hash ctx - cleans up temporary structures and
 
136
 * set up substitution blocks
 
137
 */
 
138
int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block)
 
139
        {       
 
140
        memset(ctx,0,sizeof(gost_hash_ctx));
 
141
        ctx->cipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx));
 
142
        if (!ctx->cipher_ctx)
 
143
                {
 
144
                return 0;
 
145
                }               
 
146
        gost_init(ctx->cipher_ctx,subst_block);
 
147
        return 1;
 
148
        }
 
149
 
 
150
/*
 
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
 
154
 *
 
155
 */ 
 
156
void done_gost_hash_ctx(gost_hash_ctx *ctx) 
 
157
        {
 
158
        /* No need to use gost_destroy, because cipher keys are not really
 
159
         * secret when hashing */
 
160
        MYFREE(ctx->cipher_ctx);
 
161
        }
 
162
 
 
163
/*
 
164
 * reset state of hash context to begin hashing new message
 
165
 */
 
166
int start_hash(gost_hash_ctx *ctx)
 
167
        {
 
168
        if (!ctx->cipher_ctx) return 0;
 
169
        memset(&(ctx->H),0,32);
 
170
        memset(&(ctx->S),0,32);
 
171
        ctx->len = 0L;
 
172
        ctx->left=0;
 
173
        return 1;
 
174
        }
 
175
 
 
176
/*
 
177
 * Hash block of arbitrary length
 
178
 *
 
179
 *
 
180
 */
 
181
int hash_block(gost_hash_ctx *ctx,const byte *block, size_t length)
 
182
        {
 
183
        const byte *curptr=block;
 
184
        const byte *barrier=block+(length-32);/* Last byte we can safely hash*/
 
185
        if (ctx->left)
 
186
                {
 
187
                /*There are some bytes from previous step*/
 
188
                unsigned int add_bytes = 32-ctx->left;
 
189
                if (add_bytes>length)
 
190
                        {
 
191
                        add_bytes = length;
 
192
                        }       
 
193
                memcpy(&(ctx->remainder[ctx->left]),block,add_bytes);
 
194
                ctx->left+=add_bytes;
 
195
                if (ctx->left<32)
 
196
                        {
 
197
                        return 1;
 
198
                        }       
 
199
                curptr=block+add_bytes;
 
200
                hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder);
 
201
                add_blocks(32,ctx->S,ctx->remainder);
 
202
                ctx->len+=32;
 
203
                ctx->left=0;
 
204
                }
 
205
        while (curptr<=barrier)
 
206
                {       
 
207
                hash_step(ctx->cipher_ctx,ctx->H,curptr);
 
208
                        
 
209
                add_blocks(32,ctx->S,curptr);
 
210
                ctx->len+=32;
 
211
                curptr+=32;
 
212
                }       
 
213
        if (curptr!=block+length)
 
214
                {
 
215
                ctx->left=block+length-curptr;
 
216
                memcpy(ctx->remainder,curptr,ctx->left);
 
217
                }       
 
218
        return 1;       
 
219
        }
 
220
 
 
221
/*
 
222
 * Compute hash value from current state of ctx
 
223
 * state of hash ctx becomes invalid and cannot be used for further
 
224
 * hashing.
 
225
 */ 
 
226
int finish_hash(gost_hash_ctx *ctx,byte *hashval)
 
227
        {
 
228
        byte buf[32];
 
229
        byte H[32];
 
230
        byte S[32];
 
231
        ghosthash_len fin_len=ctx->len;
 
232
        byte *bptr;
 
233
        memcpy(H,ctx->H,32);
 
234
        memcpy(S,ctx->S,32);
 
235
        if (ctx->left)
 
236
                {
 
237
                memset(buf,0,32);
 
238
                memcpy(buf,ctx->remainder,ctx->left);
 
239
                hash_step(ctx->cipher_ctx,H,buf);
 
240
                add_blocks(32,S,buf);
 
241
                fin_len+=ctx->left;
 
242
                }
 
243
        memset(buf,0,32);
 
244
        bptr=buf;
 
245
        fin_len<<=3; /* Hash length in BITS!!*/
 
246
        while(fin_len>0)
 
247
                {
 
248
                *(bptr++)=(byte)(fin_len&0xFF);
 
249
                fin_len>>=8;
 
250
                };
 
251
        hash_step(ctx->cipher_ctx,H,buf);
 
252
        hash_step(ctx->cipher_ctx,H,S);
 
253
        memcpy(hashval,H,32);
 
254
        return 1;
 
255
        }