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