Coverage Report

Created: 2025-06-24 07:14

/src/libfcrypto/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-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "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
620
  value0  = byte_stream_bit_rotate_left_32bit( value0, 13 ); \
36
620
  value2  = byte_stream_bit_rotate_left_32bit( value2, 3 ); \
37
620
  value1 ^= value0; \
38
620
  value4  = value0 << 3; \
39
620
  value3 ^= value2; \
40
620
  value1 ^= value2; \
41
620
  value1  = byte_stream_bit_rotate_left_32bit( value1, 1 ); \
42
620
  value3 ^= value4; \
43
620
  value3  = byte_stream_bit_rotate_left_32bit( value3, 7 ); \
44
620
  value4  = value1; \
45
620
  value0 ^= value1; \
46
620
  value4 <<= 7; \
47
620
  value2 ^= value3; \
48
620
  value0 ^= value3; \
49
620
  value2 ^= value4; \
50
620
  value3 ^= expanded_key_values[ expanded_key_index + 3 ]; \
51
620
  value1 ^= expanded_key_values[ expanded_key_index + 1 ]; \
52
620
  value0  = byte_stream_bit_rotate_left_32bit( value0, 5 ); \
53
620
  value2  = byte_stream_bit_rotate_left_32bit( value2, 22 ); \
54
620
  value0 ^= expanded_key_values[ expanded_key_index ]; \
55
620
  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
516
  value4  = value3; \
86
516
  value3 |= value0; \
87
516
  value0 ^= value4; \
88
516
  value4 ^= value2; \
89
516
  value4  = ~value4; \
90
516
  value3 ^= value1; \
91
516
  value1 &= value0; \
92
516
  value1 ^= value4; \
93
516
  value2 ^= value0; \
94
516
  value0 ^= value3; \
95
516
  value4 |= value0; \
96
516
  value0 ^= value2; \
97
516
  value2 &= value1; \
98
516
  value3 ^= value2; \
99
516
  value1  = ~value1; \
100
516
  value2 ^= value4; \
101
516
  value1 ^= value2;
102
103
#define libfcrypto_serpent_calculate_forward_substitution1( value0, value1, value2, value3, value4 ) \
104
516
  value4  = value1; \
105
516
  value1 ^= value0; \
106
516
  value0 ^= value3; \
107
516
  value3  = ~value3; \
108
516
  value4 &= value1; \
109
516
  value0 |= value1; \
110
516
  value3 ^= value2; \
111
516
  value0 ^= value3; \
112
516
  value1 ^= value3; \
113
516
  value3 ^= value4; \
114
516
  value1 |= value4; \
115
516
  value4 ^= value2; \
116
516
  value2 &= value0; \
117
516
  value2 ^= value1; \
118
516
  value1 |= value0; \
119
516
  value0  = ~value0; \
120
516
  value0 ^= value2; \
121
516
  value4 ^= value1;
122
123
#define libfcrypto_serpent_calculate_forward_substitution2( value0, value1, value2, value3, value4 ) \
124
516
  value3  = ~value3; \
125
516
  value1 ^= value0; \
126
516
  value4  = value0; \
127
516
  value0 &= value2; \
128
516
  value0 ^= value3; \
129
516
  value3 |= value4; \
130
516
  value2 ^= value1; \
131
516
  value3 ^= value1; \
132
516
  value1 &= value0; \
133
516
  value0 ^= value2; \
134
516
  value2 &= value3; \
135
516
  value3 |= value1; \
136
516
  value0  = ~value0; \
137
516
  value3 ^= value0; \
138
516
  value4 ^= value0; \
139
516
  value0 ^= value2; \
140
516
  value1 |= value2;
141
142
#define libfcrypto_serpent_calculate_forward_substitution3( value0, value1, value2, value3, value4 ) \
143
625
  value4  = value1; \
144
625
  value1 ^= value3; \
145
625
  value3 |= value0; \
146
625
  value4 &= value0; \
147
625
  value0 ^= value2; \
148
625
  value2 ^= value1; \
149
625
  value1 &= value3; \
150
625
  value2 ^= value3; \
151
625
  value0 |= value4; \
152
625
  value4 ^= value3; \
153
625
  value1 ^= value0; \
154
625
  value0 &= value3; \
155
625
  value3 &= value4; \
156
625
  value3 ^= value2; \
157
625
  value4 |= value1; \
158
625
  value2 &= value1; \
159
625
  value4 ^= value3; \
160
625
  value0 ^= value3; \
161
625
  value3 ^= value2;
162
163
#define libfcrypto_serpent_calculate_forward_substitution4( value0, value1, value2, value3, value4 ) \
164
516
  value4  = value3; \
165
516
  value3 &= value0; \
166
516
  value0 ^= value4; \
167
516
  value3 ^= value2; \
168
516
  value2 |= value4; \
169
516
  value0 ^= value1; \
170
516
  value4 ^= value3; \
171
516
  value2 |= value0; \
172
516
  value2 ^= value1; \
173
516
  value1 &= value0; \
174
516
  value1 ^= value4; \
175
516
  value4 &= value2; \
176
516
  value2 ^= value3; \
177
516
  value4 ^= value0; \
178
516
  value3 |= value1; \
179
516
  value1  = ~value1; \
180
516
  value3 ^= value0;
181
182
#define libfcrypto_serpent_calculate_forward_substitution5( value0, value1, value2, value3, value4 ) \
183
516
  value4  = value1; \
184
516
  value1 |= value0; \
185
516
  value2 ^= value1; \
186
516
  value3  = ~value3; \
187
516
  value4 ^= value0; \
188
516
  value0 ^= value2; \
189
516
  value1 &= value4; \
190
516
  value4 |= value3; \
191
516
  value4 ^= value0; \
192
516
  value0 &= value3; \
193
516
  value1 ^= value3; \
194
516
  value3 ^= value2; \
195
516
  value0 ^= value1; \
196
516
  value2 &= value4; \
197
516
  value1 ^= value2; \
198
516
  value2 &= value0; \
199
516
  value3 ^= value2;
200
201
#define libfcrypto_serpent_calculate_forward_substitution6( value0, value1, value2, value3, value4 ) \
202
516
  value4  = value1; \
203
516
  value3 ^= value0; \
204
516
  value1 ^= value2; \
205
516
  value2 ^= value0; \
206
516
  value0 &= value3; \
207
516
  value1 |= value3; \
208
516
  value4  = ~value4; \
209
516
  value0 ^= value1; \
210
516
  value1 ^= value2; \
211
516
  value3 ^= value4; \
212
516
  value4 ^= value0; \
213
516
  value2 &= value0; \
214
516
  value4 ^= value1; \
215
516
  value2 ^= value3; \
216
516
  value3 &= value1; \
217
516
  value3 ^= value0; \
218
516
  value1 ^= value2;
219
220
#define libfcrypto_serpent_calculate_forward_substitution7( value0, value1, value2, value3, value4 ) \
221
516
  value1  = ~value1; \
222
516
  value4  = value1; \
223
516
  value0  = ~value0; \
224
516
  value1 &= value2; \
225
516
  value1 ^= value3; \
226
516
  value3 |= value4; \
227
516
  value4 ^= value2; \
228
516
  value2 ^= value3; \
229
516
  value3 ^= value0; \
230
516
  value0 |= value1; \
231
516
  value2 &= value0; \
232
516
  value0 ^= value4; \
233
516
  value4 ^= value3; \
234
516
  value3 &= value0; \
235
516
  value4 ^= value1; \
236
516
  value2 ^= value4; \
237
516
  value3 ^= value1; \
238
516
  value4 |= value0; \
239
516
  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
14.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
14.3k
  value1 ^= value3; \
404
14.3k
  value1 ^= value2; \
405
14.3k
  value1 ^= value0; \
406
14.3k
  value1 ^= GOLDEN_RATIO_FRACTION ^ expanded_key_index; \
407
14.3k
  value1 = byte_stream_bit_rotate_left_32bit( value1, 11 ); \
408
14.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
436
  expanded_key_value0 = value0; \
412
436
  expanded_key_value1 = value1; \
413
436
  expanded_key_value2 = value2; \
414
436
  expanded_key_value3 = value3; \
415
436
  value0 = expanded_key_value4; \
416
436
  value1 = expanded_key_value5; \
417
436
  value2 = expanded_key_value6; \
418
436
  value3 = expanded_key_value7; \
419
436
  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
436
  expanded_key_value0 = value0; \
423
436
  expanded_key_value1 = value1; \
424
436
  expanded_key_value2 = value2; \
425
436
  expanded_key_value3 = value3; \
426
436
  value0 = expanded_key_value4; \
427
436
  value1 = expanded_key_value5; \
428
436
  value2 = expanded_key_value6; \
429
436
  value3 = expanded_key_value7; \
430
436
  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
436
  expanded_key_value0 = value0; \
434
436
  expanded_key_value1 = value1; \
435
436
  expanded_key_value2 = value2; \
436
436
  expanded_key_value3 = value3; \
437
436
  value0 = expanded_key_value4; \
438
436
  value1 = expanded_key_value5; \
439
436
  value2 = expanded_key_value6; \
440
436
  value3 = expanded_key_value7; \
441
436
  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
436
  expanded_key_value0 = value0; \
445
436
  expanded_key_value1 = value1; \
446
436
  expanded_key_value2 = value2; \
447
436
  expanded_key_value3 = value3; \
448
436
  value0 = expanded_key_value4; \
449
436
  value1 = expanded_key_value5; \
450
436
  value2 = expanded_key_value6; \
451
436
  value3 = expanded_key_value7; \
452
436
  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
436
  expanded_key_value0 = value0; \
456
436
  expanded_key_value1 = value1; \
457
436
  expanded_key_value2 = value2; \
458
436
  expanded_key_value3 = value3; \
459
436
  value0 = expanded_key_value4; \
