This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] sha2: new header <sha2.h>
- From: Adhemerval Zanella <adhemerval dot zanella at linaro dot org>
- To: Shawn Landden <shawn at churchofgit dot com>
- Cc: libc-alpha at sourceware dot org
- Date: Fri, 27 Mar 2015 15:11:40 -0300
- Subject: Re: [PATCH] sha2: new header <sha2.h>
- Authentication-results: sourceware.org; auth=none
- References: <87mw31thl3 dot fsf at mid dot deneb dot enyo dot de> <1427478211-368567-1-git-send-email-shawn at churchofgit dot com>
Hi,
To export the symbol you need to add them on crypt/Versions: just
create a new entry
for GLIBC 2.22.
> diff --git a/crypt/align.h b/crypt/align.h
> new file mode 100644
> index 0000000..957e1e8
> --- /dev/null
> +++ b/crypt/align.h
> @@ -0,0 +1,31 @@
>+#pragma once
>+
GLIBC does not use pragma once, please guard with usual way (ifdef
something...).
>+#if defined(__i386__) || defined(__x86_64__) || \
>+ defined(_M_IX86) || defined(_M_X64) || \
>+ defined(__ppc__) || defined(__ppc64__) || \
>+ defined(__powerpc__) || defined(__powerpc64__) || \
>+ defined(__s390__) || defined(__s390x__)
It is clean and safer to just use endian.h here.
>+}
>+
>+/* Process the remaining bytes in the internal buffer and the usual
>+ prolog according to the standard and write the result to RESBUF. */
>+void *
>+__sha256_finish_ctx (ctx, resbuf)
>+ sha256_ctx *ctx;
>+ void *resbuf;
>+{
>+ __sha256_finish_ctx_generic (ctx);
Do not declare using R&K style in new code. Same for other functions.
On Fri, Mar 27, 2015 at 2:43 PM, Shawn Landden <shawn@churchofgit.com> wrote:
> Export the SHA2 family of functions.
>
> I cannot figure out how to make these symbols not be stripped.
> ---
> crypt/Makefile | 6 ++--
> crypt/align.h | 31 +++++++++++++++++
> crypt/sha2.h | 52 ++++++++++++++++++++++++++++
> crypt/sha256-block.c | 4 +--
> crypt/sha256-crypt.c | 6 ++--
> crypt/sha256.c | 97 +++++++++++++++++++++++++++-------------------------
> crypt/sha256.h | 22 +++++++-----
> crypt/sha256test.c | 11 +++---
> crypt/sha512-block.c | 4 +--
> crypt/sha512-crypt.c | 6 ++--
> crypt/sha512.c | 89 +++++++++++++++++++++++++++--------------------
> crypt/sha512.h | 22 ++++++++----
> crypt/sha512test.c | 9 +++--
> 13 files changed, 237 insertions(+), 122 deletions(-)
> create mode 100644 crypt/align.h
> create mode 100644 crypt/sha2.h
>
> diff --git a/crypt/Makefile b/crypt/Makefile
> index 34c4dd7..3f839fc 100644
> --- a/crypt/Makefile
> +++ b/crypt/Makefile
> @@ -22,13 +22,13 @@ subdir := crypt
>
> include ../Makeconfig
>
> -headers := crypt.h
> +headers := crypt.h sha2.h
>
> extra-libs := libcrypt
> extra-libs-others := $(extra-libs)
>
> libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
> - crypt_util
> + crypt_util sha256 sha512
>
> tests := cert md5c-test sha256c-test sha512c-test badsalttest
>
> @@ -42,7 +42,7 @@ CPPFLAGS-sha512-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
> CPPFLAGS-md5-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
> LDLIBS-crypt.so = -lfreebl3
> else
> -libcrypt-routines += md5 sha256 sha512
> +libcrypt-routines += md5
>
> tests += md5test sha256test sha512test
>
> diff --git a/crypt/align.h b/crypt/align.h
> new file mode 100644
> index 0000000..957e1e8
> --- /dev/null
> +++ b/crypt/align.h
> @@ -0,0 +1,31 @@
> +#pragma once
> +
> +#if defined(__i386__) || defined(__x86_64__) || \
> + defined(_M_IX86) || defined(_M_X64) || \
> + defined(__ppc__) || defined(__ppc64__) || \
> + defined(__powerpc__) || defined(__powerpc64__) || \
> + defined(__s390__) || defined(__s390x__)
> +
> +#define put_be32(p, v) do { *(uint32_t *)(p) = be32toh(v); } while (0)
> +#define put_be64(p, v) do { *(uint64_t *)(p) = be64toh(v); } while (0)
> +
> +#else
> +
> +#define put_be32(p, v) do { \
> + unsigned int __v = (v); \
> + *((unsigned char *)(p) + 0) = __v >> 24; \
> + *((unsigned char *)(p) + 1) = __v >> 16; \
> + *((unsigned char *)(p) + 2) = __v >> 8; \
> + *((unsigned char *)(p) + 3) = __v >> 0; } while (0)
> +#define put_be64(p, v) do { \
> + unsigned int __v = (v); \
> + *((unsigned char *)(p) + 0) = __v >> 56; \
> + *((unsigned char *)(p) + 1) = __v >> 48; \
> + *((unsigned char *)(p) + 2) = __v >> 40; \
> + *((unsigned char *)(p) + 3) = __v >> 32; \
> + *((unsigned char *)(p) + 4) = __v >> 24; \
> + *((unsigned char *)(p) + 5) = __v >> 16; \
> + *((unsigned char *)(p) + 6) = __v >> 8; \
> + *((unsigned char *)(p) + 7) = __v >> 0; } while (0)
> +
> +#endif
> diff --git a/crypt/sha2.h b/crypt/sha2.h
> new file mode 100644
> index 0000000..ab4021c
> --- /dev/null
> +++ b/crypt/sha2.h
> @@ -0,0 +1,52 @@
> +/*
> + * SHA2: The SHA2 family of cryptographic functions
> + *
> + * Copyright (C) 2015 Free Software Foundation, Inc.
> + *
> + * The GNU C Library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * The GNU C Library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with the GNU C Library; if not, see
> + * <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef _SHA2_H
> +#define _SHA2_H
> +
> +#include <stdint.h>
> +
> +typedef struct {
> + char __internal_state[176];
> +} sha256_ctx __attribute__((aligned(16)));
> +
> +/* 256 bits is 32 bytes
> + * 224 bits is 28 bytes
> + */
> +void *sha256(const void *__restrict d, size_t n, void *__restrict md);
> +void sha256_init(sha256_ctx *s);
> +const void *sha256_update(sha256_ctx *__restrict s, const void *__restrict d, size_t n);
> +void sha256_finish(sha256_ctx *__restrict s, void *__restrict md);
> +void sha224_finish(sha256_ctx *__restrict s, void *__restrict md);
> +
> +typedef struct {
> + char __internal_state[352];
> +} sha512_ctx __attribute__((aligned(16)));
> +
> +/* 512 bits is 64 bytes
> + * 384 bits is 48 bytes
> + */
> +void *sha512(const void *__restrict d, size_t n, void *__restrict md);
> +void sha512_init(sha512_ctx *s);
> +const void *sha512_update(sha512_ctx *__restrict s, const void *__restrict d, size_t n);
> +void *sha512_finish(sha512_ctx *__restrict s, void *__restrict md);
> +void *sha384_finish(sha512_ctx *__restrict s, void *__restrict md);
> +
> +#endif
> diff --git a/crypt/sha256-block.c b/crypt/sha256-block.c
> index 8a77096..4fbf04b 100644
> --- a/crypt/sha256-block.c
> +++ b/crypt/sha256-block.c
> @@ -3,7 +3,7 @@
> /* Process LEN bytes of BUFFER, accumulating context into CTX.
> It is assumed that LEN % 64 == 0. */
> void
> -sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
> +sha256_process_block (const void *buffer, size_t len, sha256_ctx *ctx)
> {
> const uint32_t *words = buffer;
> size_t nwords = len / sizeof (uint32_t);
> @@ -50,7 +50,7 @@ sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
> /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */
> for (unsigned int t = 0; t < 16; ++t)
> {
> - W[t] = SWAP (*words);
> + W[t] = be32toh (*words);
> ++words;
> }
> for (unsigned int t = 16; t < 64; ++t)
> diff --git a/crypt/sha256-crypt.c b/crypt/sha256-crypt.c
> index d90e291..cdefa60 100644
> --- a/crypt/sha256-crypt.c
> +++ b/crypt/sha256-crypt.c
> @@ -68,7 +68,7 @@ typedef int PRBool;
> __sha256_init_ctx (ctxp)
>
> # define sha256_process_bytes(buf, len, ctxp, nss_ctxp) \
> - __sha256_process_bytes(buf, len, ctxp)
> + __sha256_process_bytes(ctxp, buf, len)
>
> # define sha256_finish_ctx(ctxp, nss_ctxp, result) \
> __sha256_finish_ctx (ctxp, result)
> @@ -189,8 +189,8 @@ __sha256_crypt_r (key, salt, buffer, buflen)
> NSSLOWHASHContext *nss_ctx = NULL;
> NSSLOWHASHContext *nss_alt_ctx = NULL;
> #else
> - struct sha256_ctx ctx;
> - struct sha256_ctx alt_ctx;
> + sha256_ctx ctx;
> + sha256_ctx alt_ctx;
> #endif
>
> /* Prepare for the real work. */
> diff --git a/crypt/sha256.c b/crypt/sha256.c
> index b6db8b2..f8e2810 100644
> --- a/crypt/sha256.c
> +++ b/crypt/sha256.c
> @@ -30,30 +30,7 @@
> #include <sys/types.h>
>
> #include "sha256.h"
> -
> -#if __BYTE_ORDER == __LITTLE_ENDIAN
> -# ifdef _LIBC
> -# include <byteswap.h>
> -# define SWAP(n) bswap_32 (n)
> -# define SWAP64(n) bswap_64 (n)
> -# else
> -# define SWAP(n) \
> - (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
> -# define SWAP64(n) \
> - (((n) << 56) \
> - | (((n) & 0xff00) << 40) \
> - | (((n) & 0xff0000) << 24) \
> - | (((n) & 0xff000000) << 8) \
> - | (((n) >> 8) & 0xff000000) \
> - | (((n) >> 24) & 0xff0000) \
> - | (((n) >> 40) & 0xff00) \
> - | ((n) >> 56))
> -# endif
> -#else
> -# define SWAP(n) (n)
> -# define SWAP64(n) (n)
> -#endif
> -
> +#include "align.h"
>
> /* This array contains the bytes used to pad the buffer to the next
> 64-byte boundary. (FIPS 180-2:5.1.1) */
> @@ -82,13 +59,13 @@ static const uint32_t K[64] =
> };
>
> void
> -sha256_process_block (const void *, size_t, struct sha256_ctx *);
> +sha256_process_block (const void *, size_t, sha256_ctx *);
>
> /* Initialize structure containing state of computation.
> (FIPS 180-2:5.3.2) */
> void
> __sha256_init_ctx (ctx)
> - struct sha256_ctx *ctx;
> + sha256_ctx *ctx;
> {
> ctx->H[0] = 0x6a09e667;
> ctx->H[1] = 0xbb67ae85;
> @@ -102,17 +79,10 @@ __sha256_init_ctx (ctx)
> ctx->total64 = 0;
> ctx->buflen = 0;
> }
> +weak_alias(__sha256_init_ctx, sha256_init)
>
> -
> -/* Process the remaining bytes in the internal buffer and the usual
> - prolog according to the standard and write the result to RESBUF.
> -
> - IMPORTANT: On some systems it is required that RESBUF is correctly
> - aligned for a 32 bits value. */
> -void *
> -__sha256_finish_ctx (ctx, resbuf)
> - struct sha256_ctx *ctx;
> - void *resbuf;
> +static void
> +__sha256_finish_ctx_generic (sha256_ctx *ctx)
> {
> /* Take yet unprocessed bytes into account. */
> uint32_t bytes = ctx->buflen;
> @@ -125,30 +95,51 @@ __sha256_finish_ctx (ctx, resbuf)
> memcpy (&ctx->buffer[bytes], fillbuf, pad);
>
> /* Put the 64-bit file length in *bits* at the end of the buffer. */
> -#if _STRING_ARCH_unaligned
> - ctx->buffer64[(bytes + pad) / 8] = SWAP64 (ctx->total64 << 3);
> -#else
> - ctx->buffer32[(bytes + pad + 4) / 4] = SWAP (ctx->total[TOTAL64_low] << 3);
> - ctx->buffer32[(bytes + pad) / 4] = SWAP ((ctx->total[TOTAL64_high] << 3) |
> - (ctx->total[TOTAL64_low] >> 29));
> -#endif
> + ctx->buffer64[(bytes + pad) / 8] = be64toh (ctx->total64 << 3);
>
> /* Process last bytes. */
> sha256_process_block (ctx->buffer, bytes + pad + 8, ctx);
> +}
> +
> +/* Process the remaining bytes in the internal buffer and the usual
> + prolog according to the standard and write the result to RESBUF. */
> +void *
> +__sha256_finish_ctx (ctx, resbuf)
> + sha256_ctx *ctx;
> + void *resbuf;
> +{
> + __sha256_finish_ctx_generic (ctx);
>
> /* Put result from CTX in first 32 bytes following RESBUF. */
> for (unsigned int i = 0; i < 8; ++i)
> - ((uint32_t *) resbuf)[i] = SWAP (ctx->H[i]);
> + put_be32 (((uint32_t *) resbuf) + i, ctx->H[i]);
>
> return resbuf;
> }
> +weak_alias(__sha256_finish_ctx, sha256_finish)
>
> +/* Process the remaining bytes in the internal buffer and the usual
> + prolog according to the standard and write the result to RESBUF. */
> +void *
> +__sha224_finish_ctx (ctx, resbuf)
> + sha256_ctx *ctx;
> + void *resbuf;
> +{
> + __sha256_finish_ctx_generic (ctx);
>
> -void
> -__sha256_process_bytes (buffer, len, ctx)
> + /* Put result from CTX in first 28 bytes following RESBUF. */
> + for (unsigned int i = 0; i < 7; ++i)
> + put_be32 (((uint32_t *) resbuf) + i, ctx->H[i]);
> +
> + return resbuf;
> +}
> +weak_alias(__sha224_finish_ctx, sha224_finish)
> +
> +const void *
> +__sha256_process_bytes (ctx, buffer, len)
> + sha256_ctx *ctx;
> const void *buffer;
> size_t len;
> - struct sha256_ctx *ctx;
> {
> /* When we already have some bits in our internal buffer concatenate
> both inputs first. */
> @@ -216,6 +207,18 @@ __sha256_process_bytes (buffer, len, ctx)
> }
> ctx->buflen = left_over;
> }
> +
> + return buffer;
> }
> +weak_alias(__sha256_process_bytes, sha256_update)
> +
> +extern void *__sha256(const void *__restrict d, size_t n, void *__restrict md) {
> + sha256_ctx ctx;
>
> + sha256_init(&ctx);
> + sha256_update(&ctx, d, n);
> + sha256_finish(&ctx, md);
> + return md;
> +}
> +weak_alias(__sha256, sha256)
> #include <sha256-block.c>
> diff --git a/crypt/sha256.h b/crypt/sha256.h
> index 27e0fe6..5960648 100644
> --- a/crypt/sha256.h
> +++ b/crypt/sha256.h
> @@ -27,7 +27,7 @@
>
>
> /* Structure to save state of computation between the single steps. */
> -struct sha256_ctx
> +typedef struct
> {
> uint32_t H[8];
>
> @@ -38,32 +38,38 @@ struct sha256_ctx
> #define TOTAL64_high (BYTE_ORDER == LITTLE_ENDIAN)
> uint32_t total[2];
> };
> - uint32_t buflen;
> union
> {
> char buffer[128];
> uint32_t buffer32[32];
> uint64_t buffer64[16];
> };
> -};
> + uint32_t buflen;
> +} sha256_ctx __attribute__((aligned(16)));
>
> /* Initialize structure containing state of computation.
> (FIPS 180-2: 5.3.2) */
> -extern void __sha256_init_ctx (struct sha256_ctx *ctx) __THROW;
> +extern void __sha256_init_ctx (sha256_ctx *__restrict ctx) __THROW;
>
> /* Starting with the result of former calls of this function (or the
> initialization function update the context for the next LEN bytes
> starting at BUFFER.
> It is NOT required that LEN is a multiple of 64. */
> -extern void __sha256_process_bytes (const void *buffer, size_t len,
> - struct sha256_ctx *ctx) __THROW;
> +extern const void *__sha256_process_bytes (sha256_ctx *__restrict ctx,
> + const void *__restrict buffer, size_t len) __THROW;
> +
> +/* Process the remaining bytes in the buffer and put result from CTX
> + in first 32 bytes following RESBUF. */
> +extern void *__sha256_finish_ctx (sha256_ctx *__restrict ctx, void *__restrict resbuf)
> + __THROW;
>
> /* Process the remaining bytes in the buffer and put result from CTX
> - in first 32 bytes following RESBUF.
> + in first 28 bytes following RESBUF.
>
> IMPORTANT: On some systems it is required that RESBUF is correctly
> aligned for a 32 bits value. */
> -extern void *__sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
> +extern void *__sha224_finish_ctx (sha256_ctx *__restrict ctx, void *__restrict resbuf)
> __THROW;
>
> +extern void *__sha256(const void *__restrict d, size_t n, void *__restrict md) __THROW;
> #endif /* sha256.h */
> diff --git a/crypt/sha256test.c b/crypt/sha256test.c
> index 39e8030..be46f69 100644
> --- a/crypt/sha256test.c
> +++ b/crypt/sha256test.c
> @@ -44,7 +44,7 @@ static const struct
> int
> main (void)
> {
> - struct sha256_ctx ctx;
> + sha256_ctx ctx;
> char sum[32];
> int result = 0;
> int cnt;
> @@ -52,8 +52,7 @@ main (void)
> for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt)
> {
> __sha256_init_ctx (&ctx);
> - __sha256_process_bytes (tests[cnt].input, strlen (tests[cnt].input),
> - &ctx);
> + __sha256_process_bytes (&ctx, tests[cnt].input, strlen (tests[cnt].input));
> __sha256_finish_ctx (&ctx, sum);
> if (memcmp (tests[cnt].result, sum, 32) != 0)
> {
> @@ -63,7 +62,7 @@ main (void)
>
> __sha256_init_ctx (&ctx);
> for (int i = 0; tests[cnt].input[i] != '\0'; ++i)
> - __sha256_process_bytes (&tests[cnt].input[i], 1, &ctx);
> + __sha256_process_bytes (&ctx, &tests[cnt].input[i], 1);
> __sha256_finish_ctx (&ctx, sum);
> if (memcmp (tests[cnt].result, sum, 32) != 0)
> {
> @@ -77,7 +76,7 @@ main (void)
> memset (buf, 'a', sizeof (buf));
> __sha256_init_ctx (&ctx);
> for (int i = 0; i < 1000; ++i)
> - __sha256_process_bytes (buf, sizeof (buf), &ctx);
> + __sha256_process_bytes (&ctx, buf, sizeof (buf));
> __sha256_finish_ctx (&ctx, sum);
> static const char expected[32] =
> "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
> @@ -90,7 +89,7 @@ main (void)
>
> __sha256_init_ctx (&ctx);
> for (int i = 0; i < 100000; ++i)
> - __sha256_process_bytes (buf, 10, &ctx);
> + __sha256_process_bytes (&ctx, buf, 10);
> __sha256_finish_ctx (&ctx, sum);
> if (memcmp (expected, sum, 32) != 0)
> {
> diff --git a/crypt/sha512-block.c b/crypt/sha512-block.c
> index c542db1..45c2049 100644
> --- a/crypt/sha512-block.c
> +++ b/crypt/sha512-block.c
> @@ -3,7 +3,7 @@
> /* Process LEN bytes of BUFFER, accumulating context into CTX.
> It is assumed that LEN % 128 == 0. */
> void
> -sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
> +sha512_process_block (const void *buffer, size_t len, sha512_ctx *ctx)
> {
> const uint64_t *words = buffer;
> size_t nwords = len / sizeof (uint64_t);
> @@ -57,7 +57,7 @@ sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
> /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */
> for (unsigned int t = 0; t < 16; ++t)
> {
> - W[t] = SWAP (*words);
> + W[t] = be64toh (*words);
> ++words;
> }
> for (unsigned int t = 16; t < 80; ++t)
> diff --git a/crypt/sha512-crypt.c b/crypt/sha512-crypt.c
> index 9c581ab..4cfecea 100644
> --- a/crypt/sha512-crypt.c
> +++ b/crypt/sha512-crypt.c
> @@ -68,7 +68,7 @@ typedef int PRBool;
> __sha512_init_ctx (ctxp)
>
> # define sha512_process_bytes(buf, len, ctxp, nss_ctxp) \
> - __sha512_process_bytes(buf, len, ctxp)
> + __sha512_process_bytes(ctxp, buf, len)
>
> # define sha512_finish_ctx(ctxp, nss_ctxp, result) \
> __sha512_finish_ctx (ctxp, result)
> @@ -188,8 +188,8 @@ __sha512_crypt_r (key, salt, buffer, buflen)
> NSSLOWHASHContext *nss_ctx = NULL;
> NSSLOWHASHContext *nss_alt_ctx = NULL;
> #else
> - struct sha512_ctx ctx;
> - struct sha512_ctx alt_ctx;
> + sha512_ctx ctx;
> + sha512_ctx alt_ctx;
> #endif
>
> /* Prepare for the real work. */
> diff --git a/crypt/sha512.c b/crypt/sha512.c
> index 608de82..7dc4238 100644
> --- a/crypt/sha512.c
> +++ b/crypt/sha512.c
> @@ -30,25 +30,7 @@
> #include <sys/types.h>
>
> #include "sha512.h"
> -
> -#if __BYTE_ORDER == __LITTLE_ENDIAN
> -# ifdef _LIBC
> -# include <byteswap.h>
> -# define SWAP(n) bswap_64 (n)
> -# else
> -# define SWAP(n) \
> - (((n) << 56) \
> - | (((n) & 0xff00) << 40) \
> - | (((n) & 0xff0000) << 24) \
> - | (((n) & 0xff000000) << 8) \
> - | (((n) >> 8) & 0xff000000) \
> - | (((n) >> 24) & 0xff0000) \
> - | (((n) >> 40) & 0xff00) \
> - | ((n) >> 56))
> -# endif
> -#else
> -# define SWAP(n) (n)
> -#endif
> +#include "align.h"
>
>
> /* This array contains the bytes used to pad the buffer to the next
> @@ -102,13 +84,13 @@ static const uint64_t K[80] =
> };
>
> void
> -sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx);
> +sha512_process_block (const void *buffer, size_t len, sha512_ctx *ctx);
>
> /* Initialize structure containing state of computation.
> (FIPS 180-2:5.3.3) */
> void
> __sha512_init_ctx (ctx)
> - struct sha512_ctx *ctx;
> + sha512_ctx *ctx;
> {
> ctx->H[0] = UINT64_C (0x6a09e667f3bcc908);
> ctx->H[1] = UINT64_C (0xbb67ae8584caa73b);
> @@ -122,17 +104,10 @@ __sha512_init_ctx (ctx)
> ctx->total[0] = ctx->total[1] = 0;
> ctx->buflen = 0;
> }
> +weak_alias(__sha512_init_ctx, sha512_init)
>
> -
> -/* Process the remaining bytes in the internal buffer and the usual
> - prolog according to the standard and write the result to RESBUF.
> -
> - IMPORTANT: On some systems it is required that RESBUF is correctly
> - aligned for a 32 bits value. */
> -void *
> -__sha512_finish_ctx (ctx, resbuf)
> - struct sha512_ctx *ctx;
> - void *resbuf;
> +static void
> +__sha512_finish_ctx_generic (sha512_ctx *ctx)
> {
> /* Take yet unprocessed bytes into account. */
> uint64_t bytes = ctx->buflen;
> @@ -151,26 +126,53 @@ __sha512_finish_ctx (ctx, resbuf)
> memcpy (&ctx->buffer[bytes], fillbuf, pad);
>
> /* Put the 128-bit file length in *bits* at the end of the buffer. */
> - ctx->buffer64[(bytes + pad + 8) / 8] = SWAP (ctx->total[TOTAL128_low] << 3);
> - ctx->buffer64[(bytes + pad) / 8] = SWAP ((ctx->total[TOTAL128_high] << 3) |
> + ctx->buffer64[(bytes + pad + 8) / 8] = be64toh (ctx->total[TOTAL128_low] << 3);
> + ctx->buffer64[(bytes + pad) / 8] = be64toh ((ctx->total[TOTAL128_high] << 3) |
> (ctx->total[TOTAL128_low] >> 61));
>
> /* Process last bytes. */
> sha512_process_block (ctx->buffer, bytes + pad + 16, ctx);
> +}
> +
> +/* Process the remaining bytes in the internal buffer and the usual
> + prolog according to the standard and write the result to RESBUF. */
> +void *
> +__sha512_finish_ctx (ctx, resbuf)
> + sha512_ctx *ctx;
> + void *resbuf;
> +{
> + __sha512_finish_ctx_generic (ctx);
>
> /* Put result from CTX in first 64 bytes following RESBUF. */
> for (unsigned int i = 0; i < 8; ++i)
> - ((uint64_t *) resbuf)[i] = SWAP (ctx->H[i]);
> + put_be64(((uint64_t *) resbuf) + i, ctx->H[i]);
>
> return resbuf;
> }
> +weak_alias(__sha512_finish_ctx, sha512_finish)
> +
> +/* Process the remaining bytes in the internal buffer and the usual
> + prolog according to the standard and write the result to RESBUF. */
> +void *
> +__sha384_finish_ctx (ctx, resbuf)
> + sha512_ctx *ctx;
> + void *resbuf;
> +{
> + __sha512_finish_ctx_generic (ctx);
>
> + /* Put result from CTX in first 48 bytes following RESBUF. */
> + for (unsigned int i = 0; i < 6; ++i)
> + put_be64(((uint64_t *) resbuf) + i, ctx->H[i]);
>
> -void
> -__sha512_process_bytes (buffer, len, ctx)
> + return resbuf;
> +}
> +weak_alias(__sha384_finish_ctx, sha384_finish)
> +
> +const void *
> +__sha512_process_bytes (ctx, buffer, len)
> + sha512_ctx *ctx;
> const void *buffer;
> size_t len;
> - struct sha512_ctx *ctx;
> {
> /* When we already have some bits in our internal buffer concatenate
> both inputs first. */
> @@ -239,6 +241,19 @@ __sha512_process_bytes (buffer, len, ctx)
> }
> ctx->buflen = left_over;
> }
> +
> + return buffer;
> +}
> +weak_alias(__sha512_process_bytes, sha512_update)
> +
> +extern void *__sha512(const void *__restrict d, size_t n, void *__restrict md) {
> + sha512_ctx ctx;
> +
> + sha512_init(&ctx);
> + sha512_update(&ctx, d, n);
> + sha512_finish(&ctx, md);
> + return md;
> }
> +weak_alias(__sha512, sha512)
>
> #include <sha512-block.c>
> diff --git a/crypt/sha512.h b/crypt/sha512.h
> index 159f000..359ea37 100644
> --- a/crypt/sha512.h
> +++ b/crypt/sha512.h
> @@ -28,7 +28,7 @@
>
>
> /* Structure to save state of computation between the single steps. */
> -struct sha512_ctx
> +typedef struct
> {
> uint64_t H[8];
>
> @@ -43,30 +43,40 @@ struct sha512_ctx
> uint64_t total[2];
> };
> uint64_t buflen;
> + uint8_t __padding[8];
> union
> {
> char buffer[256];
> uint64_t buffer64[32];
> };
> -};
> +} sha512_ctx __attribute__((aligned(16)));
>
> /* Initialize structure containing state of computation.
> (FIPS 180-2: 5.3.3) */
> -extern void __sha512_init_ctx (struct sha512_ctx *ctx) __THROW;
> +extern void __sha512_init_ctx (sha512_ctx *__restrict ctx) __THROW;
>
> /* Starting with the result of former calls of this function (or the
> initialization function update the context for the next LEN bytes
> starting at BUFFER.
> It is NOT required that LEN is a multiple of 128. */
> -extern void __sha512_process_bytes (const void *buffer, size_t len,
> - struct sha512_ctx *ctx) __THROW;
> +extern const void *__sha512_process_bytes (sha512_ctx *__restrict ctx,
> + const void *__restrict buffer, size_t len) __THROW;
>
> /* Process the remaining bytes in the buffer and put result from CTX
> in first 64 bytes following RESBUF.
>
> IMPORTANT: On some systems it is required that RESBUF is correctly
> aligned for a 64 bits value. */
> -extern void *__sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
> +extern void *__sha512_finish_ctx (sha512_ctx *ctx, void *__restrict resbuf)
> __THROW;
>
> +/* Process the remaining bytes in the buffer and put result from CTX
> + in first 48 bytes following RESBUF.
> +
> + IMPORTANT: On some systems it is required that RESBUF is correctly
> + aligned for a 64 bits value. */
> +extern void *__sha384_finish_ctx (sha512_ctx *ctx, void *__restrict resbuf)
> + __THROW;
> +
> +extern void *__sha512(const void *__restrict d, size_t n, void *__restrict md) __THROW;
> #endif /* sha512.h */
> diff --git a/crypt/sha512test.c b/crypt/sha512test.c
> index 792e9a7..296ce89 100644
> --- a/crypt/sha512test.c
> +++ b/crypt/sha512test.c
> @@ -63,7 +63,7 @@ static const struct
> int
> main (void)
> {
> - struct sha512_ctx ctx;
> + sha512_ctx ctx;
> char sum[64];
> int result = 0;
> int cnt;
> @@ -71,8 +71,7 @@ main (void)
> for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt)
> {
> __sha512_init_ctx (&ctx);
> - __sha512_process_bytes (tests[cnt].input, strlen (tests[cnt].input),
> - &ctx);
> + __sha512_process_bytes (&ctx, tests[cnt].input, strlen (tests[cnt].input));
> __sha512_finish_ctx (&ctx, sum);
> if (memcmp (tests[cnt].result, sum, 64) != 0)
> {
> @@ -82,7 +81,7 @@ main (void)
>
> __sha512_init_ctx (&ctx);
> for (int i = 0; tests[cnt].input[i] != '\0'; ++i)
> - __sha512_process_bytes (&tests[cnt].input[i], 1, &ctx);
> + __sha512_process_bytes (&ctx, &tests[cnt].input[i], 1);
> __sha512_finish_ctx (&ctx, sum);
> if (memcmp (tests[cnt].result, sum, 64) != 0)
> {
> @@ -96,7 +95,7 @@ main (void)
> memset (buf, 'a', sizeof (buf));
> __sha512_init_ctx (&ctx);
> for (int i = 0; i < 1000; ++i)
> - __sha512_process_bytes (buf, sizeof (buf), &ctx);
> + __sha512_process_bytes (&ctx, buf, sizeof (buf));
> __sha512_finish_ctx (&ctx, sum);
> static const char expected[64] =
> "\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63"
> --
> 2.2.1.209.g41e5f3a
>
--
âOne thing I have learned in a long life: that all our science,
measured against reality, is primitive and childlike -- and yet it is
the most precious thing we have.â
â Albert Einstein