mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-22 08:22:04 +03:00
Merge branch upstream into axtls-upgrade
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
* Copyright (c) 2007-2015, Cameron Rich
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -39,7 +39,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "bigint_impl.h"
|
||||
#include "bigint.h"
|
||||
|
||||
@ -124,22 +123,58 @@ void SHA1_Update(SHA1_CTX *, const uint8_t * msg, int len);
|
||||
void SHA1_Final(uint8_t *digest, SHA1_CTX *);
|
||||
|
||||
/**************************************************************************
|
||||
* MD2 declarations
|
||||
* SHA256 declarations
|
||||
**************************************************************************/
|
||||
|
||||
#define MD2_SIZE 16
|
||||
#define SHA256_SIZE 32
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char cksum[16]; /* checksum of the data block */
|
||||
unsigned char state[48]; /* intermediate digest state */
|
||||
unsigned char buffer[16]; /* data block being processed */
|
||||
int left; /* amount of data in buffer */
|
||||
} MD2_CTX;
|
||||
uint32_t total[2];
|
||||
uint32_t state[8];
|
||||
uint8_t buffer[64];
|
||||
} SHA256_CTX;
|
||||
|
||||
EXP_FUNC void STDCALL MD2_Init(MD2_CTX *ctx);
|
||||
EXP_FUNC void STDCALL MD2_Update(MD2_CTX *ctx, const uint8_t *input, int ilen);
|
||||
EXP_FUNC void STDCALL MD2_Final(uint8_t *digest, MD2_CTX *ctx);
|
||||
void SHA256_Init(SHA256_CTX *c);
|
||||
void SHA256_Update(SHA256_CTX *, const uint8_t *input, int len);
|
||||
void SHA256_Final(uint8_t *digest, SHA256_CTX *);
|
||||
|
||||
/**************************************************************************
|
||||
* SHA512 declarations
|
||||
**************************************************************************/
|
||||
|
||||
#define SHA512_SIZE 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
uint64_t h[8];
|
||||
uint8_t digest[64];
|
||||
} h_dig;
|
||||
union
|
||||
{
|
||||
uint64_t w[80];
|
||||
uint8_t buffer[128];
|
||||
} w_buf;
|
||||
size_t size;
|
||||
uint64_t totalSize;
|
||||
} SHA512_CTX;
|
||||
|
||||
void SHA512_Init(SHA512_CTX *c);
|
||||
void SHA512_Update(SHA512_CTX *, const uint8_t *input, int len);
|
||||
void SHA512_Final(uint8_t *digest, SHA512_CTX *);
|
||||
|
||||
/**************************************************************************
|
||||
* SHA384 declarations
|
||||
**************************************************************************/
|
||||
|
||||
#define SHA384_SIZE 48
|
||||
|
||||
typedef SHA512_CTX SHA384_CTX;
|
||||
void SHA384_Init(SHA384_CTX *c);
|
||||
void SHA384_Update(SHA384_CTX *, const uint8_t *input, int len);
|
||||
void SHA384_Final(uint8_t *digest, SHA384_CTX *);
|
||||
|
||||
/**************************************************************************
|
||||
* MD5 declarations
|
||||
@ -203,7 +238,7 @@ void RSA_pub_key_new(RSA_CTX **rsa_ctx,
|
||||
const uint8_t *pub_exp, int pub_len);
|
||||
void RSA_free(RSA_CTX *ctx);
|
||||
int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
|
||||
int is_decryption);
|
||||
int out_len, int is_decryption);
|
||||
bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg);
|
||||
#if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
|
||||
bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
|
||||
@ -220,8 +255,8 @@ void RSA_print(const RSA_CTX *ctx);
|
||||
EXP_FUNC void STDCALL RNG_initialize(void);
|
||||
EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size);
|
||||
EXP_FUNC void STDCALL RNG_terminate(void);
|
||||
EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data);
|
||||
void get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
|
||||
EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data);
|
||||
int get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
* Copyright (c) 2007-2015, Cameron Rich
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -162,11 +162,12 @@ EXP_FUNC void STDCALL RNG_terminate(void)
|
||||
/**
|
||||
* Set a series of bytes with a random number. Individual bytes can be 0
|
||||
*/
|
||||
EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data)
|
||||
{
|
||||
EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data)
|
||||
{
|
||||
#if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM)
|
||||
/* use the Linux default */
|
||||
read(rng_fd, rand_data, num_rand_bytes); /* read from /dev/urandom */
|
||||
/* use the Linux default - read from /dev/urandom */
|
||||
if (read(rng_fd, rand_data, num_rand_bytes) < 0)
|
||||
return -1;
|
||||
#elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB)
|
||||
/* use Microsoft Crypto Libraries */
|
||||
CryptGenRandom(gCryptProv, num_rand_bytes, rand_data);
|
||||
@ -211,15 +212,17 @@ EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data)
|
||||
/* insert the digest at the start of the entropy pool */
|
||||
memcpy(entropy_pool, digest, MD5_SIZE);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a series of bytes with a random number. Individual bytes are not zero.
|
||||
*/
|
||||
void get_random_NZ(int num_rand_bytes, uint8_t *rand_data)
|
||||
int get_random_NZ(int num_rand_bytes, uint8_t *rand_data)
|
||||
{
|
||||
int i;
|
||||
get_random(num_rand_bytes, rand_data);
|
||||
if (get_random(num_rand_bytes, rand_data))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < num_rand_bytes; i++)
|
||||
{
|
||||
@ -227,6 +230,8 @@ void get_random_NZ(int num_rand_bytes, uint8_t *rand_data)
|
||||
get_random(1, rand_data + i);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
162
crypto/md2.c
162
crypto/md2.c
@ -1,162 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* RFC 1115/1319 compliant MD2 implementation
|
||||
* The MD2 algorithm was designed by Ron Rivest in 1989.
|
||||
*
|
||||
* http://www.ietf.org/rfc/rfc1115.txt
|
||||
* http://www.ietf.org/rfc/rfc1319.txt
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "os_port.h"
|
||||
#include "crypto.h"
|
||||
|
||||
/**
|
||||
* This code is only here to enable the verification of Verisign root
|
||||
* certificates. So only enable it for verification mode.
|
||||
*/
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
|
||||
static const uint8_t PI_SUBST[256] =
|
||||
{
|
||||
0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
|
||||
0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
|
||||
0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
|
||||
0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
|
||||
0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
|
||||
0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
|
||||
0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
|
||||
0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
|
||||
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
|
||||
0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
|
||||
0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
|
||||
0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
|
||||
0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
|
||||
0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
|
||||
0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
|
||||
0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
|
||||
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
|
||||
0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
|
||||
0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
|
||||
0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
|
||||
0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
|
||||
0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
|
||||
0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
|
||||
0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
|
||||
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
|
||||
0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
|
||||
};
|
||||
|
||||
/*
|
||||
* MD2 context setup
|
||||
*/
|
||||
EXP_FUNC void STDCALL MD2_Init(MD2_CTX *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof *ctx);
|
||||
}
|
||||
|
||||
static void md2_process(MD2_CTX *ctx)
|
||||
{
|
||||
int i, j;
|
||||
uint8_t t = 0;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
ctx->state[i + 16] = ctx->buffer[i];
|
||||
ctx->state[i + 32] = ctx->buffer[i] ^ ctx->state[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < 18; i++)
|
||||
{
|
||||
for (j = 0; j < 48; j++)
|
||||
t = (ctx->state[j] ^= PI_SUBST[t]);
|
||||
|
||||
t = (t + i) & 0xFF;
|
||||
}
|
||||
|
||||
t = ctx->cksum[15];
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
t = (ctx->cksum[i] ^= PI_SUBST[ctx->buffer[i] ^ t]);
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 process buffer
|
||||
*/
|
||||
EXP_FUNC void STDCALL MD2_Update(MD2_CTX *ctx, const uint8_t *input, int ilen)
|
||||
{
|
||||
int fill;
|
||||
|
||||
while (ilen > 0)
|
||||
{
|
||||
if (ctx->left + ilen > 16)
|
||||
fill = 16 - ctx->left;
|
||||
else
|
||||
fill = ilen;
|
||||
|
||||
memcpy(ctx->buffer + ctx->left, input, fill);
|
||||
|
||||
ctx->left += fill;
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
|
||||
if (ctx->left == 16)
|
||||
{
|
||||
ctx->left = 0;
|
||||
md2_process(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MD2 final digest
|
||||
*/
|
||||
EXP_FUNC void STDCALL MD2_Final(uint8_t *output, MD2_CTX *ctx)
|
||||
{
|
||||
int i;
|
||||
uint8_t x;
|
||||
|
||||
x = (uint8_t)(16 - ctx->left);
|
||||
|
||||
for (i = ctx->left; i < 16; i++)
|
||||
ctx->buffer[i] = x;
|
||||
|
||||
md2_process(ctx);
|
||||
|
||||
memcpy(ctx->buffer, ctx->cksum, 16);
|
||||
md2_process(ctx);
|
||||
|
||||
memcpy(output, ctx->state, 16);
|
||||
}
|
||||
|
||||
#endif
|
@ -56,6 +56,7 @@ typedef INT64 int64_t;
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#endif /* Not Solaris */
|
||||
|
||||
#endif /* Not Win32 */
|
||||
|
46
crypto/rsa.c
46
crypto/rsa.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
* Copyright (c) 2007-2014, Cameron Rich
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -134,21 +134,26 @@ void RSA_free(RSA_CTX *rsa_ctx)
|
||||
/**
|
||||
* @brief Use PKCS1.5 for decryption/verification.
|
||||
* @param ctx [in] The context
|
||||
* @param in_data [in] The data to encrypt (must be < modulus size-11)
|
||||
* @param out_data [out] The encrypted data.
|
||||
* @param in_data [in] The data to decrypt (must be < modulus size-11)
|
||||
* @param out_data [out] The decrypted data.
|
||||
* @param out_len [int] The size of the decrypted buffer in bytes
|
||||
* @param is_decryption [in] Decryption or verify operation.
|
||||
* @return The number of bytes that were originally encrypted. -1 on error.
|
||||
* @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
|
||||
*/
|
||||
int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
|
||||
uint8_t *out_data, int is_decryption)
|
||||
uint8_t *out_data, int out_len, int is_decryption)
|
||||
{
|
||||
const int byte_size = ctx->num_octets;
|
||||
int i, size;
|
||||
int i = 0, size;
|
||||
bigint *decrypted_bi, *dat_bi;
|
||||
uint8_t *block = (uint8_t *)malloc(byte_size);
|
||||
int pad_count = 0;
|
||||
|
||||
memset(out_data, 0, byte_size); /* initialise */
|
||||
if (out_len < byte_size) /* check output has enough size */
|
||||
return -1;
|
||||
|
||||
memset(out_data, 0, out_len); /* initialise */
|
||||
|
||||
/* decrypt */
|
||||
dat_bi = bi_import(ctx->bi_ctx, in_data, byte_size);
|
||||
@ -162,28 +167,38 @@ int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
|
||||
/* convert to a normal block */
|
||||
bi_export(ctx->bi_ctx, decrypted_bi, block, byte_size);
|
||||
|
||||
i = 10; /* start at the first possible non-padded byte */
|
||||
if (block[i++] != 0) /* leading 0? */
|
||||
return -1;
|
||||
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
if (is_decryption == 0) /* PKCS1.5 signing pads with "0xff"s */
|
||||
{
|
||||
while (block[i++] == 0xff && i < byte_size);
|
||||
if (block[i++] != 0x01) /* BT correct? */
|
||||
return -1;
|
||||
|
||||
if (block[i-2] != 0xff)
|
||||
i = byte_size; /*ensure size is 0 */
|
||||
while (block[i++] == 0xff && i < byte_size)
|
||||
pad_count++;
|
||||
}
|
||||
else /* PKCS1.5 encryption padding is random */
|
||||
#endif
|
||||
{
|
||||
while (block[i++] && i < byte_size);
|
||||
if (block[i++] != 0x02) /* BT correct? */
|
||||
return -1;
|
||||
|
||||
while (block[i++] && i < byte_size)
|
||||
pad_count++;
|
||||
}
|
||||
|
||||
/* check separator byte 0x00 - and padding must be 8 or more bytes */
|
||||
if (i == byte_size || pad_count < 8)
|
||||
return -1;
|
||||
|
||||
size = byte_size - i;
|
||||
|
||||
/* get only the bit we want */
|
||||
if (size > 0)
|
||||
memcpy(out_data, &block[i], size);
|
||||
memcpy(out_data, &block[i], size);
|
||||
free(block);
|
||||
return size ? size : -1;
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -249,7 +264,8 @@ int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
|
||||
else /* randomize the encryption padding with non-zero bytes */
|
||||
{
|
||||
out_data[1] = 2;
|
||||
get_random_NZ(num_pads_needed, &out_data[2]);
|
||||
if (get_random_NZ(num_pads_needed, &out_data[2]) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
out_data[2+num_pads_needed] = 0;
|
||||
|
274
crypto/sha256.c
Normal file
274
crypto/sha256.c
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Cameron Rich
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <string.h>
|
||||
#include "os_port.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#define GET_UINT32(n,b,i) \
|
||||
{ \
|
||||
(n) = ((uint32_t) (b)[(i) ] << 24) \
|
||||
| ((uint32_t) (b)[(i) + 1] << 16) \
|
||||
| ((uint32_t) (b)[(i) + 2] << 8) \
|
||||
| ((uint32_t) (b)[(i) + 3] ); \
|
||||
}
|
||||
|
||||
#define PUT_UINT32(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (uint8_t) ((n) >> 24); \
|
||||
(b)[(i) + 1] = (uint8_t) ((n) >> 16); \
|
||||
(b)[(i) + 2] = (uint8_t) ((n) >> 8); \
|
||||
(b)[(i) + 3] = (uint8_t) ((n) ); \
|
||||
}
|
||||
|
||||
static const uint8_t sha256_padding[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
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the SHA256 context
|
||||
*/
|
||||
void SHA256_Init(SHA256_CTX *ctx)
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void SHA256_Process(const uint8_t digest[64], SHA256_CTX *ctx)
|
||||
{
|
||||
uint32_t temp1, temp2, W[64];
|
||||
uint32_t A, B, C, D, E, F, G, H;
|
||||
|
||||
GET_UINT32(W[0], digest, 0);
|
||||
GET_UINT32(W[1], digest, 4);
|
||||
GET_UINT32(W[2], digest, 8);
|
||||
GET_UINT32(W[3], digest, 12);
|
||||
GET_UINT32(W[4], digest, 16);
|
||||
GET_UINT32(W[5], digest, 20);
|
||||
GET_UINT32(W[6], digest, 24);
|
||||
GET_UINT32(W[7], digest, 28);
|
||||
GET_UINT32(W[8], digest, 32);
|
||||
GET_UINT32(W[9], digest, 36);
|
||||
GET_UINT32(W[10], digest, 40);
|
||||
GET_UINT32(W[11], digest, 44);
|
||||
GET_UINT32(W[12], digest, 48);
|
||||
GET_UINT32(W[13], digest, 52);
|
||||
GET_UINT32(W[14], digest, 56);
|
||||
GET_UINT32(W[15], digest, 60);
|
||||
|
||||
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
|
||||
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
|
||||
|
||||
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
|
||||
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
|
||||
|
||||
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
|
||||
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
|
||||
|
||||
#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
W[t] = S1(W[t - 2]) + W[t - 7] + \
|
||||
S0(W[t - 15]) + W[t - 16] \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||
{ \
|
||||
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||
temp2 = S2(a) + F0(a,b,c); \
|
||||
d += temp1; h = temp1 + temp2; \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
F = ctx->state[5];
|
||||
G = ctx->state[6];
|
||||
H = ctx->state[7];
|
||||
|
||||
P(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
|
||||
P(H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
|
||||
P(G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
|
||||
P(F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
|
||||
P(E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
|
||||
P(D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
|
||||
P(C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
|
||||
P(B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
|
||||
P(A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
|
||||
P(H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
|
||||
P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
|
||||
P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
|
||||
P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
|
||||
P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
|
||||
P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
|
||||
P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
|
||||
P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
|
||||
P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
|
||||
P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
|
||||
P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
|
||||
P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
|
||||
P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
|
||||
P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
|
||||
P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
|
||||
P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
|
||||
P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
|
||||
P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
|
||||
P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
|
||||
P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
|
||||
P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
|
||||
P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
|
||||
P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
|
||||
P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
|
||||
P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
|
||||
P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
|
||||
P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
|
||||
P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
|
||||
P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
|
||||
P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
|
||||
P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
|
||||
P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
|
||||
P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
|
||||
P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
|
||||
P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
|
||||
P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
|
||||
P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
|
||||
P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
|
||||
P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
|
||||
P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
|
||||
P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
|
||||
P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
|
||||
P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
|
||||
P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
|
||||
P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
|
||||
P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
|
||||
P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
|
||||
P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
|
||||
P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
|
||||
P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
|
||||
P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
|
||||
P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
|
||||
P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
|
||||
P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
|
||||
P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
ctx->state[5] += F;
|
||||
ctx->state[6] += G;
|
||||
ctx->state[7] += H;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts an array of octets as the next portion of the message.
|
||||
*/
|
||||
void SHA256_Update(SHA256_CTX *ctx, const uint8_t * msg, int len)
|
||||
{
|
||||
uint32_t left = ctx->total[0] & 0x3F;
|
||||
uint32_t fill = 64 - left;
|
||||
|
||||
ctx->total[0] += len;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if (ctx->total[0] < len)
|
||||
ctx->total[1]++;
|
||||
|
||||
if (left && len >= fill)
|
||||
{
|
||||
memcpy((void *) (ctx->buffer + left), (void *)msg, fill);
|
||||
SHA256_Process(ctx->buffer, ctx);
|
||||
len -= fill;
|
||||
msg += fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (len >= 64)
|
||||
{
|
||||
SHA256_Process(msg, ctx);
|
||||
len -= 64;
|
||||
msg += 64;
|
||||
}
|
||||
|
||||
if (len)
|
||||
{
|
||||
memcpy((void *) (ctx->buffer + left), (void *) msg, len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 256-bit message digest into the user's array
|
||||
*/
|
||||
void SHA256_Final(uint8_t *digest, SHA256_CTX *ctx)
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
uint8_t msglen[8];
|
||||
|
||||
high = (ctx->total[0] >> 29)
|
||||
| (ctx->total[1] << 3);
|
||||
low = (ctx->total[0] << 3);
|
||||
|
||||
PUT_UINT32(high, msglen, 0);
|
||||
PUT_UINT32(low, msglen, 4);
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = (last < 56) ? (56 - last) : (120 - last);
|
||||
|
||||
SHA256_Update(ctx, sha256_padding, padn);
|
||||
SHA256_Update(ctx, msglen, 8);
|
||||
|
||||
PUT_UINT32(ctx->state[0], digest, 0);
|
||||
PUT_UINT32(ctx->state[1], digest, 4);
|
||||
PUT_UINT32(ctx->state[2], digest, 8);
|
||||
PUT_UINT32(ctx->state[3], digest, 12);
|
||||
PUT_UINT32(ctx->state[4], digest, 16);
|
||||
PUT_UINT32(ctx->state[5], digest, 20);
|
||||
PUT_UINT32(ctx->state[6], digest, 24);
|
||||
PUT_UINT32(ctx->state[7], digest, 28);
|
||||
}
|
77
crypto/sha384.c
Normal file
77
crypto/sha384.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Cameron Rich
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <string.h>
|
||||
#include "os_port.h"
|
||||
#include "crypto.h"
|
||||
|
||||
/**
|
||||
* Initialize the SHA384 context
|
||||
*/
|
||||
void SHA384_Init(SHA384_CTX *ctx)
|
||||
{
|
||||
//Set initial hash value
|
||||
ctx->h_dig.h[0] = 0xCBBB9D5DC1059ED8LL;
|
||||
ctx->h_dig.h[1] = 0x629A292A367CD507LL;
|
||||
ctx->h_dig.h[2] = 0x9159015A3070DD17LL;
|
||||
ctx->h_dig.h[3] = 0x152FECD8F70E5939LL;
|
||||
ctx->h_dig.h[4] = 0x67332667FFC00B31LL;
|
||||
ctx->h_dig.h[5] = 0x8EB44A8768581511LL;
|
||||
ctx->h_dig.h[6] = 0xDB0C2E0D64F98FA7LL;
|
||||
ctx->h_dig.h[7] = 0x47B5481DBEFA4FA4LL;
|
||||
|
||||
// Number of bytes in the buffer
|
||||
ctx->size = 0;
|
||||
// Total length of the message
|
||||
ctx->totalSize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts an array of octets as the next portion of the message.
|
||||
*/
|
||||
void SHA384_Update(SHA384_CTX *ctx, const uint8_t * msg, int len)
|
||||
{
|
||||
// The function is defined in the exact same manner as SHA-512
|
||||
SHA512_Update(ctx, msg, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 384-bit message digest into the user's array
|
||||
*/
|
||||
void SHA384_Final(uint8_t *digest, SHA384_CTX *ctx)
|
||||
{
|
||||
// The function is defined in the exact same manner as SHA-512
|
||||
SHA512_Final(NULL, ctx);
|
||||
|
||||
// Copy the resulting digest
|
||||
if (digest != NULL)
|
||||
memcpy(digest, ctx->h_dig.digest, SHA384_SIZE);
|
||||
}
|
||||
|
220
crypto/sha512.c
Normal file
220
crypto/sha512.c
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Cameron Rich
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <string.h>
|
||||
#include "os_port.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#define SHR64(a, n) ((a) >> (n))
|
||||
#define ROR64(a, n) (((a) >> (n)) | ((a) << (64 - (n))))
|
||||
#define CH(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define MAJ(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||
#define SIGMA1(x) (ROR64(x, 28) ^ ROR64(x, 34) ^ ROR64(x, 39))
|
||||
#define SIGMA2(x) (ROR64(x, 14) ^ ROR64(x, 18) ^ ROR64(x, 41))
|
||||
#define SIGMA3(x) (ROR64(x, 1) ^ ROR64(x, 8) ^ SHR64(x, 7))
|
||||
#define SIGMA4(x) (ROR64(x, 19) ^ ROR64(x, 61) ^ SHR64(x, 6))
|
||||
#define MIN(x, y) ((x) < (y) ? x : y)
|
||||
|
||||
static const uint8_t padding[128] =
|
||||
{
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const uint64_t k[80] =
|
||||
{
|
||||
0x428A2F98D728AE22LL, 0x7137449123EF65CDLL, 0xB5C0FBCFEC4D3B2FLL, 0xE9B5DBA58189DBBCLL,
|
||||
0x3956C25BF348B538LL, 0x59F111F1B605D019LL, 0x923F82A4AF194F9BLL, 0xAB1C5ED5DA6D8118LL,
|
||||
0xD807AA98A3030242LL, 0x12835B0145706FBELL, 0x243185BE4EE4B28CLL, 0x550C7DC3D5FFB4E2LL,
|
||||
0x72BE5D74F27B896FLL, 0x80DEB1FE3B1696B1LL, 0x9BDC06A725C71235LL, 0xC19BF174CF692694LL,
|
||||
0xE49B69C19EF14AD2LL, 0xEFBE4786384F25E3LL, 0x0FC19DC68B8CD5B5LL, 0x240CA1CC77AC9C65LL,
|
||||
0x2DE92C6F592B0275LL, 0x4A7484AA6EA6E483LL, 0x5CB0A9DCBD41FBD4LL, 0x76F988DA831153B5LL,
|
||||
0x983E5152EE66DFABLL, 0xA831C66D2DB43210LL, 0xB00327C898FB213FLL, 0xBF597FC7BEEF0EE4LL,
|
||||
0xC6E00BF33DA88FC2LL, 0xD5A79147930AA725LL, 0x06CA6351E003826FLL, 0x142929670A0E6E70LL,
|
||||
0x27B70A8546D22FFCLL, 0x2E1B21385C26C926LL, 0x4D2C6DFC5AC42AEDLL, 0x53380D139D95B3DFLL,
|
||||
0x650A73548BAF63DELL, 0x766A0ABB3C77B2A8LL, 0x81C2C92E47EDAEE6LL, 0x92722C851482353BLL,
|
||||
0xA2BFE8A14CF10364LL, 0xA81A664BBC423001LL, 0xC24B8B70D0F89791LL, 0xC76C51A30654BE30LL,
|
||||
0xD192E819D6EF5218LL, 0xD69906245565A910LL, 0xF40E35855771202ALL, 0x106AA07032BBD1B8LL,
|
||||
0x19A4C116B8D2D0C8LL, 0x1E376C085141AB53LL, 0x2748774CDF8EEB99LL, 0x34B0BCB5E19B48A8LL,
|
||||
0x391C0CB3C5C95A63LL, 0x4ED8AA4AE3418ACBLL, 0x5B9CCA4F7763E373LL, 0x682E6FF3D6B2B8A3LL,
|
||||
0x748F82EE5DEFB2FCLL, 0x78A5636F43172F60LL, 0x84C87814A1F0AB72LL, 0x8CC702081A6439ECLL,
|
||||
0x90BEFFFA23631E28LL, 0xA4506CEBDE82BDE9LL, 0xBEF9A3F7B2C67915LL, 0xC67178F2E372532BLL,
|
||||
0xCA273ECEEA26619CLL, 0xD186B8C721C0C207LL, 0xEADA7DD6CDE0EB1ELL, 0xF57D4F7FEE6ED178LL,
|
||||
0x06F067AA72176FBALL, 0x0A637DC5A2C898A6LL, 0x113F9804BEF90DAELL, 0x1B710B35131C471BLL,
|
||||
0x28DB77F523047D84LL, 0x32CAAB7B40C72493LL, 0x3C9EBE0A15C9BEBCLL, 0x431D67C49C100D4CLL,
|
||||
0x4CC5D4BECB3E42B6LL, 0x597F299CFC657E2ALL, 0x5FCB6FAB3AD6FAECLL, 0x6C44198C4A475817LL
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the SHA512 context
|
||||
*/
|
||||
void SHA512_Init(SHA512_CTX *ctx)
|
||||
{
|
||||
ctx->h_dig.h[0] = 0x6A09E667F3BCC908LL;
|
||||
ctx->h_dig.h[1] = 0xBB67AE8584CAA73BLL;
|
||||
ctx->h_dig.h[2] = 0x3C6EF372FE94F82BLL;
|
||||
ctx->h_dig.h[3] = 0xA54FF53A5F1D36F1LL;
|
||||
ctx->h_dig.h[4] = 0x510E527FADE682D1LL;
|
||||
ctx->h_dig.h[5] = 0x9B05688C2B3E6C1FLL;
|
||||
ctx->h_dig.h[6] = 0x1F83D9ABFB41BD6BLL;
|
||||
ctx->h_dig.h[7] = 0x5BE0CD19137E2179LL;
|
||||
ctx->size = 0;
|
||||
ctx->totalSize = 0;
|
||||
}
|
||||
|
||||
static void SHA512_Process(SHA512_CTX *ctx)
|
||||
{
|
||||
int t;
|
||||
uint64_t temp1;
|
||||
uint64_t temp2;
|
||||
|
||||
// Initialize the 8 working registers
|
||||
uint64_t a = ctx->h_dig.h[0];
|
||||
uint64_t b = ctx->h_dig.h[1];
|
||||
uint64_t c = ctx->h_dig.h[2];
|
||||
uint64_t d = ctx->h_dig.h[3];
|
||||
uint64_t e = ctx->h_dig.h[4];
|
||||
uint64_t f = ctx->h_dig.h[5];
|
||||
uint64_t g = ctx->h_dig.h[6];
|
||||
uint64_t h = ctx->h_dig.h[7];
|
||||
|
||||
// Process message in 16-word blocks
|
||||
uint64_t *w = ctx->w_buf.w;
|
||||
|
||||
// Convert from big-endian byte order to host byte order
|
||||
for (t = 0; t < 16; t++)
|
||||
w[t] = be64toh(w[t]);
|
||||
|
||||
// Prepare the message schedule
|
||||
for (t = 16; t < 80; t++)
|
||||
w[t] = SIGMA4(w[t - 2]) + w[t - 7] + SIGMA3(w[t - 15]) + w[t - 16];
|
||||
|
||||
// SHA-512 hash computation
|
||||
for (t = 0; t < 80; t++)
|
||||
{
|
||||
// Calculate T1 and T2
|
||||
temp1 = h + SIGMA2(e) + CH(e, f, g) + k[t] + w[t];
|
||||
temp2 = SIGMA1(a) + MAJ(a, b, c);
|
||||
|
||||
// Update the working registers
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + temp1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = temp1 + temp2;
|
||||
}
|
||||
|
||||
// Update the hash value
|
||||
ctx->h_dig.h[0] += a;
|
||||
ctx->h_dig.h[1] += b;
|
||||
ctx->h_dig.h[2] += c;
|
||||
ctx->h_dig.h[3] += d;
|
||||
ctx->h_dig.h[4] += e;
|
||||
ctx->h_dig.h[5] += f;
|
||||
ctx->h_dig.h[6] += g;
|
||||
ctx->h_dig.h[7] += h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts an array of octets as the next portion of the message.
|
||||
*/
|
||||
void SHA512_Update(SHA512_CTX *ctx, const uint8_t * msg, int len)
|
||||
{
|
||||
// Process the incoming data
|
||||
while (len > 0)
|
||||
{
|
||||
// The buffer can hold at most 128 bytes
|
||||
size_t n = MIN(len, 128 - ctx->size);
|
||||
|
||||
// Copy the data to the buffer
|
||||
memcpy(ctx->w_buf.buffer + ctx->size, msg, n);
|
||||
|
||||
// Update the SHA-512 ctx
|
||||
ctx->size += n;
|
||||
ctx->totalSize += n;
|
||||
// Advance the data pointer
|
||||
msg = (uint8_t *) msg + n;
|
||||
// Remaining bytes to process
|
||||
len -= n;
|
||||
|
||||
// Process message in 16-word blocks
|
||||
if (ctx->size == 128)
|
||||
{
|
||||
// Transform the 16-word block
|
||||
SHA512_Process(ctx);
|
||||
// Empty the buffer
|
||||
ctx->size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 512-bit message digest into the user's array
|
||||
*/
|
||||
void SHA512_Final(uint8_t *digest, SHA512_CTX *ctx)
|
||||
{
|
||||
int i;
|
||||
size_t paddingSize;
|
||||
uint64_t totalSize;
|
||||
|
||||
// Length of the original message (before padding)
|
||||
totalSize = ctx->totalSize * 8;
|
||||
|
||||
// Pad the message so that its length is congruent to 112 modulo 128
|
||||
paddingSize = (ctx->size < 112) ? (112 - ctx->size) :
|
||||
(128 + 112 - ctx->size);
|
||||
// Append padding
|
||||
SHA512_Update(ctx, padding, paddingSize);
|
||||
|
||||
// Append the length of the original message
|
||||
ctx->w_buf.w[14] = 0;
|
||||
ctx->w_buf.w[15] = be64toh(totalSize);
|
||||
|
||||
// Calculate the message digest
|
||||
SHA512_Process(ctx);
|
||||
|
||||
// Convert from host byte order to big-endian byte order
|
||||
for (i = 0; i < 8; i++)
|
||||
ctx->h_dig.h[i] = be64toh(ctx->h_dig.h[i]);
|
||||
|
||||
// Copy the resulting digest
|
||||
if (digest != NULL)
|
||||
memcpy(digest, ctx->h_dig.digest, SHA512_SIZE);
|
||||
}
|
||||
|
Reference in New Issue
Block a user