460
436
  value1 = expanded_key_value5; \
461
436
  value2 = expanded_key_value6; \
462
436
  value3 = expanded_key_value7; \
463
436
  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
436
  expanded_key_value0 = value0; \
467
436
  expanded_key_value1 = value1; \
468
436
  expanded_key_value2 = value2; \
469
436
  expanded_key_value3 = value3; \
470
436
  value0 = expanded_key_value4; \
471
436
  value1 = expanded_key_value5; \
472
436
  value2 = expanded_key_value6; \
473
436
  value3 = expanded_key_value7; \
474
436
  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
436
  expanded_key_value0 = value0; \
478
436
  expanded_key_value1 = value1; \
479
436
  expanded_key_value2 = value2; \
480
436
  expanded_key_value3 = value3; \
481
436
  value0 = expanded_key_value4; \
482
436
  value1 = expanded_key_value5; \
483
436
  value2 = expanded_key_value6; \
484
436
  value3 = expanded_key_value7; \
485
436
  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
436
  expanded_key_value0 = value0; \
489
436
  expanded_key_value1 = value1; \
490
436
  expanded_key_value2 = value2; \
491
436
  expanded_key_value3 = value3; \
492
436
  value0 = expanded_key_value4; \
493
436
  value1 = expanded_key_value5; \
494
436
  value2 = expanded_key_value6; \
495
436
  value3 = expanded_key_value7; \
496
436
  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
60
  libfcrypto_serpent_calculate_forward_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
500
60
  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
80
  libfcrypto_serpent_calculate_forward_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
504
80
  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
80
  libfcrypto_serpent_calculate_forward_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
508
80
  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
80
  libfcrypto_serpent_calculate_forward_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
512
80
  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
80
  libfcrypto_serpent_calculate_forward_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
516
80
  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
80
  libfcrypto_serpent_calculate_forward_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
520
80
  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
80
  libfcrypto_serpent_calculate_forward_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
524
80
  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
80
  libfcrypto_serpent_calculate_forward_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
528
80
  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
