[patch 3/9] Add support for SHA224

From: Marko Kreen <markokr(at)gmail(dot)com>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 3/9] Add support for SHA224
Date: 2006-07-11 19:57:36
Message-ID: 20060711195803.003321000@localhost.localdomain
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers pgsql-patches

SHA224 is cut-down SHA256 with different init vector,
let the sha2.c provide it also.

New revision of DSA standard includes SHA224, thus also upcoming
update to RFC2440 (OpenPGP).

Therefore, it is good to have it available.

Index: pgsql/contrib/pgcrypto/sha2.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/sha2.c
--- pgsql/contrib/pgcrypto/sha2.c
*************** static const uint32 K256[64] = {
*** 189,194 ****
--- 189,206 ----
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};

+ /* Initial hash value H for SHA-224: */
+ static const uint32 sha224_initial_hash_value[8] = {
+ 0xc1059ed8UL,
+ 0x367cd507UL,
+ 0x3070dd17UL,
+ 0xf70e5939UL,
+ 0xffc00b31UL,
+ 0x68581511UL,
+ 0x64f98fa7UL,
+ 0xbefa4fa4UL
+ };
+
/* Initial hash value H for SHA-256: */
static const uint32 sha256_initial_hash_value[8] = {
0x6a09e667UL,
*************** SHA256_Update(SHA256_CTX * context, cons
*** 521,575 ****
usedspace = freespace = 0;
}

! void
! SHA256_Final(uint8 digest[], SHA256_CTX * context)
{
unsigned int usedspace;

! /* If no digest buffer is passed, we don't bother doing this: */
! if (digest != NULL)
! {
! usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
#if BYTE_ORDER == LITTLE_ENDIAN
! /* Convert FROM host byte order */
! REVERSE64(context->bitcount, context->bitcount);
#endif
! if (usedspace > 0)
! {
! /* Begin padding with a 1 bit: */
! context->buffer[usedspace++] = 0x80;
!
! if (usedspace <= SHA256_SHORT_BLOCK_LENGTH)
! {
! /* Set-up for the last transform: */
! memset(&context->buffer[usedspace], 0, SHA256_SHORT_BLOCK_LENGTH - usedspace);
! }
! else
! {
! if (usedspace < SHA256_BLOCK_LENGTH)
! {
! memset(&context->buffer[usedspace], 0, SHA256_BLOCK_LENGTH - usedspace);
! }
! /* Do second-to-last transform: */
! SHA256_Transform(context, context->buffer);

! /* And set-up for the last transform: */
! memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
! }
}
else
{
! /* Set-up for the last transform: */
! memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);

! /* Begin padding with a 1 bit: */
! *context->buffer = 0x80;
}
! /* Set the bit count: */
! *(uint64 *) &context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;

! /* Final transform: */
! SHA256_Transform(context, context->buffer);

#if BYTE_ORDER == LITTLE_ENDIAN
{
--- 533,593 ----
usedspace = freespace = 0;
}

! static void
! SHA256_Last(SHA256_CTX *context)
{
unsigned int usedspace;

! usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
#if BYTE_ORDER == LITTLE_ENDIAN
! /* Convert FROM host byte order */
! REVERSE64(context->bitcount, context->bitcount);
#endif
! if (usedspace > 0)
! {
! /* Begin padding with a 1 bit: */
! context->buffer[usedspace++] = 0x80;

! if (usedspace <= SHA256_SHORT_BLOCK_LENGTH)
! {
! /* Set-up for the last transform: */
! memset(&context->buffer[usedspace], 0, SHA256_SHORT_BLOCK_LENGTH - usedspace);
}
else
{
! if (usedspace < SHA256_BLOCK_LENGTH)
! {
! memset(&context->buffer[usedspace], 0, SHA256_BLOCK_LENGTH - usedspace);
! }
! /* Do second-to-last transform: */
! SHA256_Transform(context, context->buffer);

! /* And set-up for the last transform: */
! memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
}
! }
! else
! {
! /* Set-up for the last transform: */
! memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
!
! /* Begin padding with a 1 bit: */
! *context->buffer = 0x80;
! }
! /* Set the bit count: */
! *(uint64 *) &context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;

! /* Final transform: */
! SHA256_Transform(context, context->buffer);
! }
!
! void
! SHA256_Final(uint8 digest[], SHA256_CTX * context)
! {
! /* If no digest buffer is passed, we don't bother doing this: */
! if (digest != NULL)
! {
! SHA256_Last(context);

#if BYTE_ORDER == LITTLE_ENDIAN
{
*************** SHA256_Final(uint8 digest[], SHA256_CTX
*** 587,593 ****

/* Clean up state data: */
memset(context, 0, sizeof(*context));
- usedspace = 0;
}


--- 605,610 ----
*************** SHA384_Final(uint8 digest[], SHA384_CTX
*** 963,965 ****
--- 980,1026 ----
/* Zero out state data */
memset(context, 0, sizeof(*context));
}
+
+ /*** SHA-224: *********************************************************/
+ void
+ SHA224_Init(SHA224_CTX * context)
+ {
+ if (context == NULL)
+ return;
+ memcpy(context->state, sha224_initial_hash_value, SHA256_DIGEST_LENGTH);
+ memset(context->buffer, 0, SHA256_BLOCK_LENGTH);
+ context->bitcount = 0;
+ }
+
+ void
+ SHA224_Update(SHA224_CTX * context, const uint8 *data, size_t len)
+ {
+ SHA256_Update((SHA256_CTX *) context, data, len);
+ }
+
+ void
+ SHA224_Final(uint8 digest[], SHA224_CTX * context)
+ {
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != NULL)
+ {
+ SHA256_Last(context);
+
+ #if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+
+ for (j = 0; j < 8; j++)
+ {
+ REVERSE32(context->state[j], context->state[j]);
+ }
+ }
+ #endif
+ memcpy(digest, context->state, SHA224_DIGEST_LENGTH);
+ }
+
+ /* Clean up state data: */
+ memset(context, 0, sizeof(*context));
+ }
+
Index: pgsql/contrib/pgcrypto/sha2.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/sha2.h
--- pgsql/contrib/pgcrypto/sha2.h
***************
*** 49,55 ****
#define SHA512_Update pg_SHA512_Update
#define SHA512_Final pg_SHA512_Final

! /*** SHA-256/384/512 Various Length Definitions ***********************/
#define SHA256_BLOCK_LENGTH 64
#define SHA256_DIGEST_LENGTH 32
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
--- 49,58 ----
#define SHA512_Update pg_SHA512_Update
#define SHA512_Final pg_SHA512_Final

! /*** SHA-224/256/384/512 Various Length Definitions ***********************/
! #define SHA224_BLOCK_LENGTH 64
! #define SHA224_DIGEST_LENGTH 28
! #define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1)
#define SHA256_BLOCK_LENGTH 64
#define SHA256_DIGEST_LENGTH 32
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
*************** typedef struct _SHA512_CTX
*** 75,82 ****
--- 78,90 ----
uint8 buffer[SHA512_BLOCK_LENGTH];
} SHA512_CTX;

+ typedef SHA256_CTX SHA224_CTX;
typedef SHA512_CTX SHA384_CTX;

+ void SHA224_Init(SHA224_CTX *);
+ void SHA224_Update(SHA224_CTX *, const uint8 *, size_t);
+ void SHA224_Final(uint8[SHA224_DIGEST_LENGTH], SHA224_CTX *);
+
void SHA256_Init(SHA256_CTX *);
void SHA256_Update(SHA256_CTX *, const uint8 *, size_t);
void SHA256_Final(uint8[SHA256_DIGEST_LENGTH], SHA256_CTX *);
Index: pgsql/contrib/pgcrypto/internal.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/internal.c
--- pgsql/contrib/pgcrypto/internal.c
***************
*** 77,82 ****
--- 77,83 ----

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);
*************** static const struct int_digest
*** 91,96 ****
--- 92,98 ----
int_digest_list[] = {
{"md5", init_md5},
{"sha1", init_sha1},
+ {"sha224", init_sha224},
{"sha256", init_sha256},
{"sha384", init_sha384},
{"sha512", init_sha512},
*************** int_sha1_free(PX_MD * h)
*** 193,198 ****
--- 195,248 ----
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
*************** init_sha1(PX_MD * md)
*** 380,385 ****
--- 430,455 ----
}

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;
Index: pgsql/contrib/pgcrypto/expected/sha2.out
===================================================================
*** pgsql.orig/contrib/pgcrypto/expected/sha2.out
--- pgsql/contrib/pgcrypto/expected/sha2.out
***************
*** 1,6 ****
--- 1,37 ----
--
-- SHA2 family
--
+ -- SHA224
+ SELECT encode(digest('', 'sha224'), 'hex');
+ encode
+ ----------------------------------------------------------
+ d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
+ (1 row)
+
+ SELECT encode(digest('a', 'sha224'), 'hex');
+ encode
+ ----------------------------------------------------------
+ abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5
+ (1 row)
+
+ SELECT encode(digest('abc', 'sha224'), 'hex');
+ encode
+ ----------------------------------------------------------
+ 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7
+ (1 row)
+
+ SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha224'), 'hex');
+ encode
+ ----------------------------------------------------------
+ 75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525
+ (1 row)
+
+ SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha224'), 'hex');
+ encode
+ ----------------------------------------------------------
+ b50aecbe4e9bb0b57bc5f3ae760a8e01db24f203fb3cdcd13148046e
+ (1 row)
+
-- SHA256
SELECT encode(digest('', 'sha256'), 'hex');
encode
Index: pgsql/contrib/pgcrypto/sql/sha2.sql
===================================================================
*** pgsql.orig/contrib/pgcrypto/sql/sha2.sql
--- pgsql/contrib/pgcrypto/sql/sha2.sql
***************
*** 2,7 ****
--- 2,14 ----
-- SHA2 family
--

+ -- SHA224
+ SELECT encode(digest('', 'sha224'), 'hex');
+ SELECT encode(digest('a', 'sha224'), 'hex');
+ SELECT encode(digest('abc', 'sha224'), 'hex');
+ SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha224'), 'hex');
+ SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha224'), 'hex');
+
-- SHA256
SELECT encode(digest('', 'sha256'), 'hex');
SELECT encode(digest('a', 'sha256'), 'hex');
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
! SHA256/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 since 0.9.8
Any other digest algo no yes (1)
Blowfish yes yes
AES yes yes (2)

--

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Marko Kreen 2006-07-11 19:57:37 [patch 4/9] Fix use of CAST5 in regtests.
Previous Message Marko Kreen 2006-07-11 19:57:35 [patch 2/9] Fortuna tweaks

Browse pgsql-patches by date

  From Date Subject
Next Message Marko Kreen 2006-07-11 19:57:37 [patch 4/9] Fix use of CAST5 in regtests.
Previous Message Marko Kreen 2006-07-11 19:57:35 [patch 2/9] Fortuna tweaks