13 Commits

Author SHA1 Message Date
ben
7d16fe4519 Update of the warning. 2025-11-14 23:20:22 +01:00
ben
cb4ba1cb3e Update externals with latest versions. 2025-11-14 23:04:39 +01:00
ben
5db7304983 Cleanup and improve Makefile 2025-11-14 23:04:39 +01:00
ben
1b56f81768 Fix linking option for release 2025-11-14 23:04:39 +01:00
ben
9cb9b2058d Fix identation 2025-11-14 23:04:39 +01:00
ben
7ecdc0bb91 Remove rand compilation message 2025-11-14 23:04:39 +01:00
ben
69f43babec Fix missing linking option 2025-11-14 23:04:39 +01:00
ben
1d85325bb3 Add algo version 2025-11-14 23:04:39 +01:00
ben
63c4842bce Update Copyright 2025-09-01 20:53:55 +02:00
ben
f138622b1d Add License file 2025-09-01 20:53:39 +02:00
Ben
e4a63422f2 Update date 2022-06-13 22:08:12 +02:00
Ben
85c0cb6cc2 Update argtable3 and fix warnings 2022-06-13 22:05:19 +02:00
Ben
ede16c77ae Fix typos 2021-08-29 23:37:12 +02:00
14 changed files with 5052 additions and 4871 deletions

121
LICENSE Normal file
View File

@@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

View File

