aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-10-08 22:13:40 +0000
committerlloyd <[email protected]>2008-10-08 22:13:40 +0000
commit28679b8b8efd4b09c272ec582982f2d8ca2ee722 (patch)
tree88d01d3f6a708d8240ec8dc2a186fcfbe34999c9
parent611172dec170835a2ce8b9379dd9b2b9d3e0681b (diff)
Move DESX into desx.h and desx.cpp
Clean up DES implementation internals.
-rw-r--r--src/cipher/des/des.cpp306
-rw-r--r--src/cipher/des/des.h55
-rw-r--r--src/cipher/des/des_tab.cpp24
-rw-r--r--src/cipher/des/desx.cpp41
-rw-r--r--src/cipher/des/desx.h33
-rw-r--r--src/cipher/des/info.txt2
-rw-r--r--src/core/libstate/def_alg.cpp1
7 files changed, 261 insertions, 201 deletions
diff --git a/src/cipher/des/des.cpp b/src/cipher/des/des.cpp
index d09752854..53a1a278e 100644
--- a/src/cipher/des/des.cpp
+++ b/src/cipher/des/des.cpp
@@ -1,129 +1,23 @@
/*************************************************
* DES Source File *
-* (C) 1999-2007 Jack Lloyd *
+* (C) 1999-2008 Jack Lloyd *
*************************************************/
#include <botan/des.h>
#include <botan/loadstor.h>
-#include <botan/xor_buf.h>
namespace Botan {
-/*************************************************
-* DES Encryption *
-*************************************************/
-void DES::enc(const byte in[], byte out[]) const
- {
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
-
- IP(L, R);
- raw_encrypt(L, R);
- FP(L, R);
-
- store_be(out, R, L);
- }
-
-/*************************************************
-* DES Decryption *
-*************************************************/
-void DES::dec(const byte in[], byte out[]) const
- {
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
-
- IP(L, R);
- raw_decrypt(L, R);
- FP(L, R);
-
- store_be(out, R, L);
- }
-
-/*************************************************
-* DES Initial Permutation *
-*************************************************/
-void DES::IP(u32bit& L, u32bit& R)
- {
- u64bit T = (IPTAB1[get_byte(0, L)] ) | (IPTAB1[get_byte(1, L)] << 1) |
- (IPTAB1[get_byte(2, L)] << 2) | (IPTAB1[get_byte(3, L)] << 3) |
- (IPTAB1[get_byte(0, R)] << 4) | (IPTAB1[get_byte(1, R)] << 5) |
- (IPTAB1[get_byte(2, R)] << 6) | (IPTAB2[get_byte(3, R)] );
- L = static_cast<u32bit>(T >> 32);
- R = static_cast<u32bit>(T);
- }
-
-/*************************************************
-* DES Final Permutation *
-*************************************************/
-void DES::FP(u32bit& L, u32bit& R)
- {
- u64bit T = (FPTAB1[get_byte(0, L)] << 5) | (FPTAB1[get_byte(1, L)] << 3) |
- (FPTAB1[get_byte(2, L)] << 1) | (FPTAB2[get_byte(3, L)] << 1) |
- (FPTAB1[get_byte(0, R)] << 4) | (FPTAB1[get_byte(1, R)] << 2) |
- (FPTAB1[get_byte(2, R)] ) | (FPTAB2[get_byte(3, R)] );
- L = static_cast<u32bit>(T >> 32);
- R = static_cast<u32bit>(T);
- }
-
-/*************************************************
-* DES Raw Encryption *
-*************************************************/
-void DES::raw_encrypt(u32bit& L, u32bit& R) const
- {
- for(u32bit j = 0; j != 16; j += 2)
- {
- u32bit T0, T1;
-
- T0 = rotate_right(R, 4) ^ round_key[2*j];
- T1 = R ^ round_key[2*j + 1];
-
- L ^= SPBOX1[get_byte(0, T0)] ^ SPBOX2[get_byte(0, T1)] ^
- SPBOX3[get_byte(1, T0)] ^ SPBOX4[get_byte(1, T1)] ^
- SPBOX5[get_byte(2, T0)] ^ SPBOX6[get_byte(2, T1)] ^
- SPBOX7[get_byte(3, T0)] ^ SPBOX8[get_byte(3, T1)];
-
- T0 = rotate_right(L, 4) ^ round_key[2*j + 2];
- T1 = L ^ round_key[2*j + 3];
-
- R ^= SPBOX1[get_byte(0, T0)] ^ SPBOX2[get_byte(0, T1)] ^
- SPBOX3[get_byte(1, T0)] ^ SPBOX4[get_byte(1, T1)] ^
- SPBOX5[get_byte(2, T0)] ^ SPBOX6[get_byte(2, T1)] ^
- SPBOX7[get_byte(3, T0)] ^ SPBOX8[get_byte(3, T1)];
- }
- }
-
-/*************************************************
-* DES Raw Decryption *
-*************************************************/
-void DES::raw_decrypt(u32bit& L, u32bit& R) const
- {
- for(u32bit j = 16; j != 0; j -= 2)
- {
- u32bit T0, T1;
-
- T0 = rotate_right(R, 4) ^ round_key[2*j - 2];
- T1 = R ^ round_key[2*j - 1];
-
- L ^= SPBOX1[get_byte(0, T0)] ^ SPBOX2[get_byte(0, T1)] ^
- SPBOX3[get_byte(1, T0)] ^ SPBOX4[get_byte(1, T1)] ^
- SPBOX5[get_byte(2, T0)] ^ SPBOX6[get_byte(2, T1)] ^
- SPBOX7[get_byte(3, T0)] ^ SPBOX8[get_byte(3, T1)];
-
- T0 = rotate_right(L, 4) ^ round_key[2*j - 4];
- T1 = L ^ round_key[2*j - 3];
-
- R ^= SPBOX1[get_byte(0, T0)] ^ SPBOX2[get_byte(0, T1)] ^
- SPBOX3[get_byte(1, T0)] ^ SPBOX4[get_byte(1, T1)] ^
- SPBOX5[get_byte(2, T0)] ^ SPBOX6[get_byte(2, T1)] ^
- SPBOX7[get_byte(3, T0)] ^ SPBOX8[get_byte(3, T1)];
- }
- }
+namespace {
/*************************************************
* DES Key Schedule *
*************************************************/
-void DES::key(const byte key[], u32bit)
+void des_key_schedule(u32bit round_key[32], const byte key[8])
{
static const byte ROT[16] = { 1, 1, 2, 2, 2, 2, 2, 2,
1, 2, 2, 2, 2, 2, 2, 1 };
+
u32bit C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) |
((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) |
((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) |
@@ -152,6 +46,7 @@ void DES::key(const byte key[], u32bit)
((key[1] & 0x08) << 2) | ((key[0] & 0x08) << 1) |
((key[3] & 0x10) >> 1) | ((key[2] & 0x10) >> 2) |
((key[1] & 0x10) >> 3) | ((key[0] & 0x10) >> 4);
+
for(u32bit j = 0; j != 16; ++j)
{
C = ((C << ROT[j]) | (C >> (28-ROT[j]))) & 0x0FFFFFFF;
@@ -182,78 +77,187 @@ void DES::key(const byte key[], u32bit)
}
/*************************************************
-* TripleDES Encryption *
+* DES Encryption *
*************************************************/
-void TripleDES::enc(const byte in[], byte out[]) const
+void des_encrypt(u32bit& L, u32bit& R,
+ const u32bit round_key[32])
{
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ u32bit T0, T1;
- DES::IP(L, R);
- des1.raw_encrypt(L, R);
- des2.raw_decrypt(R, L);
- des3.raw_encrypt(L, R);
- DES::FP(L, R);
+ T0 = rotate_right(R, 4) ^ round_key[2*j];
+ T1 = R ^ round_key[2*j + 1];
+
+ L ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
+ DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
+ DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
+ DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
+
+ T0 = rotate_right(L, 4) ^ round_key[2*j + 2];
+ T1 = L ^ round_key[2*j + 3];
- store_be(out, R, L);
+ R ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
+ DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
+ DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
+ DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
+ }
}
/*************************************************
-* TripleDES Decryption *
+* DES Decryption *
*************************************************/
-void TripleDES::dec(const byte in[], byte out[]) const
+void des_decrypt(u32bit& L, u32bit& R,
+ const u32bit round_key[32])
{
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
+ for(u32bit j = 16; j != 0; j -= 2)
+ {
+ u32bit T0, T1;
- DES::IP(L, R);
- des3.raw_decrypt(L, R);
- des2.raw_encrypt(R, L);
- des1.raw_decrypt(L, R);
- DES::FP(L, R);
+ T0 = rotate_right(R, 4) ^ round_key[2*j - 2];
+ T1 = R ^ round_key[2*j - 1];
+
+ L ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
+ DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
+ DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
+ DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
+
+ T0 = rotate_right(L, 4) ^ round_key[2*j - 4];
+ T1 = L ^ round_key[2*j - 3];
- store_be(out, R, L);
+ R ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
+ DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
+ DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
+ DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
+ }
}
+}
+
/*************************************************
-* TripleDES Key Schedule *
+* DES Encryption *
*************************************************/
-void TripleDES::key(const byte key[], u32bit length)
+void DES::enc(const byte in[], byte out[]) const
{
- des1.set_key(key, 8);
- des2.set_key(key + 8, 8);
- if(length == 24)
- des3.set_key(key + 16, 8);
- else
- des3.set_key(key, 8);
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
+
+ des_encrypt(L, R, round_key);
+
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+
+ T = rotate_left(T, 32);
+
+ store_be(T, out);
+ }
+
+/*************************************************
+* DES Decryption *
+*************************************************/
+void DES::dec(const byte in[], byte out[]) const
+ {
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
+
+ des_decrypt(L, R, round_key);
+
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+
+ T = rotate_left(T, 32);
+
+ store_be(T, out);
}
/*************************************************
-* DESX Encryption *
+* DES Key Schedule *
*************************************************/
-void DESX::enc(const byte in[], byte out[]) const
+void DES::key(const byte key[], u32bit)
{
- xor_buf(out, in, K1.begin(), BLOCK_SIZE);
- des.encrypt(out);
- xor_buf(out, K2.begin(), BLOCK_SIZE);
+ des_key_schedule(round_key.begin(), key);
}
/*************************************************
-* DESX Decryption *
+* TripleDES Encryption *
*************************************************/
-void DESX::dec(const byte in[], byte out[]) const
+void TripleDES::enc(const byte in[], byte out[]) const
{
- xor_buf(out, in, K2.begin(), BLOCK_SIZE);
- des.decrypt(out);
- xor_buf(out, K1.begin(), BLOCK_SIZE);
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
+
+ des_encrypt(L, R, round_key);
+ des_decrypt(R, L, round_key + 32);
+ des_encrypt(L, R, round_key + 64);
+
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+
+ T = rotate_left(T, 32);
+
+ store_be(T, out);
}
/*************************************************
-* DESX Key Schedule *
+* TripleDES Decryption *
*************************************************/
-void DESX::key(const byte key[], u32bit)
+void TripleDES::dec(const byte in[], byte out[]) const
{
- K1.copy(key, 8);
- des.set_key(key + 8, 8);
- K2.copy(key + 16, 8);
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
+
+ des_decrypt(L, R, round_key + 64);
+ des_encrypt(R, L, round_key + 32);
+ des_decrypt(L, R, round_key);
+
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+
+ T = rotate_left(T, 32);
+
+ store_be(T, out);
+ }
+
+/*************************************************
+* TripleDES Key Schedule *
+*************************************************/
+void TripleDES::key(const byte key[], u32bit length)
+ {
+ des_key_schedule(&round_key[0], key);
+ des_key_schedule(&round_key[32], key + 8);
+
+ if(length == 24)
+ des_key_schedule(&round_key[64], key + 16);
+ else
+ copy_mem(&round_key[64], round_key.begin(), 32);
}
}
diff --git a/src/cipher/des/des.h b/src/cipher/des/des.h
index 3e53a6166..eb4689849 100644
--- a/src/cipher/des/des.h
+++ b/src/cipher/des/des.h
@@ -21,30 +21,9 @@ class BOTAN_DLL DES : public BlockCipher
BlockCipher* clone() const { return new DES; }
DES() : BlockCipher(8, 8) {}
private:
- friend class TripleDES;
-
void enc(const byte[], byte[]) const;
void dec(const byte[], byte[]) const;
void key(const byte[], u32bit);
- void raw_encrypt(u32bit&, u32bit&) const;
- void raw_decrypt(u32bit&, u32bit&) const;
- void round(u32bit&, u32bit, u32bit) const;
- static void IP(u32bit&, u32bit&);
- static void FP(u32bit&, u32bit&);
-
- static const u32bit SPBOX1[256];
- static const u32bit SPBOX2[256];
- static const u32bit SPBOX3[256];
- static const u32bit SPBOX4[256];
- static const u32bit SPBOX5[256];
- static const u32bit SPBOX6[256];
- static const u32bit SPBOX7[256];
- static const u32bit SPBOX8[256];
-
- static const u64bit IPTAB1[256];
- static const u64bit IPTAB2[256];
- static const u64bit FPTAB1[256];
- static const u64bit FPTAB2[256];
SecureBuffer<u32bit, 32> round_key;
};
@@ -55,7 +34,7 @@ class BOTAN_DLL DES : public BlockCipher
class BOTAN_DLL TripleDES : public BlockCipher
{
public:
- void clear() throw() { des1.clear(); des2.clear(); des3.clear(); }
+ void clear() throw() { round_key.clear(); }
std::string name() const { return "TripleDES"; }
BlockCipher* clone() const { return new TripleDES; }
TripleDES() : BlockCipher(8, 16, 24, 8) {}
@@ -63,26 +42,26 @@ class BOTAN_DLL TripleDES : public BlockCipher
void enc(const byte[], byte[]) const;
void dec(const byte[], byte[]) const;
void key(const byte[], u32bit);
- DES des1, des2, des3;
+
+ SecureBuffer<u32bit, 96> round_key;
};
/*************************************************
-* DESX *
+* DES Tables *
*************************************************/
-class BOTAN_DLL DESX : public BlockCipher
- {
- public:
- void clear() throw() { des.clear(); K1.clear(); K2.clear(); }
- std::string name() const { return "DESX"; }
- BlockCipher* clone() const { return new DESX; }
- DESX() : BlockCipher(8, 24) {}
- private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
- void key(const byte[], u32bit);
- SecureBuffer<byte, 8> K1, K2;
- DES des;
- };
+extern const u32bit DES_SPBOX1[256];
+extern const u32bit DES_SPBOX2[256];
+extern const u32bit DES_SPBOX3[256];
+extern const u32bit DES_SPBOX4[256];
+extern const u32bit DES_SPBOX5[256];
+extern const u32bit DES_SPBOX6[256];
+extern const u32bit DES_SPBOX7[256];
+extern const u32bit DES_SPBOX8[256];
+
+extern const u64bit DES_IPTAB1[256];
+extern const u64bit DES_IPTAB2[256];
+extern const u64bit DES_FPTAB1[256];
+extern const u64bit DES_FPTAB2[256];
}
diff --git a/src/cipher/des/des_tab.cpp b/src/cipher/des/des_tab.cpp
index 9788cd8c0..aa3b7cd45 100644
--- a/src/cipher/des/des_tab.cpp
+++ b/src/cipher/des/des_tab.cpp
@@ -7,7 +7,7 @@
namespace Botan {
-const u32bit DES::SPBOX1[256] = {
+const u32bit DES_SPBOX1[256] = {
0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,
0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
@@ -52,7 +52,7 @@ const u32bit DES::SPBOX1[256] = {
0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
0x00010004, 0x00010400, 0x00000000, 0x01010004 };
-const u32bit DES::SPBOX2[256] = {
+const u32bit DES_SPBOX2[256] = {
0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,
0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
@@ -97,7 +97,7 @@ const u32bit DES::SPBOX2[256] = {
0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
0x80000000, 0x80100020, 0x80108020, 0x00108000 };
-const u32bit DES::SPBOX3[256] = {
+const u32bit DES_SPBOX3[256] = {
0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,
0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
@@ -142,7 +142,7 @@ const u32bit DES::SPBOX3[256] = {
0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
0x00020208, 0x00000008, 0x08020008, 0x00020200 };
-const u32bit DES::SPBOX4[256] = {
+const u32bit DES_SPBOX4[256] = {
0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,
0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
@@ -187,7 +187,7 @@ const u32bit DES::SPBOX4[256] = {
0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002000, 0x00802080 };
-const u32bit DES::SPBOX5[256] = {
+const u32bit DES_SPBOX5[256] = {
0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,
0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
@@ -232,7 +232,7 @@ const u32bit DES::SPBOX5[256] = {
0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
0x00000000, 0x40080000, 0x02080100, 0x40000100 };
-const u32bit DES::SPBOX6[256] = {
+const u32bit DES_SPBOX6[256] = {
0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,
0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
@@ -277,7 +277,7 @@ const u32bit DES::SPBOX6[256] = {
0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
0x20404000, 0x20000000, 0x00400010, 0x20004010 };
-const u32bit DES::SPBOX7[256] = {
+const u32bit DES_SPBOX7[256] = {
0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,
0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
@@ -322,7 +322,7 @@ const u32bit DES::SPBOX7[256] = {
0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
0x04000002, 0x04000800, 0x00000800, 0x00200002 };
-const u32bit DES::SPBOX8[256] = {
+const u32bit DES_SPBOX8[256] = {
0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,
0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
@@ -367,7 +367,7 @@ const u32bit DES::SPBOX8[256] = {
0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040,
0x00001040, 0x00040040, 0x10000000, 0x10041000 };
-const u64bit DES::IPTAB1[256] = {
+const u64bit DES_IPTAB1[256] = {
0x0000000000000000, 0x0000000200000000, 0x0000000000000002, 0x0000000200000002,
0x0000020000000000, 0x0000020200000000, 0x0000020000000002, 0x0000020200000002,
0x0000000000000200, 0x0000000200000200, 0x0000000000000202, 0x0000000200000202,
@@ -433,7 +433,7 @@ const u64bit DES::IPTAB1[256] = {
0x0202000002020200, 0x0202000202020200, 0x0202000002020202, 0x0202000202020202,
0x0202020002020200, 0x0202020202020200, 0x0202020002020202, 0x0202020202020202 };
-const u64bit DES::IPTAB2[256] = {
+const u64bit DES_IPTAB2[256] = {
0x0000000000000000, 0x0000010000000000, 0x0000000000000100, 0x0000010000000100,
0x0001000000000000, 0x0001010000000000, 0x0001000000000100, 0x0001010000000100,
0x0000000000010000, 0x0000010000010000, 0x0000000000010100, 0x0000010000010100,
@@ -499,7 +499,7 @@ const u64bit DES::IPTAB2[256] = {
0x0100000101010001, 0x0100010101010001, 0x0100000101010101, 0x0100010101010101,
0x0101000101010001, 0x0101010101010001, 0x0101000101010101, 0x0101010101010101 };
-const u64bit DES::FPTAB1[256] = {
+const u64bit DES_FPTAB1[256] = {
0x0000000000000000, 0x0000000100000000, 0x0000000004000000, 0x0000000104000000,
0x0000000000040000, 0x0000000100040000, 0x0000000004040000, 0x0000000104040000,
0x0000000000000400, 0x0000000100000400, 0x0000000004000400, 0x0000000104000400,
@@ -565,7 +565,7 @@ const u64bit DES::FPTAB1[256] = {
0x0404040000000404, 0x0404040100000404, 0x0404040004000404, 0x0404040104000404,
0x0404040000040404, 0x0404040100040404, 0x0404040004040404, 0x0404040104040404 };
-const u64bit DES::FPTAB2[256] = {
+const u64bit DES_FPTAB2[256] = {
0x0000000000000000, 0x0000004000000000, 0x0000000001000000, 0x0000004001000000,
0x0000000000010000, 0x0000004000010000, 0x0000000001010000, 0x0000004001010000,
0x0000000000000100, 0x0000004000000100, 0x0000000001000100, 0x0000004001000100,
diff --git a/src/cipher/des/desx.cpp b/src/cipher/des/desx.cpp
new file mode 100644
index 000000000..fb76ec731
--- /dev/null
+++ b/src/cipher/des/desx.cpp
@@ -0,0 +1,41 @@
+/*************************************************
+* DES Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/desx.h>
+#include <botan/xor_buf.h>
+
+namespace Botan {
+
+/*************************************************
+* DESX Encryption *
+*************************************************/
+void DESX::enc(const byte in[], byte out[]) const
+ {
+ xor_buf(out, in, K1.begin(), BLOCK_SIZE);
+ des.encrypt(out);
+ xor_buf(out, K2.begin(), BLOCK_SIZE);
+ }
+
+/*************************************************
+* DESX Decryption *
+*************************************************/
+void DESX::dec(const byte in[], byte out[]) const
+ {
+ xor_buf(out, in, K2.begin(), BLOCK_SIZE);
+ des.decrypt(out);
+ xor_buf(out, K1.begin(), BLOCK_SIZE);
+ }
+
+/*************************************************
+* DESX Key Schedule *
+*************************************************/
+void DESX::key(const byte key[], u32bit)
+ {
+ K1.copy(key, 8);
+ des.set_key(key + 8, 8);
+ K2.copy(key + 16, 8);
+ }
+
+}
diff --git a/src/cipher/des/desx.h b/src/cipher/des/desx.h
new file mode 100644
index 000000000..c7e407b62
--- /dev/null
+++ b/src/cipher/des/desx.h
@@ -0,0 +1,33 @@
+/*************************************************
+* DESX Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_DESX_H__
+#define BOTAN_DESX_H__
+
+#include <botan/des.h>
+
+namespace Botan {
+
+/*************************************************
+* DESX *
+*************************************************/
+class BOTAN_DLL DESX : public BlockCipher
+ {
+ public:
+ void clear() throw() { des.clear(); K1.clear(); K2.clear(); }
+ std::string name() const { return "DESX"; }
+ BlockCipher* clone() const { return new DESX; }
+ DESX() : BlockCipher(8, 24) {}
+ private:
+ void enc(const byte[], byte[]) const;
+ void dec(const byte[], byte[]) const;
+ void key(const byte[], u32bit);
+ SecureBuffer<byte, 8> K1, K2;
+ DES des;
+ };
+
+}
+
+#endif
diff --git a/src/cipher/des/info.txt b/src/cipher/des/info.txt
index 43ea9a0bc..ed05979c9 100644
--- a/src/cipher/des/info.txt
+++ b/src/cipher/des/info.txt
@@ -8,4 +8,6 @@ load_on auto
des.cpp
des.h
des_tab.cpp
+desx.h
+desx.cpp
</add>
diff --git a/src/core/libstate/def_alg.cpp b/src/core/libstate/def_alg.cpp
index b7c812a59..6f89fa121 100644
--- a/src/core/libstate/def_alg.cpp
+++ b/src/core/libstate/def_alg.cpp
@@ -24,6 +24,7 @@
#if defined(BOTAN_HAS_DES)
#include <botan/des.h>
+ #include <botan/desx.h>
#endif
#if defined(BOTAN_HAS_GOST)