Replace sys/crypto/sha2/sha2.c with lib/libmd/sha512c.c

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
This commit is contained in:
Allan Jude
2015-12-27 17:33:59 +00:00
committed by Sebastian Huber
parent 120c857ea1
commit 225e7b9e75
4 changed files with 149 additions and 19 deletions

View File

@@ -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_ */

60
cpukit/include/sha384.h Normal file
View File

@@ -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_ */

View File

@@ -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_ */

View File

@@ -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));