109
{
570
109
  libfcrypto_internal_serpent_context_t *internal_context = NULL;
571
109
  static char *function                                   = "libfcrypto_serpent_context_initialize";
572
573
109
  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
109
  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
109
  internal_context = memory_allocate_structure(
596
109
                      libfcrypto_internal_serpent_context_t );
597
598
109
  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
109
  if( memory_set(
610
109
       internal_context,
611
109
       0,
612
109
       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
109
  *context = (libfcrypto_serpent_context_t *) internal_context;
624
625
109
  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
109
}
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
109
{
643
109
  libfcrypto_internal_serpent_context_t *internal_context = NULL;
644
109
  static char *function                                   = "libfcrypto_serpent_context_free";
645
109
  int result                                              = 1;
646
647
109
  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
109
  if( *context != NULL )
659
109
  {
660
109
    internal_context = (libfcrypto_internal_serpent_context_t *) *context;
661
109
    *context         = NULL;
662
663
109
    if( memory_set(
664
109
         internal_context,
665
109
         0,
666
109
         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
109
    memory_free(
678
109
     internal_context );
679
109
  }
680
109
  return( result );
681
109
}
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
109
{
692
109
  uint8_t key_data[ 32 ];
693
694
109
  libfcrypto_internal_serpent_context_t *internal_context = NULL;
695
109
  static char *function                                   = "libfcrypto_serpent_context_set_key";
696
109
  size_t key_byte_offset                                  = 0;
697
109
  size_t key_byte_size                                    = 0;
698
109
  uint32_t value0                                         = 0;
699
109
  uint32_t value1                                         = 0;
700
109
  uint32_t value2                                         = 0;
701
109
  uint32_t value3                                         = 0;
702
109
  uint32_t value4                                         = 0;
703
109
  uint8_t expanded_key_index                              = 0;
704
109
  uint8_t previous_expanded_key_index                     = 0;
705
706
109
  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
109
  internal_context = (libfcrypto_internal_serpent_context_t *) context;
718
719
109
  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
109
  if( ( key_bit_size != 128 )
731
109
   && ( key_bit_size != 192 )
732
109
   && ( 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
109
  if( memory_set(
744
109
       key_data,
745
109
       0,
746
109
       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
109
  if( memory_set(
758
109
       internal_context->expanded_key,
759
109
       0,
760
109
       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
109
  key_byte_size = key_bit_size / 8;
774
775
109
  if( memory_copy(
776
109
       key_data,
777
109
       key,
778
109
       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
109
  if( key_byte_size < 32 )
790
109
  {
791
109
    key_data[ key_byte_size ] = 1;
792
109
  }
793
109
  for( key_byte_offset = 0;
794
981
       key_byte_offset < 32;
795
872
       key_byte_offset += 4 )
796
872
  {
797
872
    byte_stream_copy_to_uint32_little_endian(
798
872
     &( key_data[ key_byte_offset ] ),
799
872
     value0 );
800
801
872
    internal_context->expanded_key[ expanded_key_index++ ] = value0;
802
872
  }
803
  /* 2. Calculate the prekeys
804
   */
805
109
  value0 = internal_context->expanded_key[ 3 ];
806
109
  value1 = internal_context->expanded_key[ 4 ];
807
109
  value2 = internal_context->expanded_key[ 5 ];
808
109
  value3 = internal_context->expanded_key[ 6 ];
809
109
  value4 = internal_context->expanded_key[ 7 ];
810
811
109
  libfcrypto_serpent_calculate_expanded_key(
812
109
   internal_context->expanded_key,
813
109
   0,
814
109
   internal_context->expanded_key[ 0 ],
815
109
   value0,
816
109
   value4,
817
109
   value2 );
818
819
109
  libfcrypto_serpent_calculate_expanded_key(
820
109
   internal_context->expanded_key,
821
109
   1,
822
109
   internal_context->expanded_key[ 1 ],
823
109
   value1,
824
109
   value0,
825
109
   value3 );
826
827
109
  libfcrypto_serpent_calculate_expanded_key(
828
109
   internal_context->expanded_key,
829
109
   2,
830
109
   ( internal_context->expanded_key )[ 2 ],
831
109
   value2,
832
109
   value1,
833
109
   value4 );
834
835
109
  libfcrypto_serpent_calculate_expanded_key(
836
109
   internal_context->expanded_key,
837
109
   3,
838
109
   ( internal_context->expanded_key )[ 3 ],
839
109
   value3,
840
109
   value2,
841
109
   value0 );
842
843
109
  libfcrypto_serpent_calculate_expanded_key(
844
109
   internal_context->expanded_key,
845
109
   4,
846
109
   ( internal_context->expanded_key )[ 4 ],
847
109
   value4,
848
109
   value3,
849
109
   value1 );
850
851
109
  libfcrypto_serpent_calculate_expanded_key(
852
109
   internal_context->expanded_key,
853
109
   5,
854
109
   ( internal_context->expanded_key )[ 5 ],
855
109
   value0,
856
109
   value4,
857
109
   value2 );
858
859
109
  libfcrypto_serpent_calculate_expanded_key(
860
109
   internal_context->expanded_key,
861
109
   6,
862
109
   ( internal_context->expanded_key )[ 6 ],
863
109
   value1,
864
109
   value0,
865
109
   value3 );
866
867
109
  libfcrypto_serpent_calculate_expanded_key(
868
109
   internal_context->expanded_key,
869
109
   7,
870
109
   ( internal_context->expanded_key )[ 7 ],
871
109
   value2,
872
109
   value1,
873
109
   value4 );
874
875
109
  libfcrypto_serpent_calculate_expanded_key(
876
109
   internal_context->expanded_key,
877
109
   8,
878
109
   ( internal_context->expanded_key )[ 0 ],
879
109
   value3,
880
109
   value2,
881
109
   value0 );
882
883
109
  libfcrypto_serpent_calculate_expanded_key(
884
109
   internal_context->expanded_key,
885
109
   9,
886
109
   ( internal_context->expanded_key )[ 1 ],
887
109
   value4,
888
109
   value3,
889
109
   value1 );
890
891
109
  libfcrypto_serpent_calculate_expanded_key(
892
109
   internal_context->expanded_key,
893
109
   10,
894
109
   ( internal_context->expanded_key )[ 2 ],
895
109
   value0,
896
109
   value4,
897
109
   value2 );
898
899
109
  libfcrypto_serpent_calculate_expanded_key(
900
109
   internal_context->expanded_key,
901
109
   11,
902
109
   ( internal_context->expanded_key )[ 3 ],
903
109
   value1,
904
109
   value0,
905
109
   value3 );
906
907
109
  previous_expanded_key_index = 4;
908
109
  expanded_key_index          = 12;
909
910
2.72k
  while( expanded_key_index < 128 )
911
2.61k
  {
912
2.61k
    libfcrypto_serpent_calculate_expanded_key(
913
2.61k
     internal_context->expanded_key,
914
2.61k
     expanded_key_index,
915
2.61k
     ( internal_context->expanded_key )[ previous_expanded_key_index ],
916
2.61k
     value2,
917
2.61k
     value1,
918
2.61k
     value4 );
919
920
2.61k
    expanded_key_index++;
921
2.61k
    previous_expanded_key_index++;
922
923
2.61k
    libfcrypto_serpent_calculate_expanded_key(
924
2.61k
     internal_context->expanded_key,
925
2.61k
     expanded_key_index,
926
2.61k
     ( internal_context->expanded_key )[ previous_expanded_key_index ],
927
2.61k
     value3,
928
2.61k
     value2,
929
2.61k
     value0 );
930
931
2.61k
    expanded_key_index++;
932
2.61k
    previous_expanded_key_index++;
933
934
2.61k
    libfcrypto_serpent_calculate_expanded_key(
935
2.61k
     internal_context->expanded_key,
936
2.61k
     expanded_key_index,
937
2.61k
     ( internal_context->expanded_key )[ previous_expanded_key_index ],
938
2.61k
     value4,
939
2.61k
     value3,
940
2.61k
     value1 );
941
942
2.61k
    expanded_key_index++;
943
2.61k
    previous_expanded_key_index++;
944
945
2.61k
    libfcrypto_serpent_calculate_expanded_key(
946
2.61k
     internal_context->expanded_key,
947
2.61k
     expanded_key_index,
948
2.61k
     ( internal_context->expanded_key )[ previous_expanded_key_index ],
949
2.61k
     value0,
950
2.61k
     value4,
951
2.61k
     value2 );
952
953
2.61k
    expanded_key_index++;
954
2.61k
    previous_expanded_key_index++;
955
956
2.61k
    libfcrypto_serpent_calculate_expanded_key(
957
2.61k
     internal_context->expanded_key,
958
2.61k
     expanded_key_index,
959
2.61k
     ( internal_context->expanded_key )[ previous_expanded_key_index ],
960
2.61k
     value1,
961
2.61k
     value0,
962
2.61k
     value3 );
963
964
2.61k
    expanded_key_index++;
965
2.61k
    previous_expanded_key_index++;
966
2.61k
  }
967
  /* 3. Calculate the round keys
968
   */
969
109
  libfcrypto_serpent_calculate_forward_substitution3(
970
109
   value3,
971
109
   value4,
972
109
   value0,
973
109
   value1,
974
109
   value2 );
975
976
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution4(
977
109
   internal_context->expanded_key[ 128 ],
978
109
   internal_context->expanded_key[ 129 ],
979
109
   internal_context->expanded_key[ 130 ],
980
109
   internal_context->expanded_key[ 131 ],
981
109
   internal_context->expanded_key[ 124 ],
982
109
   internal_context->expanded_key[ 125 ],
983
109
   internal_context->expanded_key[ 126 ],
984
109
   internal_context->expanded_key[ 127 ],
985
109
   value1,
986
109
   value2,
987
109
   value4,
988
109
   value3,
989
109
   value0 );
990
991
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution5(
992
109
   internal_context->expanded_key[ 124 ],
993
109
   internal_context->expanded_key[ 125 ],
994
109
   internal_context->expanded_key[ 126 ],
995
109
   internal_context->expanded_key[ 127 ],
996
109
   internal_context->expanded_key[ 120 ],
997
109
   internal_context->expanded_key[ 121 ],
998
109
   internal_context->expanded_key[ 122 ],
999
109
   internal_context->expanded_key[ 123 ],
1000
109
   value2,
1001
109
   value4,
1002
109
   value3,
1003
109
   value0,
1004
109
   value1 );
1005
1006
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution6(
1007
109
   internal_context->expanded_key[ 120 ],
1008
109
   internal_context->expanded_key[ 121 ],
1009
109
   internal_context->expanded_key[ 122 ],
1010
109
   internal_context->expanded_key[ 123 ],
1011
109
   internal_context->expanded_key[ 116 ],
1012
109
   internal_context->expanded_key[ 117 ],
1013
109
   internal_context->expanded_key[ 118 ],
1014
109
   internal_context->expanded_key[ 119 ],
1015
109
   value1,
1016
109
   value2,
1017
109
   value4,
1018
109
   value0,
1019
109
   value3 );
1020
1021
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution7(
1022
109
   internal_context->expanded_key[ 116 ],
1023
109
   internal_context->expanded_key[ 117 ],
1024
109
   internal_context->expanded_key[ 118 ],
1025
109
   internal_context->expanded_key[ 119 ],
1026
109
   internal_context->expanded_key[ 112 ],
1027
109
   internal_context->expanded_key[ 113 ],
1028
109
   internal_context->expanded_key[ 114 ],
1029
109
   internal_context->expanded_key[ 115 ],
1030
109
   value4,
1031
109
   value3,
1032
109
   value2,
1033
109
   value0,
1034
109
   value1 );
1035
1036
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution0(
1037
109
   internal_context->expanded_key[ 112 ],
1038
109
   internal_context->expanded_key[ 113 ],
1039
109
   internal_context->expanded_key[ 114 ],
1040
109
   internal_context->expanded_key[ 115 ],
1041
109
   internal_context->expanded_key[ 108 ],
1042
109
   internal_context->expanded_key[ 109 ],
1043
109
   internal_context->expanded_key[ 110 ],
1044
109
   internal_context->expanded_key[ 111 ],
1045
109
   value1,
1046
109
   value2,
1047
109
   value0,
1048
109
   value4,
1049
109
   value3 );
1050
1051
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution1(
1052
109
   internal_context->expanded_key[ 108 ],
1053
109
   internal_context->expanded_key[ 109 ],
1054
109
   internal_context->expanded_key[ 110 ],
1055
109
   internal_context->expanded_key[ 111 ],
1056
109
   internal_context->expanded_key[ 104 ],
1057
109
   internal_context->expanded_key[ 105 ],
1058
109
   internal_context->expanded_key[ 106 ],
1059
109
   internal_context->expanded_key[ 107 ],
1060
109
   value0,
1061
109
   value2,
1062
109
   value4,
1063
109
   value1,
1064
109
   value3 );
1065
1066
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution2(
1067
109
   internal_context->expanded_key[ 104 ],
1068
109
   internal_context->expanded_key[ 105 ],
1069
109
   internal_context->expanded_key[ 106 ],
1070
109
   internal_context->expanded_key[ 107 ],
1071
109
   internal_context->expanded_key[ 100 ],
1072
109
   internal_context->expanded_key[ 101 ],
1073
109
   internal_context->expanded_key[ 102 ],
1074
109
   internal_context->expanded_key[ 103 ],
1075
109
   value3,
1076
109
   value4,
1077
109
   value1,
1078
109
   value0,
1079
109
   value2 );
1080
1081
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution3(
1082
109
   internal_context->expanded_key[ 100 ],
1083
109
   internal_context->expanded_key[ 101 ],
1084
109
   internal_context->expanded_key[ 102 ],
1085
109
   internal_context->expanded_key[ 103 ],
1086
109
   internal_context->expanded_key[ 96 ],
1087
109
   internal_context->expanded_key[ 97 ],
1088
109
   internal_context->expanded_key[ 98 ],
1089
109
   internal_context->expanded_key[ 99 ],
1090
109
   value2,
1091
109
   value4,
1092
109
   value3,
1093
109
   value0,
1094
109
   value1 );
1095
1096
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution4(
1097
109
   internal_context->expanded_key[ 96 ],
1098
109
   internal_context->expanded_key[ 97 ],
1099
109
   internal_context->expanded_key[ 98 ],
1100
109
   internal_context->expanded_key[ 99 ],
1101
109
   internal_context->expanded_key[ 92 ],
1102
109
   internal_context->expanded_key[ 93 ],
1103
109
   internal_context->expanded_key[ 94 ],
1104
109
   internal_context->expanded_key[ 95 ],
1105
109
   value0,
1106
109
   value1,
1107
109
   value4,
1108
109
   value2,
1109
109
   value3 );
1110
1111
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution5(
1112
109
   internal_context->expanded_key[ 92 ],
1113
109
   internal_context->expanded_key[ 93 ],
1114
109
   internal_context->expanded_key[ 94 ],
1115
109
   internal_context->expanded_key[ 95 ],
1116
109
   internal_context->expanded_key[ 88 ],
1117
109
   internal_context->expanded_key[ 89 ],
1118
109
   internal_context->expanded_key[ 90 ],
1119
109
   internal_context->expanded_key[ 91 ],
1120
109
   value1,
1121
109
   value4,
1122
109
   value2,
1123
109
   value3,
1124
109
   value0 );
1125
1126
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution6(
1127
109
   internal_context->expanded_key[ 88 ],
1128
109
   internal_context->expanded_key[ 89 ],
1129
109
   internal_context->expanded_key[ 90 ],
1130
109
   internal_context->expanded_key[ 91 ],
1131
109
   internal_context->expanded_key[ 84 ],
1132
109
   internal_context->expanded_key[ 85 ],
1133
109
   internal_context->expanded_key[ 86 ],
1134
109
   internal_context->expanded_key[ 87 ],
1135
109
   value0,
1136
109
   value1,
1137
109
   value4,
1138
109
   value3,
1139
109
   value2 );
1140
1141
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution7(
1142
109
   internal_context->expanded_key[ 84 ],
1143
109
   internal_context->expanded_key[ 85 ],
1144
109
   internal_context->expanded_key[ 86 ],
1145
109
   internal_context->expanded_key[ 87 ],
1146
109
   internal_context->expanded_key[ 80 ],
1147
109
   internal_context->expanded_key[ 81 ],
1148
109
   internal_context->expanded_key[ 82 ],
1149
109
   internal_context->expanded_key[ 83 ],
1150
109
   value4,
1151
109
   value2,
1152
109
   value1,
1153
109
   value3,
1154
109
   value0 );
1155
1156
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution0(
1157
109
   internal_context->expanded_key[ 80 ],
1158
109
   internal_context->expanded_key[ 81 ],
1159
109
   internal_context->expanded_key[ 82 ],
1160
109
   internal_context->expanded_key[ 83 ],
1161
109
   internal_context->expanded_key[ 76 ],
1162
109
   internal_context->expanded_key[ 77 ],
1163
109
   internal_context->expanded_key[ 78 ],
1164
109
   internal_context->expanded_key[ 79 ],
1165
109
   value0,
1166
109
   value1,
1167
109
   value3,
1168
109
   value4,
1169
109
   value2 );
1170
1171
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution1(
1172
109
   internal_context->expanded_key[ 76 ],
1173
109
   internal_context->expanded_key[ 77 ],
1174
109
   internal_context->expanded_key[ 78 ],
1175
109
   internal_context->expanded_key[ 79 ],
1176
109
   internal_context->expanded_key[ 72 ],
1177
109
   internal_context->expanded_key[ 73 ],
1178
109
   internal_context->expanded_key[ 74 ],
1179
109
   internal_context->expanded_key[ 75 ],
1180
109
   value3,
1181
109
   value1,
1182
109
   value4,
1183
109
   value0,
1184
109
   value2 );
1185
1186
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution2(
1187
109
   internal_context->expanded_key[ 72 ],
1188
109
   internal_context->expanded_key[ 73 ],
1189
109
   internal_context->expanded_key[ 74 ],
1190
109
   internal_context->expanded_key[ 75 ],
1191
109
   internal_context->expanded_key[ 68 ],
1192
109
   internal_context->expanded_key[ 69 ],
1193
109
   internal_context->expanded_key[ 70 ],
1194
109
   internal_context->expanded_key[ 71 ],
1195
109
   value2,
1196
109
   value4,
1197
109
   value0,
1198
109
   value3,
1199
109
   value1 );
1200
1201
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution3(
1202
109
   internal_context->expanded_key[ 68 ],
1203
109
   internal_context->expanded_key[ 69 ],
1204
109
   internal_context->expanded_key[ 70 ],
1205
109
   internal_context->expanded_key[ 71 ],
1206
109
   internal_context->expanded_key[ 64 ],
1207
109
   internal_context->expanded_key[ 65 ],
1208
109
   internal_context->expanded_key[ 66 ],
1209
109
   internal_context->expanded_key[ 67 ],
1210
109
   value1,
1211
109
   value4,
1212
109
   value2,
1213
109
   value3,
1214
109
   value0 );
1215
1216
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution4(
1217
109
   internal_context->expanded_key[ 64 ],
1218
109
   internal_context->expanded_key[ 65 ],
1219
109
   internal_context->expanded_key[ 66 ],
1220
109
   internal_context->expanded_key[ 67 ],
1221
109
   internal_context->expanded_key[ 60 ],
1222
109
   internal_context->expanded_key[ 61 ],
1223
109
   internal_context->expanded_key[ 62 ],
1224
109
   internal_context->expanded_key[ 63 ],
1225
109
   value3,
1226
109
   value0,
1227
109
   value4,
1228
109
   value1,
1229
109
   value2 );
1230
1231
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution5(
1232
109
   internal_context->expanded_key[ 60 ],
1233
109
   internal_context->expanded_key[ 61 ],
1234
109
   internal_context->expanded_key[ 62 ],
1235
109
   internal_context->expanded_key[ 63 ],
1236
109
   internal_context->expanded_key[ 56 ],
1237
109
   internal_context->expanded_key[ 57 ],
1238
109
   internal_context->expanded_key[ 58 ],
1239
109
   internal_context->expanded_key[ 59 ],
1240
109
   value0,
1241
109
   value4,
1242
109
   value1,
1243
109
   value2,
1244
109
   value3 );
1245
1246
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution6(
1247
109
   internal_context->expanded_key[ 56 ],
1248
109
   internal_context->expanded_key[ 57 ],
1249
109
   internal_context->expanded_key[ 58 ],
1250
109
   internal_context->expanded_key[ 59 ],
1251
109
   internal_context->expanded_key[ 52 ],
1252
109
   internal_context->expanded_key[ 53 ],
1253
109
   internal_context->expanded_key[ 54 ],
1254
109
   internal_context->expanded_key[ 55 ],
1255
109
   value3,
1256
109
   value0,
1257
109
   value4,
1258
109
   value2,
1259
109
   value1 );
1260
1261
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution7(
1262
109
   internal_context->expanded_key[ 52 ],
1263
109
   internal_context->expanded_key[ 53 ],
1264
109
   internal_context->expanded_key[ 54 ],
1265
109
   internal_context->expanded_key[ 55 ],
1266
109
   internal_context->expanded_key[ 48 ],
1267
109
   internal_context->expanded_key[ 49 ],
1268
109
   internal_context->expanded_key[ 50 ],
1269
109
   internal_context->expanded_key[ 51 ],
1270
109
   value4,
1271
109
   value1,
1272
109
   value0,
1273
109
   value2,
1274
109
   value3 );
1275
1276
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution0(
1277
109
   internal_context->expanded_key[ 48 ],
1278
109
   internal_context->expanded_key[ 49 ],
1279
109
   internal_context->expanded_key[ 50 ],
1280
109
   internal_context->expanded_key[ 51 ],
1281
109
   internal_context->expanded_key[ 44 ],
1282
109
   internal_context->expanded_key[ 45 ],
1283
109
   internal_context->expanded_key[ 46 ],
1284
109
   internal_context->expanded_key[ 47 ],
1285
109
   value3,
1286
109
   value0,
1287
109
   value2,
1288
109
   value4,
1289
109
   value1 );
1290
1291
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution1(
1292
109
   internal_context->expanded_key[ 44 ],
1293
109
   internal_context->expanded_key[ 45 ],
1294
109
   internal_context->expanded_key[ 46 ],
1295
109
   internal_context->expanded_key[ 47 ],
1296
109
   internal_context->expanded_key[ 40 ],
1297
109
   internal_context->expanded_key[ 41 ],
1298
109
   internal_context->expanded_key[ 42 ],
1299
109
   internal_context->expanded_key[ 43 ],
1300
109
   value2,
1301
109
   value0,
1302
109
   value4,
1303
109
   value3,
1304
109
   value1 );
1305
1306
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution2(
1307
109
   internal_context->expanded_key[ 40 ],
1308
109
   internal_context->expanded_key[ 41 ],
1309
109
   internal_context->expanded_key[ 42 ],
1310
109
   internal_context->expanded_key[ 43 ],
1311
109
   internal_context->expanded_key[ 36 ],
1312
109
   internal_context->expanded_key[ 37 ],
1313
109
   internal_context->expanded_key[ 38 ],
1314
109
   internal_context->expanded_key[ 39 ],
1315
109
   value1,
1316
109
   value4,
1317
109
   value3,
1318
109
   value2,
1319
109
   value0 );
1320
1321
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution3(
1322
109
   internal_context->expanded_key[ 36 ],
1323
109
   internal_context->expanded_key[ 37 ],
1324
109
   internal_context->expanded_key[ 38 ],
1325
109
   internal_context->expanded_key[ 39 ],
1326
109
   internal_context->expanded_key[ 32 ],
1327
109
   internal_context->expanded_key[ 33 ],
1328
109
   internal_context->expanded_key[ 34 ],
1329
109
   internal_context->expanded_key[ 35 ],
1330
109
   value0,
1331
109
   value4,
1332
109
   value1,
1333
109
   value2,
1334
109
   value3 );
1335
1336
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution4(
1337
109
   internal_context->expanded_key[ 32 ],
1338
109
   internal_context->expanded_key[ 33 ],
1339
109
   internal_context->expanded_key[ 34 ],
1340
109
   internal_context->expanded_key[ 35 ],
1341
109
   internal_context->expanded_key[ 28 ],
1342
109
   internal_context->expanded_key[ 29 ],
1343
109
   internal_context->expanded_key[ 30 ],
1344
109
   internal_context->expanded_key[ 31 ],
1345
109
   value2,
1346
109
   value3,
1347
109
   value4,
1348
109
   value0,
1349
109
   value1 );
1350
1351
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution5(
1352
109
   internal_context->expanded_key[ 28 ],
1353
109
   internal_context->expanded_key[ 29 ],
1354
109
   internal_context->expanded_key[ 30 ],
1355
109
   internal_context->expanded_key[ 31 ],
1356
109
   internal_context->expanded_key[ 24 ],
1357
109
   internal_context->expanded_key[ 25 ],
1358
109
   internal_context->expanded_key[ 26 ],
1359
109
   internal_context->expanded_key[ 27 ],
1360
109
   value3,
1361
109
   value4,
1362
109
   value0,
1363
109
   value1,
1364
109
   value2 );
1365
1366
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution6(
1367
109
   internal_context->expanded_key[ 24 ],
1368
109
   internal_context->expanded_key[ 25 ],
1369
109
   internal_context->expanded_key[ 26 ],
1370
109
   internal_context->expanded_key[ 27 ],
1371
109
   internal_context->expanded_key[ 20 ],
1372
109
   internal_context->expanded_key[ 21 ],
1373
109
   internal_context->expanded_key[ 22 ],
1374
109
   internal_context->expanded_key[ 23 ],
1375
109
   value2,
1376
109
   value3,
1377
109
   value4,
1378
109
   value1,
1379
109
   value0 );
1380
1381
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution7(
1382
109
   internal_context->expanded_key[ 20 ],
1383
109
   internal_context->expanded_key[ 21 ],
1384
109
   internal_context->expanded_key[ 22 ],
1385
109
   internal_context->expanded_key[ 23 ],
1386
109
   internal_context->expanded_key[ 16 ],
1387
109
   internal_context->expanded_key[ 17 ],
1388
109
   internal_context->expanded_key[ 18 ],
1389
109
   internal_context->expanded_key[ 19 ],
1390
109
   value4,
1391
109
   value0,
1392
109
   value3,
1393
109
   value1,
1394
109
   value2 );
1395
1396
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution0(
1397
109
   internal_context->expanded_key[ 16 ],
1398
109
   internal_context->expanded_key[ 17 ],
1399
109
   internal_context->expanded_key[ 18 ],
1400
109
   internal_context->expanded_key[ 19 ],
1401
109
   internal_context->expanded_key[ 12 ],
1402
109
   internal_context->expanded_key[ 13 ],
1403
109
   internal_context->expanded_key[ 14 ],
1404
109
   internal_context->expanded_key[ 15 ],
1405
109
   value2,
1406
109
   value3,
1407
109
   value1,
1408
109
   value4,
1409
109
   value0 );
1410
1411
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution1(
1412
109
   internal_context->expanded_key[ 12 ],
1413
109
   internal_context->expanded_key[ 13 ],
1414
109
   internal_context->expanded_key[ 14 ],
1415
109
   internal_context->expanded_key[ 15 ],
1416
109
   internal_context->expanded_key[ 8 ],
1417
109
   internal_context->expanded_key[ 9 ],
1418
109
   internal_context->expanded_key[ 10 ],
1419
109
   internal_context->expanded_key[ 11 ],
1420
109
   value1,
1421
109
   value3,
1422
109
   value4,
1423
109
   value2,
1424
109
   value0 );
1425
1426
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution2(
1427
109
   internal_context->expanded_key[ 8 ],
1428
109
   internal_context->expanded_key[ 9 ],
1429
109
   internal_context->expanded_key[ 10 ],
1430
109
   internal_context->expanded_key[ 11 ],
1431
109
   internal_context->expanded_key[ 4 ],
1432
109
   internal_context->expanded_key[ 5 ],
1433
109
   internal_context->expanded_key[ 6 ],
1434
109
   internal_context->expanded_key[ 7 ],
1435
109
   value0,
1436
109
   value4,
1437
109
   value2,
1438
109
   value1,
1439
109
   value3 );
1440
1441
109
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution3(
1442
109
   internal_context->expanded_key[ 4 ],
1443
109
   internal_context->expanded_key[ 5 ],
1444
109
   internal_context->expanded_key[ 6 ],
1445
109
   internal_context->expanded_key[ 7 ],
1446
109
   internal_context->expanded_key[ 0 ],
1447
109
   internal_context->expanded_key[ 1 ],
1448
109
   internal_context->expanded_key[ 2 ],
1449
109
   internal_context->expanded_key[ 3 ],
1450
109
   value3,
1451
109
   value4,
1452
109
   value0,
1453
109
   value1,
1454
109
   value2 );
1455
1456
109
  internal_context->expanded_key[ 0 ] = value1;
1457
109
  internal_context->expanded_key[ 1 ] = value2;
1458
109
  internal_context->expanded_key[ 2 ] = value4;
1459
109
  internal_context->expanded_key[ 3 ] = value3;
1460
1461
109
  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
109
}
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
20
{
1489
20
  static char *function = "libfcrypto_internal_serpent_context_encrypt_block";
1490
20
  uint32_t value0       = 0;
1491
20
  uint32_t value1       = 0;
1492
20
  uint32_t value2       = 0;
1493
20
  uint32_t value3       = 0;
1494
20
  uint32_t value4       = 0;
1495
1496
20
  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
20
  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
20
  if( ( input_data_size < 16 )
1519
20
   || ( input_data_size > (size_t) SSIZE_MAX ) )
1520
0
  {
1521
0
    libcerror_error_set(
1522
0
     error,
1523
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1524
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1525
0
     "%s: invalid input data size value out of bounds.",
1526
0
     function );
1527
1528
0
    return( -1 );
1529
0
  }
1530
20
  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
20
  if( ( output_data_size < 16 )
1542
20
   || ( 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
20
  byte_stream_copy_to_uint32_little_endian(
1554
20
   &( input_data[ 0 ] ),
1555
20
   value0 );
1556
1557
20
  byte_stream_copy_to_uint32_little_endian(
1558
20
   &( input_data[ 4 ] ),
1559
20
   value1 );
1560
1561
20
  byte_stream_copy_to_uint32_little_endian(
1562
20
   &( input_data[ 8 ] ),
1563
20
   value2 );
1564
1565
20
  byte_stream_copy_to_uint32_little_endian(
1566
20
   &( input_data[ 12 ] ),
1567
20
   value3 );
1568
1569
20
  value0 ^= internal_context->expanded_key[ 0 ];
1570
20
  value1 ^= internal_context->expanded_key[ 1 ];
1571
20
  value2 ^= internal_context->expanded_key[ 2 ];
1572
20
  value3 ^= internal_context->expanded_key[ 3 ];
1573
1574
20
  libfcrypto_serpent_calculate_forward_substitution0(
1575
20
   value0,
1576
20
   value1,
1577
20
   value2,
1578
20
   value3,
1579
20
   value4 );
1580
1581
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution1(
1582
20
   internal_context->expanded_key,
1583
20
   4,
1584
20
   value2,
1585
20
   value1,
1586
20
   value3,
1587
20
   value0,
1588
20
   value4 );
1589
1590
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution2(
1591
20
   internal_context->expanded_key,
1592
20
   8,
1593
20
   value4,
1594
20
   value3,
1595
20
   value0,
1596
20
   value2,
1597
20
   value1 );
1598
1599
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution3(
1600
20
   internal_context->expanded_key,
1601
20
   12,
1602
20
   value1,
1603
20
   value3,
1604
20
   value4,
1605
20
   value2,
1606
20
   value0 );
1607
1608
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution4(
1609
20
   internal_context->expanded_key,
1610
20
   16,
1611
20
   value2,
1612
20
   value0,
1613
20
   value3,
1614
20
   value1,
1615
20
   value4 );
1616
1617
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution5(
1618
20
   internal_context->expanded_key,
1619
20
   20,
1620
20
   value0,
1621
20
   value3,
1622
20
   value1,
1623
20
   value4,
1624
20
   value2 );
1625
1626
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution6(
1627
20
   internal_context->expanded_key,
1628
20
   24,
1629
20
   value2,
1630
20
   value0,
1631
20
   value3,
1632
20
   value4,
1633
20
   value1 );
1634
1635
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution7(
1636
20
   internal_context->expanded_key,
1637
20
   28,
1638
20
   value3,
1639
20
   value1,
1640
20
   value0,
1641
20
   value4,
1642
20
   value2 );
1643
1644
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution0(
1645
20
   internal_context->expanded_key,
1646
20
   32,
1647
20
   value2,
1648
20
   value0,
1649
20
   value4,
1650
20
   value3,
1651
20
   value1 );
1652
1653
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution1(
1654
20
   internal_context->expanded_key,
1655
20
   36,
1656
20
   value4,
1657
20
   value0,
1658
20
   value3,
1659
20
   value2,
1660
20
   value1 );
1661
1662
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution2(
1663
20
   internal_context->expanded_key,
1664
20
   40,
1665
20
   value1,
1666
20
   value3,
1667
20
   value2,
1668
20
   value4,
1669
20
   value0 );
1670
1671
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution3(
1672
20
   internal_context->expanded_key,
1673
20
   44,
1674
20
   value0,
1675
20
   value3,
1676
20
   value1,
1677
20
   value4,
1678
20
   value2 );
1679
1680
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution4(
1681
20
   internal_context->expanded_key,
1682
20
   48,
1683
20
   value4,
1684
20
   value2,
1685
20
   value3,
1686
20
   value0,
1687
20
   value1 );
1688
1689
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution5(
1690
20
   internal_context->expanded_key,
1691
20
   52,
1692
20
   value2,
1693
20
   value3,
1694
20
   value0,
1695
20
   value1,
1696
20
   value4 );
1697
1698
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution6(
1699
20
   internal_context->expanded_key,
1700
20
   56,
1701
20
   value4,
1702
20
   value2,
1703
20
   value3,
1704
20
   value1,
1705
20
   value0 );
1706
1707
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution7(
1708
20
   internal_context->expanded_key,
1709
20
   60,
1710
20
   value3,
1711
20
   value0,
1712
20
   value2,
1713
20
   value1,
1714
20
   value4 );
1715
1716
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution0(
1717
20
   internal_context->expanded_key,
1718
20
   64,
1719
20
   value4,
1720
20
   value2,
1721
20
   value1,
1722
20
   value3,
1723
20
   value0 );
1724
1725
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution1(
1726
20
   internal_context->expanded_key,
1727
20
   68,
1728
20
   value1,
1729
20
   value2,
1730
20
   value3,
1731
20
   value4,
1732
20
   value0 );
1733
1734
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution2(
1735
20
   internal_context->expanded_key,
1736
20
   72,
1737
20
   value0,
1738
20
   value3,
1739
20
   value4,
1740
20
   value1,
1741
20
   value2 );
1742
1743
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution3(
1744
20
   internal_context->expanded_key,
1745
20
   76,
1746
20
   value2,
1747
20
   value3,
1748
20
   value0,
1749
20
   value1,
1750
20
   value4 );
1751
1752
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution4(
1753
20
   internal_context->expanded_key,
1754
20
   80,
1755
20
   value1,
1756
20
   value4,
1757
20
   value3,
1758
20
   value2,
1759
20
   value0 );
1760
1761
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution5(
1762
20
   internal_context->expanded_key,
1763
20
   84,
1764
20
   value4,
1765
20
   value3,
1766
20
   value2,
1767
20
   value0,
1768
20
   value1 );
1769
1770
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution6(
1771
20
   internal_context->expanded_key,
1772
20
   88,
1773
20
   value1,
1774
20
   value4,
1775
20
   value3,
1776
20
   value0,
1777
20
   value2 );
1778
1779
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution7(
1780
20
   internal_context->expanded_key,
1781
20
   92,
1782
20
   value3,
1783
20
   value2,
1784
20
   value4,
1785
20
   value0,
1786
20
   value1 );
1787
1788
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution0(
1789
20
   internal_context->expanded_key,
1790
20
   96,
1791
20
   value1,
1792
20
   value4,
1793
20
   value0,
1794
20
   value3,
1795
20
   value2 );
1796
1797
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution1(
1798
20
   internal_context->expanded_key,
1799
20
   100,
1800
20
   value0,
1801
20
   value4,
1802
20
   value3,
1803
20
   value1,
1804
20
   value2 );
1805
1806
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution2(
1807
20
   internal_context->expanded_key,
1808
20
   104,
1809
20
   value2,
1810
20
   value3,
1811
20
   value1,
1812
20
   value0,
1813
20
   value4 );
1814
1815
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution3(
1816
20
   internal_context->expanded_key,
1817
20
   108,
1818
20
   value4,
1819
20
   value3,
1820
20
   value2,
1821
20
   value0,
1822
20
   value1 );
1823
1824
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution4(
1825
20
   internal_context->expanded_key,
1826
20
   112,
1827
20
   value0,
1828
20
   value1,
1829
20
   value3,
1830
20
   value4,
1831
20
   value2 );
1832
1833
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution5(
1834
20
   internal_context->expanded_key,
1835
20
   116,
1836
20
   value1,
1837
20
   value3,
1838
20
   value4,
1839
20
   value2,
1840
20
   value0 );
1841
1842
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution6(
1843
20
   internal_context->expanded_key,
1844
20
   120,
1845
20
   value0,
1846
20
   value1,
1847
20
   value3,
1848
20
   value2,
1849
20
   value4 );
1850
1851
20
  libfcrypto_serpent_calculate_forward_linear_transformation_and_substitution7(
1852
20
   internal_context->expanded_key,
1853
20
   124,
1854
20
   value3,
1855
20
   value4,
1856
20
   value1,
1857
20
   value2,
1858
20
   value0 );
1859
1860
20
  value0 ^= internal_context->expanded_key[ 128 ];
1861
20
  value1 ^= internal_context->expanded_key[ 129 ];
1862
20
  value2 ^= internal_context->expanded_key[ 130 ];
1863
20
  value3 ^= internal_context->expanded_key[ 131 ];
1864
1865
20
  byte_stream_copy_from_uint32_little_endian(
1866
20
   &( output_data[ 0 ] ),
1867
20
   value0 );
1868
1869
20
  byte_stream_copy_from_uint32_little_endian(
1870
20
   &( output_data[ 4 ] ),
1871
20
   value1 );
1872
1873
20
  byte_stream_copy_from_uint32_little_endian(
1874
20
   &( output_data[ 8 ] ),
1875
20
   value2 );
1876
1877
20
  byte_stream_copy_from_uint32_little_endian(
1878
20
   &( output_data[ 12 ] ),
1879
20
   value3 );
1880
1881
20
  return( 1 );
1882
20
}
1883
1884
/* Decrypts a block of data using Serpent
1885
 * The size must be a multitude of the Serpent block size (16 byte)
1886
 * Returns 1 if successful or -1 on error
1887
 */
1888
int libfcrypto_internal_serpent_context_decrypt_block(
1889
     libfcrypto_internal_serpent_context_t *internal_context,
1890
     const uint8_t *input_data,
1891
     size_t input_data_size,
1892
     uint8_t *output_data,
1893
     size_t output_data_size,
1894
     libcerror_error_t **error  )
1895
0
{
1896
0
  static char *function = "libfcrypto_internal_serpent_context_decrypt_block";
1897
0
  uint32_t value0       = 0;
1898
0
  uint32_t value1       = 0;
1899
0
  uint32_t value2       = 0;
1900
0
  uint32_t value3       = 0;
1901
0
  uint32_t value4       = 0;
1902
1903
0
  if( internal_context == NULL )
1904
0
  {
1905
0
    libcerror_error_set(
1906
0
     error,
1907
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1908
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1909
0
     "%s: invalid context.",
1910
0
     function );
1911
1912
0
    return( -1 );
1913
0
  }
1914
0
  if( input_data == 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 input data.",
1921
0
     function );
1922
1923
0
    return( -1 );
1924
0
  }
1925
0
  if( ( input_data_size < 16 )
1926
0
   || ( input_data_size > (size_t) SSIZE_MAX ) )
1927
0
  {
1928
0
    libcerror_error_set(
1929
0
     error,
1930
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1931
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1932
0
     "%s: invalid input data size value out of bounds.",
1933
0
     function );
1934
1935
0
    return( -1 );
1936
0
  }
1937
0
  if( output_data == NULL )
1938
0
  {
1939
0
    libcerror_error_set(
1940
0
     error,
1941
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1942
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1943
0
     "%s: invalid output data.",
1944
0
     function );
1945
1946
0
    return( -1 );
1947
0
  }
1948
0
  if( ( output_data_size < 16 )
1949
0
   || ( output_data_size > (size_t) SSIZE_MAX ) )
1950
0
  {
1951
0
    libcerror_error_set(
1952
0
     error,
1953
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1954
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1955
0
     "%s: invalid output data size value out of bounds.",
1956
0
     function );
1957
1958
0
    return( -1 );
1959
0
  }
1960
0
  byte_stream_copy_to_uint32_little_endian(
1961
0
   &( input_data[ 0 ] ),
1962
0
   value0 );
1963
1964
0
  byte_stream_copy_to_uint32_little_endian(
1965
0
   &( input_data[ 4 ] ),
1966
0
   value1 );
1967
1968
0
  byte_stream_copy_to_uint32_little_endian(
1969
0
   &( input_data[ 8 ] ),
1970
0
   value2 );
1971
1972
0
  byte_stream_copy_to_uint32_little_endian(
1973
0
   &( input_data[ 12 ] ),
1974
0
   value3 );
1975
1976
0
  value0 ^= internal_context->expanded_key[ 128 ];
1977
0
  value1 ^= internal_context->expanded_key[ 129 ];
1978
0
  value2 ^= internal_context->expanded_key[ 130 ];
1979
0
  value3 ^= internal_context->expanded_key[ 131 ];
1980
1981
0
  libfcrypto_serpent_calculate_reverse_substitution7(
1982
0
   value0,
1983
0
   value1,
1984
0
   value2,
1985
0
   value3,
1986
0
   value4 );
1987
1988
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution6(
1989
0
   internal_context->expanded_key,
1990
0
   4 * 31,
1991
0
   value1,
1992
0
   value3,
1993
0
   value0,
1994
0
   value4,
1995
0
   value2 );
1996
1997
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution5(
1998
0
   internal_context->expanded_key,
1999
0
   4 * 30,
2000
0
   value0,
2001
0
   value2,
2002
0
   value4,
2003
0
   value1,
2004
0
   value3 );
2005
2006
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution4(
2007
0
   internal_context->expanded_key,
2008
0
   4 * 29,
2009
0
   value2,
2010
0
   value3,
2011
0
   value0,
2012
0
   value4,
2013
0
   value1 );
2014
2015
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution3(
2016
0
   internal_context->expanded_key,
2017
0
   4 * 28,
2018
0
   value2,
2019
0
   value0,
2020
0
   value1,
2021
0
   value4,
2022
0
   value3 );
2023
2024
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution2(
2025
0
   internal_context->expanded_key,
2026
0
   4 * 27,
2027
0
   value1,
2028
0
   value2,
2029
0
   value3,
2030
0
   value4,
2031
0
   value0 );
2032
2033
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution1(
2034
0
   internal_context->expanded_key,
2035
0
   4 * 26,
2036
0
   value2,
2037
0
   value0,
2038
0
   value4,
2039
0
   value3,
2040
0
   value1 );
2041
2042
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution0(
2043
0
   internal_context->expanded_key,
2044
0
   4 * 25,
2045
0
   value1,
2046
0
   value0,
2047
0
   value4,
2048
0
   value3,
2049
0
   value2 );
2050
2051
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution7(
2052
0
   internal_context->expanded_key,
2053
0
   4 * 24,
2054
0
   value4,
2055
0
   value2,
2056
0
   value0,
2057
0
   value1,
2058
0
   value3 );
2059
2060
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution6(
2061
0
   internal_context->expanded_key,
2062
0
   4 * 23,
2063
0
   value2,
2064
0
   value1,
2065
0
   value4,
2066
0
   value3,
2067
0
   value0 );
2068
2069
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution5(
2070
0
   internal_context->expanded_key,
2071
0
   4 * 22,
2072
0
   value4,
2073
0
   value0,
2074
0
   value3,
2075
0
   value2,
2076
0
   value1 );
2077
2078
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution4(
2079
0
   internal_context->expanded_key,
2080
0
   4 * 21,
2081
0
   value0,
2082
0
   value1,
2083
0
   value4,
2084
0
   value3,
2085
0
   value2 );
2086
2087
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution3(
2088
0
   internal_context->expanded_key,
2089
0
   4 * 20,
2090
0
   value0,
2091
0
   value4,
2092
0
   value2,
2093
0
   value3,
2094
0
   value1 );
2095
2096
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution2(
2097
0
   internal_context->expanded_key,
2098
0
   4 * 19,
2099
0
   value2,
2100
0
   value0,
2101
0
   value1,
2102
0
   value3,
2103
0
   value4 );
2104
2105
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution1(
2106
0
   internal_context->expanded_key,
2107
0
   4 * 18,
2108
0
   value0,
2109
0
   value4,
2110
0
   value3,
2111
0
   value1,
2112
0
   value2 );
2113
2114
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution0(
2115
0
   internal_context->expanded_key,
2116
0
   4 * 17,
2117
0
   value2,
2118
0
   value4,
2119
0
   value3,
2120
0
   value1,
2121
0
   value0 );
2122
2123
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution7(
2124
0
   internal_context->expanded_key,
2125
0
   4 * 16,
2126
0
   value3,
2127
0
   value0,
2128
0
   value4,
2129
0
   value2,
2130
0
   value1 );
2131
2132
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution6(
2133
0
   internal_context->expanded_key,
2134
0
   4 * 15,
2135
0
   value0,
2136
0
   value2,
2137
0
   value3,
2138
0
   value1,
2139
0
   value4 );
2140
2141
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution5(
2142
0
   internal_context->expanded_key,
2143
0
   4 * 14,
2144
0
   value3,
2145
0
   value4,
2146
0
   value1,
2147
0
   value0,
2148
0
   value2 );
2149
2150
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution4(
2151
0
   internal_context->expanded_key,
2152
0
   4 * 13,
2153
0
   value4,
2154
0
   value2,
2155
0
   value3,
2156
0
   value1,
2157
0
   value0 );
2158
2159
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution3(
2160
0
   internal_context->expanded_key,
2161
0
   4 * 12,
2162
0
   value4,
2163
0
   value3,
2164
0
   value0,
2165
0
   value1,
2166
0
   value2 );
2167
2168
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution2(
2169
0
   internal_context->expanded_key,
2170
0
   4 * 11,
2171
0
   value0,
2172
0
   value4,
2173
0
   value2,
2174
0
   value1,
2175
0
   value3 );
2176
2177
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution1(
2178
0
   internal_context->expanded_key,
2179
0
   4 * 10,
2180
0
   value4,
2181
0
   value3,
2182
0
   value1,
2183
0
   value2,
2184
0
   value0 );
2185
2186
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution0(
2187
0
   internal_context->expanded_key,
2188
0
   4 * 9,
2189
0
   value0,
2190
0
   value3,
2191
0
   value1,
2192
0
   value2,
2193
0
   value4 );
2194
2195
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution7(
2196
0
   internal_context->expanded_key,
2197
0
   4 * 8,
2198
0
   value1,
2199
0
   value4,
2200
0
   value3,
2201
0
   value0,
2202
0
   value2 );
2203
2204
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution6(
2205
0
   internal_context->expanded_key,
2206
0
   4 * 7,
2207
0
   value4,
2208
0
   value0,
2209
0
   value1,
2210
0
   value2,
2211
0
   value3 );
2212
2213
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution5(
2214
0
   internal_context->expanded_key,
2215
0
   4 * 6,
2216
0
   value1,
2217
0
   value3,
2218
0
   value2,
2219
0
   value4,
2220
0
   value0 );
2221
2222
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution4(
2223
0
   internal_context->expanded_key,
2224
0
   4 * 5,
2225
0
   value3,
2226
0
   value0,
2227
0
   value1,
2228
0
   value2,
2229
0
   value4 );
2230
2231
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution3(
2232
0
   internal_context->expanded_key,
2233
0
   4 * 4,
2234
0
   value3,
2235
0
   value1,
2236
0
   value4,
2237
0
   value2,
2238
0
   value0 );
2239
2240
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution2(
2241
0
   internal_context->expanded_key,
2242
0
   4 * 3,
2243
0
   value4,
2244
0
   value3,
2245
0
   value0,
2246
0
   value2,
2247
0
   value1 );
2248
2249
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution1(
2250
0
   internal_context->expanded_key,
2251
0
   4 * 2,
2252
0
   value3,
2253
0
   value1,
2254
0
   value2,
2255
0
   value0,
2256
0
   value4 );
2257
2258
0
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution0(
2259
0
   internal_context->expanded_key,
2260
0
   4 * 1,
2261
0
   value4,
2262
0
   value1,
2263
0
   value2,
2264
0
   value0,
2265
0
   value3 );
2266
2267
0
  value2 ^= internal_context->expanded_key[ 0 ];
2268
0
  value3 ^= internal_context->expanded_key[ 1 ];
2269
0
  value1 ^= internal_context->expanded_key[ 2 ];
2270
0
  value4 ^= internal_context->expanded_key[ 3 ];
2271
2272
0
  byte_stream_copy_from_uint32_little_endian(
2273
0
   &( output_data[ 0 ] ),
2274
0
   value2 );
2275
2276
0
  byte_stream_copy_from_uint32_little_endian(
2277
0
   &( output_data[ 4 ] ),
2278
0
   value3 );
2279
2280
0
  byte_stream_copy_from_uint32_little_endian(
2281
0
   &( output_data[ 8 ] ),
2282
0
   value1 );
2283
2284
0
  byte_stream_copy_from_uint32_little_endian(
2285
0
   &( output_data[ 12 ] ),
2286
0
   value4 );
2287
2288
0
  return( 1 );
2289
0
}
2290
2291
/* De- or encrypts a block of data using Serpent-CBC (Cipher Block Chaining)
2292
 * The size must be a multitude of the Serpent block size (16 byte)
2293
 * Returns 1 if successful or -1 on error
2294
 */
2295
int libfcrypto_serpent_crypt_cbc(
2296
     libfcrypto_serpent_context_t *context,
2297
     int mode,
2298
     const uint8_t *initialization_vector,
2299
     size_t initialization_vector_size,
2300
     const uint8_t *input_data,
2301
     size_t input_data_size,
2302
     uint8_t *output_data,
2303
     size_t output_data_size,
2304
     libcerror_error_t **error )
2305
54
{
2306
54
  uint8_t block_data[ 16 ];
2307
54
  uint8_t internal_initialization_vector[ 16 ];
2308
2309
54
  static char *function = "libfcrypto_serpent_context_crypt_cbc";
2310
54
  size_t data_offset    = 0;
2311
2312
54
#if !defined( LIBFCRYPTO_UNFOLLED_LOOPS )
2313
54
  uint8_t block_index   = 0;
2314
54
#endif
2315
2316
54
  if( context == NULL )
2317
0
  {
2318
0
    libcerror_error_set(
2319
0
     error,
2320
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2321
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2322
0
     "%s: invalid context.",
2323
0
     function );
2324
2325
0
    return( -1 );
2326
0
  }
2327
54
  if( initialization_vector == NULL )
2328
0
  {
2329
0
    libcerror_error_set(
2330
0
     error,
2331
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2332
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2333
0
     "%s: invalid initialization vector.",
2334
0
     function );
2335
2336
0
    return( -1 );
2337
0
  }
2338
54
  if( initialization_vector_size != 16 )
2339
0
  {
2340
0
    libcerror_error_set(
2341
0
     error,
2342
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2343
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2344
0
     "%s: invalid initialization vector size value out of bounds.",
2345
0
     function );
2346
2347
0
    return( -1 );
2348
0
  }
2349
54
  if( ( mode != LIBFCRYPTO_SERPENT_CRYPT_MODE_ENCRYPT )
2350
54
   && ( mode != LIBFCRYPTO_SERPENT_CRYPT_MODE_DECRYPT ) )
2351
0
  {
2352
0
    libcerror_error_set(
2353
0
     error,
2354
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2355
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2356
0
     "%s: unsupported mode.",
2357
0
     function );
2358
2359
0
    return( -1 );
2360
0
  }
2361
54
  if( input_data == NULL )
2362
0
  {
2363
0
    libcerror_error_set(
2364
0
     error,
2365
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2366
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2367
0
     "%s: invalid input data.",
2368
0
     function );
2369
2370
0
    return( -1 );
2371
0
  }
2372
  /* Check if the input data size is a multitude of 16-byte
2373
   */
2374
54
  if( ( ( input_data_size & (size_t) 0x0f ) != 0 )
2375
54
   || ( input_data_size < 16 )
2376
54
   || ( input_data_size > (size_t) SSIZE_MAX ) )
2377
4
  {
2378
4
    libcerror_error_set(
2379
4
     error,
2380
4
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2381
4
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2382
4
     "%s: invalid input data size value out of bounds.",
2383
4
     function );
2384
2385
4
    return( -1 );
2386
4
  }
2387
50
  if( output_data == NULL )
2388
0
  {
2389
0
    libcerror_error_set(
2390
0
     error,
2391
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2392
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2393
0
     "%s: invalid output data.",
2394
0
     function );
2395
2396
0
    return( -1 );
2397
0
  }
2398
50
  if( ( output_data_size < input_data_size )
2399
50
   || ( output_data_size > (size_t) SSIZE_MAX ) )
2400
46
  {
2401
46
    libcerror_error_set(
2402
46
     error,
2403
46
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2404
46
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2405
46
     "%s: invalid output data size value out of bounds.",
2406
46
     function );
2407
2408
46
    return( -1 );
2409
46
  }
2410
4
  if( memory_copy(
2411
4
       internal_initialization_vector,
2412
4
       initialization_vector,
2413
4
       16 ) == NULL )
2414
0
  {
2415
0
    libcerror_error_set(
2416
0
     error,
2417
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2418
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2419
0
     "%s: unable to copy initialization vector.",
2420
0
     function );
2421
2422
0
    goto on_error;
2423
0
  }
2424
14
  while( data_offset < input_data_size )
2425
10
  {
2426
10
    if( mode == LIBFCRYPTO_SERPENT_CRYPT_MODE_ENCRYPT )
2427
10
    {
2428
#if defined( LIBFCRYPTO_UNFOLLED_LOOPS )
2429
      block_data[ 0 ]  = input_data[ data_offset++ ] ^ internal_initialization_vector[ 0 ];
2430
      block_data[ 1 ]  = input_data[ data_offset++ ] ^ internal_initialization_vector[ 1 ];
2431
      block_data[ 2 ]  = input_data[ data_offset++ ] ^ internal_initialization_vector[ 2 ];
2432
      block_data[ 3 ]  = input_data[ data_offset++ ] ^ internal_initialization_vector[ 3 ];
2433
      block_data[ 4 ]  = input_data[ data_offset++ ] ^ internal_initialization_vector[ 4 ];
2434
      block_data[ 5 ]  = input_data[ data_offset++ ] ^ internal_initialization_vector[ 5 ];
2435
      block_data[ 6 ]  = input_data[ data_offset++ ] ^ internal_initialization_vector[ 6 ];
2436
      block_data[ 7 ]  = input_data[ data_offset++ ] ^ internal_initialization_vector[ 7 ];
2437
      block_data[ 8 ]  = input_data[ data_offset++ ] ^ internal_initialization_vector[ 8 ];
2438
      block_data[ 9 ]  = input_data[ data_offset++ ] ^ internal_initialization_vector[ 9 ];
2439
      block_data[ 10 ] = input_data[ data_offset++ ] ^ internal_initialization_vector[ 10 ];
2440
      block_data[ 11 ] = input_data[ data_offset++ ] ^ internal_initialization_vector[ 11 ];
2441
      block_data[ 12 ] = input_data[ data_offset++ ] ^ internal_initialization_vector[ 12 ];
2442
      block_data[ 13 ] = input_data[ data_offset++ ] ^ internal_initialization_vector[ 13 ];
2443
      block_data[ 14 ] = input_data[ data_offset++ ] ^ internal_initialization_vector[ 14 ];
2444
      block_data[ 15 ] = input_data[ data_offset++ ] ^ internal_initialization_vector[ 15 ];
2445
#else
2446
10
      for( block_index = 0;
2447
170
           block_index < 16;
2448
160
           block_index++ )
2449
160
      {
2450
160
        block_data[ block_index ] = input_data[ data_offset++ ] ^ internal_initialization_vector[ block_index ];
2451
160
      }
2452
10
#endif
2453
10
      data_offset -= 16;
2454
2455
10
      if( libfcrypto_internal_serpent_context_encrypt_block(
2456
10
           (libfcrypto_internal_serpent_context_t *) context,
2457
10
           block_data,
2458
10
           16,
2459
10
           &( output_data[ data_offset ] ),
2460
10
           16,
2461
10
           error ) != 1 )
2462
0
      {
2463
0
        libcerror_error_set(
2464
0
         error,
2465
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2466
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
2467
0
         "%s: unable to encrypt input data.",
2468
0
         function );
2469
2470
0
        goto on_error;
2471
0
      }
2472
10
      if( memory_copy(
2473
10
           internal_initialization_vector,
2474
10
           &( output_data[ data_offset ] ),
2475
10
           16 ) == NULL )
2476
0
      {
2477
0
        libcerror_error_set(
2478
0
         error,
2479
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
2480
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2481
0
         "%s: unable to copy encrypted output data to initialization vector.",
2482
0
         function );
2483
2484
0
        goto on_error;
2485
0
      }
2486
10
    }
2487
0
    else
2488
0
    {
2489
0
      if( libfcrypto_internal_serpent_context_decrypt_block(
2490
0
           (libfcrypto_internal_serpent_context_t *) context,
2491
0
           &( input_data[ data_offset ] ),
2492
0
           16,
2493
0
           &( output_data[ data_offset ] ),
2494
0
           16,
2495
0
           error ) != 1 )
2496
0
      {
2497
0
        libcerror_error_set(
2498
0
         error,
2499
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2500
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
2501
0
         "%s: unable to decrypt input data.",
2502
0
         function );
2503
2504
0
        goto on_error;
2505
0
      }
2506
#if defined( LIBFCRYPTO_UNFOLLED_LOOPS )
2507
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 0 ];
2508
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 1 ];
2509
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 2 ];
2510
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 3 ];
2511
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 4 ];
2512
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 5 ];
2513
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 6 ];
2514
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 7 ];
2515
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 8 ];
2516
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 9 ];
2517
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 10 ];
2518
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 11 ];
2519
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 12 ];
2520
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 13 ];
2521
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 14 ];
2522
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 15 ];
2523
#else
2524
0
      for( block_index = 0;
2525
0
           block_index < 16;
2526
0
           block_index++ )
