chiark / gitweb /
configure.ac: Replace with a new version.
[catacomb] / desx.c
1 /* -*-c-*-
2  *
3  * $Id$
4  *
5  * Implementation of DESX
6  *
7  * (c) 2001 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------*
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.
18  *
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.
23  *
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
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"
42 #include "desx.h"
43 #include "desx-tab.h"
44 #include "gcipher.h"
45
46 /*----- Tables ------------------------------------------------------------*/
47
48 static const octet s[256] = DESX_S;
49
50 /*----- Global variables --------------------------------------------------*/
51
52 const octet desx_keysz[] = { KSZ_SET, 23, 7, 8, 15, 16, 24, 0 };
53
54 /*----- Main code ---------------------------------------------------------*/
55
56 /* --- @desx_init@ --- *
57  *
58  * Arguments:   @desx_ctx *k@ = pointer to key block
59  *              @const void *buf@ = pointer to key buffer
60  *              @size_t sz@ = size of key material
61  *
62  * Returns:     ---
63  *
64  * Use:         Initializes a DESX key buffer.  The key buffer contains, in
65  *              order, a single-DES key (either 7 or 8 bytes), an optional
66  *              8-byte pre-whitening key, and an optional 8-byte
67  *              port-whitening key.  If no whitening keys are specified, the
68  *              algorithm becomes the same as single-DES.
69  */
70
71 static void mangle(octet *b, const octet *p)
72 {
73   unsigned i;
74
75   for (i = 0; i < 8; i++)
76     b[i] = *p++ ^ s[b[i] ^ b[(i + 1) & 7u]];
77 }
78
79 void desx_init(desx_ctx *k, const void *buf, size_t sz)
80 {
81   const octet *p = buf, *kk = buf;
82   size_t n;
83
84   KSZ_ASSERT(desx, sz);
85
86   n = sz % 8 == 7 ? 7 : 8;
87   des_init(&k->k, p, n);
88   p += n;
89   sz -= n;
90   if (!sz)
91     k->prea = k->preb = k->posta = k->postb = 0;
92   else {
93     const octet *q = p;
94     k->prea = LOAD32(q + 0);
95     k->preb = LOAD32(q + 4);
96     p += 8;
97     sz -= 8;
98     if (sz) {
99       k->posta = LOAD32(p + 0);
100       k->postb = LOAD32(p + 4);
101     } else {
102       octet b[16];
103       uint32 x, y;
104
105       des_expand(kk, n, &x, &y);
106       STORE32(b + 8, x); STORE32(b + 12, y);
107       memset(b, 0, 8);
108       mangle(b, b + 8);
109       mangle(b, q);
110       k->posta = LOAD32(b + 0);
111       k->postb = LOAD32(b + 4);
112     }
113   }
114 }
115
116 /* --- @desx_eblk@, @desx_dblk@ --- *
117  *
118  * Arguments:   @const desx_ctx *k@ = pointer to key block
119  *              @const uint32 s[2]@ = pointer to source block
120  *              @uint32 d[2]@ = pointer to destination block
121  *
122  * Returns:     ---
123  *
124  * Use:         Low-level block encryption and decryption.
125  */
126
127 void desx_eblk(const desx_ctx *k, const uint32 *s, uint32 *d)
128 {
129   uint32 x = s[0], y = s[1];
130   x ^= k->prea; y ^= k->preb;
131   DES_IP(x, y);
132   DES_EBLK(k->k.k, x, y, x, y);
133   DES_IPINV(x, y);
134   x ^= k->posta; y ^= k->postb;
135   d[0] = x, d[1] = y;
136 }
137
138 void desx_dblk(const desx_ctx *k, const uint32 *s, uint32 *d)
139 {
140   uint32 x = s[0], y = s[1];
141   x ^= k->posta; y ^= k->postb;
142   DES_IP(x, y);
143   DES_DBLK(k->k.k, x, y, x, y);
144   DES_IPINV(x, y);
145   x ^= k->prea; y ^= k->preb;
146   d[0] = x, d[1] = y;
147 }
148
149 BLKC_TEST(DESX, desx)
150
151 /*----- That's all, folks -------------------------------------------------*/