Add SHA256 and SHA512 support

This commit is contained in:
Sebastian Huber
2014-11-13 13:18:24 +01:00
parent a2b68952b1
commit 1bcd037810
14 changed files with 1003 additions and 12 deletions

View File

@@ -47,8 +47,6 @@ include_sysdir = $(includedir)/sys
include_sys_HEADERS =
include_HEADERS += include/memory.h
include_HEADERS += libmd/md4.h
include_HEADERS += libmd/md5.h
include_sys_HEADERS += libcsupport/include/sys/ioccom.h
include_sys_HEADERS += libcsupport/include/sys/event.h

View File

@@ -1,9 +1,18 @@
include $(top_srcdir)/automake/compile.am
if NEWLIB
include_HEADERS =
include_HEADERS += md4.h
include_HEADERS += md5.h
include_HEADERS += sha256.h
include_HEADERS += sha512.h
noinst_LIBRARIES = libmd.a
libmd_a_SOURCES = md5.h md5.c
libmd_a_SOURCES += md4.h md4.c
libmd_a_SOURCES =
libmd_a_SOURCES += md4.c
libmd_a_SOURCES += md5.c
libmd_a_SOURCES += sha256c.c
libmd_a_SOURCES += sha512c.c
libmd_a_CPPFLAGS = $(AM_CPPFLAGS)
endif

View File

@@ -5,3 +5,33 @@ $(srcdir)/preinstall.am: Makefile.am
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
endif
PREINSTALL_DIRS =
DISTCLEANFILES = $(PREINSTALL_DIRS)
all-am: $(PREINSTALL_FILES)
PREINSTALL_FILES =
CLEANFILES = $(PREINSTALL_FILES)
$(PROJECT_INCLUDE)/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)
@: > $(PROJECT_INCLUDE)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
if NEWLIB
$(PROJECT_INCLUDE)/md4.h: md4.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/md4.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/md4.h
$(PROJECT_INCLUDE)/md5.h: md5.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/md5.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/md5.h
$(PROJECT_INCLUDE)/sha256.h: sha256.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sha256.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/sha256.h
$(PROJECT_INCLUDE)/sha512.h: sha512.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sha512.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/sha512.h
endif

50
cpukit/libmd/sha256.h Normal file
View File

@@ -0,0 +1,50 @@
/*-
* 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 _SHA256_H_
#define _SHA256_H_
#include <sys/types.h>
typedef struct SHA256Context {
uint32_t state[8];
uint64_t count;
unsigned char buf[64];
} 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 *);
char *SHA256_End(SHA256_CTX *, 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 *);
__END_DECLS
#endif /* !_SHA256_H_ */

297
cpukit/libmd/sha256c.c Normal file
View File

