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