perftest: Document the `-q' option for disabling checking.
[u/mdw/catacomb] / des.c
CommitLineData
d03ab969 1/* -*-c-*-
2 *
986527ae 3 * $Id$
d03ab969 4 *
5 * The Data Encryption Standard
6 *
7 * (c) 1999 Straylight/Edgeware
8 */
9
45c0fd36 10/*----- Licensing notice --------------------------------------------------*
d03ab969 11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
45c0fd36 18 *
d03ab969 19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
45c0fd36 23 *
d03ab969 24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
d03ab969 30/*----- Header files ------------------------------------------------------*/
31
32#include <assert.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36
37#include <mLib/bits.h>
38
39#include "blkc.h"
40#include "des-base.h"
41#include "des.h"
89ae755d 42#include "gcipher.h"
43
44/*----- Global variables --------------------------------------------------*/
45
46const octet des_keysz[] = { KSZ_SET, 7, 8, 0 };
d03ab969 47
48/*----- Main code ---------------------------------------------------------*/
49
50/* --- @permute@ --- *
51 *
52 * Arguments: @const char *p@ = pointer to permutation table
53 * @uint32 a, b@ = source value to permute
54 * @uint32 *d@ = destination for value
55 *
56 * Returns: ---
57 *
58 * Use: Performs a 64-bit permutation. The table is given in the
59 * normal (but bizarre) DES bit numbering system. That's not to
60 * say that the tables in this source file are like the normal
61 * DES tables, because they're not.
62 */
63
64static void permute(const char *p, uint32 a, uint32 b, uint32 *d)
65{
66 uint32 x = 0, y = 0;
67 int i;
68
69 for (i = 0; i < 32; i++) {
70 int q = p[i];
71 uint32 t;
72 if (!q)
73 continue;
74 else if (q <= 32)
75 t = a;
76 else {
77 t = b;
78 q -= 32;
79 }
80 if (t & (1 << (32 - q)))
81 x |= (1 << (31 - i));
82 }
83
84 p += 32;
85
86 for (i = 0; i < 32; i++) {
87 int q = p[i];
88 uint32 t;
89 if (!q)
90 continue;
91 else if (q <= 32)
92 t = a;
93 else {
94 t = b;
95 q -= 32;
96 }
97 if (t & (1 << (32 - q)))
98 y |= (1 << (31 - i));
99 }
100
101 d[0] = x;
102 d[1] = y;
103}
104
986527ae 105/* --- @des_expand@ --- *
106 *
107 * Arguments: @const octet *k@ = pointer to key material
108 * @size_t n@ = number of octets of key material (7 or 8)
109 * @uint32 *xx, *yy@ = where to put the results
110 *
111 * Returns: ---
112 *
113 * Use: Extracts 64 bits of key material from the given buffer,
114 * possibly expanding it from 56 to 64 bits on the way.
115 * Parity is set correctly if the key is expanded.
116 */
117
118void des_expand(const octet *k, size_t n, uint32 *xx, uint32 *yy)
119{
120 uint32 x, y, z;
121
122 if (n == 8) {
123 x = LOAD32(k + 0);
124 y = LOAD32(k + 4);
125 } else {
126 x = LOAD32(k + 0);
127 x = (x & 0xfe000000) | ((x & 0x01fffff0) >> 1);
128 x = (x & 0xfffe0000) | ((x & 0x0001fff8) >> 1);
129 x = (x & 0xfffffe00) | ((x & 0x000001fc) >> 1);
130 z = x; z ^= z >> 4; z ^= z >> 2; z ^= z >> 1;
131 x |= (z & 0x01010101) ^ 0x01010101;
132 y = LOAD32(k + 3) << 1; /* Note: misaligned */
133 y = (y & 0x000000fe) | ((y & 0x1fffff00) << 1);
134 y = (y & 0x0000fefe) | ((y & 0x3fff0000) << 1);
135 y = (y & 0x00fefefe) | ((y & 0x7f000000) << 1);
136 z = y; z ^= z >> 4; z ^= z >> 2; z ^= z >> 1;
137 y |= (z & 0x01010101) ^ 0x01010101;
138 }
139 *xx = x; *yy = y;
140}
141
d03ab969 142/* --- @des_init@ --- *
143 *
144 * Arguments: @des_ctx *k@ = pointer to key block
145 * @const void *buf@ = pointer to key buffer
146 * @size_t sz@ = size of key material
147 *
148 * Returns: ---
149 *
150 * Use: Initializes a DES key buffer. The key buffer may be either 7
151 * or 8 bytes long. If it's 8 bytes, the key is assumed to be
152 * padded with parity bits in the low order bit of each octet.
153 * These are stripped out without checking prior to the actual
154 * key scheduling.
155 */
156
157void des_init(des_ctx *k, const void *buf, size_t sz)
158{
159 uint32 x, y;
160 uint32 *kp = k->k;
986527ae 161 uint32 ka[2];
d03ab969 162 int i;
163
164 /* --- @pc1@ --- *
165 *
166 * This cryptographically useless permutation is used to mangle the key
167 * before it's subjected to the key schedule proper. I've not actually
168 * messed it about much except for inserting padding at the beginning of
169 * the two halves of the key.
170 */
171
172 static const char pc1[] = {
45c0fd36 173 0, 0, 0, 0,
d03ab969 174 57, 49, 41, 33, 25, 17, 9,
175 1, 58, 50, 42, 34, 26, 18,
45c0fd36 176 10, 2, 59, 51, 43, 35, 27,
d03ab969 177 19, 11, 3, 60, 52, 44, 36,
45c0fd36 178 0, 0, 0, 0,
d03ab969 179 63, 55, 47, 39, 31, 23, 15,
180 7, 62, 54, 46, 38, 30, 22,
45c0fd36 181 14, 6, 61, 53, 45, 37, 29,
d03ab969 182 21, 13, 5, 28, 20, 12, 4
183 };
184
185 /* --- @pc2@ --- *
186 *
187 * This irritating but necessary permutation mangles the key between the
188 * simple rotation-based schedule and the actual XOR with which it modifies
189 * the behaviour of the cipher.
190 *
191 * This version of the table doesn't look much like the original. This is
192 * because some parts of the world have been permuted in order to make
193 * things simpler for the round function. In particular, everything is
194 * rotated left one place to avoid problems with the wraparound of the
195 * expansion permutation, and the key is split between odd and even S-boxes
196 * rather than high and low ones. That's without the complication of the
197 * padding bits in the representation of the 56-bit proto-key.
198 */
199
200 static const char pc2[] = {
45c0fd36
MW
201 0, 0, 3 + 4, 28 + 4, 15 + 4, 6 + 4, 21 + 4, 10 + 4, /* S-box 2 */
202 0, 0, 16 + 4, 7 + 4, 27 + 4, 20 + 4, 13 + 4, 2 + 4, /* S-box 4 */
203 0, 0, 30 + 8, 40 + 8, 51 + 8, 45 + 8, 33 + 8, 48 + 8, /* S-box 6 */
204 0, 0, 46 + 8, 42 + 8, 50 + 8, 36 + 8, 29 + 8, 32 + 8, /* S-box 8 */
205 0, 0, 14 + 4, 17 + 4, 11 + 4, 24 + 4, 1 + 4, 5 + 4, /* S-box 1 */
206 0, 0, 23 + 4, 19 + 4, 12 + 4, 4 + 4, 26 + 4, 8 + 4, /* S-box 3 */
207 0, 0, 41 + 8, 52 + 8, 31 + 8, 37 + 8, 47 + 8, 55 + 8, /* S-box 5 */
208 0, 0, 44 + 8, 49 + 8, 39 + 8, 56 + 8, 34 + 8, 53 + 8 /* S-box 7 */
d03ab969 209 };
210
211 /* --- @v@ --- *
212 *
213 * Contains the rotation amounts for the key halves.
214 */
215
216 static const char v[] = {
217 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
218 };
219
220 /* --- Extract the key into my registers --- *
221 *
222 * The 7 byte case is rather horrible. It expands the key to the 8 byte
223 * case before going any further. It could probably do with its own @pc1@
224 * table.
225 */
226
89ae755d 227 KSZ_ASSERT(des, sz);
986527ae 228 des_expand(buf, sz, &x, &y);
45c0fd36 229
d03ab969 230 /* --- Permute using the pointless PC1 --- */
231
986527ae 232 permute(pc1, x, y, ka);
233 x = ka[0]; y = ka[1];
d03ab969 234
235 /* --- Now for the key schedule proper --- */
236
237 for (i = 0; i < 16; i++) {
238 if (v[i] == 1) {
239 x = ((x << 1) | (x >> 27)) & 0x0fffffff;
240 y = ((y << 1) | (y >> 27)) & 0x0fffffff;
241 } else {
242 x = ((x << 2) | (x >> 26)) & 0x0fffffff;
243 y = ((y << 2) | (y >> 26)) & 0x0fffffff;
244 }
245 permute(pc2, x, y, kp);
246 kp += 2;
247 }
248}
249
250/* --- @des_eblk@, @des_dblk@ --- *
251 *
252 * Arguments: @const des_ctx *k@ = pointer to key block
253 * @const uint32 s[2]@ = pointer to source block
254 * @uint32 d[2]@ = pointer to destination block
255 *
256 * Returns: ---
257 *
258 * Use: Low-level block encryption and decryption.
259 */
260
261void des_eblk(const des_ctx *k, const uint32 *s, uint32 *d)
262{
263 uint32 x = s[0], y = s[1];
264 DES_IP(x, y);
265 DES_EBLK(k->k, x, y, x, y);
266 DES_IPINV(x, y);
267 d[0] = x, d[1] = y;
268}
269
270void des_dblk(const des_ctx *k, const uint32 *s, uint32 *d)
271{
272 uint32 x = s[0], y = s[1];
273 DES_IP(x, y);
274 DES_DBLK(k->k, x, y, x, y);
275 DES_IPINV(x, y);
276 d[0] = x, d[1] = y;
277}
278
279BLKC_TEST(DES, des)
280
281/*----- That's all, folks -------------------------------------------------*/