2527
0
      {
2528
0
        output_data[ data_offset++ ] ^= internal_initialization_vector[ block_index ];
2529
0
      }
2530
0
#endif
2531
0
      data_offset -= 16;
2532
2533
0
      if( memory_copy(
2534
0
           internal_initialization_vector,
2535
0
           &( input_data[ data_offset ] ),
2536
0
           16 ) == NULL )
2537
0
      {
2538
0
        libcerror_error_set(
2539
0
         error,
2540
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
2541
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2542
0
         "%s: unable to copy encrypted input data to initialization vector.",
2543
0
         function );
2544
2545
0
        goto on_error;
2546
0
      }
2547
0
    }
2548
10
    data_offset += 16;
2549
10
  }
2550
4
  if( memory_set(
2551
4
       internal_initialization_vector,
2552
4
       0,
2553
4
       16 ) == NULL )
2554
0
  {
2555
0
    libcerror_error_set(
2556
0
     error,
2557
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2558
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
2559
0
     "%s: unable to clear initialization vector.",
2560
0
     function );
2561
2562
0
    goto on_error;
2563
0
  }
2564
4
  if( memory_set(
2565
4
       block_data,
2566
4
       0,
2567
4
       16 ) == NULL )
2568
0
  {
2569
0
    libcerror_error_set(
2570
0
     error,
2571
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2572
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
2573
0
     "%s: unable to clear block data.",
2574
0
     function );
2575
2576
0
    goto on_error;
2577
0
  }
