This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] sha2: new header <sha2.h>


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]