1#ifndef CRYPTOPP_DES_H
2#define CRYPTOPP_DES_H
3
4/** \file
5*/
6
7#include "seckey.h"
8#include "secblock.h"
9
10NAMESPACE_BEGIN(CryptoPP)
11
12class CRYPTOPP_DLL RawDES
13{
14public:
15	void RawSetKey(CipherDir direction, const byte *userKey);
16	void RawProcessBlock(word32 &l, word32 &r) const;
17
18protected:
19	static const word32 Spbox[8][64];
20
21	FixedSizeSecBlock<word32, 32> k;
22};
23
24//! _
25struct DES_Info : public FixedBlockSize<8>, public FixedKeyLength<8>
26{
27	// disable DES in DLL version by not exporting this function
28	static const char * StaticAlgorithmName() {return "DES";}
29};
30
31/// <a href="http://www.weidai.com/scan-mirror/cs.html#DES">DES</a>
32/*! The DES implementation in Crypto++ ignores the parity bits
33	(the least significant bits of each byte) in the key. However
34	you can use CheckKeyParityBits() and CorrectKeyParityBits() to
35	check or correct the parity bits if you wish. */
36class DES : public DES_Info, public BlockCipherDocumentation
37{
38	class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<DES_Info>, public RawDES
39	{
40	public:
41		void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &params);
42		void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
43	};
44
45public:
46	//! check DES key parity bits
47	static bool CheckKeyParityBits(const byte *key);
48	//! correct DES key parity bits
49	static void CorrectKeyParityBits(byte *key);
50
51	typedef BlockCipherFinal<ENCRYPTION, Base> Encryption;
52	typedef BlockCipherFinal<DECRYPTION, Base> Decryption;
53};
54
55//! _
56struct DES_EDE2_Info : public FixedBlockSize<8>, public FixedKeyLength<16>
57{
58	CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "DES-EDE2";}
59};
60
61/// <a href="http://www.weidai.com/scan-mirror/cs.html#DESede">DES-EDE2</a>
62class DES_EDE2 : public DES_EDE2_Info, public BlockCipherDocumentation
63{
64	class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<DES_EDE2_Info>
65	{
66	public:
67		void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &params);
68		void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
69
70	protected:
71		RawDES m_des1, m_des2;
72	};
73
74public:
75	typedef BlockCipherFinal<ENCRYPTION, Base> Encryption;
76	typedef BlockCipherFinal<DECRYPTION, Base> Decryption;
77};
78
79//! _
80struct DES_EDE3_Info : public FixedBlockSize<8>, public FixedKeyLength<24>
81{
82	CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "DES-EDE3";}
83};
84
85/// <a href="http://www.weidai.com/scan-mirror/cs.html#DESede">DES-EDE3</a>
86class DES_EDE3 : public DES_EDE3_Info, public BlockCipherDocumentation
87{
88	class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<DES_EDE3_Info>
89	{
90	public:
91		void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &params);
92		void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
93
94	protected:
95		RawDES m_des1, m_des2, m_des3;
96	};
97
98public:
99	typedef BlockCipherFinal<ENCRYPTION, Base> Encryption;
100	typedef BlockCipherFinal<DECRYPTION, Base> Decryption;
101};
102
103//! _
104struct DES_XEX3_Info : public FixedBlockSize<8>, public FixedKeyLength<24>
105{
106	static const char *StaticAlgorithmName() {return "DES-XEX3";}
107};
108
109/// <a href="http://www.weidai.com/scan-mirror/cs.html#DESX">DES-XEX3</a>, AKA DESX
110class DES_XEX3 : public DES_XEX3_Info, public BlockCipherDocumentation
111{
112	class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<DES_XEX3_Info>
113	{
114	public:
115		void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &params);
116		void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
117
118	protected:
119		FixedSizeSecBlock<byte, BLOCKSIZE> m_x1, m_x3;
120		// VS2005 workaround: calling modules compiled with /clr gets unresolved external symbol DES::Base::ProcessAndXorBlock
121		// if we use DES::Encryption here directly without value_ptr.
122		value_ptr<DES::Encryption> m_des;
123	};
124
125public:
126	typedef BlockCipherFinal<ENCRYPTION, Base> Encryption;
127	typedef BlockCipherFinal<DECRYPTION, Base> Decryption;
128};
129
130typedef DES::Encryption DESEncryption;
131typedef DES::Decryption DESDecryption;
132
133typedef DES_EDE2::Encryption DES_EDE2_Encryption;
134typedef DES_EDE2::Decryption DES_EDE2_Decryption;
135
136typedef DES_EDE3::Encryption DES_EDE3_Encryption;
137typedef DES_EDE3::Decryption DES_EDE3_Decryption;
138
139typedef DES_XEX3::Encryption DES_XEX3_Encryption;
140typedef DES_XEX3::Decryption DES_XEX3_Decryption;
141
142NAMESPACE_END
143
144#endif
145