From aedceb9f36ef87df87d448cf32639ed6da35e820 Mon Sep 17 00:00:00 2001 From: jsing Date: Fri, 29 Mar 2024 02:41:49 +0000 Subject: [PATCH] Consolidate whirlpool into a single C file. Buy a vowel at the same time, since we're no longer limited to 8.3 file names. Discussed with tb@ --- lib/libcrypto/Makefile | 5 +- .../whrlpool/{wp_block.c => whirlpool.c} | 230 ++++++++++++++- lib/libcrypto/whrlpool/wp_dgst.c | 267 ------------------ lib/libcrypto/whrlpool/wp_local.h | 11 - 4 files changed, 229 insertions(+), 284 deletions(-) rename lib/libcrypto/whrlpool/{wp_block.c => whirlpool.c} (81%) delete mode 100644 lib/libcrypto/whrlpool/wp_dgst.c delete mode 100644 lib/libcrypto/whrlpool/wp_local.h diff --git a/lib/libcrypto/Makefile b/lib/libcrypto/Makefile index d3533412fdc..b763757ebf6 100644 --- a/lib/libcrypto/Makefile +++ b/lib/libcrypto/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.186 2024/03/29 02:33:44 jsing Exp $ +# $OpenBSD: Makefile,v 1.187 2024/03/29 02:41:49 jsing Exp $ LIB= crypto LIBREBUILD=y @@ -557,8 +557,7 @@ SRCS+= ui_openssl.c SRCS+= ui_util.c # whrlpool/ -SRCS+= wp_block.c -SRCS+= wp_dgst.c +SRCS+= whirlpool.c # x509/ SRCS+= by_dir.c diff --git a/lib/libcrypto/whrlpool/wp_block.c b/lib/libcrypto/whrlpool/whirlpool.c similarity index 81% rename from lib/libcrypto/whrlpool/wp_block.c rename to lib/libcrypto/whrlpool/whirlpool.c index ad814a3463f..217c5a919b0 100644 --- a/lib/libcrypto/whrlpool/wp_block.c +++ b/lib/libcrypto/whrlpool/whirlpool.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wp_block.c,v 1.15 2022/11/26 16:08:54 tb Exp $ */ +/* $OpenBSD: whirlpool.c,v 1.1 2024/03/29 02:41:49 jsing Exp $ */ /** * The Whirlpool hashing function. * @@ -36,11 +36,27 @@ * */ +/* + * OpenSSL-specific implementation notes. + * + * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect + * number of *bytes* as input length argument. Bit-oriented routine + * as specified by authors is called WHIRLPOOL_BitUpdate[!] and + * does not have one-stroke counterpart. + * + * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially + * to serve WHIRLPOOL_Update. This is done for performance. + * + * Unlike authors' reference implementation, block processing + * routine whirlpool_block is designed to operate on multi-block + * input. This is done for performance. + */ + #include #include -#include -#include "wp_local.h" +#include +#include typedef unsigned char u8; #if defined(_LP64) @@ -627,3 +643,211 @@ void whirlpool_block(WHIRLPOOL_CTX *ctx,const void *inp,size_t n) p += 64; } while(--n); } + +int +WHIRLPOOL_Init(WHIRLPOOL_CTX *c) +{ + memset (c, 0, sizeof(*c)); + return (1); +} + +int +WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *_inp, size_t bytes) +{ + /* Well, largest suitable chunk size actually is + * (1<<(sizeof(size_t)*8-3))-64, but below number + * is large enough for not to care about excessive + * calls to WHIRLPOOL_BitUpdate... */ + size_t chunk = ((size_t)1) << (sizeof(size_t)*8 - 4); + const unsigned char *inp = _inp; + + while (bytes >= chunk) { + WHIRLPOOL_BitUpdate(c, inp, chunk*8); + bytes -= chunk; + inp += chunk; + } + if (bytes) + WHIRLPOOL_BitUpdate(c, inp, bytes*8); + + return (1); +} + +void +WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) +{ + size_t n; + unsigned int bitoff = c->bitoff, + bitrem = bitoff % 8, + inpgap = (8 - (unsigned int)bits % 8)&7; + const unsigned char *inp = _inp; + + /* This 256-bit increment procedure relies on the size_t + * being natural size of CPU register, so that we don't + * have to mask the value in order to detect overflows. */ + c->bitlen[0] += bits; + if (c->bitlen[0] < bits) /* overflow */ + { + n = 1; + do { + c->bitlen[n]++; + } while (c->bitlen[n]==0 && + ++n < (WHIRLPOOL_COUNTER/sizeof(size_t))); + } + +#ifndef OPENSSL_SMALL_FOOTPRINT +reconsider: + if (inpgap==0 && bitrem==0) /* byte-oriented loop */ + { + while (bits) { + if (bitoff == 0 && (n = bits/WHIRLPOOL_BBLOCK)) { + whirlpool_block(c, inp, n); + inp += n*WHIRLPOOL_BBLOCK/8; + bits %= WHIRLPOOL_BBLOCK; + } else { + unsigned int byteoff = bitoff/8; + + bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */ + if (bits >= bitrem) { + bits -= bitrem; + bitrem /= 8; + memcpy(c->data + byteoff, inp, bitrem); + inp += bitrem; + whirlpool_block(c, c->data, 1); + bitoff = 0; + } else { + memcpy(c->data + byteoff, inp, bits/8); + bitoff += (unsigned int)bits; + bits = 0; + } + c->bitoff = bitoff; + } + } + } + else /* bit-oriented loop */ +#endif + { + /* + inp + | + +-------+-------+------- + ||||||||||||||||||||| + +-------+-------+------- + +-------+-------+-------+-------+------- + |||||||||||||| c->data + +-------+-------+-------+-------+------- + | + c->bitoff/8 + */ + while (bits) { + unsigned int byteoff = bitoff/8; + unsigned char b; + +#ifndef OPENSSL_SMALL_FOOTPRINT + if (bitrem == inpgap) { + c->data[byteoff++] |= inp[0] & (0xff >> inpgap); + inpgap = 8 - inpgap; + bitoff += inpgap; bitrem = 0; /* bitoff%8 */ + bits -= inpgap; inpgap = 0; /* bits%8 */ + inp++; + if (bitoff == WHIRLPOOL_BBLOCK) { + whirlpool_block(c, c->data, 1); + bitoff = 0; + } + c->bitoff = bitoff; + goto reconsider; + } else +#endif + if (bits >= 8) { + b = ((inp[0]<>(8 - inpgap))); + b &= 0xff; + if (bitrem) + c->data[byteoff++] |= b >> bitrem; + else + c->data[byteoff++] = b; + bitoff += 8; + bits -= 8; + inp++; + if (bitoff >= WHIRLPOOL_BBLOCK) { + whirlpool_block(c, c->data, 1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) + c->data[byteoff] = b << (8 - bitrem); + } + else /* remaining less than 8 bits */ + { + b = (inp[0]<data[byteoff++] |= b >> bitrem; + else + c->data[byteoff++] = b; + bitoff += (unsigned int)bits; + if (bitoff == WHIRLPOOL_BBLOCK) { + whirlpool_block(c, c->data, 1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) + c->data[byteoff] = b << (8 - bitrem); + bits = 0; + } + c->bitoff = bitoff; + } + } +} + +int +WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c) +{ + unsigned int bitoff = c->bitoff, + byteoff = bitoff/8; + size_t i, j, v; + unsigned char *p; + + bitoff %= 8; + if (bitoff) + c->data[byteoff] |= 0x80 >> bitoff; + else + c->data[byteoff] = 0x80; + byteoff++; + + /* pad with zeros */ + if (byteoff > (WHIRLPOOL_BBLOCK/8 - WHIRLPOOL_COUNTER)) { + if (byteoff < WHIRLPOOL_BBLOCK/8) + memset(&c->data[byteoff], 0, WHIRLPOOL_BBLOCK/8 - byteoff); + whirlpool_block(c, c->data, 1); + byteoff = 0; + } + if (byteoff < (WHIRLPOOL_BBLOCK/8 - WHIRLPOOL_COUNTER)) + memset(&c->data[byteoff], 0, + (WHIRLPOOL_BBLOCK/8 - WHIRLPOOL_COUNTER) - byteoff); + /* smash 256-bit c->bitlen in big-endian order */ + p = &c->data[WHIRLPOOL_BBLOCK/8-1]; /* last byte in c->data */ + for (i = 0; i < WHIRLPOOL_COUNTER/sizeof(size_t); i++) + for (v = c->bitlen[i], j = 0; j < sizeof(size_t); j++, v >>= 8) + *p-- = (unsigned char)(v&0xff); + + whirlpool_block(c, c->data, 1); + + if (md) { + memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH); + memset(c, 0, sizeof(*c)); + return (1); + } + return (0); +} + +unsigned char * +WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md) +{ + WHIRLPOOL_CTX ctx; + static unsigned char m[WHIRLPOOL_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + WHIRLPOOL_Init(&ctx); + WHIRLPOOL_Update(&ctx, inp, bytes); + WHIRLPOOL_Final(md, &ctx); + return (md); +} diff --git a/lib/libcrypto/whrlpool/wp_dgst.c b/lib/libcrypto/whrlpool/wp_dgst.c deleted file mode 100644 index 0e7c9c56d9e..00000000000 --- a/lib/libcrypto/whrlpool/wp_dgst.c +++ /dev/null @@ -1,267 +0,0 @@ -/* $OpenBSD: wp_dgst.c,v 1.8 2024/03/29 00:16:22 jsing Exp $ */ -/** - * The Whirlpool hashing function. - * - *

