gloox 1.0.27
sha.cpp
1/*
2 Copyright (c) 2006-2023 by Jakob Schröter <js@camaya.net>
3 This file is part of the gloox library. http://camaya.net/gloox
4
5 This software is distributed under a license. The full license
6 agreement can be found in the file LICENSE in this distribution.
7 This software may not be copied, modified, sold or distributed
8 other than expressed in the named license agreement.
9
10 This software is distributed without any warranty.
11*/
12
13#include "config.h"
14
15#include "sha.h"
16#include "gloox.h"
17
18#include <cstdio>
19
20namespace gloox
21{
22
24 {
25 init();
26 }
27
29 {
30 }
31
32 void SHA::init()
33 {
34 Length_Low = 0;
35 Length_High = 0;
36 Message_Block_Index = 0;
37
38 H[0] = 0x67452301;
39 H[1] = 0xEFCDAB89;
40 H[2] = 0x98BADCFE;
41 H[3] = 0x10325476;
42 H[4] = 0xC3D2E1F0;
43
44 m_finished = false;
45 m_corrupted = false;
46 }
47
49 {
50 init();
51 }
52
53 const std::string SHA::hex()
54 {
55 if( m_corrupted )
56 return EmptyString;
57
58 if( !m_finished )
59 finalize();
60
61 char buf[41];
62 for( int i = 0; i < 20; ++i )
63 sprintf( buf + i * 2, "%02x", static_cast<unsigned char>( H[i >> 2] >> ( ( 3 - ( i & 3 ) ) << 3 ) ) );
64
65 return std::string( buf, 40 );
66 }
67
68 const std::string SHA::binary()
69 {
70 if( !m_finished )
71 finalize();
72
73 unsigned char digest[20];
74 for( int i = 0; i < 20; ++i )
75 digest[i] = static_cast<unsigned char>( H[i >> 2] >> ( ( 3 - ( i & 3 ) ) << 3 ) );
76
77 return std::string( reinterpret_cast<char*>( digest ), 20 );
78 }
79
81 {
82 if( !m_finished )
83 {
84 pad();
85 m_finished = true;
86 }
87 }
88
89 void SHA::feed( const unsigned char* data, unsigned length )
90 {
91 if( !length )
92 return;
93
94 if( m_finished || m_corrupted )
95 {
96 m_corrupted = true;
97 return;
98 }
99
100 while( length-- && !m_corrupted )
101 {
102 Message_Block[Message_Block_Index++] = ( *data & 0xFF );
103
104 Length_Low += 8;
105 Length_Low &= 0xFFFFFFFF;
106 if( Length_Low == 0 )
107 {
108 Length_High++;
109 Length_High &= 0xFFFFFFFF;
110 if( Length_High == 0 )
111 {
112 m_corrupted = true;
113 }
114 }
115
116 if( Message_Block_Index == 64 )
117 {
118 process();
119 }
120
121 ++data;
122 }
123 }
124
125 void SHA::feed( const std::string& data )
126 {
127 feed( reinterpret_cast<const unsigned char*>( data.c_str() ), static_cast<int>( data.length() ) );
128 }
129
130 void SHA::process()
131 {
132 const unsigned K[] = { 0x5A827999,
133 0x6ED9EBA1,
134 0x8F1BBCDC,
135 0xCA62C1D6
136 };
137 int t;
138 unsigned temp;
139 unsigned W[80];
140 unsigned A, B, C, D, E;
141
142 for( t = 0; t < 16; t++ )
143 {
144 W[t] = static_cast<unsigned int>( Message_Block[t * 4] ) << 24;
145 W[t] |= static_cast<unsigned int>( Message_Block[t * 4 + 1] ) << 16;
146 W[t] |= static_cast<unsigned int>( Message_Block[t * 4 + 2] ) << 8;
147 W[t] |= static_cast<unsigned int>( Message_Block[t * 4 + 3] );
148 }
149
150 for( t = 16; t < 80; ++t )
151 {
152 W[t] = shift( 1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16] );
153 }
154
155 A = H[0];
156 B = H[1];
157 C = H[2];
158 D = H[3];
159 E = H[4];
160
161 for( t = 0; t < 20; ++t )
162 {
163 temp = shift( 5, A ) + ( ( B & C ) | ( ( ~B ) & D ) ) + E + W[t] + K[0];
164 temp &= 0xFFFFFFFF;
165 E = D;
166 D = C;
167 C = shift( 30, B );
168 B = A;
169 A = temp;
170 }
171
172 for( t = 20; t < 40; ++t )
173 {
174 temp = shift( 5, A ) + ( B ^ C ^ D ) + E + W[t] + K[1];
175 temp &= 0xFFFFFFFF;
176 E = D;
177 D = C;
178 C = shift( 30, B );
179 B = A;
180 A = temp;
181 }
182
183 for( t = 40; t < 60; ++t )
184 {
185 temp = shift( 5, A ) + ( ( B & C ) | ( B & D ) | ( C & D ) ) + E + W[t] + K[2];
186 temp &= 0xFFFFFFFF;
187 E = D;
188 D = C;
189 C = shift( 30, B );
190 B = A;
191 A = temp;
192 }
193
194 for( t = 60; t < 80; ++t )
195 {
196 temp = shift( 5, A ) + ( B ^ C ^ D ) + E + W[t] + K[3];
197 temp &= 0xFFFFFFFF;
198 E = D;
199 D = C;
200 C = shift( 30, B );
201 B = A;
202 A = temp;
203 }
204
205 H[0] = ( H[0] + A ) & 0xFFFFFFFF;
206 H[1] = ( H[1] + B ) & 0xFFFFFFFF;
207 H[2] = ( H[2] + C ) & 0xFFFFFFFF;
208 H[3] = ( H[3] + D ) & 0xFFFFFFFF;
209 H[4] = ( H[4] + E ) & 0xFFFFFFFF;
210
211 Message_Block_Index = 0;
212 }
213
214 void SHA::pad()
215 {
216 Message_Block[Message_Block_Index++] = 0x80;
217
218 if( Message_Block_Index > 56 )
219 {
220 while( Message_Block_Index < 64 )
221 {
222 Message_Block[Message_Block_Index++] = 0;
223 }
224
225 process();
226 }
227
228 while( Message_Block_Index < 56 )
229 {
230 Message_Block[Message_Block_Index++] = 0;
231 }
232
233 Message_Block[56] = static_cast<unsigned char>( ( Length_High >> 24 ) & 0xFF );
234 Message_Block[57] = static_cast<unsigned char>( ( Length_High >> 16 ) & 0xFF );
235 Message_Block[58] = static_cast<unsigned char>( ( Length_High >> 8 ) & 0xFF );
236 Message_Block[59] = static_cast<unsigned char>( ( Length_High ) & 0xFF );
237 Message_Block[60] = static_cast<unsigned char>( ( Length_Low >> 24 ) & 0xFF );
238 Message_Block[61] = static_cast<unsigned char>( ( Length_Low >> 16 ) & 0xFF );
239 Message_Block[62] = static_cast<unsigned char>( ( Length_Low >> 8 ) & 0xFF );
240 Message_Block[63] = static_cast<unsigned char>( ( Length_Low ) & 0xFF );
241
242 process();
243 }
244
245
246 unsigned SHA::shift( int bits, unsigned word )
247 {
248 return ( ( word << bits ) & 0xFFFFFFFF) | ( ( word & 0xFFFFFFFF ) >> ( 32-bits ) );
249 }
250
251}
virtual ~SHA()
Definition sha.cpp:28
void finalize()
Definition sha.cpp:80
void feed(const unsigned char *data, unsigned length)
Definition sha.cpp:89
const std::string binary()
Definition sha.cpp:68
const std::string hex()
Definition sha.cpp:53
void reset()
Definition sha.cpp:48
The namespace for the gloox library.
Definition adhoc.cpp:28
const std::string EmptyString
Definition gloox.cpp:124