Update externals with latest versions.
This commit is contained in:
5978
src/argtable3.c
5978
src/argtable3.c
File diff suppressed because it is too large
Load Diff
2585
src/argtable3.h
2585
src/argtable3.h
File diff suppressed because it is too large
Load Diff
@@ -35,8 +35,25 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef ARG_ENABLE_TRACE
|
||||||
#define ARG_ENABLE_TRACE 0
|
#define ARG_ENABLE_TRACE 0
|
||||||
|
#endif /* ARG_ENABLE_TRACE */
|
||||||
|
|
||||||
|
#ifndef ARG_ENABLE_LOG
|
||||||
#define ARG_ENABLE_LOG 1
|
#define ARG_ENABLE_LOG 1
|
||||||
|
#endif /* ARG_ENABLE_LOG */
|
||||||
|
|
||||||
|
/* Use the embedded getopt as the system getopt(3) */
|
||||||
|
#ifndef ARG_REPLACE_GETOPT
|
||||||
|
#define ARG_REPLACE_GETOPT 1
|
||||||
|
#endif /* ARG_REPLACE_GETOPT */
|
||||||
|
|
||||||
|
/* Size of the buffer pre-allocated for dynamic strings.
|
||||||
|
* If the length exceeds this size, the buffer will be dynamically allocated.
|
||||||
|
*/
|
||||||
|
#ifndef ARG_DSTR_SIZE
|
||||||
|
#define ARG_DSTR_SIZE 200
|
||||||
|
#endif /* ARG_DSTR_SIZE */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -81,10 +98,10 @@ typedef void(arg_panicfn)(const char* fmt, ...);
|
|||||||
* They can be a problem for the platforms like NuttX, where
|
* They can be a problem for the platforms like NuttX, where
|
||||||
* the namespace is flat for everything including apps and libraries.
|
* the namespace is flat for everything including apps and libraries.
|
||||||
*/
|
*/
|
||||||
#define xmalloc argtable3_xmalloc
|
#define xmalloc malloc
|
||||||
#define xcalloc argtable3_xcalloc
|
#define xcalloc calloc
|
||||||
#define xrealloc argtable3_xrealloc
|
#define xrealloc realloc
|
||||||
#define xfree argtable3_xfree
|
#define xfree free
|
||||||
|
|
||||||
extern void dbg_printf(const char* fmt, ...);
|
extern void dbg_printf(const char* fmt, ...);
|
||||||
extern void arg_set_panic(arg_panicfn* proc);
|
extern void arg_set_panic(arg_panicfn* proc);
|
||||||
|
|||||||
@@ -17,22 +17,17 @@
|
|||||||
* DAMAGE.
|
* DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "chacha20_drng.h"
|
#include "chacha20_drng.h"
|
||||||
#include "randombytes.h"
|
|
||||||
|
|
||||||
#define MAJVERSION 1 /* API / ABI incompatible changes,
|
#define MAJVERSION 1 /* API / ABI incompatible changes,
|
||||||
* functional changes that require consumer
|
* functional changes that require consumer
|
||||||
@@ -58,9 +53,7 @@
|
|||||||
|
|
||||||
/*********************************** Helper ***********************************/
|
/*********************************** Helper ***********************************/
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
#define min(x, y) ((x < y) ? x : y)
|
#define min(x, y) ((x < y) ? x : y)
|
||||||
#endif
|
|
||||||
#define __aligned(x) __attribute__((aligned(x)))
|
#define __aligned(x) __attribute__((aligned(x)))
|
||||||
|
|
||||||
static inline void memset_secure(void *s, int c, uint32_t n)
|
static inline void memset_secure(void *s, int c, uint32_t n)
|
||||||
@@ -71,23 +64,14 @@ static inline void memset_secure(void *s, int c, uint32_t n)
|
|||||||
|
|
||||||
static inline void get_time(time_t *sec, uint32_t *nsec)
|
static inline void get_time(time_t *sec, uint32_t *nsec)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
SYSTEMTIME SystemTime;
|
|
||||||
GetSystemTime(&SystemTime);
|
|
||||||
if(sec)
|
|
||||||
*sec = SystemTime.wSecond;
|
|
||||||
if(nsec)
|
|
||||||
*nsec = SystemTime.wMilliseconds;
|
|
||||||
#else
|
|
||||||
struct timespec time;
|
struct timespec time;
|
||||||
|
|
||||||
if (clock_gettime(CLOCK_REALTIME, &time) == 0) {
|
if (clock_gettime(CLOCK_REALTIME, &time) == 0) {
|
||||||
if (sec)
|
if (sec)
|
||||||
*sec = time.tv_sec;
|
*sec = time.tv_sec;
|
||||||
if (nsec)
|
if (nsec)
|
||||||
*nsec = time.tv_nsec;
|
*nsec = time.tv_nsec;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t rol32(uint32_t x, int n)
|
static inline uint32_t rol32(uint32_t x, int n)
|
||||||
@@ -95,25 +79,36 @@ static inline uint32_t rol32(uint32_t x, int n)
|
|||||||
return ( (x << (n&(32-1))) | (x >> ((32-n)&(32-1))) );
|
return ( (x << (n&(32-1))) | (x >> ((32-n)&(32-1))) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Endian dependent byte swap operations. */
|
/* Endian dependent byte swap operations. */
|
||||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||||
/* Byte swap for 32-bit and 64-bit integers. */
|
# define le_bswap32(x) _bswap32(x)
|
||||||
static inline uint32_t ror32(uint32_t x, int n)
|
static inline uint32_t ror32(uint32_t x, int n)
|
||||||
{
|
{
|
||||||
return ( (x >> (n&(32-1))) | (x << ((32-n)&(32-1))) );
|
return ( (x >> (n&(32-1))) | (x << ((32-n)&(32-1))) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Byte swap for 32-bit and 64-bit integers. */
|
||||||
static inline uint32_t _bswap32(uint32_t x)
|
static inline uint32_t _bswap32(uint32_t x)
|
||||||
{
|
{
|
||||||
return ((rol32(x, 8) & 0x00ff00ffL) | (ror32(x, 8) & 0xff00ff00L));
|
return ((rol32(x, 8) & 0x00ff00ffL) | (ror32(x, 8) & 0xff00ff00L));
|
||||||
}
|
}
|
||||||
# define le_bswap32(x) _bswap32(x)
|
|
||||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
# define le_bswap32(x) ((uint32_t)(x))
|
# define le_bswap32(x) ((uint32_t)(x))
|
||||||
#else
|
#else
|
||||||
#error "Endianess not defined"
|
#error "Endianess not defined"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline void drng_chacha20_bswap32(uint32_t *ptr, uint32_t words)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
/* Byte-swap data which is an LE representation */
|
||||||
|
for (i = 0; i < words; i++) {
|
||||||
|
*ptr = le_bswap32(*ptr);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/******************************* ChaCha20 Block *******************************/
|
/******************************* ChaCha20 Block *******************************/
|
||||||
|
|
||||||
#define CHACHA20_KEY_SIZE 32
|
#define CHACHA20_KEY_SIZE 32
|
||||||
@@ -203,6 +198,7 @@ static inline int drng_chacha20_selftest_one(struct chacha20_state *state,
|
|||||||
uint32_t result[CHACHA20_BLOCK_SIZE_WORDS];
|
uint32_t result[CHACHA20_BLOCK_SIZE_WORDS];
|
||||||
|
|
||||||
chacha20_block(&state->constants[0], result);
|
chacha20_block(&state->constants[0], result);
|
||||||
|
|
||||||
return memcmp(expected, result, CHACHA20_BLOCK_SIZE);
|
return memcmp(expected, result, CHACHA20_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,24 +226,186 @@ static int drng_chacha20_selftest(void)
|
|||||||
expected[12] = 0xd19c12b5; expected[13] = 0xb94e16de;
|
expected[12] = 0xd19c12b5; expected[13] = 0xb94e16de;
|
||||||
expected[14] = 0xe883d0cb; expected[15] = 0x4e3c50a2;
|
expected[14] = 0xe883d0cb; expected[15] = 0x4e3c50a2;
|
||||||
|
|
||||||
|
drng_chacha20_bswap32(expected, CHACHA20_BLOCK_SIZE_WORDS);
|
||||||
|
|
||||||
return drng_chacha20_selftest_one(&chacha20, &expected[0]);
|
return drng_chacha20_selftest_one(&chacha20, &expected[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************* getrandom system call seed source *********************/
|
||||||
|
#ifdef GETRANDOM
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
static int drng_getrandom_get(uint8_t *buf, uint32_t buflen)
|
||||||
|
{
|
||||||
|
uint32_t len = 0;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
if (buflen > INT_MAX)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = syscall(__NR_getrandom, (buf + len), (buflen - len), 0);
|
||||||
|
if (0 < ret)
|
||||||
|
len += ret;
|
||||||
|
} while ((0 < ret || EINTR == errno || ERESTART == errno)
|
||||||
|
&& buflen > len);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
static int drng_getrandom_get(uint8_t *buf, uint32_t buflen)
|
||||||
|
{
|
||||||
|
(void)buf;
|
||||||
|
(void)buflen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************************** Jitter RNG seed source ***************************/
|
||||||
|
#ifdef JENT
|
||||||
|
|
||||||
|
#include "jitterentropy.h"
|
||||||
|
|
||||||
|
struct jent_noise_source {
|
||||||
|
struct rand_data *ec;
|
||||||
|
int initialized;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct jent_noise_source jent_noise_source = {
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int drng_jent_alloc()
|
||||||
|
{
|
||||||
|
int ret = jent_entropy_init();
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
jent_noise_source.initialized = -1;
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
jent_noise_source.ec = jent_entropy_collector_alloc(0, 0);
|
||||||
|
if (!jent_noise_source.ec)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drng_jent_dealloc(void)
|
||||||
|
{
|
||||||
|
if (jent_noise_source.initialized != 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
jent_entropy_collector_free(jent_noise_source.ec);
|
||||||
|
jent_noise_source.ec = NULL;
|
||||||
|
jent_noise_source.initialized = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int drng_jent_get(uint8_t *buf, uint32_t buflen)
|
||||||
|
{
|
||||||
|
if (!jent_noise_source.initialized) {
|
||||||
|
int ret = drng_jent_alloc();
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
jent_noise_source.initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jent_noise_source.initialized > 0)
|
||||||
|
return jent_read_entropy(jent_noise_source.ec,
|
||||||
|
(char *)buf, buflen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
static int drng_jent_get(uint8_t *buf, uint32_t buflen)
|
||||||
|
{
|
||||||
|
(void)buf;
|
||||||
|
(void)buflen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drng_jent_dealloc(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************************** /dev/random seed source **************************/
|
||||||
|
#ifdef DEVRANDOM
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
static int random_fd = -1;
|
||||||
|
|
||||||
|
static int drng_random_alloc(void)
|
||||||
|
{
|
||||||
|
random_fd = open("/dev/random", O_RDONLY|O_CLOEXEC);
|
||||||
|
if (0 > random_fd)
|
||||||
|
return -EBADFD;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int drng_random_get(uint8_t *buf, uint32_t buflen)
|
static int drng_random_get(uint8_t *buf, uint32_t buflen)
|
||||||
{
|
{
|
||||||
int ret = randombytes(buf, buflen);
|
uint32_t len = 0;
|
||||||
if( ret != 0) {
|
ssize_t ret;
|
||||||
|
|
||||||
|
if (random_fd == -1) {
|
||||||
|
int ret = drng_random_alloc();
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buflen > INT_MAX)
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
|
||||||
return buflen;
|
do {
|
||||||
|
ret = read(random_fd, (buf + len), (buflen - len));
|
||||||
|
if (0 < ret)
|
||||||
|
len += ret;
|
||||||
|
} while ((0 < ret || EINTR == errno || ERESTART == errno)
|
||||||
|
&& buflen > len);
|
||||||
|
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drng_random_dealloc(void)
|
||||||
|
{
|
||||||
|
if (random_fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
close(random_fd);
|
||||||
|
random_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
static int drng_random_get(uint8_t *buf, uint32_t buflen)
|
||||||
|
{
|
||||||
|
(void)buf;
|
||||||
|
(void)buflen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drng_random_dealloc(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/******************************* ChaCha20 DRNG *******************************/
|
/******************************* ChaCha20 DRNG *******************************/
|
||||||
|
|
||||||
struct chacha20_drng {
|
struct chacha20_drng {
|
||||||
@@ -267,22 +425,23 @@ static inline void drng_chacha20_update(struct chacha20_state *chacha20,
|
|||||||
{
|
{
|
||||||
uint32_t i, tmp[CHACHA20_BLOCK_SIZE_WORDS];
|
uint32_t i, tmp[CHACHA20_BLOCK_SIZE_WORDS];
|
||||||
|
|
||||||
if (used_words > CHACHA20_KEY_SIZE_WORDS) {
|
if (CHACHA20_BLOCK_SIZE_WORDS - used_words < CHACHA20_KEY_SIZE_WORDS) {
|
||||||
chacha20_block(&chacha20->constants[0], tmp);
|
chacha20_block(&chacha20->constants[0], tmp);
|
||||||
for (i = 0; i < CHACHA20_KEY_SIZE_WORDS; i++)
|
for (i = 0; i < CHACHA20_KEY_SIZE_WORDS; i++)
|
||||||
chacha20->key.u[i] ^= tmp[i];
|
chacha20->key.u[i] ^= le_bswap32(tmp[i]);
|
||||||
memset_secure(tmp, 0, sizeof(tmp));
|
memset_secure(tmp, 0, sizeof(tmp));
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < CHACHA20_KEY_SIZE_WORDS; i++)
|
for (i = 0; i < CHACHA20_KEY_SIZE_WORDS; i++)
|
||||||
chacha20->key.u[i] ^= buf[i + used_words];
|
chacha20->key.u[i] ^= le_bswap32(buf[i + used_words]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deterministic increment of nonce as required in RFC 7539 chapter 4 */
|
/* Deterministic increment of nonce as required in RFC 7539 chapter 4 */
|
||||||
chacha20->nonce[0]++;
|
chacha20->nonce[0]++;
|
||||||
if (chacha20->nonce[0] == 0)
|
if (chacha20->nonce[0] == 0){
|
||||||
chacha20->nonce[1]++;
|
chacha20->nonce[1]++;
|
||||||
if (chacha20->nonce[1] == 0)
|
if (chacha20->nonce[1] == 0)
|
||||||
chacha20->nonce[2]++;
|
chacha20->nonce[2]++;
|
||||||
|
}
|
||||||
|
|
||||||
/* Leave counter untouched as it is start value is undefined in RFC */
|
/* Leave counter untouched as it is start value is undefined in RFC */
|
||||||
}
|
}
|
||||||
@@ -338,7 +497,7 @@ static int drng_chacha20_generate(struct chacha20_state *chacha20,
|
|||||||
int zeroize_buf = 0;
|
int zeroize_buf = 0;
|
||||||
|
|
||||||
while (outbuflen >= CHACHA20_BLOCK_SIZE) {
|
while (outbuflen >= CHACHA20_BLOCK_SIZE) {
|
||||||
if ((uintptr_t)outbuf & (sizeof(aligned_buf[0]) - 1)) {
|
if ((unsigned long)outbuf & (sizeof(aligned_buf[0]) - 1)) {
|
||||||
chacha20_block(&chacha20->constants[0], aligned_buf);
|
chacha20_block(&chacha20->constants[0], aligned_buf);
|
||||||
memcpy(outbuf, aligned_buf, CHACHA20_BLOCK_SIZE);
|
memcpy(outbuf, aligned_buf, CHACHA20_BLOCK_SIZE);
|
||||||
zeroize_buf = 1;
|
zeroize_buf = 1;
|
||||||
@@ -388,7 +547,7 @@ static int drng_chacha20_rng_selftest(struct chacha20_drng *drng)
|
|||||||
* * remaining state is 0
|
* * remaining state is 0
|
||||||
* and pulling one ChaCha20 DRNG block.
|
* and pulling one ChaCha20 DRNG block.
|
||||||
*/
|
*/
|
||||||
uint8_t expected_block[CHACHA20_KEY_SIZE] = {
|
static const uint8_t expected_block[CHACHA20_KEY_SIZE] = {
|
||||||
0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
|
0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
|
||||||
0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
|
0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
|
||||||
0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
|
0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
|
||||||
@@ -409,15 +568,15 @@ static int drng_chacha20_rng_selftest(struct chacha20_drng *drng)
|
|||||||
* 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
|
* 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
|
||||||
* and pulling two ChaCha20 DRNG blocks.
|
* and pulling two ChaCha20 DRNG blocks.
|
||||||
*/
|
*/
|
||||||
uint8_t expected_twoblocks[CHACHA20_KEY_SIZE * 2] = {
|
static const uint8_t expected_twoblocks[CHACHA20_KEY_SIZE * 2] = {
|
||||||
0xf5, 0xb4, 0xb6, 0x5a, 0xec, 0xcd, 0x5a, 0x65,
|
0xe3, 0xb0, 0x8a, 0xcc, 0x34, 0xc3, 0x17, 0x0e,
|
||||||
0x87, 0x56, 0xe3, 0x86, 0x51, 0x54, 0xfc, 0x90,
|
0xc3, 0xd8, 0xc3, 0x40, 0xe7, 0x73, 0xe9, 0x0d,
|
||||||
0x56, 0xff, 0x5e, 0xae, 0x58, 0xf2, 0x01, 0x88,
|
0xd1, 0x62, 0xa3, 0x5d, 0x7d, 0xf2, 0xf1, 0x4a,
|
||||||
0xb1, 0x7e, 0xb8, 0x2e, 0x17, 0x9a, 0x27, 0xe6,
|
0x24, 0x42, 0xb7, 0x1e, 0xb0, 0x05, 0x17, 0x07,
|
||||||
0x86, 0xb3, 0xed, 0x33, 0xf7, 0xb9, 0x06, 0x05,
|
0xb9, 0x35, 0x10, 0x69, 0x8b, 0x46, 0xfb, 0x51,
|
||||||
0x8a, 0x2d, 0x1a, 0x93, 0xc9, 0x0b, 0x80, 0x04,
|
0xe9, 0x91, 0x3f, 0x46, 0xf2, 0x4d, 0xea, 0xd0,
|
||||||
0x03, 0xaa, 0x60, 0xaf, 0xd5, 0x36, 0x40, 0x11,
|
0x81, 0xc1, 0x1b, 0xa9, 0x5d, 0x52, 0x91, 0x5f,
|
||||||
0x67, 0x89, 0xb1, 0x66, 0xd5, 0x88, 0x62, 0x6d };
|
0xcd, 0xdc, 0xc6, 0xd6, 0xc3, 0x7c, 0x50, 0x23 };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expected result when ChaCha20 DRNG state is zero:
|
* Expected result when ChaCha20 DRNG state is zero:
|
||||||
@@ -429,18 +588,22 @@ static int drng_chacha20_rng_selftest(struct chacha20_drng *drng)
|
|||||||
* 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
* 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||||
* 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
* 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||||
* 0x20
|
* 0x20
|
||||||
* and pulling one ChaCha20 DRNG block plus one byte.
|
* and pulling one ChaCha20 DRNG block plus four byte.
|
||||||
*/
|
*/
|
||||||
uint8_t expected_block_and_byte[CHACHA20_KEY_SIZE + 1] = {
|
static const uint8_t expected_block_nonaligned[CHACHA20_KEY_SIZE + 4] = {
|
||||||
0x3d, 0x13, 0x47, 0x1e, 0x7f, 0x7c, 0x99, 0x33,
|
0x9c, 0xfc, 0x5e, 0x31, 0x21, 0x62, 0x11, 0x85,
|
||||||
0xfc, 0x44, 0xa4, 0xdd, 0xf9, 0x3d, 0xe1, 0x9a,
|
0xd3, 0x77, 0xd3, 0x69, 0x0f, 0xa8, 0x16, 0x55,
|
||||||
0xd4, 0xe8, 0x7a, 0x7d, 0x42, 0xac, 0xd1, 0xcd,
|
0xb4, 0x4c, 0xf6, 0x52, 0xf3, 0xa8, 0x37, 0x99,
|
||||||
0x10, 0x69, 0xe7, 0xbf, 0xd4, 0xfd, 0x69, 0x4b,
|
0x38, 0x76, 0xa0, 0x66, 0xec, 0xbb, 0xce, 0xa9,
|
||||||
0xa7 };
|
0x9c, 0x95, 0xa1, 0xfd };
|
||||||
|
|
||||||
|
drng_chacha20_bswap32((uint32_t *)seed,
|
||||||
|
sizeof(seed) / sizeof(uint32_t));
|
||||||
|
|
||||||
/* Generate with zero state */
|
/* Generate with zero state */
|
||||||
ret = drng_chacha20_generate(&drng->chacha20, outbuf,
|
ret = drng_chacha20_generate(&drng->chacha20, outbuf,
|
||||||
sizeof(expected_block));
|
sizeof(expected_block));
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (memcmp(outbuf, expected_block, sizeof(expected_block)))
|
if (memcmp(outbuf, expected_block, sizeof(expected_block)))
|
||||||
@@ -454,6 +617,7 @@ static int drng_chacha20_rng_selftest(struct chacha20_drng *drng)
|
|||||||
sizeof(expected_twoblocks));
|
sizeof(expected_twoblocks));
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = drng_chacha20_generate(&drng->chacha20, outbuf,
|
ret = drng_chacha20_generate(&drng->chacha20, outbuf,
|
||||||
sizeof(expected_twoblocks));
|
sizeof(expected_twoblocks));
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -466,15 +630,15 @@ static int drng_chacha20_rng_selftest(struct chacha20_drng *drng)
|
|||||||
|
|
||||||
/* Reseed with 1 block and one byte */
|
/* Reseed with 1 block and one byte */
|
||||||
ret = drng_chacha20_seed(&drng->chacha20, seed,
|
ret = drng_chacha20_seed(&drng->chacha20, seed,
|
||||||
sizeof(expected_block_and_byte));
|
sizeof(expected_block_nonaligned));
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = drng_chacha20_generate(&drng->chacha20, outbuf,
|
ret = drng_chacha20_generate(&drng->chacha20, outbuf,
|
||||||
sizeof(expected_block_and_byte));
|
sizeof(expected_block_nonaligned));
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (memcmp(outbuf, expected_block_and_byte,
|
if (memcmp(outbuf, expected_block_nonaligned,
|
||||||
sizeof(expected_block_and_byte)))
|
sizeof(expected_block_nonaligned)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -499,31 +663,26 @@ static int drng_chacha20_alloc(struct chacha20_drng **out)
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
ret = posix_memalign((void *)&drng, CHACHA20_DRNG_ALIGNMENT,
|
||||||
drng = _aligned_malloc(sizeof(*drng), CHACHA20_DRNG_ALIGNMENT);
|
sizeof(*drng));
|
||||||
#endif
|
if (ret) {
|
||||||
|
return -ret;
|
||||||
#ifndef aligned_alloc
|
|
||||||
drng = malloc(sizeof(*drng));
|
|
||||||
#else
|
|
||||||
drng = aligned_alloc(CHACHA20_DRNG_ALIGNMENT, sizeof(*drng));
|
|
||||||
#endif
|
|
||||||
if (drng == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
/* prevent paging out of the memory state to swap space */
|
/* prevent paging out of the memory state to swap space */
|
||||||
ret = mlock(drng, sizeof(*drng));
|
ret = mlock(drng, sizeof(*drng));
|
||||||
if (ret && errno != EPERM && errno != EAGAIN) {
|
if (ret && errno != EPERM && errno != EAGAIN) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
memset(drng, 0, sizeof(*drng));
|
memset(drng, 0, sizeof(*drng));
|
||||||
|
|
||||||
memcpy(&drng->chacha20.constants[0], "expand 32-byte k", 16);
|
/* String "expand 32-byte k" */
|
||||||
|
drng->chacha20.constants[0] = 0x61707865;
|
||||||
|
drng->chacha20.constants[1] = 0x3320646e;
|
||||||
|
drng->chacha20.constants[2] = 0x79622d32;
|
||||||
|
drng->chacha20.constants[3] = 0x6b206574;
|
||||||
|
|
||||||
ret = drng_chacha20_rng_selftest(drng);
|
ret = drng_chacha20_rng_selftest(drng);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -559,6 +718,33 @@ int drng_chacha20_reseed(struct chacha20_drng *drng, const uint8_t *inbuf,
|
|||||||
int ret;
|
int ret;
|
||||||
uint32_t collected = 0;
|
uint32_t collected = 0;
|
||||||
|
|
||||||
|
/* Entropy assumption: 1 data bit delivers one bit of entropy */
|
||||||
|
ret = drng_getrandom_get(seed, CHACHA20_KEY_SIZE);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
collected = ret;
|
||||||
|
|
||||||
|
ret = drng_chacha20_seed(&drng->chacha20, seed,
|
||||||
|
CHACHA20_KEY_SIZE);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Entropy assumption: 2 data bits deliver one bit of entropy */
|
||||||
|
ret = drng_jent_get(seed, sizeof(seed));
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
collected += ret;
|
||||||
|
|
||||||
|
ret = drng_chacha20_seed(&drng->chacha20, seed, sizeof(seed));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Entropy assumption: 1 data bit delivers one bit of entropy */
|
/* Entropy assumption: 1 data bit delivers one bit of entropy */
|
||||||
ret = drng_random_get(seed, CHACHA20_KEY_SIZE);
|
ret = drng_random_get(seed, CHACHA20_KEY_SIZE);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -591,6 +777,8 @@ int drng_chacha20_reseed(struct chacha20_drng *drng, const uint8_t *inbuf,
|
|||||||
DSO_PUBLIC
|
DSO_PUBLIC
|
||||||
void drng_chacha20_destroy(struct chacha20_drng *drng)
|
void drng_chacha20_destroy(struct chacha20_drng *drng)
|
||||||
{
|
{
|
||||||
|
drng_jent_dealloc();
|
||||||
|
drng_random_dealloc();
|
||||||
drng_chacha20_dealloc(drng);
|
drng_chacha20_dealloc(drng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1134,4 +1134,3 @@ exit:
|
|||||||
return message;
|
return message;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
133
src/sha3.c
133
src/sha3.c
@@ -23,22 +23,15 @@
|
|||||||
#include "sha3.h"
|
#include "sha3.h"
|
||||||
|
|
||||||
#define SHA3_ASSERT( x )
|
#define SHA3_ASSERT( x )
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#define SHA3_TRACE( format, ...)
|
#define SHA3_TRACE( format, ...)
|
||||||
#define SHA3_TRACE_BUF( format, buf, l, ...)
|
#define SHA3_TRACE_BUF(format, buf, l)
|
||||||
#else
|
|
||||||
#define SHA3_TRACE(format, args...)
|
|
||||||
#define SHA3_TRACE_BUF(format, buf, l, args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//#define SHA3_USE_KECCAK
|
|
||||||
/*
|
/*
|
||||||
* Define SHA3_USE_KECCAK to run "pure" Keccak, as opposed to SHA3.
|
* This flag is used to configure "pure" Keccak, as opposed to NIST SHA3.
|
||||||
* The tests that this macro enables use the input and output from [Keccak]
|
|
||||||
* (see the reference below). The used test vectors aren't correct for SHA3,
|
|
||||||
* however, they are helpful to verify the implementation.
|
|
||||||
* SHA3_USE_KECCAK only changes one line of code in Finalize.
|
|
||||||
*/
|
*/
|
||||||
|
#define SHA3_USE_KECCAK_FLAG 0x80000000
|
||||||
|
#define SHA3_CW(x) ((x) & (~SHA3_USE_KECCAK_FLAG))
|
||||||
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#define SHA3_CONST(x) x
|
#define SHA3_CONST(x) x
|
||||||
@@ -123,30 +116,44 @@ keccakf(uint64_t s[25])
|
|||||||
/* *************************** Public Inteface ************************ */
|
/* *************************** Public Inteface ************************ */
|
||||||
|
|
||||||
/* For Init or Reset call these: */
|
/* For Init or Reset call these: */
|
||||||
|
sha3_return_t
|
||||||
|
sha3_Init(void *priv, unsigned bitSize) {
|
||||||
|
sha3_context *ctx = (sha3_context *) priv;
|
||||||
|
if( bitSize != 256 && bitSize != 384 && bitSize != 512 )
|
||||||
|
return SHA3_RETURN_BAD_PARAMS;
|
||||||
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
|
ctx->capacityWords = 2 * bitSize / (8 * sizeof(uint64_t));
|
||||||
|
return SHA3_RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sha3_Init256(void *priv)
|
sha3_Init256(void *priv)
|
||||||
{
|
{
|
||||||
sha3_context *ctx = (sha3_context *) priv;
|
sha3_Init(priv, 256);
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
|
||||||
ctx->capacityWords = 2 * 256 / (8 * sizeof(uint64_t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sha3_Init384(void *priv)
|
sha3_Init384(void *priv)
|
||||||
{
|
{
|
||||||
sha3_context *ctx = (sha3_context *) priv;
|
sha3_Init(priv, 384);
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
|
||||||
ctx->capacityWords = 2 * 384 / (8 * sizeof(uint64_t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sha3_Init512(void *priv)
|
sha3_Init512(void *priv)
|
||||||
{
|
{
|
||||||
sha3_context *ctx = (sha3_context *) priv;
|
sha3_Init(priv, 512);
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
|
||||||
ctx->capacityWords = 2 * 512 / (8 * sizeof(uint64_t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SHA3_FLAGS
|
||||||
|
sha3_SetFlags(void *priv, enum SHA3_FLAGS flags)
|
||||||
|
{
|
||||||
|
sha3_context *ctx = (sha3_context *) priv;
|
||||||
|
flags &= SHA3_FLAGS_KECCAK;
|
||||||
|
ctx->capacityWords |= (flags == SHA3_FLAGS_KECCAK ? SHA3_USE_KECCAK_FLAG : 0);
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sha3_Update(void *priv, void const *bufIn, size_t len)
|
sha3_Update(void *priv, void const *bufIn, size_t len)
|
||||||
{
|
{
|
||||||
@@ -164,7 +171,7 @@ sha3_Update(void *priv, void const *bufIn, size_t len)
|
|||||||
SHA3_TRACE_BUF("called to update with:", buf, len);
|
SHA3_TRACE_BUF("called to update with:", buf, len);
|
||||||
|
|
||||||
SHA3_ASSERT(ctx->byteIndex < 8);
|
SHA3_ASSERT(ctx->byteIndex < 8);
|
||||||
SHA3_ASSERT(ctx->wordIndex < sizeof(ctx->s) / sizeof(ctx->s[0]));
|
SHA3_ASSERT(ctx->wordIndex < sizeof(ctx->u.s) / sizeof(ctx->u.s[0]));
|
||||||
|
|
||||||
if(len < old_tail) { /* have no complete word or haven't started
|
if(len < old_tail) { /* have no complete word or haven't started
|
||||||
* the word yet */
|
* the word yet */
|
||||||
@@ -185,13 +192,13 @@ sha3_Update(void *priv, void const *bufIn, size_t len)
|
|||||||
ctx->saved |= (uint64_t) (*(buf++)) << ((ctx->byteIndex++) * 8);
|
ctx->saved |= (uint64_t) (*(buf++)) << ((ctx->byteIndex++) * 8);
|
||||||
|
|
||||||
/* now ready to add saved to the sponge */
|
/* now ready to add saved to the sponge */
|
||||||
ctx->s[ctx->wordIndex] ^= ctx->saved;
|
ctx->u.s[ctx->wordIndex] ^= ctx->saved;
|
||||||
SHA3_ASSERT(ctx->byteIndex == 8);
|
SHA3_ASSERT(ctx->byteIndex == 8);
|
||||||
ctx->byteIndex = 0;
|
ctx->byteIndex = 0;
|
||||||
ctx->saved = 0;
|
ctx->saved = 0;
|
||||||
if(++ctx->wordIndex ==
|
if(++ctx->wordIndex ==
|
||||||
(SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords)) {
|
(SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx->capacityWords))) {
|
||||||
keccakf(ctx->s);
|
keccakf(ctx->u.s);
|
||||||
ctx->wordIndex = 0;
|
ctx->wordIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,10 +224,10 @@ sha3_Update(void *priv, void const *bufIn, size_t len)
|
|||||||
#if defined(__x86_64__ ) || defined(__i386__)
|
#if defined(__x86_64__ ) || defined(__i386__)
|
||||||
SHA3_ASSERT(memcmp(&t, buf, 8) == 0);
|
SHA3_ASSERT(memcmp(&t, buf, 8) == 0);
|
||||||
#endif
|
#endif
|
||||||
ctx->s[ctx->wordIndex] ^= t;
|
ctx->u.s[ctx->wordIndex] ^= t;
|
||||||
if(++ctx->wordIndex ==
|
if(++ctx->wordIndex ==
|
||||||
(SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords)) {
|
(SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx->capacityWords))) {
|
||||||
keccakf(ctx->s);
|
keccakf(ctx->u.s);
|
||||||
ctx->wordIndex = 0;
|
ctx->wordIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,21 +260,22 @@ sha3_Finalize(void *priv)
|
|||||||
* Overall, we feed 0, then 1, and finally 1 to start padding. Without
|
* Overall, we feed 0, then 1, and finally 1 to start padding. Without
|
||||||
* M || 01, we would simply use 1 to start padding. */
|
* M || 01, we would simply use 1 to start padding. */
|
||||||
|
|
||||||
#ifndef SHA3_USE_KECCAK
|
uint64_t t;
|
||||||
/* SHA3 version */
|
|
||||||
ctx->s[ctx->wordIndex] ^=
|
|
||||||
(ctx->saved ^ ((uint64_t) ((uint64_t) (0x02 | (1 << 2)) <<
|
|
||||||
((ctx->byteIndex) * 8))));
|
|
||||||
#else
|
|
||||||
/* For testing the "pure" Keccak version */
|
|
||||||
ctx->s[ctx->wordIndex] ^=
|
|
||||||
(ctx->saved ^ ((uint64_t) ((uint64_t) 1 << (ctx->byteIndex *
|
|
||||||
8))));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ctx->s[SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords - 1] ^=
|
if( ctx->capacityWords & SHA3_USE_KECCAK_FLAG ) {
|
||||||
|
/* Keccak version */
|
||||||
|
t = (uint64_t)(((uint64_t) 1) << (ctx->byteIndex * 8));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* SHA3 version */
|
||||||
|
t = (uint64_t)(((uint64_t)(0x02 | (1 << 2))) << ((ctx->byteIndex) * 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->u.s[ctx->wordIndex] ^= ctx->saved ^ t;
|
||||||
|
|
||||||
|
ctx->u.s[SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx->capacityWords) - 1] ^=
|
||||||
SHA3_CONST(0x8000000000000000UL);
|
SHA3_CONST(0x8000000000000000UL);
|
||||||
keccakf(ctx->s);
|
keccakf(ctx->u.s);
|
||||||
|
|
||||||
/* Return first bytes of the ctx->s. This conversion is not needed for
|
/* Return first bytes of the ctx->s. This conversion is not needed for
|
||||||
* little-endian platforms e.g. wrap with #if !defined(__BYTE_ORDER__)
|
* little-endian platforms e.g. wrap with #if !defined(__BYTE_ORDER__)
|
||||||
@@ -277,20 +285,39 @@ sha3_Finalize(void *priv)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) {
|
for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) {
|
||||||
const unsigned t1 = (uint32_t) ctx->s[i];
|
const unsigned t1 = (uint32_t) ctx->u.s[i];
|
||||||
const unsigned t2 = (uint32_t) ((ctx->s[i] >> 16) >> 16);
|
const unsigned t2 = (uint32_t) ((ctx->u.s[i] >> 16) >> 16);
|
||||||
ctx->sb[i * 8 + 0] = (uint8_t) (t1);
|
ctx->u.sb[i * 8 + 0] = (uint8_t) (t1);
|
||||||
ctx->sb[i * 8 + 1] = (uint8_t) (t1 >> 8);
|
ctx->u.sb[i * 8 + 1] = (uint8_t) (t1 >> 8);
|
||||||
ctx->sb[i * 8 + 2] = (uint8_t) (t1 >> 16);
|
ctx->u.sb[i * 8 + 2] = (uint8_t) (t1 >> 16);
|
||||||
ctx->sb[i * 8 + 3] = (uint8_t) (t1 >> 24);
|
ctx->u.sb[i * 8 + 3] = (uint8_t) (t1 >> 24);
|
||||||
ctx->sb[i * 8 + 4] = (uint8_t) (t2);
|
ctx->u.sb[i * 8 + 4] = (uint8_t) (t2);
|
||||||
ctx->sb[i * 8 + 5] = (uint8_t) (t2 >> 8);
|
ctx->u.sb[i * 8 + 5] = (uint8_t) (t2 >> 8);
|
||||||
ctx->sb[i * 8 + 6] = (uint8_t) (t2 >> 16);
|
ctx->u.sb[i * 8 + 6] = (uint8_t) (t2 >> 16);
|
||||||
ctx->sb[i * 8 + 7] = (uint8_t) (t2 >> 24);
|
ctx->u.sb[i * 8 + 7] = (uint8_t) (t2 >> 24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHA3_TRACE_BUF("Hash: (first 32 bytes)", ctx->sb, 256 / 8);
|
SHA3_TRACE_BUF("Hash: (first 32 bytes)", ctx->u.sb, 256 / 8);
|
||||||
|
|
||||||
return (ctx->sb);
|
return (ctx->u.sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
sha3_return_t sha3_HashBuffer( unsigned bitSize, enum SHA3_FLAGS flags, const void *in, unsigned inBytes, void *out, unsigned outBytes ) {
|
||||||
|
sha3_return_t err;
|
||||||
|
sha3_context c;
|
||||||
|
|
||||||
|
err = sha3_Init(&c, bitSize);
|
||||||
|
if( err != SHA3_RETURN_OK )
|
||||||
|
return err;
|
||||||
|
if( sha3_SetFlags(&c, flags) != flags ) {
|
||||||
|
return SHA3_RETURN_BAD_PARAMS;
|
||||||
|
}
|
||||||
|
sha3_Update(&c, in, inBytes);
|
||||||
|
const void *h = sha3_Finalize(&c);
|
||||||
|
|
||||||
|
if(outBytes > bitSize/8)
|
||||||
|
outBytes = bitSize/8;
|
||||||
|
memcpy(out, h, outBytes);
|
||||||
|
return SHA3_RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/sha3.h
25
src/sha3.h
@@ -1,6 +1,8 @@
|
|||||||
#ifndef SHA3_H
|
#ifndef SHA3_H
|
||||||
#define SHA3_H
|
#define SHA3_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
* Works when compiled for either 32-bit or 64-bit targets, optimized for
|
* Works when compiled for either 32-bit or 64-bit targets, optimized for
|
||||||
* 64 bit.
|
* 64 bit.
|
||||||
@@ -28,7 +30,7 @@ typedef struct sha3_context_ {
|
|||||||
union { /* Keccak's state */
|
union { /* Keccak's state */
|
||||||
uint64_t s[SHA3_KECCAK_SPONGE_WORDS];
|
uint64_t s[SHA3_KECCAK_SPONGE_WORDS];
|
||||||
uint8_t sb[SHA3_KECCAK_SPONGE_WORDS * 8];
|
uint8_t sb[SHA3_KECCAK_SPONGE_WORDS * 8];
|
||||||
};
|
} u;
|
||||||
unsigned byteIndex; /* 0..7--the next byte after the set one
|
unsigned byteIndex; /* 0..7--the next byte after the set one
|
||||||
* (starts from 0; 0--none are buffered) */
|
* (starts from 0; 0--none are buffered) */
|
||||||
unsigned wordIndex; /* 0..24--the next word to integrate input
|
unsigned wordIndex; /* 0..24--the next word to integrate input
|
||||||
@@ -37,14 +39,35 @@ typedef struct sha3_context_ {
|
|||||||
* words (e.g. 16 for Keccak 512) */
|
* words (e.g. 16 for Keccak 512) */
|
||||||
} sha3_context;
|
} sha3_context;
|
||||||
|
|
||||||
|
enum SHA3_FLAGS {
|
||||||
|
SHA3_FLAGS_NONE=0,
|
||||||
|
SHA3_FLAGS_KECCAK=1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SHA3_RETURN {
|
||||||
|
SHA3_RETURN_OK=0,
|
||||||
|
SHA3_RETURN_BAD_PARAMS=1
|
||||||
|
};
|
||||||
|
typedef enum SHA3_RETURN sha3_return_t;
|
||||||
|
|
||||||
/* For Init or Reset call these: */
|
/* For Init or Reset call these: */
|
||||||
|
sha3_return_t sha3_Init(void *priv, unsigned bitSize);
|
||||||
|
|
||||||
void sha3_Init256(void *priv);
|
void sha3_Init256(void *priv);
|
||||||
void sha3_Init384(void *priv);
|
void sha3_Init384(void *priv);
|
||||||
void sha3_Init512(void *priv);
|
void sha3_Init512(void *priv);
|
||||||
|
|
||||||
|
enum SHA3_FLAGS sha3_SetFlags(void *priv, enum SHA3_FLAGS);
|
||||||
|
|
||||||
void sha3_Update(void *priv, void const *bufIn, size_t len);
|
void sha3_Update(void *priv, void const *bufIn, size_t len);
|
||||||
|
|
||||||
void const *sha3_Finalize(void *priv);
|
void const *sha3_Finalize(void *priv);
|
||||||
|
|
||||||
|
/* Single-call hashing */
|
||||||
|
sha3_return_t sha3_HashBuffer(
|
||||||
|
unsigned bitSize, /* 256, 384, 512 */
|
||||||
|
enum SHA3_FLAGS flags, /* SHA3_FLAGS_NONE or SHA3_FLAGS_KECCAK */
|
||||||
|
const void *in, unsigned inBytes,
|
||||||
|
void *out, unsigned outBytes ); /* up to bitSize/8; truncation OK */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user