|
1 /* |
|
2 * Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: EAP and WLAN authentication protocols. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // This is enumeration of EAPOL source code. |
|
20 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES) |
|
21 #undef EAP_FILE_NUMBER_ENUM |
|
22 #define EAP_FILE_NUMBER_ENUM 7 |
|
23 #undef EAP_FILE_NUMBER_DATE |
|
24 #define EAP_FILE_NUMBER_DATE 1127594498 |
|
25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) |
|
26 |
|
27 |
|
28 |
|
29 #include "eap_am_memory.h" |
|
30 #include "eap_am_crypto_sha1.h" |
|
31 |
|
32 //-------------------------------------------------- |
|
33 |
|
34 #if 1 |
|
35 #define EAP_SHA1_TRACE_DEBUG EAP_TRACE_DEBUG |
|
36 #define EAP_SHA1_TRACE_DATA_DEBUG EAP_TRACE_DATA_DEBUG |
|
37 #else |
|
38 #define EAP_SHA1_TRACE_DEBUG(tools, flags, params) |
|
39 #define EAP_SHA1_TRACE_DATA_DEBUG(object_name, flags, _parameter_list_) |
|
40 #endif |
|
41 |
|
42 #if defined(USE_EAP_TRACE) |
|
43 static const u32_t EAP_TRACE_MASK_SHA1 = eap_am_tools_c::eap_trace_mask_crypto_sha1; |
|
44 #endif //#if defined(USE_EAP_TRACE) |
|
45 |
|
46 //-------------------------------------------------- |
|
47 |
|
48 EAP_FUNC_EXPORT eap_am_crypto_sha1_c::~eap_am_crypto_sha1_c() |
|
49 { |
|
50 hash_cleanup(); |
|
51 } |
|
52 |
|
53 //-------------------------------------------------- |
|
54 |
|
55 EAP_FUNC_EXPORT eap_am_crypto_sha1_c::eap_am_crypto_sha1_c( |
|
56 abs_eap_am_tools_c * const tools) |
|
57 : m_am_tools(tools) |
|
58 , m_saved_data(tools) |
|
59 , m_full_hashed_data_length(0ul) |
|
60 , m_is_valid(false) |
|
61 { |
|
62 m_H[0] = 0; |
|
63 m_T[0] = 0; |
|
64 m_W_in_host_order[0] = 0; |
|
65 |
|
66 if (m_saved_data.get_is_valid() == false) |
|
67 { |
|
68 return; |
|
69 } |
|
70 |
|
71 eap_status_e status = hash_init(); |
|
72 if (status != eap_status_ok) |
|
73 { |
|
74 return; |
|
75 } |
|
76 |
|
77 set_is_valid(); |
|
78 } |
|
79 |
|
80 //------------------------------------------------------------ |
|
81 |
|
82 /** |
|
83 * The set_is_invalid() function sets the state of the eap_am_crypto_sha1_c |
|
84 * object invalid. |
|
85 * The eap_am_crypto_sha1_c object calls this function after it is initialized. |
|
86 */ |
|
87 EAP_FUNC_EXPORT void eap_am_crypto_sha1_c::set_is_invalid() |
|
88 { |
|
89 m_is_valid = false; |
|
90 } |
|
91 |
|
92 //------------------------------------------------------------ |
|
93 |
|
94 /** |
|
95 * The set_is_valid() function sets the state of the eap_am_crypto_sha1_c |
|
96 * object valid. |
|
97 * The eap_am_crypto_sha1_c object calls this function after it is initialized. |
|
98 */ |
|
99 EAP_FUNC_EXPORT void eap_am_crypto_sha1_c::set_is_valid() |
|
100 { |
|
101 m_is_valid = true; |
|
102 } |
|
103 |
|
104 //------------------------------------------------------------ |
|
105 |
|
106 /** |
|
107 * The get_is_valid() function returns the status of the eap_am_crypto_sha1_c |
|
108 * object. |
|
109 * True indicates the object is allocated successfully. |
|
110 */ |
|
111 EAP_FUNC_EXPORT bool eap_am_crypto_sha1_c::get_is_valid() |
|
112 { |
|
113 return m_is_valid; |
|
114 } |
|
115 |
|
116 //-------------------------------------------------- |
|
117 |
|
118 inline u32_t eap_am_crypto_sha1_c::eap_sha1_rotate( |
|
119 const u32_t value, |
|
120 const u32_t shift |
|
121 ) |
|
122 { |
|
123 return (value << shift) | (value >> (32ul - shift)); |
|
124 } |
|
125 |
|
126 //-------------------------------------------------- |
|
127 |
|
128 inline u32_t eap_am_crypto_sha1_c::eap_sha1_b_substitution( |
|
129 const u32_t Wt_3, |
|
130 const u32_t Wt_8, |
|
131 const u32_t Wt_14, |
|
132 const u32_t Wt_16 |
|
133 ) |
|
134 { |
|
135 return eap_sha1_rotate(Wt_3 ^ Wt_8 ^ Wt_14 ^ Wt_16, 1ul); |
|
136 } |
|
137 |
|
138 //-------------------------------------------------- |
|
139 |
|
140 inline u32_t eap_am_crypto_sha1_c::eap_sha1_ft_0_19( |
|
141 const u32_t B, |
|
142 const u32_t C, |
|
143 const u32_t D |
|
144 ) |
|
145 { |
|
146 return (((C ^ D) & B) ^ D); |
|
147 } |
|
148 |
|
149 //-------------------------------------------------- |
|
150 |
|
151 inline u32_t eap_am_crypto_sha1_c::eap_sha1_ft_20_39( |
|
152 const u32_t B, |
|
153 const u32_t C, |
|
154 const u32_t D |
|
155 ) |
|
156 { |
|
157 return (B ^ C ^ D); |
|
158 } |
|
159 |
|
160 //-------------------------------------------------- |
|
161 |
|
162 inline u32_t eap_am_crypto_sha1_c::eap_sha1_ft_40_59( |
|
163 const u32_t B, |
|
164 const u32_t C, |
|
165 const u32_t D |
|
166 ) |
|
167 { |
|
168 return ((B & C) | ((B | C) & D)); |
|
169 } |
|
170 |
|
171 //-------------------------------------------------- |
|
172 |
|
173 inline u32_t eap_am_crypto_sha1_c::eap_sha1_ft_60_79( |
|
174 const u32_t B, |
|
175 const u32_t C, |
|
176 const u32_t D |
|
177 ) |
|
178 { |
|
179 return eap_sha1_ft_20_39(B, C, D); |
|
180 } |
|
181 |
|
182 //-------------------------------------------------- |
|
183 |
|
184 inline void eap_am_crypto_sha1_c::d_substitution( |
|
185 u32_t * const A, |
|
186 u32_t * const B, |
|
187 u32_t * const C, |
|
188 u32_t * const D, |
|
189 u32_t * const E, |
|
190 const u32_t temp |
|
191 ) |
|
192 { |
|
193 *E = *D; |
|
194 *D = *C; |
|
195 *C = eap_sha1_rotate(*B, 30ul); |
|
196 *B = *A; |
|
197 *A = temp; |
|
198 } |
|
199 |
|
200 //-------------------------------------------------- |
|
201 |
|
202 inline void eap_am_crypto_sha1_c::d_substitution_0_15( |
|
203 const u32_t t, |
|
204 u32_t * const A, |
|
205 u32_t * const B, |
|
206 u32_t * const C, |
|
207 u32_t * const D, |
|
208 u32_t * const E, |
|
209 const u32_t Wt |
|
210 ) |
|
211 { |
|
212 EAP_UNREFERENCED_PARAMETER(t); |
|
213 |
|
214 const u32_t TEMP = eap_sha1_rotate(*A, 5ul) |
|
215 + eap_sha1_ft_0_19(*B, *C, *D) |
|
216 + *E + Wt + eap_am_crypto_sha1_c::EAP_SHA1_K__0_19; |
|
217 |
|
218 d_substitution(A, B, C, D, E, TEMP); |
|
219 |
|
220 EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, |
|
221 (EAPL("SHA1: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\n"), |
|
222 t, *A, *B, *C, *D, *E)); |
|
223 } |
|
224 |
|
225 //-------------------------------------------------- |
|
226 |
|
227 inline void eap_am_crypto_sha1_c::d_substitution_16_19( |
|
228 const u32_t t, |
|
229 u32_t * const A, |
|
230 u32_t * const B, |
|
231 u32_t * const C, |
|
232 u32_t * const D, |
|
233 u32_t * const E, |
|
234 u32_t * const Wt, |
|
235 const u32_t Wt_3, |
|
236 const u32_t Wt_8, |
|
237 const u32_t Wt_14, |
|
238 const u32_t Wt_16 |
|
239 ) |
|
240 { |
|
241 EAP_UNREFERENCED_PARAMETER(t); |
|
242 |
|
243 *Wt = eap_sha1_b_substitution(Wt_3, Wt_8, Wt_14, Wt_16); |
|
244 |
|
245 const u32_t TEMP = eap_sha1_rotate(*A, 5ul) |
|
246 + eap_sha1_ft_0_19(*B, *C, *D) |
|
247 + *E + *Wt + eap_am_crypto_sha1_c::EAP_SHA1_K__0_19; |
|
248 |
|
249 d_substitution(A, B, C, D, E, TEMP); |
|
250 |
|
251 EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, |
|
252 (EAPL("SHA1: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\n"), |
|
253 t, *A, *B, *C, *D, *E)); |
|
254 } |
|
255 |
|
256 //-------------------------------------------------- |
|
257 |
|
258 inline void eap_am_crypto_sha1_c::d_substitution_20_39( |
|
259 const u32_t t, |
|
260 u32_t * const A, |
|
261 u32_t * const B, |
|
262 u32_t * const C, |
|
263 u32_t * const D, |
|
264 u32_t * const E, |
|
265 u32_t * const Wt, |
|
266 const u32_t Wt_3, |
|
267 const u32_t Wt_8, |
|
268 const u32_t Wt_14, |
|
269 const u32_t Wt_16 |
|
270 ) |
|
271 { |
|
272 EAP_UNREFERENCED_PARAMETER(t); |
|
273 |
|
274 *Wt = eap_sha1_b_substitution(Wt_3, Wt_8, Wt_14, Wt_16); |
|
275 |
|
276 const u32_t TEMP = eap_sha1_rotate(*A, 5ul) |
|
277 + eap_sha1_ft_20_39(*B, *C, *D) |
|
278 + *E + *Wt + eap_am_crypto_sha1_c::EAP_SHA1_K_20_39; |
|
279 |
|
280 d_substitution(A, B, C, D, E, TEMP); |
|
281 |
|
282 EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, |
|
283 (EAPL("SHA1: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\n"), |
|
284 t, *A, *B, *C, *D, *E)); |
|
285 } |
|
286 |
|
287 //-------------------------------------------------- |
|
288 |
|
289 inline void eap_am_crypto_sha1_c::d_substitution_40_59( |
|
290 const u32_t t, |
|
291 u32_t * const A, |
|
292 u32_t * const B, |
|
293 u32_t * const C, |
|
294 u32_t * const D, |
|
295 u32_t * const E, |
|
296 u32_t * const Wt, |
|
297 const u32_t Wt_3, |
|
298 const u32_t Wt_8, |
|
299 const u32_t Wt_14, |
|
300 const u32_t Wt_16 |
|
301 ) |
|
302 { |
|
303 EAP_UNREFERENCED_PARAMETER(t); |
|
304 |
|
305 *Wt = eap_sha1_b_substitution(Wt_3, Wt_8, Wt_14, Wt_16); |
|
306 |
|
307 const u32_t TEMP = eap_sha1_rotate(*A, 5ul) |
|
308 + eap_sha1_ft_40_59(*B, *C, *D) |
|
309 + *E + *Wt + static_cast<u32_t>(eap_am_crypto_sha1_c::EAP_SHA1_K_40_59); |
|
310 |
|
311 d_substitution(A, B, C, D, E, TEMP); |
|
312 |
|
313 EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, |
|
314 (EAPL("SHA1: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\n"), |
|
315 t, *A, *B, *C, *D, *E)); |
|
316 } |
|
317 |
|
318 //-------------------------------------------------- |
|
319 |
|
320 inline void eap_am_crypto_sha1_c::d_substitution_60_79( |
|
321 const u32_t t, |
|
322 u32_t * const A, |
|
323 u32_t * const B, |
|
324 u32_t * const C, |
|
325 u32_t * const D, |
|
326 u32_t * const E, |
|
327 u32_t * const Wt, |
|
328 const u32_t Wt_3, |
|
329 const u32_t Wt_8, |
|
330 const u32_t Wt_14, |
|
331 const u32_t Wt_16 |
|
332 ) |
|
333 { |
|
334 EAP_UNREFERENCED_PARAMETER(t); |
|
335 |
|
336 *Wt = eap_sha1_b_substitution(Wt_3, Wt_8, Wt_14, Wt_16); |
|
337 |
|
338 const u32_t TEMP = eap_sha1_rotate(*A, 5ul) |
|
339 + eap_sha1_ft_60_79(*B, *C, *D) |
|
340 + *E + *Wt + static_cast<u32_t>(eap_am_crypto_sha1_c::EAP_SHA1_K_60_79); |
|
341 |
|
342 d_substitution(A, B, C, D, E, TEMP); |
|
343 |
|
344 EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, |
|
345 (EAPL("SHA1: t=%d\t%08x\t%08x\t%08x\t%08x\t%08x\n"), |
|
346 t, *A, *B, *C, *D, *E)); |
|
347 } |
|
348 |
|
349 //-------------------------------------------------- |
|
350 |
|
351 EAP_FUNC_EXPORT eap_status_e |
|
352 eap_am_crypto_sha1_c::eap_sha1_process_data_host_order( |
|
353 const u32_t * W, |
|
354 u32_t W_count |
|
355 ) |
|
356 { |
|
357 u32_t A; |
|
358 u32_t B; |
|
359 u32_t C; |
|
360 u32_t D; |
|
361 u32_t E; |
|
362 |
|
363 if (W == 0 |
|
364 //|| (reinterpret_cast<u32_t>(W) % sizeof(u32_t)) != 0 |
|
365 || W_count == 0 |
|
366 || (W_count % EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT) != 0) |
|
367 { |
|
368 EAP_ASSERT_ANYWAY; |
|
369 EAP_SYSTEM_DEBUG_BREAK(); |
|
370 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
371 } |
|
372 |
|
373 |
|
374 #if defined(_DEBUG) |
|
375 for (u32_t ind = 0ul; ind < W_count; ind++) |
|
376 { |
|
377 EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, |
|
378 (EAPL("SHA1: W[%d]=%08x\n"), |
|
379 ind, |
|
380 W[ind])); |
|
381 } // for() |
|
382 #endif //#if defined(_DEBUG) |
|
383 |
|
384 |
|
385 do |
|
386 { |
|
387 |
|
388 #if defined(_DEBUG) |
|
389 EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, |
|
390 (EAPL("SHA1: H[0]=0x%08x, H[1]=0x%08x, H[2]=0x%08x, H[3]=0x%08x, H[4]=0x%08x\n"), |
|
391 m_H[0], |
|
392 m_H[1], |
|
393 m_H[2], |
|
394 m_H[3], |
|
395 m_H[4])); |
|
396 EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, |
|
397 (EAPL("SHA1: % 4s\t% 8s\t% 8s\t% 8s\t% 8s\t% 8s\n"), |
|
398 "t", "A", "B", "C", "D", "E")); |
|
399 #endif //#if defined(_DEBUG) |
|
400 |
|
401 A = m_H[0]; |
|
402 B = m_H[1]; |
|
403 C = m_H[2]; |
|
404 D = m_H[3]; |
|
405 E = m_H[4]; |
|
406 |
|
407 d_substitution_0_15( 0, &A, &B, &C, &D, &E, W[ 0]); |
|
408 d_substitution_0_15( 1, &A, &B, &C, &D, &E, W[ 1]); |
|
409 d_substitution_0_15( 2, &A, &B, &C, &D, &E, W[ 2]); |
|
410 d_substitution_0_15( 3, &A, &B, &C, &D, &E, W[ 3]); |
|
411 d_substitution_0_15( 4, &A, &B, &C, &D, &E, W[ 4]); |
|
412 d_substitution_0_15( 5, &A, &B, &C, &D, &E, W[ 5]); |
|
413 d_substitution_0_15( 6, &A, &B, &C, &D, &E, W[ 6]); |
|
414 d_substitution_0_15( 7, &A, &B, &C, &D, &E, W[ 7]); |
|
415 d_substitution_0_15( 8, &A, &B, &C, &D, &E, W[ 8]); |
|
416 d_substitution_0_15( 9, &A, &B, &C, &D, &E, W[ 9]); |
|
417 d_substitution_0_15(10, &A, &B, &C, &D, &E, W[10]); |
|
418 d_substitution_0_15(11, &A, &B, &C, &D, &E, W[11]); |
|
419 d_substitution_0_15(12, &A, &B, &C, &D, &E, W[12]); |
|
420 d_substitution_0_15(13, &A, &B, &C, &D, &E, W[13]); |
|
421 d_substitution_0_15(14, &A, &B, &C, &D, &E, W[14]); |
|
422 d_substitution_0_15(15, &A, &B, &C, &D, &E, W[15]); |
|
423 |
|
424 d_substitution_16_19(16, &A, &B, &C, &D, &E, &(m_T[ 0]), |
|
425 W[13], W[ 8], W[ 2], W[ 0]); |
|
426 d_substitution_16_19(17, &A, &B, &C, &D, &E, &(m_T[ 1]), |
|
427 W[14], W[ 9], W[ 3], W[ 1]); |
|
428 d_substitution_16_19(18, &A, &B, &C, &D, &E, &(m_T[ 2]), |
|
429 W[15], W[10], W[ 4], W[ 2]); |
|
430 d_substitution_16_19(19, &A, &B, &C, &D, &E, &(m_T[ 3]), |
|
431 m_T[ 0], W[11], W[ 5], W[ 3]); |
|
432 |
|
433 d_substitution_20_39(20, &A, &B, &C, &D, &E, &(m_T[ 4]), |
|
434 m_T[ 1], W[12], W[ 6], W[ 4]); |
|
435 d_substitution_20_39(21, &A, &B, &C, &D, &E, &(m_T[ 5]), |
|
436 m_T[ 2], W[13], W[ 7], W[ 5]); |
|
437 d_substitution_20_39(22, &A, &B, &C, &D, &E, &(m_T[ 6]), |
|
438 m_T[ 3], W[14], W[ 8], W[ 6]); |
|
439 d_substitution_20_39(23, &A, &B, &C, &D, &E, &(m_T[ 7]), |
|
440 m_T[ 4], W[15], W[ 9], W[ 7]); |
|
441 d_substitution_20_39(24, &A, &B, &C, &D, &E, &(m_T[ 8]), |
|
442 m_T[ 5], m_T[ 0], W[10], W[ 8]); |
|
443 d_substitution_20_39(25, &A, &B, &C, &D, &E, &(m_T[ 9]), |
|
444 m_T[ 6], m_T[ 1], W[11], W[ 9]); |
|
445 d_substitution_20_39(26, &A, &B, &C, &D, &E, &(m_T[10]), |
|
446 m_T[ 7], m_T[ 2], W[12], W[10]); |
|
447 d_substitution_20_39(27, &A, &B, &C, &D, &E, &(m_T[11]), |
|
448 m_T[ 8], m_T[ 3], W[13], W[11]); |
|
449 d_substitution_20_39(28, &A, &B, &C, &D, &E, &(m_T[12]), |
|
450 m_T[ 9], m_T[ 4], W[14], W[12]); |
|
451 d_substitution_20_39(29, &A, &B, &C, &D, &E, &(m_T[13]), |
|
452 m_T[10], m_T[ 5], W[15], W[13]); |
|
453 d_substitution_20_39(30, &A, &B, &C, &D, &E, &(m_T[14]), |
|
454 m_T[11], m_T[ 6], m_T[ 0], W[14]); |
|
455 d_substitution_20_39(31, &A, &B, &C, &D, &E, &(m_T[15]), |
|
456 m_T[12], m_T[ 7], m_T[ 1], W[15]); |
|
457 d_substitution_20_39(32, &A, &B, &C, &D, &E, &(m_T[ 0]), |
|
458 m_T[13], m_T[ 8], m_T[ 2], m_T[ 0]); |
|
459 d_substitution_20_39(33, &A, &B, &C, &D, &E, &(m_T[ 1]), |
|
460 m_T[14], m_T[ 9], m_T[ 3], m_T[ 1]); |
|
461 d_substitution_20_39(34, &A, &B, &C, &D, &E, &(m_T[ 2]), |
|
462 m_T[15], m_T[10], m_T[ 4], m_T[ 2]); |
|
463 d_substitution_20_39(35, &A, &B, &C, &D, &E, &(m_T[ 3]), |
|
464 m_T[ 0], m_T[11], m_T[ 5], m_T[ 3]); |
|
465 d_substitution_20_39(36, &A, &B, &C, &D, &E, &(m_T[ 4]), |
|
466 m_T[ 1], m_T[12], m_T[ 6], m_T[ 4]); |
|
467 d_substitution_20_39(37, &A, &B, &C, &D, &E, &(m_T[ 5]), |
|
468 m_T[ 2], m_T[13], m_T[ 7], m_T[ 5]); |
|
469 d_substitution_20_39(38, &A, &B, &C, &D, &E, &(m_T[ 6]), |
|
470 m_T[ 3], m_T[14], m_T[ 8], m_T[ 6]); |
|
471 d_substitution_20_39(39, &A, &B, &C, &D, &E, &(m_T[ 7]), |
|
472 m_T[ 4], m_T[15], m_T[ 9], m_T[ 7]); |
|
473 |
|
474 d_substitution_40_59(40, &A, &B, &C, &D, &E, &(m_T[ 8]), |
|
475 m_T[ 5], m_T[ 0], m_T[10], m_T[ 8]); |
|
476 d_substitution_40_59(41, &A, &B, &C, &D, &E, &(m_T[ 9]), |
|
477 m_T[ 6], m_T[ 1], m_T[11], m_T[ 9]); |
|
478 d_substitution_40_59(42, &A, &B, &C, &D, &E, &(m_T[10]), |
|
479 m_T[ 7], m_T[ 2], m_T[12], m_T[10]); |
|
480 d_substitution_40_59(43, &A, &B, &C, &D, &E, &(m_T[11]), |
|
481 m_T[ 8], m_T[ 3], m_T[13], m_T[11]); |
|
482 d_substitution_40_59(44, &A, &B, &C, &D, &E, &(m_T[12]), |
|
483 m_T[ 9], m_T[ 4], m_T[14], m_T[12]); |
|
484 d_substitution_40_59(45, &A, &B, &C, &D, &E, &(m_T[13]), |
|
485 m_T[10], m_T[ 5], m_T[15], m_T[13]); |
|
486 d_substitution_40_59(46, &A, &B, &C, &D, &E, &(m_T[14]), |
|
487 m_T[11], m_T[ 6], m_T[ 0], m_T[14]); |
|
488 d_substitution_40_59(47, &A, &B, &C, &D, &E, &(m_T[15]), |
|
489 m_T[12], m_T[ 7], m_T[ 1], m_T[15]); |
|
490 d_substitution_40_59(48, &A, &B, &C, &D, &E, &(m_T[ 0]), |
|
491 m_T[13], m_T[ 8], m_T[ 2], m_T[ 0]); |
|
492 d_substitution_40_59(49, &A, &B, &C, &D, &E, &(m_T[ 1]), |
|
493 m_T[14], m_T[ 9], m_T[ 3], m_T[ 1]); |
|
494 d_substitution_40_59(50, &A, &B, &C, &D, &E, &(m_T[ 2]), |
|
495 m_T[15], m_T[10], m_T[ 4], m_T[ 2]); |
|
496 d_substitution_40_59(51, &A, &B, &C, &D, &E, &(m_T[ 3]), |
|
497 m_T[ 0], m_T[11], m_T[ 5], m_T[ 3]); |
|
498 d_substitution_40_59(52, &A, &B, &C, &D, &E, &(m_T[ 4]), |
|
499 m_T[ 1], m_T[12], m_T[ 6], m_T[ 4]); |
|
500 d_substitution_40_59(53, &A, &B, &C, &D, &E, &(m_T[ 5]), |
|
501 m_T[ 2], m_T[13], m_T[ 7], m_T[ 5]); |
|
502 d_substitution_40_59(54, &A, &B, &C, &D, &E, &(m_T[ 6]), |
|
503 m_T[ 3], m_T[14], m_T[ 8], m_T[ 6]); |
|
504 d_substitution_40_59(55, &A, &B, &C, &D, &E, &(m_T[ 7]), |
|
505 m_T[ 4], m_T[15], m_T[ 9], m_T[ 7]); |
|
506 d_substitution_40_59(56, &A, &B, &C, &D, &E, &(m_T[ 8]), |
|
507 m_T[ 5], m_T[ 0], m_T[10], m_T[ 8]); |
|
508 d_substitution_40_59(57, &A, &B, &C, &D, &E, &(m_T[ 9]), |
|
509 m_T[ 6], m_T[ 1], m_T[11], m_T[ 9]); |
|
510 d_substitution_40_59(58, &A, &B, &C, &D, &E, &(m_T[10]), |
|
511 m_T[ 7], m_T[ 2], m_T[12], m_T[10]); |
|
512 d_substitution_40_59(59, &A, &B, &C, &D, &E, &(m_T[11]), |
|
513 m_T[ 8], m_T[ 3], m_T[13], m_T[11]); |
|
514 |
|
515 d_substitution_60_79(60, &A, &B, &C, &D, &E, &(m_T[12]), |
|
516 m_T[ 9], m_T[ 4], m_T[14], m_T[12]); |
|
517 d_substitution_60_79(61, &A, &B, &C, &D, &E, &(m_T[13]), |
|
518 m_T[10], m_T[ 5], m_T[15], m_T[13]); |
|
519 d_substitution_60_79(62, &A, &B, &C, &D, &E, &(m_T[14]), |
|
520 m_T[11], m_T[ 6], m_T[ 0], m_T[14]); |
|
521 d_substitution_60_79(63, &A, &B, &C, &D, &E, &(m_T[15]), |
|
522 m_T[12], m_T[ 7], m_T[ 1], m_T[15]); |
|
523 d_substitution_60_79(64, &A, &B, &C, &D, &E, &(m_T[ 0]), |
|
524 m_T[13], m_T[ 8], m_T[ 2], m_T[ 0]); |
|
525 d_substitution_60_79(65, &A, &B, &C, &D, &E, &(m_T[ 1]), |
|
526 m_T[14], m_T[ 9], m_T[ 3], m_T[ 1]); |
|
527 d_substitution_60_79(66, &A, &B, &C, &D, &E, &(m_T[ 2]), |
|
528 m_T[15], m_T[10], m_T[ 4], m_T[ 2]); |
|
529 d_substitution_60_79(67, &A, &B, &C, &D, &E, &(m_T[ 3]), |
|
530 m_T[ 0], m_T[11], m_T[ 5], m_T[ 3]); |
|
531 d_substitution_60_79(68, &A, &B, &C, &D, &E, &(m_T[ 4]), |
|
532 m_T[ 1], m_T[12], m_T[ 6], m_T[ 4]); |
|
533 d_substitution_60_79(69, &A, &B, &C, &D, &E, &(m_T[ 5]), |
|
534 m_T[ 2], m_T[13], m_T[ 7], m_T[ 5]); |
|
535 d_substitution_60_79(70, &A, &B, &C, &D, &E, &(m_T[ 6]), |
|
536 m_T[ 3], m_T[14], m_T[ 8], m_T[ 6]); |
|
537 d_substitution_60_79(71, &A, &B, &C, &D, &E, &(m_T[ 7]), |
|
538 m_T[ 4], m_T[15], m_T[ 9], m_T[ 7]); |
|
539 d_substitution_60_79(72, &A, &B, &C, &D, &E, &(m_T[ 8]), |
|
540 m_T[ 5], m_T[ 0], m_T[10], m_T[ 8]); |
|
541 d_substitution_60_79(73, &A, &B, &C, &D, &E, &(m_T[ 9]), |
|
542 m_T[ 6], m_T[ 1], m_T[11], m_T[ 9]); |
|
543 d_substitution_60_79(74, &A, &B, &C, &D, &E, &(m_T[10]), |
|
544 m_T[ 7], m_T[ 2], m_T[12], m_T[10]); |
|
545 d_substitution_60_79(75, &A, &B, &C, &D, &E, &(m_T[11]), |
|
546 m_T[ 8], m_T[ 3], m_T[13], m_T[11]); |
|
547 d_substitution_60_79(76, &A, &B, &C, &D, &E, &(m_T[12]), |
|
548 m_T[ 9], m_T[ 4], m_T[14], m_T[12]); |
|
549 d_substitution_60_79(77, &A, &B, &C, &D, &E, &(m_T[13]), |
|
550 m_T[10], m_T[ 5], m_T[15], m_T[13]); |
|
551 d_substitution_60_79(78, &A, &B, &C, &D, &E, &(m_T[14]), |
|
552 m_T[11], m_T[ 6], m_T[ 0], m_T[14]); |
|
553 d_substitution_60_79(79, &A, &B, &C, &D, &E, &(m_T[15]), |
|
554 m_T[12], m_T[ 7], m_T[ 1], m_T[15]); |
|
555 |
|
556 m_H[0] = m_H[0] + A; |
|
557 m_H[1] = m_H[1] + B; |
|
558 m_H[2] = m_H[2] + C; |
|
559 m_H[3] = m_H[3] + D; |
|
560 m_H[4] = m_H[4] + E; |
|
561 |
|
562 W_count -= EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT; |
|
563 W += EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT; |
|
564 |
|
565 } while(W_count > 0ul); |
|
566 |
|
567 EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, |
|
568 (EAPL("SHA1: digest=\t%08x\t%08x\t%08x\t%08x\t%08x\n"), |
|
569 m_H[0], m_H[1], m_H[2], m_H[3], m_H[4])); |
|
570 |
|
571 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
572 } |
|
573 |
|
574 //-------------------------------------------------- |
|
575 |
|
576 EAP_FUNC_EXPORT eap_status_e |
|
577 eap_am_crypto_sha1_c::eap_sha1_process_data_network_order( |
|
578 const u32_t * W, |
|
579 u32_t W_count |
|
580 ) |
|
581 { |
|
582 if (W == 0 |
|
583 //|| (reinterpret_cast<u32_t>(W) % sizeof(u32_t)) != 0 |
|
584 || W_count == 0 |
|
585 || (W_count % EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT) != 0) |
|
586 { |
|
587 EAP_ASSERT_ANYWAY; |
|
588 EAP_SYSTEM_DEBUG_BREAK(); |
|
589 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
590 } |
|
591 |
|
592 eap_status_e status = eap_status_ok; |
|
593 |
|
594 // Array of 16 temporary 32-bit unsigned integers. |
|
595 u32_t count = W_count / EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT; |
|
596 |
|
597 for (u32_t ind = 0ul; ind < count; ind++) |
|
598 { |
|
599 for (u32_t ind_W = 0ul; ind_W < EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT |
|
600 ; ind_W++) |
|
601 { |
|
602 // Here we must read data in 8-bit blocks bacause W can be aligned at any position. |
|
603 const u8_t * const data |
|
604 = reinterpret_cast<const u8_t *>( |
|
605 &W[ind*EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT+ind_W]); |
|
606 m_W_in_host_order[ind_W] |
|
607 = (data[0] << 24) |
|
608 | (data[1] << 16) |
|
609 | (data[2] << 8) |
|
610 | (data[3] << 0); |
|
611 } // for() |
|
612 |
|
613 status = eap_sha1_process_data_host_order( |
|
614 m_W_in_host_order, |
|
615 EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT); |
|
616 if (status != eap_status_ok) |
|
617 { |
|
618 return EAP_STATUS_RETURN(m_am_tools, status); |
|
619 } |
|
620 |
|
621 } // for() |
|
622 |
|
623 return EAP_STATUS_RETURN(m_am_tools, status); |
|
624 } |
|
625 |
|
626 //-------------------------------------------------- |
|
627 |
|
628 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::copy_message_digest( |
|
629 void * const output, |
|
630 u32_t * const max_output_size) |
|
631 { |
|
632 if (output == 0 |
|
633 || max_output_size == 0 |
|
634 || *max_output_size < EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE) |
|
635 { |
|
636 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
637 } |
|
638 |
|
639 #if defined(EAP_LITTLE_ENDIAN) |
|
640 // We must change the data from host order to network order. |
|
641 u32_t * const tmp_H = static_cast<u32_t *>(output); |
|
642 for (u32_t ind = 0ul; ind < EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_u32_COUNT |
|
643 ; ind++) |
|
644 { |
|
645 tmp_H[ind] = eap_htonl(m_H[ind]); |
|
646 } // for() |
|
647 |
|
648 #elif defined(EAP_BIG_ENDIAN) |
|
649 |
|
650 m_am_tools->memmove( |
|
651 output, |
|
652 m_H, |
|
653 EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE); |
|
654 |
|
655 #else |
|
656 #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ |
|
657 or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). |
|
658 #endif |
|
659 |
|
660 *max_output_size = EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE; |
|
661 |
|
662 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
663 } |
|
664 |
|
665 //-------------------------------------------------- |
|
666 |
|
667 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::eap_sha1_dss_G_function( |
|
668 const void * const data, |
|
669 const u32_t data_length, |
|
670 void * const output, |
|
671 u32_t * const output_length |
|
672 ) |
|
673 { |
|
674 if (data == 0 |
|
675 || data_length == 0 |
|
676 || data_length > EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE |
|
677 || output == 0 |
|
678 || output_length == 0 |
|
679 || *output_length < EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE) |
|
680 { |
|
681 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
682 } |
|
683 |
|
684 eap_status_e status = hash_init(); |
|
685 if (status != eap_status_ok) |
|
686 { |
|
687 return EAP_STATUS_RETURN(m_am_tools, status); |
|
688 } |
|
689 |
|
690 m_am_tools->memset(m_W_in_host_order, 0, sizeof(m_W_in_host_order)); |
|
691 m_am_tools->memmove(m_W_in_host_order, data, data_length); |
|
692 |
|
693 |
|
694 #if defined(EAP_LITTLE_ENDIAN) |
|
695 |
|
696 { |
|
697 for (u32_t ind_W = 0ul; ind_W < EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT |
|
698 ; ind_W++) |
|
699 { |
|
700 m_W_in_host_order[ind_W] = eap_ntohl(m_W_in_host_order[ind_W]); |
|
701 } // for() |
|
702 |
|
703 status = eap_sha1_process_data_host_order( |
|
704 m_W_in_host_order, |
|
705 EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT); |
|
706 if (status != eap_status_ok) |
|
707 { |
|
708 return EAP_STATUS_RETURN(m_am_tools, status); |
|
709 } |
|
710 } |
|
711 |
|
712 #elif defined(EAP_BIG_ENDIAN) |
|
713 |
|
714 { |
|
715 u32_t count_W = data_length |
|
716 / EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE; |
|
717 |
|
718 status = eap_sha1_process_data_host_order(m_W_in_host_order, count_W); |
|
719 if (status != eap_status_ok) |
|
720 { |
|
721 return EAP_STATUS_RETURN(m_am_tools, status); |
|
722 } |
|
723 } |
|
724 |
|
725 #else |
|
726 #error ERROR: define EAP_LITTLE_ENDIAN (byte 0 is least significant (i386)) \ |
|
727 or EAP_BIG_ENDIAN (byte 0 is most significant (mc68k)). |
|
728 #endif |
|
729 |
|
730 status = copy_message_digest( |
|
731 output, |
|
732 output_length); |
|
733 if (status != eap_status_ok) |
|
734 { |
|
735 return EAP_STATUS_RETURN(m_am_tools, status); |
|
736 } |
|
737 |
|
738 return EAP_STATUS_RETURN(m_am_tools, status); |
|
739 } |
|
740 |
|
741 //-------------------------------------------------- |
|
742 |
|
743 /** |
|
744 * This function returns the size of message digest of HASH-algorithm. |
|
745 */ |
|
746 EAP_FUNC_EXPORT u32_t eap_am_crypto_sha1_c::get_digest_length() |
|
747 { |
|
748 return EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE; |
|
749 } |
|
750 |
|
751 //-------------------------------------------------- |
|
752 |
|
753 /** |
|
754 * This function returns the size of block of HASH-algorithm. |
|
755 */ |
|
756 EAP_FUNC_EXPORT u32_t eap_am_crypto_sha1_c::get_block_size() |
|
757 { |
|
758 return EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE; |
|
759 } |
|
760 |
|
761 //-------------------------------------------------- |
|
762 |
|
763 /** |
|
764 * This function initializes the context of SHA1-algorithm. |
|
765 */ |
|
766 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::hash_init() |
|
767 { |
|
768 m_full_hashed_data_length = 0ul; |
|
769 |
|
770 m_H[0] = static_cast<u32_t>(EAP_SHA1_INIT_H0); |
|
771 m_H[1] = static_cast<u32_t>(EAP_SHA1_INIT_H1); |
|
772 m_H[2] = static_cast<u32_t>(EAP_SHA1_INIT_H2); |
|
773 m_H[3] = static_cast<u32_t>(EAP_SHA1_INIT_H3); |
|
774 m_H[4] = static_cast<u32_t>(EAP_SHA1_INIT_H4); |
|
775 |
|
776 if (m_saved_data.get_is_valid() == false) |
|
777 { |
|
778 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
779 } |
|
780 |
|
781 eap_status_e status = m_saved_data.set_data_length(0ul); |
|
782 |
|
783 return EAP_STATUS_RETURN(m_am_tools, status); |
|
784 } |
|
785 |
|
786 //-------------------------------------------------- |
|
787 /** |
|
788 * This function updates the context of SHA1-algorithm with data. |
|
789 */ |
|
790 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::hash_update( |
|
791 const void * const data, |
|
792 const u32_t data_length) |
|
793 { |
|
794 eap_status_e status = eap_status_ok; |
|
795 u32_t prosessed_data_length = 0ul; |
|
796 |
|
797 |
|
798 m_full_hashed_data_length += data_length; |
|
799 |
|
800 EAP_SHA1_TRACE_DEBUG(m_am_tools, EAP_TRACE_MASK_SHA1, |
|
801 (EAPL("SHA1: Processed data length %u\n"), |
|
802 m_full_hashed_data_length)); |
|
803 |
|
804 if (m_saved_data.get_is_valid_data() == true |
|
805 && m_saved_data.get_data_length() > 0ul) |
|
806 { |
|
807 EAP_SHA1_TRACE_DATA_DEBUG( |
|
808 m_am_tools, |
|
809 EAP_TRACE_MASK_SHA1, |
|
810 (EAPL("SHA1 saved data"), |
|
811 m_saved_data.get_data(m_saved_data.get_data_length()), |
|
812 m_saved_data.get_data_length())); |
|
813 |
|
814 // Here we have remaining data to process from previous call |
|
815 // of hash_update(). |
|
816 u32_t needed_data_length = EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE |
|
817 - m_saved_data.get_data_length(); |
|
818 if (needed_data_length > data_length) |
|
819 { |
|
820 // Not enough input data. |
|
821 needed_data_length = data_length; |
|
822 } |
|
823 |
|
824 prosessed_data_length = needed_data_length; |
|
825 status = m_saved_data.add_data(data, needed_data_length); |
|
826 if (status != eap_status_ok) |
|
827 { |
|
828 return EAP_STATUS_RETURN(m_am_tools, status); |
|
829 } |
|
830 |
|
831 if (m_saved_data.get_data_length() |
|
832 == EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE) |
|
833 { |
|
834 // Enough data to process. |
|
835 // Just one block of integers in W array. |
|
836 |
|
837 status = eap_sha1_process_data_network_order( |
|
838 reinterpret_cast<const u32_t *>( |
|
839 m_saved_data.get_data( |
|
840 m_saved_data.get_data_length())), |
|
841 EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT |
|
842 ); |
|
843 |
|
844 if (status != eap_status_ok) |
|
845 { |
|
846 return EAP_STATUS_RETURN(m_am_tools, status); |
|
847 } |
|
848 |
|
849 // This is optimization of buffer allocations. |
|
850 status = m_saved_data.set_data_length(0ul); |
|
851 if (status != eap_status_ok) |
|
852 { |
|
853 return EAP_STATUS_RETURN(m_am_tools, status); |
|
854 } |
|
855 } |
|
856 |
|
857 EAP_ASSERT(m_saved_data.get_is_valid_data() == false |
|
858 || m_saved_data.get_data_length() |
|
859 <= EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE); |
|
860 |
|
861 } |
|
862 |
|
863 u32_t remaining_data_length = data_length - prosessed_data_length; |
|
864 u32_t full_block_count = remaining_data_length |
|
865 / EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE; |
|
866 |
|
867 if (full_block_count > 0ul) |
|
868 { |
|
869 // Here we have full blocks to process. |
|
870 status = eap_sha1_process_data_network_order( |
|
871 reinterpret_cast<const u32_t *>( |
|
872 static_cast<const u8_t *>(data)+prosessed_data_length), |
|
873 full_block_count * EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT |
|
874 ); |
|
875 |
|
876 if (status != eap_status_ok) |
|
877 { |
|
878 return EAP_STATUS_RETURN(m_am_tools, status); |
|
879 } |
|
880 |
|
881 prosessed_data_length += sizeof(u32_t) * full_block_count |
|
882 * EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT; |
|
883 } |
|
884 if (data_length > prosessed_data_length) |
|
885 { |
|
886 // Save the remaining data. |
|
887 status = m_saved_data.add_data( |
|
888 static_cast<const u8_t *>(data)+prosessed_data_length, |
|
889 data_length-prosessed_data_length); |
|
890 if (status != eap_status_ok) |
|
891 { |
|
892 return EAP_STATUS_RETURN(m_am_tools, status); |
|
893 } |
|
894 } |
|
895 |
|
896 return EAP_STATUS_RETURN(m_am_tools, status); |
|
897 } |
|
898 |
|
899 //-------------------------------------------------- |
|
900 |
|
901 /** |
|
902 * This function writes the message digest to buffer. |
|
903 * @param Length is set if md_length_or_null is non-NULL. |
|
904 */ |
|
905 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::hash_final( |
|
906 void * const message_digest, |
|
907 u32_t *md_length_or_null) |
|
908 { |
|
909 eap_status_e status = eap_status_ok; |
|
910 |
|
911 if (message_digest == 0) |
|
912 { |
|
913 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
914 } |
|
915 |
|
916 if (m_saved_data.get_is_valid_data() == true) |
|
917 { |
|
918 EAP_SHA1_TRACE_DATA_DEBUG( |
|
919 m_am_tools, |
|
920 EAP_TRACE_MASK_SHA1, |
|
921 (EAPL("SHA1 saved data"), |
|
922 m_saved_data.get_data(m_saved_data.get_data_length()), |
|
923 m_saved_data.get_data_length())); |
|
924 } |
|
925 |
|
926 // First add the one bit. We use one byte 0x80. |
|
927 u8_t bit_pad = 0x80; |
|
928 status = m_saved_data.add_data(&bit_pad, sizeof(bit_pad)); |
|
929 if (status != eap_status_ok) |
|
930 { |
|
931 return EAP_STATUS_RETURN(m_am_tools, status); |
|
932 } |
|
933 |
|
934 // Here we may have remaining data to process from previous call |
|
935 // of hash_update(). |
|
936 u32_t min_data_length = m_saved_data.get_data_length() + sizeof(u64_t); |
|
937 u32_t padding_zero_count = 0ul; |
|
938 u32_t block_count = min_data_length / EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE; |
|
939 if ((min_data_length % EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE) != 0) |
|
940 { |
|
941 // Last block is not full. |
|
942 ++block_count; |
|
943 } |
|
944 padding_zero_count = (block_count*EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE) |
|
945 - min_data_length; |
|
946 |
|
947 // Now we need to pad the remaining data. |
|
948 u32_t data_length = m_saved_data.get_data_length(); |
|
949 status = m_saved_data.set_buffer_length(data_length+padding_zero_count); |
|
950 if (status != eap_status_ok) |
|
951 { |
|
952 return EAP_STATUS_RETURN(m_am_tools, status); |
|
953 } |
|
954 m_saved_data.set_data_length(data_length+padding_zero_count); |
|
955 |
|
956 u8_t * const padding = m_saved_data.get_data_offset(data_length, padding_zero_count); |
|
957 if (padding == 0) |
|
958 { |
|
959 return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); |
|
960 } |
|
961 |
|
962 m_am_tools->memset( |
|
963 padding, |
|
964 0, |
|
965 padding_zero_count); |
|
966 |
|
967 // And finally the length of the hashed data is added to block. |
|
968 // Note the length is in bits. |
|
969 u64_t full_hashed_data_length_in_network_order |
|
970 = eap_htonll(eap_shift_left_64_bit(m_full_hashed_data_length, 3ul)); |
|
971 status = m_saved_data.add_data( |
|
972 &full_hashed_data_length_in_network_order, |
|
973 sizeof(full_hashed_data_length_in_network_order)); |
|
974 if (status != eap_status_ok) |
|
975 { |
|
976 return EAP_STATUS_RETURN(m_am_tools, status); |
|
977 } |
|
978 |
|
979 EAP_ASSERT(m_saved_data.get_data_length() |
|
980 >= EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE |
|
981 && (m_saved_data.get_data_length() |
|
982 % EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE) == 0); |
|
983 |
|
984 u32_t full_block_count = m_saved_data.get_data_length() |
|
985 / EAP_AM_CRYPTO_SHA1_BLOCK_BYTE_SIZE; |
|
986 |
|
987 status = eap_sha1_process_data_network_order( |
|
988 reinterpret_cast<const u32_t *>( |
|
989 m_saved_data.get_data( |
|
990 m_saved_data.get_data_length())), |
|
991 full_block_count * EAP_AM_CRYPTO_SHA1_BLOCK_u32_COUNT |
|
992 ); |
|
993 if (status != eap_status_ok) |
|
994 { |
|
995 return EAP_STATUS_RETURN(m_am_tools, status); |
|
996 } |
|
997 |
|
998 // This is optimization of buffer allocations. |
|
999 status = m_saved_data.set_data_length(0ul); |
|
1000 if (status != eap_status_ok) |
|
1001 { |
|
1002 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1003 } |
|
1004 |
|
1005 |
|
1006 u32_t output_length = 0ul; |
|
1007 if (md_length_or_null == 0) |
|
1008 { |
|
1009 // Let's use temporary length variable. |
|
1010 output_length = EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE; |
|
1011 md_length_or_null = &output_length; |
|
1012 } |
|
1013 |
|
1014 status = copy_message_digest( |
|
1015 message_digest, |
|
1016 md_length_or_null); |
|
1017 if (status != eap_status_ok) |
|
1018 { |
|
1019 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1020 } |
|
1021 |
|
1022 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1023 } |
|
1024 |
|
1025 //-------------------------------------------------- |
|
1026 |
|
1027 /** |
|
1028 * This function cleans up the SHA1 context. |
|
1029 */ |
|
1030 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::hash_cleanup() |
|
1031 { |
|
1032 m_saved_data.reset(); |
|
1033 |
|
1034 m_full_hashed_data_length = 0ul; |
|
1035 |
|
1036 m_am_tools->memset(m_H, 0, EAP_AM_CRYPTO_SHA1_DIGEST_BUFFER_BYTE_SIZE); |
|
1037 |
|
1038 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1039 } |
|
1040 |
|
1041 //-------------------------------------------------- |
|
1042 |
|
1043 /** |
|
1044 * This function copies the context of SHA1. |
|
1045 */ |
|
1046 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_sha1_c::copy_context( |
|
1047 const eap_variable_data_c * const saved_data, |
|
1048 const u64_t full_hashed_data_length, |
|
1049 const u32_t * const H, |
|
1050 const u32_t * const T, |
|
1051 const u32_t * const W_in_host_order) |
|
1052 { |
|
1053 if (saved_data->get_is_valid_data() == true) |
|
1054 { |
|
1055 eap_status_e status = m_saved_data.set_copy_of_buffer(saved_data); |
|
1056 if (status != eap_status_ok) |
|
1057 { |
|
1058 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1059 } |
|
1060 } |
|
1061 else |
|
1062 { |
|
1063 // No saved data. Just reset. |
|
1064 m_saved_data.reset(); |
|
1065 } |
|
1066 |
|
1067 m_full_hashed_data_length = full_hashed_data_length; |
|
1068 |
|
1069 m_am_tools->memmove(m_H, H, sizeof(m_H)); |
|
1070 |
|
1071 m_am_tools->memmove(m_T, T, sizeof(m_T)); |
|
1072 |
|
1073 m_am_tools->memmove(m_W_in_host_order, W_in_host_order, sizeof(m_W_in_host_order)); |
|
1074 |
|
1075 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1076 } |
|
1077 |
|
1078 //-------------------------------------------------- |
|
1079 |
|
1080 /** |
|
1081 * This function copies the context of SHA1. |
|
1082 */ |
|
1083 EAP_FUNC_EXPORT eap_am_crypto_sha1_c * eap_am_crypto_sha1_c::copy() |
|
1084 { |
|
1085 eap_am_crypto_sha1_c * const sha1 = new eap_am_crypto_sha1_c(m_am_tools); |
|
1086 if (sha1 == 0 |
|
1087 || sha1->get_is_valid() == false) |
|
1088 { |
|
1089 delete sha1; |
|
1090 return 0; |
|
1091 } |
|
1092 |
|
1093 eap_status_e status = sha1->copy_context( |
|
1094 &m_saved_data, |
|
1095 m_full_hashed_data_length, |
|
1096 m_H, |
|
1097 m_T, |
|
1098 m_W_in_host_order); |
|
1099 if (status != eap_status_ok) |
|
1100 { |
|
1101 delete sha1; |
|
1102 return 0; |
|
1103 } |
|
1104 |
|
1105 return sha1; |
|
1106 } |
|
1107 |
|
1108 //-------------------------------------------------- |
|
1109 |
|
1110 |
|
1111 |
|
1112 // End. |