@@ -0,0 +1,297 @@
/*-
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/types.h>
#include <string.h>
#include "sha256.h"
#if BYTE_ORDER == BIG_ENDIAN
/* Copy a vector of big-endian uint32_t into a vector of bytes */
#define be32enc_vect(dst, src, len) \
memcpy((void *)dst, (const void *)src, (size_t)len)
/* Copy a vector of bytes into a vector of big-endian uint32_t */
#define be32dec_vect(dst, src, len) \
memcpy((void *)dst, (const void *)src, (size_t)len)
#else /* BYTE_ORDER != BIG_ENDIAN */
/*
* Encode a length len/4 vector of (uint32_t) into a length len vector of
* (unsigned char) in big-endian form. Assumes len is a multiple of 4.
*/
static void
be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
{
size_t i;
for (i = 0; i < len / 4; i++)
be32enc(dst + i * 4, src[i]);
}
/*
* Decode a big-endian length len vector of (unsigned char) into a length
* len/4 vector of (uint32_t). Assumes len is a multiple of 4.
*/
static void
be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
{
size_t i;
for (i = 0; i < len / 4; i++)
dst[i] = be32dec(src + i * 4);
}
#endif /* BYTE_ORDER != BIG_ENDIAN */
/* Elementary functions used by SHA256 */
#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
#define Maj(x, y, z) ((x & (y | z)) | (y & z))
#define SHR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
/* SHA256 round function */
#define RND(a, b, c, d, e, f, g, h, k) \
t0 = h + S1(e) + Ch(e, f, g) + k; \
t1 = S0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
/* Adjusted round function for rotating state */
#define RNDr(S, W, i, k) \
RND(S[(64 - i) % 8], S[(65 - i) % 8], \
S[(66 - i) % 8], S[(67 - i) % 8], \
S[(68 - i) % 8], S[(69 - i) % 8], \
S[(70 - i) % 8], S[(71 - i) % 8], \
W[i] + k)
/*
* SHA256 block compression function. The 256-bit state is transformed via
* the 512-bit input block to produce a new state.
*/
static void
SHA256_Transform(uint32_t * state, const unsigned char block[64])
{
uint32_t W[64];
uint32_t S[8];
uint32_t t0, t1;
int i;
/* 1. Prepare message schedule W. */
be32dec_vect(W, block, 64);
for (i = 16; i < 64; i++)
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
/* 2. Initialize working variables. */
memcpy(S, state, 32);
/* 3. Mix. */
RNDr(S, W, 0, 0x428a2f98);
RNDr(S, W, 1, 0x71374491);
RNDr(S, W, 2, 0xb5c0fbcf);
RNDr(S, W, 3, 0xe9b5dba5);
RNDr(S, W, 4, 0x3956c25b);
RNDr(S, W, 5, 0x59f111f1);
RNDr(S, W, 6, 0x923f82a4);
RNDr(S, W, 7, 0xab1c5ed5);
RNDr(S, W, 8, 0xd807aa98);
RNDr(S, W, 9, 0x12835b01);
RNDr(S, W, 10, 0x243185be);
RNDr(S, W, 11, 0x550c7dc3);
RNDr(S, W, 12, 0x72be5d74);
RNDr(S, W, 13, 0x80deb1fe);
RNDr(S, W, 14, 0x9bdc06a7);
RNDr(S, W, 15, 0xc19bf174);
RNDr(S, W, 16, 0xe49b69c1);
RNDr(S, W, 17, 0xefbe4786);
RNDr(S, W, 18, 0x0fc19dc6);
RNDr(S, W, 19, 0x240ca1cc);
RNDr(S, W, 20, 0x2de92c6f);
RNDr(S, W, 21, 0x4a7484aa);
RNDr(S, W, 22, 0x5cb0a9dc);
RNDr(S, W, 23, 0x76f988da);
RNDr(S, W, 24, 0x983e5152);
RNDr(S, W, 25, 0xa831c66d);
RNDr(S, W, 26, 0xb00327c8);
RNDr(S, W, 27, 0xbf597fc7);
RNDr(S, W, 28, 0xc6e00bf3);
RNDr(S, W, 29, 0xd5a79147);
RNDr(S, W, 30, 0x06ca6351);
RNDr(S, W, 31, 0x14292967);
RNDr(S, W, 32, 0x27b70a85);
RNDr(S, W, 33, 0x2e1b2138);
RNDr(S, W, 34, 0x4d2c6dfc);
RNDr(S, W, 35, 0x53380d13);
RNDr(S, W, 36, 0x650a7354);
RNDr(S, W, 37, 0x766a0abb);
RNDr(S, W, 38, 0x81c2c92e);
RNDr(S, W, 39, 0x92722c85);
RNDr(S, W, 40, 0xa2bfe8a1);
RNDr(S, W, 41, 0xa81a664b);
RNDr(S, W, 42, 0xc24b8b70);
RNDr(S, W, 43, 0xc76c51a3);
RNDr(S, W, 44, 0xd192e819);
RNDr(S, W, 45, 0xd6990624);
RNDr(S, W, 46, 0xf40e3585);
RNDr(S, W, 47, 0x106aa070);
RNDr(S, W, 48, 0x19a4c116);
RNDr(S, W, 49, 0x1e376c08);
RNDr(S, W, 50, 0x2748774c);
RNDr(S, W, 51, 0x34b0bcb5);
RNDr(S, W, 52, 0x391c0cb3);
RNDr(S, W, 53, 0x4ed8aa4a);
RNDr(S, W, 54, 0x5b9cca4f);
RNDr(S, W, 55, 0x682e6ff3);
RNDr(S, W, 56, 0x748f82ee);
RNDr(S, W, 57, 0x78a5636f);
RNDr(S, W, 58, 0x84c87814);
RNDr(S, W, 59, 0x8cc70208);
RNDr(S, W, 60, 0x90befffa);
RNDr(S, W, 61, 0xa4506ceb);
RNDr(S, W, 62, 0xbef9a3f7);
RNDr(S, W, 63, 0xc67178f2);
/* 4. Mix local working variables into global state */
for (i = 0; i < 8; i++)
state[i] += S[i];
}
static const unsigned char PAD[64] = {
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,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* Add padding and terminating bit-count. */
static void
SHA256_Pad(SHA256_CTX * ctx)
{
unsigned char len[8];
uint32_t r, plen;
/*
* Convert length to a vector of bytes -- we do this now rather
* than later because the length will change after we pad.
*/
be64enc(len, ctx->count);
/* Add 1--64 bytes so that the resulting length is 56 mod 64 */
r = (ctx->count >> 3) & 0x3f;
plen = (r < 56) ? (56 - r) : (120 - r);
SHA256_Update(ctx, PAD, (size_t)plen);
/* Add the terminating bit-count */
SHA256_Update(ctx, len, 8);
}
/* SHA-256 initialization. Begins a SHA-256 operation. */
void
SHA256_Init(SHA256_CTX * ctx)
{
/* Zero bits processed so far */
ctx->count = 0;
/* Magic initialization constants */
ctx->state[0] = 0x6A09E667;
ctx->state[1] = 0xBB67AE85;
ctx->state[2] = 0x3C6EF372;
ctx->state[3] = 0xA54FF53A;
ctx->state[4] = 0x510E527F;
ctx->state[5] = 0x9B05688C;
ctx->state[6] = 0x1F83D9AB;
ctx->state[7] = 0x5BE0CD19;
}
/* Add bytes into the hash */
void
SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
{
uint64_t bitlen;
uint32_t r;
const unsigned char *src = in;
/* Number of bytes left in the buffer from previous updates */
r = (ctx->count >> 3) & 0x3f;
/* Convert the length into a number of bits */
bitlen = len << 3;
/* Update number of bits */
ctx->count += bitlen;
/* Handle the case where we don't need to perform any transforms */
if (len < 64 - r) {
memcpy(&ctx->buf[r], src, len);
return;
}
/* Finish the current block */
memcpy(&ctx->buf[r], src, 64 - r);
SHA256_Transform(ctx->state, ctx->buf);
src += 64 - r;
len -= 64 - r;
/* Perform complete blocks */
while (len >= 64) {
SHA256_Transform(ctx->state, src);
src += 64;
len -= 64;
}
/* Copy left over data into buffer */
memcpy(ctx->buf, src, len);
}
/*
* SHA-256 finalization. Pads the input data, exports the hash value,
* and clears the context state.
*/
void
SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
{
/* Add padding */
SHA256_Pad(ctx);
/* Write the hash */
be32enc_vect(digest, ctx->state, 32);
/* Clear the context state */
memset((void *)ctx, 0, sizeof(*ctx));
}

50
cpukit/libmd/sha512.h Normal file
View File

@@ -0,0 +1,50 @@
/*-
* 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 _SHA512_H_
#define _SHA512_H_
#include <sys/types.h>
typedef struct SHA512Context {
uint64_t state[8];
uint64_t count[2];
unsigned char buf[128];
} 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 *);
char *SHA512_End(SHA512_CTX *, 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 *);
__END_DECLS
#endif /* !_SHA512_H_ */

320
cpukit/libmd/sha512c.c Normal file
View File

@@ -0,0 +1,320 @@
/*-
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/types.h>
#include <string.h>
#include "sha512.h"
#if BYTE_ORDER == BIG_ENDIAN
/* Copy a vector of big-endian uint64_t into a vector of bytes */
#define be64enc_vect(dst, src, len) \
memcpy((void *)dst, (const void *)src, (size_t)len)
/* Copy a vector of bytes into a vector of big-endian uint64_t */
#define be64dec_vect(dst, src, len) \
memcpy((void *)dst, (const void *)src, (size_t)len)
#else /* BYTE_ORDER != BIG_ENDIAN */
/*
* Encode a length len/4 vector of (uint64_t) into a length len vector of
* (unsigned char) in big-endian form. Assumes len is a multiple of 8.
*/
static void
be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
{
size_t i;
for (i = 0; i < len / 8; i++)
be64enc(dst + i * 8, src[i]);
}
/*
* Decode a big-endian length len vector of (unsigned char) into a length
* len/4 vector of (uint64_t). Assumes len is a multiple of 8.
*/
static void
be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
{
size_t i;
for (i = 0; i < len / 8; i++)
dst[i] = be64dec(src + i * 8);
}
#endif /* BYTE_ORDER != BIG_ENDIAN */
/* Elementary functions used by SHA512 */
#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
#define Maj(x, y, z) ((x & (y | z)) | (y & z))
#define SHR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << (64 - n)))
#define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
#define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
#define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
#define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
/* SHA512 round function */
#define RND(a, b, c, d, e, f, g, h, k) \
t0 = h + S1(e) + Ch(e, f, g) + k; \
t1 = S0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
/* Adjusted round function for rotating state */
#define RNDr(S, W, i, k) \
RND(S[(80 - i) % 8], S[(81 - i) % 8], \
S[(82 - i) % 8], S[(83 - i) % 8], \
S[(84 - i) % 8], S[(85 - i) % 8], \
S[(86 - i) % 8], S[(87 - i) % 8], \
W[i] + k)
/*
* SHA512 block compression function. The 512-bit state is transformed via
* the 512-bit input block to produce a new state.
*/
static void
SHA512_Transform(uint64_t * state, const unsigned char block[128])
{
uint64_t W[80];
uint64_t S[8];
uint64_t t0, t1;
int i;
/* 1. Prepare message schedule W. */
be64dec_vect(W, block, 128);
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);
/* 3. Mix. */
RNDr(S, W, 0, 0x428a2f98d728ae22ULL);
RNDr(S, W, 1, 0x7137449123ef65cdULL);
RNDr(S, W, 2, 0xb5c0fbcfec4d3b2fULL);
RNDr(S, W, 3, 0xe9b5dba58189dbbcULL);
RNDr(S, W, 4, 0x3956c25bf348b538ULL);
RNDr(S, W, 5, 0x59f111f1b605d019ULL);
RNDr(S, W, 6, 0x923f82a4af194f9bULL);
RNDr(S, W, 7, 0xab1c5ed5da6d8118ULL);
RNDr(S, W, 8, 0xd807aa98a3030242ULL);
RNDr(S, W, 9, 0x12835b0145706fbeULL);
RNDr(S, W, 10, 0x243185be4ee4b28cULL);
RNDr(S, W, 11, 0x550c7dc3d5ffb4e2ULL);
RNDr(S, W, 12, 0x72be5d74f27b896fULL);
RNDr(S, W, 13, 0x80deb1fe3b1696b1ULL);
RNDr(S, W, 14, 0x9bdc06a725c71235ULL);
RNDr(S, W, 15, 0xc19bf174cf692694ULL);
RNDr(S, W, 16, 0xe49b69c19ef14ad2ULL);
RNDr(S, W, 17, 0xefbe4786384f25e3ULL);
RNDr(S, W, 18, 0x0fc19dc68b8cd5b5ULL);
RNDr(S, W, 19, 0x240ca1cc77ac9c65ULL);
RNDr(S, W, 20, 0x2de92c6f592b0275ULL);
RNDr(S, W, 21, 0x4a7484aa6ea6e483ULL);
RNDr(S, W, 22, 0x5cb0a9dcbd41fbd4ULL);
RNDr(S, W, 23, 0x76f988da831153b5ULL);
RNDr(S, W, 24, 0x983e5152ee66dfabULL);
RNDr(S, W, 25, 0xa831c66d2db43210ULL);
RNDr(S, W, 26, 0xb00327c898fb213fULL);
RNDr(S, W, 27, 0xbf597fc7beef0ee4ULL);
RNDr(S, W, 28, 0xc6e00bf33da88fc2ULL);
RNDr(S, W, 29, 0xd5a79147930aa725ULL);
RNDr(S, W, 30, 0x06ca6351e003826fULL);
RNDr(S, W, 31, 0x142929670a0e6e70ULL);
RNDr(S, W, 32, 0x27b70a8546d22ffcULL);
RNDr(S, W, 33, 0x2e1b21385c26c926ULL);
RNDr(S, W, 34, 0x4d2c6dfc5ac42aedULL);
RNDr(S, W, 35, 0x53380d139d95b3dfULL);
RNDr(S, W, 36, 0x650a73548baf63deULL);
RNDr(S, W, 37, 0x766a0abb3c77b2a8ULL);
RNDr(S, W, 38, 0x81c2c92e47edaee6ULL);
RNDr(S, W, 39, 0x92722c851482353bULL);
RNDr(S, W, 40, 0xa2bfe8a14cf10364ULL);
RNDr(S, W, 41, 0xa81a664bbc423001ULL);
RNDr(S, W, 42, 0xc24b8b70d0f89791ULL);
RNDr(S, W, 43, 0xc76c51a30654be30ULL);
RNDr(S, W, 44, 0xd192e819d6ef5218ULL);
RNDr(S, W, 45, 0xd69906245565a910ULL);
RNDr(S, W, 46, 0xf40e35855771202aULL);
RNDr(S, W, 47, 0x106aa07032bbd1b8ULL);
RNDr(S, W, 48, 0x19a4c116b8d2d0c8ULL);
RNDr(S, W, 49, 0x1e376c085141ab53ULL);
RNDr(S, W, 50, 0x2748774cdf8eeb99ULL);
RNDr(S, W, 51, 0x34b0bcb5e19b48a8ULL);
RNDr(S, W, 52, 0x391c0cb3c5c95a63ULL);
RNDr(S, W, 53, 0x4ed8aa4ae3418acbULL);
RNDr(S, W, 54, 0x5b9cca4f7763e373ULL);
RNDr(S, W, 55, 0x682e6ff3d6b2b8a3ULL);
RNDr(S, W, 56, 0x748f82ee5defb2fcULL);
RNDr(S, W, 57, 0x78a5636f43172f60ULL);
RNDr(S, W, 58, 0x84c87814a1f0ab72ULL);
RNDr(S, W, 59, 0x8cc702081a6439ecULL);
RNDr(S, W, 60, 0x90befffa23631e28ULL);
RNDr(S, W, 61, 0xa4506cebde82bde9ULL);
RNDr(S, W, 62, 0xbef9a3f7b2c67915ULL);
RNDr(S, W, 63, 0xc67178f2e372532bULL);
RNDr(S, W, 64, 0xca273eceea26619cULL);
RNDr(S, W, 65, 0xd186b8c721c0c207ULL);
RNDr(S, W, 66, 0xeada7dd6cde0eb1eULL);
RNDr(S, W, 67, 0xf57d4f7fee6ed178ULL);
RNDr(S, W, 68, 0x06f067aa72176fbaULL);
RNDr(S, W, 69, 0x0a637dc5a2c898a6ULL);
RNDr(S, W, 70, 0x113f9804bef90daeULL);
RNDr(S, W, 71, 0x1b710b35131c471bULL);
RNDr(S, W, 72, 0x28db77f523047d84ULL);
RNDr(S, W, 73, 0x32caab7b40c72493ULL);
RNDr(S, W, 74, 0x3c9ebe0a15c9bebcULL);
RNDr(S, W, 75, 0x431d67c49c100d4cULL);
RNDr(S, W, 76, 0x4cc5d4becb3e42b6ULL);
RNDr(S, W, 77, 0x597f299cfc657e2aULL);
RNDr(S, W, 78, 0x5fcb6fab3ad6faecULL);
RNDr(S, W, 79, 0x6c44198c4a475817ULL);
/* 4. Mix local working variables into global state */
for (i = 0; i < 8; i++)
state[i] += S[i];
}
static const unsigned char PAD[128] = {
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,
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, 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
};
/* Add padding and terminating bit-count. */
static void
SHA512_Pad(SHA512_CTX * ctx)
{
unsigned char len[16];
uint64_t r, plen;
/*
* Convert length to a vector of bytes -- we do this now rather
* than later because the length will change after we pad.
*/
be64enc_vect(len, ctx->count, 16);
/* Add 1--128 bytes so that the resulting length is 112 mod 128 */
r = (ctx->count[1] >> 3) & 0x7f;
plen = (r < 112) ? (112 - r) : (240 - r);
SHA512_Update(ctx, PAD, (size_t)plen);
/* Add the terminating bit-count */
SHA512_Update(ctx, len, 16);
}
/* SHA-512 initialization. Begins a SHA-512 operation. */
void
SHA512_Init(SHA512_CTX * ctx)
{
/* Zero bits processed so far */
ctx->count[0] = ctx->count[1] = 0;
/* Magic initialization constants */
ctx->state[0] = 0x6a09e667f3bcc908ULL;
ctx->state[1] = 0xbb67ae8584caa73bULL;
ctx->state[2] = 0x3c6ef372fe94f82bULL;
ctx->state[3] = 0xa54ff53a5f1d36f1ULL;
ctx->state[4] = 0x510e527fade682d1ULL;
ctx->state[5] = 0x9b05688c2b3e6c1fULL;
ctx->state[6] = 0x1f83d9abfb41bd6bULL;
ctx->state[7] = 0x5be0cd19137e2179ULL;
}
/* Add bytes into the hash */
void
SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len)
{
uint64_t bitlen[2];
uint64_t r;
const unsigned char *src = in;
/* Number of bytes left in the buffer from previous updates */
r = (ctx->count[1] >> 3) & 0x7f;
/* Convert the length into a number of bits */
bitlen[1] = ((uint64_t)len) << 3;
bitlen[0] = ((uint64_t)len) >> 61;
/* Update number of bits */
if ((ctx->count[1] += bitlen[1]) < bitlen[1])
ctx->count[0]++;
ctx->count[0] += bitlen[0];
/* Handle the case where we don't need to perform any transforms */
if (len < 128 - r) {
memcpy(&ctx->buf[r], src, len);
return;
}
/* Finish the current block */
memcpy(&ctx->buf[r], src, 128 - r);
SHA512_Transform(ctx->state, ctx->buf);
src += 128 - r;
len -= 128 - r;
/* Perform complete blocks */
while (len >= 128) {
SHA512_Transform(ctx->state, src);
src += 128;
len -= 128;
}
/* Copy left over data into buffer */
memcpy(ctx->buf, src, len);
}
/*
* SHA-512 finalization. Pads the input data, exports the hash value,
* and clears the context state.
*/
void
SHA512_Final(unsigned char digest[64], SHA512_CTX * ctx)
{
/* Add padding */
SHA512_Pad(ctx);
/* Write the hash */
be64enc_vect(digest, ctx->state, 64);
/* Clear the context state */
memset((void *)ctx, 0, sizeof(*ctx));
}

