Coverage Report

Created: 2024-02-25 07:19

/src/libbde/libbde/libbde_diffuser.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Elephant diffuser encryption functions
3
 *
4
 * Copyright (C) 2011-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 <memory.h>
25
#include <types.h>
26
27
#include "libbde_diffuser.h"
28
#include "libbde_libcerror.h"
29
30
/* Decrypts the data using Diffuser-A and B
31
 * Returns 1 if successful or -1 on error
32
 */
33
int libbde_diffuser_decrypt(
34
     uint8_t *data,
35
     size_t data_size,
36
     libcerror_error_t **error )
37
17
{
38
17
  uint32_t *values_32bit   = NULL;
39
17
  static char *function    = "libbde_diffuser_decrypt";
40
17
  size_t data_index        = 0;
41
17
  size_t number_of_values  = 0;
42
17
  size_t value_32bit_index = 0;
43
44
17
  if( data == NULL )
45
0
  {
46
0
    libcerror_error_set(
47
0
     error,
48
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
49
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
50
0
     "%s: invalid data.",
51
0
     function );
52
53
0
    return( -1 );
54
0
  }
55
17
  if( ( data_size == 0 )
56
17
   || ( data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
57
17
   || ( ( data_size % 4 ) != 0 ) )
58
0
  {
59
0
    libcerror_error_set(
60
0
     error,
61
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
62
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
63
0
     "%s: invalid data size value out of bounds.",
64
0
     function );
65
66
0
    return( -1 );
67
0
  }
68
17
  number_of_values = data_size / 4;
69
70
17
  values_32bit = (uint32_t *) memory_allocate(
71
17
                               data_size );
72
73
17
  if( values_32bit == NULL )
74
0
  {
75
0
    libcerror_error_set(
76
0
     error,
77
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
78
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
79
0
     "%s: unable to create values 32-bit.",
80
0
     function );
81
82
0
    goto on_error;
83
0
  }
84
17
  data_index = 0;
85
86
17
  for( value_32bit_index = 0;
87
3.60k
       value_32bit_index < number_of_values;
88
3.58k
       value_32bit_index++ )
89
3.58k
  {
90
3.58k
    byte_stream_copy_to_uint32_little_endian(
91
3.58k
     &( data[ data_index ] ),
92
3.58k
     values_32bit[ value_32bit_index ] );
93
94
3.58k
    data_index += sizeof( uint32_t );
95
3.58k
  }
96
17
  if( libbde_diffuser_b_decrypt(
97
17
       values_32bit,
98
17
       number_of_values,
99
17
       error ) != 1 )
100
0
  {
101
0
    libcerror_error_set(
102
0
     error,
103
0
     LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
104
0
     LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED,
105
0
     "%s: unable to decrypt data using Diffuser-B.",
106
0
     function );
107
108
0
    goto on_error;
109
0
  }
110
17
  if( libbde_diffuser_a_decrypt(
111
17
       values_32bit,
112
17
       number_of_values,
113
17
       error ) != 1 )
114
0
  {
115
0
    libcerror_error_set(
116
0
     error,
117
0
     LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
118
0
     LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED,
119
0
     "%s: unable to decrypt data using Diffuser-A.",
120
0
     function );
121
122
0
    goto on_error;
123
0
  }
124
17
  data_index = 0;
125
126
17
  for( value_32bit_index = 0;
127
3.60k
       value_32bit_index < number_of_values;
128
3.58k
       value_32bit_index++ )
129
3.58k
  {
130
3.58k
    byte_stream_copy_from_uint32_little_endian(
131
3.58k
     &( data[ data_index ] ),
132
3.58k
     values_32bit[ value_32bit_index ] );
133
134
3.58k
    data_index += sizeof( uint32_t );
135
3.58k
  }
136
17
  if( memory_set(
137
17
       values_32bit,
138
17
       0,
139
17
       data_size ) == NULL )
140
0
  {
141
0
    libcerror_error_set(
142
0
     error,
143
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
144
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
145
0
     "%s: unable to clear values 32-bit.",
146
0
     function );
147
148
0
    goto on_error;
149
0
  }
150
17
  memory_free(
151
17
   values_32bit );
152
153
17
  return( 1 );
154
155
0
on_error:
156
0
  if( values_32bit != NULL )
157
0
  {
158
0
    memory_set(
159
0
     values_32bit,
160
0
     0,
161
0
     data_size );
162
163
0
    memory_free(
164
0
     values_32bit );
165
0
  }
166
0
  return( -1 );
167
17
}
168
169
/* Decrypts the data using Diffuser-A
170
 * Returns 1 if successful or -1 on error
171
 */
172
int libbde_diffuser_a_decrypt(
173
     uint32_t *values_32bit,
174
     size_t number_of_values,
175
     libcerror_error_t **error )
176
17
{
177
17
  static char *function       = "libbde_diffuser_a_decrypt";
178
17
  size_t number_of_iterations = 0;
179
17
  size_t value_32bit_index1   = 0;
180
17
  size_t value_32bit_index2   = 0;
181
17
  size_t value_32bit_index3   = 0;
182
183
17
  if( values_32bit == NULL )
184
0
  {
185
0
    libcerror_error_set(
186
0
     error,
187
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
188
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
189
0
     "%s: invalid values 32-bit.",
190
0
     function );
191
192
0
    return( -1 );
193
0
  }
194
17
  if( number_of_values < 8 )
195
0
  {
196
0
    libcerror_error_set(
197
0
     error,
198
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
199
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
200
0
     "%s: invalid number of values value too small.",
201
0
     function );
202
203
0
    return( -1 );
204
0
  }
205
17
  if( number_of_values > (size_t) SSIZE_MAX )
206
0
  {
207
0
    libcerror_error_set(
208
0
     error,
209
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
210
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
211
0
     "%s: invalid number of values exceeds maximum.",
212
0
     function );
213
214
0
    return( -1 );
215
0
  }
216
17
  for( number_of_iterations = 5;
217
102
       number_of_iterations > 0;
218
85
       number_of_iterations-- )
219
85
  {
220
85
    value_32bit_index1 = 0;
221
85
    value_32bit_index2 = number_of_values - 2;
222
85
    value_32bit_index3 = number_of_values - 5;
223
224
4.56k
    while( value_32bit_index1 < ( number_of_values - 1 ) )
225
4.48k
    {
226
4.48k
      values_32bit[ value_32bit_index1 ] += values_32bit[ value_32bit_index2 ]
227
4.48k
                                          ^ byte_stream_bit_rotate_left_32bit(
228
4.48k
                                             values_32bit[ value_32bit_index3 ],
229
4.48k
                                             9 );
230
231
4.48k
      value_32bit_index1++;
232
4.48k
      value_32bit_index2++;
233
4.48k
      value_32bit_index3++;
234
235
4.48k
      if( value_32bit_index3 >= number_of_values )
236
85
      {
237
85
        value_32bit_index3 -= number_of_values;
238
85
      }
239
4.48k
      values_32bit[ value_32bit_index1 ] += values_32bit[ value_32bit_index2 ]
240
4.48k
                                          ^ values_32bit[ value_32bit_index3 ];
241
242
4.48k
      value_32bit_index1++;
243
4.48k
      value_32bit_index2++;
244
4.48k
      value_32bit_index3++;
245
246
4.48k
      if( value_32bit_index2 >= number_of_values )
247
85
      {
248
85
        value_32bit_index2 -= number_of_values;
249
85
      }
250
4.48k
      values_32bit[ value_32bit_index1 ] += values_32bit[ value_32bit_index2 ]
251
4.48k
                                          ^ byte_stream_bit_rotate_left_32bit(
252
4.48k
                                             values_32bit[ value_32bit_index3 ],
253
4.48k
                                             13 );
254
255
4.48k
      value_32bit_index1++;
256
4.48k
      value_32bit_index2++;
257
4.48k
      value_32bit_index3++;
258
259
4.48k
      values_32bit[ value_32bit_index1 ] += values_32bit[ value_32bit_index2 ]
260
4.48k
                                          ^ values_32bit[ value_32bit_index3 ];
261
262
4.48k
      value_32bit_index1++;
263
4.48k
      value_32bit_index2++;
264
4.48k
      value_32bit_index3++;
265
4.48k
    }
266
85
  }
267
17
  return( 1 );
268
17
}
269
270
/* Decrypts the data using Diffuser-B
271
 * Returns 1 if successful or -1 on error
272
 */
273
int libbde_diffuser_b_decrypt(
274
     uint32_t *values_32bit,
275
     size_t number_of_values,
276
     libcerror_error_t **error )
277
17
{
278
17
  static char *function       = "libbde_diffuser_b_decrypt";
279
17
  size_t number_of_iterations = 0;
280
17
  size_t value_32bit_index1   = 0;
281
17
  size_t value_32bit_index2   = 0;
282
17
  size_t value_32bit_index3   = 0;
283
284
17
  if( values_32bit == NULL )
285
0
  {
286
0
    libcerror_error_set(
287
0
     error,
288
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
289
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
290
0
     "%s: invalid values 32-bit.",
291
0
     function );
292
293
0
    return( -1 );
294
0
  }
295
17
  if( number_of_values < 8 )
296
0
  {
297
0
    libcerror_error_set(
298
0
     error,
299
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
300
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
301
0
     "%s: invalid number of values value too small.",
302
0
     function );
303
304
0
    return( -1 );
305
0
  }
306
17
  if( number_of_values > (size_t) SSIZE_MAX )
307
0
  {
308
0
    libcerror_error_set(
309
0
     error,
310
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
311
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
312
0
     "%s: invalid number of values exceeds maximum.",
313
0
     function );
314
315
0
    return( -1 );
316
0
  }
317
17
  for( number_of_iterations = 3;
318
68
       number_of_iterations > 0;
319
51
       number_of_iterations-- )
320
51
  {
321
51
    value_32bit_index1 = 0;
322
51
    value_32bit_index2 = 2;
323
51
    value_32bit_index3 = 5;
324
325
2.73k
    while( value_32bit_index1 < ( number_of_values - 1 ) )
326
2.68k
    {
327
2.68k
      values_32bit[ value_32bit_index1 ] += values_32bit[ value_32bit_index2 ]
328
2.68k
                                          ^ values_32bit[ value_32bit_index3 ];
329
330
2.68k
      value_32bit_index1++;
331
2.68k
      value_32bit_index2++;
332
2.68k
      value_32bit_index3++;
333
334
2.68k
      values_32bit[ value_32bit_index1 ] += values_32bit[ value_32bit_index2 ]
335
2.68k
                                          ^ byte_stream_bit_rotate_left_32bit(
336
2.68k
                                             values_32bit[ value_32bit_index3 ],
337
2.68k
                                             10 );
338
339
2.68k
      value_32bit_index1++;
340
2.68k
      value_32bit_index2++;
341
2.68k
      value_32bit_index3++;
342
343
2.68k
      if( value_32bit_index2 >= number_of_values )
344
51
      {
345
51
        value_32bit_index2 -= number_of_values;
346
51
      }
347
2.68k
      values_32bit[ value_32bit_index1 ] += values_32bit[ value_32bit_index2 ]
348
2.68k
                                          ^ values_32bit[ value_32bit_index3 ];
349
350
2.68k
      value_32bit_index1++;
351
2.68k
      value_32bit_index2++;
352
2.68k
      value_32bit_index3++;
353
354
2.68k
      if( value_32bit_index3 >= number_of_values )
355
51
      {
356
51
        value_32bit_index3 -= number_of_values;
357
51
      }
358
2.68k
      values_32bit[ value_32bit_index1 ] += values_32bit[ value_32bit_index2 ]
359
2.68k
                                          ^ byte_stream_bit_rotate_left_32bit(
360
2.68k
                                             values_32bit[ value_32bit_index3 ],
361
2.68k
                                             25 );
362
363
2.68k
      value_32bit_index1++;
364
2.68k
      value_32bit_index2++;
365
2.68k
      value_32bit_index3++;
366
2.68k
    }
367
51
  }
368
17
  return( 1 );
369
17
}
370
371
/* Encrypts the data using Diffuser-A and B
372
 * Returns 1 if successful or -1 on error
373
 */
374
int libbde_diffuser_encrypt(
375
     uint8_t *data,
376
     size_t data_size,
377
     libcerror_error_t **error )
378
0
{
379
0
  uint32_t *values_32bit   = NULL;
380
0
  static char *function    = "libbde_diffuser_encrypt";
381
0
  size_t data_index        = 0;
382
0
  size_t number_of_values  = 0;
383
0
  size_t value_32bit_index = 0;
384
385
0
  if( data == NULL )
386
0
  {
387
0
    libcerror_error_set(
388
0
     error,
389
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
390
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
391
0
     "%s: invalid data.",
392
0
     function );
393
394
0
    return( -1 );
395
0
  }
396
0
  if( ( data_size == 0 )
397
0
   || ( data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
398
0
   || ( ( data_size % 4 ) != 0 ) )
399
0
  {
400
0
    libcerror_error_set(
401
0
     error,
402
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
403
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
404
0
     "%s: invalid data size value out of bounds.",
405
0
     function );
406
407
0
    return( -1 );
408
0
  }
409
0
  number_of_values = data_size / 4;
410
411
0
  values_32bit = (uint32_t *) memory_allocate(
412
0
                               data_size );
413
414
0
  if( values_32bit == NULL )
415
0
  {
416
0
    libcerror_error_set(
417
0
     error,
418
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
419
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
420
0
     "%s: unable to create values 32-bit.",
421
0
     function );
422
423
0
    goto on_error;
424
0
  }
425
0
  data_index = 0;
426
427
0
  for( value_32bit_index = 0;
428
0
       value_32bit_index < number_of_values;
429
0
       value_32bit_index++ )
430
0
  {
431
0
    byte_stream_copy_to_uint32_little_endian(
432
0
     &( data[ data_index ] ),
433
0
     values_32bit[ value_32bit_index ] );
434
435
0
    data_index += sizeof( uint32_t );
436
0
  }
437
0
  if( libbde_diffuser_a_encrypt(
438
0
       values_32bit,
439
0
       number_of_values,
440
0
       error ) != 1 )
441
0
  {
442
0
    libcerror_error_set(
443
0
     error,
444
0
     LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
445
0
     LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED,
446
0
     "%s: unable to encrypt data using Diffuser-A.",
447
0
     function );
448
449
0
    goto on_error;
450
0
  }
451
0
  if( libbde_diffuser_b_encrypt(
452
0
       values_32bit,
453
0
       number_of_values,
454
0
       error ) != 1 )
455
0
  {
456
0
    libcerror_error_set(
457
0
     error,
458
0
     LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
459
0
     LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED,
460
0
     "%s: unable to encrypt data using Diffuser-B.",
461
0
     function );
462
463
0
    goto on_error;
464
0
  }
465
0
  data_index = 0;
466
467
0
  for( value_32bit_index = 0;
468
0
       value_32bit_index < number_of_values;
469
0
       value_32bit_index++ )
470
0
  {
471
0
    byte_stream_copy_from_uint32_little_endian(
472
0
     &( data[ data_index ] ),
473
0
     values_32bit[ value_32bit_index ] );
474
475
0
    data_index += sizeof( uint32_t );
476
0
  }
477
0
  if( memory_set(
478
0
       values_32bit,
479
0
       0,
480
0
       data_size ) == NULL )
481
0
  {
482
0
    libcerror_error_set(
483
0
     error,
484
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
485
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
486
0
     "%s: unable to clear values 32-bit.",
487
0
     function );
488
489
0
    goto on_error;
490
0
  }
491
0
  memory_free(
492
0
   values_32bit );
493
494
0
  return( 1 );
495
496
0
on_error:
497
0
  if( values_32bit != NULL )
498
0
  {
499
0
    memory_set(
500
0
     values_32bit,
501
0
     0,
502
0
     data_size );
503
504
0
    memory_free(
505
0
     values_32bit );
506
0
  }
507
0
  return( -1 );
508
0
}
509
510
/* Encrypts the data using Diffuser-A
511
 * Returns 1 if successful or -1 on error
512
 */
513
int libbde_diffuser_a_encrypt(
514
     uint32_t *values_32bit,
515
     size_t number_of_values,
516
     libcerror_error_t **error )
517
0
{
518
0
  static char *function       = "libbde_diffuser_a_encrypt";
519
0
  size_t number_of_iterations = 0;
520
0
  size_t value_32bit_index1   = 0;
521
0
  size_t value_32bit_index2   = 0;
522
0
  size_t value_32bit_index3   = 0;
523
524
0
  if( values_32bit == NULL )
525
0
  {
526
0
    libcerror_error_set(
527
0
     error,
528
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
529
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
530
0
     "%s: invalid values 32-bit.",
531
0
     function );
532
533
0
    return( -1 );
534
0
  }
535
0
  if( number_of_values < 8 )
536
0
  {
537
0
    libcerror_error_set(
538
0
     error,
539
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
540
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
541
0
     "%s: invalid number of values value too small.",
542
0
     function );
543
544
0
    return( -1 );
545
0
  }
546
0
  if( number_of_values > (size_t) SSIZE_MAX )
547
0
  {
548
0
    libcerror_error_set(
549
0
     error,
550
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
551
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
552
0
     "%s: invalid number of values exceeds maximum.",
553
0
     function );
554
555
0
    return( -1 );
556
0
  }
557
/* TODO reverse loop
558
  number_of_iterations = number_of_values * 5;
559
560
  value_32bit_index1 = 0;
561
  value_32bit_index2 = number_of_values - 2;
562
  value_32bit_index3 = number_of_values - 5;
563
*/
564
565
0
  for( number_of_iterations = 5;
566
0
       number_of_iterations > 0;
567
0
       number_of_iterations-- )
568
0
  {
569
0
    value_32bit_index1 = 0;
570
0
    value_32bit_index2 = number_of_values - 2;
571
0
    value_32bit_index3 = number_of_values - 5;
572
573
0
    while( value_32bit_index1 < ( number_of_values - 1 ) )
574
0
    {
575
0
      values_32bit[ value_32bit_index1 ] -= values_32bit[ value_32bit_index2 ]
576
0
                                          ^ byte_stream_bit_rotate_left_32bit(
577
0
                                             values_32bit[ value_32bit_index3 ],
578
0
                                             9 );
579
580
0
      value_32bit_index1++;
581
0
      value_32bit_index2++;
582
0
      value_32bit_index3++;
583
584
0
      if( value_32bit_index3 >= number_of_values )
585
0
      {
586
0
        value_32bit_index3 -= number_of_values;
587
0
      }
588
0
      values_32bit[ value_32bit_index1 ] -= values_32bit[ value_32bit_index2 ]
589
0
                                          ^ values_32bit[ value_32bit_index3 ];
590
591
0
      value_32bit_index1++;
592
0
      value_32bit_index2++;
593
0
      value_32bit_index3++;
594
595
0
      if( value_32bit_index2 >= number_of_values )
596
0
      {
597
0
        value_32bit_index2 -= number_of_values;
598
0
      }
599
0
      values_32bit[ value_32bit_index1 ] -= values_32bit[ value_32bit_index2 ]
600
0
                                          ^ byte_stream_bit_rotate_left_32bit(
601
0
                                             values_32bit[ value_32bit_index3 ],
602
0
                                             13 );
603
604
0
      value_32bit_index1++;
605
0
      value_32bit_index2++;
606
0
      value_32bit_index3++;
607
608
0
      values_32bit[ value_32bit_index1 ] -= values_32bit[ value_32bit_index2 ]
609
0
                                          ^ values_32bit[ value_32bit_index3 ];
610
611
0
      value_32bit_index1++;
612
0
      value_32bit_index2++;
613
0
      value_32bit_index3++;
614
0
    }
615
0
  }
616
0
  return( 1 );
617
0
}
618
619
/* Encrypts the data using Diffuser-B
620
 * Returns 1 if successful or -1 on error
621
 */
622
int libbde_diffuser_b_encrypt(
623
     uint32_t *values_32bit,
624
     size_t number_of_values,
625
     libcerror_error_t **error )
626
0
{
627
0
  static char *function       = "libbde_diffuser_b_encrypt";
628
0
  size_t number_of_iterations = 0;
629
0
  size_t value_32bit_index1   = 0;
630
0
  size_t value_32bit_index2   = 0;
631
0
  size_t value_32bit_index3   = 0;
632
633
0
  if( values_32bit == NULL )
634
0
  {
635
0
    libcerror_error_set(
636
0
     error,
637
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
638
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
639
0
     "%s: invalid values 32-bit.",
640
0
     function );
641
642
0
    return( -1 );
643
0
  }
644
0
  if( number_of_values < 8 )
645
0
  {
646
0
    libcerror_error_set(
647
0
     error,
648
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
649
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
650
0
     "%s: invalid number of values value too small.",
651
0
     function );
652
653
0
    return( -1 );
654
0
  }
655
0
  if( number_of_values > (size_t) SSIZE_MAX )
656
0
  {
657
0
    libcerror_error_set(
658
0
     error,
659
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
660
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
661
0
     "%s: invalid number of values exceeds maximum.",
662
0
     function );
663
664
0
    return( -1 );
665
0
  }
666
/* TODO reverse loop
667
  number_of_iterations = number_of_values * 3;
668
669
  value_32bit_index1 = 0;
670
  value_32bit_index2 = 2;
671
  value_32bit_index3 = 5;
672
*/
673
674
0
  for( number_of_iterations = 3;
675
0
       number_of_iterations > 0;
676
0
       number_of_iterations-- )
677
0
  {
678
0
    value_32bit_index1 = 0;
679
0
    value_32bit_index2 = 2;
680
0
    value_32bit_index3 = 5;
681
682
0
    while( value_32bit_index1 < ( number_of_values - 1 ) )
683
0
    {
684
0
      values_32bit[ value_32bit_index1 ] -= values_32bit[ value_32bit_index2 ]
685
0
                                          ^ values_32bit[ value_32bit_index3 ];
686
687
0
      value_32bit_index1++;
688
0
      value_32bit_index2++;
689
0
      value_32bit_index3++;
690
691
0
      values_32bit[ value_32bit_index1 ] -= values_32bit[ value_32bit_index2 ]
692
0
                                          ^ byte_stream_bit_rotate_left_32bit(
693
0
                                             values_32bit[ value_32bit_index3 ],
694
0
                                             10 );
695
696
0
      value_32bit_index1++;
697
0
      value_32bit_index2++;
698
0
      value_32bit_index3++;
699
700
0
      if( value_32bit_index2 >= number_of_values )
701
0
      {
702
0
        value_32bit_index2 -= number_of_values;
703
0
      }
704
0
      values_32bit[ value_32bit_index1 ] -= values_32bit[ value_32bit_index2 ]
705
0
                                          ^ values_32bit[ value_32bit_index3 ];
706
707
0
      value_32bit_index1++;
708
0
      value_32bit_index2++;
709
0
      value_32bit_index3++;
710
711
0
      if( value_32bit_index3 >= number_of_values )
712
0
      {
713
0
        value_32bit_index3 -= number_of_values;
714
0
      }
715
0
      values_32bit[ value_32bit_index1 ] -= values_32bit[ value_32bit_index2 ]
716
0
                                          ^ byte_stream_bit_rotate_left_32bit(
717
0
                                             values_32bit[ value_32bit_index3 ],
718
0
                                             25 );
719
720
0
      value_32bit_index1++;
721
0
      value_32bit_index2++;
722
0
      value_32bit_index3++;
723
0
    }
724
0
  }
725
0
  return( 1 );
726
0
}
727