[patch 8/9] Provide SHA2 for older OpenSSL

From: Marko Kreen <markokr(at)gmail(dot)com>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 8/9] Provide SHA2 for older OpenSSL
Date: 2006-07-11 19:57:41
Message-ID: 20060711195804.402864000@localhost.localdomain
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers pgsql-patches

I'd like to promote SHA2 algortihms (SHA224/256/384/512)
to "always available" status. Problem is that OpenSSL
only provides them from version 0.9.8. Considering
that 0.9.7 has not yet replaced 0.9.6, the 0.9.8 version
won't be generally available for long time.

Following patch splits support for SHA2 out from internal.c
and then uses same trick as for AES to provide it for older
OpenSSL versions.

Index: pgsql/contrib/pgcrypto/internal-sha2.c
===================================================================
*** /dev/null
--- pgsql/contrib/pgcrypto/internal-sha2.c
***************
*** 0 ****
--- 1,317 ----
+ /*
+ * internal.c
+ * Wrapper for builtin functions
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.22 2005/07/18 17:12:54 tgl Exp $
+ */
+
+ #include "postgres.h"
+
+ #include <time.h>
+
+ #include "px.h"
+ #include "sha2.h"
+
+ void init_sha224(PX_MD * h);
+ void init_sha256(PX_MD * h);
+ void init_sha384(PX_MD * h);
+ void init_sha512(PX_MD * h);
+
+ /* SHA224 */
+
+ static unsigned
+ int_sha224_len(PX_MD * h)
+ {
+ return SHA224_DIGEST_LENGTH;
+ }
+
+ static unsigned
+ int_sha224_block_len(PX_MD * h)
+ {
+ return SHA224_BLOCK_LENGTH;
+ }
+
+ static void
+ int_sha224_update(PX_MD * h, const uint8 *data, unsigned dlen)
+ {
+ SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
+
+ SHA224_Update(ctx, data, dlen);
+ }
+
+ static void
+ int_sha224_reset(PX_MD * h)
+ {
+ SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
+
+ SHA224_Init(ctx);
+ }
+
+ static void
+ int_sha224_finish(PX_MD * h, uint8 *dst)
+ {
+ SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
+
+ SHA224_Final(dst, ctx);
+ }
+
+ static void
+ int_sha224_free(PX_MD * h)
+ {
+ SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
+
+ memset(ctx, 0, sizeof(*ctx));
+ px_free(ctx);
+ px_free(h);
+ }
+
+ /* SHA256 */
+
+ static unsigned
+ int_sha256_len(PX_MD * h)
+ {
+ return SHA256_DIGEST_LENGTH;
+ }
+
+ static unsigned
+ int_sha256_block_len(PX_MD * h)
+ {
+ return SHA256_BLOCK_LENGTH;
+ }
+
+ static void
+ int_sha256_update(PX_MD * h, const uint8 *data, unsigned dlen)
+ {
+ SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
+
+ SHA256_Update(ctx, data, dlen);
+ }
+
+ static void
+ int_sha256_reset(PX_MD * h)
+ {
+ SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
+
+ SHA256_Init(ctx);
+ }
+
+ static void
+ int_sha256_finish(PX_MD * h, uint8 *dst)
+ {
+ SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
+
+ SHA256_Final(dst, ctx);
+ }
+
+ static void
+ int_sha256_free(PX_MD * h)
+ {
+ SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
+
+ memset(ctx, 0, sizeof(*ctx));
+ px_free(ctx);
+ px_free(h);
+ }
+
+ /* SHA384 */
+
+ static unsigned
+ int_sha384_len(PX_MD * h)
+ {
+ return SHA384_DIGEST_LENGTH;
+ }
+
+ static unsigned
+ int_sha384_block_len(PX_MD * h)
+ {
+ return SHA384_BLOCK_LENGTH;
+ }
+
+ static void
+ int_sha384_update(PX_MD * h, const uint8 *data, unsigned dlen)
+ {
+ SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
+
+ SHA384_Update(ctx, data, dlen);
+ }
+
+ static void
+ int_sha384_reset(PX_MD * h)
+ {
+ SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
+
+ SHA384_Init(ctx);
+ }
+
+ static void
+ int_sha384_finish(PX_MD * h, uint8 *dst)
+ {
+ SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
+
+ SHA384_Final(dst, ctx);
+ }
+
+ static void
+ int_sha384_free(PX_MD * h)
+ {
+ SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
+
+ memset(ctx, 0, sizeof(*ctx));
+ px_free(ctx);
+ px_free(h);
+ }
+
+ /* SHA512 */
+
+ static unsigned
+ int_sha512_len(PX_MD * h)
+ {
+ return SHA512_DIGEST_LENGTH;
+ }
+
+ static unsigned
+ int_sha512_block_len(PX_MD * h)
+ {
+ return SHA512_BLOCK_LENGTH;
+ }
+
+ static void
+ int_sha512_update(PX_MD * h, const uint8 *data, unsigned dlen)
+ {
+ SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
+
+ SHA512_Update(ctx, data, dlen);
+ }
+
+ static void
+ int_sha512_reset(PX_MD * h)
+ {
+ SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
+
+ SHA512_Init(ctx);
+ }
+
+ static void
+ int_sha512_finish(PX_MD * h, uint8 *dst)
+ {
+ SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
+
+ SHA512_Final(dst, ctx);
+ }
+
+ static void
+ int_sha512_free(PX_MD * h)
+ {
+ SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
+
+ memset(ctx, 0, sizeof(*ctx));
+ px_free(ctx);
+ px_free(h);
+ }
+
+ /* init functions */
+
+ void
+ init_sha224(PX_MD * md)
+ {
+ SHA224_CTX *ctx;
+
+ ctx = px_alloc(sizeof(*ctx));
+ memset(ctx, 0, sizeof(*ctx));
+
+ md->p.ptr = ctx;
+
+ md->result_size = int_sha224_len;
+ md->block_size = int_sha224_block_len;
+ md->reset = int_sha224_reset;
+ md->update = int_sha224_update;
+ md->finish = int_sha224_finish;
+ md->free = int_sha224_free;
+
+ md->reset(md);
+ }
+
+ void
+ init_sha256(PX_MD * md)
+ {
+ SHA256_CTX *ctx;
+
+ ctx = px_alloc(sizeof(*ctx));
+ memset(ctx, 0, sizeof(*ctx));
+
+ md->p.ptr = ctx;
+
+ md->result_size = int_sha256_len;
+ md->block_size = int_sha256_block_len;
+ md->reset = int_sha256_reset;
+ md->update = int_sha256_update;
+ md->finish = int_sha256_finish;
+ md->free = int_sha256_free;
+
+ md->reset(md);
+ }
+
+ void
+ init_sha384(PX_MD * md)
+ {
+ SHA384_CTX *ctx;
+
+ ctx = px_alloc(sizeof(*ctx));
+ memset(ctx, 0, sizeof(*ctx));
+
+ md->p.ptr = ctx;
+
+ md->result_size = int_sha384_len;
+ md->block_size = int_sha384_block_len;
+ md->reset = int_sha384_reset;
+ md->update = int_sha384_update;
+ md->finish = int_sha384_finish;
+ md->free = int_sha384_free;
+
+ md->reset(md);
+ }
+
+ void
+ init_sha512(PX_MD * md)
+ {
+ SHA512_CTX *ctx;
+
+ ctx = px_alloc(sizeof(*ctx));
+ memset(ctx, 0, sizeof(*ctx));
+
+ md->p.ptr = ctx;
+
+ md->result_size = int_sha512_len;
+ md->block_size = int_sha512_block_len;
+ md->reset = int_sha512_reset;
+ md->update = int_sha512_update;
+ md->finish = int_sha512_finish;
+ md->free = int_sha512_free;
+
+ md->reset(md);
+ }
+
Index: pgsql/contrib/pgcrypto/internal.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/internal.c
--- pgsql/contrib/pgcrypto/internal.c
***************
*** 77,86 ****

