1 /*
2 * Debug functions
3 *
4 * Copyright (C) 2011-2021, 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 <memory.h>
24 #include <types.h>
25
26 #include "libbde_debug.h"
27 #include "libbde_definitions.h"
28 #include "libbde_libbfio.h"
29 #include "libbde_libcerror.h"
30 #include "libbde_libcnotify.h"
31 #include "libbde_libfdatetime.h"
32 #include "libbde_libfguid.h"
33
34 #if defined( HAVE_DEBUG_OUTPUT )
35
36 /* Prints the encryption method
37 */
libbde_debug_print_encryption_method(uint16_t encryption_method)38 const char *libbde_debug_print_encryption_method(
39 uint16_t encryption_method )
40 {
41 switch( encryption_method )
42 {
43 case LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER:
44 return( "AES-CBC 128-bit encryption with diffuser" );
45
46 case LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER:
47 return( "AES-CBC 256-bit encryption with diffuser" );
48
49 case LIBBDE_ENCRYPTION_METHOD_AES_128_CBC:
50 return( "AES-CBC 128-bit encryption" );
51
52 case LIBBDE_ENCRYPTION_METHOD_AES_256_CBC:
53 return( "AES-CBC 256-bit encryption" );
54
55 case LIBBDE_ENCRYPTION_METHOD_AES_128_XTS:
56 return( "AES-XTS 128-bit encryption" );
57
58 case LIBBDE_ENCRYPTION_METHOD_AES_256_XTS:
59 return( "AES-XTS 256-bit encryption" );
60
61 case LIBBDE_ENCRYPTION_METHOD_NONE:
62 return( "None" );
63 }
64 return( "_UNKNOWN_" );
65 }
66
67 /* Prints the entry type
68 */
libbde_debug_print_entry_type(uint16_t entry_type)69 const char *libbde_debug_print_entry_type(
70 uint16_t entry_type )
71 {
72 switch( entry_type )
73 {
74 case LIBBDE_ENTRY_TYPE_PROPERTY:
75 return( "Property" );
76
77 case LIBBDE_ENTRY_TYPE_VOLUME_MASTER_KEY:
78 return( "Volume master key (VMK)" );
79
80 case LIBBDE_ENTRY_TYPE_FULL_VOLUME_ENCRYPTION_KEY:
81 return( "Full volume encryption key (FVEK)" );
82
83 case LIBBDE_ENTRY_TYPE_VALIDATION:
84 return( "Validation" );
85
86 case LIBBDE_ENTRY_TYPE_STARTUP_KEY:
87 return( "Startup key" );
88
89 case LIBBDE_ENTRY_TYPE_DESCRIPTION:
90 return( "Description" );
91
92 case LIBBDE_ENTRY_TYPE_VOLUME_HEADER_BLOCK:
93 return( "Volume header block" );
94 }
95 return( "_UNKNOWN_" );
96 }
97
98 /* Prints the value type
99 */
libbde_debug_print_value_type(uint16_t value_type)100 const char *libbde_debug_print_value_type(
101 uint16_t value_type )
102 {
103 switch( value_type )
104 {
105 case LIBBDE_VALUE_TYPE_ERASED:
106 return( "Erased" );
107
108 case LIBBDE_VALUE_TYPE_KEY:
109 return( "Key" );
110
111 case LIBBDE_VALUE_TYPE_UNICODE_STRING:
112 return( "Unicode string (UTF-16 little-endian)" );
113
114 case LIBBDE_VALUE_TYPE_STRETCH_KEY:
115 return( "Stretch key" );
116
117 case LIBBDE_VALUE_TYPE_USE_KEY:
118 return( "Use key" );
119
120 case LIBBDE_VALUE_TYPE_AES_CCM_ENCRYPTED_KEY:
121 return( "AES-CCM encrypted key" );
122
123 case LIBBDE_VALUE_TYPE_TPM_ENCODED_KEY:
124 return( "TPM encoded key" );
125
126 case LIBBDE_VALUE_TYPE_VALIDATION:
127 return( "Validation" );
128
129 case LIBBDE_VALUE_TYPE_VOLUME_MASTER_KEY:
130 return( "Volume master key" );
131
132 case LIBBDE_VALUE_TYPE_EXTERNAL_KEY:
133 return( "External key" );
134
135 case LIBBDE_VALUE_TYPE_UPDATE:
136 return( "Update" );
137
138 case LIBBDE_VALUE_TYPE_ERROR:
139 return( "Error" );
140
141 case LIBBDE_VALUE_TYPE_OFFSET_AND_SIZE:
142 return( "Offset and size" );
143 }
144 return( "_UNKNOWN_" );
145 }
146
147 /* Prints the key protection type
148 */
libbde_debug_print_key_protection_type(uint16_t key_protection_type)149 const char *libbde_debug_print_key_protection_type(
150 uint16_t key_protection_type )
151 {
152 switch( key_protection_type )
153 {
154 case LIBBDE_KEY_PROTECTION_TYPE_CLEAR_KEY:
155 return( "clear key protected" );
156
157 case LIBBDE_KEY_PROTECTION_TYPE_TPM:
158 return( "TPM protected" );
159
160 case LIBBDE_KEY_PROTECTION_TYPE_STARTUP_KEY:
161 return( "startup key protected" );
162
163 case LIBBDE_KEY_PROTECTION_TYPE_TPM_AND_PIN:
164 return( "TPM and PIN protected" );
165
166 case LIBBDE_KEY_PROTECTION_TYPE_RECOVERY_PASSWORD:
167 return( "recovery password protected" );
168
169 case LIBBDE_KEY_PROTECTION_TYPE_PASSWORD:
170 return( "password protected" );
171 }
172 return( "_UNKNOWN_" );
173 }
174
175 /* Prints a FILETIME value
176 * Returns 1 if successful or -1 on error
177 */
libbde_debug_print_filetime_value(const char * function_name,const char * value_name,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,uint32_t string_format_flags,libcerror_error_t ** error)178 int libbde_debug_print_filetime_value(
179 const char *function_name,
180 const char *value_name,
181 const uint8_t *byte_stream,
182 size_t byte_stream_size,
183 int byte_order,
184 uint32_t string_format_flags,
185 libcerror_error_t **error )
186 {
187 char date_time_string[ 32 ];
188
189 libfdatetime_filetime_t *filetime = NULL;
190 static char *function = "libbde_debug_print_filetime_value";
191
192 if( libfdatetime_filetime_initialize(
193 &filetime,
194 error ) != 1 )
195 {
196 libcerror_error_set(
197 error,
198 LIBCERROR_ERROR_DOMAIN_RUNTIME,
199 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
200 "%s: unable to create filetime.",
201 function );
202
203 goto on_error;
204 }
205 if( libfdatetime_filetime_copy_from_byte_stream(
206 filetime,
207 byte_stream,
208 byte_stream_size,
209 byte_order,
210 error ) != 1 )
211 {
212 libcerror_error_set(
213 error,
214 LIBCERROR_ERROR_DOMAIN_RUNTIME,
215 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
216 "%s: unable to copy byte stream to filetime.",
217 function );
218
219 goto on_error;
220 }
221 if( libfdatetime_filetime_copy_to_utf8_string(
222 filetime,
223 (uint8_t *) date_time_string,
224 32,
225 string_format_flags,
226 error ) != 1 )
227 {
228 libcerror_error_set(
229 error,
230 LIBCERROR_ERROR_DOMAIN_RUNTIME,
231 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
232 "%s: unable to copy filetime to string.",
233 function );
234
235 goto on_error;
236 }
237 libcnotify_printf(
238 "%s: %s: %s UTC\n",
239 function_name,
240 value_name,
241 date_time_string );
242
243 if( libfdatetime_filetime_free(
244 &filetime,
245 error ) != 1 )
246 {
247 libcerror_error_set(
248 error,
249 LIBCERROR_ERROR_DOMAIN_RUNTIME,
250 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
251 "%s: unable to free filetime.",
252 function );
253
254 goto on_error;
255 }
256 return( 1 );
257
258 on_error:
259 if( filetime != NULL )
260 {
261 libfdatetime_filetime_free(
262 &filetime,
263 NULL );
264 }
265 return( -1 );
266 }
267
268 /* Prints a GUID/UUID value
269 * Returns 1 if successful or -1 on error
270 */
libbde_debug_print_guid_value(const char * function_name,const char * value_name,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,uint32_t string_format_flags,libcerror_error_t ** error)271 int libbde_debug_print_guid_value(
272 const char *function_name,
273 const char *value_name,
274 const uint8_t *byte_stream,
275 size_t byte_stream_size,
276 int byte_order,
277 uint32_t string_format_flags,
278 libcerror_error_t **error )
279 {
280 system_character_t guid_string[ 48 ];
281
282 libfguid_identifier_t *guid = NULL;
283 static char *function = "libbde_debug_print_guid_value";
284
285 if( libfguid_identifier_initialize(
286 &guid,
287 error ) != 1 )
288 {
289 libcerror_error_set(
290 error,
291 LIBCERROR_ERROR_DOMAIN_RUNTIME,
292 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
293 "%s: unable to create GUID.",
294 function );
295
296 goto on_error;
297 }
298 if( libfguid_identifier_copy_from_byte_stream(
299 guid,
300 byte_stream,
301 byte_stream_size,
302 byte_order,
303 error ) != 1 )
304 {
305 libcerror_error_set(
306 error,
307 LIBCERROR_ERROR_DOMAIN_RUNTIME,
308 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
309 "%s: unable to copy byte stream to GUID.",
310 function );
311
312 goto on_error;
313 }
314 if( libfguid_identifier_copy_to_utf8_string(
315 guid,
316 (uint8_t *) guid_string,
317 48,
318 string_format_flags,
319 error ) != 1 )
320 {
321 libcerror_error_set(
322 error,
323 LIBCERROR_ERROR_DOMAIN_RUNTIME,
324 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
325 "%s: unable to copy GUID to string.",
326 function );
327
328 goto on_error;
329 }
330 libcnotify_printf(
331 "%s: %s: %s\n",
332 function_name,
333 value_name,
334 guid_string );
335
336 if( libfguid_identifier_free(
337 &guid,
338 error ) != 1 )
339 {
340 libcerror_error_set(
341 error,
342 LIBCERROR_ERROR_DOMAIN_RUNTIME,
343 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
344 "%s: unable to free GUID.",
345 function );
346
347 goto on_error;
348 }
349 return( 1 );
350
351 on_error:
352 if( guid != NULL )
353 {
354 libfguid_identifier_free(
355 &guid,
356 NULL );
357 }
358 return( -1 );
359 }
360
361 /* Prints the read offsets
362 * Returns 1 if successful or -1 on error
363 */
libbde_debug_print_read_offsets(libbfio_handle_t * file_io_handle,libcerror_error_t ** error)364 int libbde_debug_print_read_offsets(
365 libbfio_handle_t *file_io_handle,
366 libcerror_error_t **error )
367 {
368 static char *function = "libbde_debug_print_read_offsets";
369 off64_t offset = 0;
370 size64_t size = 0;
371 int number_of_offsets = 0;
372 int offset_iterator = 0;
373
374 if( file_io_handle == NULL )
375 {
376 libcerror_error_set(
377 error,
378 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
379 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
380 "%s: invalid file IO handle.",
381 function );
382
383 return( -1 );
384 }
385 if( libbfio_handle_get_number_of_offsets_read(
386 file_io_handle,
387 &number_of_offsets,
388 error ) != 1 )
389 {
390 libcerror_error_set(
391 error,
392 LIBCERROR_ERROR_DOMAIN_RUNTIME,
393 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
394 "%s: unable to retrieve number of offsets read.",
395 function );
396
397 return( -1 );
398 }
399 libcnotify_printf(
400 "Offsets read:\n" );
401
402 for( offset_iterator = 0;
403 offset_iterator < number_of_offsets;
404 offset_iterator++ )
405 {
406 if( libbfio_handle_get_offset_read(
407 file_io_handle,
408 offset_iterator,
409 &offset,
410 &size,
411 error ) != 1 )
412 {
413 libcerror_error_set(
414 error,
415 LIBCERROR_ERROR_DOMAIN_RUNTIME,
416 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
417 "%s: unable to retrieve offset: %d.",
418 function,
419 ( offset_iterator + 1 ) );
420
421 return( -1 );
422 }
423 libcnotify_printf(
424 "%08" PRIi64 " ( 0x%08" PRIx64 " ) - %08" PRIi64 " ( 0x%08" PRIx64 " ) size: %" PRIu64 "\n",
425 offset,
426 offset,
427 offset + (off64_t) size,
428 offset + (off64_t) size,
429 size );
430 }
431 libcnotify_printf(
432 "\n" );
433
434 return( 1 );
435 }
436
437 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
438
439