iPXE
des.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27/** @file
28 *
29 * DES algorithm
30 *
31 * DES was not designed to be implemented in software, and therefore
32 * contains a large number of bit permutation operations that are
33 * essentially free in hardware (requiring only wires, no gates) but
34 * expensive in software.
35 *
36 * Since DES is no longer used as a practical block cipher for large
37 * volumes of data, we optimise for code size, and do not attempt to
38 * obtain fast throughput.
39 *
40 * The algorithm is specified in NIST SP 800-67, downloadable from
41 * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-67r2.pdf
42 */
43
44#include <stdint.h>
45#include <string.h>
46#include <errno.h>
47#include <byteswap.h>
48#include <ipxe/rotate.h>
49#include <ipxe/crypto.h>
50#include <ipxe/ecb.h>
51#include <ipxe/cbc.h>
52#include <ipxe/init.h>
53#include <ipxe/des.h>
54
55/**
56 * DES shift schedule
57 *
58 * The DES shift schedule (ordered from round 16 down to round 1) is
59 * {1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,1}. In binary, this may be
60 * represented as {1,10,10,10,10,10,10,1,10,10,10,10,10,10,1,1} and
61 * concatenated (without padding) to produce a single binary integer
62 * 1101010101010110101010101011 (equal to 0x0d556aab in hexadecimal).
63 *
64 * This integer may then be consumed LSB-first, where a 1 bit
65 * indicates a shift and the generation of a round key, and a 0 bit
66 * indicates a shift without the generation of a round key.
67 */
68#define DES_SCHEDULE 0x0d556aab
69
70/**
71 * Define an element pair in a DES S-box
72 *
73 * @v x Upper element of element pair
74 * @v y Lower element of element pair
75 *
76 * DES S-box elements are 4-bit values. We encode two values per
77 * byte, ordering the elements so that the six-bit input value may be
78 * used directly as a lookup index.
79 *
80 * Specifically, if the input value is {r1,c3,c2,c1,c0,r0}, where
81 * {r1,r0} is the table row index and {c3,c2,c1,c0} is the table
82 * column index (as used in the DES specification), then:
83 *
84 * - {r1,c3,c2,c1,c0} is the byte index into the table
85 *
86 * - (4*r0) is the required bit shift to extract the 4-bit value
87 */
88#define SBYTE( x, y ) ( ( (y) << 4 ) | (x) )
89
90/**
91 * Define a row pair in a DES S-box
92 *
93 * @v x0..xf Upper row of row pair
94 * @v y0..yf Lower row of row pair
95 */
96#define SBOX( x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf, \
97 y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, ya, yb, yc, yd, ye, yf ) \
98 SBYTE ( x0, y0 ), SBYTE ( x1, y1 ), SBYTE ( x2, y2 ), SBYTE ( x3, y3 ),\
99 SBYTE ( x4, y4 ), SBYTE ( x5, y5 ), SBYTE ( x6, y6 ), SBYTE ( x7, y7 ),\
100 SBYTE ( x8, y8 ), SBYTE ( x9, y9 ), SBYTE ( xa, ya ), SBYTE ( xb, yb ),\
101 SBYTE ( xc, yc ), SBYTE ( xd, yd ), SBYTE ( xe, ye ), SBYTE ( xf, yf )
102
103/** DES S-boxes S1..S8 */
104static const uint8_t des_s[8][32] = { {
105 /* S1 */
106 SBOX ( 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
107 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 ),
108 SBOX ( 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
109 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 )
110}, {
111 /* S2 */
112 SBOX ( 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
113 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 ),
114 SBOX ( 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
115 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 )
116}, {
117 /* S3 */
118 SBOX ( 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
119 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 ),
120 SBOX ( 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
121 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 )
122}, {
123 /* S4 */
124 SBOX ( 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
125 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 ),
126 SBOX ( 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
127 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 )
128}, {
129 /* S5 */
130 SBOX ( 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
131 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 ),
132 SBOX ( 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
133 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 )
134}, {
135 /* S6 */
136 SBOX ( 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
137 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 ),
138 SBOX ( 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
139 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 )
140}, {
141 /* S7 */
142 SBOX ( 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
143 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 ),
144 SBOX ( 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
145 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 )
146}, {
147 /* S8 */
148 SBOX ( 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
149 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 ),
150 SBOX ( 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
151 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 )
152} };
153
154/**
155 * Define a bit index within permuted choice 2 (PC2)
156 *
157 * @v bit Bit index
158 *
159 * Permuted choice 2 (PC2) is used to select bits from a concatenated
160 * pair of 28-bit registers ("C" and "D") as part of the key schedule.
161 * We store these as 32-bit registers and so must add 4 to indexes
162 * above 28.
163 */
164#define DES_PC2( x ) ( (x) + ( ( (x) > 28 ) ? 4 : 0 ) )
165
166/**
167 * Define six bits of permuted choice 2 (PC2)
168 *
169 * @v r1:r0 Bits corresponding to S-box row index
170 * @v c3:c0 Bits corresponding to S-box column index
171 *
172 * There are 8 steps within a DES round (one step per S-box). Each
173 * step requires six bits of the round key, corresponding to the S-box
174 * input value {r1,c3,c2,c1,c0,r0}, where {r1,r0} is the table row
175 * index and {c3,c2,c1,c0} is the table column index.
176 *
177 * As an optimisation, we store the least significant of the 6 bits in
178 * the sign bit of a signed 8-bit value, and the remaining 5 bits in
179 * the least significant 5 bits of the 8-bit value. See the comments
180 * in des_sbox() for further details.
181 */
182#define DES_PC2R( r1, c3, c2, c1, c0, r0 ) \
183 DES_PC2 ( r0 ), /* LSB stored in sign bit */ \
184 DES_PC2 ( r0 ), /* Unused bit */ \
185 DES_PC2 ( r0 ), /* Unused bit */ \
186 DES_PC2 ( r1 ), /* Remaining 5 bits */ \
187 DES_PC2 ( c3 ), /* ... */ \
188 DES_PC2 ( c2 ), /* ... */ \
189 DES_PC2 ( c1 ), /* ... */ \
190 DES_PC2 ( c0 ) /* ... */
191
192/**
193 * A DES systematic permutation generator
194 *
195 * Many of the permutations used in DES comprise systematic bit
196 * patterns. We generate these permutations at runtime to save on
197 * code size.
198 */
200 /** Permutation */
202 /** Seed value */
204};
205
206/**
207 * Define a DES permutation generator
208 *
209 * @v PERMUTATION Permutation
210 * @v OFFSET Fixed input bit offset (0 or 1)
211 * @v INV<n> Input bit index bit <n> should be inverted
212 * @v BIT<n> Source bit for input bit index bit <n>
213 * @ret generator Permutation generator
214 */
215#define DES_GENERATOR( PERMUTATION, OFFSET, INV5, BIT5, INV4, BIT4, \
216 INV3, BIT3, INV2, BIT2, INV1, BIT1, INV0, BIT0 ) \
217 { \
218 .permutation = (PERMUTATION), \
219 .seed = ( ( ( ( unsigned int ) (INV0) ) << 31 ) | \
220 ( ( ( unsigned int ) (BIT0) ) << 28 ) | \
221 ( ( ( unsigned int ) (INV1) ) << 27 ) | \
222 ( ( ( unsigned int ) (BIT1) ) << 24 ) | \
223 ( ( ( unsigned int ) (INV2) ) << 23 ) | \
224 ( ( ( unsigned int ) (BIT2) ) << 20 ) | \
225 ( ( ( unsigned int ) (INV3) ) << 19 ) | \
226 ( ( ( unsigned int ) (BIT3) ) << 16 ) | \
227 ( ( ( unsigned int ) (INV4) ) << 15 ) | \
228 ( ( ( unsigned int ) (BIT4) ) << 12 ) | \
229 ( ( ( unsigned int ) (INV5) ) << 11 ) | \
230 ( ( ( unsigned int ) (BIT5) ) << 8 ) | \
231 ( ( uint32_t ) sizeof (PERMUTATION) - 1 ) | \
232 (OFFSET) ), \
233 }
234
235/** DES permuted choice 1 (PC1) "C" register */
236static uint8_t des_pc1c[29];
237
238/** DES permuted choice 1 (PC1) "D" register */
239static uint8_t des_pc1d[33];
240
241/** DES permuted choice 2 (PC2) */
242static const uint8_t des_pc2[65] = {
243 DES_PC2R ( 14, 17, 11, 24, 1, 5 ),
244 DES_PC2R ( 3, 28, 15, 6, 21, 10 ),
245 DES_PC2R ( 23, 19, 12, 4, 26, 8 ),
246 DES_PC2R ( 16, 7, 27, 20, 13, 2 ),
247 DES_PC2R ( 41, 52, 31, 37, 47, 55 ),
248 DES_PC2R ( 30, 40, 51, 45, 33, 48 ),
249 DES_PC2R ( 44, 49, 39, 56, 34, 53 ),
250 DES_PC2R ( 46, 42, 50, 36, 29, 32 ),
251 0 /* terminator */
252};
253
254/** DES initial permutation (IP) */
255static uint8_t des_ip[65];
256
257/** DES data permutation (P) */
258static const uint8_t des_p[33] = {
259 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
260 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25,
261 0 /* terminator */
262};
263
264/** DES final / inverse initial permutation (FP / IP^-1) */
265static uint8_t des_fp[65];
266
267/** DES permutation generators */
268static struct des_generator des_generators[] = {
269
270 /* The DES initial permutation transforms the bit index
271 * {x5,x4,x3,x2,x1,x0}+1 into {~x2,~x1,~x0,x4,x3,~x5}+1
272 */
273 DES_GENERATOR ( des_ip, 1, 1, 2, 1, 1, 1, 0, 0, 4, 0, 3, 1, 5 ),
274
275 /* The DES final permutation transforms the bit index
276 * {x5,x4,x3,x2,x1,x0}+1 into {~x0,x2,x1,~x5,~x4,~x3}+1
277 *
278 * There is an asymmetry in the DES block diagram for the last
279 * of the 16 rounds, which is functionally equivalent to
280 * performing 16 identical rounds and then swapping the left
281 * and right halves before applying the final permutation. We
282 * may therefore account for this asymmetry by inverting the
283 * MSB in each bit index, to point to the corresponding bit in
284 * the other half.
285 *
286 * This is equivalent to using a permutation that transforms
287 * {x5,x4,x3,x2,x1,x0}+1 into {x0,x2,x1,~x5,~x4,~x3}+1
288 */
289 DES_GENERATOR ( des_fp, 1, 0, 0, 0, 2, 0, 1, 1, 5, 1, 4, 1, 3 ),
290
291 /* The "C" half of DES permuted choice 1 (PC1) transforms the
292 * bit index {x5,x4,x3,x2,x1,x0}+1 into {~x2,~x1,~x0,x5,x4,x3}+1
293 */
294 DES_GENERATOR ( des_pc1c, 1, 1, 2, 1, 1, 1, 0, 0, 5, 0, 4, 0, 3 ),
295
296 /* The "D" half of DES permuted choice 1 (PC1) transforms the
297 * bit index {x5,x4,x3,x2,x1,x0}+1 into {~x2,~x1,~x0,~x5,~x4,~x3}+0
298 *
299 * Due to the idosyncratic design choice of using 28-bit
300 * registers in the DES key expansion schedule, the final four
301 * permutation values appear at indices [28:31] instead of
302 * [24:27]. This is adjusted for in @c des_setkey().
303 */
304 DES_GENERATOR ( des_pc1d, 0, 1, 2, 1, 1, 1, 0, 1, 5, 1, 4, 1, 3 ),
305};
306
307/**
308 * Generate DES permutation
309 *
310 * @v generator Generator
311 */
312static __attribute__ (( noinline )) void
313des_generate ( struct des_generator *generator ) {
314 uint8_t *permutation = generator->permutation;
315 uint32_t seed = generator->seed;
316 unsigned int index = 0;
317 uint8_t accum;
318 uint8_t bit;
319
320 /* Generate permutations
321 *
322 * This loop is optimised for code size on a
323 * register-constrained architecture such as i386.
324 */
325 do {
326 /* Rotate seed to access MSB's bit descriptor */
327 seed = ror32 ( seed, 8 );
328
329 /* Initialise accumulator with six flag bits */
330 accum = 0xfc;
331
332 /* Accumulate bits until all six flag bits are cleared */
333 do {
334 /* Extract specified bit from index. Use a
335 * rotation instead of a shift, since this
336 * will allow the mask to be elided.
337 */
338 bit = ror8 ( index, ( seed & 0x07 ) );
339 seed = ror32 ( seed, 3 );
340
341 /* Toggle bit if applicable */
342 bit ^= seed;
343 seed = ror32 ( seed, 1 );
344
345 /* Add bit to accumulator and clear one flag bit */
346 accum <<= 1;
347 accum |= ( bit & 0x01 );
348
349 } while ( accum & 0x80 );
350
351 /* Add constant offset if applicable */
352 accum += ( seed & 0x01 );
353
354 /* Store permutation */
355 permutation[index] = accum;
356
357 /* Loop until reaching length (which is always even) */
358 } while ( ++index < ( seed & 0xfe ) );
359 DBGC2 ( permutation, "DES generated permutation %p:\n", permutation );
361 ( ( seed & 0xfe ) + 1 /* zero terminator */ ) );
362}
363
364/**
365 * Initialise permutations
366 */
367static void des_init ( void ) {
368 unsigned int i;
369
370 /* Generate all generated permutations */
371 for ( i = 0 ; i < ( sizeof ( des_generators ) /
372 sizeof ( des_generators[0] ) ) ; i++ ) {
374 }
375}
376
377/** Initialisation function */
378struct init_fn des_init_fn __init_fn ( INIT_NORMAL ) = {
379 .name = "des",
380 .initialise = des_init,
381};
382
383/**
384 * Perform bit permutation
385 *
386 * @v permutation Bit permutation (zero-terminated)
387 * @v in Input value
388 * @v out Output value
389 */
390static void des_permute ( const uint8_t *permutation, const uint8_t *in,
391 uint8_t *out ) {
392 uint8_t mask = 0x80;
393 uint8_t accum = 0;
394 unsigned int bit;
395
396 /* Extract individual input bits to construct output value */
397 while ( ( bit = *(permutation++) ) ) {
398 bit--;
399 if ( in[ bit / 8 ] & ( 0x80 >> ( bit % 8 ) ) )
400 accum |= mask;
401 *out = accum;
402 mask = ror8 ( mask, 1 );
403 if ( mask == 0x80 ) {
404 out++;
405 accum = 0;
406 }
407 }
408}
409
410/**
411 * Perform DES S-box substitution
412 *
413 * @v in 32-bit input value (native endian)
414 * @v rkey 48-bit round key
415 * @ret out 32-bit output value (native endian)
416 */
417static uint32_t des_sbox ( uint32_t in, const union des_round_key *rkey ) {
418 uint32_t out = 0;
419 uint32_t lookup;
420 int32_t key;
421 uint8_t sub;
422 unsigned int i;
423
424 /* Perform input expansion, key addition, and S-box substitution */
425 for ( i = 0 ; i < 8 ; i++ ) {
426
427 /* Rotate input and output */
428 out = rol32 ( out, 4 );
429 in = rol32 ( in, 4 );
430
431 /* Extract step key from relevant 6 bits of round key
432 *
433 * The least significant of the 6 bits (corresponding
434 * to bit r0 in the S-box lookup index) is stored in
435 * the sign bit of the step key byte. It will
436 * therefore be propagated via sign extension to the
437 * MSB of the 32-bit step key.
438 *
439 * The remaining 5 of the 6 bits (corresponding to
440 * bits {r1,c3,c2,c1,c0} in the S-box lookup index)
441 * are stored in the least significant 5 bits of the
442 * step key byte and will end up in the least
443 * significant 5 bits of the 32-bit step key.
444 */
445 key = rkey->step[i];
446
447 /* Add step key to input to produce S-box lookup index
448 *
449 * We do not ever perform an explicit expansion of the
450 * input value from 32 to 48 bits. Instead, we rotate
451 * the 32-bit input value by 4 bits on each step, and
452 * extract the relevant 6 bits.
453 *
454 * The least significant of the 6 bits (corresponding
455 * to bit r0 in the S-box lookup index) is currently
456 * in the MSB of the 32-bit (rotated) input value.
457 *
458 * The remaining 5 of the 6 bits (corresponding to
459 * bits {r1,c3,c2,c1,c0} in the S-box lookup index)
460 * are currently in the least significant 5 bits of
461 * the 32-bit (rotated) input value.
462 *
463 * This aligns with the placement of the bits in the
464 * step key (see above), and we can therefore perform
465 * a single XOR to add the 6-bit step key to the
466 * relevant 6 bits of the input value.
467 */
468 lookup = ( in ^ key );
469
470 /* Look up S[i][in ^ key] from S-box
471 *
472 * We have bits {r1,c3,c2,c1,c0} in the least
473 * significant 5 bits of the lookup index, and so can
474 * use the masked lookup index directly as a byte
475 * index into the relevant S-box to extract the byte
476 * containing both {r1,c3,c2,c1,c0,'0'} and
477 * {r1,c3,c2,c1,c0,'1'}.
478 *
479 * We then use the MSB of the 32-bit lookup index to
480 * extract the relevant nibble for the full lookup
481 * index {r1,c3,c2,c1,c0,r0}.
482 */
483 sub = des_s[i][ lookup & 0x1f ];
484 sub >>= ( ( lookup >> 29 ) & 4 );
485 sub &= 0x0f;
486
487 /* Substitute S[i][input ^ key] into output */
488 out |= sub;
489 }
490
491 return out;
492}
493
494/**
495 * Perform a single DES round
496 *
497 * @v block DES block
498 * @v rkey 48-bit round key
499 */
500static void des_round ( union des_block *block,
501 const union des_round_key *rkey ) {
502 union des_dword sbox;
503 uint32_t left;
504 uint32_t right;
505
506 /* Extract left and right halves L[n-1] and R[n-1] */
507 left = block->left.dword;
508 right = block->right.dword;
509 DBGC2 ( block, "DES L=%08x R=%08x K=%08x%08x", be32_to_cpu ( left ),
510 be32_to_cpu ( right ), be32_to_cpu ( rkey->dword[0] ),
511 be32_to_cpu ( rkey->dword[1] ) );
512
513 /* L[n] = R[n-1] */
514 block->left.dword = right;
515
516 /* Calculate Feistel function f(R[n-1], K[n]) */
517 sbox.dword = cpu_to_be32 ( des_sbox ( be32_to_cpu ( right ), rkey ) );
518 des_permute ( des_p, sbox.byte, block->right.byte );
519
520 /* R[n] = L[n-1] + f(R[n-1], K[n]) */
521 block->right.dword ^= left;
522 DBGC2 ( block, " => L=%08x R=%08x\n",
523 be32_to_cpu ( block->left.dword ),
524 be32_to_cpu ( block->right.dword ) );
525}
526
527/**
528 * Perform all DES rounds
529 *
530 * @v in Input DES block
531 * @v out Output DES block
532 * @v rkey Starting 48-bit round key
533 * @v offset Byte offset between round keys
534 */
535static void des_rounds ( const union des_block *in, union des_block *out,
536 const union des_round_key *rkey,
537 ssize_t offset ) {
538 union des_block tmp;
539 unsigned int i;
540
541 /* Apply initial permutation */
542 des_permute ( des_ip, in->byte, tmp.byte );
543
544 /* Perform all DES rounds, consuming keys in the specified order */
545 for ( i = 0 ; i < DES_ROUNDS ; i++ ) {
546 des_round ( &tmp, rkey );
547 rkey = ( ( ( void * ) rkey ) + offset );
548 }
549
550 /* Apply final permutation */
551 DBGC ( &tmp, "DES %scrypted %08x%08x => ",
552 ( ( offset > 0 ) ? "en" : "de" ), be32_to_cpu ( in->dword[0] ),
553 be32_to_cpu ( in->dword[1] ) );
554 des_permute ( des_fp, tmp.byte, out->byte );
555 DBGC ( &tmp, "%08x%08x\n", be32_to_cpu ( out->dword[0] ),
556 be32_to_cpu ( out->dword[1] ) );
557}
558
559/**
560 * Rotate 28-bit word
561 *
562 * @v dword 28-bit dword value
563 * @ret dword Rotated 28-bit dword value
564 */
566 int32_t sdword;
567
568 /* Convert to native-endian */
569 sdword = be32_to_cpu ( dword );
570
571 /* Signed shift right by 4 places to copy bit 31 to bits 27:31 */
572 sdword >>= 4;
573
574 /* Rotate left */
575 sdword = rol32 ( sdword, 1 );
576
577 /* Shift left by 4 places to restore bit positions */
578 sdword <<= 4;
579
580 /* Convert back to big-endian */
581 dword = cpu_to_be32 ( sdword );
582
583 return dword;
584}
585
586/**
587 * Set key
588 *
589 * @v cipher Cipher algorithm
590 * @v ctx Context
591 * @v key Key
592 * @v keylen Key length
593 * @ret rc Return status code
594 */
595static int des_setkey ( struct cipher_algorithm *cipher __unused, void *ctx,
596 const void *key, size_t keylen ) {
597 struct des_context *des = ctx;
598 union des_round_key *rkey = des->rkey;
599 union des_block reg;
600 uint32_t schedule;
601
602 /* Validate key length */
603 if ( keylen != DES_BLOCKSIZE )
604 return -EINVAL;
605 DBGC ( des, "DES %p new key:\n", des );
606 DBGC_HDA ( des, 0, key, keylen );
607
608 /* Apply permuted choice 1 */
609 des_permute ( des_pc1c, key, reg.c.byte );
610 des_permute ( des_pc1d, key, reg.d.byte );
611 reg.d.byte[3] <<= 4; /* see comment for @c des_pc1d */
612 DBGC2 ( des, "DES %p C[ 0]=%07x D[ 0]=%07x\n",
613 des, ( be32_to_cpu ( reg.c.dword ) >> 4 ),
614 ( be32_to_cpu ( reg.d.dword ) >> 4 ) );
615
616 /* Generate round keys */
617 for ( schedule = DES_SCHEDULE ; schedule ; schedule >>= 1 ) {
618
619 /* Shift 28-bit words */
620 reg.c.dword = des_rol28 ( reg.c.dword );
621 reg.d.dword = des_rol28 ( reg.d.dword );
622
623 /* Skip rounds according to shift schedule */
624 if ( ! ( schedule & 1 ) )
625 continue;
626
627 /* Apply permuted choice 2 */
628 des_permute ( des_pc2, reg.byte, rkey->byte );
629 DBGC2 ( des, "DES %p C[%2zd]=%07x D[%2zd]=%07x K[%2zd]="
630 "%08x%08x\n", des, ( ( rkey - des->rkey ) + 1 ),
631 ( be32_to_cpu ( reg.c.dword ) >> 4 ),
632 ( ( rkey - des->rkey ) + 1 ),
633 ( be32_to_cpu ( reg.d.dword ) >> 4 ),
634 ( ( rkey - des->rkey ) + 1 ),
635 be32_to_cpu ( rkey->dword[0] ),
636 be32_to_cpu ( rkey->dword[1] ) );
637
638 /* Move to next key */
639 rkey++;
640 }
641
642 /* Sanity check */
643 assert ( rkey == &des->rkey[DES_ROUNDS] );
644
645 return 0;
646}
647
648/**
649 * Encrypt data
650 *
651 * @v cipher Cipher algorithm
652 * @v ctx Context
653 * @v src Data to encrypt
654 * @v dst Buffer for encrypted data
655 * @v len Length of data
656 */
657static void des_encrypt ( struct cipher_algorithm *cipher __unused, void *ctx,
658 const void *src, void *dst, size_t len ) {
659 struct des_context *des = ctx;
660
661 /* Sanity check */
662 assert ( len == DES_BLOCKSIZE );
663
664 /* Cipher using keys in forward direction */
665 des_rounds ( src, dst, &des->rkey[0], sizeof ( des->rkey[0] ) );
666}
667
668/**
669 * Decrypt data
670 *
671 * @v cipher Cipher algorithm
672 * @v ctx Context
673 * @v src Data to decrypt
674 * @v dst Buffer for decrypted data
675 * @v len Length of data
676 */
677static void des_decrypt ( struct cipher_algorithm *cipher __unused, void *ctx,
678 const void *src, void *dst, size_t len ) {
679 struct des_context *des = ctx;
680
681 /* Sanity check */
682 assert ( len == DES_BLOCKSIZE );
683
684 /* Cipher using keys in reverse direction */
685 des_rounds ( src, dst, &des->rkey[ DES_ROUNDS - 1 ],
686 -sizeof ( des->rkey[0] ) );
687}
688
689/** Basic DES algorithm */
691 .name = "des",
692 .ctxsize = sizeof ( struct des_context ),
693 .blocksize = DES_BLOCKSIZE,
694 .alignsize = 0,
695 .authsize = 0,
696 .confidential = 1,
697 .setkey = des_setkey,
698 .setiv = cipher_null_setiv,
699 .encrypt = des_encrypt,
700 .decrypt = des_decrypt,
701 .auth = cipher_null_auth,
702};
703
704/* DES in Electronic Codebook mode */
707
708/* DES in Cipher Block Chaining mode */
struct golan_eq_context ctx
Definition CIB_PRM.h:0
__be32 out[4]
Definition CIB_PRM.h:8
__be32 in[4]
Definition CIB_PRM.h:7
union @162305117151260234136356364136041353210355154177 key
unsigned int uint32_t
Definition stdint.h:12
signed int int32_t
Definition stdint.h:17
unsigned char uint8_t
Definition stdint.h:10
signed long ssize_t
Definition stdint.h:7
long index
Definition bigint.h:30
static const void * src
Definition string.h:48
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
uint16_t offset
Offset to command line.
Definition bzimage.h:3
Cipher-block chaining.
#define CBC_CIPHER(_cbc_name, _cbc_cipher, _raw_cipher, _raw_context, _blocksize)
Create a cipher-block chaining mode of behaviour of an existing cipher.
Definition cbc.h:40
int cipher_null_setiv(struct cipher_algorithm *cipher __unused, void *ctx __unused, const void *iv __unused, size_t ivlen __unused)
Definition crypto_null.c:70
void cipher_null_auth(struct cipher_algorithm *cipher __unused, void *ctx __unused, void *auth __unused)
Definition crypto_null.c:89
#define DES_GENERATOR(PERMUTATION, OFFSET, INV5, BIT5, INV4, BIT4, INV3, BIT3, INV2, BIT2, INV1, BIT1, INV0, BIT0)
Define a DES permutation generator.
Definition des.c:215
static uint32_t des_sbox(uint32_t in, const union des_round_key *rkey)
Perform DES S-box substitution.
Definition des.c:417
static void des_init(void)
Initialise permutations.
Definition des.c:367
static uint32_t des_rol28(uint32_t dword)
Rotate 28-bit word.
Definition des.c:565
static void des_permute(const uint8_t *permutation, const uint8_t *in, uint8_t *out)
Perform bit permutation.
Definition des.c:390
#define SBOX(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf, y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, ya, yb, yc, yd, ye, yf)
Define a row pair in a DES S-box.
Definition des.c:96
static uint8_t des_pc1c[29]
DES permuted choice 1 (PC1) "C" register.
Definition des.c:236
static const uint8_t des_s[8][32]
DES S-boxes S1..S8.
Definition des.c:104
static const uint8_t des_p[33]
DES data permutation (P).
Definition des.c:258
static void des_encrypt(struct cipher_algorithm *cipher __unused, void *ctx, const void *src, void *dst, size_t len)
Encrypt data.
Definition des.c:657
static void des_decrypt(struct cipher_algorithm *cipher __unused, void *ctx, const void *src, void *dst, size_t len)
Decrypt data.
Definition des.c:677
static void des_round(union des_block *block, const union des_round_key *rkey)
Perform a single DES round.
Definition des.c:500
struct cipher_algorithm des_algorithm
Basic DES algorithm.
Definition des.c:690
static struct des_generator des_generators[]
DES permutation generators.
Definition des.c:268
static void des_generate(struct des_generator *generator)
Generate DES permutation.
Definition des.c:313
#define DES_SCHEDULE
DES shift schedule.
Definition des.c:68
static int des_setkey(struct cipher_algorithm *cipher __unused, void *ctx, const void *key, size_t keylen)
Set key.
Definition des.c:595
#define DES_PC2R(r1, c3, c2, c1, c0, r0)
Define six bits of permuted choice 2 (PC2).
Definition des.c:182
static uint8_t des_pc1d[33]
DES permuted choice 1 (PC1) "D" register.
Definition des.c:239
static uint8_t des_fp[65]
DES final / inverse initial permutation (FP / IP^-1).
Definition des.c:265
static uint8_t des_ip[65]
DES initial permutation (IP).
Definition des.c:255
static const uint8_t des_pc2[65]
DES permuted choice 2 (PC2).
Definition des.c:242
static void des_rounds(const union des_block *in, union des_block *out, const union des_round_key *rkey, ssize_t offset)
Perform all DES rounds.
Definition des.c:535
DES algorithm.
#define DES_BLOCKSIZE
DES blocksize.
Definition des.h:50
#define DES_ROUNDS
Number of DES rounds.
Definition des.h:77
struct cipher_algorithm des_cbc_algorithm
struct cipher_algorithm des_ecb_algorithm
ring len
Length.
Definition dwmac.h:226
Electronic codebook (ECB).
#define ECB_CIPHER(_ecb_name, _ecb_cipher, _raw_cipher, _raw_context, _blocksize)
Create an electronic codebook mode of behaviour of an existing cipher.
Definition ecb.h:31
Error codes.
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:598
#define DBGC2(...)
Definition compiler.h:547
#define DBGC2_HDA(...)
Definition compiler.h:548
#define DBGC(...)
Definition compiler.h:530
#define DBGC_HDA(...)
Definition compiler.h:531
#define INIT_NORMAL
Normal initialisation.
Definition init.h:32
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define EINVAL
Invalid argument.
Definition errno.h:472
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
#define be32_to_cpu(value)
Definition byteswap.h:117
#define cpu_to_be32(value)
Definition byteswap.h:111
#define __attribute__(x)
Definition compiler.h:10
static unsigned int unsigned int bit
Definition bigint.h:390
Cryptographic API.
String functions.
#define __init_fn(init_order)
Declare an initialisation functon.
Definition init.h:24
unsigned long tmp
Definition linux_pci.h:65
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
static unsigned int unsigned int reg
Definition myson.h:162
Bit operations.
unsigned long int dword
Definition smc9000.h:40
A cipher algorithm.
Definition crypto.h:58
DES context.
Definition des.h:80
union des_round_key rkey[DES_ROUNDS]
Round keys.
Definition des.h:82
A DES systematic permutation generator.
Definition des.c:199
uint32_t seed
Seed value.
Definition des.c:203
uint8_t * permutation
Permutation.
Definition des.c:201
An initialisation function.
Definition init.h:15
A DES 64-bit block.
Definition des.h:28
A DES 32-bit dword value.
Definition des.h:20
uint8_t byte[4]
Raw bytes.
Definition des.h:22
uint32_t dword
32-bit big-endian dword
Definition des.h:24
A DES round key.
Definition des.h:57
uint32_t dword[2]
32-bit big-endian dwords
Definition des.h:61
uint8_t byte[8]
Raw bytes.
Definition des.h:59
int8_t step[8]
6-bit step key byte
Definition des.h:73
static u32 ror32(u32 v, int bits)
Rotate 32-bit value right.
Definition wpa_tkip.c:162
static u32 rol32(u32 v, int bits)
Rotate 32-bit value left.
Definition wpa_tkip.c:174