- * References - * - *

- * The Whirlpool algorithm was developed by - * Paulo S. L. M. Barreto and - * Vincent Rijmen. - * - * See - * P.S.L.M. Barreto, V. Rijmen, - * ``The Whirlpool hashing function,'' - * NESSIE submission, 2000 (tweaked version, 2001), - * - * - * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and - * Vincent Rijmen. Lookup "reference implementations" on - * - * - * ============================================================================= - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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. - * - */ - -/* - * OpenSSL-specific implementation notes. - * - * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect - * number of *bytes* as input length argument. Bit-oriented routine - * as specified by authors is called WHIRLPOOL_BitUpdate[!] and - * does not have one-stroke counterpart. - * - * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially - * to serve WHIRLPOOL_Update. This is done for performance. - * - * Unlike authors' reference implementation, block processing - * routine whirlpool_block is designed to operate on multi-block - * input. This is done for performance. - */ - -#include - -#include - -#include "wp_local.h" - -int -WHIRLPOOL_Init(WHIRLPOOL_CTX *c) -{ - memset (c, 0, sizeof(*c)); - return (1); -} - -int -WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *_inp, size_t bytes) -{ - /* Well, largest suitable chunk size actually is - * (1<<(sizeof(size_t)*8-3))-64, but below number - * is large enough for not to care about excessive - * calls to WHIRLPOOL_BitUpdate... */ - size_t chunk = ((size_t)1) << (sizeof(size_t)*8 - 4); - const unsigned char *inp = _inp; - - while (bytes >= chunk) { - WHIRLPOOL_BitUpdate(c, inp, chunk*8); - bytes -= chunk; - inp += chunk; - } - if (bytes) - WHIRLPOOL_BitUpdate(c, inp, bytes*8); - - return (1); -} - -void -WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) -{ - size_t n; - unsigned int bitoff = c->bitoff, - bitrem = bitoff % 8, - inpgap = (8 - (unsigned int)bits % 8)&7; - const unsigned char *inp = _inp; - - /* This 256-bit increment procedure relies on the size_t - * being natural size of CPU register, so that we don't - * have to mask the value in order to detect overflows. */ - c->bitlen[0] += bits; - if (c->bitlen[0] < bits) /* overflow */ - { - n = 1; - do { - c->bitlen[n]++; - } while (c->bitlen[n]==0 && - ++n < (WHIRLPOOL_COUNTER/sizeof(size_t))); - } - -#ifndef OPENSSL_SMALL_FOOTPRINT -reconsider: - if (inpgap==0 && bitrem==0) /* byte-oriented loop */ - { - while (bits) { - if (bitoff == 0 && (n = bits/WHIRLPOOL_BBLOCK)) { - whirlpool_block(c, inp, n); - inp += n*WHIRLPOOL_BBLOCK/8; - bits %= WHIRLPOOL_BBLOCK; - } else { - unsigned int byteoff = bitoff/8; - - bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */ - if (bits >= bitrem) { - bits -= bitrem; - bitrem /= 8; - memcpy(c->data + byteoff, inp, bitrem); - inp += bitrem; - whirlpool_block(c, c->data, 1); - bitoff = 0; - } else { - memcpy(c->data + byteoff, inp, bits/8); - bitoff += (unsigned int)bits; - bits = 0; - } - c->bitoff = bitoff; - } - } - } - else /* bit-oriented loop */ -#endif - { - /* - inp - | - +-------+-------+------- - ||||||||||||||||||||| - +-------+-------+------- - +-------+-------+-------+-------+------- - |||||||||||||| c->data - +-------+-------+-------+-------+------- - | - c->bitoff/8 - */ - while (bits) { - unsigned int byteoff = bitoff/8; - unsigned char b; - -#ifndef OPENSSL_SMALL_FOOTPRINT - if (bitrem == inpgap) { - c->data[byteoff++] |= inp[0] & (0xff >> inpgap); - inpgap = 8 - inpgap; - bitoff += inpgap; bitrem = 0; /* bitoff%8 */ - bits -= inpgap; inpgap = 0; /* bits%8 */ - inp++; - if (bitoff == WHIRLPOOL_BBLOCK) { - whirlpool_block(c, c->data, 1); - bitoff = 0; - } - c->bitoff = bitoff; - goto reconsider; - } else -#endif - if (bits >= 8) { - b = ((inp[0]<>(8 - inpgap))); - b &= 0xff; - if (bitrem) - c->data[byteoff++] |= b >> bitrem; - else - c->data[byteoff++] = b; - bitoff += 8; - bits -= 8; - inp++; - if (bitoff >= WHIRLPOOL_BBLOCK) { - whirlpool_block(c, c->data, 1); - byteoff = 0; - bitoff %= WHIRLPOOL_BBLOCK; - } - if (bitrem) - c->data[byteoff] = b << (8 - bitrem); - } - else /* remaining less than 8 bits */ - { - b = (inp[0]<data[byteoff++] |= b >> bitrem; - else - c->data[byteoff++] = b; - bitoff += (unsigned int)bits; - if (bitoff == WHIRLPOOL_BBLOCK) { - whirlpool_block(c, c->data, 1); - byteoff = 0; - bitoff %= WHIRLPOOL_BBLOCK; - } - if (bitrem) - c->data[byteoff] = b << (8 - bitrem); - bits = 0; - } - c->bitoff = bitoff; - } - } -} - -int -WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c) -{ - unsigned int bitoff = c->bitoff, - byteoff = bitoff/8; - size_t i, j, v; - unsigned char *p; - - bitoff %= 8; - if (bitoff) - c->data[byteoff] |= 0x80 >> bitoff; - else - c->data[byteoff] = 0x80; - byteoff++; - - /* pad with zeros */ - if (byteoff > (WHIRLPOOL_BBLOCK/8 - WHIRLPOOL_COUNTER)) { - if (byteoff < WHIRLPOOL_BBLOCK/8) - memset(&c->data[byteoff], 0, WHIRLPOOL_BBLOCK/8 - byteoff); - whirlpool_block(c, c->data, 1); - byteoff = 0; - } - if (byteoff < (WHIRLPOOL_BBLOCK/8 - WHIRLPOOL_COUNTER)) - memset(&c->data[byteoff], 0, - (WHIRLPOOL_BBLOCK/8 - WHIRLPOOL_COUNTER) - byteoff); - /* smash 256-bit c->bitlen in big-endian order */ - p = &c->data[WHIRLPOOL_BBLOCK/8-1]; /* last byte in c->data */ - for (i = 0; i < WHIRLPOOL_COUNTER/sizeof(size_t); i++) - for (v = c->bitlen[i], j = 0; j < sizeof(size_t); j++, v >>= 8) - *p-- = (unsigned char)(v&0xff); - - whirlpool_block(c, c->data, 1); - - if (md) { - memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH); - memset(c, 0, sizeof(*c)); - return (1); - } - return (0); -} - -unsigned char * -WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md) -{ - WHIRLPOOL_CTX ctx; - static unsigned char m[WHIRLPOOL_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - WHIRLPOOL_Init(&ctx); - WHIRLPOOL_Update(&ctx, inp, bytes); - WHIRLPOOL_Final(md, &ctx); - return (md); -} diff --git a/lib/libcrypto/whrlpool/wp_local.h b/lib/libcrypto/whrlpool/wp_local.h deleted file mode 100644 index 892dce23b67..00000000000 --- a/lib/libcrypto/whrlpool/wp_local.h +++ /dev/null @@ -1,11 +0,0 @@ -/* $OpenBSD: wp_local.h,v 1.2 2023/09/04 08:43:41 tb Exp $ */ - -#include - -#include - -__BEGIN_HIDDEN_DECLS - -void whirlpool_block(WHIRLPOOL_CTX *,const void *,size_t); - -__END_HIDDEN_DECLS -- 2.20.1