View File

@@ -55,14 +55,6 @@ $(PROJECT_INCLUDE)/memory.h: include/memory.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/memory.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/memory.h
$(PROJECT_INCLUDE)/md4.h: libmd/md4.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/md4.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/md4.h
$(PROJECT_INCLUDE)/md5.h: libmd/md5.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/md5.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/md5.h
$(PROJECT_INCLUDE)/sys/ioccom.h: libcsupport/include/sys/ioccom.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/ioccom.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/ioccom.h

View File

@@ -1,6 +1,7 @@
ACLOCAL_AMFLAGS = -I ../aclocal
_SUBDIRS = POSIX
_SUBDIRS += sha
_SUBDIRS += i2c01
_SUBDIRS += newlib01
_SUBDIRS += block17

View File

@@ -66,6 +66,7 @@ AS_IF([test x"$HAVE_LIBDL" = x"yes"],[
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile
sha/Makefile
i2c01/Makefile
newlib01/Makefile
block17/Makefile

View File

@@ -0,0 +1,19 @@
rtems_tests_PROGRAMS = sha
sha_SOURCES = init.c
dist_rtems_tests_DATA = sha.scn sha.doc
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../automake/compile.am
include $(top_srcdir)/../automake/leaf.am
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
LINK_OBJS = $(sha_OBJECTS)
LINK_LIBS = $(sha_LDLIBS)
sha$(EXEEXT): $(sha_OBJECTS) $(sha_DEPENDENCIES)
@rm -f sha$(EXEEXT)
$(make-exe)
include $(top_srcdir)/../automake/local.am

View File

@@ -0,0 +1,191 @@
/*
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sha256.h>
#include <sha512.h>
#include <stdio.h>
#include <string.h>
#include "tmacros.h"
const char rtems_test_name[] = "SHA";
static const char *const test_vectors[] = {
"abc",
"",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
};
static const unsigned char
test_sha256_results[RTEMS_ARRAY_SIZE(test_vectors)][32] = {
{
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
}, {
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
}, {
0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1
}, {
0xcf, 0x5b, 0x16, 0xa7, 0x78, 0xaf, 0x83, 0x80,
0x03, 0x6c, 0xe5, 0x9e, 0x7b, 0x04, 0x92, 0x37,
0x0b, 0x24, 0x9b, 0x11, 0xe8, 0xf0, 0x7a, 0x51,
0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1
}
};
static const unsigned char
test_sha512_results[RTEMS_ARRAY_SIZE(test_vectors)][64] = {
{
0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f
}, {
0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e
}, {
0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a,
0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16,
0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8,
0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35,
0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9,
0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0,
0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03,
0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45
}, {
0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09
}
};
static void print_result(const unsigned char *r, size_t n)
{
size_t i;
for (i = 0; i < n; ++i) {
if (i == 0) {
/* Do nothing */
} else if (i % 32 == 0) {
printf("\n");
} else if (i % 8 == 0) {
printf(" ");
}
printf("%02x", r[i]);
}
printf("\n");
}
static void test_sha256(void)
{
size_t i;
printf("test SHA256\n");
for (i = 0; i < RTEMS_ARRAY_SIZE(test_vectors); ++i) {
SHA256_CTX ctx;
unsigned char r[32];
const char *s = test_vectors[i];
SHA256_Init(&ctx);
SHA256_Update(&ctx, s, strlen(s));
SHA256_Final(r, &ctx);
print_result(&r[0], sizeof(r));
rtems_test_assert(
memcmp(&r[0], &test_sha256_results[i][0], sizeof(r)) == 0
);
}
}
static void test_sha512(void)
{
size_t i;
printf("test SHA512\n");
for (i = 0; i < RTEMS_ARRAY_SIZE(test_vectors); ++i) {
SHA512_CTX ctx;
unsigned char r[64];
const char *s = test_vectors[i];
SHA512_Init(&ctx);
SHA512_Update(&ctx, s, strlen(s));
SHA512_Final(r, &ctx);
print_result(&r[0], sizeof(r));
rtems_test_assert(
memcmp(&r[0], &test_sha512_results[i][0], sizeof(r)) == 0
);
}
}
static void Init(rtems_task_argument arg)
{
TEST_BEGIN();
test_sha256();
test_sha512();
TEST_END();
rtems_test_exit(0);
}
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>

