1 /* iksemel (XML parser for Jabber)
2 ** Copyright (C) 2000-2003 Gurer Ozen
3 ** This code is free software; you can redistribute it and/or
4 ** modify it under the terms of GNU Lesser General Public License.
5 */
6
7 #include "common.h"
8 #include "iksemel.h"
9
10 static void sha_buffer (iksha *sha, const unsigned char *data, int len);
11 static void sha_calculate (iksha *sha);
12
13 struct iksha_struct {
14 unsigned int hash[5];
15 unsigned int buf[80];
16 int blen;
17 unsigned int lenhi, lenlo;
18 };
19
20 iksha *
iks_sha_new(void)21 iks_sha_new (void)
22 {
23 iksha *sha;
24
25 sha = iks_malloc (sizeof (iksha));
26 if (!sha) return NULL;
27 iks_sha_reset (sha);
28 return sha;
29 }
30
31 void
iks_sha_reset(iksha * sha)32 iks_sha_reset (iksha *sha)
33 {
34 memset (sha, 0, sizeof (iksha));
35 sha->hash[0] = 0x67452301;
36 sha->hash[1] = 0xefcdab89;
37 sha->hash[2] = 0x98badcfe;
38 sha->hash[3] = 0x10325476;
39 sha->hash[4] = 0xc3d2e1f0;
40 }
41
42 void
iks_sha_hash(iksha * sha,const unsigned char * data,size_t len,int finish)43 iks_sha_hash (iksha *sha, const unsigned char *data, size_t len, int finish)
44 {
45 unsigned char pad[8];
46 unsigned char padc;
47
48 if (data && len != 0) sha_buffer (sha, data, len);
49 if (!finish) return;
50
51 pad[0] = (unsigned char)((sha->lenhi >> 24) & 0xff);
52 pad[1] = (unsigned char)((sha->lenhi >> 16) & 0xff);
53 pad[2] = (unsigned char)((sha->lenhi >> 8) & 0xff);
54 pad[3] = (unsigned char)(sha->lenhi & 0xff);
55 pad[4] = (unsigned char)((sha->lenlo >> 24) & 0xff);
56 pad[5] = (unsigned char)((sha->lenlo >> 16) & 0xff);
57 pad[6] = (unsigned char)((sha->lenlo >> 8) & 0xff);
58 pad[7] = (unsigned char)(sha->lenlo & 255);
59
60 padc = 0x80;
61 sha_buffer (sha, &padc, 1);
62
63 padc = 0x00;
64 while (sha->blen != 56)
65 sha_buffer (sha, &padc, 1);
66
67 sha_buffer (sha, pad, 8);
68 }
69
70 void
iks_sha_print(iksha * sha,char * hash)71 iks_sha_print (iksha *sha, char *hash)
72 {
73 int i;
74
75 for (i=0; i<5; i++)
76 {
77 sprintf (hash, "%08x", sha->hash[i]);
78 hash += 8;
79 }
80 }
81
82 void
iks_sha_delete(iksha * sha)83 iks_sha_delete (iksha *sha)
84 {
85 iks_free (sha);
86 }
87
88 void
iks_sha(const char * data,char * hash)89 iks_sha (const char *data, char *hash)
90 {
91 iksha *sha;
92
93 sha = iks_sha_new ();
94 iks_sha_hash (sha, (const unsigned char*)data, strlen (data), 1);
95 iks_sha_print (sha, hash);
96 iks_free (sha);
97 }
98
99 static void
sha_buffer(iksha * sha,const unsigned char * data,int len)100 sha_buffer (iksha *sha, const unsigned char *data, int len)
101 {
102 int i;
103
104 for (i=0; i<len; i++) {
105 sha->buf[sha->blen / 4] <<= 8;
106 sha->buf[sha->blen / 4] |= (unsigned int)data[i];
107 if ((++sha->blen) % 64 == 0) {
108 sha_calculate (sha);
109 sha->blen = 0;
110 }
111 sha->lenlo += 8;
112 sha->lenhi += (sha->lenlo < 8);
113 }
114 }
115
116 #define SRL(x,y) (((x) << (y)) | ((x) >> (32-(y))))
117 #define SHA(a,b,f,c) \
118 for (i= (a) ; i<= (b) ; i++) { \
119 TMP = SRL(A,5) + ( (f) ) + E + sha->buf[i] + (c) ; \
120 E = D; \
121 D = C; \
122 C = SRL(B,30); \
123 B = A; \
124 A = TMP; \
125 }
126
127 static void
sha_calculate(iksha * sha)128 sha_calculate (iksha *sha)
129 {
130 int i;
131 unsigned int A, B, C, D, E, TMP;
132
133 for (i=16; i<80; i++)
134 sha->buf[i] = SRL (sha->buf[i-3] ^ sha->buf[i-8] ^ sha->buf[i-14] ^ sha->buf[i-16], 1);
135
136 A = sha->hash[0];
137 B = sha->hash[1];
138 C = sha->hash[2];
139 D = sha->hash[3];
140 E = sha->hash[4];
141
142 SHA (0, 19, ((C^D)&B)^D, 0x5a827999);
143 SHA (20, 39, B^C^D, 0x6ed9eba1);
144 SHA (40, 59, (B&C)|(D&(B|C)), 0x8f1bbcdc);
145 SHA (60, 79, B^C^D, 0xca62c1d6);
146
147 sha->hash[0] += A;
148 sha->hash[1] += B;
149 sha->hash[2] += C;
150 sha->hash[3] += D;
151 sha->hash[4] += E;
152 }
153