From 1010b590350915c63dfec3f14c64654a57695b04 Mon Sep 17 00:00:00 2001
From: Brad Hards <bradh@frogmouth.net>
Date: Sun, 28 Nov 2004 11:13:05 +0000
Subject: [PATCH] Initial work towards padding support. I've basically screwed
 up the first implementation, and dumped the lot. This is what was salvageable
 - a DES interface, removal of a stray <unistd.h> and some minor tweaks.

I'll have another try later.

svn path=/trunk/kdesupport/qca/; revision=366841
---
 src/qca.cpp       |  1 -
 src/qca.h         | 79 ++++++++++++++++++++++++++++++++++++++++++-----
 src/qca_basic.cpp |  2 +-
 src/qcaprovider.h |  2 +-
 4 files changed, 74 insertions(+), 10 deletions(-)

diff --git a/src/qca.cpp b/src/qca.cpp
index acf05768..d067bdbd 100644
--- a/src/qca.cpp
+++ b/src/qca.cpp
@@ -27,7 +27,6 @@
 #include <qguardedptr.h>
 #include <qptrdict.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include "qcaprovider.h"
 #include "qca_plugin.h"
 
diff --git a/src/qca.h b/src/qca.h
index ddb5bb5e..b809db0a 100644
--- a/src/qca.h
+++ b/src/qca.h
@@ -1457,6 +1457,41 @@ namespace QCA
 		Hash(const QString &type, const QString &provider);
 	};
 
+        /** \page padding Padding
+
+	For those Cipher sub-classes that are block based, there are modes
+	that require a full block on encryption and decryption - %Cipher Block
+	Chaining mode and Electronic Code Book modes are good examples. 
+	
+	Since real world messages are not always a convenient multiple of a
+	block size, we have to adding <i>padding</i>. There are a number of
+	padding modes that %QCA supports, including not doing any padding
+	at all.
+	
+	If you are not going to use padding, then you can pass 
+	QCA::Cipher::NoPadding as the pad argument to the Cipher sub-class, however
+	it is then your responsibility to pass in appropriate data for
+	the mode that you are using.
+
+	The most common padding scheme is known as PKCS#7 (also PKCS#1), and
+	it specifies that the pad bytes are all equal to the length of the 
+	padding ( for example, if you need three pad bytes to complete the block, then
+	the padding is 0x03 0x03 0x03 ).
+
+	On encryption, for algorithm / mode combinations that require
+	padding, you will get a block of ciphertext when the input plain text block
+	is complete. When you call final(), you will get out the ciphertext that
+	corresponds to the last bit of plain text, plus any padding. If you had
+	provided plaintext that matched up with a block size, then the cipher
+	text block is generated from pure padding - you always get at least some
+	padding, to ensure that the padding can be safely removed on decryption.
+	
+	On decryption, for algorithm / mode combinations that use padding,
+	you will get back a block of plaintext when the input ciphertext block
+	is complete. When you call final(), you will a block that has been stripped
+	of ciphertext.
+	*/
+
 	/**
 	 * General superclass for cipher (encryption / decryption) algorithms.
 	 *
@@ -1512,7 +1547,7 @@ namespace QCA
 		/**
 		 * return the block size for the cipher object
 		 */
-		int blockSize() const;
+		unsigned int blockSize() const;
 
 		/**
 		 * reset the cipher object, to allow re-use
@@ -1542,7 +1577,6 @@ namespace QCA
 
 	protected:
 		Cipher(const QString &type, Mode m, Direction dir, const SymmetricKey &key, const InitializationVector &iv, Padding pad, const QString &provider);
-
 	private:
 		class Private;
 		Private *d;
@@ -2038,7 +2072,8 @@ namespace QCA
 		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
 		 * \param key the key to use. 
 		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad whether to apply padding, or not.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
 		 * \param provider the provider to use (eg "qca-gcrypt" )
 		 *
 		 */
@@ -2062,7 +2097,8 @@ namespace QCA
 		 * \param key the key to use. Note that triple DES requires a 24 byte (192 bit) key,
 		 * even though the effective key length is 168 bits.
 		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad whether to apply padding, or not.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
 		 * \param provider the provider to use (eg "qca-gcrypt" )
 		 *
 		 */
@@ -2071,6 +2107,32 @@ namespace QCA
 		:Cipher("tripledes", m, dir, key, iv, pad, provider) {}
 	};
 
+	/**
+	 *DES %Cipher
+	 *
+	 */
+	class QCA_EXPORT DES : public Cipher
+	{
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a DES encryption or decryption object.
+		 *
+		 * \param m the Mode to operate in
+		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
+		 * \param key the key to use. Note that triple DES requires a 24 byte (192 bit) key,
+		 * even though the effective key length is 168 bits.
+		 * \param iv the initialisation vector to use. Ignored for ECB mode.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
+		 * \param provider the provider to use (eg "qca-gcrypt" )
+		 *
+		 */
+	public:
+		DES(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = "")
+		:Cipher("des", m, dir, key, iv, pad, provider) {}
+	};
+
 	/**
 	 * Advanced Encryption Standard %Cipher - 128 bits
 	 *
@@ -2088,7 +2150,8 @@ namespace QCA
 		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
 		 * \param key the key to use. Note that AES128 requires a 16 byte (128 bit) key.
 		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad whether to apply padding, or not.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
 		 * \param provider the provider to use (eg "qca-gcrypt" )
 		 *
 		 */
@@ -2113,7 +2176,8 @@ namespace QCA
 		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
 		 * \param key the key to use. Note that AES192 requires a 24 byte (192 bit) key.
 		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad whether to apply padding, or not.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
 		 * \param provider the provider to use (eg "qca-gcrypt" )
 		 *
 		 */
@@ -2138,7 +2202,8 @@ namespace QCA
 		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
 		 * \param key the key to use. Note that AES256 requires a 32 byte (256 bit) key.
 		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad whether to apply padding, or not.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
 		 * \param provider the provider to use (eg "qca-gcrypt" )
 		 *
 		 */
diff --git a/src/qca_basic.cpp b/src/qca_basic.cpp
index ab19c0f7..659e27c8 100644
--- a/src/qca_basic.cpp
+++ b/src/qca_basic.cpp
@@ -187,7 +187,7 @@ bool Cipher::validKeyLength(int n) const
 	return ((n >= keyLength().minimum()) && (n <= keyLength().maximum()) && (n % keyLength().multiple() == 0));
 }
 
-int Cipher::blockSize() const
+unsigned int Cipher::blockSize() const
 {
 	return ((CipherContext *)context())->blockSize();
 }
diff --git a/src/qcaprovider.h b/src/qcaprovider.h
index afddf5e6..548b13d9 100644
--- a/src/qcaprovider.h
+++ b/src/qcaprovider.h
@@ -78,7 +78,7 @@ public:
 	CipherContext(Provider *p, const QString &type) : Provider::Context(p, type) {}
 	virtual void setup(const SymmetricKey &key, Mode m, Direction dir, const InitializationVector &iv) = 0;
 	virtual KeyLength keyLength() const = 0;
-	virtual int blockSize() const = 0;
+	virtual unsigned int blockSize() const = 0;
 
 	virtual bool update(const QSecureArray &in, QSecureArray *out) = 0;
 	virtual bool final(QSecureArray *out) = 0;