Coverage Report

Created: 2024-02-25 07:20

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