Thread: [patch 8/9] Provide SHA2 for older OpenSSL

[patch 8/9] Provide SHA2 for older OpenSSL

From
Marko Kreen
Date:
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
  ~~~~~~~~~~~~~~~~~~~~

--