[PATCH 01/15] Replace sys/crypto/sha2/sha2.c with lib/libmd/sha512c.c
Sebastian Huber
sebastian.huber at embedded-brains.de
Thu Sep 8 13:27:18 UTC 2022
From: Allan Jude <allanjude at FreeBSD.org>
cperciva's libmd implementation is 5-30% faster
The same was done for SHA256 previously in r263218
cperciva's implementation was lacking SHA-384 which I implemented, validated against OpenSSL and the NIST documentation
Extend sbin/md5 to create sha384(1)
Chase dependancies on sys/crypto/sha2/sha2.{c,h} and replace them with sha512{c.c,.h}
Reviewed by: cperciva, des, delphij
Approved by: secteam, bapt (mentor)
MFC after: 2 weeks
Sponsored by: ScaleEngine Inc.
Differential Revision: https://reviews.freebsd.org/D3929
---
cpukit/include/sha256.h | 15 ++++++--
cpukit/include/sha384.h | 60 ++++++++++++++++++++++++++++++++
cpukit/include/sha512.h | 16 +++++++--
cpukit/libmd/sha512c.c | 77 ++++++++++++++++++++++++++++++++++-------
4 files changed, 149 insertions(+), 19 deletions(-)
create mode 100644 cpukit/include/sha384.h
diff --git a/cpukit/include/sha256.h b/cpukit/include/sha256.h
index 1b6a4f4c57..9deed91255 100644
--- a/cpukit/include/sha256.h
+++ b/cpukit/include/sha256.h
@@ -29,22 +29,31 @@
#ifndef _SHA256_H_
#define _SHA256_H_
+#ifndef _KERNEL
#include <sys/types.h>
+#endif
+
+#define SHA256_BLOCK_LENGTH 64
+#define SHA256_DIGEST_LENGTH 32
+#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
typedef struct SHA256Context {
uint32_t state[8];
uint64_t count;
- unsigned char buf[64];
+ uint8_t buf[SHA256_BLOCK_LENGTH];
} SHA256_CTX;
__BEGIN_DECLS
+
void SHA256_Init(SHA256_CTX *);
void SHA256_Update(SHA256_CTX *, const void *, size_t);
-void SHA256_Final(unsigned char [32], SHA256_CTX *);
+void SHA256_Final(unsigned char [SHA256_DIGEST_LENGTH], SHA256_CTX *);
+#ifndef _KERNEL
char *SHA256_End(SHA256_CTX *, char *);
+char *SHA256_Data(const void *, unsigned int, char *);
char *SHA256_File(const char *, char *);
char *SHA256_FileChunk(const char *, char *, off_t, off_t);
-char *SHA256_Data(const void *, unsigned int, char *);
+#endif
__END_DECLS
#endif /* !_SHA256_H_ */
diff --git a/cpukit/include/sha384.h b/cpukit/include/sha384.h
new file mode 100644
index 0000000000..2035d6ff54
--- /dev/null
+++ b/cpukit/include/sha384.h
@@ -0,0 +1,60 @@
+/*-
+ * Copyright 2005 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SHA384_H_
+#define _SHA384_H_
+
+#ifndef _KERNEL
+#include <sys/types.h>
+#endif
+
+#define SHA384_BLOCK_LENGTH 128
+#define SHA384_DIGEST_LENGTH 48
+#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
+
+typedef struct SHA384Context {
+ uint64_t state[8];
+ uint64_t count[2];
+ uint8_t buf[SHA384_BLOCK_LENGTH];
+} SHA384_CTX;
+
+__BEGIN_DECLS
+
+void SHA384_Init(SHA384_CTX *);
+void SHA384_Update(SHA384_CTX *, const void *, size_t);
+void SHA384_Final(unsigned char [SHA384_DIGEST_LENGTH], SHA384_CTX *);
+#ifndef _KERNEL
+char *SHA384_End(SHA384_CTX *, char *);
+char *SHA384_Data(const void *, unsigned int, char *);
+char *SHA384_File(const char *, char *);
+char *SHA384_FileChunk(const char *, char *, off_t, off_t);
+#endif
+
+__END_DECLS
+
+#endif /* !_SHA384_H_ */
diff --git a/cpukit/include/sha512.h b/cpukit/include/sha512.h
index 8998f4c5bf..1964562160 100644
--- a/cpukit/include/sha512.h
+++ b/cpukit/include/sha512.h
@@ -29,22 +29,32 @@
#ifndef _SHA512_H_
#define _SHA512_H_
+#ifndef _KERNEL
#include <sys/types.h>
+#endif
+
+#define SHA512_BLOCK_LENGTH 128
+#define SHA512_DIGEST_LENGTH 64
+#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
typedef struct SHA512Context {
uint64_t state[8];
uint64_t count[2];
- unsigned char buf[128];
+ uint8_t buf[SHA512_BLOCK_LENGTH];
} SHA512_CTX;
__BEGIN_DECLS
+
void SHA512_Init(SHA512_CTX *);
void SHA512_Update(SHA512_CTX *, const void *, size_t);
-void SHA512_Final(unsigned char [64], SHA512_CTX *);
+void SHA512_Final(unsigned char [SHA512_DIGEST_LENGTH], SHA512_CTX *);
+#ifndef _KERNEL
char *SHA512_End(SHA512_CTX *, char *);
+char *SHA512_Data(const void *, unsigned int, char *);
char *SHA512_File(const char *, char *);
char *SHA512_FileChunk(const char *, char *, off_t, off_t);
-char *SHA512_Data(const void *, unsigned int, char *);
+#endif
+
__END_DECLS
#endif /* !_SHA512_H_ */
diff --git a/cpukit/libmd/sha512c.c b/cpukit/libmd/sha512c.c
index a4f268045a..7d0e875550 100644
--- a/cpukit/libmd/sha512c.c
+++ b/cpukit/libmd/sha512c.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include "sha512.h"
+#include "sha384.h"
#if BYTE_ORDER == BIG_ENDIAN
@@ -104,7 +105,7 @@ be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
* the 512-bit input block to produce a new state.
*/
static void
-SHA512_Transform(uint64_t * state, const unsigned char block[128])
+SHA512_Transform(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH])
{
uint64_t W[80];
uint64_t S[8];
@@ -112,12 +113,12 @@ SHA512_Transform(uint64_t * state, const unsigned char block[128])
int i;
/* 1. Prepare message schedule W. */
- be64dec_vect(W, block, 128);
+ be64dec_vect(W, block, SHA512_BLOCK_LENGTH);
for (i = 16; i < 80; i++)
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
/* 2. Initialize working variables. */
- memcpy(S, state, 64);
+ memcpy(S, state, SHA512_DIGEST_LENGTH);
/* 3. Mix. */
RNDr(S, W, 0, 0x428a2f98d728ae22ULL);
@@ -206,7 +207,7 @@ SHA512_Transform(uint64_t * state, const unsigned char block[128])
state[i] += S[i];
}
-static const unsigned char PAD[128] = {
+static const unsigned char PAD[SHA512_BLOCK_LENGTH] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -279,22 +280,22 @@ SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len)
ctx->count[0] += bitlen[0];
/* Handle the case where we don't need to perform any transforms */
- if (len < 128 - r) {
+ if (len < SHA512_BLOCK_LENGTH - r) {
memcpy(&ctx->buf[r], src, len);
return;
}
/* Finish the current block */
- memcpy(&ctx->buf[r], src, 128 - r);
+ memcpy(&ctx->buf[r], src, SHA512_BLOCK_LENGTH - r);
SHA512_Transform(ctx->state, ctx->buf);
- src += 128 - r;
- len -= 128 - r;
+ src += SHA512_BLOCK_LENGTH - r;
+ len -= SHA512_BLOCK_LENGTH - r;
/* Perform complete blocks */
- while (len >= 128) {
+ while (len >= SHA512_BLOCK_LENGTH) {
SHA512_Transform(ctx->state, src);
- src += 128;
- len -= 128;
+ src += SHA512_BLOCK_LENGTH;
+ len -= SHA512_BLOCK_LENGTH;
}
/* Copy left over data into buffer */
@@ -306,14 +307,64 @@ SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len)
* and clears the context state.
*/
void
-SHA512_Final(unsigned char digest[64], SHA512_CTX * ctx)
+SHA512_Final(unsigned char digest[SHA512_DIGEST_LENGTH], SHA512_CTX * ctx)
{
/* Add padding */
SHA512_Pad(ctx);
/* Write the hash */
- be64enc_vect(digest, ctx->state, 64);
+ be64enc_vect(digest, ctx->state, SHA512_DIGEST_LENGTH);
+
+ /* Clear the context state */
+ memset((void *)ctx, 0, sizeof(*ctx));
+}
+
+/*** SHA-384: *********************************************************/
+/*
+ * the SHA384 and SHA512 transforms are identical, so SHA384 is skipped
+ */
+
+/* SHA-384 initialization. Begins a SHA-384 operation. */
+void
+SHA384_Init(SHA384_CTX * ctx)
+{
+
+ /* Zero bits processed so far */
+ ctx->count[0] = ctx->count[1] = 0;
+
+ /* Magic initialization constants */
+ ctx->state[0] = 0xcbbb9d5dc1059ed8ULL;
+ ctx->state[1] = 0x629a292a367cd507ULL;
+ ctx->state[2] = 0x9159015a3070dd17ULL;
+ ctx->state[3] = 0x152fecd8f70e5939ULL;
+ ctx->state[4] = 0x67332667ffc00b31ULL;
+ ctx->state[5] = 0x8eb44a8768581511ULL;
+ ctx->state[6] = 0xdb0c2e0d64f98fa7ULL;
+ ctx->state[7] = 0x47b5481dbefa4fa4ULL;
+}
+
+/* Add bytes into the SHA-384 hash */
+void
+SHA384_Update(SHA384_CTX * ctx, const void *in, size_t len)
+{
+
+ SHA512_Update((SHA512_CTX *)ctx, in, len);
+}
+
+/*
+ * SHA-384 finalization. Pads the input data, exports the hash value,
+ * and clears the context state.
+ */
+void
+SHA384_Final(unsigned char digest[SHA384_DIGEST_LENGTH], SHA384_CTX * ctx)
+{
+
+ /* Add padding */
+ SHA512_Pad((SHA512_CTX *)ctx);
+
+ /* Write the hash */
+ be64enc_vect(digest, ctx->state, SHA384_DIGEST_LENGTH);
/* Clear the context state */
memset((void *)ctx, 0, sizeof(*ctx));
--
2.35.3
More information about the devel
mailing list