Add a salt to the key derivation using the 'enc' program.
diff --git a/CHANGES b/CHANGES
index 574c319..81942a0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@
 
  Changes between 0.9.4 and 0.9.5  [xx XXX 1999]
 
+  *) Add a salt to the key derivation routines in enc.c. This
+     forms the first 8 bytes of the encrypted file. Also add a
+     -S option to allow a salt to be input on the command line.
+     [Steve Henson]
+
   *) New function X509_cmp(). Oddly enough there wasn't a function
      to compare two certificates. We do this by working out the SHA1
      hash and comparing that. X509_cmp() will be needed by the trust
diff --git a/apps/enc.c b/apps/enc.c
index bce936a..d033e38 100644
--- a/apps/enc.c
+++ b/apps/enc.c
@@ -65,6 +65,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include <openssl/rand.h>
 #ifndef NO_MD5
 #include <openssl/md5.h>
 #endif
@@ -86,10 +87,11 @@
 	int bsize=BSIZE,verbose=0;
 	int ret=1,inl;
 	unsigned char key[24],iv[MD5_DIGEST_LENGTH];
+	unsigned char salt[PKCS5_SALT_LEN];
 	char *str=NULL;
-	char *hkey=NULL,*hiv=NULL;
+	char *hkey=NULL,*hiv=NULL,*hsalt = NULL;
 	int enc=1,printkey=0,i,base64=0;
-	int debug=0,olb64=0;
+	int debug=0,olb64=0,nosalt=1;
 	const EVP_CIPHER *cipher=NULL,*c;
 	char *inf=NULL,*outf=NULL;
 	BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL;
@@ -136,8 +138,11 @@
 			printkey=1;
 		else if	(strcmp(*argv,"-v") == 0)
 			verbose=1;
-		else if	((strcmp(*argv,"-debug") == 0) ||
-			 (strcmp(*argv,"-d") == 0))
+		else if	(strcmp(*argv,"-salt") == 0)
+			nosalt=0;
+		else if	(strcmp(*argv,"-nosalt") == 0)
+			nosalt=1;
+		else if	(strcmp(*argv,"-debug") == 0)
 			debug=1;
 		else if	(strcmp(*argv,"-P") == 0)
 			printkey=2;
@@ -194,6 +199,11 @@
 			if (--argc < 1) goto bad;
 			hkey= *(++argv);
 			}
+		else if (strcmp(*argv,"-S") == 0)
+			{
+			if (--argc < 1) goto bad;
+			hsalt= *(++argv);
+			}
 		else if (strcmp(*argv,"-iv") == 0)
 			{
 			if (--argc < 1) goto bad;
@@ -386,11 +396,73 @@
 			}
 		}
 
