1 /*
2  * SHA1 functions
3  *
4  * Copyright (C) 2011-2020, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 #include <byte_stream.h>
24 #include <memory.h>
25 #include <types.h>
26 
27 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_SHA_H )
28 #include <openssl/sha.h>
29 
30 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H )
31 #include <openssl/err.h>
32 #include <openssl/evp.h>
33 
34 #endif
35 
36 #include "libhmac_byte_stream.h"
37 #include "libhmac_definitions.h"
38 #include "libhmac_libcerror.h"
39 #include "libhmac_sha1.h"
40 
41 #if !defined( LIBHMAC_HAVE_SHA1_SUPPORT )
42 
43 /* RFC 3174/FIPS 180-1 based SHA-1 functions
44  */
45 
46 /* TODO decription what these values are based on
47  */
48 uint32_t libhmac_sha1_fixed_constants[ 5 ] = {
49 	0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL
50 };
51 
52 #define libhmac_sha1_transform_extend_32bit_value( values_32bit, value_32bit_index ) \
53 	values_32bit[ value_32bit_index ] = values_32bit[ value_32bit_index - 3 ] \
54 	                                  ^ values_32bit[ value_32bit_index - 8 ] \
55 	                                  ^ values_32bit[ value_32bit_index - 14 ] \
56 	                                  ^ values_32bit[ value_32bit_index - 16 ]; \
57 	values_32bit[ value_32bit_index ] = byte_stream_bit_rotate_left_32bit( \
58 	                                     values_32bit[ value_32bit_index ], \
59 	                                     1 );
60 
61 #define libhmac_sha1_transform_unfolded_extend_32bit_values( values_32bit ) \
62 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 16 ); \
63 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 17 ); \
64 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 18 ); \
65 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 19 ); \
66 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 20 ); \
67 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 21 ); \
68 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 22 ); \
69 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 23 ); \
70 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 24 ); \
71 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 25 ); \
72 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 26 ); \
73 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 27 ); \
74 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 28 ); \
75 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 29 ); \
76 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 30 ); \
77 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 31 ); \
78 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 32 ); \
79 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 33 ); \
80 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 34 ); \
81 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 35 ); \
82 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 36 ); \
83 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 37 ); \
84 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 38 ); \
85 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 39 ); \
86 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 40 ); \
87 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 41 ); \
88 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 42 ); \
89 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 43 ); \
90 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 44 ); \
91 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 45 ); \
92 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 46 ); \
93 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 47 ); \
94 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 48 ); \
95 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 49 ); \
96 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 50 ); \
97 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 51 ); \
98 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 52 ); \
99 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 53 ); \
100 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 54 ); \
101 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 55 ); \
102 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 56 ); \
103 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 57 ); \
104 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 58 ); \
105 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 59 ); \
106 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 60 ); \
107 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 61 ); \
108 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 62 ); \
109 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 63 ); \
110 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 64 ); \
111 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 65 ); \
112 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 66 ); \
113 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 67 ); \
114 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 68 ); \
115 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 69 ); \
116 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 70 ); \
117 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 71 ); \
118 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 72 ); \
119 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 73 ); \
120 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 74 ); \
121 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 75 ); \
122 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 76 ); \
123 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 77 ); \
124 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 78 ); \
125 	libhmac_sha1_transform_extend_32bit_value( values_32bit, 79 );
126 
127 #define libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, value_32bit_index, hash_values, hash_value_index0, hash_value_index1, hash_value_index2, hash_value_index3, hash_value_index4 ) \
128 	hash_values[ hash_value_index4 ] += ( hash_values[ hash_value_index1 ] & hash_values[ hash_value_index2 ] ) \
129 	                                  | ( ~( hash_values[ hash_value_index1 ] ) & hash_values[ hash_value_index3 ] ); \
130 	hash_values[ hash_value_index4 ] += 0x5a827999UL; \
131 	hash_values[ hash_value_index4 ] += byte_stream_bit_rotate_left_32bit( \
132 	                                     hash_values[ hash_value_index0 ], \
133 	                                     5 ); \
134 	hash_values[ hash_value_index4 ] += values_32bit[ value_32bit_index ]; \
135 \
136 	hash_values[ hash_value_index1 ] = byte_stream_bit_rotate_left_32bit( \
137 	                                    hash_values[ hash_value_index1 ], \
138 			                    30 );
139 
140 #define libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, value_32bit_index, hash_values, hash_value_index0, hash_value_index1, hash_value_index2, hash_value_index3, hash_value_index4 ) \
141 	hash_values[ hash_value_index4 ] += hash_values[ hash_value_index1 ] \
142 	                                  ^ hash_values[ hash_value_index2 ] \
143 	                                  ^ hash_values[ hash_value_index3 ]; \
144 	hash_values[ hash_value_index4 ] += 0x6ed9eba1UL; \
145 	hash_values[ hash_value_index4 ] += byte_stream_bit_rotate_left_32bit( \
146 	                                     hash_values[ hash_value_index0 ], \
147 	                                     5 ); \
148 	hash_values[ hash_value_index4 ] += values_32bit[ value_32bit_index ]; \
149 \
150 	hash_values[ hash_value_index1 ] = byte_stream_bit_rotate_left_32bit( \
151 	                                    hash_values[ hash_value_index1 ], \
152 			                    30 );
153 
154 #define libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, value_32bit_index, hash_values, hash_value_index0, hash_value_index1, hash_value_index2, hash_value_index3, hash_value_index4 ) \
155 	hash_values[ hash_value_index4 ] += ( hash_values[ hash_value_index1 ] & hash_values[ hash_value_index2 ] ) \
156 	                                  | ( hash_values[ hash_value_index1 ] & hash_values[ hash_value_index3 ] ) \
157 	                                  | ( hash_values[ hash_value_index2 ] & hash_values[ hash_value_index3 ] ); \
158 	hash_values[ hash_value_index4 ] += 0x8f1bbcdcUL; \
159 	hash_values[ hash_value_index4 ] += byte_stream_bit_rotate_left_32bit( \
160 	                                     hash_values[ hash_value_index0 ], \
161 	                                     5 ); \
162 	hash_values[ hash_value_index4 ] += values_32bit[ value_32bit_index ]; \
163 \
164 	hash_values[ hash_value_index1 ] = byte_stream_bit_rotate_left_32bit( \
165 	                                    hash_values[ hash_value_index1 ], \
166 			                    30 );
167 
168 #define libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, value_32bit_index, hash_values, hash_value_index0, hash_value_index1, hash_value_index2, hash_value_index3, hash_value_index4 ) \
169 	hash_values[ hash_value_index4 ] += hash_values[ hash_value_index1 ] \
170 	                                  ^ hash_values[ hash_value_index2 ] \
171 	                                  ^ hash_values[ hash_value_index3 ]; \
172 	hash_values[ hash_value_index4 ] += 0xca62c1d6UL; \
173 	hash_values[ hash_value_index4 ] += byte_stream_bit_rotate_left_32bit( \
174 	                                     hash_values[ hash_value_index0 ], \
175 	                                     5 ); \
176 	hash_values[ hash_value_index4 ] += values_32bit[ value_32bit_index ]; \
177 \
178 	hash_values[ hash_value_index1 ] = byte_stream_bit_rotate_left_32bit( \
179 	                                    hash_values[ hash_value_index1 ], \
180 			                    30 );
181 
182 #define libhmac_sha1_transform_unfolded_calculate_hash_values( values_32bit, hash_values ) \
183         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 0, hash_values, 0, 1, 2, 3, 4 ); \
184         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 1, hash_values, 4, 0, 1, 2, 3 ); \
185         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 2, hash_values, 3 ,4, 0, 1, 2 ); \
186         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 3, hash_values, 2, 3, 4, 0, 1 ); \
187         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 4, hash_values, 1, 2, 3, 4, 0 ); \
188         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 5, hash_values, 0, 1, 2, 3, 4 ); \
189         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 6, hash_values, 4, 0, 1, 2, 3 ); \
190         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 7, hash_values, 3 ,4, 0, 1, 2 ); \
191         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 8, hash_values, 2, 3, 4, 0, 1 ); \
192         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 9, hash_values, 1, 2, 3, 4, 0 ); \
193         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 10, hash_values, 0, 1, 2, 3, 4 ); \
194         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 11, hash_values, 4, 0, 1, 2, 3 ); \
195         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 12, hash_values, 3 ,4, 0, 1, 2 ); \
196         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 13, hash_values, 2, 3, 4, 0, 1 ); \
197         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 14, hash_values, 1, 2, 3, 4, 0 ); \
198         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 15, hash_values, 0, 1, 2, 3, 4 ); \
199         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 16, hash_values, 4, 0, 1, 2, 3 ); \
200         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 17, hash_values, 3 ,4, 0, 1, 2 ); \
201         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 18, hash_values, 2, 3, 4, 0, 1 ); \
202         libhmac_sha1_transform_unfolded_calculate_hash_value_round1( values_32bit, 19, hash_values, 1, 2, 3, 4, 0 ); \
203 \
204         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 20, hash_values, 0, 1, 2, 3, 4 ); \
205         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 21, hash_values, 4, 0, 1, 2, 3 ); \
206         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 22, hash_values, 3 ,4, 0, 1, 2 ); \
207         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 23, hash_values, 2, 3, 4, 0, 1 ); \
208         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 24, hash_values, 1, 2, 3, 4, 0 ); \
209         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 25, hash_values, 0, 1, 2, 3, 4 ); \
210         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 26, hash_values, 4, 0, 1, 2, 3 ); \
211         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 27, hash_values, 3 ,4, 0, 1, 2 ); \
212         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 28, hash_values, 2, 3, 4, 0, 1 ); \
213         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 29, hash_values, 1, 2, 3, 4, 0 ); \
214         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 30, hash_values, 0, 1, 2, 3, 4 ); \
215         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 31, hash_values, 4, 0, 1, 2, 3 ); \
216         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 32, hash_values, 3 ,4, 0, 1, 2 ); \
217         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 33, hash_values, 2, 3, 4, 0, 1 ); \
218         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 34, hash_values, 1, 2, 3, 4, 0 ); \
219         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 35, hash_values, 0, 1, 2, 3, 4 ); \
220         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 36, hash_values, 4, 0, 1, 2, 3 ); \
221         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 37, hash_values, 3 ,4, 0, 1, 2 ); \
222         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 38, hash_values, 2, 3, 4, 0, 1 ); \
223         libhmac_sha1_transform_unfolded_calculate_hash_value_round2( values_32bit, 39, hash_values, 1, 2, 3, 4, 0 ); \
224 \
225         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 40, hash_values, 0, 1, 2, 3, 4 ); \
226         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 41, hash_values, 4, 0, 1, 2, 3 ); \
227         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 42, hash_values, 3 ,4, 0, 1, 2 ); \
228         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 43, hash_values, 2, 3, 4, 0, 1 ); \
229         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 44, hash_values, 1, 2, 3, 4, 0 ); \
230         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 45, hash_values, 0, 1, 2, 3, 4 ); \
231         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 46, hash_values, 4, 0, 1, 2, 3 ); \
232         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 47, hash_values, 3 ,4, 0, 1, 2 ); \
233         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 48, hash_values, 2, 3, 4, 0, 1 ); \
234         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 49, hash_values, 1, 2, 3, 4, 0 ); \
235         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 50, hash_values, 0, 1, 2, 3, 4 ); \
236         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 51, hash_values, 4, 0, 1, 2, 3 ); \
237         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 52, hash_values, 3 ,4, 0, 1, 2 ); \
238         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 53, hash_values, 2, 3, 4, 0, 1 ); \
239         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 54, hash_values, 1, 2, 3, 4, 0 ); \
240         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 55, hash_values, 0, 1, 2, 3, 4 ); \
241         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 56, hash_values, 4, 0, 1, 2, 3 ); \
242         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 57, hash_values, 3 ,4, 0, 1, 2 ); \
243         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 58, hash_values, 2, 3, 4, 0, 1 ); \
244         libhmac_sha1_transform_unfolded_calculate_hash_value_round3( values_32bit, 59, hash_values, 1, 2, 3, 4, 0 ); \
245 \
246         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 60, hash_values, 0, 1, 2, 3, 4 ); \
247         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 61, hash_values, 4, 0, 1, 2, 3 ); \
248         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 62, hash_values, 3 ,4, 0, 1, 2 ); \
249         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 63, hash_values, 2, 3, 4, 0, 1 ); \
250         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 64, hash_values, 1, 2, 3, 4, 0 ); \
251         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 65, hash_values, 0, 1, 2, 3, 4 ); \
252         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 66, hash_values, 4, 0, 1, 2, 3 ); \
253         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 67, hash_values, 3 ,4, 0, 1, 2 ); \
254         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 68, hash_values, 2, 3, 4, 0, 1 ); \
255         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 69, hash_values, 1, 2, 3, 4, 0 ); \
256         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 70, hash_values, 0, 1, 2, 3, 4 ); \
257         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 71, hash_values, 4, 0, 1, 2, 3 ); \
258         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 72, hash_values, 3 ,4, 0, 1, 2 ); \
259         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 73, hash_values, 2, 3, 4, 0, 1 ); \
260         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 74, hash_values, 1, 2, 3, 4, 0 ); \
261         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 75, hash_values, 0, 1, 2, 3, 4 ); \
262         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 76, hash_values, 4, 0, 1, 2, 3 ); \
263         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 77, hash_values, 3 ,4, 0, 1, 2 ); \
264         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 78, hash_values, 2, 3, 4, 0, 1 ); \
265         libhmac_sha1_transform_unfolded_calculate_hash_value_round4( values_32bit, 79, hash_values, 1, 2, 3, 4, 0 );
266 
267 /* Calculates the SHA1 of 64 byte sized blocks of data in a buffer
268  * Returns the number of bytes used if successful or -1 on error
269  */
libhmac_sha1_transform(libhmac_internal_sha1_context_t * internal_context,const uint8_t * buffer,size_t size,libcerror_error_t ** error)270 ssize_t libhmac_sha1_transform(
271          libhmac_internal_sha1_context_t *internal_context,
272          const uint8_t *buffer,
273          size_t size,
274          libcerror_error_t **error )
275 {
276 	uint32_t hash_values[ 5 ];
277 	uint32_t values_32bit[ 80 ];
278 
279 	static char *function     = "libhmac_sha1_transform";
280 	size_t buffer_offset      = 0;
281 
282 #if !defined( LIBHMAC_UNFOLLED_LOOPS )
283 	uint32_t hash_value       = 0;
284 	uint8_t hash_values_index = 0;
285 	uint8_t value_32bit_index = 0;
286 #endif
287 
288 	if( internal_context == NULL )
289 	{
290 		libcerror_error_set(
291 		 error,
292 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
293 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
294 		 "%s: invalid internal context.",
295 		 function );
296 
297 		return( -1 );
298 	}
299 	if( buffer == NULL )
300 	{
301 		libcerror_error_set(
302 		 error,
303 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
304 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
305 		 "%s: invalid buffer.",
306 		 function );
307 
308 		return( -1 );
309 	}
310 	if( size > (size_t) SSIZE_MAX )
311 	{
312 		libcerror_error_set(
313 		 error,
314 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
315 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
316 		 "%s: invalid size value exceeds maximum.",
317 		 function );
318 
319 		return( -1 );
320 	}
321 	while( size >= LIBHMAC_SHA1_BLOCK_SIZE )
322 	{
323 		if( memory_copy(
324 		     hash_values,
325 		     internal_context->hash_values,
326 		     sizeof( uint32_t ) * 5 ) == NULL )
327 		{
328 			libcerror_error_set(
329 			 error,
330 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
331 			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
332 			 "%s: unable to copy hash values.",
333 			 function );
334 
335 			goto on_error;
336 		}
337 #if defined( LIBHMAC_UNFOLLED_LOOPS )
338 		/* Break the block into 16 x 32-bit values
339 		 */
340 		libhmac_byte_stream_copy_to_16x_uint32_big_endian(
341 		 &( buffer[ buffer_offset ] ),
342 		 values_32bit );
343 
344 		buffer_offset += LIBHMAC_SHA1_BLOCK_SIZE;
345 
346 		/* Extend to 80 x 32-bit values
347 		 */
348 		libhmac_sha1_transform_unfolded_extend_32bit_values(
349 		 values_32bit );
350 
351 		/* Calculate the hash values for the 32-bit values
352 		 */
353 		libhmac_sha1_transform_unfolded_calculate_hash_values(
354 		 values_32bit,
355 		 hash_values );
356 
357 		/* Update the hash values in the context
358 		 */
359 		internal_context->hash_values[ 0 ] += hash_values[ 0 ];
360 		internal_context->hash_values[ 1 ] += hash_values[ 1 ];
361 		internal_context->hash_values[ 2 ] += hash_values[ 2 ];
362 		internal_context->hash_values[ 3 ] += hash_values[ 3 ];
363 		internal_context->hash_values[ 4 ] += hash_values[ 4 ];
364 #else
365 		/* Break the block into 16 x 32-bit values
366 		 */
367 		for( value_32bit_index = 0;
368 		     value_32bit_index < 16;
369 		     value_32bit_index++ )
370 		{
371 			byte_stream_copy_to_uint32_big_endian(
372 			 &( buffer[ buffer_offset ] ),
373 			 values_32bit[ value_32bit_index ] );
374 
375 			buffer_offset += sizeof( uint32_t );
376 		}
377 		/* Extend to 80 x 32-bit values
378 		 */
379 		for( value_32bit_index = 16;
380 		     value_32bit_index < 80;
381 		     value_32bit_index++ )
382 		{
383 			libhmac_sha1_transform_extend_32bit_value(
384 			 values_32bit,
385 			 value_32bit_index );
386 		}
387 		/* Calculate the hash values for the 32-bit values
388 		 */
389 		for( value_32bit_index = 0;
390 		     value_32bit_index < 80;
391 		     value_32bit_index++ )
392 		{
393 			if( value_32bit_index < 20 )
394 			{
395 				hash_values[ 4 ] += ( hash_values[ 1 ] & hash_values[ 2 ] )
396 				                  | ( ~( hash_values[ 1 ] ) & hash_values[ 3 ] );
397 				hash_values[ 4 ] += 0x5a827999UL;
398 			}
399 			else if( value_32bit_index < 40 )
400 			{
401 				hash_values[ 4 ] += hash_values[ 1 ]
402 				                  ^ hash_values[ 2 ]
403 				                  ^ hash_values[ 3 ];
404 				hash_values[ 4 ] += 0x6ed9eba1UL;
405 			}
406 			else if( value_32bit_index < 60 )
407 			{
408 				hash_values[ 4 ] += ( hash_values[ 1 ] & hash_values[ 2 ] )
409 				                  | ( hash_values[ 1 ] & hash_values[ 3 ] )
410 				                  | ( hash_values[ 2 ] & hash_values[ 3 ] );
411 				hash_values[ 4 ] += 0x8f1bbcdcUL;
412 			}
413 			else
414 			{
415 				hash_values[ 4 ] += hash_values[ 1 ]
416 				                  ^ hash_values[ 2 ]
417 				                  ^ hash_values[ 3 ];
418 				hash_values[ 4 ] += 0xca62c1d6UL;
419 			}
420 			hash_values[ 4 ] += byte_stream_bit_rotate_left_32bit(
421 			                     hash_values[ 0 ],
422 			                     5 );
423 			hash_values[ 4 ] += values_32bit[ value_32bit_index ];
424 
425 			hash_value       = hash_values[ 4 ];
426 			hash_values[ 4 ] = hash_values[ 3 ];
427 			hash_values[ 3 ] = hash_values[ 2 ];
428 			hash_values[ 2 ] = byte_stream_bit_rotate_left_32bit(
429 			                    hash_values[ 1 ],
430 			                    30 );
431 			hash_values[ 1 ] = hash_values[ 0 ];
432 			hash_values[ 0 ] = hash_value;
433 		}
434 		/* Update the hash values in the context
435 		 */
436 		for( hash_values_index = 0;
437 		     hash_values_index < 5;
438 		     hash_values_index++ )
439 		{
440 			internal_context->hash_values[ hash_values_index ] += hash_values[ hash_values_index ];
441 		}
442 #endif /* defined( LIBHMAC_UNFOLLED_LOOPS ) */
443 
444 		size -= LIBHMAC_SHA1_BLOCK_SIZE;
445 	}
446 	/* Prevent sensitive data from leaking
447 	 */
448 	if( memory_set(
449 	     hash_values,
450 	     0,
451 	     sizeof( uint32_t ) * 5 ) == NULL )
452 	{
453 		libcerror_error_set(
454 		 error,
455 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
456 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
457 		 "%s: unable to clear hash values.",
458 		 function );
459 
460 		goto on_error;
461 	}
462 	if( memory_set(
463 	     values_32bit,
464 	     0,
465 	     sizeof( uint32_t ) * 16 ) == NULL )
466 	{
467 		libcerror_error_set(
468 		 error,
469 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
470 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
471 		 "%s: unable to clear 32-bit values.",
472 		 function );
473 
474 		goto on_error;
475 	}
476 	return( (ssize_t) buffer_offset );
477 
478 on_error:
479 	memory_set(
480 	 values_32bit,
481 	 0,
482 	 sizeof( uint32_t ) * 64 );
483 
484 	memory_set(
485 	 hash_values,
486 	 0,
487 	 sizeof( uint32_t ) * 5 );
488 
489 	return( -1 );
490 }
491 
492 #endif /* !defined( LIBHMAC_HAVE_SHA1_SUPPORT ) */
493 
494 /* Creates a SHA1 context
495  * Make sure the value context is referencing, is set to NULL
496  * Returns 1 if successful or -1 on error
497  */
libhmac_sha1_initialize(libhmac_sha1_context_t ** context,libcerror_error_t ** error)498 int libhmac_sha1_initialize(
499      libhmac_sha1_context_t **context,
500      libcerror_error_t **error )
501 {
502 	libhmac_internal_sha1_context_t *internal_context = NULL;
503 	static char *function                             = "libhmac_sha1_initialize";
504 
505 	if( context == NULL )
506 	{
507 		libcerror_error_set(
508 		 error,
509 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
510 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
511 		 "%s: invalid context.",
512 		 function );
513 
514 		return( -1 );
515 	}
516 	if( *context != NULL )
517 	{
518 		libcerror_error_set(
519 		 error,
520 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
521 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
522 		 "%s: invalid context value already set.",
523 		 function );
524 
525 		return( -1 );
526 	}
527 	internal_context = memory_allocate_structure(
528 	                    libhmac_internal_sha1_context_t );
529 
530 	if( internal_context == NULL )
531 	{
532 		libcerror_error_set(
533 		 error,
534 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
535 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
536 		 "%s: unable to create context.",
537 		 function );
538 
539 		goto on_error;
540 	}
541 	if( memory_set(
542 	     internal_context,
543 	     0,
544 	     sizeof( libhmac_internal_sha1_context_t ) ) == NULL )
545 	{
546 		libcerror_error_set(
547 		 error,
548 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
549 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
550 		 "%s: unable to clear context.",
551 		 function );
552 
553 		memory_free(
554 		 internal_context );
555 
556 		return( -1 );
557 	}
558 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_SHA_H ) && defined( SHA_DIGEST_LENGTH )
559 	if( SHA1_Init(
560 	     &( internal_context->sha1_context ) ) != 1 )
561 	{
562 		libcerror_error_set(
563 		 error,
564 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
565 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
566 		 "%s: unable to initialize context.",
567 		 function );
568 
569 		goto on_error;
570 	}
571 
572 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_SHA1 )
573 #if defined( HAVE_EVP_MD_CTX_INIT )
574 	EVP_MD_CTX_init(
575 	 &( internal_context->internal_evp_md_context ) );
576 
577 	internal_context->evp_md_context = &( internal_context->internal_evp_md_context );
578 #else
579 	internal_context->evp_md_context = EVP_MD_CTX_new();
580 
581 	if( internal_context->evp_md_context == NULL )
582 	{
583 		libcerror_error_set(
584 		 error,
585 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
586 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
587 		 "%s: unable to create EVP message digest context.",
588 		 function );
589 
590 		goto on_error;
591 	}
592 #endif /* defined( HAVE_EVP_MD_CTX_INIT ) */
593 
594 	if( EVP_DigestInit_ex(
595 	     internal_context->evp_md_context,
596 	     EVP_sha1(),
597 	     NULL ) != 1 )
598 	{
599 		libcerror_error_set(
600 		 error,
601 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
602 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
603 		 "%s: unable to initialize context.",
604 		 function );
605 
606 #if defined( HAVE_EVP_MD_CTX_CLEANUP )
607 		EVP_MD_CTX_cleanup(
608 		 &( internal_context->internal_evp_md_context ) );
609 		ERR_remove_thread_state(
610 		 NULL );
611 #else
612 		EVP_MD_CTX_free(
613 		 internal_context->evp_md_context );
614 #endif
615 		internal_context->evp_md_context = NULL;
616 
617 		goto on_error;
618 	}
619 #else
620 	if( memory_copy(
621 	     internal_context->hash_values,
622 	     libhmac_sha1_fixed_constants,
623 	     sizeof( uint32_t ) * 5 ) == NULL )
624 	{
625 		libcerror_error_set(
626 		 error,
627 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
628 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
629 		 "%s: unable to copy fixed constants to hash values.",
630 		 function );
631 
632 		goto on_error;
633 	}
634 #endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_SHA_H ) && defined( SHA_DIGEST_LENGTH ) */
635 
636 	*context = (libhmac_sha1_context_t *) internal_context;
637 
638 	return( 1 );
639 
640 on_error:
641 	if( internal_context != NULL )
642 	{
643 		memory_free(
644 		 internal_context );
645 	}
646 	return( -1 );
647 }
648 
649 /* Frees a SHA1 context
650  * Returns 1 if successful or -1 on error
651  */
libhmac_sha1_free(libhmac_sha1_context_t ** context,libcerror_error_t ** error)652 int libhmac_sha1_free(
653      libhmac_sha1_context_t **context,
654      libcerror_error_t **error )
655 {
656 	libhmac_internal_sha1_context_t *internal_context = NULL;
657 	static char *function                             = "libhmac_sha1_free";
658 
659 	if( context == NULL )
660 	{
661 		libcerror_error_set(
662 		 error,
663 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
664 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
665 		 "%s: invalid context.",
666 		 function );
667 
668 		return( -1 );
669 	}
670 	if( *context != NULL )
671 	{
672 		internal_context = (libhmac_internal_sha1_context_t *) *context;
673 		*context         = NULL;
674 
675 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_SHA_H ) && defined( SHA_DIGEST_LENGTH )
676 		/* No additional clean up necessary
677 		 */
678 
679 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_SHA1 )
680 #if defined( HAVE_EVP_MD_CTX_CLEANUP )
681 		if( EVP_MD_CTX_cleanup(
682 		     &( internal_context->internal_evp_md_context ) ) != 1 )
683 		{
684 			libcerror_error_set(
685 			 error,
686 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
687 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
688 			 "%s: unable to clean up EVP message digest context.",
689 			 function );
690 		}
691 		/* Make sure the error state is removed otherwise OpenSSL will leak memory
692 		 */
693 		ERR_remove_thread_state(
694 		 NULL );
695 #else
696 		EVP_MD_CTX_free(
697 		 internal_context->evp_md_context );
698 
699 #endif /* defined( HAVE_EVP_MD_CTX_CLEANUP ) */
700 
701 		internal_context->evp_md_context = NULL;
702 #else
703 		/* No additional clean up necessary
704 		 */
705 
706 #endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_SHA_H ) && defined( SHA_DIGEST_LENGTH ) */
707 		memory_free(
708 		 internal_context );
709 	}
710 	return( 1 );
711 }
712 
713 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_SHA_H ) && defined( SHA_DIGEST_LENGTH )
714 
715 /* Updates the SHA1 context using OpenSSL
716  * Returns 1 if successful or -1 on error
717  */
libhmac_sha1_update(libhmac_sha1_context_t * context,const uint8_t * buffer,size_t size,libcerror_error_t ** error)718 int libhmac_sha1_update(
719      libhmac_sha1_context_t *context,
720      const uint8_t *buffer,
721      size_t size,
722      libcerror_error_t **error )
723 {
724 	libhmac_internal_sha1_context_t *internal_context = NULL;
725 	static char *function                             = "libhmac_sha1_update";
726 	unsigned long safe_hash_size                      = 0;
727 
728 	if( context == NULL )
729 	{
730 		libcerror_error_set(
731 		 error,
732 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
733 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
734 		 "%s: invalid context.",
735 		 function );
736 
737 		return( -1 );
738 	}
739 	internal_context = (libhmac_internal_sha1_context_t *) context;
740 
741 	if( buffer == NULL )
742 	{
743 		libcerror_error_set(
744 		 error,
745 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
746 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
747 		 "%s: invalid buffer.",
748 		 function );
749 
750 		return( -1 );
751 	}
752 #if ( SIZEOF_LONG < SIZEOF_SIZE_T )
753 	if( size > (size_t) ULONG_MAX )
754 #else
755 	if( size > (size_t) SSIZE_MAX )
756 #endif
757 	{
758 		libcerror_error_set(
759 		 error,
760 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
761 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
762 		 "%s: invalid size value exceeds maximum.",
763 		 function );
764 
765 		return( -1 );
766 	}
767 	if( size == 0 )
768 	{
769 		return( 1 );
770 	}
771 	safe_hash_size = (unsigned long) size;
772 
773 	if( SHA1_Update(
774 	     &( internal_context->sha1_context ),
775 	     (const void *) buffer,
776 	     size ) != 1 )
777 	{
778 		libcerror_error_set(
779 		 error,
780 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
781 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
782 		 "%s: unable to update context.",
783 		 function );
784 
785 		return( -1 );
786 	}
787 	return( 1 );
788 }
789 
790 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_SHA1 )
791 
792 /* Updates the SHA1 context using OpenSSL EVP
793  * Returns 1 if successful or -1 on error
794  */
libhmac_sha1_update(libhmac_sha1_context_t * context,const uint8_t * buffer,size_t size,libcerror_error_t ** error)795 int libhmac_sha1_update(
796      libhmac_sha1_context_t *context,
797      const uint8_t *buffer,
798      size_t size,
799      libcerror_error_t **error )
800 {
801 	libhmac_internal_sha1_context_t *internal_context = NULL;
802 	static char *function                             = "libhmac_sha1_update";
803 
804 	if( context == NULL )
805 	{
806 		libcerror_error_set(
807 		 error,
808 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
809 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
810 		 "%s: invalid context.",
811 		 function );
812 
813 		return( -1 );
814 	}
815 	internal_context = (libhmac_internal_sha1_context_t *) context;
816 
817 	if( buffer == NULL )
818 	{
819 		libcerror_error_set(
820 		 error,
821 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
822 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
823 		 "%s: invalid buffer.",
824 		 function );
825 
826 		return( -1 );
827 	}
828 	if( size > (size_t) SSIZE_MAX )
829 	{
830 		libcerror_error_set(
831 		 error,
832 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
833 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
834 		 "%s: invalid size value exceeds maximum.",
835 		 function );
836 
837 		return( -1 );
838 	}
839 	if( size == 0 )
840 	{
841 		return( 1 );
842 	}
843 	if( EVP_DigestUpdate(
844 	     internal_context->evp_md_context,
845 	     (const void *) buffer,
846 	     size ) != 1 )
847 	{
848 		libcerror_error_set(
849 		 error,
850 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
851 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
852 		 "%s: unable to update context.",
853 		 function );
854 
855 		return( -1 );
856 	}
857 	return( 1 );
858 }
859 
860 #else
861 
862 /* Updates the SHA1 context using fallback implementation
863  * Returns 1 if successful or -1 on error
864  */
libhmac_sha1_update(libhmac_sha1_context_t * context,const uint8_t * buffer,size_t size,libcerror_error_t ** error)865 int libhmac_sha1_update(
866      libhmac_sha1_context_t *context,
867      const uint8_t *buffer,
868      size_t size,
869      libcerror_error_t **error )
870 {
871 	libhmac_internal_sha1_context_t *internal_context = NULL;
872 	static char *function                             = "libhmac_sha1_update";
873 	size_t buffer_offset                              = 0;
874 	size_t remaining_block_size                       = 0;
875 	ssize_t process_count                             = 0;
876 
877 	if( context == NULL )
878 	{
879 		libcerror_error_set(
880 		 error,
881 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
882 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
883 		 "%s: invalid context.",
884 		 function );
885 
886 		return( -1 );
887 	}
888 	internal_context = (libhmac_internal_sha1_context_t *) context;
889 
890 	if( buffer == NULL )
891 	{
892 		libcerror_error_set(
893 		 error,
894 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
895 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
896 		 "%s: invalid buffer.",
897 		 function );
898 
899 		return( -1 );
900 	}
901 	if( size > (size_t) SSIZE_MAX )
902 	{
903 		libcerror_error_set(
904 		 error,
905 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
906 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
907 		 "%s: invalid size value exceeds maximum.",
908 		 function );
909 
910 		return( -1 );
911 	}
912 	if( size == 0 )
913 	{
914 		return( 1 );
915 	}
916 	if( internal_context->block_offset > 0 )
917 	{
918 		remaining_block_size = LIBHMAC_SHA1_BLOCK_SIZE - internal_context->block_offset;
919 
920 		if( remaining_block_size > size )
921 		{
922 			remaining_block_size = size;
923 		}
924 		if( memory_copy(
925 		     &( internal_context->block[ internal_context->block_offset ] ),
926 		     buffer,
927 		     remaining_block_size ) == NULL )
928 		{
929 			libcerror_error_set(
930 			 error,
931 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
932 			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
933 			 "%s: unable to copy data to context block.",
934 			 function );
935 
936 			return( -1 );
937 		}
938 		internal_context->block_offset += remaining_block_size;
939 
940 		if( internal_context->block_offset < LIBHMAC_SHA1_BLOCK_SIZE )
941 		{
942 			return( 1 );
943 		}
944 		buffer_offset += remaining_block_size;
945 		size          -= remaining_block_size;
946 
947 		process_count = libhmac_sha1_transform(
948 		                 internal_context,
949 		                 internal_context->block,
950 		                 LIBHMAC_SHA1_BLOCK_SIZE,
951 		                 error );
952 
953 		if( process_count == -1 )
954 		{
955 			libcerror_error_set(
956 			 error,
957 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
958 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
959 			 "%s: unable to transform context block.",
960 			 function );
961 
962 			return( -1 );
963 		}
964 		internal_context->hash_count  += process_count;
965 		internal_context->block_offset = 0;
966 	}
967 	if( size > 0 )
968 	{
969 		process_count = libhmac_sha1_transform(
970 		                 internal_context,
971 		                 &( buffer[ buffer_offset ] ),
972 		                 size,
973 		                 error );
974 
975 		if( process_count == -1 )
976 		{
977 			libcerror_error_set(
978 			 error,
979 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
980 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
981 			 "%s: unable to transform buffer.",
982 			 function );
983 
984 			return( -1 );
985 		}
986 		internal_context->hash_count += process_count;
987 
988 		buffer_offset += process_count;
989 		size          -= process_count;
990 	}
991 	if( size > 0 )
992 	{
993 		if( size >= LIBHMAC_SHA1_BLOCK_SIZE )
994 		{
995 			libcerror_error_set(
996 			 error,
997 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
998 			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
999 			 "%s: invalid size value out of bounds.",
1000 			 function );
1001 
1002 			return( -1 );
1003 		}
1004 		if( memory_copy(
1005 		     internal_context->block,
1006 		     &( buffer[ buffer_offset ] ),
1007 		     size ) == NULL )
1008 		{
1009 			libcerror_error_set(
1010 			 error,
1011 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1012 			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1013 			 "%s: unable to copy remaining data to context block.",
1014 			 function );
1015 
1016 			return( -1 );
1017 		}
1018 		internal_context->block_offset = size;
1019 	}
1020 	return( 1 );
1021 }
1022 
1023 #endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_SHA_H ) && defined( SHA_DIGEST_LENGTH ) */
1024 
1025 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_SHA_H ) && defined( SHA_DIGEST_LENGTH )
1026 
1027 /* Finalizes the SHA1 context using OpenSSL
1028  * Returns 1 if successful or -1 on error
1029  */
libhmac_sha1_finalize(libhmac_sha1_context_t * context,uint8_t * hash,size_t hash_size,libcerror_error_t ** error)1030 int libhmac_sha1_finalize(
1031      libhmac_sha1_context_t *context,
1032      uint8_t *hash,
1033      size_t hash_size,
1034      libcerror_error_t **error )
1035 {
1036 	libhmac_internal_sha1_context_t *internal_context = NULL;
1037 	static char *function                             = "libhmac_sha1_finalize";
1038 
1039 	if( context == NULL )
1040 	{
1041 		libcerror_error_set(
1042 		 error,
1043 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1044 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1045 		 "%s: invalid context.",
1046 		 function );
1047 
1048 		return( -1 );
1049 	}
1050 	internal_context = (libhmac_internal_sha1_context_t *) context;
1051 
1052 	if( hash == NULL )
1053 	{
1054 		libcerror_error_set(
1055 		 error,
1056 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1057 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1058 		 "%s: invalid hash.",
1059 		 function );
1060 
1061 		return( -1 );
1062 	}
1063 	if( hash_size > (size_t) SSIZE_MAX )
1064 	{
1065 		libcerror_error_set(
1066 		 error,
1067 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1068 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1069 		 "%s: invalid hash size value exceeds maximum.",
1070 		 function );
1071 
1072 		return( -1 );
1073 	}
1074 	if( hash_size < (size_t) LIBHMAC_SHA1_HASH_SIZE )
1075 	{
1076 		libcerror_error_set(
1077 		 error,
1078 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1079 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1080 		 "%s: invalid hash size value too small.",
1081 		 function );
1082 
1083 		return( -1 );
1084 	}
1085 	if( SHA1_Final(
1086 	     hash,
1087 	     &( internal_context->sha1_context ) ) != 1 )
1088 	{
1089 		libcerror_error_set(
1090 		 error,
1091 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1092 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1093 		 "%s: unable to finalize context.",
1094 		 function );
1095 
1096 		return( -1 );
1097 	}
1098 	return( 1 );
1099 }
1100 
1101 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_SHA1 )
1102 
1103 /* Finalizes the SHA1 context using OpenSSL EVP
1104  * Returns 1 if successful or -1 on error
1105  */
libhmac_sha1_finalize(libhmac_sha1_context_t * context,uint8_t * hash,size_t hash_size,libcerror_error_t ** error)1106 int libhmac_sha1_finalize(
1107      libhmac_sha1_context_t *context,
1108      uint8_t *hash,
1109      size_t hash_size,
1110      libcerror_error_t **error )
1111 {
1112 	libhmac_internal_sha1_context_t *internal_context = NULL;
1113 	static char *function                             = "libhmac_sha1_finalize";
1114 	unsigned int safe_hash_size                       = 0;
1115 
1116 	if( context == NULL )
1117 	{
1118 		libcerror_error_set(
1119 		 error,
1120 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1121 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1122 		 "%s: invalid context.",
1123 		 function );
1124 
1125 		return( -1 );
1126 	}
1127 	internal_context = (libhmac_internal_sha1_context_t *) context;
1128 
1129 	if( hash == NULL )
1130 	{
1131 		libcerror_error_set(
1132 		 error,
1133 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1134 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1135 		 "%s: invalid hash.",
1136 		 function );
1137 
1138 		return( -1 );
1139 	}
1140 	if( hash_size > (size_t) UINT_MAX )
1141 	{
1142 		libcerror_error_set(
1143 		 error,
1144 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1145 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1146 		 "%s: invalid hash size value exceeds maximum.",
1147 		 function );
1148 
1149 		return( -1 );
1150 	}
1151 	if( hash_size < (size_t) LIBHMAC_SHA1_HASH_SIZE )
1152 	{
1153 		libcerror_error_set(
1154 		 error,
1155 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1156 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1157 		 "%s: invalid hash size value too small.",
1158 		 function );
1159 
1160 		return( -1 );
1161 	}
1162 	safe_hash_size = (unsigned int) hash_size;
1163 
1164 	if( EVP_DigestFinal_ex(
1165 	     internal_context->evp_md_context,
1166 	     (unsigned char *) hash,
1167 	     &safe_hash_size ) != 1 )
1168 	{
1169 		libcerror_error_set(
1170 		 error,
1171 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1172 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1173 		 "%s: unable to finalize context.",
1174 		 function );
1175 
1176 		return( -1 );
1177 	}
1178 	return( 1 );
1179 }
1180 
1181 #else
1182 
1183 /* Finalizes the SHA1 context using fallback implementation
1184  * Returns 1 if successful or -1 on error
1185  */
libhmac_sha1_finalize(libhmac_sha1_context_t * context,uint8_t * hash,size_t hash_size,libcerror_error_t ** error)1186 int libhmac_sha1_finalize(
1187      libhmac_sha1_context_t *context,
1188      uint8_t *hash,
1189      size_t hash_size,
1190      libcerror_error_t **error )
1191 {
1192 	libhmac_internal_sha1_context_t *internal_context = NULL;
1193 	static char *function                             = "libhmac_sha1_finalize";
1194 	size_t block_size                                 = 0;
1195 	size_t number_of_blocks                           = 0;
1196 	ssize_t process_count                             = 0;
1197 	uint64_t bit_size                                 = 0;
1198 
1199 #if !defined( LIBHMAC_UNFOLLED_LOOPS )
1200 	size_t hash_index                                 = 0;
1201 	int hash_values_index                             = 0;
1202 #endif
1203 
1204 	if( context == NULL )
1205 	{
1206 		libcerror_error_set(
1207 		 error,
1208 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1209 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1210 		 "%s: invalid context.",
1211 		 function );
1212 
1213 		return( -1 );
1214 	}
1215 	internal_context = (libhmac_internal_sha1_context_t *) context;
1216 
1217 	if( hash == NULL )
1218 	{
1219 		libcerror_error_set(
1220 		 error,
1221 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1222 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1223 		 "%s: invalid hash.",
1224 		 function );
1225 
1226 		return( -1 );
1227 	}
1228 	if( hash_size < (size_t) LIBHMAC_SHA1_HASH_SIZE )
1229 	{
1230 		libcerror_error_set(
1231 		 error,
1232 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1233 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1234 		 "%s: invalid hash value too small.",
1235 		 function );
1236 
1237 		return( -1 );
1238 	}
1239 	if( hash_size > (size_t) SSIZE_MAX )
1240 	{
1241 		libcerror_error_set(
1242 		 error,
1243 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1244 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1245 		 "%s: invalid hash size value exceeds maximum.",
1246 		 function );
1247 
1248 		return( -1 );
1249 	}
1250 	if( hash_size < (size_t) LIBHMAC_SHA1_HASH_SIZE )
1251 	{
1252 		libcerror_error_set(
1253 		 error,
1254 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1255 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1256 		 "%s: invalid hash size value too small.",
1257 		 function );
1258 
1259 		return( -1 );
1260 	}
1261 	/* Add padding with a size of 56 mod 64
1262 	 */
1263 	number_of_blocks = 1;
1264 
1265 	if( internal_context->block_offset > 55 )
1266 	{
1267 		number_of_blocks += 1;
1268 	}
1269 	block_size = number_of_blocks * LIBHMAC_SHA1_BLOCK_SIZE;
1270 
1271 	if( memory_set(
1272 	     &( internal_context->block[ internal_context->block_offset ] ),
1273 	     0,
1274 	     block_size - internal_context->block_offset ) == NULL )
1275 	{
1276 		libcerror_error_set(
1277 		 error,
1278 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1279 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1280 		 "%s: unable to clear context block.",
1281 		 function );
1282 
1283 		return( -1 );
1284 	}
1285 	/* The first byte of the padding contains 0x80
1286 	 */
1287 	internal_context->block[ internal_context->block_offset ] = 0x80;
1288 
1289 	bit_size = ( internal_context->hash_count + internal_context->block_offset ) * 8;
1290 
1291 	byte_stream_copy_from_uint64_big_endian(
1292 	 &( internal_context->block[ block_size - 8 ] ),
1293 	 bit_size );
1294 
1295 	process_count = libhmac_sha1_transform(
1296 	                 internal_context,
1297 	                 internal_context->block,
1298 	                 block_size,
1299 	                 error );
1300 
1301 	if( process_count == -1 )
1302 	{
1303 		libcerror_error_set(
1304 		 error,
1305 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1306 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1307 		 "%s: unable to transform context block.",
1308 		 function );
1309 
1310 		return( -1 );
1311 	}
1312 #if !defined( LIBHMAC_UNFOLLED_LOOPS )
1313 	for( hash_values_index = 0;
1314 	     hash_values_index < 5;
1315 	     hash_values_index++ )
1316 	{
1317 		byte_stream_copy_from_uint32_big_endian(
1318 		 &( hash[ hash_index ] ),
1319 		 internal_context->hash_values[ hash_values_index ] );
1320 
1321 		hash_index += sizeof( uint32_t );
1322 	}
1323 #else
1324 	byte_stream_copy_from_uint32_big_endian(
1325 	 &( hash[ 0 ] ),
1326 	 internal_context->hash_values[ 0 ] );
1327 
1328 	byte_stream_copy_from_uint32_big_endian(
1329 	 &( hash[ 4 ] ),
1330 	 internal_context->hash_values[ 1 ] );
1331 
1332 	byte_stream_copy_from_uint32_big_endian(
1333 	 &( hash[ 8 ] ),
1334 	 internal_context->hash_values[ 2 ] );
1335 
1336 	byte_stream_copy_from_uint32_big_endian(
1337 	 &( hash[ 12 ] ),
1338 	 internal_context->hash_values[ 3 ] );
1339 
1340 	byte_stream_copy_from_uint32_big_endian(
1341 	 &( hash[ 16 ] ),
1342 	 internal_context->hash_values[ 4 ] );
1343 
1344 #endif /* !defined( LIBHMAC_UNFOLLED_LOOPS ) */
1345 
1346 	/* Prevent sensitive data from leaking
1347 	 */
1348 	if( memory_set(
1349 	     internal_context,
1350 	     0,
1351 	     sizeof( libhmac_internal_sha1_context_t ) ) == NULL )
1352 	{
1353 		libcerror_error_set(
1354 		 error,
1355 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1356 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1357 		 "%s: unable to clear context.",
1358 		 function );
1359 
1360 		return( -1 );
1361 	}
1362 	return( 1 );
1363 }
1364 
1365 #endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_SHA_H ) && defined( SHA_DIGEST_LENGTH ) */
1366 
1367 /* Calculates the SHA1 of the buffer
1368  * Returns 1 if successful or -1 on error
1369  */
libhmac_sha1_calculate(const uint8_t * buffer,size_t size,uint8_t * hash,size_t hash_size,libcerror_error_t ** error)1370 int libhmac_sha1_calculate(
1371      const uint8_t *buffer,
1372      size_t size,
1373      uint8_t *hash,
1374      size_t hash_size,
1375      libcerror_error_t **error )
1376 {
1377 	libhmac_sha1_context_t *context = NULL;
1378 	static char *function           = "libhmac_sha1_calculate";
1379 
1380 	if( libhmac_sha1_initialize(
1381 	     &context,
1382 	     error ) != 1 )
1383 	{
1384 		libcerror_error_set(
1385 		 error,
1386 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1387 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1388 		 "%s: unable to initialize context.",
1389 		 function );
1390 
1391 		goto on_error;
1392 	}
1393 	if( libhmac_sha1_update(
1394 	     context,
1395 	     buffer,
1396 	     size,
1397 	     error ) != 1 )
1398 	{
1399 		libcerror_error_set(
1400 		 error,
1401 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1402 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1403 		 "%s: unable to update context.",
1404 		 function );
1405 
1406 		goto on_error;
1407 	}
1408 	if( libhmac_sha1_finalize(
1409 	     context,
1410 	     hash,
1411 	     hash_size,
1412 	     error ) != 1 )
1413 	{
1414 		libcerror_error_set(
1415 		 error,
1416 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1417 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1418 		 "%s: unable to finalize context.",
1419 		 function );
1420 
1421 		goto on_error;
1422 	}
1423 	if( libhmac_sha1_free(
1424 	     &context,
1425 	     error ) != 1 )
1426 	{
1427 		libcerror_error_set(
1428 		 error,
1429 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1430 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1431 		 "%s: unable to free context.",
1432 		 function );
1433 
1434 		goto on_error;
1435 	}
1436 	return( 1 );
1437 
1438 on_error:
1439 	if( context != NULL )
1440 	{
1441 		libhmac_sha1_free(
1442 		 &context,
1443 		 NULL );
1444 	}
1445 	return( -1 );
1446 }
1447 
1448 /* Calculates the SHA1 HMAC of the buffer
1449  * HMAC is defined in RFC 2104
1450  * Returns 1 if successful or -1 on error
1451  */
libhmac_sha1_calculate_hmac(const uint8_t * key,size_t key_size,const uint8_t * buffer,size_t size,uint8_t * hmac,size_t hmac_size,libcerror_error_t ** error)1452 int libhmac_sha1_calculate_hmac(
1453      const uint8_t *key,
1454      size_t key_size,
1455      const uint8_t *buffer,
1456      size_t size,
1457      uint8_t *hmac,
1458      size_t hmac_size,
1459      libcerror_error_t **error )
1460 {
1461 	uint8_t key_hash[ LIBHMAC_SHA1_HASH_SIZE ];
1462 
1463 	libhmac_sha1_context_t *context = NULL;
1464 	uint8_t *key_data               = NULL;
1465 	uint8_t *inner_padding          = NULL;
1466 	uint8_t *outer_padding          = NULL;
1467 	static char *function           = "libhmac_sha1_calculate_hmac";
1468 	size_t block_index              = 0;
1469 	size_t block_size               = 64;
1470 
1471 	if( key == NULL )
1472 	{
1473 		libcerror_error_set(
1474 		 error,
1475 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1476 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1477 		 "%s: invalid key.",
1478 		 function );
1479 
1480 		return( -1 );
1481 	}
1482 	if( key_size > (size_t) SSIZE_MAX )
1483 	{
1484 		libcerror_error_set(
1485 		 error,
1486 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1487 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1488 		 "%s: invalid key size value exceeds maximum.",
1489 		 function );
1490 
1491 		return( -1 );
1492 	}
1493 	if( hmac_size < (size_t) LIBHMAC_SHA1_HASH_SIZE )
1494 	{
1495 		libcerror_error_set(
1496 		 error,
1497 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1498 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1499 		 "%s: invalid HMAC size value too small.",
1500 		 function );
1501 
1502 		return( -1 );
1503 	}
1504 	key_data = (uint8_t *) memory_allocate(
1505 	                        sizeof( uint8_t ) * block_size );
1506 
1507 	if( key_data == NULL )
1508 	{
1509 		libcerror_error_set(
1510 		 error,
1511 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1512 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1513 		 "%s: unable to create key data.",
1514 		 function );
1515 
1516 		goto on_error;
1517 	}
1518 	if( key_size <= block_size )
1519 	{
1520 		if( memory_copy(
1521 		     key_data,
1522 		     key,
1523 		     key_size ) == NULL )
1524 		{
1525 			libcerror_error_set(
1526 			 error,
1527 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1528 			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1529 			 "%s: unable to copy key data.",
1530 			 function );
1531 
1532 			goto on_error;
1533 		}
1534 		if( memory_set(
1535 		     &( key_data[ key_size ] ),
1536 		     0,
1537 		     block_size - key_size ) == NULL )
1538 		{
1539 			libcerror_error_set(
1540 			 error,
1541 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1542 			 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1543 			 "%s: unable to clear key remaining data.",
1544 			 function );
1545 
1546 			goto on_error;
1547 		}
1548 	}
1549 	else
1550 	{
1551 		if( libhmac_sha1_initialize(
1552 		     &context,
1553 		     error ) != 1 )
1554 		{
1555 			libcerror_error_set(
1556 			 error,
1557 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1558 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1559 			 "%s: unable to initialize context.",
1560 			 function );
1561 
1562 			goto on_error;
1563 		}
1564 		if( libhmac_sha1_update(
1565 		     context,
1566 		     key,
1567 		     key_size,
1568 		     error ) != 1 )
1569 		{
1570 			libcerror_error_set(
1571 			 error,
1572 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1573 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1574 			 "%s: unable to update context.",
1575 			 function );
1576 
1577 			goto on_error;
1578 		}
1579 		if( libhmac_sha1_finalize(
1580 		     context,
1581 		     key_hash,
1582 		     LIBHMAC_SHA1_HASH_SIZE,
1583 		     error ) != 1 )
1584 		{
1585 			libcerror_error_set(
1586 			 error,
1587 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1588 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1589 			 "%s: unable to finalize context.",
1590 			 function );
1591 
1592 			goto on_error;
1593 		}
1594 		if( libhmac_sha1_free(
1595 		     &context,
1596 		     error ) != 1 )
1597 		{
1598 			libcerror_error_set(
1599 			 error,
1600 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1601 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1602 			 "%s: unable to free context.",
1603 			 function );
1604 
1605 			goto on_error;
1606 		}
1607 		if( block_size > LIBHMAC_SHA1_HASH_SIZE )
1608 		{
1609 			if( memory_set(
1610 			     &( key_data[ LIBHMAC_SHA1_HASH_SIZE ] ),
1611 			     0,
1612 			     block_size - LIBHMAC_SHA1_HASH_SIZE ) == NULL )
1613 			{
1614 				libcerror_error_set(
1615 				 error,
1616 				 LIBCERROR_ERROR_DOMAIN_MEMORY,
1617 				 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1618 				 "%s: unable to clear remaining key data.",
1619 				 function );
1620 
1621 				goto on_error;
1622 			}
1623 		}
1624 		if( memory_copy(
1625 		     key_data,
1626 		     key_hash,
1627 		     LIBHMAC_SHA1_HASH_SIZE ) == NULL )
1628 		{
1629 			libcerror_error_set(
1630 			 error,
1631 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1632 			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1633 			 "%s: unable to copy key hash data.",
1634 			 function );
1635 
1636 			goto on_error;
1637 		}
1638 	}
1639 	inner_padding = (uint8_t *) memory_allocate(
1640 	                             sizeof( uint8_t ) * block_size );
1641 
1642 	if( inner_padding == NULL )
1643 	{
1644 		libcerror_error_set(
1645 		 error,
1646 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1647 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1648 		 "%s: unable to create inner padding.",
1649 		 function );
1650 
1651 		goto on_error;
1652 	}
1653 	if( memory_set(
1654 	     inner_padding,
1655 	     0x36,
1656 	     block_size ) == NULL )
1657 	{
1658 		libcerror_error_set(
1659 		 error,
1660 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1661 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1662 		 "%s: unable to set inner padding.",
1663 		 function );
1664 
1665 		goto on_error;
1666 	}
1667 	outer_padding = (uint8_t *) memory_allocate(
1668 	                             sizeof( uint8_t ) * block_size );
1669 
1670 	if( outer_padding == NULL )
1671 	{
1672 		libcerror_error_set(
1673 		 error,
1674 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1675 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1676 		 "%s: unable to create outer padding.",
1677 		 function );
1678 
1679 		goto on_error;
1680 	}
1681 	if( memory_set(
1682 	     outer_padding,
1683 	     0x5c,
1684 	     block_size ) == NULL )
1685 	{
1686 		libcerror_error_set(
1687 		 error,
1688 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1689 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1690 		 "%s: unable to set outer padding.",
1691 		 function );
1692 
1693 		goto on_error;
1694 	}
1695 	for( block_index = 0;
1696 	     block_index < block_size;
1697 	     block_index++ )
1698 	{
1699 		inner_padding[ block_index ] ^= key_data[ block_index ];
1700 		outer_padding[ block_index ] ^= key_data[ block_index ];
1701 	}
1702 	if( libhmac_sha1_initialize(
1703 	     &context,
1704 	     error ) != 1 )
1705 	{
1706 		libcerror_error_set(
1707 		 error,
1708 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1709 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1710 		 "%s: unable to initialize context.",
1711 		 function );
1712 
1713 		goto on_error;
1714 	}
1715 	if( libhmac_sha1_update(
1716 	     context,
1717 	     inner_padding,
1718 	     block_size,
1719 	     error ) != 1 )
1720 	{
1721 		libcerror_error_set(
1722 		 error,
1723 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1724 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1725 		 "%s: unable to update context.",
1726 		 function );
1727 
1728 		goto on_error;
1729 	}
1730 	if( libhmac_sha1_update(
1731 	     context,
1732 	     buffer,
1733 	     size,
1734 	     error ) != 1 )
1735 	{
1736 		libcerror_error_set(
1737 		 error,
1738 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1739 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1740 		 "%s: unable to update context.",
1741 		 function );
1742 
1743 		goto on_error;
1744 	}
1745 	if( libhmac_sha1_finalize(
1746 	     context,
1747 	     hmac,
1748 	     hmac_size,
1749 	     error ) != 1 )
1750 	{
1751 		libcerror_error_set(
1752 		 error,
1753 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1754 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1755 		 "%s: unable to finalize context.",
1756 		 function );
1757 
1758 		goto on_error;
1759 	}
1760 	if( libhmac_sha1_free(
1761 	     &context,
1762 	     error ) != 1 )
1763 	{
1764 		libcerror_error_set(
1765 		 error,
1766 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1767 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1768 		 "%s: unable to free context.",
1769 		 function );
1770 
1771 		goto on_error;
1772 	}
1773 	if( libhmac_sha1_initialize(
1774 	     &context,
1775 	     error ) != 1 )
1776 	{
1777 		libcerror_error_set(
1778 		 error,
1779 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1780 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1781 		 "%s: unable to initialize context.",
1782 		 function );
1783 
1784 		goto on_error;
1785 	}
1786 	if( libhmac_sha1_update(
1787 	     context,
1788 	     outer_padding,
1789 	     block_size,
1790 	     error ) != 1 )
1791 	{
1792 		libcerror_error_set(
1793 		 error,
1794 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1795 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1796 		 "%s: unable to update context.",
1797 		 function );
1798 
1799 		goto on_error;
1800 	}
1801 	if( libhmac_sha1_update(
1802 	     context,
1803 	     hmac,
1804 	     LIBHMAC_SHA1_HASH_SIZE,
1805 	     error ) != 1 )
1806 	{
1807 		libcerror_error_set(
1808 		 error,
1809 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1810 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1811 		 "%s: unable to update context.",
1812 		 function );
1813 
1814 		goto on_error;
1815 	}
1816 	if( libhmac_sha1_finalize(
1817 	     context,
1818 	     hmac,
1819 	     hmac_size,
1820 	     error ) != 1 )
1821 	{
1822 		libcerror_error_set(
1823 		 error,
1824 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1825 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1826 		 "%s: unable to finalize context.",
1827 		 function );
1828 
1829 		goto on_error;
1830 	}
1831 	if( libhmac_sha1_free(
1832 	     &context,
1833 	     error ) != 1 )
1834 	{
1835 		libcerror_error_set(
1836 		 error,
1837 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1838 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1839 		 "%s: unable to free context.",
1840 		 function );
1841 
1842 		goto on_error;
1843 	}
1844 	if( memory_set(
1845 	     outer_padding,
1846 	     0,
1847 	     block_size ) == NULL )
1848 	{
1849 		libcerror_error_set(
1850 		 error,
1851 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1852 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1853 		 "%s: unable to clear outer padding.",
1854 		 function );
1855 
1856 		goto on_error;
1857 	}
1858 	memory_free(
1859 	 outer_padding );
1860 
1861 	outer_padding = NULL;
1862 
1863 	if( memory_set(
1864 	     inner_padding,
1865 	     0,
1866 	     block_size ) == NULL )
1867 	{
1868 		libcerror_error_set(
1869 		 error,
1870 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1871 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1872 		 "%s: unable to clear inner padding.",
1873 		 function );
1874 
1875 		goto on_error;
1876 	}
1877 	memory_free(
1878 	 inner_padding );
1879 
1880 	inner_padding = NULL;
1881 
1882 	if( memory_set(
1883 	     key_data,
1884 	     0,
1885 	     block_size ) == NULL )
1886 	{
1887 		libcerror_error_set(
1888 		 error,
1889 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1890 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1891 		 "%s: unable to clear key data.",
1892 		 function );
1893 
1894 		goto on_error;
1895 	}
1896 	memory_free(
1897 	 key_data );
1898 
1899 	key_data = NULL;
1900 
1901 	return( 1 );
1902 
1903 on_error:
1904 	if( context != NULL )
1905 	{
1906 		libhmac_sha1_free(
1907 		 &context,
1908 		 NULL );
1909 	}
1910 	if( outer_padding != NULL )
1911 	{
1912 		memory_set(
1913         	 outer_padding,
1914 	         0,
1915         	 block_size );
1916 
1917 		memory_free(
1918 		 outer_padding );
1919 	}
1920 	if( inner_padding != NULL )
1921 	{
1922 		memory_set(
1923         	 inner_padding,
1924 	         0,
1925         	 block_size );
1926 
1927 		memory_free(
1928 		 inner_padding );
1929 	}
1930 	if( key_data != NULL )
1931 	{
1932 		memory_set(
1933         	 key_data,
1934 	         0,
1935         	 block_size );
1936 
1937 		memory_free(
1938 		 key_data );
1939 	}
1940 	return( -1 );
1941 }
1942 
1943