1 /*
2  * Base32 stream functions
3  *
4  * Copyright (C) 2008-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 <byte_stream.h>
24 #include <types.h>
25 
26 #include "libuna_base32_stream.h"
27 #include "libuna_definitions.h"
28 #include "libuna_libcerror.h"
29 #include "libuna_types.h"
30 
31 static uint8_t libuna_base32_quintet_to_character_table[ 32 ] = {
32 	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
33 	'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7' };
34 
35 static uint8_t libuna_base32hex_quintet_to_character_table[ 32 ] = {
36 	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
37 	'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V' };
38 
39 /* Copies a base32 character to a base32 quintet
40  * Returns 1 if successful or -1 on error
41  */
libuna_base32_character_copy_to_quintet(uint8_t base32_character,uint8_t * base32_quintet,uint32_t base32_variant,libcerror_error_t ** error)42 int libuna_base32_character_copy_to_quintet(
43      uint8_t base32_character,
44      uint8_t *base32_quintet,
45      uint32_t base32_variant,
46      libcerror_error_t **error )
47 {
48 	static char *function       = "libuna_base32_character_copy_to_quintet";
49 	uint8_t safe_base32_quintet = 0;
50 
51 	if( base32_quintet == NULL )
52 	{
53 		libcerror_error_set(
54 		 error,
55 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
56 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
57 		 "%s: invalid base32 quintet.",
58 		 function );
59 
60 		return( -1 );
61 	}
62 	switch( base32_variant & 0x000f0000UL )
63 	{
64 		case LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL:
65 			/* A-Z is not a continous range on an EBCDIC based system
66 			 * it consists of the ranges: A-I, J-R, S-Z
67 			 */
68 			if( ( base32_character >= (uint8_t) 'A' )
69 			 && ( base32_character <= (uint8_t) 'I' ) )
70 			{
71 				safe_base32_quintet = base32_character - (uint8_t) 'A';
72 			}
73 			else if( ( base32_character >= (uint8_t) 'J' )
74 			      && ( base32_character <= (uint8_t) 'R' ) )
75 			{
76 				safe_base32_quintet = base32_character - (uint8_t) 'J' + 9;
77 			}
78 			else if( ( base32_character >= (uint8_t) 'S' )
79 			      && ( base32_character <= (uint8_t) 'Z' ) )
80 			{
81 				safe_base32_quintet = base32_character - (uint8_t) 'S' + 18;
82 			}
83 			else if( ( base32_character >= (uint8_t) '2' )
84 			      && ( base32_character <= (uint8_t) '7' ) )
85 			{
86 				safe_base32_quintet = base32_character - (uint8_t) '2' + 26;
87 			}
88 			else
89 			{
90 				libcerror_error_set(
91 				 error,
92 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
93 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
94 				 "%s: invalid base32 character: 0x%02" PRIx8 ".",
95 				 function,
96 				 base32_character );
97 
98 				return( -1 );
99 			}
100 			break;
101 
102 		case LIBUNA_BASE32_VARIANT_ALPHABET_HEX:
103 			if( ( base32_character >= (uint8_t) '0' )
104 			 && ( base32_character <= (uint8_t) '9' ) )
105 			{
106 				safe_base32_quintet = base32_character - (uint8_t) '0';
107 			}
108 			/* A-V is not a continous range on an EBCDIC based system
109 			 * it consists of the ranges: A-I, J-R, S-V
110 			 */
111 			else if( ( base32_character >= (uint8_t) 'A' )
112 			      && ( base32_character <= (uint8_t) 'I' ) )
113 			{
114 				safe_base32_quintet = base32_character - (uint8_t) 'A' + 10;
115 			}
116 			else if( ( base32_character >= (uint8_t) 'J' )
117 			      && ( base32_character <= (uint8_t) 'R' ) )
118 			{
119 				safe_base32_quintet = base32_character - (uint8_t) 'J' + 19;
120 			}
121 			else if( ( base32_character >= (uint8_t) 'S' )
122 			      && ( base32_character <= (uint8_t) 'V' ) )
123 			{
124 				safe_base32_quintet = base32_character - (uint8_t) 'S' + 27;
125 			}
126 			else
127 			{
128 				libcerror_error_set(
129 				 error,
130 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
131 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
132 				 "%s: invalid base32 character: 0x%02" PRIx8 ".",
133 				 function,
134 				 base32_character );
135 
136 				return( -1 );
137 			}
138 			break;
139 
140 		default:
141 			libcerror_error_set(
142 			 error,
143 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
144 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
145 			 "%s: unsupported base32 variant.",
146 			 function );
147 
148 			return( -1 );
149 	}
150 	*base32_quintet = safe_base32_quintet;
151 
152 	return( 1 );
153 }
154 
155 /* Copies a base32 quintuplet from a base32 stream
156  *
157  * The padding size will still be set to indicate the number of
158  * quintets in the quintuplet
159  *
160  * Returns 1 if successful or -1 on error
161  */
libuna_base32_quintuplet_copy_from_base32_stream(uint64_t * base32_quintuplet,const uint8_t * base32_stream,size_t base32_stream_size,size_t * base32_stream_index,uint8_t * padding_size,uint32_t base32_variant,libcerror_error_t ** error)162 int libuna_base32_quintuplet_copy_from_base32_stream(
163      uint64_t *base32_quintuplet,
164      const uint8_t *base32_stream,
165      size_t base32_stream_size,
166      size_t *base32_stream_index,
167      uint8_t *padding_size,
168      uint32_t base32_variant,
169      libcerror_error_t **error )
170 {
171 	static char *function           = "libuna_base32_quintuplet_copy_from_base32_stream";
172 	size_t base32_character_size    = 0;
173 	size_t safe_base32_stream_index = 0;
174 	uint64_t safe_base32_quintuplet = 0;
175 	uint32_t base32_character1      = 0;
176 	uint32_t base32_character2      = 0;
177 	uint8_t quintet1                = 0;
178 	uint8_t quintet2                = 0;
179 	uint8_t quintet3                = 0;
180 	uint8_t quintet4                = 0;
181 	uint8_t quintet5                = 0;
182 	uint8_t quintet6                = 0;
183 	uint8_t quintet7                = 0;
184 	uint8_t quintet8                = 0;
185 	uint8_t safe_padding_size       = 0;
186 
187 	if( base32_quintuplet == NULL )
188 	{
189 		libcerror_error_set(
190 		 error,
191 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
192 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
193 		 "%s: invalid base32 quintuplet.",
194 		 function );
195 
196 		return( -1 );
197 	}
198 	if( base32_stream == NULL )
199 	{
200 		libcerror_error_set(
201 		 error,
202 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
203 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
204 		 "%s: invalid base32 stream.",
205 		 function );
206 
207 		return( -1 );
208 	}
209 	if( base32_stream_size > (size_t) SSIZE_MAX )
210 	{
211 		libcerror_error_set(
212 		 error,
213 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
214 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
215 		 "%s: invalid base32 stream size value exceeds maximum.",
216 		 function );
217 
218 		return( -1 );
219 	}
220 	if( base32_stream_index == NULL )
221 	{
222 		libcerror_error_set(
223 		 error,
224 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
225 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
226 		 "%s: invalid base32 stream index.",
227 		 function );
228 
229 		return( -1 );
230 	}
231 	if( *base32_stream_index >= base32_stream_size )
232 	{
233 		libcerror_error_set(
234 		 error,
235 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
236 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
237 		 "%s: base32 stream string too small.",
238 		 function );
239 
240 		return( -1 );
241 	}
242 	if( padding_size == NULL )
243 	{
244 		libcerror_error_set(
245 		 error,
246 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
247 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
248 		 "%s: invalid padding size.",
249 		 function );
250 
251 		return( -1 );
252 	}
253 	switch( base32_variant & 0x0f000000UL )
254 	{
255 		case LIBUNA_BASE32_VARIANT_PADDING_NONE:
256 		case LIBUNA_BASE32_VARIANT_PADDING_OPTIONAL:
257 		case LIBUNA_BASE32_VARIANT_PADDING_REQUIRED:
258 			break;
259 
260 		default:
261 			libcerror_error_set(
262 			 error,
263 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
264 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
265 			 "%s: unsupported base32 variant.",
266 			 function );
267 
268 			return( -1 );
269 	}
270 	switch( base32_variant & 0xf0000000UL )
271 	{
272 		case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
273 			base32_character_size = 1;
274 			break;
275 
276 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
277 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
278 			base32_character_size = 2;
279 			break;
280 
281 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
282 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
283 			base32_character_size = 4;
284 			break;
285 
286 		default:
287 			libcerror_error_set(
288 			 error,
289 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
290 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
291 			 "%s: unsupported base32 variant.",
292 			 function );
293 
294 			return( -1 );
295 	}
296 	safe_base32_stream_index = *base32_stream_index;
297 
298 	if( base32_character_size > ( base32_stream_size - safe_base32_stream_index ) )
299 	{
300 		libcerror_error_set(
301 		 error,
302 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
303 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
304 		 "%s: missing 1st base32 character.",
305 		 function );
306 
307 		return( -1 );
308 	}
309 	switch( base32_variant & 0xf0000000UL )
310 	{
311 		case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
312 			base32_character1 = base32_stream[ safe_base32_stream_index ];
313 			break;
314 
315 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
316 			byte_stream_copy_to_uint16_big_endian(
317 			 &( base32_stream[ safe_base32_stream_index ] ),
318 			 base32_character1 );
319 			break;
320 
321 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
322 			byte_stream_copy_to_uint16_little_endian(
323 			 &( base32_stream[ safe_base32_stream_index ] ),
324 			 base32_character1 );
325 			break;
326 
327 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
328 			byte_stream_copy_to_uint32_big_endian(
329 			 &( base32_stream[ safe_base32_stream_index ] ),
330 			 base32_character1 );
331 			break;
332 
333 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
334 			byte_stream_copy_to_uint32_little_endian(
335 			 &( base32_stream[ safe_base32_stream_index ] ),
336 			 base32_character1 );
337 			break;
338 	}
339 	safe_base32_stream_index += base32_character_size;
340 
341 	if( ( base32_character1 & 0xffffff00UL ) != 0 )
342 	{
343 		libcerror_error_set(
344 		 error,
345 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
346 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
347 		 "%s: invalid 1st base32 character.",
348 		 function );
349 
350 		return( -1 );
351 	}
352 	if( libuna_base32_character_copy_to_quintet(
353 	     (uint8_t) base32_character1,
354 	     &quintet1,
355 	     base32_variant,
356 	     error ) != 1 )
357 	{
358 		libcerror_error_set(
359 		 error,
360 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
361 		 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
362 		 "%s: unable to copy base32 character to 1st quintet.",
363 		 function );
364 
365 		return( -1 );
366 	}
367 	if( base32_character_size > ( base32_stream_size - safe_base32_stream_index ) )
368 	{
369 		libcerror_error_set(
370 		 error,
371 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
372 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
373 		 "%s: missing 2nd base32 character.",
374 		 function );
375 
376 		return( -1 );
377 	}
378 	switch( base32_variant & 0xf0000000UL )
379 	{
380 		case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
381 			base32_character1 = base32_stream[ safe_base32_stream_index ];
382 			break;
383 
384 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
385 			byte_stream_copy_to_uint16_big_endian(
386 			 &( base32_stream[ safe_base32_stream_index ] ),
387 			 base32_character1 );
388 			break;
389 
390 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
391 			byte_stream_copy_to_uint16_little_endian(
392 			 &( base32_stream[ safe_base32_stream_index ] ),
393 			 base32_character1 );
394 			break;
395 
396 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
397 			byte_stream_copy_to_uint32_big_endian(
398 			 &( base32_stream[ safe_base32_stream_index ] ),
399 			 base32_character1 );
400 			break;
401 
402 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
403 			byte_stream_copy_to_uint32_little_endian(
404 			 &( base32_stream[ safe_base32_stream_index ] ),
405 			 base32_character1 );
406 			break;
407 	}
408 	safe_base32_stream_index += base32_character_size;
409 
410 	if( ( base32_character1 & 0xffffff00UL ) != 0 )
411 	{
412 		libcerror_error_set(
413 		 error,
414 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
415 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
416 		 "%s: invalid 2nd base32 character.",
417 		 function );
418 
419 		return( -1 );
420 	}
421 	if( libuna_base32_character_copy_to_quintet(
422 	     (uint8_t) base32_character1,
423 	     &quintet2,
424 	     base32_variant,
425 	     error ) != 1 )
426 	{
427 		libcerror_error_set(
428 		 error,
429 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
430 		 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
431 		 "%s: unable to copy base32 character to 2nd quintet.",
432 		 function );
433 
434 		return( -1 );
435 	}
436 	safe_padding_size = 6;
437 
438 	if( ( 2 * base32_character_size ) <= ( base32_stream_size - safe_base32_stream_index ) )
439 	{
440 		switch( base32_variant & 0xf0000000UL )
441 		{
442 			case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
443 				base32_character1 = base32_stream[ safe_base32_stream_index ];
444 				base32_character2 = base32_stream[ safe_base32_stream_index + 1 ];
445 				break;
446 
447 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
448 				byte_stream_copy_to_uint16_big_endian(
449 				 &( base32_stream[ safe_base32_stream_index ] ),
450 				 base32_character1 );
451 
452 				byte_stream_copy_to_uint16_big_endian(
453 				 &( base32_stream[ safe_base32_stream_index + 2 ] ),
454 				 base32_character2 );
455 				break;
456 
457 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
458 				byte_stream_copy_to_uint16_little_endian(
459 				 &( base32_stream[ safe_base32_stream_index ] ),
460 				 base32_character1 );
461 
462 				byte_stream_copy_to_uint16_little_endian(
463 				 &( base32_stream[ safe_base32_stream_index + 2 ] ),
464 				 base32_character2 );
465 				break;
466 
467 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
468 				byte_stream_copy_to_uint32_big_endian(
469 				 &( base32_stream[ safe_base32_stream_index ] ),
470 				 base32_character1 );
471 
472 				byte_stream_copy_to_uint32_big_endian(
473 				 &( base32_stream[ safe_base32_stream_index + 4 ] ),
474 				 base32_character2 );
475 				break;
476 
477 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
478 				byte_stream_copy_to_uint32_little_endian(
479 				 &( base32_stream[ safe_base32_stream_index ] ),
480 				 base32_character1 );
481 
482 				byte_stream_copy_to_uint32_little_endian(
483 				 &( base32_stream[ safe_base32_stream_index + 4 ] ),
484 				 base32_character2 );
485 				break;
486 		}
487 		safe_base32_stream_index += 2 * base32_character_size;
488 
489 		if( ( base32_character1 & 0xffffff00UL ) != 0 )
490 		{
491 			libcerror_error_set(
492 			 error,
493 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
494 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
495 			 "%s: invalid 3rd base32 character.",
496 			 function );
497 
498 			return( -1 );
499 		}
500 		if( ( base32_character2 & 0xffffff00UL ) != 0 )
501 		{
502 			libcerror_error_set(
503 			 error,
504 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
505 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
506 			 "%s: invalid 4th base32 character.",
507 			 function );
508 
509 			return( -1 );
510 		}
511 		if( ( base32_character1 == (uint32_t) '=' )
512 		 || ( base32_character2 == (uint32_t) '=' ) )
513 		{
514 			if( ( base32_variant & 0x0f000000UL ) == LIBUNA_BASE32_VARIANT_PADDING_NONE )
515 			{
516 				libcerror_error_set(
517 				 error,
518 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
519 				 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
520 				 "%s: padding where not supposed to - invalid 3rd or 4th base32 character.",
521 				 function );
522 
523 				return( -1 );
524 			}
525 			if( base32_character1 != (uint32_t) '=' )
526 			{
527 				libcerror_error_set(
528 				 error,
529 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
530 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
531 				 "%s: invalid 3rd base32 character.",
532 				 function );
533 
534 				return( -1 );
535 			}
536 			if( base32_character2 != (uint32_t) '=' )
537 			{
538 				libcerror_error_set(
539 				 error,
540 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
541 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
542 				 "%s: invalid 4th base32 character.",
543 				 function );
544 
545 				return( -1 );
546 			}
547 		}
548 		else
549 		{
550 			if( libuna_base32_character_copy_to_quintet(
551 			     (uint8_t) base32_character1,
552 			     &quintet3,
553 			     base32_variant,
554 			     error ) != 1 )
555 			{
556 				libcerror_error_set(
557 				 error,
558 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
559 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
560 				 "%s: invalid 3rd base32 quintet.",
561 				 function );
562 
563 				return( -1 );
564 			}
565 			if( libuna_base32_character_copy_to_quintet(
566 			     (uint8_t) base32_character2,
567 			     &quintet4,
568 			     base32_variant,
569 			     error ) != 1 )
570 			{
571 				libcerror_error_set(
572 				 error,
573 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
574 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
575 				 "%s: invalid 4th base32 quintet.",
576 				 function );
577 
578 				return( -1 );
579 			}
580 			safe_padding_size -= 2;
581 		}
582 	}
583 	else if( ( base32_variant & 0x0f000000UL ) != LIBUNA_BASE32_VARIANT_PADDING_NONE )
584 	{
585 		libcerror_error_set(
586 		 error,
587 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
588 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
589 		 "%s: missing 3rd or 4th base32 character.",
590 		 function );
591 
592 		return( -1 );
593 	}
594 	if( base32_character_size <= ( base32_stream_size - safe_base32_stream_index ) )
595 	{
596 		switch( base32_variant & 0xf0000000UL )
597 		{
598 			case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
599 				base32_character1 = base32_stream[ safe_base32_stream_index ];
600 				break;
601 
602 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
603 				byte_stream_copy_to_uint16_big_endian(
604 				 &( base32_stream[ safe_base32_stream_index ] ),
605 				 base32_character1 );
606 				break;
607 
608 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
609 				byte_stream_copy_to_uint16_little_endian(
610 				 &( base32_stream[ safe_base32_stream_index ] ),
611 				 base32_character1 );
612 				break;
613 
614 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
615 				byte_stream_copy_to_uint32_big_endian(
616 				 &( base32_stream[ safe_base32_stream_index ] ),
617 				 base32_character1 );
618 				break;
619 
620 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
621 				byte_stream_copy_to_uint32_little_endian(
622 				 &( base32_stream[ safe_base32_stream_index ] ),
623 				 base32_character1 );
624 				break;
625 		}
626 		safe_base32_stream_index += base32_character_size;
627 
628 		if( ( base32_character1 & 0xffffff00UL ) != 0 )
629 		{
630 			libcerror_error_set(
631 			 error,
632 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
633 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
634 			 "%s: invalid 5th base32 character.",
635 			 function );
636 
637 			return( -1 );
638 		}
639 		if( base32_character1 == (uint32_t) '=' )
640 		{
641 			if( ( base32_variant & 0x0f000000UL ) == LIBUNA_BASE32_VARIANT_PADDING_NONE )
642 			{
643 				libcerror_error_set(
644 				 error,
645 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
646 				 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
647 				 "%s: padding where not supposed to - invalid 5th base32 character.",
648 				 function );
649 
650 				return( -1 );
651 			}
652 		}
653 		else
654 		{
655 			if( safe_padding_size > 4 )
656 			{
657 				libcerror_error_set(
658 				 error,
659 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
660 				 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
661 				 "%s: non-padding where not supposed to - invalid 5th base32 character.",
662 				 function );
663 
664 				return( -1 );
665 			}
666 			if( libuna_base32_character_copy_to_quintet(
667 			     (uint8_t) base32_character1,
668 			     &quintet5,
669 			     base32_variant,
670 			     error ) != 1 )
671 			{
672 				libcerror_error_set(
673 				 error,
674 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
675 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
676 				 "%s: invalid 5th base32 quintet.",
677 				 function );
678 
679 				return( -1 );
680 			}
681 			safe_padding_size -= 1;
682 		}
683 	}
684 	else if( ( base32_variant & 0x0f000000UL ) != LIBUNA_BASE32_VARIANT_PADDING_NONE )
685 	{
686 		libcerror_error_set(
687 		 error,
688 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
689 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
690 		 "%s: missing 5th base32 character.",
691 		 function );
692 
693 		return( -1 );
694 	}
695 	if( ( 2 * base32_character_size ) <= ( base32_stream_size - safe_base32_stream_index ) )
696 	{
697 		switch( base32_variant & 0xf0000000UL )
698 		{
699 			case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
700 				base32_character1 = base32_stream[ safe_base32_stream_index ];
701 				base32_character2 = base32_stream[ safe_base32_stream_index + 1 ];
702 				break;
703 
704 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
705 				byte_stream_copy_to_uint16_big_endian(
706 				 &( base32_stream[ safe_base32_stream_index ] ),
707 				 base32_character1 );
708 
709 				byte_stream_copy_to_uint16_big_endian(
710 				 &( base32_stream[ safe_base32_stream_index + 2 ] ),
711 				 base32_character2 );
712 				break;
713 
714 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
715 				byte_stream_copy_to_uint16_little_endian(
716 				 &( base32_stream[ safe_base32_stream_index ] ),
717 				 base32_character1 );
718 
719 				byte_stream_copy_to_uint16_little_endian(
720 				 &( base32_stream[ safe_base32_stream_index + 2 ] ),
721 				 base32_character2 );
722 				break;
723 
724 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
725 				byte_stream_copy_to_uint32_big_endian(
726 				 &( base32_stream[ safe_base32_stream_index ] ),
727 				 base32_character1 );
728 
729 				byte_stream_copy_to_uint32_big_endian(
730 				 &( base32_stream[ safe_base32_stream_index + 4 ] ),
731 				 base32_character2 );
732 				break;
733 
734 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
735 				byte_stream_copy_to_uint32_little_endian(
736 				 &( base32_stream[ safe_base32_stream_index ] ),
737 				 base32_character1 );
738 
739 				byte_stream_copy_to_uint32_little_endian(
740 				 &( base32_stream[ safe_base32_stream_index + 4 ] ),
741 				 base32_character2 );
742 				break;
743 		}
744 		safe_base32_stream_index += 2 * base32_character_size;
745 
746 		if( ( base32_character1 & 0xffffff00UL ) != 0 )
747 		{
748 			libcerror_error_set(
749 			 error,
750 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
751 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
752 			 "%s: invalid 6th base32 character.",
753 			 function );
754 
755 			return( -1 );
756 		}
757 		if( ( base32_character2 & 0xffffff00UL ) != 0 )
758 		{
759 			libcerror_error_set(
760 			 error,
761 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
762 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
763 			 "%s: invalid 7th base32 character.",
764 			 function );
765 
766 			return( -1 );
767 		}
768 		if( ( base32_character1 == (uint32_t) '=' )
769 		 || ( base32_character2 == (uint32_t) '=' ) )
770 		{
771 			if( ( base32_variant & 0x0f000000UL ) == LIBUNA_BASE32_VARIANT_PADDING_NONE )
772 			{
773 				libcerror_error_set(
774 				 error,
775 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
776 				 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
777 				 "%s: padding where not supposed to - invalid 6th or 7th base32 character.",
778 				 function );
779 
780 				return( -1 );
781 			}
782 			if( base32_character1 != (uint32_t) '=' )
783 			{
784 				libcerror_error_set(
785 				 error,
786 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
787 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
788 				 "%s: invalid 6th base32 quintet.",
789 				 function );
790 
791 				return( -1 );
792 			}
793 			if( base32_character2 != (uint32_t) '=' )
794 			{
795 				libcerror_error_set(
796 				 error,
797 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
798 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
799 				 "%s: invalid 7th base32 quintet.",
800 				 function );
801 
802 				return( -1 );
803 			}
804 		}
805 		else
806 		{
807 			if( safe_padding_size > 3 )
808 			{
809 				libcerror_error_set(
810 				 error,
811 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
812 				 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
813 				 "%s: non-padding where not supposed to - invalid 6th or 7th base32 character.",
814 				 function );
815 
816 				return( -1 );
817 			}
818 			if( libuna_base32_character_copy_to_quintet(
819 			     (uint8_t) base32_character1,
820 			     &quintet6,
821 			     base32_variant,
822 			     error ) != 1 )
823 			{
824 				libcerror_error_set(
825 				 error,
826 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
827 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
828 				 "%s: invalid 6th base32 quintet.",
829 				 function );
830 
831 				return( -1 );
832 			}
833 			if( libuna_base32_character_copy_to_quintet(
834 			     (uint8_t) base32_character2,
835 			     &quintet7,
836 			     base32_variant,
837 			     error ) != 1 )
838 			{
839 				libcerror_error_set(
840 				 error,
841 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
842 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
843 				 "%s: invalid 7th base32 quintet.",
844 				 function );
845 
846 				return( -1 );
847 			}
848 			safe_padding_size -= 2;
849 		}
850 	}
851 	else if( ( base32_variant & 0x0f000000UL ) != LIBUNA_BASE32_VARIANT_PADDING_NONE )
852 	{
853 		libcerror_error_set(
854 		 error,
855 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
856 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
857 		 "%s: missing 6th or 7th base32 character.",
858 		 function );
859 
860 		return( -1 );
861 	}
862 	if( base32_character_size <= ( base32_stream_size - safe_base32_stream_index ) )
863 	{
864 		switch( base32_variant & 0xf0000000UL )
865 		{
866 			case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
867 				base32_character1 = base32_stream[ safe_base32_stream_index ];
868 				break;
869 
870 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
871 				byte_stream_copy_to_uint16_big_endian(
872 				 &( base32_stream[ safe_base32_stream_index ] ),
873 				 base32_character1 );
874 				break;
875 
876 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
877 				byte_stream_copy_to_uint16_little_endian(
878 				 &( base32_stream[ safe_base32_stream_index ] ),
879 				 base32_character1 );
880 				break;
881 
882 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
883 				byte_stream_copy_to_uint32_big_endian(
884 				 &( base32_stream[ safe_base32_stream_index ] ),
885 				 base32_character1 );
886 				break;
887 
888 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
889 				byte_stream_copy_to_uint32_little_endian(
890 				 &( base32_stream[ safe_base32_stream_index ] ),
891 				 base32_character1 );
892 				break;
893 		}
894 		safe_base32_stream_index += base32_character_size;
895 
896 		if( ( base32_character1 & 0xffffff00UL ) != 0 )
897 		{
898 			libcerror_error_set(
899 			 error,
900 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
901 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
902 			 "%s: invalid 8th base32 character.",
903 			 function );
904 
905 			return( -1 );
906 		}
907 		if( base32_character1 == (uint32_t) '=' )
908 		{
909 			if( ( base32_variant & 0x0f000000UL ) == LIBUNA_BASE32_VARIANT_PADDING_NONE )
910 			{
911 				libcerror_error_set(
912 				 error,
913 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
914 				 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
915 				 "%s: padding where not supposed to - invalid 8th base32 character.",
916 				 function );
917 
918 				return( -1 );
919 			}
920 		}
921 		else
922 		{
923 			if( safe_padding_size > 1 )
924 			{
925 				libcerror_error_set(
926 				 error,
927 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
928 				 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
929 				 "%s: non-padding where not supposed to - invalid 8th base32 character.",
930 				 function );
931 
932 				return( -1 );
933 			}
934 			if( libuna_base32_character_copy_to_quintet(
935 			     (uint8_t) base32_character1,
936 			     &quintet8,
937 			     base32_variant,
938 			     error ) != 1 )
939 			{
940 				libcerror_error_set(
941 				 error,
942 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
943 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
944 				 "%s: invalid 8th base32 quintet.",
945 				 function );
946 
947 				return( -1 );
948 			}
949 			safe_padding_size -= 1;
950 		}
951 	}
952 	else if( ( base32_variant & 0x0f000000UL ) != LIBUNA_BASE32_VARIANT_PADDING_NONE )
953 	{
954 		libcerror_error_set(
955 		 error,
956 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
957 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
958 		 "%s: missing 8th base32 character.",
959 		 function );
960 
961 		return( -1 );
962 	}
963 	safe_base32_quintuplet   = quintet1;
964 	safe_base32_quintuplet <<= 5;
965 	safe_base32_quintuplet  |= quintet2;
966 	safe_base32_quintuplet <<= 5;
967 	safe_base32_quintuplet  |= quintet3;
968 	safe_base32_quintuplet <<= 5;
969 	safe_base32_quintuplet  |= quintet4;
970 	safe_base32_quintuplet <<= 5;
971 	safe_base32_quintuplet  |= quintet5;
972 	safe_base32_quintuplet <<= 5;
973 	safe_base32_quintuplet  |= quintet6;
974 	safe_base32_quintuplet <<= 5;
975 	safe_base32_quintuplet  |= quintet7;
976 	safe_base32_quintuplet <<= 5;
977 	safe_base32_quintuplet  |= quintet8;
978 
979 	*base32_stream_index = safe_base32_stream_index;
980 	*base32_quintuplet   = safe_base32_quintuplet;
981 	*padding_size        = safe_padding_size;
982 
983 	return( 1 );
984 }
985 
986 /* Copies a base32 quintuplet to a base32 stream
987  * Returns 1 if successful or -1 on error
988  */
libuna_base32_quintuplet_copy_to_base32_stream(uint64_t base32_quintuplet,uint8_t * base32_stream,size_t base32_stream_size,size_t * base32_stream_index,uint8_t padding_size,uint32_t base32_variant,libcerror_error_t ** error)989 int libuna_base32_quintuplet_copy_to_base32_stream(
990      uint64_t base32_quintuplet,
991      uint8_t *base32_stream,
992      size_t base32_stream_size,
993      size_t *base32_stream_index,
994      uint8_t padding_size,
995      uint32_t base32_variant,
996      libcerror_error_t **error )
997 {
998 	uint8_t *quintet_to_character_table = NULL;
999 	static char *function               = "libuna_base32_quintuplet_copy_to_base32_stream";
1000 	size_t base32_character_size        = 0;
1001 	size_t safe_base32_stream_index     = 0;
1002 	uint32_t base32_character1          = 0;
1003 	uint32_t base32_character2          = 0;
1004 	uint8_t quintet1                    = 0;
1005 	uint8_t quintet2                    = 0;
1006 	uint8_t quintet3                    = 0;
1007 	uint8_t quintet4                    = 0;
1008 	uint8_t quintet5                    = 0;
1009 	uint8_t quintet6                    = 0;
1010 	uint8_t quintet7                    = 0;
1011 	uint8_t quintet8                    = 0;
1012 
1013 	if( base32_stream == NULL )
1014 	{
1015 		libcerror_error_set(
1016 		 error,
1017 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1018 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1019 		 "%s: invalid base32 stream.",
1020 		 function );
1021 
1022 		return( -1 );
1023 	}
1024 	if( base32_stream_size > (size_t) SSIZE_MAX )
1025 	{
1026 		libcerror_error_set(
1027 		 error,
1028 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1029 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1030 		 "%s: invalid base32 stream size value exceeds maximum.",
1031 		 function );
1032 
1033 		return( -1 );
1034 	}
1035 	if( base32_stream_index == NULL )
1036 	{
1037 		libcerror_error_set(
1038 		 error,
1039 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1040 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1041 		 "%s: invalid base32 stream index.",
1042 		 function );
1043 
1044 		return( -1 );
1045 	}
1046 	if( *base32_stream_index >= base32_stream_size )
1047 	{
1048 		libcerror_error_set(
1049 		 error,
1050 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1051 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1052 		 "%s: base32 stream string too small.",
1053 		 function );
1054 
1055 		return( -1 );
1056 	}
1057 	if( padding_size > 6 )
1058 	{
1059 		libcerror_error_set(
1060 		 error,
1061 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1062 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1063 		 "%s: invalid padding size value out of bounds.",
1064 		 function );
1065 
1066 		return( -1 );
1067 	}
1068 	switch( base32_variant & 0x000f0000UL )
1069 	{
1070 		case LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL:
1071 			quintet_to_character_table = libuna_base32_quintet_to_character_table;
1072 			break;
1073 
1074 		case LIBUNA_BASE32_VARIANT_ALPHABET_HEX:
1075 			quintet_to_character_table = libuna_base32hex_quintet_to_character_table;
1076 			break;
1077 
1078 		default:
1079 			libcerror_error_set(
1080 			 error,
1081 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1082 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1083 			 "%s: unsupported base32 variant.",
1084 			 function );
1085 
1086 			return( -1 );
1087 	}
1088 	switch( base32_variant & 0x0f000000UL )
1089 	{
1090 		case LIBUNA_BASE32_VARIANT_PADDING_NONE:
1091 		case LIBUNA_BASE32_VARIANT_PADDING_OPTIONAL:
1092 		case LIBUNA_BASE32_VARIANT_PADDING_REQUIRED:
1093 			break;
1094 
1095 		default:
1096 			libcerror_error_set(
1097 			 error,
1098 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1099 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1100 			 "%s: unsupported base32 variant.",
1101 			 function );
1102 
1103 			return( -1 );
1104 	}
1105 	switch( base32_variant & 0xf0000000UL )
1106 	{
1107 		case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
1108 			base32_character_size = 1;
1109 			break;
1110 
1111 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
1112 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
1113 			base32_character_size = 2;
1114 			break;
1115 
1116 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
1117 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
1118 			base32_character_size = 4;
1119 			break;
1120 
1121 		default:
1122 			libcerror_error_set(
1123 			 error,
1124 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1125 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1126 			 "%s: unsupported base32 variant.",
1127 			 function );
1128 
1129 			return( -1 );
1130 	}
1131 	safe_base32_stream_index = *base32_stream_index;
1132 
1133 	/* Separate the 3 bytes value into 8 x 5 bit values
1134 	 */
1135 	quintet8          = (uint8_t) ( base32_quintuplet & 0x1f );
1136 	base32_quintuplet >>= 5;
1137 	quintet7          = (uint8_t) ( base32_quintuplet & 0x1f );
1138 	base32_quintuplet >>= 5;
1139 	quintet6          = (uint8_t) ( base32_quintuplet & 0x1f );
1140 	base32_quintuplet >>= 5;
1141 	quintet5          = (uint8_t) ( base32_quintuplet & 0x1f );
1142 	base32_quintuplet >>= 5;
1143 	quintet4          = (uint8_t) ( base32_quintuplet & 0x1f );
1144 	base32_quintuplet >>= 5;
1145 	quintet3          = (uint8_t) ( base32_quintuplet & 0x1f );
1146 	base32_quintuplet >>= 5;
1147 	quintet2          = (uint8_t) ( base32_quintuplet & 0x1f );
1148 	base32_quintuplet >>= 5;
1149 	quintet1          = (uint8_t) ( base32_quintuplet & 0x1f );
1150 
1151 	/* Spread the encoding over 2 characters if 1 byte is available
1152 	 */
1153 	if( ( 2 * base32_character_size ) > ( base32_stream_size - safe_base32_stream_index ) )
1154 	{
1155 		libcerror_error_set(
1156 		 error,
1157 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1158 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1159 		 "%s: base32 stream is too small - insufficient space for 1st and 2nd base32 characters.",
1160 		 function );
1161 
1162 		return( -1 );
1163 	}
1164 	base32_character1 = (uint32_t) quintet_to_character_table[ quintet1 ];
1165 	base32_character2 = (uint32_t) quintet_to_character_table[ quintet2 ];
1166 
1167 	switch( base32_variant & 0xf0000000UL )
1168 	{
1169 		case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
1170 			base32_stream[ safe_base32_stream_index     ] = (uint8_t) base32_character1;
1171 			base32_stream[ safe_base32_stream_index + 1 ] = (uint8_t) base32_character2;
1172 			break;
1173 
1174 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
1175 			byte_stream_copy_from_uint16_big_endian(
1176 			 &( base32_stream[ safe_base32_stream_index ] ),
1177 			 base32_character1 );
1178 
1179 			byte_stream_copy_from_uint16_big_endian(
1180 			 &( base32_stream[ safe_base32_stream_index + 2 ] ),
1181 			 base32_character2 );
1182 			break;
1183 
1184 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
1185 			byte_stream_copy_from_uint16_little_endian(
1186 			 &( base32_stream[ safe_base32_stream_index ] ),
1187 			 base32_character1 );
1188 
1189 			byte_stream_copy_from_uint16_little_endian(
1190 			 &( base32_stream[ safe_base32_stream_index + 2 ] ),
1191 			 base32_character2 );
1192 			break;
1193 
1194 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
1195 			byte_stream_copy_from_uint32_big_endian(
1196 			 &( base32_stream[ safe_base32_stream_index ] ),
1197 			 base32_character1 );
1198 
1199 			byte_stream_copy_from_uint32_big_endian(
1200 			 &( base32_stream[ safe_base32_stream_index + 4 ] ),
1201 			 base32_character2 );
1202 			break;
1203 
1204 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
1205 			byte_stream_copy_from_uint32_little_endian(
1206 			 &( base32_stream[ safe_base32_stream_index ] ),
1207 			 base32_character1 );
1208 
1209 			byte_stream_copy_from_uint32_little_endian(
1210 			 &( base32_stream[ safe_base32_stream_index + 4 ] ),
1211 			 base32_character2 );
1212 			break;
1213 	}
1214 	safe_base32_stream_index += 2 * base32_character_size;
1215 
1216 	/* Spread the encoding over 4 characters if 2 bytes are available
1217 	 * Otherwise pad the remaining bytes if required
1218 	 */
1219 	if( ( padding_size < 6 )
1220 	 || ( ( base32_variant & 0x0f000000UL ) != LIBUNA_BASE32_VARIANT_PADDING_NONE ) )
1221 	{
1222 		if( ( 2 * base32_character_size ) > ( base32_stream_size - safe_base32_stream_index ) )
1223 		{
1224 			libcerror_error_set(
1225 			 error,
1226 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1227 			 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1228 			 "%s: base32 stream is too small - insufficient space for 3rd and 4th base32 characters.",
1229 			 function );
1230 
1231 			return( -1 );
1232 		}
1233 		if( padding_size < 6 )
1234 		{
1235 			base32_character1 = (uint32_t) quintet_to_character_table[ quintet3 ];
1236 			base32_character2 = (uint32_t) quintet_to_character_table[ quintet4 ];
1237 		}
1238 		else
1239 		{
1240 			base32_character1 = (uint32_t) '=';
1241 			base32_character2 = (uint32_t) '=';
1242 		}
1243 		switch( base32_variant & 0xf0000000UL )
1244 		{
1245 			case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
1246 				base32_stream[ safe_base32_stream_index     ] = (uint8_t) base32_character1;
1247 				base32_stream[ safe_base32_stream_index + 1 ] = (uint8_t) base32_character2;
1248 				break;
1249 
1250 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
1251 				byte_stream_copy_from_uint16_big_endian(
1252 				 &( base32_stream[ safe_base32_stream_index ] ),
1253 				 base32_character1 );
1254 
1255 				byte_stream_copy_from_uint16_big_endian(
1256 				 &( base32_stream[ safe_base32_stream_index + 2 ] ),
1257 				 base32_character2 );
1258 				break;
1259 
1260 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
1261 				byte_stream_copy_from_uint16_little_endian(
1262 				 &( base32_stream[ safe_base32_stream_index ] ),
1263 				 base32_character1 );
1264 
1265 				byte_stream_copy_from_uint16_little_endian(
1266 				 &( base32_stream[ safe_base32_stream_index + 2 ] ),
1267 				 base32_character2 );
1268 				break;
1269 
1270 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
1271 				byte_stream_copy_from_uint32_big_endian(
1272 				 &( base32_stream[ safe_base32_stream_index ] ),
1273 				 base32_character1 );
1274 
1275 				byte_stream_copy_from_uint32_big_endian(
1276 				 &( base32_stream[ safe_base32_stream_index + 4 ] ),
1277 				 base32_character2 );
1278 				break;
1279 
1280 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
1281 				byte_stream_copy_from_uint32_little_endian(
1282 				 &( base32_stream[ safe_base32_stream_index ] ),
1283 				 base32_character1 );
1284 
1285 				byte_stream_copy_from_uint32_little_endian(
1286 				 &( base32_stream[ safe_base32_stream_index + 4 ] ),
1287 				 base32_character2 );
1288 				break;
1289 		}
1290 		safe_base32_stream_index += 2 * base32_character_size;
1291 	}
1292 	/* Spread the encoding over 5 characters if 3 bytes are available
1293 	 * Otherwise pad the remaining bytes if required
1294 	 */
1295 	if( ( padding_size < 4 )
1296 	 || ( ( base32_variant & 0x0f000000UL ) != LIBUNA_BASE32_VARIANT_PADDING_NONE ) )
1297 	{
1298 		if( base32_character_size > ( base32_stream_size - safe_base32_stream_index ) )
1299 		{
1300 			libcerror_error_set(
1301 			 error,
1302 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1303 			 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1304 			 "%s: base32 stream is too small - insufficient space for 5th base32 character.",
1305 			 function );
1306 
1307 			return( -1 );
1308 		}
1309 		if( padding_size < 4 )
1310 		{
1311 			base32_character1 = (uint32_t) quintet_to_character_table[ quintet5 ];
1312 		}
1313 		else
1314 		{
1315 			base32_character1 = (uint32_t) '=';
1316 		}
1317 		switch( base32_variant & 0xf0000000UL )
1318 		{
1319 			case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
1320 				base32_stream[ safe_base32_stream_index ] = (uint8_t) base32_character1;
1321 				break;
1322 
1323 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
1324 				byte_stream_copy_from_uint16_big_endian(
1325 				 &( base32_stream[ safe_base32_stream_index ] ),
1326 				 base32_character1 );
1327 				break;
1328 
1329 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
1330 				byte_stream_copy_from_uint16_little_endian(
1331 				 &( base32_stream[ safe_base32_stream_index ] ),
1332 				 base32_character1 );
1333 				break;
1334 
1335 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
1336 				byte_stream_copy_from_uint32_big_endian(
1337 				 &( base32_stream[ safe_base32_stream_index ] ),
1338 				 base32_character1 );
1339 				break;
1340 
1341 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
1342 				byte_stream_copy_from_uint32_little_endian(
1343 				 &( base32_stream[ safe_base32_stream_index ] ),
1344 				 base32_character1 );
1345 				break;
1346 		}
1347 		safe_base32_stream_index += base32_character_size;
1348 	}
1349 	/* Spread the encoding over 7 characters if 4 bytes are available
1350 	 * Otherwise pad the remaining bytes if required
1351 	 */
1352 	if( ( padding_size < 3 )
1353 	 || ( ( base32_variant & 0x0f000000UL ) != LIBUNA_BASE32_VARIANT_PADDING_NONE ) )
1354 	{
1355 		if( ( 2 * base32_character_size ) > ( base32_stream_size - safe_base32_stream_index ) )
1356 		{
1357 			libcerror_error_set(
1358 			 error,
1359 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1360 			 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1361 			 "%s: base32 stream is too small - insufficient space for 6th and 7th base32 characters.",
1362 			 function );
1363 
1364 			return( -1 );
1365 		}
1366 		if( padding_size < 3 )
1367 		{
1368 			base32_character1 = (uint32_t) quintet_to_character_table[ quintet6 ];
1369 			base32_character2 = (uint32_t) quintet_to_character_table[ quintet7 ];
1370 		}
1371 		else
1372 		{
1373 			base32_character1 = (uint32_t) '=';
1374 			base32_character2 = (uint32_t) '=';
1375 		}
1376 		switch( base32_variant & 0xf0000000UL )
1377 		{
1378 			case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
1379 				base32_stream[ safe_base32_stream_index     ] = (uint8_t) base32_character1;
1380 				base32_stream[ safe_base32_stream_index + 1 ] = (uint8_t) base32_character2;
1381 				break;
1382 
1383 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
1384 				byte_stream_copy_from_uint16_big_endian(
1385 				 &( base32_stream[ safe_base32_stream_index ] ),
1386 				 base32_character1 );
1387 
1388 				byte_stream_copy_from_uint16_big_endian(
1389 				 &( base32_stream[ safe_base32_stream_index + 2 ] ),
1390 				 base32_character2 );
1391 				break;
1392 
1393 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
1394 				byte_stream_copy_from_uint16_little_endian(
1395 				 &( base32_stream[ safe_base32_stream_index ] ),
1396 				 base32_character1 );
1397 
1398 				byte_stream_copy_from_uint16_little_endian(
1399 				 &( base32_stream[ safe_base32_stream_index + 2 ] ),
1400 				 base32_character2 );
1401 				break;
1402 
1403 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
1404 				byte_stream_copy_from_uint32_big_endian(
1405 				 &( base32_stream[ safe_base32_stream_index ] ),
1406 				 base32_character1 );
1407 
1408 				byte_stream_copy_from_uint32_big_endian(
1409 				 &( base32_stream[ safe_base32_stream_index + 4 ] ),
1410 				 base32_character2 );
1411 				break;
1412 
1413 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
1414 				byte_stream_copy_from_uint32_little_endian(
1415 				 &( base32_stream[ safe_base32_stream_index ] ),
1416 				 base32_character1 );
1417 
1418 				byte_stream_copy_from_uint32_little_endian(
1419 				 &( base32_stream[ safe_base32_stream_index + 4 ] ),
1420 				 base32_character2 );
1421 				break;
1422 		}
1423 		safe_base32_stream_index += 2 * base32_character_size;
1424 	}
1425 	/* Spread the encoding over 8 characters if 5 bytes are available
1426 	 * Otherwise pad the remaining bytes if required
1427 	 */
1428 	if( ( padding_size < 1 )
1429 	 || ( ( base32_variant & 0x0f000000UL ) != LIBUNA_BASE32_VARIANT_PADDING_NONE ) )
1430 	{
1431 		if( base32_character_size > ( base32_stream_size - safe_base32_stream_index ) )
1432 		{
1433 			libcerror_error_set(
1434 			 error,
1435 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1436 			 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1437 			 "%s: base32 stream is too small - insufficient space for 8th base32 character.",
1438 			 function );
1439 
1440 			return( -1 );
1441 		}
1442 		if( padding_size < 1 )
1443 		{
1444 			base32_character1 = (uint32_t) quintet_to_character_table[ quintet8 ];
1445 		}
1446 		else
1447 		{
1448 			base32_character1 = (uint32_t) '=';
1449 		}
1450 		switch( base32_variant & 0xf0000000UL )
1451 		{
1452 			case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
1453 				base32_stream[ safe_base32_stream_index ] = (uint8_t) base32_character1;
1454 				break;
1455 
1456 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
1457 				byte_stream_copy_from_uint16_big_endian(
1458 				 &( base32_stream[ safe_base32_stream_index ] ),
1459 				 base32_character1 );
1460 				break;
1461 
1462 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
1463 				byte_stream_copy_from_uint16_little_endian(
1464 				 &( base32_stream[ safe_base32_stream_index ] ),
1465 				 base32_character1 );
1466 				break;
1467 
1468 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
1469 				byte_stream_copy_from_uint32_big_endian(
1470 				 &( base32_stream[ safe_base32_stream_index ] ),
1471 				 base32_character1 );
1472 				break;
1473 
1474 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
1475 				byte_stream_copy_from_uint32_little_endian(
1476 				 &( base32_stream[ safe_base32_stream_index ] ),
1477 				 base32_character1 );
1478 				break;
1479 		}
1480 		safe_base32_stream_index += base32_character_size;
1481 	}
1482 	*base32_stream_index = safe_base32_stream_index;
1483 
1484 	return( 1 );
1485 }
1486 
1487 /* Copies a base32 quintuplet from a byte stream
1488  * Returns 1 if successful or -1 on error
1489  */
libuna_base32_quintuplet_copy_from_byte_stream(uint64_t * base32_quintuplet,const uint8_t * byte_stream,size_t byte_stream_size,size_t * byte_stream_index,uint8_t * padding_size,libcerror_error_t ** error)1490 int libuna_base32_quintuplet_copy_from_byte_stream(
1491      uint64_t *base32_quintuplet,
1492      const uint8_t *byte_stream,
1493      size_t byte_stream_size,
1494      size_t *byte_stream_index,
1495      uint8_t *padding_size,
1496      libcerror_error_t **error )
1497 {
1498 	static char *function           = "libuna_base32_quintuplet_copy_from_byte_stream";
1499 	size_t safe_byte_stream_index   = 0;
1500 	uint64_t safe_base32_quintuplet = 0;
1501 	uint8_t safe_padding_size       = 0;
1502 
1503 	if( base32_quintuplet == NULL )
1504 	{
1505 		libcerror_error_set(
1506 		 error,
1507 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1508 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1509 		 "%s: invalid base32 quintuplet.",
1510 		 function );
1511 
1512 		return( -1 );
1513 	}
1514 	if( byte_stream == NULL )
1515 	{
1516 		libcerror_error_set(
1517 		 error,
1518 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1519 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1520 		 "%s: invalid byte stream.",
1521 		 function );
1522 
1523 		return( -1 );
1524 	}
1525 	if( byte_stream_size > (size_t) SSIZE_MAX )
1526 	{
1527 		libcerror_error_set(
1528 		 error,
1529 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1530 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1531 		 "%s: invalid byte stream size value exceeds maximum.",
1532 		 function );
1533 
1534 		return( -1 );
1535 	}
1536 	if( byte_stream_index == NULL )
1537 	{
1538 		libcerror_error_set(
1539 		 error,
1540 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1541 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1542 		 "%s: invalid byte stream index.",
1543 		 function );
1544 
1545 		return( -1 );
1546 	}
1547 	if( *byte_stream_index >= byte_stream_size )
1548 	{
1549 		libcerror_error_set(
1550 		 error,
1551 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1552 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1553 		 "%s: byte stream string too small.",
1554 		 function );
1555 
1556 		return( -1 );
1557 	}
1558 	if( padding_size == NULL )
1559 	{
1560 		libcerror_error_set(
1561 		 error,
1562 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1563 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1564 		 "%s: invalid padding size.",
1565 		 function );
1566 
1567 		return( -1 );
1568 	}
1569 	/* Determine the value of 5 bytes (40 bits)
1570 	 */
1571 	safe_byte_stream_index = *byte_stream_index;
1572 
1573 	safe_base32_quintuplet = byte_stream[ safe_byte_stream_index++ ];
1574 	safe_padding_size      = 6;
1575 
1576 	safe_base32_quintuplet <<= 8;
1577 
1578 	if( safe_byte_stream_index < byte_stream_size )
1579 	{
1580 		safe_base32_quintuplet |= byte_stream[ safe_byte_stream_index++ ];
1581 		safe_padding_size      -= 2;
1582 	}
1583 	safe_base32_quintuplet <<= 8;
1584 
1585 	if( safe_byte_stream_index < byte_stream_size )
1586 	{
1587 		safe_base32_quintuplet |= byte_stream[ safe_byte_stream_index++ ];
1588 		safe_padding_size      -= 1;
1589 	}
1590 	safe_base32_quintuplet <<= 8;
1591 
1592 	if( safe_byte_stream_index < byte_stream_size )
1593 	{
1594 		safe_base32_quintuplet |= byte_stream[ safe_byte_stream_index++ ];
1595 		safe_padding_size      -= 2;
1596 	}
1597 	safe_base32_quintuplet <<= 8;
1598 
1599 	if( safe_byte_stream_index < byte_stream_size )
1600 	{
1601 		safe_base32_quintuplet |= byte_stream[ safe_byte_stream_index++ ];
1602 		safe_padding_size      -= 1;
1603 	}
1604 	*base32_quintuplet = safe_base32_quintuplet;
1605 	*byte_stream_index = safe_byte_stream_index;
1606 	*padding_size      = safe_padding_size;
1607 
1608 	return( 1 );
1609 }
1610 
1611 /* Copies a base32 quintuplet to a byte stream
1612  * Returns 1 if successful or -1 on error
1613  */
libuna_base32_quintuplet_copy_to_byte_stream(uint64_t base32_quintuplet,uint8_t * byte_stream,size_t byte_stream_size,size_t * byte_stream_index,uint8_t padding_size,libcerror_error_t ** error)1614 int libuna_base32_quintuplet_copy_to_byte_stream(
1615      uint64_t base32_quintuplet,
1616      uint8_t *byte_stream,
1617      size_t byte_stream_size,
1618      size_t *byte_stream_index,
1619      uint8_t padding_size,
1620      libcerror_error_t **error )
1621 {
1622 	static char *function         = "libuna_base32_quintuplet_copy_to_byte_stream";
1623 	size_t safe_byte_stream_index = 0;
1624 
1625 	if( byte_stream == NULL )
1626 	{
1627 		libcerror_error_set(
1628 		 error,
1629 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1630 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1631 		 "%s: invalid byte stream.",
1632 		 function );
1633 
1634 		return( -1 );
1635 	}
1636 	if( byte_stream_size > (size_t) SSIZE_MAX )
1637 	{
1638 		libcerror_error_set(
1639 		 error,
1640 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1641 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1642 		 "%s: invalid byte stream size value exceeds maximum.",
1643 		 function );
1644 
1645 		return( -1 );
1646 	}
1647 	if( byte_stream_index == NULL )
1648 	{
1649 		libcerror_error_set(
1650 		 error,
1651 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1652 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1653 		 "%s: invalid byte stream index.",
1654 		 function );
1655 
1656 		return( -1 );
1657 	}
1658 	if( *byte_stream_index >= byte_stream_size )
1659 	{
1660 		libcerror_error_set(
1661 		 error,
1662 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1663 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1664 		 "%s: byte stream string too small.",
1665 		 function );
1666 
1667 		return( -1 );
1668 	}
1669 	if( padding_size > 6 )
1670 	{
1671 		libcerror_error_set(
1672 		 error,
1673 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1674 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1675 		 "%s: invalid padding size value out of bounds.",
1676 		 function );
1677 
1678 		return( -1 );
1679 	}
1680 	safe_byte_stream_index = *byte_stream_index;
1681 
1682 	byte_stream[ safe_byte_stream_index++ ] = (uint8_t) ( ( base32_quintuplet >> 32 ) & 0xff );
1683 
1684 	if( padding_size <= 4 )
1685 	{
1686 		if( safe_byte_stream_index >= byte_stream_size )
1687 		{
1688 			libcerror_error_set(
1689 			 error,
1690 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1691 			 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1692 			 "%s: byte stream string too small.",
1693 			 function );
1694 
1695 			return( -1 );
1696 		}
1697 		byte_stream[ safe_byte_stream_index++ ] = (uint8_t) ( ( base32_quintuplet >> 24 ) & 0xff );
1698 	}
1699 	if( padding_size <= 3 )
1700 	{
1701 		if( safe_byte_stream_index >= byte_stream_size )
1702 		{
1703 			libcerror_error_set(
1704 			 error,
1705 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1706 			 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1707 			 "%s: byte stream string too small.",
1708 			 function );
1709 
1710 			return( -1 );
1711 		}
1712 		byte_stream[ safe_byte_stream_index++ ] = (uint8_t) ( ( base32_quintuplet >> 16 ) & 0xff );
1713 	}
1714 	if( padding_size <= 2 )
1715 	{
1716 		if( safe_byte_stream_index >= byte_stream_size )
1717 		{
1718 			libcerror_error_set(
1719 			 error,
1720 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1721 			 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1722 			 "%s: byte stream string too small.",
1723 			 function );
1724 
1725 			return( -1 );
1726 		}
1727 		byte_stream[ safe_byte_stream_index++ ] = (uint8_t) ( ( base32_quintuplet >> 8 ) & 0xff );
1728 	}
1729 	if( padding_size == 0 )
1730 	{
1731 		if( safe_byte_stream_index >= byte_stream_size )
1732 		{
1733 			libcerror_error_set(
1734 			 error,
1735 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1736 			 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1737 			 "%s: byte stream is too small.",
1738 			 function );
1739 
1740 			return( -1 );
1741 		}
1742 		byte_stream[ safe_byte_stream_index++ ] = (uint8_t) ( base32_quintuplet & 0xff );
1743 	}
1744 	*byte_stream_index = safe_byte_stream_index;
1745 
1746 	return( 1 );
1747 }
1748 
1749 /* Determines the size of a byte stream from a base32 stream
1750  *
1751  * LIBUNA_BASE32_FLAG_STRIP_WHITESPACE removes leading space and tab characters,
1752  * and trailing space, tab and end of line characters
1753  *
1754  * Returns 1 if successful or -1 on error
1755  */
libuna_base32_stream_size_to_byte_stream(const uint8_t * base32_stream,size_t base32_stream_size,size_t * byte_stream_size,uint32_t base32_variant,uint8_t flags,libcerror_error_t ** error)1756 int libuna_base32_stream_size_to_byte_stream(
1757      const uint8_t *base32_stream,
1758      size_t base32_stream_size,
1759      size_t *byte_stream_size,
1760      uint32_t base32_variant,
1761      uint8_t flags,
1762      libcerror_error_t **error )
1763 {
1764 	static char *function        = "libuna_base32_stream_size_to_byte_stream";
1765 	size_t base32_character_size = 0;
1766 	size_t base32_stream_index   = 0;
1767 	size_t number_of_characters  = 0;
1768 	size_t safe_byte_stream_size = 0;
1769 	size_t whitespace_size       = 0;
1770 	uint32_t base32_character1   = 0;
1771 	uint32_t base32_character2   = 0;
1772 	uint8_t character_limit      = 0;
1773 	uint8_t padding_size         = 0;
1774 	uint8_t strip_mode           = LIBUNA_STRIP_MODE_LEADING_WHITESPACE;
1775 
1776 	if( base32_stream == NULL )
1777 	{
1778 		libcerror_error_set(
1779 		 error,
1780 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1781 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1782 		 "%s: invalid base32 stream.",
1783 		 function );
1784 
1785 		return( -1 );
1786 	}
1787 	if( base32_stream_size > (size_t) SSIZE_MAX )
1788 	{
1789 		libcerror_error_set(
1790 		 error,
1791 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1792 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1793 		 "%s: invalid base32 stream size value exceeds maximum.",
1794 		 function );
1795 
1796 		return( -1 );
1797 	}
1798 	if( byte_stream_size == NULL )
1799 	{
1800 		libcerror_error_set(
1801 		 error,
1802 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1803 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1804 		 "%s: invalid byte stream size.",
1805 		 function );
1806 
1807 		return( -1 );
1808 	}
1809 	switch( base32_variant & 0x000000ffUL )
1810 	{
1811 		case LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE:
1812 			character_limit = 0;
1813 			break;
1814 
1815 		case LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_64:
1816 			character_limit = 64;
1817 			break;
1818 
1819 		default:
1820 			libcerror_error_set(
1821 			 error,
1822 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1823 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1824 			 "%s: unsupported base32 variant.",
1825 			 function );
1826 
1827 			return( -1 );
1828 	}
1829 	switch( base32_variant & 0x000f0000UL )
1830 	{
1831 		case LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL:
1832 		case LIBUNA_BASE32_VARIANT_ALPHABET_HEX:
1833 			break;
1834 
1835 		default:
1836 			libcerror_error_set(
1837 			 error,
1838 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1839 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1840 			 "%s: unsupported base32 variant.",
1841 			 function );
1842 
1843 			return( -1 );
1844 	}
1845 	switch( base32_variant & 0xf0000000UL )
1846 	{
1847 		case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
1848 			base32_character_size = 1;
1849 			break;
1850 
1851 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
1852 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
1853 			base32_character_size = 2;
1854 			break;
1855 
1856 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
1857 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
1858 			base32_character_size = 4;
1859 			break;
1860 
1861 		default:
1862 			libcerror_error_set(
1863 			 error,
1864 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1865 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1866 			 "%s: unsupported base32 variant.",
1867 			 function );
1868 
1869 			return( -1 );
1870 	}
1871 	if( ( flags & ~( LIBUNA_BASE32_FLAG_STRIP_WHITESPACE ) ) != 0 )
1872 	{
1873 		libcerror_error_set(
1874 		 error,
1875 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1876 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1877 		 "%s: unsupported flags.",
1878 		 function );
1879 
1880 		return( -1 );
1881 	}
1882 	/* Ignore trailing whitespace
1883 	 */
1884 	if( base32_stream_size > base32_character_size )
1885 	{
1886 		base32_stream_index = base32_stream_size - base32_character_size;
1887 		whitespace_size     = 0;
1888 
1889 		while( base32_stream_index > base32_character_size )
1890 		{
1891 			switch( base32_variant & 0xf0000000UL )
1892 			{
1893 				case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
1894 					base32_character1 = base32_stream[ base32_stream_index ];
1895 					break;
1896 
1897 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
1898 					byte_stream_copy_to_uint16_big_endian(
1899 					 &( base32_stream[ base32_stream_index ] ),
1900 					 base32_character1 );
1901 					break;
1902 
1903 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
1904 					byte_stream_copy_to_uint16_little_endian(
1905 					 &( base32_stream[ base32_stream_index ] ),
1906 					 base32_character1 );
1907 					break;
1908 
1909 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
1910 					byte_stream_copy_to_uint32_big_endian(
1911 					 &( base32_stream[ base32_stream_index ] ),
1912 					 base32_character1 );
1913 					break;
1914 
1915 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
1916 					byte_stream_copy_to_uint32_little_endian(
1917 					 &( base32_stream[ base32_stream_index ] ),
1918 					 base32_character1 );
1919 					break;
1920 			}
1921 			base32_stream_index -= base32_character_size;
1922 
1923 			if( ( base32_character1 == (uint32_t) '\n' )
1924 			 || ( base32_character1 == (uint32_t) '\r' ) )
1925 			{
1926 				whitespace_size += base32_character_size;
1927 
1928 				continue;
1929 			}
1930 			else if( ( flags & LIBUNA_BASE32_FLAG_STRIP_WHITESPACE ) == 0 )
1931 			{
1932 				break;
1933 			}
1934 			if( ( base32_character1 == (uint32_t) ' ' )
1935 			 || ( base32_character1 == (uint32_t) '\t' )
1936 			 || ( base32_character1 == (uint32_t) '\v' ) )
1937 			{
1938 				whitespace_size += base32_character_size;
1939 			}
1940 			else
1941 			{
1942 				break;
1943 			}
1944 		}
1945 		base32_stream_size -= whitespace_size;
1946 	}
1947 	/* Determine and ignore the padding
1948 	 */
1949 	if( base32_stream_size > base32_character_size )
1950 	{
1951 		base32_stream_index = base32_stream_size - base32_character_size;
1952 
1953 		while( ( base32_stream_index > base32_character_size )
1954 		    && ( padding_size <= 6 ) )
1955 		{
1956 			switch( base32_variant & 0xf0000000UL )
1957 			{
1958 				case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
1959 					base32_character1 = base32_stream[ base32_stream_index ];
1960 					break;
1961 
1962 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
1963 					byte_stream_copy_to_uint16_big_endian(
1964 					 &( base32_stream[ base32_stream_index ] ),
1965 					 base32_character1 );
1966 					break;
1967 
1968 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
1969 					byte_stream_copy_to_uint16_little_endian(
1970 					 &( base32_stream[ base32_stream_index ] ),
1971 					 base32_character1 );
1972 					break;
1973 
1974 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
1975 					byte_stream_copy_to_uint32_big_endian(
1976 					 &( base32_stream[ base32_stream_index ] ),
1977 					 base32_character1 );
1978 					break;
1979 
1980 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
1981 					byte_stream_copy_to_uint32_little_endian(
1982 					 &( base32_stream[ base32_stream_index ] ),
1983 					 base32_character1 );
1984 					break;
1985 			}
1986 			base32_stream_index -= base32_character_size;
1987 
1988 			if( base32_character1 == (uint32_t) '=' )
1989 			{
1990 				padding_size += 1;
1991 			}
1992 		}
1993 		if( padding_size > 6 )
1994 		{
1995 			libcerror_error_set(
1996 			 error,
1997 			 LIBCERROR_ERROR_DOMAIN_CONVERSION,
1998 			 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
1999 			 "%s: invalid amount of padding - found more than 6 padding characters.",
2000 			 function );
2001 
2002 			return( -1 );
2003 		}
2004 		base32_stream_size -= padding_size * base32_character_size;
2005 	}
2006 	base32_stream_index = 0;
2007 	whitespace_size     = 0;
2008 
2009 	while( ( base32_stream_index + base32_character_size ) < base32_stream_size )
2010 	{
2011 		switch( base32_variant & 0xf0000000UL )
2012 		{
2013 			case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
2014 				base32_character1 = base32_stream[ base32_stream_index ];
2015 				break;
2016 
2017 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
2018 				byte_stream_copy_to_uint16_big_endian(
2019 				 &( base32_stream[ base32_stream_index ] ),
2020 				 base32_character1 );
2021 				break;
2022 
2023 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
2024 				byte_stream_copy_to_uint16_little_endian(
2025 				 &( base32_stream[ base32_stream_index ] ),
2026 				 base32_character1 );
2027 				break;
2028 
2029 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
2030 				byte_stream_copy_to_uint32_big_endian(
2031 				 &( base32_stream[ base32_stream_index ] ),
2032 				 base32_character1 );
2033 				break;
2034 
2035 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
2036 				byte_stream_copy_to_uint32_little_endian(
2037 				 &( base32_stream[ base32_stream_index ] ),
2038 				 base32_character1 );
2039 				break;
2040 		}
2041 		if( ( base32_character1 == (uint32_t) '\n' )
2042 		 || ( base32_character1 == (uint32_t) '\r' ) )
2043 		{
2044 			if( ( strip_mode != LIBUNA_STRIP_MODE_NON_WHITESPACE )
2045 			 && ( strip_mode != LIBUNA_STRIP_MODE_TRAILING_WHITESPACE ) )
2046 			{
2047 				strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2048 			}
2049 			else
2050 			{
2051 				/* Handle multi-character end-of-line
2052 				 */
2053 				if( ( base32_stream_index + base32_character_size ) < base32_stream_size )
2054 				{
2055 					switch( base32_variant & 0xf0000000UL )
2056 					{
2057 						case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
2058 							base32_character2 = base32_stream[ base32_stream_index + 1 ];
2059 							break;
2060 
2061 						case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
2062 							byte_stream_copy_to_uint16_big_endian(
2063 							 &( base32_stream[ base32_stream_index + 2 ] ),
2064 							 base32_character2 );
2065 							break;
2066 
2067 						case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
2068 							byte_stream_copy_to_uint16_little_endian(
2069 							 &( base32_stream[ base32_stream_index + 2 ] ),
2070 							 base32_character2 );
2071 							break;
2072 
2073 						case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
2074 							byte_stream_copy_to_uint32_big_endian(
2075 							 &( base32_stream[ base32_stream_index + 4 ] ),
2076 							 base32_character2 );
2077 							break;
2078 
2079 						case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
2080 							byte_stream_copy_to_uint32_little_endian(
2081 							 &( base32_stream[ base32_stream_index + 4 ] ),
2082 							 base32_character2 );
2083 							break;
2084 					}
2085 					if( ( base32_character2 == (uint32_t) '\n' )
2086 					 || ( base32_character2 == (uint32_t) '\r' ) )
2087 					{
2088 						base32_stream_index += base32_character_size;
2089 
2090 						whitespace_size += base32_character_size;
2091 					}
2092 				}
2093 				strip_mode = LIBUNA_STRIP_MODE_LEADING_WHITESPACE;
2094 			}
2095 			if( ( number_of_characters != 0 )
2096 			 && ( character_limit != 0 ) )
2097 			{
2098 				if( number_of_characters != (size_t) character_limit )
2099 				{
2100 					libcerror_error_set(
2101 					 error,
2102 					 LIBCERROR_ERROR_DOMAIN_CONVERSION,
2103 					 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
2104 					 "%s: number of characters in line: %" PRIzd " does not match character limit: %" PRIu8 ".",
2105 					 function,
2106 					 number_of_characters,
2107 					 character_limit );
2108 
2109 					return( -1 );
2110 				}
2111 				number_of_characters = 0;
2112 			}
2113 			whitespace_size += base32_character_size;
2114 		}
2115 		else if( ( base32_character1 == (uint32_t) ' ' )
2116 		      || ( base32_character1 == (uint32_t) '\t' )
2117 		      || ( base32_character1 == (uint32_t) '\v' ) )
2118 		{
2119 			if( ( flags & LIBUNA_BASE32_FLAG_STRIP_WHITESPACE ) == 0 )
2120 			{
2121 				strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2122 			}
2123 			else
2124 			{
2125 				if( strip_mode == LIBUNA_STRIP_MODE_NON_WHITESPACE )
2126 				{
2127 					strip_mode = LIBUNA_STRIP_MODE_TRAILING_WHITESPACE;
2128 				}
2129 				if( ( strip_mode != LIBUNA_STRIP_MODE_LEADING_WHITESPACE )
2130 				 && ( strip_mode != LIBUNA_STRIP_MODE_TRAILING_WHITESPACE ) )
2131 				{
2132 					strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2133 				}
2134 				else
2135 				{
2136 					whitespace_size += base32_character_size;
2137 				}
2138 			}
2139 		}
2140 		else if( strip_mode == LIBUNA_STRIP_MODE_LEADING_WHITESPACE )
2141 		{
2142 			strip_mode = LIBUNA_STRIP_MODE_NON_WHITESPACE;
2143 		}
2144 		else if( strip_mode == LIBUNA_STRIP_MODE_TRAILING_WHITESPACE )
2145 		{
2146 			strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2147 		}
2148 		if( strip_mode == LIBUNA_STRIP_MODE_NON_WHITESPACE )
2149 		{
2150 			switch( base32_variant & 0x000f0000UL )
2151 			{
2152 				case LIBUNA_BASE32_VARIANT_ALPHABET_NORMAL:
2153 					/* A-Z is not a continous range on an EBCDIC based system
2154 					 * it consists of the ranges: A-I, J-R, S-Z
2155 					 */
2156 					if( ( base32_character1 >= (uint32_t) 'A' )
2157 					 && ( base32_character1 <= (uint32_t) 'I' ) )
2158 					{
2159 						number_of_characters++;
2160 					}
2161 					else if( ( base32_character1 >= (uint32_t) 'J' )
2162 					      && ( base32_character1 <= (uint32_t) 'R' ) )
2163 					{
2164 						number_of_characters++;
2165 					}
2166 					else if( ( base32_character1 >= (uint32_t) 'S' )
2167 					      && ( base32_character1 <= (uint32_t) 'Z' ) )
2168 					{
2169 						number_of_characters++;
2170 					}
2171 					else if( ( base32_character1 >= (uint32_t) '2' )
2172 					      && ( base32_character1 <= (uint32_t) '7' ) )
2173 					{
2174 						number_of_characters++;
2175 					}
2176 					else
2177 					{
2178 						strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2179 					}
2180 					break;
2181 
2182 				case LIBUNA_BASE32_VARIANT_ALPHABET_HEX:
2183 					if( ( base32_character1 >= (uint32_t) '0' )
2184 					 && ( base32_character1 <= (uint32_t) '9' ) )
2185 					{
2186 						number_of_characters++;
2187 					}
2188 					/* A-V is not a continous range on an EBCDIC based system
2189 					 * it consists of the ranges: A-I, J-R, S-V
2190 					 */
2191 					else if( ( base32_character1 >= (uint32_t) 'A' )
2192 					      && ( base32_character1 <= (uint32_t) 'I' ) )
2193 					{
2194 						number_of_characters++;
2195 					}
2196 					else if( ( base32_character1 >= (uint32_t) 'J' )
2197 					      && ( base32_character1 <= (uint32_t) 'R' ) )
2198 					{
2199 						number_of_characters++;
2200 					}
2201 					else if( ( base32_character1 >= (uint32_t) 'S' )
2202 					      && ( base32_character1 <= (uint32_t) 'V' ) )
2203 					{
2204 						number_of_characters++;
2205 					}
2206 					else
2207 					{
2208 						strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2209 					}
2210 					break;
2211 
2212 				default:
2213 					strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2214 			}
2215 		}
2216 		if( strip_mode == LIBUNA_STRIP_MODE_INVALID_CHARACTER )
2217 		{
2218 			libcerror_error_set(
2219 			 error,
2220 			 LIBCERROR_ERROR_DOMAIN_CONVERSION,
2221 			 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
2222 			 "%s: invalid character in base32 stream at index: %d.",
2223 			 function,
2224 			 base32_stream_index );
2225 
2226 			return( -1 );
2227 		}
2228 		base32_stream_index += base32_character_size;
2229 	}
2230 	if( character_limit != 0 )
2231 	{
2232 		if( number_of_characters > (size_t) character_limit )
2233 		{
2234 			libcerror_error_set(
2235 			 error,
2236 			 LIBCERROR_ERROR_DOMAIN_CONVERSION,
2237 			 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
2238 			 "%s: number of characters in last line exceed maximum.",
2239 			 function );
2240 
2241 			return( -1 );
2242 		}
2243 	}
2244 	base32_stream_size -= whitespace_size;
2245 
2246 	/* Make sure the byte stream is able to hold
2247 	 * at least 5 bytes for each 8 base32 characters
2248 	 */
2249 	safe_byte_stream_size = ( base32_stream_size  * 5 ) / ( base32_character_size * 8 );
2250 
2251 	*byte_stream_size = safe_byte_stream_size * base32_character_size;
2252 
2253 	return( 1 );
2254 }
2255 
2256 /* Copies a byte stream from a base32 stream
2257  *
2258  * LIBUNA_BASE32_FLAG_STRIP_WHITESPACE removes leading space and tab characters,
2259  * and trailing space, tab and end of line characters
2260  *
2261  * Returns 1 if successful or -1 on error
2262  */
libuna_base32_stream_copy_to_byte_stream(const uint8_t * base32_stream,size_t base32_stream_size,uint8_t * byte_stream,size_t byte_stream_size,uint32_t base32_variant,uint8_t flags,libcerror_error_t ** error)2263 int libuna_base32_stream_copy_to_byte_stream(
2264      const uint8_t *base32_stream,
2265      size_t base32_stream_size,
2266      uint8_t *byte_stream,
2267      size_t byte_stream_size,
2268      uint32_t base32_variant,
2269      uint8_t flags,
2270      libcerror_error_t **error )
2271 {
2272 	static char *function        = "libuna_base32_stream_copy_to_byte_stream";
2273 	size_t base32_character_size = 0;
2274 	size_t base32_stream_index   = 0;
2275 	size_t byte_stream_index     = 0;
2276 	size_t number_of_characters  = 0;
2277 	size_t whitespace_size       = 0;
2278 	uint64_t base32_quintuplet   = 0;
2279 	uint32_t base32_character1   = 0;
2280 	uint32_t base32_character2   = 0;
2281 	uint8_t character_limit      = 0;
2282 	uint8_t padding_size         = 0;
2283 	uint8_t strip_mode           = LIBUNA_STRIP_MODE_LEADING_WHITESPACE;
2284 
2285 	if( base32_stream == NULL )
2286 	{
2287 		libcerror_error_set(
2288 		 error,
2289 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2290 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2291 		 "%s: invalid base32 stream.",
2292 		 function );
2293 
2294 		return( -1 );
2295 	}
2296 	if( base32_stream_size > (size_t) SSIZE_MAX )
2297 	{
2298 		libcerror_error_set(
2299 		 error,
2300 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2301 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2302 		 "%s: invalid base32 stream size value exceeds maximum.",
2303 		 function );
2304 
2305 		return( -1 );
2306 	}
2307 	if( byte_stream == NULL )
2308 	{
2309 		libcerror_error_set(
2310 		 error,
2311 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2312 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2313 		 "%s: invalid byte stream.",
2314 		 function );
2315 
2316 		return( -1 );
2317 	}
2318 	if( byte_stream_size > (size_t) SSIZE_MAX )
2319 	{
2320 		libcerror_error_set(
2321 		 error,
2322 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2323 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2324 		 "%s: invalid byte stream size value exceeds maximum.",
2325 		 function );
2326 
2327 		return( -1 );
2328 	}
2329 	switch( base32_variant & 0x000000ffUL )
2330 	{
2331 		case LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE:
2332 			character_limit = 0;
2333 			break;
2334 
2335 		case LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_64:
2336 			character_limit = 64;
2337 			break;
2338 
2339 		default:
2340 			libcerror_error_set(
2341 			 error,
2342 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2343 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2344 			 "%s: unsupported base32 variant.",
2345 			 function );
2346 
2347 			return( -1 );
2348 	}
2349 	switch( base32_variant & 0xf0000000UL )
2350 	{
2351 		case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
2352 			base32_character_size = 1;
2353 			break;
2354 
2355 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
2356 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
2357 			base32_character_size = 2;
2358 			break;
2359 
2360 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
2361 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
2362 			base32_character_size = 4;
2363 			break;
2364 
2365 		default:
2366 			libcerror_error_set(
2367 			 error,
2368 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2369 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2370 			 "%s: unsupported base32 variant.",
2371 			 function );
2372 
2373 			return( -1 );
2374 	}
2375 	if( ( flags & ~( LIBUNA_BASE32_FLAG_STRIP_WHITESPACE ) ) != 0 )
2376 	{
2377 		libcerror_error_set(
2378 		 error,
2379 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2380 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2381 		 "%s: unsupported flags.",
2382 		 function );
2383 
2384 		return( -1 );
2385 	}
2386 	/* Ignore trailing whitespace
2387 	 */
2388 	if( base32_stream_size > base32_character_size )
2389 	{
2390 		base32_stream_index = base32_stream_size - base32_character_size;
2391 		whitespace_size     = 0;
2392 
2393 		while( base32_stream_index > base32_character_size )
2394 		{
2395 			switch( base32_variant & 0xf0000000UL )
2396 			{
2397 				case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
2398 					base32_character1 = base32_stream[ base32_stream_index ];
2399 					break;
2400 
2401 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
2402 					byte_stream_copy_to_uint16_big_endian(
2403 					 &( base32_stream[ base32_stream_index ] ),
2404 					 base32_character1 );
2405 					break;
2406 
2407 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
2408 					byte_stream_copy_to_uint16_little_endian(
2409 					 &( base32_stream[ base32_stream_index ] ),
2410 					 base32_character1 );
2411 					break;
2412 
2413 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
2414 					byte_stream_copy_to_uint32_big_endian(
2415 					 &( base32_stream[ base32_stream_index ] ),
2416 					 base32_character1 );
2417 					break;
2418 
2419 				case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
2420 					byte_stream_copy_to_uint32_little_endian(
2421 					 &( base32_stream[ base32_stream_index ] ),
2422 					 base32_character1 );
2423 					break;
2424 			}
2425 			base32_stream_index -= base32_character_size;
2426 
2427 			if( ( base32_character1 == (uint32_t) '\n' )
2428 			 || ( base32_character1 == (uint32_t) '\r' ) )
2429 			{
2430 				whitespace_size += base32_character_size;
2431 
2432 				continue;
2433 			}
2434 			else if( ( flags & LIBUNA_BASE32_FLAG_STRIP_WHITESPACE ) == 0 )
2435 			{
2436 				break;
2437 			}
2438 			if( ( base32_character1 == (uint32_t) ' ' )
2439 			 || ( base32_character1 == (uint32_t) '\t' )
2440 			 || ( base32_character1 == (uint32_t) '\v' ) )
2441 			{
2442 				whitespace_size += base32_character_size;
2443 			}
2444 			else
2445 			{
2446 				break;
2447 			}
2448 		}
2449 		base32_stream_size -= whitespace_size;
2450 	}
2451 	if( ( flags & LIBUNA_BASE32_FLAG_STRIP_WHITESPACE ) == 0 )
2452 	{
2453 		strip_mode = LIBUNA_STRIP_MODE_NON_WHITESPACE;
2454 	}
2455 	base32_stream_index = 0;
2456 
2457 	while( ( base32_stream_index + base32_character_size ) < base32_stream_size )
2458 	{
2459 		switch( base32_variant & 0xf0000000UL )
2460 		{
2461 			case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
2462 				base32_character1 = base32_stream[ base32_stream_index ];
2463 				break;
2464 
2465 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
2466 				byte_stream_copy_to_uint16_big_endian(
2467 				 &( base32_stream[ base32_stream_index ] ),
2468 				 base32_character1 );
2469 				break;
2470 
2471 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
2472 				byte_stream_copy_to_uint16_little_endian(
2473 				 &( base32_stream[ base32_stream_index ] ),
2474 				 base32_character1 );
2475 				break;
2476 
2477 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
2478 				byte_stream_copy_to_uint32_big_endian(
2479 				 &( base32_stream[ base32_stream_index ] ),
2480 				 base32_character1 );
2481 				break;
2482 
2483 			case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
2484 				byte_stream_copy_to_uint32_little_endian(
2485 				 &( base32_stream[ base32_stream_index ] ),
2486 				 base32_character1 );
2487 				break;
2488 		}
2489 		if( ( base32_character1 == (uint32_t) '\n' )
2490 		 || ( base32_character1 == (uint32_t) '\r' ) )
2491 		{
2492 			if( ( strip_mode != LIBUNA_STRIP_MODE_NON_WHITESPACE )
2493 			 && ( strip_mode != LIBUNA_STRIP_MODE_TRAILING_WHITESPACE ) )
2494 			{
2495 				strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2496 			}
2497 			else
2498 			{
2499 				/* Handle multi-character end-of-line
2500 				 */
2501 				if( ( base32_stream_index + base32_character_size ) < base32_stream_size )
2502 				{
2503 					switch( base32_variant & 0xf0000000UL )
2504 					{
2505 						case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
2506 							base32_character2 = base32_stream[ base32_stream_index + 1 ];
2507 							break;
2508 
2509 						case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
2510 							byte_stream_copy_to_uint16_big_endian(
2511 							 &( base32_stream[ base32_stream_index + 2 ] ),
2512 							 base32_character2 );
2513 							break;
2514 
2515 						case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
2516 							byte_stream_copy_to_uint16_little_endian(
2517 							 &( base32_stream[ base32_stream_index + 2 ] ),
2518 							 base32_character2 );
2519 							break;
2520 
2521 						case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
2522 							byte_stream_copy_to_uint32_big_endian(
2523 							 &( base32_stream[ base32_stream_index + 4 ] ),
2524 							 base32_character2 );
2525 							break;
2526 
2527 						case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
2528 							byte_stream_copy_to_uint32_little_endian(
2529 							 &( base32_stream[ base32_stream_index + 4 ] ),
2530 							 base32_character2 );
2531 							break;
2532 					}
2533 					if( ( base32_character2 == (uint32_t) '\n' )
2534 					 || ( base32_character2 == (uint32_t) '\r' ) )
2535 					{
2536 						base32_stream_index += base32_character_size;
2537 					}
2538 				}
2539 				strip_mode = LIBUNA_STRIP_MODE_LEADING_WHITESPACE;
2540 
2541 				base32_stream_index += base32_character_size;
2542 			}
2543 			if( character_limit != 0 )
2544 			{
2545 				if( number_of_characters != (size_t) character_limit )
2546 				{
2547 					libcerror_error_set(
2548 					 error,
2549 					 LIBCERROR_ERROR_DOMAIN_CONVERSION,
2550 					 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
2551 					 "%s: number of characters in line does not match character limit.",
2552 					 function );
2553 
2554 					return( -1 );
2555 				}
2556 				number_of_characters = 0;
2557 			}
2558 		}
2559 		else if( ( base32_character1 == (uint32_t) ' ' )
2560 		      || ( base32_character1 == (uint32_t) '\t' )
2561 		      || ( base32_character1 == (uint32_t) '\v' ) )
2562 		{
2563 			if( ( flags & LIBUNA_BASE32_FLAG_STRIP_WHITESPACE ) != 0 )
2564 			{
2565 				if( strip_mode == LIBUNA_STRIP_MODE_NON_WHITESPACE )
2566 				{
2567 					strip_mode = LIBUNA_STRIP_MODE_TRAILING_WHITESPACE;
2568 				}
2569 				if( ( strip_mode != LIBUNA_STRIP_MODE_LEADING_WHITESPACE )
2570 				 && ( strip_mode != LIBUNA_STRIP_MODE_TRAILING_WHITESPACE ) )
2571 				{
2572 					strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2573 				}
2574 				base32_stream_index += base32_character_size;
2575 			}
2576 			else
2577 			{
2578 				strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2579 			}
2580 		}
2581 		else if( strip_mode == LIBUNA_STRIP_MODE_LEADING_WHITESPACE )
2582 		{
2583 			strip_mode = LIBUNA_STRIP_MODE_NON_WHITESPACE;
2584 		}
2585 		else if( strip_mode == LIBUNA_STRIP_MODE_TRAILING_WHITESPACE )
2586 		{
2587 			strip_mode = LIBUNA_STRIP_MODE_INVALID_CHARACTER;
2588 		}
2589 		if( strip_mode == LIBUNA_STRIP_MODE_INVALID_CHARACTER )
2590 		{
2591 			libcerror_error_set(
2592 			 error,
2593 			 LIBCERROR_ERROR_DOMAIN_CONVERSION,
2594 			 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
2595 			 "%s: invalid character in base32 stream at index: %d.",
2596 			 function,
2597 			 base32_stream_index );
2598 
2599 			return( -1 );
2600 		}
2601 		if( strip_mode == LIBUNA_STRIP_MODE_NON_WHITESPACE )
2602 		{
2603 			if( padding_size > 0 )
2604 			{
2605 				libcerror_error_set(
2606 				 error,
2607 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2608 				 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2609 				 "%s: invalid 1st base32 quintet.",
2610 				 function );
2611 
2612 				return( -1 );
2613 			}
2614 			/* Convert the base32 stream into a base32 quintuplet
2615 			 */
2616 			if( libuna_base32_quintuplet_copy_from_base32_stream(
2617 			     &base32_quintuplet,
2618 			     base32_stream,
2619 			     base32_stream_size,
2620 			     &base32_stream_index,
2621 			     &padding_size,
2622 			     base32_variant,
2623 			     error ) != 1 )
2624 			{
2625 				libcerror_error_set(
2626 				 error,
2627 				 LIBCERROR_ERROR_DOMAIN_CONVERSION,
2628 				 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
2629 				 "%s: unable to copy base32 quintuplet from base32 stream.",
2630 				 function );
2631 
2632 				return( -1 );
2633 			}
2634 			/* Convert the base32 quintuplet into a byte stream
2635 			 */
2636 			if( libuna_base32_quintuplet_copy_to_byte_stream(
2637 			     base32_quintuplet,
2638 			     byte_stream,
2639 			     byte_stream_size,
2640 			     &byte_stream_index,
2641 			     padding_size,
2642 			     error ) != 1 )
2643 			{
2644 				libcerror_error_set(
2645 				 error,
2646 				 LIBCERROR_ERROR_DOMAIN_CONVERSION,
2647 				 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
2648 				 "%s: unable to copy base32 quintuplet to byte stream.",
2649 				 function );
2650 
2651 				return( -1 );
2652 			}
2653 			number_of_characters += 8 - padding_size;
2654 		}
2655 	}
2656 	if( character_limit != 0 )
2657 	{
2658 		if( number_of_characters > (size_t) character_limit )
2659 		{
2660 			libcerror_error_set(
2661 			 error,
2662 			 LIBCERROR_ERROR_DOMAIN_CONVERSION,
2663 			 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
2664 			 "%s: number of characters in last line exceed maximum.",
2665 			 function );
2666 
2667 			return( -1 );
2668 		}
2669 	}
2670 	return( 1 );
2671 }
2672 
2673 /* Determines the size of a base32 stream from a byte stream
2674  * Returns 1 if successful or -1 on error
2675  */
libuna_base32_stream_size_from_byte_stream(const uint8_t * byte_stream,size_t byte_stream_size,size_t * base32_stream_size,uint32_t base32_variant,libcerror_error_t ** error)2676 int libuna_base32_stream_size_from_byte_stream(
2677      const uint8_t *byte_stream,
2678      size_t byte_stream_size,
2679      size_t *base32_stream_size,
2680      uint32_t base32_variant,
2681      libcerror_error_t **error )
2682 {
2683 	static char *function          = "libuna_base32_stream_size_from_byte_stream";
2684 	size_t base32_character_size   = 0;
2685 	size_t safe_base32_stream_size = 0;
2686 	size_t whitespace_size         = 0;
2687 	uint8_t character_limit        = 0;
2688 
2689 	if( byte_stream == NULL )
2690 	{
2691 		libcerror_error_set(
2692 		 error,
2693 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2694 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2695 		 "%s: invalid byte stream.",
2696 		 function );
2697 
2698 		return( -1 );
2699 	}
2700 	if( byte_stream_size > (size_t) SSIZE_MAX )
2701 	{
2702 		libcerror_error_set(
2703 		 error,
2704 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2705 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2706 		 "%s: invalid byte stream size value exceeds maximum.",
2707 		 function );
2708 
2709 		return( -1 );
2710 	}
2711 	if( base32_stream_size == NULL )
2712 	{
2713 		libcerror_error_set(
2714 		 error,
2715 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2716 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2717 		 "%s: invalid base32 stream size.",
2718 		 function );
2719 
2720 		return( -1 );
2721 	}
2722 	switch( base32_variant & 0x000000ffUL )
2723 	{
2724 		case LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE:
2725 			character_limit = 0;
2726 			break;
2727 
2728 		case LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_64:
2729 			character_limit = 64;
2730 			break;
2731 
2732 		default:
2733 			libcerror_error_set(
2734 			 error,
2735 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2736 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2737 			 "%s: unsupported base32 variant.",
2738 			 function );
2739 
2740 			return( -1 );
2741 	}
2742 	switch( base32_variant & 0xf0000000UL )
2743 	{
2744 		case LIBUNA_BASE32_VARIANT_ENCODING_BYTE_STREAM:
2745 			base32_character_size = 1;
2746 			break;
2747 
2748 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_BIG_ENDIAN:
2749 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN:
2750 			base32_character_size = 2;
2751 			break;
2752 
2753 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_BIG_ENDIAN:
2754 		case LIBUNA_BASE32_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN:
2755 			base32_character_size = 4;
2756 			break;
2757 
2758 		default:
2759 			libcerror_error_set(
2760 			 error,
2761 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2762 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2763 			 "%s: unsupported base32 variant.",
2764 			 function );
2765 
2766 			return( -1 );
2767 	}
2768 	/* Make sure the base32 stream is able to hold
2769 	 * at least 8 base32 characters for each 5 bytes
2770 	 */
2771 	safe_base32_stream_size = byte_stream_size / 5;
2772 
2773 	if( ( byte_stream_size % 5 ) != 0 )
2774 	{
2775 		safe_base32_stream_size += 1;
2776 	}
2777 	safe_base32_stream_size *= 8;
2778 
2779 	if( character_limit != 0 )
2780 	{
2781 		whitespace_size = safe_base32_stream_size / character_limit;
2782 
2783 		if( ( safe_base32_stream_size % character_limit ) != 0 )
2784 		{
2785 			whitespace_size += 1;
2786 		}
2787 		safe_base32_stream_size += whitespace_size;
2788 	}
2789 	*base32_stream_size = safe_base32_stream_size * base32_character_size;
2790 
2791 	return( 1 );
2792 }
2793 
2794 /* Copies a base32 stream from a byte stream
2795  * Returns 1 if successful or -1 on error
2796  */
libuna_base32_stream_copy_from_byte_stream(uint8_t * base32_stream,size_t base32_stream_size,const uint8_t * byte_stream,size_t byte_stream_size,uint32_t base32_variant,libcerror_error_t ** error)2797 int libuna_base32_stream_copy_from_byte_stream(
2798      uint8_t *base32_stream,
2799      size_t base32_stream_size,
2800      const uint8_t *byte_stream,
2801      size_t byte_stream_size,
2802      uint32_t base32_variant,
2803      libcerror_error_t **error )
2804 {
2805 	static char *function      = "libuna_base32_stream_copy_from_byte_stream";
2806 	size_t base32_stream_index = 0;
2807 
2808 	if( libuna_base32_stream_with_index_copy_from_byte_stream(
2809 	     base32_stream,
2810 	     base32_stream_size,
2811 	     &base32_stream_index,
2812 	     byte_stream,
2813 	     byte_stream_size,
2814 	     base32_variant,
2815 	     error ) != 1 )
2816 	{
2817 		libcerror_error_set(
2818 		 error,
2819 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2820 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2821 		 "%s: unable to copy base32 stream from byte stream.",
2822 		 function );
2823 
2824 		return( -1 );
2825 	}
2826 	return( 1 );
2827 }
2828 
2829 /* Copies a base32 stream from a byte stream
2830  * Returns 1 if successful or -1 on error
2831  */
libuna_base32_stream_with_index_copy_from_byte_stream(uint8_t * base32_stream,size_t base32_stream_size,size_t * base32_stream_index,const uint8_t * byte_stream,size_t byte_stream_size,uint32_t base32_variant,libcerror_error_t ** error)2832 int libuna_base32_stream_with_index_copy_from_byte_stream(
2833      uint8_t *base32_stream,
2834      size_t base32_stream_size,
2835      size_t *base32_stream_index,
2836      const uint8_t *byte_stream,
2837      size_t byte_stream_size,
2838      uint32_t base32_variant,
2839      libcerror_error_t **error )
2840 {
2841 	static char *function                = "libuna_base32_stream_with_index_copy_from_byte_stream";
2842 	size_t calculated_base32_stream_size = 0;
2843 	size_t safe_base32_stream_index      = 0;
2844 	size_t byte_stream_index             = 0;
2845 	size_t number_of_characters          = 0;
2846 	size_t whitespace_size               = 0;
2847 	uint64_t base32_quintuplet           = 0;
2848 	uint8_t character_limit              = 0;
2849 	uint8_t padding_size                 = 0;
2850 
2851 	if( base32_stream == NULL )
2852 	{
2853 		libcerror_error_set(
2854 		 error,
2855 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2856 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2857 		 "%s: invalid base32 stream.",
2858 		 function );
2859 
2860 		return( -1 );
2861 	}
2862 	if( base32_stream_size > (size_t) SSIZE_MAX )
2863 	{
2864 		libcerror_error_set(
2865 		 error,
2866 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2867 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2868 		 "%s: invalid base32 stream size value exceeds maximum.",
2869 		 function );
2870 
2871 		return( -1 );
2872 	}
2873 	if( base32_stream_index == NULL )
2874 	{
2875 		libcerror_error_set(
2876 		 error,
2877 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2878 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2879 		 "%s: invalid base32 stream index.",
2880 		 function );
2881 
2882 		return( -1 );
2883 	}
2884 	if( *base32_stream_index >= base32_stream_size )
2885 	{
2886 		libcerror_error_set(
2887 		 error,
2888 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2889 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2890 		 "%s: base32 stream string too small.",
2891 		 function );
2892 
2893 		return( -1 );
2894 	}
2895 	if( byte_stream == NULL )
2896 	{
2897 		libcerror_error_set(
2898 		 error,
2899 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2900 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2901 		 "%s: invalid byte stream.",
2902 		 function );
2903 
2904 		return( -1 );
2905 	}
2906 	if( byte_stream_size > (size_t) SSIZE_MAX )
2907 	{
2908 		libcerror_error_set(
2909 		 error,
2910 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2911 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2912 		 "%s: invalid byte stream size value exceeds maximum.",
2913 		 function );
2914 
2915 		return( -1 );
2916 	}
2917 	switch( base32_variant & 0x000000ffUL )
2918 	{
2919 		case LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_NONE:
2920 			character_limit = 0;
2921 			break;
2922 
2923 		case LIBUNA_BASE32_VARIANT_CHARACTER_LIMIT_64:
2924 			character_limit = 64;
2925 			break;
2926 
2927 		default:
2928 			libcerror_error_set(
2929 			 error,
2930 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2931 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2932 			 "%s: unsupported base32 variant.",
2933 			 function );
2934 
2935 			return( -1 );
2936 	}
2937 	safe_base32_stream_index = *base32_stream_index;
2938 
2939 	/* Make sure the base32 stream is able to hold
2940 	 * at least 8 base32 characters for each 5 bytes
2941 	 */
2942 	calculated_base32_stream_size = byte_stream_size / 5;
2943 
2944 	if( ( byte_stream_size % 5 ) != 0 )
2945 	{
2946 		calculated_base32_stream_size += 1;
2947 	}
2948 	calculated_base32_stream_size *= 8;
2949 
2950 	if( character_limit != 0 )
2951 	{
2952 		whitespace_size = calculated_base32_stream_size / character_limit;
2953 
2954 		if( ( calculated_base32_stream_size % character_limit ) != 0 )
2955 		{
2956 			whitespace_size += 1;
2957 		}
2958 		calculated_base32_stream_size += whitespace_size;
2959 	}
2960 	if( base32_stream_size < calculated_base32_stream_size )
2961 	{
2962 		libcerror_error_set(
2963 		 error,
2964 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2965 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2966 		 "%s: base32 stream is too small.",
2967 		 function );
2968 
2969 		return( -1 );
2970 	}
2971 	while( byte_stream_index < byte_stream_size )
2972 	{
2973 		/* Convert the byte stream into a base32 quintuplet
2974 		 */
2975 		if( libuna_base32_quintuplet_copy_from_byte_stream(
2976 		     &base32_quintuplet,
2977 		     byte_stream,
2978 		     byte_stream_size,
2979 		     &byte_stream_index,
2980 		     &padding_size,
2981 		     error ) != 1 )
2982 		{
2983 			libcerror_error_set(
2984 			 error,
2985 			 LIBCERROR_ERROR_DOMAIN_CONVERSION,
2986 			 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
2987 			 "%s: unable to copy base32 quintuplet from byte stream.",
2988 			 function );
2989 
2990 			return( -1 );
2991 		}
2992 		/* Convert the base32 quintuplet into a base32 stream
2993 		 */
2994 		if( libuna_base32_quintuplet_copy_to_base32_stream(
2995 		     base32_quintuplet,
2996 		     base32_stream,
2997 		     base32_stream_size,
2998 		     &safe_base32_stream_index,
2999 		     padding_size,
3000 		     base32_variant,
3001 		     error ) != 1 )
3002 		{
3003 			libcerror_error_set(
3004 			 error,
3005 			 LIBCERROR_ERROR_DOMAIN_CONVERSION,
3006 			 LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
3007 			 "%s: unable to copy base32 quintuplet to base32 stream.",
3008 			 function );
3009 
3010 			return( -1 );
3011 		}
3012 		if( character_limit != 0 )
3013 		{
3014 			number_of_characters += 8;
3015 
3016 			if( number_of_characters >= (size_t) character_limit )
3017 			{
3018 				base32_stream[ safe_base32_stream_index++ ] = (uint8_t) '\n';
3019 
3020 				number_of_characters = 0;
3021 			}
3022 		}
3023 	}
3024 	if( character_limit != 0 )
3025 	{
3026 		if( number_of_characters != 0 )
3027 		{
3028 			base32_stream[ safe_base32_stream_index++ ] = (uint8_t) '\n';
3029 		}
3030 	}
3031 	*base32_stream_index = safe_base32_stream_index;
3032 
3033 	return( 1 );
3034 }
3035 
3036