@@ -1,21 +1,12 @@
CC=gcc
CFLAGS=-Wall -Werror -pthread -O3
LDFLAGS=
CFLAGS=-Wall -Werror -pthread -O3 -g0
CFLAGS += -DGETRANDOM -DARG_REPLACE_GETOPT=0
LDFLAGS=-lm -s
default: inexact
windows: CC=x86_64-w64-mingw32-gcc
windows: CFLAGS=-Wall -Werror -pthread -O3
windows: LDFLAGS=
windows: inexact
windows-debug: CC=x86_64-w64-mingw32-gcc
windows-debug: CFLAGS=-Wall -Werror -pthread -O3 -g
windows-debug: LDFLAGS=
windows-debug: inexact
debug: CFLAGS=-Wall -Werror -pthread -O3 -g
debug: LDFLAGS=
debug: CFLAGS=-Wall -Werror -pthread -O0 -g
debug: CFLAGS += -DGETRANDOM -DARG_REPLACE_GETOPT=0
debug: LDFLAGS=-lm
debug: inexact
argtable3.o: src/argtable3.c
@@ -61,4 +52,3 @@ inexact: src/main.c argtable3.o base64.o binhex.o curve25519.o inexact.o norx_in
clean:
-rm objs/*.o
-rm -f inexact inexact.exe

View File

@@ -1,9 +1,9 @@
# INadvisable EXperimental Asymmetric Crypto Tool #
Inexact is an experimental cryptographic tools, multi-platform, scriptable
complying with the KISS principle (Keep it simple and stupid).
Inexact is an experimental cryptographic tool, multi-platform, scriptable
complying with the KISS principle (Keep It Simple and Stupid).
The main features are as follow:
The main features are as follows:
- Asymmetric encryption.
- Symmetric encryption.
@@ -13,15 +13,15 @@ The main features are as follow:
- Base64 or modified base64 encoding output compatible with a URL path, DNS entry, or file name.
** WARNING : Inexact uses recent algorithms not approved nor by NIST or NSA ! **
** WARNING : Inexact uses experimental algorithms that are not certified. **
** Don't use for anything other than experiments. **
** Don't use this to secure sensitive things. **
## Encryption principles
Inexact implements the following algorithms:
- Norx 256bits
- Norx 3.0 256bits
- Diffie-Hellman X25219
- SHA3-256
- DRNG chacha20
@@ -43,7 +43,7 @@ Rest of protocol:
- The nonce for the Norx function of the second part is a SHA3-256 hash of
parameters of the first part and rand1 buffer.
- Argon2 is used as a challenge for the password of the private key.
- The symmetric encryption is based on ian asymmetric encryption by adding argon2
- The symmetric encryption is based on the asymmetric encryption by adding argon2
challenge nonce and public key in the encrypted message.
Schematic:
@@ -62,20 +62,13 @@ Schematic:
## How to build
For GNU/Linux and Mac OS X:
For GNU/Linux and macOS, you must have GCC or Clang installed. For Windows, w64-mingw32-gcc is required.
```
cd inexact
make
```
For Microsoft Windows using cross compilation on GNU/Linux:
```
cd inexact
make windows
```
## Usage
Asymmetric encryption:
@@ -126,7 +119,7 @@ Variable encrypted message size (400 chars):
## Credits
Copyright © 2019 <ben@hackade.org>
Copyright © 2019-2025 <ben@hackade.org>
Inexact is released under CC0 licence, except for this externals libraries:
@@ -139,4 +132,3 @@ Inexact is released under CC0 licence, except for this externals libraries:
- https://nachtimwald.com/2017/09/24/hex-encode-and-decode-in-c/
- https://github.com/argtable/argtable3
- https://github.com/dsprenkels/randombytes

View File

@@ -26,6 +26,8 @@
#define CONST_CAST(x) (x)(uintptr_t)
#define rotr64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
/**********************Argon2 internal constants*******************************/
enum argon2_core_constants {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

257
src/argtable3_private.h Normal file
View File

@@ -0,0 +1,257 @@
/*******************************************************************************
* argtable3_private: Declares private types, constants, and interfaces
*
* This file is part of the argtable3 library.
*
* Copyright (C) 2013-2019 Tom G. Huang
* <tomghuang@gmail.com>
* 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 STEWART HEITMANN 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 STEWART HEITMANN 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.
******************************************************************************/
#ifndef ARG_UTILS_H
#define ARG_UTILS_H
#include <stdlib.h>
#ifndef ARG_ENABLE_TRACE
#define ARG_ENABLE_TRACE 0
#endif /* ARG_ENABLE_TRACE */
#ifndef ARG_ENABLE_LOG
#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
extern "C" {
#endif
enum { ARG_ERR_MINCOUNT = 1, ARG_ERR_MAXCOUNT, ARG_ERR_BADINT, ARG_ERR_OVERFLOW, ARG_ERR_BADDOUBLE, ARG_ERR_BADDATE, ARG_ERR_REGNOMATCH };
typedef void(arg_panicfn)(const char* fmt, ...);
#if defined(_MSC_VER)
#define ARG_TRACE(x) \
__pragma(warning(push)) __pragma(warning(disable : 4127)) do { \
if (ARG_ENABLE_TRACE) \
dbg_printf x; \
} \
while (0) \
__pragma(warning(pop))
#define ARG_LOG(x) \
__pragma(warning(push)) __pragma(warning(disable : 4127)) do { \
if (ARG_ENABLE_LOG) \
dbg_printf x; \
} \
while (0) \
__pragma(warning(pop))
#else
#define ARG_TRACE(x) \
do { \
if (ARG_ENABLE_TRACE) \
dbg_printf x; \
} while (0)
#define ARG_LOG(x) \
do { \
if (ARG_ENABLE_LOG) \
dbg_printf x; \
} while (0)
#endif
/*
* Rename a few generic names to unique names.
* They can be a problem for the platforms like NuttX, where
* the namespace is flat for everything including apps and libraries.
*/
#define xmalloc malloc
#define xcalloc calloc
#define xrealloc realloc
#define xfree free
extern void dbg_printf(const char* fmt, ...);
extern void arg_set_panic(arg_panicfn* proc);
extern void* xmalloc(size_t size);
extern void* xcalloc(size_t count, size_t size);
extern void* xrealloc(void* ptr, size_t size);
extern void xfree(void* ptr);
struct arg_hashtable_entry {
void *k, *v;
unsigned int h;
struct arg_hashtable_entry* next;
};
typedef struct arg_hashtable {
unsigned int tablelength;
struct arg_hashtable_entry** table;
unsigned int entrycount;
unsigned int loadlimit;
unsigned int primeindex;
unsigned int (*hashfn)(const void* k);
int (*eqfn)(const void* k1, const void* k2);
} arg_hashtable_t;
/**
* @brief Create a hash table.
*
* @param minsize minimum initial size of hash table
* @param hashfn function for hashing keys
* @param eqfn function for determining key equality
* @return newly created hash table or NULL on failure
*/
arg_hashtable_t* arg_hashtable_create(unsigned int minsize, unsigned int (*hashfn)(const void*), int (*eqfn)(const void*, const void*));
/**
* @brief This function will cause the table to expand if the insertion would take
* the ratio of entries to table size over the maximum load factor.
*
* This function does not check for repeated insertions with a duplicate key.
* The value returned when using a duplicate key is undefined -- when
* the hash table changes size, the order of retrieval of duplicate key
* entries is reversed.
* If in doubt, remove before insert.
*
* @param h the hash table to insert into
* @param k the key - hash table claims ownership and will free on removal
* @param v the value - does not claim ownership
* @return non-zero for successful insertion
*/
void arg_hashtable_insert(arg_hashtable_t* h, void* k, void* v);
#define ARG_DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
int fnname(arg_hashtable_t* h, keytype* k, valuetype* v) { return arg_hashtable_insert(h, k, v); }
/**
* @brief Search the specified key in the hash table.
*
* @param h the hash table to search
* @param k the key to search for - does not claim ownership
* @return the value associated with the key, or NULL if none found
*/
void* arg_hashtable_search(arg_hashtable_t* h, const void* k);
#define ARG_DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
valuetype* fnname(arg_hashtable_t* h, keytype* k) { return (valuetype*)(arg_hashtable_search(h, k)); }
/**
* @brief Remove the specified key from the hash table.
*
* @param h the hash table to remove the item from
* @param k the key to search for - does not claim ownership
*/
void arg_hashtable_remove(arg_hashtable_t* h, const void* k);
#define ARG_DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
void fnname(arg_hashtable_t* h, keytype* k) { arg_hashtable_remove(h, k); }
/**
* @brief Return the number of keys in the hash table.
*
* @param h the hash table
* @return the number of items stored in the hash table
*/
unsigned int arg_hashtable_count(arg_hashtable_t* h);
/**
* @brief Change the value associated with the key.
*
* function to change the value associated with a key, where there already
* exists a value bound to the key in the hash table.
* Source due to Holger Schemel.
*
* @name hashtable_change
* @param h the hash table
* @param key
* @param value
*/
int arg_hashtable_change(arg_hashtable_t* h, void* k, void* v);
/**
* @brief Free the hash table and the memory allocated for each key-value pair.
*
* @param h the hash table
* @param free_values whether to call 'free' on the remaining values
*/
void arg_hashtable_destroy(arg_hashtable_t* h, int free_values);
typedef struct arg_hashtable_itr {
arg_hashtable_t* h;
struct arg_hashtable_entry* e;
struct arg_hashtable_entry* parent;
unsigned int index;
} arg_hashtable_itr_t;
arg_hashtable_itr_t* arg_hashtable_itr_create(arg_hashtable_t* h);
void arg_hashtable_itr_destroy(arg_hashtable_itr_t* itr);
/**
* @brief Return the value of the (key,value) pair at the current position.
*/
extern void* arg_hashtable_itr_key(arg_hashtable_itr_t* i);
/**
* @brief Return the value of the (key,value) pair at the current position.
*/
extern void* arg_hashtable_itr_value(arg_hashtable_itr_t* i);
/**
* @brief Advance the iterator to the next element. Returns zero if advanced to end of table.
*/
int arg_hashtable_itr_advance(arg_hashtable_itr_t* itr);
/**
* @brief Remove current element and advance the iterator to the next element.
*/
int arg_hashtable_itr_remove(arg_hashtable_itr_t* itr);
/**
* @brief Search and overwrite the supplied iterator, to point to the entry matching the supplied key.
*
* @return Zero if not found.
*/
int arg_hashtable_itr_search(arg_hashtable_itr_t* itr, arg_hashtable_t* h, void* k);
#define ARG_DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
int fnname(arg_hashtable_itr_t* i, arg_hashtable_t* h, keytype* k) { return (arg_hashtable_iterator_search(i, h, k)); }
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -177,6 +177,7 @@ unsigned char * b64t_encode(const unsigned char *src, size_t len,
new_index ++;
}
}
if(new_index)
out[new_index] = 0;
*out_len = new_index;

View File

@@ -17,22 +17,17 @@
* DAMAGE.
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#endif
#include "chacha20_drng.h"
#include "randombytes.h"
#define MAJVERSION 1 /* API / ABI incompatible changes,
* functional changes that require consumer
@@ -58,9 +53,7 @@
/*********************************** Helper ***********************************/
#ifndef _WIN32
#define min(x, y) ((x < y) ? x : y)
#endif
#define __aligned(x) __attribute__((aligned(x)))
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)
{
#ifdef _WIN32
SYSTEMTIME SystemTime;
GetSystemTime(&SystemTime);
if(sec)
*sec = SystemTime.wSecond;
if(nsec)
*nsec = SystemTime.wMilliseconds;
#else
struct timespec time;
if (clock_gettime(CLOCK_REALTIME, &time) == 0) {
if (sec)
*sec = time.tv_sec;
if (nsec)
*nsec = time.tv_nsec;
}
#endif
}
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))) );
}
/* Endian dependent byte swap operations. */
#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)
{
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)
{
return ((rol32(x, 8) & 0x00ff00ffL) | (ror32(x, 8) & 0xff00ff00L));
}
# define le_bswap32(x) _bswap32(x)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define le_bswap32(x) ((uint32_t)(x))
#else
#error "Endianess not defined"
#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 *******************************/
#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];
chacha20_block(&state->constants[0], result);
return memcmp(expected, result, CHACHA20_BLOCK_SIZE);
}
@@ -230,24 +226,186 @@ static int drng_chacha20_selftest(void)
expected[12] = 0xd19c12b5; expected[13] = 0xb94e16de;
expected[14] = 0xe883d0cb; expected[15] = 0x4e3c50a2;
drng_chacha20_bswap32(expected, CHACHA20_BLOCK_SIZE_WORDS);
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/stat.h>
#include <fcntl.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)
{
int ret = randombytes(buf, buflen);
if( ret != 0) {
uint32_t len = 0;
ssize_t ret;
if (random_fd == -1) {
int ret = drng_random_alloc();
if (ret)
return ret;
}
if (buflen > INT_MAX)
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 *******************************/
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];
if (used_words > CHACHA20_KEY_SIZE_WORDS) {
if (CHACHA20_BLOCK_SIZE_WORDS - used_words < CHACHA20_KEY_SIZE_WORDS) {
chacha20_block(&chacha20->constants[0], tmp);
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));
} else {
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 */
chacha20->nonce[0]++;
if (chacha20->nonce[0] == 0)
if (chacha20->nonce[0] == 0){
chacha20->nonce[1]++;
if (chacha20->nonce[1] == 0)
chacha20->nonce[2]++;
}
/* 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;
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);
memcpy(outbuf, aligned_buf, CHACHA20_BLOCK_SIZE);
zeroize_buf = 1;
@@ -388,7 +547,7 @@ static int drng_chacha20_rng_selftest(struct chacha20_drng *drng)
* * remaining state is 0
* 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,
0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
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
* and pulling two ChaCha20 DRNG blocks.
*/
uint8_t expected_twoblocks[CHACHA20_KEY_SIZE * 2] = {
0xf5, 0xb4, 0xb6, 0x5a, 0xec, 0xcd, 0x5a, 0x65,
0x87, 0x56, 0xe3, 0x86, 0x51, 0x54, 0xfc, 0x90,
0x56, 0xff, 0x5e, 0xae, 0x58, 0xf2, 0x01, 0x88,
0xb1, 0x7e, 0xb8, 0x2e, 0x17, 0x9a, 0x27, 0xe6,
0x86, 0xb3, 0xed, 0x33, 0xf7, 0xb9, 0x06, 0x05,
0x8a, 0x2d, 0x1a, 0x93, 0xc9, 0x0b, 0x80, 0x04,
0x03, 0xaa, 0x60, 0xaf, 0xd5, 0x36, 0x40, 0x11,
0x67, 0x89, 0xb1, 0x66, 0xd5, 0x88, 0x62, 0x6d };
static const uint8_t expected_twoblocks[CHACHA20_KEY_SIZE * 2] = {
0xe3, 0xb0, 0x8a, 0xcc, 0x34, 0xc3, 0x17, 0x0e,
0xc3, 0xd8, 0xc3, 0x40, 0xe7, 0x73, 0xe9, 0x0d,
0xd1, 0x62, 0xa3, 0x5d, 0x7d, 0xf2, 0xf1, 0x4a,
0x24, 0x42, 0xb7, 0x1e, 0xb0, 0x05, 0x17, 0x07,
0xb9, 0x35, 0x10, 0x69, 0x8b, 0x46, 0xfb, 0x51,
0xe9, 0x91, 0x3f, 0x46, 0xf2, 0x4d, 0xea, 0xd0,
0x81, 0xc1, 0x1b, 0xa9, 0x5d, 0x52, 0x91, 0x5f,
0xcd, 0xdc, 0xc6, 0xd6, 0xc3, 0x7c, 0x50, 0x23 };
/*
* 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,
* 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
* 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] = {
0x3d, 0x13, 0x47, 0x1e, 0x7f, 0x7c, 0x99, 0x33,
0xfc, 0x44, 0xa4, 0xdd, 0xf9, 0x3d, 0xe1, 0x9a,
0xd4, 0xe8, 0x7a, 0x7d, 0x42, 0xac, 0xd1, 0xcd,
0x10, 0x69, 0xe7, 0xbf, 0xd4, 0xfd, 0x69, 0x4b,
0xa7 };
static const uint8_t expected_block_nonaligned[CHACHA20_KEY_SIZE + 4] = {
0x9c, 0xfc, 0x5e, 0x31, 0x21, 0x62, 0x11, 0x85,
0xd3, 0x77, 0xd3, 0x69, 0x0f, 0xa8, 0x16, 0x55,
0xb4, 0x4c, 0xf6, 0x52, 0xf3, 0xa8, 0x37, 0x99,
0x38, 0x76, 0xa0, 0x66, 0xec, 0xbb, 0xce, 0xa9,
0x9c, 0x95, 0xa1, 0xfd };
drng_chacha20_bswap32((uint32_t *)seed,
sizeof(seed) / sizeof(uint32_t));
/* Generate with zero state */
ret = drng_chacha20_generate(&drng->chacha20, outbuf,
sizeof(expected_block));
if (ret)
return ret;
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));
if (ret)
return ret;
ret = drng_chacha20_generate(&drng->chacha20, outbuf,
sizeof(expected_twoblocks));
if (ret)
@@ -466,15 +630,15 @@ static int drng_chacha20_rng_selftest(struct chacha20_drng *drng)
/* Reseed with 1 block and one byte */
ret = drng_chacha20_seed(&drng->chacha20, seed,
sizeof(expected_block_and_byte));
sizeof(expected_block_nonaligned));
if (ret)
return ret;
ret = drng_chacha20_generate(&drng->chacha20, outbuf,
sizeof(expected_block_and_byte));
sizeof(expected_block_nonaligned));
if (ret)
return ret;
if (memcmp(outbuf, expected_block_and_byte,
sizeof(expected_block_and_byte)))
if (memcmp(outbuf, expected_block_nonaligned,
sizeof(expected_block_nonaligned)))
return -EFAULT;
return 0;
@@ -499,31 +663,26 @@ static int drng_chacha20_alloc(struct chacha20_drng **out)
return -EFAULT;
}
#ifdef _WIN32
drng = _aligned_malloc(sizeof(*drng), CHACHA20_DRNG_ALIGNMENT);
#endif
#ifndef aligned_alloc
drng = malloc(sizeof(*drng));
#else
drng = aligned_alloc(CHACHA20_DRNG_ALIGNMENT, sizeof(*drng));
#endif
if (drng == NULL) {
return -1;
ret = posix_memalign((void *)&drng, CHACHA20_DRNG_ALIGNMENT,
sizeof(*drng));
if (ret) {
return -ret;
}
#ifndef _WIN32
/* prevent paging out of the memory state to swap space */
ret = mlock(drng, sizeof(*drng));
if (ret && errno != EPERM && errno != EAGAIN) {
ret = -errno;
goto err;
}
#endif
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);
if (ret)
@@ -559,6 +718,33 @@ int drng_chacha20_reseed(struct chacha20_drng *drng, const uint8_t *inbuf,
int ret;
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 */
ret = drng_random_get(seed, CHACHA20_KEY_SIZE);
if (ret < 0)
@@ -591,6 +777,8 @@ int drng_chacha20_reseed(struct chacha20_drng *drng, const uint8_t *inbuf,
DSO_PUBLIC
void drng_chacha20_destroy(struct chacha20_drng *drng)
{
drng_jent_dealloc();
drng_random_dealloc();
drng_chacha20_dealloc(drng);
}

View File

@@ -1134,4 +1134,3 @@ exit:
return message;
return NULL;
}

View File

@@ -236,24 +236,24 @@ static int randombytes_js_randombytes_nodejs(void *buf, size_t n) {
int randombytes(void *buf, size_t n)
{
#if defined(__EMSCRIPTEN__)
# pragma message("Using crypto api from NodeJS")
//# pragma message("Using crypto api from NodeJS")
return randombytes_js_randombytes_nodejs(buf, n);
#elif defined(__linux__)
# if defined(SYS_getrandom)
# pragma message("Using getrandom system call")
//# pragma message("Using getrandom system call")
/* Use getrandom system call */
return randombytes_linux_randombytes_getrandom(buf, n);
# else
# pragma message("Using /dev/urandom device")
//# pragma message("Using /dev/urandom device")
/* When we have enough entropy, we can read from /dev/urandom */
return randombytes_linux_randombytes_urandom(buf, n);
# endif
#elif defined(BSD)
# pragma message("Using arc4random system call")
//# pragma message("Using arc4random system call")
/* Use arc4random system call */
return randombytes_bsd_randombytes(buf, n);
#elif defined(_WIN32)
# pragma message("Using Windows cryptographic API")
//# pragma message("Using Windows cryptographic API")
/* Use windows API */
return randombytes_win32_randombytes(buf, n);
#else

View File

@@ -133,15 +133,15 @@ restart:
/*
* Fix strange behaviour: a file must be open to prevent echo
*/
if (!(flags & RPP_ECHO_ON))
if (!(flags & RPP_ECHO_ON)) {
open(_PATH_TTY, O_RDONLY);
}
/*
* Read and write to /dev/tty if available. If not, read from
* stdin and write to stderr unless a tty is required.
*/
if ((flags & RPP_STDIN) ||
(input = output = open(_PATH_TTY, O_RDWR)) == -1) {
if ((flags & RPP_STDIN) || (input = output = open(_PATH_TTY, O_RDWR)) == -1) {
if (flags & RPP_REQUIRE_TTY) {
errno = ENOTTY;
return(NULL);

View File

@@ -23,22 +23,15 @@
#include "sha3.h"
#define SHA3_ASSERT( x )
#if defined(_MSC_VER)
#define SHA3_TRACE( format, ...)
#define SHA3_TRACE_BUF( format, buf, l, ...)
#else
#define SHA3_TRACE(format, args...)
#define SHA3_TRACE_BUF(format, buf, l, args...)
#endif
#define SHA3_TRACE_BUF(format, buf, l)
//#define SHA3_USE_KECCAK
/*
* Define SHA3_USE_KECCAK to run "pure" Keccak, as opposed to 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.
* This flag is used to configure "pure" Keccak, as opposed to NIST SHA3.
*/
#define SHA3_USE_KECCAK_FLAG 0x80000000
#define SHA3_CW(x) ((x) & (~SHA3_USE_KECCAK_FLAG))
#if defined(_MSC_VER)
#define SHA3_CONST(x) x
@@ -123,30 +116,44 @@ keccakf(uint64_t s[25])
/* *************************** Public Inteface ************************ */
/* 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
sha3_Init256(void *priv)
{
sha3_context *ctx = (sha3_context *) priv;
memset(ctx, 0, sizeof(*ctx));
ctx->capacityWords = 2 * 256 / (8 * sizeof(uint64_t));
sha3_Init(priv, 256);
}
void
sha3_Init384(void *priv)
{
sha3_context *ctx = (sha3_context *) priv;
memset(ctx, 0, sizeof(*ctx));
ctx->capacityWords = 2 * 384 / (8 * sizeof(uint64_t));
sha3_Init(priv, 384);
}
void
sha3_Init512(void *priv)
{
sha3_context *ctx = (sha3_context *) priv;
memset(ctx, 0, sizeof(*ctx));
ctx->capacityWords = 2 * 512 / (8 * sizeof(uint64_t));
sha3_Init(priv, 512);
}
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
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_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
* 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);
/* 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);
ctx->byteIndex = 0;
ctx->saved = 0;
if(++ctx->wordIndex ==
(SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords)) {
keccakf(ctx->s);
(SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx->capacityWords))) {
keccakf(ctx->u.s);
ctx->wordIndex = 0;
}
}
@@ -217,10 +224,10 @@ sha3_Update(void *priv, void const *bufIn, size_t len)
#if defined(__x86_64__ ) || defined(__i386__)
SHA3_ASSERT(memcmp(&t, buf, 8) == 0);
#endif
ctx->s[ctx->wordIndex] ^= t;
ctx->u.s[ctx->wordIndex] ^= t;
if(++ctx->wordIndex ==
(SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords)) {
keccakf(ctx->s);
(SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx->capacityWords))) {
keccakf(ctx->u.s);
ctx->wordIndex = 0;
}
}
@@ -253,21 +260,22 @@ sha3_Finalize(void *priv)
* Overall, we feed 0, then 1, and finally 1 to start padding. Without
* M || 01, we would simply use 1 to start padding. */
#ifndef SHA3_USE_KECCAK
/* 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
uint64_t t;
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);
keccakf(ctx->s);
keccakf(ctx->u.s);
/* Return first bytes of the ctx->s. This conversion is not needed for
* little-endian platforms e.g. wrap with #if !defined(__BYTE_ORDER__)
@@ -277,20 +285,39 @@ sha3_Finalize(void *priv)
{
unsigned i;
for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) {
const unsigned t1 = (uint32_t) ctx->s[i];
const unsigned t2 = (uint32_t) ((ctx->s[i] >> 16) >> 16);
ctx->sb[i * 8 + 0] = (uint8_t) (t1);
ctx->sb[i * 8 + 1] = (uint8_t) (t1 >> 8);
ctx->sb[i * 8 + 2] = (uint8_t) (t1 >> 16);
ctx->sb[i * 8 + 3] = (uint8_t) (t1 >> 24);
ctx->sb[i * 8 + 4] = (uint8_t) (t2);
ctx->sb[i * 8 + 5] = (uint8_t) (t2 >> 8);
ctx->sb[i * 8 + 6] = (uint8_t) (t2 >> 16);
ctx->sb[i * 8 + 7] = (uint8_t) (t2 >> 24);
const unsigned t1 = (uint32_t) ctx->u.s[i];
const unsigned t2 = (uint32_t) ((ctx->u.s[i] >> 16) >> 16);
ctx->u.sb[i * 8 + 0] = (uint8_t) (t1);
ctx->u.sb[i * 8 + 1] = (uint8_t) (t1 >> 8);
ctx->u.sb[i * 8 + 2] = (uint8_t) (t1 >> 16);
ctx->u.sb[i * 8 + 3] = (uint8_t) (t1 >> 24);
ctx->u.sb[i * 8 + 4] = (uint8_t) (t2);
ctx->u.sb[i * 8 + 5] = (uint8_t) (t2 >> 8);
ctx->u.sb[i * 8 + 6] = (uint8_t) (t2 >> 16);
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;
}

View File

@@ -1,6 +1,8 @@
#ifndef SHA3_H
#define SHA3_H
#include <stdint.h>
/* -------------------------------------------------------------------------
* Works when compiled for either 32-bit or 64-bit targets, optimized for
* 64 bit.
@@ -28,7 +30,7 @@ typedef struct sha3_context_ {
union { /* Keccak's state */
uint64_t s[SHA3_KECCAK_SPONGE_WORDS];
uint8_t sb[SHA3_KECCAK_SPONGE_WORDS * 8];
};
} u;
unsigned byteIndex; /* 0..7--the next byte after the set one
* (starts from 0; 0--none are buffered) */
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) */
} 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: */
sha3_return_t sha3_Init(void *priv, unsigned bitSize);
void sha3_Init256(void *priv);
void sha3_Init384(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 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