Coverage Report

Created: 2026-10-22 07:28

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