static void init_md5(PX_MD * h);
static void init_sha1(PX_MD * h);
! static void init_sha224(PX_MD * h);
! static void init_sha256(PX_MD * h);
! static void init_sha384(PX_MD * h);
! static void init_sha512(PX_MD * h);

struct int_digest
{
--- 77,87 ----

static void init_md5(PX_MD * h);
static void init_sha1(PX_MD * h);
!
! void init_sha224(PX_MD * h);
! void init_sha256(PX_MD * h);
! void init_sha384(PX_MD * h);
! void init_sha512(PX_MD * h);

struct int_digest
{
*************** int_sha1_free(PX_MD * h)
*** 195,392 ****
px_free(h);
}

- /* SHA224 */
-
- static unsigned
- int_sha224_len(PX_MD * h)
- {
- return SHA224_DIGEST_LENGTH;
- }
-
- static unsigned
- int_sha224_block_len(PX_MD * h)
- {
- return SHA224_BLOCK_LENGTH;
- }
-
- static void
- int_sha224_update(PX_MD * h, const uint8 *data, unsigned dlen)
- {
- SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
-
- SHA224_Update(ctx, data, dlen);
- }
-
- static void
- int_sha224_reset(PX_MD * h)
- {
- SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
-
- SHA224_Init(ctx);
- }
-
- static void
- int_sha224_finish(PX_MD * h, uint8 *dst)
- {
- SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
-
- SHA224_Final(dst, ctx);
- }
-
- static void
- int_sha224_free(PX_MD * h)
- {
- SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
-
- memset(ctx, 0, sizeof(*ctx));
- px_free(ctx);
- px_free(h);
- }
-
- /* SHA256 */
-
- static unsigned
- int_sha256_len(PX_MD * h)
- {
- return SHA256_DIGEST_LENGTH;
- }
-
- static unsigned
- int_sha256_block_len(PX_MD * h)
- {
- return SHA256_BLOCK_LENGTH;
- }
-
- static void
- int_sha256_update(PX_MD * h, const uint8 *data, unsigned dlen)
- {
- SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
-
- SHA256_Update(ctx, data, dlen);
- }
-
- static void
- int_sha256_reset(PX_MD * h)
- {
- SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
-
- SHA256_Init(ctx);
- }
-
- static void
- int_sha256_finish(PX_MD * h, uint8 *dst)
- {
- SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
-
- SHA256_Final(dst, ctx);
- }
-
- static void
- int_sha256_free(PX_MD * h)
- {
- SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
-
- memset(ctx, 0, sizeof(*ctx));
- px_free(ctx);
- px_free(h);
- }
-
- /* SHA384 */
-
- static unsigned
- int_sha384_len(PX_MD * h)
- {
- return SHA384_DIGEST_LENGTH;
- }
-
- static unsigned
- int_sha384_block_len(PX_MD * h)
- {
- return SHA384_BLOCK_LENGTH;
- }
-
- static void
- int_sha384_update(PX_MD * h, const uint8 *data, unsigned dlen)
- {
- SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
-
- SHA384_Update(ctx, data, dlen);
- }
-
- static void
- int_sha384_reset(PX_MD * h)
- {
- SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
-
- SHA384_Init(ctx);
- }
-
- static void
- int_sha384_finish(PX_MD * h, uint8 *dst)
- {
- SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
-
- SHA384_Final(dst, ctx);
- }
-
- static void
- int_sha384_free(PX_MD * h)
- {
- SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
-
- memset(ctx, 0, sizeof(*ctx));
- px_free(ctx);
- px_free(h);
- }
-
- /* SHA512 */
-
- static unsigned
- int_sha512_len(PX_MD * h)
- {
- return SHA512_DIGEST_LENGTH;
- }
-
- static unsigned
- int_sha512_block_len(PX_MD * h)
- {
- return SHA512_BLOCK_LENGTH;
- }
-
- static void
- int_sha512_update(PX_MD * h, const uint8 *data, unsigned dlen)
- {
- SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
-
- SHA512_Update(ctx, data, dlen);
- }
-
- static void
- int_sha512_reset(PX_MD * h)
- {
- SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
-
- SHA512_Init(ctx);
- }
-
- static void
- int_sha512_finish(PX_MD * h, uint8 *dst)
- {
- SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
-
- SHA512_Final(dst, ctx);
- }
-
- static void
- int_sha512_free(PX_MD * h)
- {
- SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
-
- memset(ctx, 0, sizeof(*ctx));
- px_free(ctx);
- px_free(h);
- }
-
/* init functions */

static void
--- 196,201 ----
*************** init_sha1(PX_MD * md)
*** 429,514 ****
md->reset(md);
}

