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