DKIM: reinstate embedded Polarssl SHA routines under older GnuTLS. Bug 1772
[exim.git] / src / src / pdkim / sha1.c
CommitLineData
cb224393
JH
1#include "crypt_ver.h"
2
3#ifdef SHA_POLARSSL /* remainder of file */
4
5/*
6 * FIPS-180-1 compliant SHA-1 implementation
7 *
8 * Copyright (C) 2006-2010, Brainspark B.V.
9 *
10 * This file is part of PolarSSL (http://www.polarssl.org)
11 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
12 *
13 * All rights reserved.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 */
29/*
30 * The SHA-1 standard was published by NIST in 1993.
31 *
32 * http://www.itl.nist.gov/fipspubs/fip180-1.htm
33 */
34
35#include "polarssl/config.h"
36
37#if defined(POLARSSL_SHA1_C)
38
39#include "polarssl/sha1.h"
40
41#include <string.h>
42#include <stdio.h>
43
44/*
45 * 32-bit integer manipulation macros (big endian)
46 */
47#ifndef GET_ULONG_BE
48#define GET_ULONG_BE(n,b,i) \
49{ \
50 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
51 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
52 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
53 | ( (unsigned long) (b)[(i) + 3] ); \
54}
55#endif
56
57#ifndef PUT_ULONG_BE
58#define PUT_ULONG_BE(n,b,i) \
59{ \
60 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
61 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
62 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
63 (b)[(i) + 3] = (unsigned char) ( (n) ); \
64}
65#endif
66
67/*
68 * SHA-1 context setup
69 * Called from pdkim_parse_sig_header() pdkim_feed_finish() pdkim_init_sign()
70 */
71void sha1_starts( sha1_context *ctx )
72{
73 ctx->total[0] = 0;
74 ctx->total[1] = 0;
75
76 ctx->state[0] = 0x67452301;
77 ctx->state[1] = 0xEFCDAB89;
78 ctx->state[2] = 0x98BADCFE;
79 ctx->state[3] = 0x10325476;
80 ctx->state[4] = 0xC3D2E1F0;
81}
82
83static void sha1_process( sha1_context *ctx, const unsigned char data[64] )
84{
85 unsigned long temp, W[16], A, B, C, D, E;
86
87 GET_ULONG_BE( W[ 0], data, 0 );
88 GET_ULONG_BE( W[ 1], data, 4 );
89 GET_ULONG_BE( W[ 2], data, 8 );
90 GET_ULONG_BE( W[ 3], data, 12 );
91 GET_ULONG_BE( W[ 4], data, 16 );
92 GET_ULONG_BE( W[ 5], data, 20 );
93 GET_ULONG_BE( W[ 6], data, 24 );
94 GET_ULONG_BE( W[ 7], data, 28 );
95 GET_ULONG_BE( W[ 8], data, 32 );
96 GET_ULONG_BE( W[ 9], data, 36 );
97 GET_ULONG_BE( W[10], data, 40 );
98 GET_ULONG_BE( W[11], data, 44 );
99 GET_ULONG_BE( W[12], data, 48 );
100 GET_ULONG_BE( W[13], data, 52 );
101 GET_ULONG_BE( W[14], data, 56 );
102 GET_ULONG_BE( W[15], data, 60 );
103
104#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
105
106#define R(t) \
107( \
108 temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
109 W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
110 ( W[t & 0x0F] = S(temp,1) ) \
111)
112
113#define P(a,b,c,d,e,x) \
114{ \
115 e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
116}
117
118 A = ctx->state[0];
119 B = ctx->state[1];
120 C = ctx->state[2];
121 D = ctx->state[3];
122 E = ctx->state[4];
123
124#define F(x,y,z) (z ^ (x & (y ^ z)))
125#define K 0x5A827999
126
127 P( A, B, C, D, E, W[0] );
128 P( E, A, B, C, D, W[1] );
129 P( D, E, A, B, C, W[2] );
130 P( C, D, E, A, B, W[3] );
131 P( B, C, D, E, A, W[4] );
132 P( A, B, C, D, E, W[5] );
133 P( E, A, B, C, D, W[6] );
134 P( D, E, A, B, C, W[7] );
135 P( C, D, E, A, B, W[8] );
136 P( B, C, D, E, A, W[9] );
137 P( A, B, C, D, E, W[10] );
138 P( E, A, B, C, D, W[11] );
139 P( D, E, A, B, C, W[12] );
140 P( C, D, E, A, B, W[13] );
141 P( B, C, D, E, A, W[14] );
142 P( A, B, C, D, E, W[15] );
143 P( E, A, B, C, D, R(16) );
144 P( D, E, A, B, C, R(17) );
145 P( C, D, E, A, B, R(18) );
146 P( B, C, D, E, A, R(19) );
147
148#undef K
149#undef F
150
151#define F(x,y,z) (x ^ y ^ z)
152#define K 0x6ED9EBA1
153
154 P( A, B, C, D, E, R(20) );
155 P( E, A, B, C, D, R(21) );
156 P( D, E, A, B, C, R(22) );
157 P( C, D, E, A, B, R(23) );
158 P( B, C, D, E, A, R(24) );
159 P( A, B, C, D, E, R(25) );
160 P( E, A, B, C, D, R(26) );
161 P( D, E, A, B, C, R(27) );
162 P( C, D, E, A, B, R(28) );
163 P( B, C, D, E, A, R(29) );
164 P( A, B, C, D, E, R(30) );
165 P( E, A, B, C, D, R(31) );
166 P( D, E, A, B, C, R(32) );
167 P( C, D, E, A, B, R(33) );
168 P( B, C, D, E, A, R(34) );
169 P( A, B, C, D, E, R(35) );
170 P( E, A, B, C, D, R(36) );
171 P( D, E, A, B, C, R(37) );
172 P( C, D, E, A, B, R(38) );
173 P( B, C, D, E, A, R(39) );
174
175#undef K
176#undef F
177
178#define F(x,y,z) ((x & y) | (z & (x | y)))
179#define K 0x8F1BBCDC
180
181 P( A, B, C, D, E, R(40) );
182 P( E, A, B, C, D, R(41) );
183 P( D, E, A, B, C, R(42) );
184 P( C, D, E, A, B, R(43) );
185 P( B, C, D, E, A, R(44) );
186 P( A, B, C, D, E, R(45) );
187 P( E, A, B, C, D, R(46) );
188 P( D, E, A, B, C, R(47) );
189 P( C, D, E, A, B, R(48) );
190 P( B, C, D, E, A, R(49) );
191 P( A, B, C, D, E, R(50) );
192 P( E, A, B, C, D, R(51) );
193 P( D, E, A, B, C, R(52) );
194 P( C, D, E, A, B, R(53) );
195 P( B, C, D, E, A, R(54) );
196 P( A, B, C, D, E, R(55) );
197 P( E, A, B, C, D, R(56) );
198 P( D, E, A, B, C, R(57) );
199 P( C, D, E, A, B, R(58) );
200 P( B, C, D, E, A, R(59) );
201
202#undef K
203#undef F
204
205#define F(x,y,z) (x ^ y ^ z)
206#define K 0xCA62C1D6
207
208 P( A, B, C, D, E, R(60) );
209 P( E, A, B, C, D, R(61) );
210 P( D, E, A, B, C, R(62) );
211 P( C, D, E, A, B, R(63) );
212 P( B, C, D, E, A, R(64) );
213 P( A, B, C, D, E, R(65) );
214 P( E, A, B, C, D, R(66) );
215 P( D, E, A, B, C, R(67) );
216 P( C, D, E, A, B, R(68) );
217 P( B, C, D, E, A, R(69) );
218 P( A, B, C, D, E, R(70) );
219 P( E, A, B, C, D, R(71) );
220 P( D, E, A, B, C, R(72) );
221 P( C, D, E, A, B, R(73) );
222 P( B, C, D, E, A, R(74) );
223 P( A, B, C, D, E, R(75) );
224 P( E, A, B, C, D, R(76) );
225 P( D, E, A, B, C, R(77) );
226 P( C, D, E, A, B, R(78) );
227 P( B, C, D, E, A, R(79) );
228
229#undef K
230#undef F
231
232 ctx->state[0] += A;
233 ctx->state[1] += B;
234 ctx->state[2] += C;
235 ctx->state[3] += D;
236 ctx->state[4] += E;
237}
238
239/*
240 * SHA-1 process buffer
241 * Called from pdkim_feed_finish() & pdkim_finish_bodyhash()
242 */
243void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen )
244{
245 int fill;
246 unsigned long left;
247
248 if( ilen <= 0 )
249 return;
250
251 left = ctx->total[0] & 0x3F;
252 fill = 64 - left;
253
254 ctx->total[0] += ilen;
255 ctx->total[0] &= 0xFFFFFFFF;
256
257 if( ctx->total[0] < (unsigned long) ilen )
258 ctx->total[1]++;
259
260 if( left && ilen >= fill )
261 {
262 memcpy( (void *) (ctx->buffer + left),
263 (void *) input, fill );
264 sha1_process( ctx, ctx->buffer );
265 input += fill;
266 ilen -= fill;
267 left = 0;
268 }
269
270 while( ilen >= 64 )
271 {
272 sha1_process( ctx, input );
273 input += 64;
274 ilen -= 64;
275 }
276
277 if( ilen > 0 )
278 {
279 memcpy( (void *) (ctx->buffer + left),
280 (void *) input, ilen );
281 }
282}
283
284static const unsigned char sha1_padding[64] =
285{
286 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
287 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
288 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
290};
291
292/*
293 * SHA-1 final digest
294 * Called from pdkim_feed_finish() & pdkim_finish_bodyhash()
295 */
296void sha1_finish( sha1_context *ctx, unsigned char output[20] )
297{
298 unsigned long last, padn;
299 unsigned long high, low;
300 unsigned char msglen[8];
301
302 high = ( ctx->total[0] >> 29 )
303 | ( ctx->total[1] << 3 );
304 low = ( ctx->total[0] << 3 );
305
306 PUT_ULONG_BE( high, msglen, 0 );
307 PUT_ULONG_BE( low, msglen, 4 );
308
309 last = ctx->total[0] & 0x3F;
310 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
311
312 sha1_update( ctx, (unsigned char *) sha1_padding, padn );
313 sha1_update( ctx, msglen, 8 );
314
315 PUT_ULONG_BE( ctx->state[0], output, 0 );
316 PUT_ULONG_BE( ctx->state[1], output, 4 );
317 PUT_ULONG_BE( ctx->state[2], output, 8 );
318 PUT_ULONG_BE( ctx->state[3], output, 12 );
319 PUT_ULONG_BE( ctx->state[4], output, 16 );
320}
321
322#endif
323#endif