+
+	if (outf == NULL)
+		BIO_set_fp(out,stdout,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_write_filename(out,outf) <= 0)
+			{
+			perror(outf);
+			goto end;
+			}
+		}
+
+	rbio=in;
+	wbio=out;
+
+	if (base64)
+		{
+		if ((b64=BIO_new(BIO_f_base64())) == NULL)
+			goto end;
+		if (debug)
+			{
+			BIO_set_callback(b64,BIO_debug_callback);
+			BIO_set_callback_arg(b64,bio_err);
+			}
+		if (olb64)
+			BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
+		if (enc)
+			wbio=BIO_push(b64,wbio);
+		else
+			rbio=BIO_push(b64,rbio);
+		}
+
 	if (cipher != NULL)
 		{
 		if (str != NULL)
 			{
-			EVP_BytesToKey(cipher,EVP_md5(),NULL,
+			/* Salt handling: if encrypting generate a salt and
+			 * write to output BIO. If decrypting read salt from
+			 * input BIO.
+			 */
+			unsigned char *sptr;
+			if(nosalt) sptr = NULL;
+			else {
+				if(enc) {
+					if(hsalt) {
+						if(!set_hex(hsalt,salt,PKCS5_SALT_LEN)) {
+							BIO_printf(bio_err,
+								"invalid hex salt value\n");
+							goto end;
+						}
+					} else RAND_bytes(salt, PKCS5_SALT_LEN);
+					/* If -P option then don't bother writing */
+					if((printkey != 2) && (BIO_write(wbio,
+							(unsigned char *) salt,
+				    			PKCS5_SALT_LEN) != PKCS5_SALT_LEN)) {
+						BIO_printf(bio_err,"error writing output file\n");
+						goto end;
+					}
+				} else if(BIO_read(rbio, (unsigned char *)salt,
+				    PKCS5_SALT_LEN) != PKCS5_SALT_LEN) {
+					BIO_printf(bio_err,"error reading input file\n");
+					goto end;
+				}
+				sptr = salt;
+			}
+
+			EVP_BytesToKey(cipher,EVP_md5(),sptr,
 				(unsigned char *)str,
 				strlen(str),1,key,iv);
 			/* zero the complete buffer or the string
@@ -424,6 +496,13 @@
 
 		if (printkey)
 			{
+			if (!nosalt)
+				{
+				printf("salt=");
+				for (i=0; i<PKCS5_SALT_LEN; i++)
+					printf("%02X",salt[i]);
+				printf("\n");
+				}
 			if (cipher->key_len > 0)
 				{
 				printf("key=");
@@ -446,38 +525,6 @@
 			}
 		}
 
-
-	if (outf == NULL)
-		BIO_set_fp(out,stdout,BIO_NOCLOSE);
-	else
-		{
-		if (BIO_write_filename(out,outf) <= 0)
-			{
-			perror(outf);
-			goto end;
-			}
-		}
-
-	rbio=in;
-	wbio=out;
-
-	if (base64)
-		{
-		if ((b64=BIO_new(BIO_f_base64())) == NULL)
-			goto end;
-		if (debug)
-			{
-			BIO_set_callback(b64,BIO_debug_callback);
-			BIO_set_callback_arg(b64,bio_err);
-			}
-		if (olb64)
-			BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
-		if (enc)
-			wbio=BIO_push(b64,wbio);
-		else
-			rbio=BIO_push(b64,rbio);
-		}
-
 	/* Only encrypt/decrypt as we write the file */
 	if (benc != NULL)
 		wbio=BIO_push(benc,wbio);
diff --git a/doc/man/enc.pod b/doc/man/enc.pod
index 40b1c3a..d6875bc 100644
--- a/doc/man/enc.pod
+++ b/doc/man/enc.pod
@@ -40,6 +40,18 @@
 
 the output filename, standard output by default.
 
+=item B<-salt>
+
+use a salt in the key derivation routines. This option should B<ALWAYS>
+be used unless compatability with previous versions of OpenSSL or SSLeay
+is required. This option is only present on OpenSSL versions 0.9.5 or
+above.
+
+=item B<-nosalt>
+
+don't use a salt in the key derivation routines. This is the default for
+compatability with previous versions of OpenSSL and SSLeay.
+
 =item B<-e>
 
 encrypt the input data: this is the default.
@@ -66,6 +78,11 @@
 
 read the password to derive the key from the first line of B<filename>
 
+=item B<-S salt>
+
+the actual salt to use: this must be represented as a string comprised only
+of hex digits.
+
 =item B<-K key>
 
 the actual key to use: this must be represented as a string comprised only
@@ -102,6 +119,16 @@
 
 A password will be prompted for to derive the key and IV if necessary.
 
+The B<-salt> option should B<ALWAYS> be used unless you want compatability
+with previous versions of OpenSSL and SSLeay.
+
+Without the B<-salt> option it is possible to perform efficient dictionary
+attacks on the password and to attack stream cipher encrypted data. The reason
+for this is that without the salt the same password always generates the same
+encryption key. When the salt is being used the first eight bytes of the
+encrypted data are reserved for the salt: it is generated at random when
+encrypting a file and read from the encrypted file when it is decrypted.
+
 Some of the ciphers do not have large keys and others have security
 implications if not used correctly. A beginner is advised to just use
 a strong block cipher in CBC mode such as bf or des3.
@@ -187,20 +214,20 @@
 
 Encrypt a file using triple DES in CBC mode using a prompted password:
 
- openssl des3 -in file.txt -out file.des3 
+ openssl des3 -salt -in file.txt -out file.des3 
 
 Decrypt a file using a supplied password:
 
- openssl des3 -d -in file.des3 -out file.txt -k mypassword
+ openssl des3 -d -salt -in file.des3 -out file.txt -k mypassword
 
 Encrypt a file then base64 encode it (so it can be sent via mail for example)
 using Blowfish in CBC mode:
 
- openssl bf -a -in file.txt -out file.bf
+ openssl bf -a -salt -in file.txt -out file.bf
 
 Base64 decode a file then decrypt it:
 
- openssl bf -d -a -in file.bf -out file.txt
+ openssl bf -d -salt -a -in file.bf -out file.txt
 
 Decrypt some data using a supplied 40 bit RC4 key:
 
@@ -210,10 +237,7 @@
 
 The B<-A> option when used with large files doesn't work properly.
 
-The key derivation algorithm used is compatible with the SSLeay algorithm. It
-is not very good: it uses unsalted MD5.
-
-There should be an option to allow a salt or iteration count to be included.
+There should be an option to allow an iteration count to be included.
 
 Like the EVP library the B<enc> program only supports a fixed number of
 algorithms with certain parameters. So if, for example, you want to use RC2