Fix API.
[shishi.git] / crypto / des.c
blobc9f294c24f9f5775a677a74a1d28fda526d2c43f
1 /* des.c
3 * The des block cipher.
5 * $Id$
6 */
8 /* nettle, low-level cryptographics library
10 * Copyright (C) 2001 Niels Möller
12 * The nettle library is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License as published by
14 * the Free Software Foundation; either version 2.1 of the License, or (at your
15 * option) any later version.
17 * The nettle library is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
20 * License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with the nettle library; see the file COPYING.LIB. If not, write to
24 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * MA 02111-1307, USA.
28 /* des - fast & portable DES encryption & decryption.
29 * Copyright (C) 1992 Dana L. How
30 * Please see the file `descore.README' for the complete copyright notice.
33 #if HAVE_CONFIG_H
34 # include "config.h"
35 #endif
37 #include <assert.h>
39 #include "des.h"
41 #include "desCode.h"
43 /* various tables */
45 static const uint32_t
46 des_keymap[] = {
47 #include "keymap.h"
50 static const uint8_t
51 rotors[] = {
52 #include "rotors.h"
55 static const char
56 parity[] = {
57 #include "parity.h"
60 static ENCRYPT(DesSmallFipsEncrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS)
61 static DECRYPT(DesSmallFipsDecrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS)
63 void
64 des_fix_parity(unsigned length, uint8_t *dst,
65 const uint8_t *src)
67 unsigned i;
68 for (i = 0; i<length; i++)
69 dst[i] = src[i] ^ (parity[src[i]] == 8);
72 int
73 des_set_key(struct des_ctx *ctx, const uint8_t *key)
75 register uint32_t n, w;
76 register char * b0, * b1;
77 char bits0[56], bits1[56];
78 uint32_t *method;
79 const uint8_t *k;
82 register const char *b;
83 /* check for bad parity and weak keys */
84 b = parity;
85 n = b[key[0]]; n <<= 4;
86 n |= b[key[1]]; n <<= 4;
87 n |= b[key[2]]; n <<= 4;
88 n |= b[key[3]]; n <<= 4;
89 n |= b[key[4]]; n <<= 4;
90 n |= b[key[5]]; n <<= 4;
91 n |= b[key[6]]; n <<= 4;
92 n |= b[key[7]];
93 w = 0x88888888l;
96 /* report bad parity in key */
97 if ( n & w )
99 ctx->status = DES_BAD_PARITY;
100 return 0;
102 ctx->status = DES_OK;
104 /* report a weak or semi-weak key */
105 if ( !((n - (w >> 3)) & w) ) { /* 1 in 10^10 keys passes this test */
106 if ( n < 0X41415151 ) {
107 if ( n < 0X31312121 ) {
108 if ( n < 0X14141515 ) {
109 /* 01 01 01 01 01 01 01 01 */
110 if ( n == 0X11111111 ) goto weak;
111 /* 01 1F 01 1F 01 0E 01 0E */
112 if ( n == 0X13131212 ) goto weak;
113 } else {
114 /* 01 E0 01 E0 01 F1 01 F1 */
115 if ( n == 0X14141515 ) goto weak;
116 /* 01 FE 01 FE 01 FE 01 FE */
117 if ( n == 0X16161616 ) goto weak;
119 } else {
120 if ( n < 0X34342525 ) {
121 /* 1F 01 1F 01 0E 01 0E 01 */
122 if ( n == 0X31312121 ) goto weak;
123 /* 1F 1F 1F 1F 0E 0E 0E 0E */ /* ? */
124 if ( n == 0X33332222 ) goto weak;
125 } else {
126 /* 1F E0 1F E0 0E F1 0E F1 */
127 if ( n == 0X34342525 ) goto weak;
128 /* 1F FE 1F FE 0E FE 0E FE */
129 if ( n == 0X36362626 ) goto weak;
132 } else {
133 if ( n < 0X61616161 ) {
134 if ( n < 0X44445555 ) {
135 /* E0 01 E0 01 F1 01 F1 01 */
136 if ( n == 0X41415151 ) goto weak;
137 /* E0 1F E0 1F F1 0E F1 0E */
138 if ( n == 0X43435252 ) goto weak;
139 } else {
140 /* E0 E0 E0 E0 F1 F1 F1 F1 */ /* ? */
141 if ( n == 0X44445555 ) goto weak;
142 /* E0 FE E0 FE F1 FE F1 FE */
143 if ( n == 0X46465656 ) goto weak;
145 } else {
146 if ( n < 0X64646565 ) {
147 /* FE 01 FE 01 FE 01 FE 01 */
148 if ( n == 0X61616161 ) goto weak;
149 /* FE 1F FE 1F FE 0E FE 0E */
150 if ( n == 0X63636262 ) goto weak;
151 } else {
152 /* FE E0 FE E0 FE F1 FE F1 */
153 if ( n == 0X64646565 ) goto weak;
154 /* FE FE FE FE FE FE FE FE */
155 if ( n == 0X66666666 )
157 weak:
158 ctx->status = DES_WEAK_KEY;
165 /* NOTE: We go on and expand the key, even if it was weak */
166 /* explode the bits */
167 n = 56;
168 b0 = bits0;
169 b1 = bits1;
170 do {
171 w = (256 | *key++) << 2;
172 do {
173 --n;
174 b1[n] = 8 & w;
175 w >>= 1;
176 b0[n] = 4 & w;
177 } while ( w >= 16 );
178 } while ( n );
180 /* put the bits in the correct places */
181 n = 16;
182 k = rotors;
183 method = ctx->key;
185 do {
186 w = (b1[k[ 0 ]] | b0[k[ 1 ]]) << 4;
187 w |= (b1[k[ 2 ]] | b0[k[ 3 ]]) << 2;
188 w |= b1[k[ 4 ]] | b0[k[ 5 ]];
189 w <<= 8;
190 w |= (b1[k[ 6 ]] | b0[k[ 7 ]]) << 4;
191 w |= (b1[k[ 8 ]] | b0[k[ 9 ]]) << 2;
192 w |= b1[k[10 ]] | b0[k[11 ]];
193 w <<= 8;
194 w |= (b1[k[12 ]] | b0[k[13 ]]) << 4;
195 w |= (b1[k[14 ]] | b0[k[15 ]]) << 2;
196 w |= b1[k[16 ]] | b0[k[17 ]];
197 w <<= 8;
198 w |= (b1[k[18 ]] | b0[k[19 ]]) << 4;
199 w |= (b1[k[20 ]] | b0[k[21 ]]) << 2;
200 w |= b1[k[22 ]] | b0[k[23 ]];
202 method[0] = w;
204 w = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
205 w |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
206 w |= b1[k[ 4+24]] | b0[k[ 5+24]];
207 w <<= 8;
208 w |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
209 w |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
210 w |= b1[k[10+24]] | b0[k[11+24]];
211 w <<= 8;
212 w |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
213 w |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
214 w |= b1[k[16+24]] | b0[k[17+24]];
215 w <<= 8;
216 w |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
217 w |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
218 w |= b1[k[22+24]] | b0[k[23+24]];
220 ROR(w, 4, 28); /* could be eliminated */
221 method[1] = w;
223 k += 48;
224 method += 2;
225 } while ( --n );
227 return (ctx->status == DES_OK);
230 void
231 des_encrypt(struct des_ctx *ctx,
232 unsigned length, uint8_t *dst,
233 const uint8_t *src)
235 assert(!(length % DES_BLOCK_SIZE));
236 assert(ctx->status == DES_OK);
238 while (length)
240 DesSmallFipsEncrypt(dst, ctx->key, src);
241 length -= DES_BLOCK_SIZE;
242 src += DES_BLOCK_SIZE;
243 dst += DES_BLOCK_SIZE;
247 void
248 des_decrypt(struct des_ctx *ctx,
249 unsigned length, uint8_t *dst,
250 const uint8_t *src)
252 assert(!(length % DES_BLOCK_SIZE));
253 assert(ctx->status == DES_OK);
255 while (length)
257 DesSmallFipsDecrypt(dst, ctx->key, src);
258 length -= DES_BLOCK_SIZE;
259 src += DES_BLOCK_SIZE;
260 dst += DES_BLOCK_SIZE;