Hello ! I propose the attached patch against the CVS HEAD dated 19112009. It fixes a few issues with the message digest functions (conditional compilation, enable/disable of individual SHA2 algorithms, functions not being displayed by command-line openssl, updated manual pages, updated information regarding the MDC2 patent expiration).
Changes to the 1.1.0 development branch (CVS-19112009):
- Modified top-level README file to document SHA2 family of message
digest algorithms;
- Mentioned in top-level FAQ file that MDC2 patent has expired;
- Modified the generation of the algorithm hash-table named "functions"
by apps/progs.pl so that all enabled message digest algorithms ("dgst"
command) are printed out (SHA2 had been left out): see for example, this
bug report <URL: http://marc.info/?l=openssl-dev&m=125642196006284&w=2>;
- Introduced the OPENSSL_NO_SHA224 and OPENSSL_NO_SHA384 defines, so
that individual SHA2 algorithms can be excluded from compilation (in the
end, the fact that SHA224 and SHA384 are implemented using SHA256 and
SHA512 functions respectively, does not imply that they are the same
algorithm);
- Modified the conditional compilation of SHA2 functions taking
advantage of the newly defined OPENSSL_NO_SHA{224,256}, so that it
should be now easier to read, maintain and use;
- Modified the manual page for dgst to document the SHA2 message digest
algorithms;
- Modified the man3 page for sha in order to briefly document in a note
the availability of the SHA2 message digest algorithms;
- Modified the man3 page for EVP_DigestInit to document the availability
of the SHA2 message digest functions and data structures and to mention
that now the hash function of choice for new applications should be one
of the SHA2 family (see also NIST reccomendation <URL:
http://csrc.nist.gov/groups/ST/hash/policy.html>).
Regards,
Guido
diff -pru openssl/apps/progs.h openssl-1.0.0-dev-patched/apps/progs.h
--- openssl/apps/progs.h 2009-06-30 17:28:15.000000000 +0200
+++ openssl-1.0.0-dev-patched/apps/progs.h 2009-11-20 01:52:27.000000000 +0100
@@ -162,6 +162,18 @@ FUNCTION functions[] = {
#ifndef OPENSSL_NO_SHA1
{FUNC_TYPE_MD,"sha1",dgst_main},
#endif
+#ifndef OPENSSL_NO_SHA224
+ {FUNC_TYPE_MD,"sha224",dgst_main},
+#endif
+#ifndef OPENSSL_NO_SHA256
+ {FUNC_TYPE_MD,"sha256",dgst_main},
+#endif
+#ifndef OPENSSL_NO_SHA384
+ {FUNC_TYPE_MD,"sha384",dgst_main},
+#endif
+#ifndef OPENSSL_NO_SHA512
+ {FUNC_TYPE_MD,"sha512",dgst_main},
+#endif
#ifndef OPENSSL_NO_MDC2
{FUNC_TYPE_MD,"mdc2",dgst_main},
#endif
diff -pru openssl/apps/progs.pl openssl-1.0.0-dev-patched/apps/progs.pl
--- openssl/apps/progs.pl 2009-06-30 17:28:15.000000000 +0200
+++ openssl-1.0.0-dev-patched/apps/progs.pl 2009-11-19 03:06:17.000000000 +0100
@@ -55,7 +55,7 @@ foreach (@ARGV)
{ print $str; }
}
-foreach ("md2","md4","md5","sha","sha1","mdc2","rmd160")
+foreach ("md2","md4","md5","sha","sha1","sha224","sha256","sha384","sha512","mdc2","rmd160")
{
push(@files,$_);
printf "#ifndef OPENSSL_NO_".uc($_)."\n\t{FUNC_TYPE_MD,\"".$_."\",dgst_main},\n#endif\n";
diff -pru openssl/crypto/evp/c_alld.c openssl-1.0.0-dev-patched/crypto/evp/c_alld.c
--- openssl/crypto/evp/c_alld.c 2009-07-08 10:49:17.000000000 +0200
+++ openssl-1.0.0-dev-patched/crypto/evp/c_alld.c 2009-11-19 20:58:18.000000000 +0100
@@ -100,12 +100,16 @@ void OpenSSL_add_all_digests(void)
EVP_add_digest_alias(SN_ripemd160,"ripemd");
EVP_add_digest_alias(SN_ripemd160,"rmd160");
#endif
-#ifndef OPENSSL_NO_SHA256
+#ifndef OPENSSL_NO_SHA224
EVP_add_digest(EVP_sha224());
+#endif
+#ifndef OPENSSL_NO_SHA256
EVP_add_digest(EVP_sha256());
#endif
-#ifndef OPENSSL_NO_SHA512
+#ifndef OPENSSL_NO_SHA384
EVP_add_digest(EVP_sha384());
+#endif
+#ifndef OPENSSL_NO_SHA512
EVP_add_digest(EVP_sha512());
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
diff -pru openssl/crypto/evp/evp.h openssl-1.0.0-dev-patched/crypto/evp/evp.h
--- openssl/crypto/evp/evp.h 2009-09-24 01:40:13.000000000 +0200
+++ openssl-1.0.0-dev-patched/crypto/evp/evp.h 2009-11-19 23:31:33.000000000 +0100
@@ -624,12 +624,16 @@ const EVP_MD *EVP_dss(void);
const EVP_MD *EVP_dss1(void);
const EVP_MD *EVP_ecdsa(void);
#endif
-#ifndef OPENSSL_NO_SHA256
+#ifndef OPENSSL_NO_SHA224
const EVP_MD *EVP_sha224(void);
+#endif
+#ifndef OPENSSL_NO_SHA256
const EVP_MD *EVP_sha256(void);
#endif
-#ifndef OPENSSL_NO_SHA512
+#ifndef OPENSSL_NO_SHA384
const EVP_MD *EVP_sha384(void);
+#endif
+#ifndef OPENSSL_NO_SHA512
const EVP_MD *EVP_sha512(void);
#endif
#ifndef OPENSSL_NO_MDC2
diff -pru openssl/crypto/evp/m_sha1.c openssl-1.0.0-dev-patched/crypto/evp/m_sha1.c
--- openssl/crypto/evp/m_sha1.c 2008-03-12 22:14:24.000000000 +0100
+++ openssl-1.0.0-dev-patched/crypto/evp/m_sha1.c 2009-11-19 04:17:37.000000000 +0100
@@ -99,7 +99,7 @@ const EVP_MD *EVP_sha1(void)
}
#endif
-#ifndef OPENSSL_NO_SHA256
+#if !defined(OPENSSL_NO_SHA224) || !defined(OPENSSL_NO_SHA256)
static int init224(EVP_MD_CTX *ctx)
{ return SHA224_Init(ctx->md_data); }
static int init256(EVP_MD_CTX *ctx)
@@ -151,9 +151,9 @@ static const EVP_MD sha256_md=
const EVP_MD *EVP_sha256(void)
{ return(&sha256_md); }
-#endif /* ifndef OPENSSL_NO_SHA256 */
+#endif /* !defined(OPENSSL_NO_SHA224) || !defined(OPENSSL_NO_SHA256) */
-#ifndef OPENSSL_NO_SHA512
+#if !defined(OPENSSL_NO_SHA384) || !defined(OPENSSL_NO_SHA512)
static int init384(EVP_MD_CTX *ctx)
{ return SHA384_Init(ctx->md_data); }
static int init512(EVP_MD_CTX *ctx)
@@ -201,4 +201,4 @@ static const EVP_MD sha512_md=
const EVP_MD *EVP_sha512(void)
{ return(&sha512_md); }
-#endif /* ifndef OPENSSL_NO_SHA512 */
+#endif /* !defined(OPENSSL_NO_SHA384) || !defined(OPENSSL_NO_SHA512) */
diff -pru openssl/crypto/sha/sha256.c openssl-1.0.0-dev-patched/crypto/sha/sha256.c
--- openssl/crypto/sha/sha256.c 2007-01-21 14:07:14.000000000 +0100
+++ openssl-1.0.0-dev-patched/crypto/sha/sha256.c 2009-11-19 03:32:43.000000000 +0100
@@ -5,7 +5,7 @@
* ====================================================================
*/
#include <openssl/opensslconf.h>
-#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
+#if !defined(OPENSSL_NO_SHA) && (!defined(OPENSSL_NO_SHA224) || !defined(OPENSSL_NO_SHA256))
#include <stdlib.h>
#include <string.h>
@@ -279,4 +279,4 @@ static void sha256_block_data_order (SHA
#endif
#endif /* SHA256_ASM */
-#endif /* OPENSSL_NO_SHA256 */
+#endif /* !defined(OPENSSL_NO_SHA224) || !defined(OPENSSL_NO_SHA256) */
diff -pru openssl/crypto/sha/sha256t.c openssl-1.0.0-dev-patched/crypto/sha/sha256t.c
--- openssl/crypto/sha/sha256t.c 2005-08-29 00:49:56.000000000 +0200
+++ openssl-1.0.0-dev-patched/crypto/sha/sha256t.c 2009-11-19 03:37:23.000000000 +0100
@@ -10,10 +10,10 @@
#include <openssl/sha.h>
#include <openssl/evp.h>
-#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA256)
+#if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA224) && defined(OPENSSL_NO_SHA256))
int main(int argc, char *argv[])
{
- printf("No SHA256 support\n");
+ printf("No SHA224/SHA256 support\n");
return(0);
}
#else
diff -pru openssl/crypto/sha/sha512.c openssl-1.0.0-dev-patched/crypto/sha/sha512.c
--- openssl/crypto/sha/sha512.c 2009-11-15 18:19:49.000000000 +0100
+++ openssl-1.0.0-dev-patched/crypto/sha/sha512.c 2009-11-19 03:38:42.000000000 +0100
@@ -5,7 +5,7 @@
* ====================================================================
*/
#include <openssl/opensslconf.h>
-#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
+#if !defined(OPENSSL_NO_SHA) && (!defined(OPENSSL_NO_SHA384) || !defined(OPENSSL_NO_SHA512))
/*
* IMPLEMENTATION NOTES.
*
@@ -638,4 +638,4 @@ static void sha512_block_data_order (SHA
static void *dummy=&dummy;
#endif
-#endif /* !OPENSSL_NO_SHA512 */
+#endif /* !defined(OPENSSL_NO_SHA384) || !defined(OPENSSL_NO_SHA512) */
diff -pru openssl/crypto/sha/sha512t.c openssl-1.0.0-dev-patched/crypto/sha/sha512t.c
--- openssl/crypto/sha/sha512t.c 2005-08-29 00:49:56.000000000 +0200
+++ openssl-1.0.0-dev-patched/crypto/sha/sha512t.c 2009-11-19 03:39:13.000000000 +0100
@@ -11,10 +11,10 @@
#include <openssl/evp.h>
#include <openssl/crypto.h>
-#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA512)
+#if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA384) && defined(OPENSSL_NO_SHA512))
int main(int argc, char *argv[])
{
- printf("No SHA512 support\n");
+ printf("No SAH384/SHA512 support\n");
return(0);
}
#else
diff -pru openssl/crypto/sha/sha.h openssl-1.0.0-dev-patched/crypto/sha/sha.h
--- openssl/crypto/sha/sha.h 2006-12-22 16:47:01.000000000 +0100
+++ openssl-1.0.0-dev-patched/crypto/sha/sha.h 2009-11-19 22:45:21.000000000 +0100
@@ -120,11 +120,13 @@ unsigned char *SHA1(const unsigned char
void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
#endif
+#if !defined(OPENSSL_NO_SHA224) || !defined(OPENSSL_NO_SHA256)
+#define SHA224_DIGEST_LENGTH 28
+#define SHA256_DIGEST_LENGTH 32
+
#define SHA256_CBLOCK (SHA_LBLOCK*4) /* SHA-256 treats input data as a
* contiguous array of 32 bit
* wide big-endian values. */
-#define SHA224_DIGEST_LENGTH 28
-#define SHA256_DIGEST_LENGTH 32
typedef struct SHA256state_st
{
@@ -134,7 +136,6 @@ typedef struct SHA256state_st
unsigned int num,md_len;
} SHA256_CTX;
-#ifndef OPENSSL_NO_SHA256
int SHA224_Init(SHA256_CTX *c);
int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA224_Final(unsigned char *md, SHA256_CTX *c);
@@ -146,10 +147,10 @@ unsigned char *SHA256(const unsigned cha
void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
#endif
-#define SHA384_DIGEST_LENGTH 48
-#define SHA512_DIGEST_LENGTH 64
+#if !defined(OPENSSL_NO_SHA384) || !defined(OPENSSL_NO_SHA512)
+#define SHA384_DIGEST_LENGTH 48
+#define SHA512_DIGEST_LENGTH 64
-#ifndef OPENSSL_NO_SHA512
/*
* Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
* being exactly 64-bit wide. See Implementation Notes in sha512.c
@@ -179,9 +180,7 @@ typedef struct SHA512state_st
} u;
unsigned int num,md_len;
} SHA512_CTX;
-#endif
-#ifndef OPENSSL_NO_SHA512
int SHA384_Init(SHA512_CTX *c);
int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA384_Final(unsigned char *md, SHA512_CTX *c);
diff -pru openssl/doc/apps/dgst.pod openssl-1.0.0-dev-patched/doc/apps/dgst.pod
--- openssl/doc/apps/dgst.pod 2009-04-15 17:26:55.000000000 +0200
+++ openssl-1.0.0-dev-patched/doc/apps/dgst.pod 2009-11-19 23:00:08.000000000 +0100
@@ -2,12 +2,12 @@
=head1 NAME
-dgst, md5, md4, md2, sha1, sha, mdc2, ripemd160 - message digests
+dgst, md5, md4, md2, sha512, sha384, sha256, sha224, sha1, sha, mdc2, ripemd160 - message digests
=head1 SYNOPSIS
B<openssl> B<dgst>
-[B<-md5|-md4|-md2|-sha1|-sha|-mdc2|-ripemd160|-dss1>]
+[B<-md5|-md4|-md2|-sha512|-sha384|-sha256|-sha224|-sha1|-sha|-mdc2|-ripemd160|-dss1>]
[B<-c>]
[B<-d>]
[B<-hex>]
@@ -22,7 +22,7 @@ B<openssl> B<dgst>
[B<-hmac key>]
[B<file...>]
-[B<md5|md4|md2|sha1|sha|mdc2|ripemd160>]
+[B<md5|md4|md2|sha512|sha384|sha256|sha224|sha1|sha|mdc2|ripemd160>]
[B<-c>]
[B<-d>]
[B<file...>]
diff -pru openssl/doc/crypto/EVP_DigestInit.pod openssl-1.0.0-dev-patched/doc/crypto/EVP_DigestInit.pod
--- openssl/doc/crypto/EVP_DigestInit.pod 2009-10-16 17:30:13.000000000 +0200
+++ openssl-1.0.0-dev-patched/doc/crypto/EVP_DigestInit.pod 2009-11-20 00:23:48.000000000 +0100
@@ -6,8 +6,9 @@ EVP_MD_CTX_init, EVP_MD_CTX_create, EVP_
EVP_DigestFinal_ex, EVP_MD_CTX_cleanup, EVP_MD_CTX_destroy, EVP_MAX_MD_SIZE,
EVP_MD_CTX_copy_ex, EVP_MD_CTX_copy, EVP_MD_type, EVP_MD_pkey_type, EVP_MD_size,
EVP_MD_block_size, EVP_MD_CTX_md, EVP_MD_CTX_size, EVP_MD_CTX_block_size, EVP_MD_CTX_type,
-EVP_md_null, EVP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_dss, EVP_dss1, EVP_mdc2,
-EVP_ripemd160, EVP_get_digestbyname, EVP_get_digestbynid, EVP_get_digestbyobj -
+EVP_md_null, EVP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_sha224, EVP_sha256, EVP_sha384,
+EVP_sha512, EVP_dss, EVP_dss1, EVP_mdc2, EVP_ripemd160, EVP_get_digestbyname,
+EVP_get_digestbynid, EVP_get_digestbyobj -
EVP digest routines
=head1 SYNOPSIS
@@ -127,9 +128,11 @@ with this digest. For example EVP_sha1()
return B<NID_sha1WithRSAEncryption>. This "link" between digests and signature
algorithms may not be retained in future versions of OpenSSL.
-EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_mdc2() and EVP_ripemd160()
-return B<EVP_MD> structures for the MD2, MD5, SHA, SHA1, MDC2 and RIPEMD160 digest
-algorithms respectively. The associated signature algorithm is RSA in each case.
+EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_sha224(), EVP_sha256(),
+EVP_sha384(), EVP_sha512(), EVP_mdc2() and EVP_ripemd160() return B<EVP_MD>
+structures for the MD2, MD5, SHA, SHA1, SHA224, SHA256, SHA384, SHA512, MDC2
+and RIPEMD160 digest algorithms respectively. The associated signature
+algorithm is RSA in each case.
EVP_dss() and EVP_dss1() return B<EVP_MD> structures for SHA and SHA1 digest
algorithms but using DSS (DSA) for the signature algorithm. Note: there is
@@ -158,9 +161,9 @@ EVP_MD_size(), EVP_MD_block_size(), EVP_
EVP_MD_CTX_block_size() and EVP_MD_block_size() return the digest or block
size in bytes.
-EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_dss(),
-EVP_dss1(), EVP_mdc2() and EVP_ripemd160() return pointers to the
-corresponding EVP_MD structures.
+EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_sha224(),
+EVP_sha256(), EVP_sha384(), EVP_sha512(), EVP_dss(), EVP_dss1(), EVP_mdc2()
+and EVP_ripemd160() return pointers to the corresponding EVP_MD structures.
EVP_get_digestbyname(), EVP_get_digestbynid() and EVP_get_digestbyobj()
return either an B<EVP_MD> structure or NULL if an error occurs.
@@ -171,8 +174,10 @@ The B<EVP> interface to message digests
preference to the low level interfaces. This is because the code then becomes
transparent to the digest used and much more flexible.
-SHA1 is the digest of choice for new applications. The other digest algorithms
-are still in common use.
+Algorithms from the SHA2 family should be the digest of choice for new
+applications (see also NIST reccomendations), as they offer enhanced
+security and collision-resistance with respect to their predecessor SHA
+functions. The other digest algorithms are still in common use.
For most applications the B<impl> parameter to EVP_DigestInit_ex() will be
set to NULL to use the default digest implementation.
diff -pru openssl/doc/crypto/md5.pod openssl-1.0.0-dev-patched/doc/crypto/md5.pod
--- openssl/doc/crypto/md5.pod 2006-10-27 23:58:09.000000000 +0200
+++ openssl-1.0.0-dev-patched/doc/crypto/md5.pod 2009-11-20 00:26:56.000000000 +0100
@@ -70,7 +70,7 @@ etc. instead of calling the hash functio
=head1 NOTE
MD2, MD4, and MD5 are recommended only for compatibility with existing
-applications. In new applications, SHA-1 or RIPEMD-160 should be
+applications. In new applications, SHA-2, SHA-1 or RIPEMD-160 should be
preferred.
=head1 RETURN VALUES
diff -pru openssl/doc/crypto/sha.pod openssl-1.0.0-dev-patched/doc/crypto/sha.pod
--- openssl/doc/crypto/sha.pod 2006-10-27 23:58:09.000000000 +0200
+++ openssl-1.0.0-dev-patched/doc/crypto/sha.pod 2009-11-20 00:15:55.000000000 +0100
@@ -3,6 +3,7 @@
=head1 NAME
SHA1, SHA1_Init, SHA1_Update, SHA1_Final - Secure Hash Algorithm
+SHA{224,256,384,512}, SHA{224,256,384,512}_Init, SHA{224,256,384,512}_Update, SHA{224,256,384,512}_Final - Secure Hash Algorithm 2
=head1 SYNOPSIS
@@ -21,6 +22,13 @@ SHA1, SHA1_Init, SHA1_Update, SHA1_Final
SHA-1 (Secure Hash Algorithm) is a cryptographic hash function with a
160 bit output.
+SHA-2 OR SHA2 is a family of functions that include the SHA224, the
+SHA256, the SHA384 and the SHA512 algorithms and that provides functions
+that provide enhanced security and collision-resistance respect to their
+predecessor function SHA-1.
+The SHA2 family of functions are defined in OpenSSL with a naming
+scheme that is syntactically similar way to SHA1.
+
SHA1() computes the SHA-1 message digest of the B<n>
bytes at B<d> and places it in B<md> (which must have space for
SHA_DIGEST_LENGTH == 20 bytes of output). If B<md> is NULL, the digest
@@ -50,6 +58,13 @@ SHA1() returns a pointer to the hash val
SHA1_Init(), SHA1_Update() and SHA1_Final() return 1 for success, 0 otherwise.
+=head1 NOTES
+
+Similarly to SHA1(), have been defined functions and data structures
+that implement the SHA2 family of message digest algorithms. These are
+named with the prefix SHA224, SHA256, SHA384 and SHA512 (for example
+SHA224_Init() or B<SHA512_CTX>).
+
=head1 CONFORMING TO
SHA: US Federal Information Processing Standard FIPS PUB 180 (Secure Hash
diff -pru openssl/FAQ openssl-1.0.0-dev-patched/FAQ
--- openssl/FAQ 2009-10-23 14:36:41.000000000 +0200
+++ openssl-1.0.0-dev-patched/FAQ 2009-11-20 02:35:47.000000000 +0100
@@ -182,6 +182,9 @@ offer legal advice.
You can configure OpenSSL so as not to use IDEA, MDC2 and RC5 by using
./config no-idea no-mdc2 no-rc5
+It should be noted that the patent for MDC2 has now expired (see <URL:
+https://ramps.uspto.gov/eram/getMaintFeesInfo.do?patentNum=4908861&applicationNum=07090633>).
+
* Can I use OpenSSL with GPL software?
@@ -619,7 +622,7 @@ A possible way around this is to persuad
version of Red Hat Linux.
FYI: Patent numbers and expiry dates of US patents:
-MDC-2: 4,908,861 13/03/2007
+MDC-2: 4,908,861 13/03/2007 (now expired)
IDEA: 5,214,703 25/05/2010
RC5: 5,724,428 03/03/2015
diff -pru openssl/README openssl-1.0.0-dev-patched/README
--- openssl/README 2009-08-12 18:44:33.000000000 +0200
+++ openssl-1.0.0-dev-patched/README 2009-11-19 01:26:17.000000000 +0100
@@ -50,7 +50,7 @@
Digests
MD5 and MD2 message digest algorithms, fast implementations,
- SHA (SHA-0) and SHA-1 message digest algorithms,
+ SHA (SHA-0), SHA-1 and SHA-2 message digest algorithms,
MDC2 message digest. A DES based hash that is popular on smart cards.
Public Key
smime.p7s
Description: S/MIME cryptographic signature
