Coverage Report

Created: 2023-06-07 06:53

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