mirror of
https://github.com/nodemcu/nodemcu-firmware.git
synced 2025-01-16 20:52:57 +08:00
Crypto library with unified interface.
Uses both existing MD2/MD5/SHA1 and the Gifford SHA256-512, unless WITHOUT_SHA2 is defined.
This commit is contained in:
parent
68ef22ace5
commit
32dd9b7b7a
@ -37,7 +37,8 @@ SUBDIRS= \
|
||||
wofs \
|
||||
modules \
|
||||
spiffs \
|
||||
cjson
|
||||
cjson \
|
||||
crypto \
|
||||
|
||||
endif # } PDIR
|
||||
|
||||
@ -86,6 +87,7 @@ COMPONENTS_eagle.app.v6 = \
|
||||
wofs/wofs.a \
|
||||
spiffs/spiffs.a \
|
||||
cjson/libcjson.a \
|
||||
crypto/libcrypto.a \
|
||||
modules/libmodules.a
|
||||
|
||||
LINKFLAGS_eagle.app.v6 = \
|
||||
|
44
app/crypto/Makefile
Normal file
44
app/crypto/Makefile
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
#############################################################
|
||||
# Required variables for each makefile
|
||||
# Discard this section from all parent makefiles
|
||||
# Expected variables (with automatic defaults):
|
||||
# CSRCS (all "C" files in the dir)
|
||||
# SUBDIRS (all subdirs with a Makefile)
|
||||
# GEN_LIBS - list of libs to be generated ()
|
||||
# GEN_IMAGES - list of images to be generated ()
|
||||
# COMPONENTS_xxx - a list of libs/objs in the form
|
||||
# subdir/lib to be extracted and rolled up into
|
||||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libcrypto.a
|
||||
endif
|
||||
|
||||
#############################################################
|
||||
# Configuration i.e. compile options etc.
|
||||
# Target specific stuff (defines etc.) goes in here!
|
||||
# Generally values applying to a tree are captured in the
|
||||
# makefile at its root level - these are then overridden
|
||||
# for a subtree within the makefile rooted therein
|
||||
#
|
||||
#DEFINES +=
|
||||
|
||||
#############################################################
|
||||
# Recursion Magic - Don't touch this!!
|
||||
#
|
||||
# Each subtree potentially has an include directory
|
||||
# corresponding to the common APIs applicable to modules
|
||||
# rooted at that subtree. Accordingly, the INCLUDE PATH
|
||||
# of a module can only contain the include directories up
|
||||
# its parent path, and not its siblings
|
||||
#
|
||||
# Required for each makefile to inherit from the parent
|
||||
#
|
||||
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
INCLUDES += -I ./
|
||||
INCLUDES += -I ../libc
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
||||
|
168
app/crypto/digests.c
Normal file
168
app/crypto/digests.c
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2015, DiUS Computing Pty Ltd (jmattsson@dius.com.au)
|
||||
* 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.
|
||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 CONTRIBUTOR(S) 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 "digests.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/arch.h"
|
||||
#include "ssl/ssl_crypto.h"
|
||||
#include "sha2.h"
|
||||
#include <string.h>
|
||||
#include <c_errno.h>
|
||||
|
||||
typedef char ensure_int_and_size_t_same[(sizeof(int)==sizeof(size_t)) ? 0 : -1];
|
||||
|
||||
/* None of the functions match the prototype fully due to the void *, and in
|
||||
some cases also the int vs size_t len, so wrap declarations in a macro. */
|
||||
#define MECH(pfx, ds, bs) \
|
||||
{ #pfx, \
|
||||
(create_ctx_fn)pfx ## _Init, \
|
||||
(update_ctx_fn)pfx ## _Update, \
|
||||
(finalize_ctx_fn)pfx ## _Final, \
|
||||
sizeof(pfx ## _CTX), \
|
||||
ds, \
|
||||
bs }
|
||||
|
||||
static const digest_mech_info_t hash_mechs[] =
|
||||
{
|
||||
MECH(MD2, MD2_SIZE, 16)
|
||||
,MECH(MD5, MD5_SIZE, 64)
|
||||
,MECH(SHA1, SHA1_SIZE, 64)
|
||||
#ifndef WITHOUT_SHA2
|
||||
,MECH(SHA256, SHA256_DIGEST_LENGTH, SHA256_BLOCK_LENGTH)
|
||||
,MECH(SHA384, SHA384_DIGEST_LENGTH, SHA384_BLOCK_LENGTH)
|
||||
,MECH(SHA512, SHA512_DIGEST_LENGTH, SHA512_BLOCK_LENGTH)
|
||||
#endif
|
||||
};
|
||||
|
||||
#undef MECH
|
||||
|
||||
const digest_mech_info_t *crypto_digest_mech (const char *mech)
|
||||
{
|
||||
if (!mech)
|
||||
return 0;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < (sizeof (hash_mechs) / sizeof (digest_mech_info_t)); ++i)
|
||||
{
|
||||
const digest_mech_info_t *mi = hash_mechs + i;
|
||||
if (strcasecmp (mech, mi->name) == 0)
|
||||
return mi;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
// note: supports in-place encoding
|
||||
void crypto_encode_asciihex (const char *bin, size_t binlen, char *outbuf)
|
||||
{
|
||||
size_t aidx = binlen * 2;
|
||||
int i;
|
||||
for (i = binlen -1; i >= 0; --i)
|
||||
{
|
||||
outbuf[aidx--] = hex[bin[i] & 0xf];
|
||||
outbuf[aidx--] = hex[bin[i] >> 4];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t crypto_digest_size (const char *mech)
|
||||
{
|
||||
const digest_mech_info_t *mi = crypto_digest_mech (mech);
|
||||
return mi ? mi->digest_size : 0;
|
||||
}
|
||||
|
||||
|
||||
int crypto_hash (const digest_mech_info_t *mi,
|
||||
const char *data, size_t data_len,
|
||||
uint8_t *digest)
|
||||
{
|
||||
if (!mi)
|
||||
return EINVAL;
|
||||
|
||||
void *ctx = os_malloc (mi->ctx_size);
|
||||
if (!ctx)
|
||||
return ENOMEM;
|
||||
|
||||
mi->create (ctx);
|
||||
mi->update (ctx, data, data_len);
|
||||
mi->finalize (digest, ctx);
|
||||
|
||||
os_free (ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int crypto_hmac (const digest_mech_info_t *mi,
|
||||
const char *data, size_t data_len,
|
||||
const char *key, size_t key_len,
|
||||
uint8_t *digest)
|
||||
{
|
||||
if (!mi)
|
||||
return EINVAL;
|
||||
|
||||
void *ctx = os_malloc (mi->ctx_size);
|
||||
if (!ctx)
|
||||
return ENOMEM;
|
||||
|
||||
// If key too long, it needs to be hashed before use
|
||||
if (key_len > mi->block_size)
|
||||
{
|
||||
mi->create (ctx);
|
||||
mi->update (ctx, key, key_len);
|
||||
mi->finalize (digest, ctx);
|
||||
key = digest;
|
||||
key_len = mi->block_size;
|
||||
}
|
||||
|
||||
const size_t bs = mi->block_size;
|
||||
uint8_t k_ipad[bs];
|
||||
uint8_t k_opad[bs];
|
||||
|
||||
os_memset (k_ipad, 0x36, bs);
|
||||
os_memset (k_opad, 0x5c, bs);
|
||||
size_t i;
|
||||
for (i = 0; i < key_len; ++i)
|
||||
{
|
||||
k_ipad[i] ^= key[i];
|
||||
k_opad[i] ^= key[i];
|
||||
}
|
||||
|
||||
mi->create (ctx);
|
||||
mi->update (ctx, k_ipad, bs);
|
||||
mi->update (ctx, data, data_len);
|
||||
mi->finalize (digest, ctx);
|
||||
|
||||
mi->create (ctx);
|
||||
mi->update (ctx, k_opad, bs);
|
||||
mi->update (ctx, digest, mi->digest_size);
|
||||
mi->finalize (digest, ctx);
|
||||
|
||||
os_free (ctx);
|
||||
return 0;
|
||||
}
|
81
app/crypto/digests.h
Normal file
81
app/crypto/digests.h
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef _CRYPTO_DIGESTS_H_
|
||||
#define _CRYPTO_DIGESTS_H_
|
||||
|
||||
#include <c_types.h>
|
||||
|
||||
typedef void (*create_ctx_fn)(void *ctx);
|
||||
typedef void (*update_ctx_fn)(void *ctx, const uint8_t *msg, int len);
|
||||
typedef void (*finalize_ctx_fn)(uint8_t *digest, void *ctx);
|
||||
|
||||
/**
|
||||
* Description of a message digest mechanism.
|
||||
*
|
||||
* Typical usage (if not using the crypto_xxxx() functions below):
|
||||
* digest_mech_info_t *mi = crypto_digest_mech (chosen_algorithm);
|
||||
* void *ctx = os_malloc (mi->ctx_size);
|
||||
* mi->create (ctx);
|
||||
* mi->update (ctx, data, len);
|
||||
* ...
|
||||
* uint8_t *digest = os_malloc (mi->digest_size);
|
||||
* mi->finalize (digest, ctx);
|
||||
* ...
|
||||
* os_free (ctx);
|
||||
* os_free (digest);
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const char * name;
|
||||
create_ctx_fn create;
|
||||
update_ctx_fn update;
|
||||
finalize_ctx_fn finalize;
|
||||
uint16_t ctx_size;
|
||||
uint16_t digest_size;
|
||||
uint16_t block_size;
|
||||
} digest_mech_info_t;
|
||||
|
||||
|
||||
/**
|
||||
* Looks up the mech data for a specified digest algorithm.
|
||||
* @param mech The name of the algorithm, e.g. "MD5", "SHA256"
|
||||
* @returns The mech data, or null if the mech is unknown.
|
||||
*/
|
||||
const digest_mech_info_t *crypto_digest_mech (const char *mech);
|
||||
|
||||
/**
|
||||
* Wrapper function for performing a one-in-all hashing operation.
|
||||
* @param mi A mech from @c crypto_digest_mech(). A null pointer @c mi
|
||||
* is harmless, but will of course result in an error return.
|
||||
* @param data The data to create a digest for.
|
||||
* @param data_len Number of bytes at @c data to digest.
|
||||
* @param digest Output buffer, must be at least @c mi->digest_size in size.
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int crypto_hash (const digest_mech_info_t *mi, const char *data, size_t data_len, uint8_t *digest);
|
||||
|
||||
|
||||
/**
|
||||
* Generate a HMAC signature.
|
||||
* @param mi A mech from @c crypto_digest_mech(). A null pointer @c mi
|
||||
* is harmless, but will of course result in an error return.
|
||||
* @param data The data to generate a signature for.
|
||||
* @param data_len Number of bytes at @c data to process.
|
||||
* @param key The key to use.
|
||||
* @param key_len Number of bytes the @c key comprises.
|
||||
* @param digest Output buffer, must be at least @c mi->digest_size in size.
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int crypto_hmac (const digest_mech_info_t *mi, const char *data, size_t data_len, const char *key, size_t key_len, uint8_t *digest);
|
||||
|
||||
/**
|
||||
* Perform ASCII Hex encoding. Does not null-terminate the buffer.
|
||||
*
|
||||
* @param bin The buffer to ascii-hex encode.
|
||||
* @param bin_len Number of bytes in @c bin to encode.
|
||||
* @param outbuf Output buffer, must be at least @c bin_len*2 bytes in size.
|
||||
* Note that in-place encoding is supported, and as such
|
||||
* bin==outbuf is safe, provided the buffer is large enough.
|
||||
*/
|
||||
void crypto_encode_asciihex (const char *bin, size_t bin_len, char *outbuf);
|
||||
|
||||
|
||||
#endif
|
@ -3,6 +3,7 @@
|
||||
* AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
|
||||
*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* Copyright (c) 2015, DiUS Computing Pty Ltd (jmattsson@dius.com.au)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -31,9 +32,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */
|
||||
#include <assert.h> /* assert() */
|
||||
#ifndef WITHOUT_SHA2
|
||||
|
||||
#include "sha2.h"
|
||||
#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */
|
||||
#define assert(x) do {} while (0)
|
||||
|
||||
/*
|
||||
* ASSERT NOTE:
|
||||
@ -56,76 +59,19 @@
|
||||
*/
|
||||
|
||||
|
||||
/*** SHA-256/384/512 Machine Architecture Definitions *****************/
|
||||
/*
|
||||
* BYTE_ORDER NOTE:
|
||||
*
|
||||
* Please make sure that your system defines BYTE_ORDER. If your
|
||||
* architecture is little-endian, make sure it also defines
|
||||
* LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
|
||||
* equivilent.
|
||||
*
|
||||
* If your system does not define the above, then you can do so by
|
||||
* hand like this:
|
||||
*
|
||||
* #define LITTLE_ENDIAN 1234
|
||||
* #define BIG_ENDIAN 4321
|
||||
*
|
||||
* And for little-endian machines, add:
|
||||
*
|
||||
* #define BYTE_ORDER LITTLE_ENDIAN
|
||||
*
|
||||
* Or for big-endian machines:
|
||||
*
|
||||
* #define BYTE_ORDER BIG_ENDIAN
|
||||
*
|
||||
* The FreeBSD machine this was written on defines BYTE_ORDER
|
||||
* appropriately by including <sys/types.h> (which in turn includes
|
||||
* <machine/endian.h> where the appropriate definitions are actually
|
||||
* made).
|
||||
*/
|
||||
#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
|
||||
#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define the followingsha2_* types to types of the correct length on
|
||||
* the native archtecture. Most BSD systems and Linux define u_intXX_t
|
||||
* types. Machines with very recent ANSI C headers, can use the
|
||||
* uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
|
||||
* during compile or in the sha.h header file.
|
||||
*
|
||||
* Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
|
||||
* will need to define these three typedefs below (and the appropriate
|
||||
* ones in sha.h too) by hand according to their system architecture.
|
||||
*
|
||||
* Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
|
||||
* types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
|
||||
*/
|
||||
#ifdef SHA2_USE_INTTYPES_H
|
||||
|
||||
typedef uint8_t sha2_byte; /* Exactly 1 byte */
|
||||
typedef uint32_t sha2_word32; /* Exactly 4 bytes */
|
||||
typedef uint64_t sha2_word64; /* Exactly 8 bytes */
|
||||
|
||||
#else /* SHA2_USE_INTTYPES_H */
|
||||
|
||||
typedef u_int8_t sha2_byte; /* Exactly 1 byte */
|
||||
typedef u_int32_t sha2_word32; /* Exactly 4 bytes */
|
||||
typedef u_int64_t sha2_word64; /* Exactly 8 bytes */
|
||||
|
||||
#endif /* SHA2_USE_INTTYPES_H */
|
||||
|
||||
|
||||
/*** SHA-256/384/512 Various Length Definitions ***********************/
|
||||
/* NOTE: Most of these are in sha2.h */
|
||||
#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
|
||||
#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
|
||||
#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
|
||||
|
||||
|
||||
/*** ENDIAN REVERSAL MACROS *******************************************/
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define REVERSE32(w,x) { \
|
||||
sha2_word32 tmp = (w); \
|
||||
tmp = (tmp >> 16) | (tmp << 16); \
|
||||
@ -139,7 +85,7 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */
|
||||
(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
|
||||
((tmp & 0x0000ffff0000ffffULL) << 16); \
|
||||
}
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
|
||||
|
||||
/*
|
||||
* Macro for incrementally adding the unsigned 64-bit integer n to the
|
||||
@ -324,15 +270,9 @@ const static sha2_word64 sha512_initial_hash_value[8] = {
|
||||
0x5be0cd19137e2179ULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Constant used by SHA256/384/512_End() functions for converting the
|
||||
* digest to a readable hexadecimal character string:
|
||||
*/
|
||||
static const char *sha2_hex_digits = "0123456789abcdef";
|
||||
|
||||
|
||||
/*** SHA-256: *********************************************************/
|
||||
void SHA256_Init(SHA256_CTX* context) {
|
||||
void ICACHE_FLASH_ATTR SHA256_Init(SHA256_CTX* context) {
|
||||
if (context == (SHA256_CTX*)0) {
|
||||
return;
|
||||
}
|
||||
@ -345,7 +285,7 @@ void SHA256_Init(SHA256_CTX* context) {
|
||||
|
||||
/* Unrolled SHA-256 round macros: */
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN_
|
||||
|
||||
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
|
||||
REVERSE32(*data++, W256[j]); \
|
||||
@ -356,7 +296,7 @@ void SHA256_Init(SHA256_CTX* context) {
|
||||
j++
|
||||
|
||||
|
||||
#else /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN_ */
|
||||
|
||||
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
|
||||
T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
|
||||
@ -365,7 +305,7 @@ void SHA256_Init(SHA256_CTX* context) {
|
||||
(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
|
||||
j++
|
||||
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN_ */
|
||||
|
||||
#define ROUND256(a,b,c,d,e,f,g,h) \
|
||||
s0 = W256[(j+1)&0x0f]; \
|
||||
@ -378,7 +318,7 @@ void SHA256_Init(SHA256_CTX* context) {
|
||||
(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
|
||||
j++
|
||||
|
||||
void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
|
||||
void ICACHE_FLASH_ATTR SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
|
||||
sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
|
||||
sha2_word32 T1, *W256;
|
||||
int j;
|
||||
@ -436,7 +376,7 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
|
||||
|
||||
#else /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
|
||||
void ICACHE_FLASH_ATTR SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
|
||||
sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
|
||||
sha2_word32 T1, T2, *W256;
|
||||
int j;
|
||||
@ -455,15 +395,15 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
/* Copy data while converting to host byte order */
|
||||
REVERSE32(*data++,W256[j]);
|
||||
/* Apply the SHA-256 compression function to update a..h */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
|
||||
#else /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN_ */
|
||||
/* Apply the SHA-256 compression function to update a..h with copy */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN_ */
|
||||
T2 = Sigma0_256(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
@ -516,7 +456,7 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
|
||||
|
||||
#endif /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
|
||||
void ICACHE_FLASH_ATTR SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
|
||||
unsigned int freespace, usedspace;
|
||||
|
||||
if (len == 0) {
|
||||
@ -564,7 +504,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
|
||||
usedspace = freespace = 0;
|
||||
}
|
||||
|
||||
void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
|
||||
void ICACHE_FLASH_ATTR SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
|
||||
sha2_word32 *d = (sha2_word32*)digest;
|
||||
unsigned int usedspace;
|
||||
|
||||
@ -574,7 +514,7 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
|
||||
/* If no digest buffer is passed, we don't bother doing this: */
|
||||
if (digest != (sha2_byte*)0) {
|
||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
/* Convert FROM host byte order */
|
||||
REVERSE64(context->bitcount,context->bitcount);
|
||||
#endif
|
||||
@ -608,7 +548,7 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
|
||||
/* Final transform: */
|
||||
SHA256_Transform(context, (sha2_word32*)context->buffer);
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
{
|
||||
/* Convert TO host byte order */
|
||||
int j;
|
||||
@ -627,40 +567,9 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
|
||||
usedspace = 0;
|
||||
}
|
||||
|
||||
char *SHA256_End(SHA256_CTX* context, char buffer[]) {
|
||||
sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
|
||||
int i;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA256_CTX*)0);
|
||||
|
||||
if (buffer != (char*)0) {
|
||||
SHA256_Final(digest, context);
|
||||
|
||||
for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
|
||||
*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
|
||||
*buffer++ = sha2_hex_digits[*d & 0x0f];
|
||||
d++;
|
||||
}
|
||||
*buffer = (char)0;
|
||||
} else {
|
||||
MEMSET_BZERO(context, sizeof(SHA256_CTX));
|
||||
}
|
||||
MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
|
||||
SHA256_CTX context;
|
||||
|
||||
SHA256_Init(&context);
|
||||
SHA256_Update(&context, data, len);
|
||||
return SHA256_End(&context, digest);
|
||||
}
|
||||
|
||||
|
||||
/*** SHA-512: *********************************************************/
|
||||
void SHA512_Init(SHA512_CTX* context) {
|
||||
void ICACHE_FLASH_ATTR SHA512_Init(SHA512_CTX* context) {
|
||||
if (context == (SHA512_CTX*)0) {
|
||||
return;
|
||||
}
|
||||
@ -672,7 +581,7 @@ void SHA512_Init(SHA512_CTX* context) {
|
||||
#ifdef SHA2_UNROLL_TRANSFORM
|
||||
|
||||
/* Unrolled SHA-512 round macros: */
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN_
|
||||
|
||||
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
|
||||
REVERSE64(*data++, W512[j]); \
|
||||
@ -683,7 +592,7 @@ void SHA512_Init(SHA512_CTX* context) {
|
||||
j++
|
||||
|
||||
|
||||
#else /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN_ */
|
||||
|
||||
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
|
||||
T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
|
||||
@ -692,7 +601,7 @@ void SHA512_Init(SHA512_CTX* context) {
|
||||
(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
|
||||
j++
|
||||
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN_ */
|
||||
|
||||
#define ROUND512(a,b,c,d,e,f,g,h) \
|
||||
s0 = W512[(j+1)&0x0f]; \
|
||||
@ -705,7 +614,7 @@ void SHA512_Init(SHA512_CTX* context) {
|
||||
(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
|
||||
j++
|
||||
|
||||
void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
|
||||
void ICACHE_FLASH_ATTR SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
|
||||
sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
|
||||
sha2_word64 T1, *W512 = (sha2_word64*)context->buffer;
|
||||
int j;
|
||||
@ -760,7 +669,7 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
|
||||
|
||||
#else /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
|
||||
void ICACHE_FLASH_ATTR SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
|
||||
sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
|
||||
sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer;
|
||||
int j;
|
||||
@ -777,15 +686,15 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
/* Convert TO host byte order */
|
||||
REVERSE64(*data++, W512[j]);
|
||||
/* Apply the SHA-512 compression function to update a..h */
|
||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
|
||||
#else /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN_ */
|
||||
/* Apply the SHA-512 compression function to update a..h with copy */
|
||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN_ */
|
||||
T2 = Sigma0_512(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
@ -838,7 +747,7 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
|
||||
|
||||
#endif /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
|
||||
void ICACHE_FLASH_ATTR SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
|
||||
unsigned int freespace, usedspace;
|
||||
|
||||
if (len == 0) {
|
||||
@ -886,11 +795,11 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
|
||||
usedspace = freespace = 0;
|
||||
}
|
||||
|
||||
void SHA512_Last(SHA512_CTX* context) {
|
||||
void ICACHE_FLASH_ATTR SHA512_Last(SHA512_CTX* context) {
|
||||
unsigned int usedspace;
|
||||
|
||||
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
/* Convert FROM host byte order */
|
||||
REVERSE64(context->bitcount[0],context->bitcount[0]);
|
||||
REVERSE64(context->bitcount[1],context->bitcount[1]);
|
||||
@ -927,7 +836,7 @@ void SHA512_Last(SHA512_CTX* context) {
|
||||
SHA512_Transform(context, (sha2_word64*)context->buffer);
|
||||
}
|
||||
|
||||
void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
|
||||
void ICACHE_FLASH_ATTR SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
|
||||
sha2_word64 *d = (sha2_word64*)digest;
|
||||
|
||||
/* Sanity check: */
|
||||
@ -938,7 +847,7 @@ void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
|
||||
SHA512_Last(context);
|
||||
|
||||
/* Save the hash data for output: */
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
{
|
||||
/* Convert TO host byte order */
|
||||
int j;
|
||||
@ -956,40 +865,9 @@ void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
|
||||
MEMSET_BZERO(context, sizeof(SHA512_CTX));
|
||||
}
|
||||
|
||||
char *SHA512_End(SHA512_CTX* context, char buffer[]) {
|
||||
sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest;
|
||||
int i;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA512_CTX*)0);
|
||||
|
||||
if (buffer != (char*)0) {
|
||||
SHA512_Final(digest, context);
|
||||
|
||||
for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
|
||||
*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
|
||||
*buffer++ = sha2_hex_digits[*d & 0x0f];
|
||||
d++;
|
||||
}
|
||||
*buffer = (char)0;
|
||||
} else {
|
||||
MEMSET_BZERO(context, sizeof(SHA512_CTX));
|
||||
}
|
||||
MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
|
||||
SHA512_CTX context;
|
||||
|
||||
SHA512_Init(&context);
|
||||
SHA512_Update(&context, data, len);
|
||||
return SHA512_End(&context, digest);
|
||||
}
|
||||
|
||||
|
||||
/*** SHA-384: *********************************************************/
|
||||
void SHA384_Init(SHA384_CTX* context) {
|
||||
void ICACHE_FLASH_ATTR SHA384_Init(SHA384_CTX* context) {
|
||||
if (context == (SHA384_CTX*)0) {
|
||||
return;
|
||||
}
|
||||
@ -998,11 +876,11 @@ void SHA384_Init(SHA384_CTX* context) {
|
||||
context->bitcount[0] = context->bitcount[1] = 0;
|
||||
}
|
||||
|
||||
void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
|
||||
void ICACHE_FLASH_ATTR SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
|
||||
SHA512_Update((SHA512_CTX*)context, data, len);
|
||||
}
|
||||
|
||||
void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
|
||||
void ICACHE_FLASH_ATTR SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
|
||||
sha2_word64 *d = (sha2_word64*)digest;
|
||||
|
||||
/* Sanity check: */
|
||||
@ -1013,7 +891,7 @@ void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
|
||||
SHA512_Last((SHA512_CTX*)context);
|
||||
|
||||
/* Save the hash data for output: */
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
{
|
||||
/* Convert TO host byte order */
|
||||
int j;
|
||||
@ -1031,34 +909,4 @@ void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
|
||||
MEMSET_BZERO(context, sizeof(SHA384_CTX));
|
||||
}
|
||||
|
||||
char *SHA384_End(SHA384_CTX* context, char buffer[]) {
|
||||
sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest;
|
||||
int i;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA384_CTX*)0);
|
||||
|
||||
if (buffer != (char*)0) {
|
||||
SHA384_Final(digest, context);
|
||||
|
||||
for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
|
||||
*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
|
||||
*buffer++ = sha2_hex_digits[*d & 0x0f];
|
||||
d++;
|
||||
}
|
||||
*buffer = (char)0;
|
||||
} else {
|
||||
MEMSET_BZERO(context, sizeof(SHA384_CTX));
|
||||
}
|
||||
MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
|
||||
SHA384_CTX context;
|
||||
|
||||
SHA384_Init(&context);
|
||||
SHA384_Update(&context, data, len);
|
||||
return SHA384_End(&context, digest);
|
||||
}
|
||||
|
||||
#endif // WITHOUT_SHA2
|
||||
|
47
app/crypto/sha2.h
Normal file
47
app/crypto/sha2.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef __SHA2_H__
|
||||
#define __SHA2_H__
|
||||
|
||||
#include <c_types.h>
|
||||
|
||||
/**************************************************************************
|
||||
* SHA256/384/512 declarations
|
||||
**************************************************************************/
|
||||
|
||||
#define SHA256_BLOCK_LENGTH 64
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t state[8];
|
||||
uint64_t bitcount;
|
||||
uint8_t buffer[SHA256_BLOCK_LENGTH];
|
||||
} SHA256_CTX;
|
||||
|
||||
|
||||
void SHA256_Init(SHA256_CTX *);
|
||||
void SHA256_Update(SHA256_CTX *, const uint8_t *msg, size_t len);
|
||||
void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
|
||||
|
||||
#define SHA384_BLOCK_LENGTH 128
|
||||
#define SHA384_DIGEST_LENGTH 48
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t state[8];
|
||||
uint64_t bitcount[2];
|
||||
uint8_t buffer[SHA384_BLOCK_LENGTH];
|
||||
} SHA384_CTX;
|
||||
|
||||
void SHA384_Init(SHA384_CTX*);
|
||||
void SHA384_Update(SHA384_CTX*, const uint8_t *msg, size_t len);
|
||||
void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
|
||||
|
||||
#define SHA512_BLOCK_LENGTH 128
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
typedef SHA384_CTX SHA512_CTX;
|
||||
|
||||
void SHA512_Init(SHA512_CTX*);
|
||||
void SHA512_Update(SHA512_CTX*, const uint8_t *msg, size_t len);
|
||||
void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user