View File

@@ -0,0 +1,17 @@
This file describes the directives and concepts tested by this test set.
test set name: sha01
directives:
- SHA256_Init
- SHA256_Update
- SHA256_Final
- SHA512_Init
- SHA512_Update
- SHA512_Final
concepts:
- Ensure that the SHA256 and SHA512 implementations yield the expected
results for some standard test vectors.

View File

@@ -0,0 +1,16 @@
*** BEGIN OF TEST SHA ***
test SHA256
ba7816bf8f01cfea 414140de5dae2223 b00361a396177a9c b410ff61f20015ad
e3b0c44298fc1c14 9afbf4c8996fb924 27ae41e4649b934c a495991b7852b855
248d6a61d20638b8 e5c026930c3e6039 a33ce45964ff2167 f6ecedd419db06c1
cf5b16a778af8380 036ce59e7b049237 0b249b11e8f07a51 afac45037afee9d1
test SHA512
ddaf35a193617aba cc417349ae204131 12e6fa4e89a97ea2 0a9eeee64b55d39a
2192992a274fc1a8 36ba3c23a3feebbd 454d4423643ce80e 2a9ac94fa54ca49f
cf83e1357eefb8bd f1542850d66d8007 d620e4050b5715dc 83f4a921d36ce9ce
47d0d13c5d85f2b0 ff8318d2877eec2f 63b931bd47417a81 a538327af927da3e
204a8fc6dda82f0a 0ced7beb8e08a416 57c16ef468b228a8 279be331a703c335
96fd15c13b1b07f9 aa1d3bea57789ca0 31ad85c7a71dd703 54ec631238ca3445
8e959b75dae313da 8cf4f72814fc143f 8f7779c6eb9f7fa1 7299aeadb6889018
501d289e4900f7e4 331b99dec4b5433a c7d329eeb6dd2654 5e96e55b874be909
*** END OF TEST SHA ***