- static void
- init_sha224(PX_MD * md)
- {
- SHA224_CTX *ctx;
-
- ctx = px_alloc(sizeof(*ctx));
- memset(ctx, 0, sizeof(*ctx));
-
- md->p.ptr = ctx;
-
- md->result_size = int_sha224_len;
- md->block_size = int_sha224_block_len;
- md->reset = int_sha224_reset;
- md->update = int_sha224_update;
- md->finish = int_sha224_finish;
- md->free = int_sha224_free;
-
- md->reset(md);
- }
-
- static void
- init_sha256(PX_MD * md)
- {
- SHA256_CTX *ctx;
-
- ctx = px_alloc(sizeof(*ctx));
- memset(ctx, 0, sizeof(*ctx));
-
- md->p.ptr = ctx;
-
- md->result_size = int_sha256_len;
- md->block_size = int_sha256_block_len;
- md->reset = int_sha256_reset;
- md->update = int_sha256_update;
- md->finish = int_sha256_finish;
- md->free = int_sha256_free;
-
- md->reset(md);
- }
-
- static void
- init_sha384(PX_MD * md)
- {
- SHA384_CTX *ctx;
-
- ctx = px_alloc(sizeof(*ctx));
- memset(ctx, 0, sizeof(*ctx));
-
- md->p.ptr = ctx;
-
- md->result_size = int_sha384_len;
- md->block_size = int_sha384_block_len;
- md->reset = int_sha384_reset;
- md->update = int_sha384_update;
- md->finish = int_sha384_finish;
- md->free = int_sha384_free;
-
- md->reset(md);
- }
-
- static void
- init_sha512(PX_MD * md)
- {
- SHA512_CTX *ctx;
-
- ctx = px_alloc(sizeof(*ctx));
- memset(ctx, 0, sizeof(*ctx));
-
- md->p.ptr = ctx;
-
- md->result_size = int_sha512_len;
- md->block_size = int_sha512_block_len;
- md->reset = int_sha512_reset;
- md->update = int_sha512_update;
- md->finish = int_sha512_finish;
- md->free = int_sha512_free;
-
- md->reset(md);
- }
-
/*
* ciphers generally
*/
--- 238,243 ----
Index: pgsql/contrib/pgcrypto/openssl.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/openssl.c
--- pgsql/contrib/pgcrypto/openssl.c
*************** static int EVP_DigestFinal_ex(EVP_MD_CTX
*** 147,152 ****
--- 147,184 ----
#endif /* old OpenSSL */

/*
+ * Provide SHA2 for older OpenSSL < 0.9.8
+ */
+ #if OPENSSL_VERSION_NUMBER < 0x00908000L
+
+ #include "sha2.c"
+ #include "internal-sha2.c"
+
+ typedef int (*init_f)(PX_MD *md);
+
+ static int compat_find_digest(const char *name, PX_MD **res)
+ {
+ init_f init = NULL;
+ if (pg_strcasecmp(name, "sha224") == 0)
+ init = init_sha224;
+ else if (pg_strcasecmp(name, "sha256") == 0)
+ init = init_sha256;
+ else if (pg_strcasecmp(name, "sha384") == 0)
+ init = init_sha384;
+ else if (pg_strcasecmp(name, "sha512") == 0)
+ init = init_sha512;
+ else
+ return PXE_NO_HASH;
+ *res = px_alloc(sizeof(PX_MD));
+ init(*res);
+ return 0;
+ }
+
+ #else
+ #define compat_find_digest(name, res) (PXE_NO_HASH)
+ #endif
+
+ /*
* Hashes
*/

*************** px_find_digest(const char *name, PX_MD *
*** 223,229 ****

md = EVP_get_digestbyname(name);
if (md == NULL)
! return PXE_NO_HASH;

digest = px_alloc(sizeof(*digest));
digest->algo = md;
--- 255,261 ----

md = EVP_get_digestbyname(name);
if (md == NULL)
! return compat_find_digest(name, res);

digest = px_alloc(sizeof(*digest));
digest->algo = md;
Index: pgsql/contrib/pgcrypto/Makefile
===================================================================
*** pgsql.orig/contrib/pgcrypto/Makefile
--- pgsql/contrib/pgcrypto/Makefile
***************
*** 2,13 ****
# $PostgreSQL: pgsql/contrib/pgcrypto/Makefile,v 1.22 2005/08/13 02:06:20 momjian Exp $
#

! INT_SRCS = md5.c sha1.c sha2.c internal.c blf.c rijndael.c \
fortuna.c random.c pgp-mpi-internal.c
INT_TESTS = sha2

OSSL_SRCS = openssl.c pgp-mpi-openssl.c
! OSSL_TESTS = des 3des cast5

ZLIB_OFF_CFLAGS = -DDISABLE_ZLIB
ZLIB_TST = pgp-compression
--- 2,13 ----
# $PostgreSQL: pgsql/contrib/pgcrypto/Makefile,v 1.22 2005/08/13 02:06:20 momjian Exp $
#

! INT_SRCS = md5.c sha1.c sha2.c internal.c internal-sha2.c blf.c rijndael.c \
fortuna.c random.c pgp-mpi-internal.c
INT_TESTS = sha2

OSSL_SRCS = openssl.c pgp-mpi-openssl.c
! OSSL_TESTS = sha2 des 3des cast5

ZLIB_OFF_CFLAGS = -DDISABLE_ZLIB
ZLIB_TST = pgp-compression
Index: pgsql/contrib/pgcrypto/README.pgcrypto
===================================================================
*** pgsql.orig/contrib/pgcrypto/README.pgcrypto
--- pgsql/contrib/pgcrypto/README.pgcrypto
*************** There are some other differences with an
*** 49,55 ****
----------------------------------------------------
MD5 yes yes
SHA1 yes yes
! SHA224/256/384/512 yes since 0.9.8
Any other digest algo no yes (1)
Blowfish yes yes
AES yes yes (2)
--- 49,55 ----
----------------------------------------------------
MD5 yes yes
SHA1 yes yes
! SHA224/256/384/512 yes yes (3)
Any other digest algo no yes (1)
Blowfish yes yes
AES yes yes (2)
*************** There are some other differences with an
*** 67,72 ****
--- 67,75 ----
compiled against older version, it will use built-in AES code,
so it has AES always available.

+ 3. SHA2 algorithms were added to OpenSSL in version 0.9.8. For
+ older versions, pgcrypto will use built-in code.
+

2.2. NULL handling
~~~~~~~~~~~~~~~~~~~~

--

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Marko Kreen 2006-07-11 19:57:42 [patch 9/9] Include code for bignum math
Previous Message Marko Kreen 2006-07-11 19:57:40 [patch 7/9] remove file misc.c

Browse pgsql-patches by date

  From Date Subject
Next Message Marko Kreen 2006-07-11 19:57:42 [patch 9/9] Include code for bignum math
Previous Message Marko Kreen 2006-07-11 19:57:40 [patch 7/9] remove file misc.c