2578
4
  return( 1 );
2579
2580
0
on_error:
2581
0
  memory_set(
2582
0
   internal_initialization_vector,
2583
0
   0,
2584
0
   16 );
2585
2586
0
  memory_set(
2587
0
   block_data,
2588
0
   0,
2589
0
   16 );
2590
2591
0
  return( -1 );
2592
4
}
2593
2594
/* De- or encrypts a block of data using Serpent-ECB (Electronic CodeBook)
2595
 * The size must be a multitude of the Serpent block size (16 byte)
2596
 * Returns 1 if successful or -1 on error
2597
 */
2598
int libfcrypto_serpent_crypt_ecb(
2599
     libfcrypto_serpent_context_t *context,
2600
     int mode,
2601
     const uint8_t *input_data,
2602
     size_t input_data_size,
2603
     uint8_t *output_data,
2604
     size_t output_data_size,
2605
     libcerror_error_t **error )
2606
55
{
2607
55
  static char *function = "libfcrypto_serpent_context_crypt_ecb";
2608
55
  size_t data_offset    = 0;
2609
2610
55
  if( context == NULL )
2611
0
  {
2612
0
    libcerror_error_set(
2613
0
     error,
2614
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2615
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2616
0
     "%s: invalid context.",
2617
0
     function );
2618
2619
0
    return( -1 );
2620
0
  }
2621
55
  if( ( mode != LIBFCRYPTO_SERPENT_CRYPT_MODE_ENCRYPT )
2622
55
   && ( mode != LIBFCRYPTO_SERPENT_CRYPT_MODE_DECRYPT ) )
2623
0
  {
2624
0
    libcerror_error_set(
2625
0
     error,
2626
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2627
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2628
0
     "%s: unsupported mode.",
2629
0
     function );
2630
2631
0
    return( -1 );
2632
0
  }
2633
55
  if( input_data == NULL )
2634
0
  {
2635
0
    libcerror_error_set(
2636
0
     error,
2637
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2638
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2639
0
     "%s: invalid input data.",
2640
0
     function );
2641
2642
0
    return( -1 );
2643
0
  }
2644
  /* Check if the input data size is a multitude of 16-byte
2645
   */
2646
55
  if( ( ( input_data_size & (size_t) 0x0f ) != 0 )
2647
55
   || ( input_data_size < 16 )
2648
55
   || ( input_data_size > (size_t) SSIZE_MAX ) )
2649
4
  {
2650
4
    libcerror_error_set(
2651
4
     error,
2652
4
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2653
4
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2654
4
     "%s: invalid input data size value out of bounds.",
2655
4
     function );
2656
2657
4
    return( -1 );
2658
4
  }
2659
51
  if( output_data == NULL )
2660
0
  {
2661
0
    libcerror_error_set(
2662
0
     error,
2663
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2664
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2665
0
     "%s: invalid output data.",
2666
0
     function );
2667
2668
0
    return( -1 );
2669
0
  }
2670
51
  if( ( output_data_size < input_data_size )
2671
51
   || ( output_data_size > (size_t) SSIZE_MAX ) )
2672
47
  {
2673
47
    libcerror_error_set(
2674
47
     error,
2675
47
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2676
47
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2677
47
     "%s: invalid output data size value out of bounds.",
2678
47
     function );
2679
2680
47
    return( -1 );
2681
47
  }
2682
14
  while( data_offset < input_data_size )
2683
10
  {
2684
10
    if( mode == LIBFCRYPTO_SERPENT_CRYPT_MODE_ENCRYPT )
2685
10
    {
2686
10
      if( libfcrypto_internal_serpent_context_encrypt_block(
2687
10
           (libfcrypto_internal_serpent_context_t *) context,
2688
10
           &( input_data[ data_offset ] ),
2689
10
           16,
2690
10
           &( output_data[ data_offset ] ),
2691
10
           16,
2692
10
           error ) != 1 )
2693
0
      {
2694
0
        libcerror_error_set(
2695
0
         error,
2696
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2697
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
2698
0
         "%s: unable to encrypt input data.",
2699
0
         function );
2700
2701
0
        return( -1 );
2702
0
      }
2703
10
    }
2704
0
    else
2705
0
    {
2706
0
      if( libfcrypto_internal_serpent_context_decrypt_block(
2707
0
           (libfcrypto_internal_serpent_context_t *) context,
2708
0
           &( input_data[ data_offset ] ),
2709
0
           16,
2710
0
           &( output_data[ data_offset ] ),
2711
0
           16,
2712
0
           error ) != 1 )
2713
0
      {
2714
0
        libcerror_error_set(
2715
0
         error,
2716
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2717
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
2718
0
         "%s: unable to decrypt input data.",
2719
0
         function );
2720
2721
0
        return( -1 );
2722
0
      }
2723
0
    }
2724
10
    data_offset += 16;
2725
10
  }
2726
4
  return( 1 );
2727
4
}
2728