[patch 3/9] Add support for SHA224 - Mailing list pgsql-patches
From | Marko Kreen |
---|---|
Subject | [patch 3/9] Add support for SHA224 |
Date | |
Msg-id | 20060711195803.003321000@localhost.localdomain Whole thread Raw |
List | 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) --
pgsql-patches by date: