Coverage Report

Created: 2026-08-31 07:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libluksde/libfcrypto/libfcrypto_serpent_context.c
Line
Count
Source
1
/*
2
 * Serpent (de/en)crypt functions
3
 *
4
 * Copyright (C) 2017-2026, 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
40.6k
  value0 ^= expanded_key_values[ expanded_key_index ]; \
59
40.6k
  value1 ^= expanded_key_values[ expanded_key_index + 1 ]; \
60
40.6k
  value2 ^= expanded_key_values[ expanded_key_index + 2 ]; \
61
40.6k
  \
62
40.6k
  value3 ^= expanded_key_values[ expanded_key_index + 3 ];   \
63
40.6k
  value0 = byte_stream_bit_rotate_right_32bit( value0, 5 ); \
64
40.6k
  value2 = byte_stream_bit_rotate_right_32bit( value2, 22 ); \
65
40.6k
  \
66
40.6k
  value4 =  value1; \
67
40.6k
  value2 ^= value3; \
68
40.6k
  value0 ^= value3; \
69
40.6k
  \
70
40.6k
  value4 <<= 7; \
71
40.6k
  value0 ^= value1; \
72
40.6k
  value1 = byte_stream_bit_rotate_right_32bit( value1, 1 );  \
73
40.6k
  value2 ^= value4; \
74
40.6k
  value3 = byte_stream_bit_rotate_right_32bit( value3, 7 ); \
75
40.6k
  value4 = value0 << 3; \
76
40.6k
  \
77
40.6k
  value1 ^= value0; \
78
40.6k
  value3 ^= value4; \
79
40.6k
  value0 = byte_stream_bit_rotate_right_32bit( value0, 13 ); \
80
40.6k
  value1 ^= value2; \
81
40.6k
  value3 ^= value2; \
82
40.6k
  value2 = byte_stream_bit_rotate_right_32bit( value2, 3 );
83
84
#define libfcrypto_serpent_calculate_forward_substitution0( value0, value1, value2, value3, value4 ) \
85
572
  value4  = value3; \
86
572
  value3 |= value0; \
87
572
  value0 ^= value4; \
88
572
  value4 ^= value2; \
89
572
  value4  = ~value4; \
90
572
  value3 ^= value1; \
91
572
  value1 &= value0; \
92
572
  value1 ^= value4; \
93
572
  value2 ^= value0; \
94
572
  value0 ^= value3; \
95
572
  value4 |= value0; \
96
572
  value0 ^= value2; \
97
572
  value2 &= value1; \
98
572
  value3 ^= value2; \
99
572
  value1  = ~value1; \
100
572
  value2 ^= value4; \
101
572
  value1 ^= value2;
102
103
#define libfcrypto_serpent_calculate_forward_substitution1( value0, value1, value2, value3, value4 ) \
104
572
  value4  = value1; \
105
572
  value1 ^= value0; \
106
572
  value0 ^= value3; \
107
572
  value3  = ~value3; \
108
572
  value4 &= value1; \
109
572
  value0 |= value1; \
110
572
  value3 ^= value2; \
111
572
  value0 ^= value3; \
112
572
  value1 ^= value3; \
113
572
  value3 ^= value4; \
114
572
  value1 |= value4; \
115
572
  value4 ^= value2; \
116
572
  value2 &= value0; \
117
572
  value2 ^= value1; \
118
572
  value1 |= value0; \
119
572
  value0  = ~value0; \
120
572
  value0 ^= value2; \
121
572
  value4 ^= value1;
122
123
#define libfcrypto_serpent_calculate_forward_substitution2( value0, value1, value2, value3, value4 ) \
124
572
  value3  = ~value3; \
125
572
  value1 ^= value0; \
126
572
  value4  = value0; \
127
572
  value0 &= value2; \
128
572
  value0 ^= value3; \
129
572
  value3 |= value4; \
130
572
  value2 ^= value1; \
131
572
  value3 ^= value1; \
132
572
  value1 &= value0; \
133
572
  value0 ^= value2; \
134
572
  value2 &= value3; \
135
572
  value3 |= value1; \
136
572
  value0  = ~value0; \
137
572
  value3 ^= value0; \
138
572
  value4 ^= value0; \
139
572
  value0 ^= value2; \
140
572
  value1 |= value2;
141
142
#define libfcrypto_serpent_calculate_forward_substitution3( value0, value1, value2, value3, value4 ) \
143
695
  value4  = value1; \
144
695
  value1 ^= value3; \
145
695
  value3 |= value0; \
146
695
  value4 &= value0; \
147
695
  value0 ^= value2; \
148
695
  value2 ^= value1; \
149
695
  value1 &= value3; \
150
695
  value2 ^= value3; \
151
695
  value0 |= value4; \
152
695
  value4 ^= value3; \
153
695
  value1 ^= value0; \
154
695
  value0 &= value3; \
155
695
  value3 &= value4; \
156
695
  value3 ^= value2; \
157
695
  value4 |= value1; \
158
695
  value2 &= value1; \
159
695
  value4 ^= value3; \
160
695
  value0 ^= value3; \
161
695
  value3 ^= value2;
162
163
#define libfcrypto_serpent_calculate_forward_substitution4( value0, value1, value2, value3, value4 ) \
164
572
  value4  = value3; \
165
572
  value3 &= value0; \
166
572
  value0 ^= value4; \
167
572
  value3 ^= value2; \
168
572
  value2 |= value4; \
169
572
  value0 ^= value1; \
170
572
  value4 ^= value3; \
171
572
  value2 |= value0; \
172
572
  value2 ^= value1; \
173
572
  value1 &= value0; \
174
572
  value1 ^= value4; \
175
572
  value4 &= value2; \
176
572
  value2 ^= value3; \
177
572
  value4 ^= value0; \
178
572
  value3 |= value1; \
179
572
  value1  = ~value1; \
180
572
  value3 ^= value0;
181
182
#define libfcrypto_serpent_calculate_forward_substitution5( value0, value1, value2, value3, value4 ) \
183
572
  value4  = value1; \
184
572
  value1 |= value0; \
185
572
  value2 ^= value1; \
186
572
  value3  = ~value3; \
187
572
  value4 ^= value0; \
188
572
  value0 ^= value2; \
189
572
  value1 &= value4; \
190
572
  value4 |= value3; \
191
572
  value4 ^= value0; \
192
572
  value0 &= value3; \
193
572
  value1 ^= value3; \
194
572
  value3 ^= value2; \
195
572
  value0 ^= value1; \
196
572
  value2 &= value4; \
197
572
  value1 ^= value2; \
198
572
  value2 &= value0; \
199
572
  value3 ^= value2;
200
201
#define libfcrypto_serpent_calculate_forward_substitution6( value0, value1, value2, value3, value4 ) \
202
572
  value4  = value1; \
203
572
  value3 ^= value0; \
204
572
  value1 ^= value2; \
205
572
  value2 ^= value0; \
206
572
  value0 &= value3; \
207
572
  value1 |= value3; \
208
572
  value4  = ~value4; \
209
572
  value0 ^= value1; \
210
572
  value1 ^= value2; \
211
572
  value3 ^= value4; \
212
572
  value4 ^= value0; \
213
572
  value2 &= value0; \
214
572
  value4 ^= value1; \
215
572
  value2 ^= value3; \
216
572
  value3 &= value1; \
217
572
  value3 ^= value0; \
218
572
  value1 ^= value2;
219
220
#define libfcrypto_serpent_calculate_forward_substitution7( value0, value1, value2, value3, value4 ) \
221
572
  value1  = ~value1; \
222
572
  value4  = value1; \
223
572
  value0  = ~value0; \
224
572
  value1 &= value2; \
225
572
  value1 ^= value3; \
226
572
  value3 |= value4; \
227
572
  value4 ^= value2; \
228
572
  value2 ^= value3; \
229
572
  value3 ^= value0; \
230
572
  value0 |= value1; \
231
572
  value2 &= value0; \
232
572
  value0 ^= value4; \
233
572
  value4 ^= value3; \
234
572
  value3 &= value0; \
235
572
  value4 ^= value1; \
236
572
  value2 ^= value4; \
237
572
  value3 ^= value1; \
238
572
  value4 |= value0; \
239
572
  value4 ^= value1;
240
241
#define libfcrypto_serpent_calculate_reverse_substitution0( value0, value1, value2, value3, value4 ) \
242
5.24k
  value4  = value3; \
243
5.24k
  value1 ^= value0; \
244
5.24k
  value3 |= value1; \
245
5.24k
  value4 ^= value1; \
246
5.24k
  value0  = ~value0; \
247
5.24k
  value2 ^= value3; \
248
5.24k
  value3 ^= value0; \
249
5.24k
  value0 &= value1; \
250
5.24k
  value0 ^= value2; \
251
5.24k
  value2 &= value3; \
252
5.24k
  value3 ^= value4; \
253
5.24k
  value2 ^= value3; \
254
5.24k
  value1 ^= value3; \
255
5.24k
  value3 &= value0; \
256
5.24k
  value1 ^= value0; \
257
5.24k
  value0 ^= value2; \
258
5.24k
  value4 ^= value3;
259
260
#define libfcrypto_serpent_calculate_reverse_substitution1( value0, value1, value2, value3, value4 ) \
261
5.24k
  value1 ^= value3; \
262
5.24k
  value4  = value0; \
263
5.24k
  value0 ^= value2; \
264
5.24k
  value2  = ~value2; \
265
5.24k
  value4 |= value1; \
266
5.24k
  value4 ^= value3; \
267
5.24k
  value3 &= value1; \
268
5.24k
  value1 ^= value2; \
269
5.24k
  value2 &= value4; \
270
5.24k
  value4 ^= value1; \
271
5.24k
  value1 |= value3; \
272
5.24k
  value3 ^= value0; \
273
5.24k
  value2 ^= value0; \
274
5.24k
  value0 |= value4; \
275
5.24k
  value2 ^= value4; \
276
5.24k
  value1 ^= value0; \
277
5.24k
  value4 ^= value1;
278
279
#define libfcrypto_serpent_calculate_reverse_substitution2( value0, value1, value2, value3, value4 ) \
280
5.24k
  value2 ^= value1; \
281
5.24k
  value4  = value3; \
282
5.24k
  value3  = ~value3; \
283
5.24k
  value3 |= value2; \
284
5.24k
  value2 ^= value4; \
285
5.24k
  value4 ^= value0; \
286
5.24k
  value3 ^= value1; \
287
5.24k
  value1 |= value2; \
288
5.24k
  value2 ^= value0; \
289
5.24k
  value1 ^= value4; \
290
5.24k
  value4 |= value3; \
291
5.24k
  value2 ^= value3; \
292
5.24k
  value4 ^= value2; \
293
5.24k
  value2 &= value1; \
294
5.24k
  value2 ^= value3; \
295
5.24k
  value3 ^= value4; \
296
5.24k
  value4 ^= value0;
297
298
#define libfcrypto_serpent_calculate_reverse_substitution3( value0, value1, value2, value3, value4 ) \
299
5.24k
  value2 ^= value1; \
300
5.24k
  value4  = value1; \
301
5.24k
  value1 &= value2; \
302
5.24k
  value1 ^= value0; \
303
5.24k
  value0 |= value4; \
304
5.24k
  value4 ^= value3; \
305
5.24k
  value0 ^= value3; \
306
5.24k
  value3 |= value1; \
307
5.24k
  value1 ^= value2; \
308
5.24k
  value1 ^= value3; \
309
5.24k
  value0 ^= value2; \
310
5.24k
  value2 ^= value3; \
311
5.24k
  value3 &= value1; \
312
5.24k
  value1 ^= value0; \
313
5.24k
  value0 &= value2; \
314
5.24k
  value4 ^= value3; \
315
5.24k
  value3 ^= value0; \
316
5.24k
  value0 ^= value1;
317
318
#define libfcrypto_serpent_calculate_reverse_substitution4( value0, value1, value2, value3, value4 ) \
319
5.24k
  value2 ^= value3; \
320
5.24k
  value4  = value0; \
321
5.24k
  value0 &= value1; \
322
5.24k
  value0 ^= value2; \
323
5.24k
  value2 |= value3; \
324
5.24k
  value4  = ~value4; \
325
5.24k
  value1 ^= value0; \
326
5.24k
  value0 ^= value2; \
327
5.24k
  value2 &= value4; \
328
5.24k
  value2 ^= value0; \
329
5.24k
  value0 |= value4; \
330
5.24k
  value0 ^= value3; \
331
5.24k
  value3 &= value2; \
332
5.24k
  value4 ^= value3; \
333
5.24k
  value3 ^= value1; \
334
5.24k
  value1 &= value0; \
335
5.24k
  value4 ^= value1; \
336
5.24k
  value0 ^= value3;
337
338
#define libfcrypto_serpent_calculate_reverse_substitution5( value0, value1, value2, value3, value4 ) \
339
5.24k
  value4  = value1; \
340
5.24k
  value1 |= value2; \
341
5.24k
  value2 ^= value4; \
342
5.24k
  value1 ^= value3; \
343
5.24k
  value3 &= value4; \
344
5.24k
  value2 ^= value3; \
345
5.24k
  value3 |= value0; \
346
5.24k
  value0  = ~value0; \
347
5.24k
  value3 ^= value2; \
348
5.24k
  value2 |= value0; \
349
5.24k
  value4 ^= value1; \
350
5.24k
  value2 ^= value4; \
351
5.24k
  value4 &= value0; \
352
5.24k
  value0 ^= value1; \
353
5.24k
  value1 ^= value3; \
354
5.24k
  value0 &= value2; \
355
5.24k
  value2 ^= value3; \
356
5.24k
  value0 ^= value2; \
357
5.24k
  value2 ^= value4; \
358
5.24k
  value4 ^= value3;
359
360
#define libfcrypto_serpent_calculate_reverse_substitution6( value0, value1, value2, value3, value4 ) \
361
5.24k
  value0 ^= value2; \
362
5.24k
  value4  = value0; \
363
5.24k
  value0 &= value3; \
364
5.24k
  value2 ^= value3; \
365
5.24k
  value0 ^= value2; \
366
5.24k
  value3 ^= value1; \
367
5.24k
  value2 |= value4; \
368
5.24k
  value2 ^= value3; \
369
5.24k
  value3 &= value0; \
370
5.24k
  value0  = ~value0; \
371
5.24k
  value3 ^= value1; \
372
5.24k
  value1 &= value2; \
373
5.24k
  value4 ^= value0; \
374
5.24k
  value3 ^= value4; \
375
5.24k
  value4 ^= value2; \
376
5.24k
  value0 ^= value1; \
377
5.24k
  value2 ^= value0;
378
379
#define libfcrypto_serpent_calculate_reverse_substitution7( value0, value1, value2, value3, value4 ) \
380
5.24k
  value4  = value3; \
381
5.24k
  value3 &= value0; \
382
5.24k
  value0 ^= value2; \
383
5.24k
  value2 |= value4; \
384
5.24k
  value4 ^= value1; \
385
5.24k
  value0  = ~value0; \
386
5.24k
  value1 |= value3; \
387
5.24k
  value4 ^= value0; \
388
5.24k
  value0 &= value2; \
389
5.24k
  value0 ^= value1; \
390
5.24k
  value1 &= value2; \
391
5.24k
  value3 ^= value2; \
392
5.24k
  value4 ^= value3; \
393
5.24k
  value2 &= value3; \
394
5.24k
  value3 |= value0; \
395
5.24k
  value1 ^= value4; \
396
5.24k
  value3 ^= value4; \
397
5.24k
  value4 &= value0; \
398
5.24k
  value4 ^= value2;
399
400
16.2k
#define GOLDEN_RATIO_FRACTION 0x9e3779b9UL
401
402
#define libfcrypto_serpent_calculate_expanded_key( expanded_key_values, expanded_key_index, value0, value1, value2, value3 ) \
403
16.2k
  value1 ^= value3; \
404
16.2k
  value1 ^= value2; \
405
16.2k
  value1 ^= value0; \
406
16.2k
  value1 ^= GOLDEN_RATIO_FRACTION ^ expanded_key_index; \
407
16.2k
  value1 = byte_stream_bit_rotate_left_32bit( value1, 11 ); \
408
16.2k
  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
492
  expanded_key_value0 = value0; \
412
492
  expanded_key_value1 = value1; \
413
492
  expanded_key_value2 = value2; \
414
492
  expanded_key_value3 = value3; \
415
492
  value0 = expanded_key_value4; \
416
492
  value1 = expanded_key_value5; \
417
492
  value2 = expanded_key_value6; \
418
492
  value3 = expanded_key_value7; \
419
492
  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
492
  expanded_key_value0 = value0; \
423
492
  expanded_key_value1 = value1; \
424
492
  expanded_key_value2 = value2; \
425
492
  expanded_key_value3 = value3; \
426
492
  value0 = expanded_key_value4; \
427
492
  value1 = expanded_key_value5; \
428
492
  value2 = expanded_key_value6; \
429
492
  value3 = expanded_key_value7; \
430
492
  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
492
  expanded_key_value0 = value0; \
434
492
  expanded_key_value1 = value1; \
435
492
  expanded_key_value2 = value2; \
436
492
  expanded_key_value3 = value3; \
437
492
  value0 = expanded_key_value4; \
438
492
  value1 = expanded_key_value5; \
439
492
  value2 = expanded_key_value6; \
440
492
  value3 = expanded_key_value7; \
441
492
  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
492
  expanded_key_value0 = value0; \
445
492
  expanded_key_value1 = value1; \
446
492
  expanded_key_value2 = value2; \
447
492
  expanded_key_value3 = value3; \
448
492
  value0 = expanded_key_value4; \
449
492
  value1 = expanded_key_value5; \
450
492
  value2 = expanded_key_value6; \
451
492
  value3 = expanded_key_value7; \
452
492
  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
492
  expanded_key_value0 = value0; \
456
492
  expanded_key_value1 = value1; \
457
492
  expanded_key_value2 = value2; \
458
492
  expanded_key_value3 = value3; \
459
492
  value0 = expanded_key_value4; \
460
492
  value1 = expanded_key_value5; \
461
492
  value2 = expanded_key_value6; \
462
492
  value3 = expanded_key_value7; \
463
492
  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
492
  expanded_key_value0 = value0; \
467
492
  expanded_key_value1 = value1; \
468
492
  expanded_key_value2 = value2; \
469
492
  expanded_key_value3 = value3; \
470
492
  value0 = expanded_key_value4; \
471
492
  value1 = expanded_key_value5; \
472
492
  value2 = expanded_key_value6; \
473
492
  value3 = expanded_key_value7; \
474
492
  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
492
  expanded_key_value0 = value0; \
478
492
  expanded_key_value1 = value1; \
479
492
  expanded_key_value2 = value2; \
480
492
  expanded_key_value3 = value3; \
481
492
  value0 = expanded_key_value4; \
482
492
  value1 = expanded_key_value5; \
483
492
  value2 = expanded_key_value6; \
484
492
  value3 = expanded_key_value7; \
485
492
  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
492
  expanded_key_value0 = value0; \
489
492
  expanded_key_value1 = value1; \
490
492
  expanded_key_value2 = value2; \
491
492
  expanded_key_value3 = value3; \
492
492
  value0 = expanded_key_value4; \
493
492
  value1 = expanded_key_value5; \
494
492
  value2 = expanded_key_value6; \
495
492
  value3 = expanded_key_value7; \
496
492
  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
5.24k
  libfcrypto_serpent_calculate_reverse_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
532
5.24k
  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
5.24k
  libfcrypto_serpent_calculate_reverse_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
536
5.24k
  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
5.24k
  libfcrypto_serpent_calculate_reverse_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
540
5.24k
  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
5.24k
  libfcrypto_serpent_calculate_reverse_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
544
5.24k
  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
5.24k
  libfcrypto_serpent_calculate_reverse_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
548
5.24k
  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
5.24k
  libfcrypto_serpent_calculate_reverse_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
552
5.24k
  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
5.24k
  libfcrypto_serpent_calculate_reverse_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
556
5.24k
  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
3.93k
  libfcrypto_serpent_calculate_reverse_linear_transformation( expanded_key_values, expanded_key_index, value0, value1, value2, value3, value4 ); \
560
3.93k
  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
125
{
570
125
  libfcrypto_internal_serpent_context_t *internal_context = NULL;
571
125
  static char *function                                   = "libfcrypto_serpent_context_initialize";
572
573
125
  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
125
  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
125
  internal_context = memory_allocate_structure(
596
125
                      libfcrypto_internal_serpent_context_t );
597
598
125
  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
125
  if( memory_set(
610
125
       internal_context,
611
125
       0,
612
125
       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
125
  *context = (libfcrypto_serpent_context_t *) internal_context;
624
625
125
  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
125
}
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
125
{
643
125
  libfcrypto_internal_serpent_context_t *internal_context = NULL;
644
125
  static char *function                                   = "libfcrypto_serpent_context_free";
645
125
  int result                                              = 1;
646
647
125
  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
125
  if( *context != NULL )
659
125
  {
660
125
    internal_context = (libfcrypto_internal_serpent_context_t *) *context;
661
125
    *context         = NULL;
662
663
125
    if( memory_set(
664
125
         internal_context,
665
125
         0,
666
125
         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
125
    memory_free(
678
125
     internal_context );
679
125
  }
680
125
  return( result );
681
125
}
682
683
/* Sets the key
684
 * Returns 1 if successful or -1 on error
685
 */
