1 /*
2 * Base32 stream functions
3 *
4 * Copyright (C) 2008-2020, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <byte_stream.h>
24 #include <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