686
int libfcrypto_serpent_context_set_key(
687
     libfcrypto_serpent_context_t *context,
688
     const uint8_t *key,
689
     size_t key_bit_size,
690
     libcerror_error_t **error )
691
124
{
692
124
  uint8_t key_data[ 32 ];
693
694
124
  libfcrypto_internal_serpent_context_t *internal_context = NULL;
695
124
  static char *function                                   = "libfcrypto_serpent_context_set_key";
696
124
  size_t key_byte_offset                                  = 0;
697
124
  size_t key_byte_size                                    = 0;
698
124
  uint32_t value0                                         = 0;
699
124
  uint32_t value1                                         = 0;
700
124
  uint32_t value2                                         = 0;
701
124
  uint32_t value3                                         = 0;
702
124
  uint32_t value4                                         = 0;
703
124
  uint8_t expanded_key_index                              = 0;
704
124
  uint8_t previous_expanded_key_index                     = 0;
705
706
124
  if( context == NULL )
707
0
  {
708
0
    libcerror_error_set(
709
0
     error,
710
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
711
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
712
0
     "%s: invalid context.",
713
0
     function );
714
715
0
    return( -1 );
716
0
  }
717
124
  internal_context = (libfcrypto_internal_serpent_context_t *) context;
718
719
124
  if( key == NULL )
720
0
  {
721
0
    libcerror_error_set(
722
0
     error,
723
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
724
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
725
0
     "%s: invalid key.",
726
0
     function );
727
728
0
    return( -1 );
729
0
  }
730
124
  if( ( key_bit_size != 128 )
731
11
   && ( key_bit_size != 192 )
732
11
   && ( key_bit_size != 256 ) )
733
1
  {
734
1
    libcerror_error_set(
735
1
     error,
736
1
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
737
1
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
738
1
     "%s: unsupported key bit size.",
739
1
     function );
740
741
1
    return( -1 );
742
1
  }
743
123
  if( memory_set(
744
123
       key_data,
745
123
       0,
746
123
       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
123
  if( memory_set(
758
123
       internal_context->expanded_key,
759
123
       0,
760
123
       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
123
  key_byte_size = key_bit_size / 8;
774
775
123
  if( memory_copy(
776
123
       key_data,
777
123
       key,
778
123
       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
123
  if( key_byte_size < 32 )
790
113
  {
791
113
    key_data[ key_byte_size ] = 1;
792
113
  }
793
123
  for( key_byte_offset = 0;
794
1.10k
       key_byte_offset < 32;
795
984
       key_byte_offset += 4 )
796
984
  {
797
984
    byte_stream_copy_to_uint32_little_endian(
798
984
     &( key_data[ key_byte_offset ] ),
799
984
     value0 );
800
801
984
    internal_context->expanded_key[ expanded_key_index++ ] = value0;
802
984
  }
803
  /* 2. Calculate the prekeys
804
   */
805
123
  value0 = internal_context->expanded_key[ 3 ];
806
123
  value1 = internal_context->expanded_key[ 4 ];
807
123
  value2 = internal_context->expanded_key[ 5 ];
808
123
  value3 = internal_context->expanded_key[ 6 ];
809
123
  value4 = internal_context->expanded_key[ 7 ];
810
811
123
  libfcrypto_serpent_calculate_expanded_key(
812
123
   internal_context->expanded_key,
813
123
   0,
814
123
   internal_context->expanded_key[ 0 ],
815
123
   value0,
816
123
   value4,
817
123
   value2 );
818
819
123
  libfcrypto_serpent_calculate_expanded_key(
820
123
   internal_context->expanded_key,
821
123
   1,
822
123
   internal_context->expanded_key[ 1 ],
823
123
   value1,
824
123
   value0,
825
123
   value3 );
826
827
123
  libfcrypto_serpent_calculate_expanded_key(
828
123
   internal_context->expanded_key,
829
123
   2,
830
123
   ( internal_context->expanded_key )[ 2 ],
831
123
   value2,
832
123
   value1,
833
123
   value4 );
834
835
123
  libfcrypto_serpent_calculate_expanded_key(
836
123
   internal_context->expanded_key,
837
123
   3,
838
123
   ( internal_context->expanded_key )[ 3 ],
839
123
   value3,
840
123
   value2,
841
123
   value0 );
842
843
123
  libfcrypto_serpent_calculate_expanded_key(
844
123
   internal_context->expanded_key,
845
123
   4,
846
123
   ( internal_context->expanded_key )[ 4 ],
847
123
   value4,
848
123
   value3,
849
123
   value1 );
850
851
123
  libfcrypto_serpent_calculate_expanded_key(
852
123
   internal_context->expanded_key,
853
123
   5,
854
123
   ( internal_context->expanded_key )[ 5 ],
855
123
   value0,
856
123
   value4,
857
123
   value2 );
858
859
123
  libfcrypto_serpent_calculate_expanded_key(
860
123
   internal_context->expanded_key,
861
123
   6,
862
123
   ( internal_context->expanded_key )[ 6 ],
863
123
   value1,
864
123
   value0,
865
123
   value3 );
866
867
123
  libfcrypto_serpent_calculate_expanded_key(
868
123
   internal_context->expanded_key,
869
123
   7,
870
123
   ( internal_context->expanded_key )[ 7 ],
871
123
   value2,
872
123
   value1,
873
123
   value4 );
874
875
123
  libfcrypto_serpent_calculate_expanded_key(
876
123
   internal_context->expanded_key,
877
123
   8,
878
123
   ( internal_context->expanded_key )[ 0 ],
879
123
   value3,
880
123
   value2,
881
123
   value0 );
882
883
123
  libfcrypto_serpent_calculate_expanded_key(
884
123
   internal_context->expanded_key,
885
123
   9,
886
123
   ( internal_context->expanded_key )[ 1 ],
887
123
   value4,
888
123
   value3,
889
123
   value1 );
890
891
123
  libfcrypto_serpent_calculate_expanded_key(
892
123
   internal_context->expanded_key,
893
123
   10,
894
123
   ( internal_context->expanded_key )[ 2 ],
895
123
   value0,
896
123
   value4,
897
123
   value2 );
898
899
123
  libfcrypto_serpent_calculate_expanded_key(
900
123
   internal_context->expanded_key,
901
123
   11,
902
123
   ( internal_context->expanded_key )[ 3 ],
903
123
   value1,
904
123
   value0,
905
123
   value3 );
906
907
123
  previous_expanded_key_index = 4;
908
123
  expanded_key_index          = 12;
909
910
3.07k
  while( expanded_key_index < 128 )
911
2.95k
  {
912
2.95k
    libfcrypto_serpent_calculate_expanded_key(
913
2.95k
     internal_context->expanded_key,
914
2.95k
     expanded_key_index,
915
2.95k
     ( internal_context->expanded_key )[ previous_expanded_key_index ],
916
2.95k
     value2,
917
2.95k
     value1,
918
2.95k
     value4 );
919
920
2.95k
    expanded_key_index++;
921
2.95k
    previous_expanded_key_index++;
922
923
2.95k
    libfcrypto_serpent_calculate_expanded_key(
924
2.95k
     internal_context->expanded_key,
925
2.95k
     expanded_key_index,
926
2.95k
     ( internal_context->expanded_key )[ previous_expanded_key_index ],
927
2.95k
     value3,
928
2.95k
     value2,
929
2.95k
     value0 );
930
931
2.95k
    expanded_key_index++;
932
2.95k
    previous_expanded_key_index++;
933
934
2.95k
    libfcrypto_serpent_calculate_expanded_key(
935
2.95k
     internal_context->expanded_key,
936
2.95k
     expanded_key_index,
937
2.95k
     ( internal_context->expanded_key )[ previous_expanded_key_index ],
938
2.95k
     value4,
939
2.95k
     value3,
940
2.95k
     value1 );
941
942
2.95k
    expanded_key_index++;
943
2.95k
    previous_expanded_key_index++;
944
945
2.95k
    libfcrypto_serpent_calculate_expanded_key(
946
2.95k
     internal_context->expanded_key,
947
2.95k
     expanded_key_index,
948
2.95k
     ( internal_context->expanded_key )[ previous_expanded_key_index ],
949
2.95k
     value0,
950
2.95k
     value4,
951
2.95k
     value2 );
952
953
2.95k
    expanded_key_index++;
954
2.95k
    previous_expanded_key_index++;
955
956
2.95k
    libfcrypto_serpent_calculate_expanded_key(
957
2.95k
     internal_context->expanded_key,
958
2.95k
     expanded_key_index,
959
2.95k
     ( internal_context->expanded_key )[ previous_expanded_key_index ],
960
2.95k
     value1,
961
2.95k
     value0,
962
2.95k
     value3 );
963
964
2.95k
    expanded_key_index++;
965
2.95k
    previous_expanded_key_index++;
966
2.95k
  }
967
  /* 3. Calculate the round keys
968
   */
969
123
  libfcrypto_serpent_calculate_forward_substitution3(
970
123
   value3,
971
123
   value4,
972
123
   value0,
973
123
   value1,
974
123
   value2 );
975
976
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution4(
977
123
   internal_context->expanded_key[ 128 ],
978
123
   internal_context->expanded_key[ 129 ],
979
123
   internal_context->expanded_key[ 130 ],
980
123
   internal_context->expanded_key[ 131 ],
981
123
   internal_context->expanded_key[ 124 ],
982
123
   internal_context->expanded_key[ 125 ],
983
123
   internal_context->expanded_key[ 126 ],
984
123
   internal_context->expanded_key[ 127 ],
985
123
   value1,
986
123
   value2,
987
123
   value4,
988
123
   value3,
989
123
   value0 );
990
991
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution5(
992
123
   internal_context->expanded_key[ 124 ],
993
123
   internal_context->expanded_key[ 125 ],
994
123
   internal_context->expanded_key[ 126 ],
995
123
   internal_context->expanded_key[ 127 ],
996
123
   internal_context->expanded_key[ 120 ],
997
123
   internal_context->expanded_key[ 121 ],
998
123
   internal_context->expanded_key[ 122 ],
999
123
   internal_context->expanded_key[ 123 ],
1000
123
   value2,
1001
123
   value4,
1002
123
   value3,
1003
123
   value0,
1004
123
   value1 );
1005
1006
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution6(
1007
123
   internal_context->expanded_key[ 120 ],
1008
123
   internal_context->expanded_key[ 121 ],
1009
123
   internal_context->expanded_key[ 122 ],
1010
123
   internal_context->expanded_key[ 123 ],
1011
123
   internal_context->expanded_key[ 116 ],
1012
123
   internal_context->expanded_key[ 117 ],
1013
123
   internal_context->expanded_key[ 118 ],
1014
123
   internal_context->expanded_key[ 119 ],
1015
123
   value1,
1016
123
   value2,
1017
123
   value4,
1018
123
   value0,
1019
123
   value3 );
1020
1021
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution7(
1022
123
   internal_context->expanded_key[ 116 ],
1023
123
   internal_context->expanded_key[ 117 ],
1024
123
   internal_context->expanded_key[ 118 ],
1025
123
   internal_context->expanded_key[ 119 ],
1026
123
   internal_context->expanded_key[ 112 ],
1027
123
   internal_context->expanded_key[ 113 ],
1028
123
   internal_context->expanded_key[ 114 ],
1029
123
   internal_context->expanded_key[ 115 ],
1030
123
   value4,
1031
123
   value3,
1032
123
   value2,
1033
123
   value0,
1034
123
   value1 );
1035
1036
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution0(
1037
123
   internal_context->expanded_key[ 112 ],
1038
123
   internal_context->expanded_key[ 113 ],
1039
123
   internal_context->expanded_key[ 114 ],
1040
123
   internal_context->expanded_key[ 115 ],
1041
123
   internal_context->expanded_key[ 108 ],
1042
123
   internal_context->expanded_key[ 109 ],
1043
123
   internal_context->expanded_key[ 110 ],
1044
123
   internal_context->expanded_key[ 111 ],
1045
123
   value1,
1046
123
   value2,
1047
123
   value0,
1048
123
   value4,
1049
123
   value3 );
1050
1051
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution1(
1052
123
   internal_context->expanded_key[ 108 ],
1053
123
   internal_context->expanded_key[ 109 ],
1054
123
   internal_context->expanded_key[ 110 ],
1055
123
   internal_context->expanded_key[ 111 ],
1056
123
   internal_context->expanded_key[ 104 ],
1057
123
   internal_context->expanded_key[ 105 ],
1058
123
   internal_context->expanded_key[ 106 ],
1059
123
   internal_context->expanded_key[ 107 ],
1060
123
   value0,
1061
123
   value2,
1062
123
   value4,
1063
123
   value1,
1064
123
   value3 );
1065
1066
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution2(
1067
123
   internal_context->expanded_key[ 104 ],
1068
123
   internal_context->expanded_key[ 105 ],
1069
123
   internal_context->expanded_key[ 106 ],
1070
123
   internal_context->expanded_key[ 107 ],
1071
123
   internal_context->expanded_key[ 100 ],
1072
123
   internal_context->expanded_key[ 101 ],
1073
123
   internal_context->expanded_key[ 102 ],
1074
123
   internal_context->expanded_key[ 103 ],
1075
123
   value3,
1076
123
   value4,
1077
123
   value1,
1078
123
   value0,
1079
123
   value2 );
1080
1081
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution3(
1082
123
   internal_context->expanded_key[ 100 ],
1083
123
   internal_context->expanded_key[ 101 ],
1084
123
   internal_context->expanded_key[ 102 ],
1085
123
   internal_context->expanded_key[ 103 ],
1086
123
   internal_context->expanded_key[ 96 ],
1087
123
   internal_context->expanded_key[ 97 ],
1088
123
   internal_context->expanded_key[ 98 ],
1089
123
   internal_context->expanded_key[ 99 ],
1090
123
   value2,
1091
123
   value4,
1092
123
   value3,
1093
123
   value0,
1094
123
   value1 );
1095
1096
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution4(
1097
123
   internal_context->expanded_key[ 96 ],
1098
123
   internal_context->expanded_key[ 97 ],
1099
123
   internal_context->expanded_key[ 98 ],
1100
123
   internal_context->expanded_key[ 99 ],
1101
123
   internal_context->expanded_key[ 92 ],
1102
123
   internal_context->expanded_key[ 93 ],
1103
123
   internal_context->expanded_key[ 94 ],
1104
123
   internal_context->expanded_key[ 95 ],
1105
123
   value0,
1106
123
   value1,
1107
123
   value4,
1108
123
   value2,
1109
123
   value3 );
1110
1111
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution5(
1112
123
   internal_context->expanded_key[ 92 ],
1113
123
   internal_context->expanded_key[ 93 ],
1114
123
   internal_context->expanded_key[ 94 ],
1115
123
   internal_context->expanded_key[ 95 ],
1116
123
   internal_context->expanded_key[ 88 ],
1117
123
   internal_context->expanded_key[ 89 ],
1118
123
   internal_context->expanded_key[ 90 ],
1119
123
   internal_context->expanded_key[ 91 ],
1120
123
   value1,
1121
123
   value4,
1122
123
   value2,
1123
123
   value3,
1124
123
   value0 );
1125
1126
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution6(
1127
123
   internal_context->expanded_key[ 88 ],
1128
123
   internal_context->expanded_key[ 89 ],
1129
123
   internal_context->expanded_key[ 90 ],
1130
123
   internal_context->expanded_key[ 91 ],
1131
123
   internal_context->expanded_key[ 84 ],
1132
123
   internal_context->expanded_key[ 85 ],
1133
123
   internal_context->expanded_key[ 86 ],
1134
123
   internal_context->expanded_key[ 87 ],
1135
123
   value0,
1136
123
   value1,
1137
123
   value4,
1138
123
   value3,
1139
123
   value2 );
1140
1141
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution7(
1142
123
   internal_context->expanded_key[ 84 ],
1143
123
   internal_context->expanded_key[ 85 ],
1144
123
   internal_context->expanded_key[ 86 ],
1145
123
   internal_context->expanded_key[ 87 ],
1146
123
   internal_context->expanded_key[ 80 ],
1147
123
   internal_context->expanded_key[ 81 ],
1148
123
   internal_context->expanded_key[ 82 ],
1149
123
   internal_context->expanded_key[ 83 ],
1150
123
   value4,
1151
123
   value2,
1152
123
   value1,
1153
123
   value3,
1154
123
   value0 );
1155
1156
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution0(
1157
123
   internal_context->expanded_key[ 80 ],
1158
123
   internal_context->expanded_key[ 81 ],
1159
123
   internal_context->expanded_key[ 82 ],
1160
123
   internal_context->expanded_key[ 83 ],
1161
123
   internal_context->expanded_key[ 76 ],
1162
123
   internal_context->expanded_key[ 77 ],
1163
123
   internal_context->expanded_key[ 78 ],
1164
123
   internal_context->expanded_key[ 79 ],
1165
123
   value0,
1166
123
   value1,
1167
123
   value3,
1168
123
   value4,
1169
123
   value2 );
1170
1171
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution1(
1172
123
   internal_context->expanded_key[ 76 ],
1173
123
   internal_context->expanded_key[ 77 ],
1174
123
   internal_context->expanded_key[ 78 ],
1175
123
   internal_context->expanded_key[ 79 ],
1176
123
   internal_context->expanded_key[ 72 ],
1177
123
   internal_context->expanded_key[ 73 ],
1178
123
   internal_context->expanded_key[ 74 ],
1179
123
   internal_context->expanded_key[ 75 ],
1180
123
   value3,
1181
123
   value1,
1182
123
   value4,
1183
123
   value0,
1184
123
   value2 );
1185
1186
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution2(
1187
123
   internal_context->expanded_key[ 72 ],
1188
123
   internal_context->expanded_key[ 73 ],
1189
123
   internal_context->expanded_key[ 74 ],
1190
123
   internal_context->expanded_key[ 75 ],
1191
123
   internal_context->expanded_key[ 68 ],
1192
123
   internal_context->expanded_key[ 69 ],
1193
123
   internal_context->expanded_key[ 70 ],
1194
123
   internal_context->expanded_key[ 71 ],
1195
123
   value2,
1196
123
   value4,
1197
123
   value0,
1198
123
   value3,
1199
123
   value1 );
1200
1201
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution3(
1202
123
   internal_context->expanded_key[ 68 ],
1203
123
   internal_context->expanded_key[ 69 ],
1204
123
   internal_context->expanded_key[ 70 ],
1205
123
   internal_context->expanded_key[ 71 ],
1206
123
   internal_context->expanded_key[ 64 ],
1207
123
   internal_context->expanded_key[ 65 ],
1208
123
   internal_context->expanded_key[ 66 ],
1209
123
   internal_context->expanded_key[ 67 ],
1210
123
   value1,
1211
123
   value4,
1212
123
   value2,
1213
123
   value3,
1214
123
   value0 );
1215
1216
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution4(
1217
123
   internal_context->expanded_key[ 64 ],
1218
123
   internal_context->expanded_key[ 65 ],
1219
123
   internal_context->expanded_key[ 66 ],
1220
123
   internal_context->expanded_key[ 67 ],
1221
123
   internal_context->expanded_key[ 60 ],
1222
123
   internal_context->expanded_key[ 61 ],
1223
123
   internal_context->expanded_key[ 62 ],
1224
123
   internal_context->expanded_key[ 63 ],
1225
123
   value3,
1226
123
   value0,
1227
123
   value4,
1228
123
   value1,
1229
123
   value2 );
1230
1231
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution5(
1232
123
   internal_context->expanded_key[ 60 ],
1233
123
   internal_context->expanded_key[ 61 ],
1234
123
   internal_context->expanded_key[ 62 ],
1235
123
   internal_context->expanded_key[ 63 ],
1236
123
   internal_context->expanded_key[ 56 ],
1237
123
   internal_context->expanded_key[ 57 ],
1238
123
   internal_context->expanded_key[ 58 ],
1239
123
   internal_context->expanded_key[ 59 ],
1240
123
   value0,
1241
123
   value4,
1242
123
   value1,
1243
123
   value2,
1244
123
   value3 );
1245
1246
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution6(
1247
123
   internal_context->expanded_key[ 56 ],
1248
123
   internal_context->expanded_key[ 57 ],
1249
123
   internal_context->expanded_key[ 58 ],
1250
123
   internal_context->expanded_key[ 59 ],
1251
123
   internal_context->expanded_key[ 52 ],
1252
123
   internal_context->expanded_key[ 53 ],
1253
123
   internal_context->expanded_key[ 54 ],
1254
123
   internal_context->expanded_key[ 55 ],
1255
123
   value3,
1256
123
   value0,
1257
123
   value4,
1258
123
   value2,
1259
123
   value1 );
1260
1261
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution7(
1262
123
   internal_context->expanded_key[ 52 ],
1263
123
   internal_context->expanded_key[ 53 ],
1264
123
   internal_context->expanded_key[ 54 ],
1265
123
   internal_context->expanded_key[ 55 ],
1266
123
   internal_context->expanded_key[ 48 ],
1267
123
   internal_context->expanded_key[ 49 ],
1268
123
   internal_context->expanded_key[ 50 ],
1269
123
   internal_context->expanded_key[ 51 ],
1270
123
   value4,
1271
123
   value1,
1272
123
   value0,
1273
123
   value2,
1274
123
   value3 );
1275
1276
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution0(
1277
123
   internal_context->expanded_key[ 48 ],
1278
123
   internal_context->expanded_key[ 49 ],
1279
123
   internal_context->expanded_key[ 50 ],
1280
123
   internal_context->expanded_key[ 51 ],
1281
123
   internal_context->expanded_key[ 44 ],
1282
123
   internal_context->expanded_key[ 45 ],
1283
123
   internal_context->expanded_key[ 46 ],
1284
123
   internal_context->expanded_key[ 47 ],
1285
123
   value3,
1286
123
   value0,
1287
123
   value2,
1288
123
   value4,
1289
123
   value1 );
1290
1291
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution1(
1292
123
   internal_context->expanded_key[ 44 ],
1293
123
   internal_context->expanded_key[ 45 ],
1294
123
   internal_context->expanded_key[ 46 ],
1295
123
   internal_context->expanded_key[ 47 ],
1296
123
   internal_context->expanded_key[ 40 ],
1297
123
   internal_context->expanded_key[ 41 ],
1298
123
   internal_context->expanded_key[ 42 ],
1299
123
   internal_context->expanded_key[ 43 ],
1300
123
   value2,
1301
123
   value0,
1302
123
   value4,
1303
123
   value3,
1304
123
   value1 );
1305
1306
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution2(
1307
123
   internal_context->expanded_key[ 40 ],
1308
123
   internal_context->expanded_key[ 41 ],
1309
123
   internal_context->expanded_key[ 42 ],
1310
123
   internal_context->expanded_key[ 43 ],
1311
123
   internal_context->expanded_key[ 36 ],
1312
123
   internal_context->expanded_key[ 37 ],
1313
123
   internal_context->expanded_key[ 38 ],
1314
123
   internal_context->expanded_key[ 39 ],
1315
123
   value1,
1316
123
   value4,
1317
123
   value3,
1318
123
   value2,
1319
123
   value0 );
1320
1321
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution3(
1322
123
   internal_context->expanded_key[ 36 ],
1323
123
   internal_context->expanded_key[ 37 ],
1324
123
   internal_context->expanded_key[ 38 ],
1325
123
   internal_context->expanded_key[ 39 ],
1326
123
   internal_context->expanded_key[ 32 ],
1327
123
   internal_context->expanded_key[ 33 ],
1328
123
   internal_context->expanded_key[ 34 ],
1329
123
   internal_context->expanded_key[ 35 ],
1330
123
   value0,
1331
123
   value4,
1332
123
   value1,
1333
123
   value2,
1334
123
   value3 );
1335
1336
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution4(
1337
123
   internal_context->expanded_key[ 32 ],
1338
123
   internal_context->expanded_key[ 33 ],
1339
123
   internal_context->expanded_key[ 34 ],
1340
123
   internal_context->expanded_key[ 35 ],
1341
123
   internal_context->expanded_key[ 28 ],
1342
123
   internal_context->expanded_key[ 29 ],
1343
123
   internal_context->expanded_key[ 30 ],
1344
123
   internal_context->expanded_key[ 31 ],
1345
123
   value2,
1346
123
   value3,
1347
123
   value4,
1348
123
   value0,
1349
123
   value1 );
1350
1351
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution5(
1352
123
   internal_context->expanded_key[ 28 ],
1353
123
   internal_context->expanded_key[ 29 ],
1354
123
   internal_context->expanded_key[ 30 ],
1355
123
   internal_context->expanded_key[ 31 ],
1356
123
   internal_context->expanded_key[ 24 ],
1357
123
   internal_context->expanded_key[ 25 ],
1358
123
   internal_context->expanded_key[ 26 ],
1359
123
   internal_context->expanded_key[ 27 ],
1360
123
   value3,
1361
123
   value4,
1362
123
   value0,
1363
123
   value1,
1364
123
   value2 );
1365
1366
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution6(
1367
123
   internal_context->expanded_key[ 24 ],
1368
123
   internal_context->expanded_key[ 25 ],
1369
123
   internal_context->expanded_key[ 26 ],
1370
123
   internal_context->expanded_key[ 27 ],
1371
123
   internal_context->expanded_key[ 20 ],
1372
123
   internal_context->expanded_key[ 21 ],
1373
123
   internal_context->expanded_key[ 22 ],
1374
123
   internal_context->expanded_key[ 23 ],
1375
123
   value2,
1376
123
   value3,
1377
123
   value4,
1378
123
   value1,
1379
123
   value0 );
1380
1381
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution7(
1382
123
   internal_context->expanded_key[ 20 ],
1383
123
   internal_context->expanded_key[ 21 ],
1384
123
   internal_context->expanded_key[ 22 ],
1385
123
   internal_context->expanded_key[ 23 ],
1386
123
   internal_context->expanded_key[ 16 ],
1387
123
   internal_context->expanded_key[ 17 ],
1388
123
   internal_context->expanded_key[ 18 ],
1389
123
   internal_context->expanded_key[ 19 ],
1390
123
   value4,
1391
123
   value0,
1392
123
   value3,
1393
123
   value1,
1394
123
   value2 );
1395
1396
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution0(
1397
123
   internal_context->expanded_key[ 16 ],
1398
123
   internal_context->expanded_key[ 17 ],
1399
123
   internal_context->expanded_key[ 18 ],
1400
123
   internal_context->expanded_key[ 19 ],
1401
123
   internal_context->expanded_key[ 12 ],
1402
123
   internal_context->expanded_key[ 13 ],
1403
123
   internal_context->expanded_key[ 14 ],
1404
123
   internal_context->expanded_key[ 15 ],
1405
123
   value2,
1406
123
   value3,
1407
123
   value1,
1408
123
   value4,
1409
123
   value0 );
1410
1411
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution1(
1412
123
   internal_context->expanded_key[ 12 ],
1413
123
   internal_context->expanded_key[ 13 ],
1414
123
   internal_context->expanded_key[ 14 ],
1415
123
   internal_context->expanded_key[ 15 ],
1416
123
   internal_context->expanded_key[ 8 ],
1417
123
   internal_context->expanded_key[ 9 ],
1418
123
   internal_context->expanded_key[ 10 ],
1419
123
   internal_context->expanded_key[ 11 ],
1420
123
   value1,
1421
123
   value3,
1422
123
   value4,
1423
123
   value2,
1424
123
   value0 );
1425
1426
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution2(
1427
123
   internal_context->expanded_key[ 8 ],
1428
123
   internal_context->expanded_key[ 9 ],
1429
123
   internal_context->expanded_key[ 10 ],
1430
123
   internal_context->expanded_key[ 11 ],
1431
123
   internal_context->expanded_key[ 4 ],
1432
123
   internal_context->expanded_key[ 5 ],
1433
123
   internal_context->expanded_key[ 6 ],
1434
123
   internal_context->expanded_key[ 7 ],
1435
123
   value0,
1436
123
   value4,
1437
123
   value2,
1438
123
   value1,
1439
123
   value3 );
1440
1441
123
  libfcrypto_serpent_calculate_expanded_key_with_forward_substitution3(
1442
123
   internal_context->expanded_key[ 4 ],
1443
123
   internal_context->expanded_key[ 5 ],
1444
123
   internal_context->expanded_key[ 6 ],
1445
123
   internal_context->expanded_key[ 7 ],
1446
123
   internal_context->expanded_key[ 0 ],
1447
123
   internal_context->expanded_key[ 1 ],
1448
123
   internal_context->expanded_key[ 2 ],
1449
123
   internal_context->expanded_key[ 3 ],
1450
123
   value3,
1451
123
   value4,
1452
123
   value0,
1453
123
   value1,
1454
123
   value2 );
1455
1456
123
  internal_context->expanded_key[ 0 ] = value1;
1457
123
  internal_context->expanded_key[ 1 ] = value2;
1458
123
  internal_context->expanded_key[ 2 ] = value4;
1459
123
  internal_context->expanded_key[ 3 ] = value3;
1460
1461
123
  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
123
}
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
1.31k
{
1896
1.31k
  static char *function = "libfcrypto_internal_serpent_context_decrypt_block";
1897
1.31k
  uint32_t value0       = 0;
1898
1.31k
  uint32_t value1       = 0;
1899
1.31k
  uint32_t value2       = 0;
1900
1.31k
  uint32_t value3       = 0;
1901
1.31k
  uint32_t value4       = 0;
1902
1903
1.31k
  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
1.31k
  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
1.31k
  if( ( input_data_size < 16 )
1926
1.31k
   || ( 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
1.31k
  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
1.31k
  if( ( output_data_size < 16 )
1949
1.31k
   || ( 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
1.31k
  byte_stream_copy_to_uint32_little_endian(
1961
1.31k
   &( input_data[ 0 ] ),
1962
1.31k
   value0 );
1963
1964
1.31k
  byte_stream_copy_to_uint32_little_endian(
1965
1.31k
   &( input_data[ 4 ] ),
1966
1.31k
   value1 );
1967
1968
1.31k
  byte_stream_copy_to_uint32_little_endian(
1969
1.31k
   &( input_data[ 8 ] ),
1970
1.31k
   value2 );
1971
1972
1.31k
  byte_stream_copy_to_uint32_little_endian(
1973
1.31k
   &( input_data[ 12 ] ),
1974
1.31k
   value3 );
1975
1976
1.31k
  value0 ^= internal_context->expanded_key[ 128 ];
1977
1.31k
  value1 ^= internal_context->expanded_key[ 129 ];
1978
1.31k
  value2 ^= internal_context->expanded_key[ 130 ];
1979
1.31k
  value3 ^= internal_context->expanded_key[ 131 ];
1980
1981
1.31k
  libfcrypto_serpent_calculate_reverse_substitution7(
1982
1.31k
   value0,
1983
1.31k
   value1,
1984
1.31k
   value2,
1985
1.31k
   value3,
1986
1.31k
   value4 );
1987
1988
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution6(
1989
1.31k
   internal_context->expanded_key,
1990
1.31k
   4 * 31,
1991
1.31k
   value1,
1992
1.31k
   value3,
1993
1.31k
   value0,
1994
1.31k
   value4,
1995
1.31k
   value2 );
1996
1997
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution5(
1998
1.31k
   internal_context->expanded_key,
1999
1.31k
   4 * 30,
2000
1.31k
   value0,
2001
1.31k
   value2,
2002
1.31k
   value4,
2003
1.31k
   value1,
2004
1.31k
   value3 );
2005
2006
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution4(
2007
1.31k
   internal_context->expanded_key,
2008
1.31k
   4 * 29,
2009
1.31k
   value2,
2010
1.31k
   value3,
2011
1.31k
   value0,
2012
1.31k
   value4,
2013
1.31k
   value1 );
2014
2015
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution3(
2016
1.31k
   internal_context->expanded_key,
2017
1.31k
   4 * 28,
2018
1.31k
   value2,
2019
1.31k
   value0,
2020
1.31k
   value1,
2021
1.31k
   value4,
2022
1.31k
   value3 );
2023
2024
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution2(
2025
1.31k
   internal_context->expanded_key,
2026
1.31k
   4 * 27,
2027
1.31k
   value1,
2028
1.31k
   value2,
2029
1.31k
   value3,
2030
1.31k
   value4,
2031
1.31k
   value0 );
2032
2033
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution1(
2034
1.31k
   internal_context->expanded_key,
2035
1.31k
   4 * 26,
2036
1.31k
   value2,
2037
1.31k
   value0,
2038
1.31k
   value4,
2039
1.31k
   value3,
2040
1.31k
   value1 );
2041
2042
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution0(
2043
1.31k
   internal_context->expanded_key,
2044
1.31k
   4 * 25,
2045
1.31k
   value1,
2046
1.31k
   value0,
2047
1.31k
   value4,
2048
1.31k
   value3,
2049
1.31k
   value2 );
2050
2051
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution7(
2052
1.31k
   internal_context->expanded_key,
2053
1.31k
   4 * 24,
2054
1.31k
   value4,
2055
1.31k
   value2,
2056
1.31k
   value0,
2057
1.31k
   value1,
2058
1.31k
   value3 );
2059
2060
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution6(
2061
1.31k
   internal_context->expanded_key,
2062
1.31k
   4 * 23,
2063
1.31k
   value2,
2064
1.31k
   value1,
2065
1.31k
   value4,
2066
1.31k
   value3,
2067
1.31k
   value0 );
2068
2069
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution5(
2070
1.31k
   internal_context->expanded_key,
2071
1.31k
   4 * 22,
2072
1.31k
   value4,
2073
1.31k
   value0,
2074
1.31k
   value3,
2075
1.31k
   value2,
2076
1.31k
   value1 );
2077
2078
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution4(
2079
1.31k
   internal_context->expanded_key,
2080
1.31k
   4 * 21,
2081
1.31k
   value0,
2082
1.31k
   value1,
2083
1.31k
   value4,
2084
1.31k
   value3,
2085
1.31k
   value2 );
2086
2087
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution3(
2088
1.31k
   internal_context->expanded_key,
2089
1.31k
   4 * 20,
2090
1.31k
   value0,
2091
1.31k
   value4,
2092
1.31k
   value2,
2093
1.31k
   value3,
2094
1.31k
   value1 );
2095
2096
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution2(
2097
1.31k
   internal_context->expanded_key,
2098
1.31k
   4 * 19,
2099
1.31k
   value2,
2100
1.31k
   value0,
2101
1.31k
   value1,
2102
1.31k
   value3,
2103
1.31k
   value4 );
2104
2105
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution1(
2106
1.31k
   internal_context->expanded_key,
2107
1.31k
   4 * 18,
2108
1.31k
   value0,
2109
1.31k
   value4,
2110
1.31k
   value3,
2111
1.31k
   value1,
2112
1.31k
   value2 );
2113
2114
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution0(
2115
1.31k
   internal_context->expanded_key,
2116
1.31k
   4 * 17,
2117
1.31k
   value2,
2118
1.31k
   value4,
2119
1.31k
   value3,
2120
1.31k
   value1,
2121
1.31k
   value0 );
2122
2123
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution7(
2124
1.31k
   internal_context->expanded_key,
2125
1.31k
   4 * 16,
2126
1.31k
   value3,
2127
1.31k
   value0,
2128
1.31k
   value4,
2129
1.31k
   value2,
2130
1.31k
   value1 );
2131
2132
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution6(
2133
1.31k
   internal_context->expanded_key,
2134
1.31k
   4 * 15,
2135
1.31k
   value0,
2136
1.31k
   value2,
2137
1.31k
   value3,
2138
1.31k
   value1,
2139
1.31k
   value4 );
2140
2141
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution5(
2142
1.31k
   internal_context->expanded_key,
2143
1.31k
   4 * 14,
2144
1.31k
   value3,
2145
1.31k
   value4,
2146
1.31k
   value1,
2147
1.31k
   value0,
2148
1.31k
   value2 );
2149
2150
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution4(
2151
1.31k
   internal_context->expanded_key,
2152
1.31k
   4 * 13,
2153
1.31k
   value4,
2154
1.31k
   value2,
2155
1.31k
   value3,
2156
1.31k
   value1,
2157
1.31k
   value0 );
2158
2159
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution3(
2160
1.31k
   internal_context->expanded_key,
2161
1.31k
   4 * 12,
2162
1.31k
   value4,
2163
1.31k
   value3,
2164
1.31k
   value0,
2165
1.31k
   value1,
2166
1.31k
   value2 );
2167
2168
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution2(
2169
1.31k
   internal_context->expanded_key,
2170
1.31k
   4 * 11,
2171
1.31k
   value0,
2172
1.31k
   value4,
2173
1.31k
   value2,
2174
1.31k
   value1,
2175
1.31k
   value3 );
2176
2177
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution1(
2178
1.31k
   internal_context->expanded_key,
2179
1.31k
   4 * 10,
2180
1.31k
   value4,
2181
1.31k
   value3,
2182
1.31k
   value1,
2183
1.31k
   value2,
2184
1.31k
   value0 );
2185
2186
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution0(
2187
1.31k
   internal_context->expanded_key,
2188
1.31k
   4 * 9,
2189
1.31k
   value0,
2190
1.31k
   value3,
2191
1.31k
   value1,
2192
1.31k
   value2,
2193
1.31k
   value4 );
2194
2195
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution7(
2196
1.31k
   internal_context->expanded_key,
2197
1.31k
   4 * 8,
2198
1.31k
   value1,
2199
1.31k
   value4,
2200
1.31k
   value3,
2201
1.31k
   value0,
2202
1.31k
   value2 );
2203
2204
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution6(
2205
1.31k
   internal_context->expanded_key,
2206
1.31k
   4 * 7,
2207
1.31k
   value4,
2208
1.31k
   value0,
2209
1.31k
   value1,
2210
1.31k
   value2,
2211
1.31k
   value3 );
2212
2213
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution5(
2214
1.31k
   internal_context->expanded_key,
2215
1.31k
   4 * 6,
2216
1.31k
   value1,
2217
1.31k
   value3,
2218
1.31k
   value2,
2219
1.31k
   value4,
2220
1.31k
   value0 );
2221
2222
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution4(
2223
1.31k
   internal_context->expanded_key,
2224
1.31k
   4 * 5,
2225
1.31k
   value3,
2226
1.31k
   value0,
2227
1.31k
   value1,
2228
1.31k
   value2,
2229
1.31k
   value4 );
2230
2231
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution3(
2232
1.31k
   internal_context->expanded_key,
2233
1.31k
   4 * 4,
2234
1.31k
   value3,
2235
1.31k
   value1,
2236
1.31k
   value4,
2237
1.31k
   value2,
2238
1.31k
   value0 );
2239
2240
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution2(
2241
1.31k
   internal_context->expanded_key,
2242
1.31k
   4 * 3,
2243
1.31k
   value4,
2244
1.31k
   value3,
2245
1.31k
   value0,
2246
1.31k
   value2,
2247
1.31k
   value1 );
2248
2249
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution1(
2250
1.31k
   internal_context->expanded_key,
2251
1.31k
   4 * 2,
2252
1.31k
   value3,
2253
1.31k
   value1,
2254
1.31k
   value2,
2255
1.31k
   value0,
2256
1.31k
   value4 );
2257
2258
1.31k
  libfcrypto_serpent_calculate_reverse_linear_transformation_and_substitution0(
2259
1.31k
   internal_context->expanded_key,
2260
1.31k
   4 * 1,
2261
1.31k
   value4,
2262
1.31k
   value1,
2263
1.31k
   value2,
2264
1.31k
   value0,
2265
1.31k
   value3 );
2266
2267
1.31k
  value2 ^= internal_context->expanded_key[ 0 ];
2268
1.31k
  value3 ^= internal_context->expanded_key[ 1 ];
2269
1.31k
  value1 ^= internal_context->expanded_key[ 2 ];
2270
1.31k
  value4 ^= internal_context->expanded_key[ 3 ];
2271
2272
1.31k
  byte_stream_copy_from_uint32_little_endian(
2273
1.31k
   &( output_data[ 0 ] ),
2274
1.31k
   value2 );
2275
2276
1.31k
  byte_stream_copy_from_uint32_little_endian(
2277
1.31k
   &( output_data[ 4 ] ),
2278
1.31k
   value3 );
2279
2280
1.31k
  byte_stream_copy_from_uint32_little_endian(
2281
1.31k
   &( output_data[ 8 ] ),
2282
1.31k
   value1 );
2283
2284
1.31k
  byte_stream_copy_from_uint32_little_endian(
2285
1.31k
   &( output_data[ 12 ] ),
2286
1.31k
   value4 );
2287
2288
1.31k
  return( 1 );
2289
1.31k
}
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
95
{
2306
95
  uint8_t block_data[ 16 ];
2307
95
  uint8_t internal_initialization_vector[ 16 ];
2308
2309
95
  static char *function = "libfcrypto_serpent_context_crypt_cbc";
2310
95
  size_t data_offset    = 0;
2311
2312
95
#if !defined( LIBFCRYPTO_UNFOLLED_LOOPS )
2313
95
  uint8_t block_index   = 0;
2314
95
#endif
2315
2316
95
  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
95
  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
95
  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
95
  if( ( mode != LIBFCRYPTO_SERPENT_CRYPT_MODE_ENCRYPT )
2350
41
   && ( 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
95
  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
95
  if( ( ( input_data_size & (size_t) 0x0f ) != 0 )
2375
91
   || ( input_data_size < 16 )
2376
91
   || ( 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
91
  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
91
  if( ( output_data_size < input_data_size )
2399
45
   || ( 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
45
  if( memory_copy(
2411
45
       internal_initialization_vector,
2412
45
       initialization_vector,
2413
45
       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
1.36k
  while( data_offset < input_data_size )
2425
1.32k
  {
2426
1.32k
    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
1.31k
    else
2488
1.31k
    {
2489
1.31k
      if( libfcrypto_internal_serpent_context_decrypt_block(
2490
1.31k
           (libfcrypto_internal_serpent_context_t *) context,
2491
1.31k
           &( input_data[ data_offset ] ),
2492
1.31k
           16,
2493
1.31k
           &( output_data[ data_offset ] ),
2494
1.31k
           16,
2495
1.31k
           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
1.31k
      for( block_index = 0;
2525
22.3k
           block_index < 16;
2526
20.9k
           block_index++ )
2527
20.9k
      {
2528
20.9k
        output_data[ data_offset++ ] ^= internal_initialization_vector[ block_index ];
2529
20.9k
      }
2530
1.31k
#endif
2531
1.31k
      data_offset -= 16;
2532
2533
1.31k
      if( memory_copy(
2534
1.31k
           internal_initialization_vector,
2535
1.31k
           &( input_data[ data_offset ] ),
2536
1.31k
           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
1.31k
    }
2548
1.32k
    data_offset += 16;
2549
1.32k
  }
2550
45
  if( memory_set(
2551
45
       internal_initialization_vector,
2552
45
       0,
2553
45
       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
45
  if( memory_set(
2565
45
       block_data,
2566
45
       0,
2567
45
       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
45
  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
45
}
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
0
   && ( 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
51
   || ( input_data_size < 16 )
2648
51
   || ( 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
4
   || ( 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