| @@ -81,11 +81,9 @@ void sha3_output ( | |||
| * for the purpose of C++ default operators. | |||
| * | |||
| * Returns n/8 for SHA3-n and 2n/8 for SHAKE-n. | |||
| * | |||
| * @param [inout] sponge The context. | |||
| */ | |||
| size_t sponge_default_output_bytes ( | |||
| const keccak_sponge_t sponge | |||
| const keccak_sponge_t sponge /**< [inout] The context. */ | |||
| ) API_VIS; | |||
| /** | |||
| @@ -32,33 +32,19 @@ | |||
| namespace decaf { | |||
| /** A Keccak sponge internal class */ | |||
| class KeccakSponge { | |||
| protected: | |||
| /** @cond internal */ | |||
| /** The C-wrapper sponge state */ | |||
| keccak_sponge_t sp; | |||
| /** Initialize from parameters */ | |||
| inline KeccakSponge(const struct kparams_s *params) NOEXCEPT { sponge_init(sp, params); } | |||
| /** No initialization */ | |||
| inline KeccakSponge(const NOINIT &) NOEXCEPT { } | |||
| /** @endcond */ | |||
| public: | |||
| /** Destructor zeroizes state */ | |||
| inline ~KeccakSponge() NOEXCEPT { sponge_destroy(sp); } | |||
| }; | |||
| /** | |||
| * Hash function derived from Keccak | |||
| * @todo throw exceptions when hash is misused. | |||
| */ | |||
| class KeccakHash : public KeccakSponge { | |||
| class KeccakHash { | |||
| protected: | |||
| /** @cond internal */ | |||
| /** The C-wrapper sponge state */ | |||
| keccak_sponge_t sp; | |||
| /** Initialize from parameters */ | |||
| inline KeccakHash(const kparams_s *params) NOEXCEPT : KeccakSponge(params) {} | |||
| inline KeccakHash(const kparams_s *params) NOEXCEPT { sponge_init(sp, params); } | |||
| /** @endcond */ | |||
| public: | |||
| /** Add more data to running hash */ | |||
| @@ -95,6 +81,9 @@ public: | |||
| inline SecureBuffer output() { | |||
| return output(default_output_size()); | |||
| } | |||
| /** Destructor zeroizes state */ | |||
| inline ~KeccakHash() NOEXCEPT { sponge_destroy(sp); } | |||
| }; | |||
| /** Fixed-output-length SHA3 */ | |||
| @@ -160,7 +149,11 @@ public: | |||
| }; | |||
| /** Sponge-based random-number generator */ | |||
| class SpongeRng : public Rng, private KeccakSponge { | |||
| class SpongeRng : public Rng { | |||
| private: | |||
| /** C wrapped object */ | |||
| keccak_prng_t sp; | |||
| public: | |||
| /** Exception thrown when The RNG fails (to seed itself) */ | |||
| class RngException : public std::exception { | |||
| @@ -175,21 +168,22 @@ public: | |||
| }; | |||
| /** Initialize, deterministically by default, from block */ | |||
| inline SpongeRng( const Block &in, bool deterministic = true ) | |||
| : KeccakSponge((NOINIT())) { | |||
| inline SpongeRng( const Block &in, bool deterministic = true ) { | |||
| spongerng_init_from_buffer(sp,in.data(),in.size(),deterministic); | |||
| } | |||
| /** Initialize, non-deterministically by default, from C/C++ filename */ | |||
| inline SpongeRng( const std::string &in = "/dev/urandom", size_t len = 32, bool deterministic = false ) | |||
| throw(RngException) | |||
| : KeccakSponge((NOINIT())) { | |||
| throw(RngException) { | |||
| decaf_error_t ret = spongerng_init_from_file(sp,in.c_str(),len,deterministic); | |||
| if (!decaf_successful(ret)) { | |||
| throw RngException(errno, "Couldn't load from file"); | |||
| } | |||
| } | |||
| /** Securely destroy by overwriting state. */ | |||
| inline ~SpongeRng() NOEXCEPT { spongerng_destroy(sp); } | |||
| using Rng::read; | |||
| /** Read data to a buffer. */ | |||
| @@ -206,7 +200,11 @@ private: | |||
| /**@endcond*/ | |||
| /** STROBE protocol framework object */ | |||
| class Strobe : private KeccakSponge { | |||
| class Strobe { | |||
| private: | |||
| /** The wrapped object */ | |||
| keccak_strobe_t sp; | |||
| public: | |||
| /** Number of bytes in a default authentication size. */ | |||
| static const uint16_t DEFAULT_AUTH_SIZE = 16; | |||
| @@ -219,10 +217,13 @@ public: | |||
| const char *description, /**< Description of this protocol. */ | |||
| client_or_server whoami, /**< Am I client or server? */ | |||
| const kparams_s ¶ms = STROBE_256 /**< Strength parameters */ | |||
| ) NOEXCEPT : KeccakSponge(NOINIT()) { | |||
| ) NOEXCEPT { | |||
| strobe_init(sp, ¶ms, description, whoami == CLIENT); | |||
| keyed = false; | |||
| } | |||
| /** Securely destroy by overwriting state. */ | |||
| inline ~Strobe() NOEXCEPT { strobe_destroy(sp); } | |||
| /** Stir in fixed key, from a C++ block. */ | |||
| inline void fixed_key ( | |||
| @@ -18,8 +18,10 @@ | |||
| extern "C" { | |||
| #endif | |||
| /** Keccak CSPRNG structure as struct. FUTURE: distinguish. */ | |||
| typedef struct keccak_sponge_s keccak_prng_s; | |||
| /** Keccak CSPRNG structure as struct. */ | |||
| typedef struct { | |||
| keccak_sponge_t sponge; /**< Internal sponge object. */ | |||
| } keccak_prng_s; | |||
| /** Keccak CSPRNG structure as one-element array */ | |||
| typedef keccak_prng_s keccak_prng_t[1]; | |||
| @@ -80,7 +82,7 @@ spongerng_destroy ( | |||
| /* Implementations of inline functions */ | |||
| /***************************************/ | |||
| void spongerng_destroy (keccak_prng_t doomed) { | |||
| sponge_destroy(doomed); | |||
| sponge_destroy(doomed->sponge); | |||
| } | |||
| /** @endcond */ /* internal */ | |||
| @@ -17,8 +17,10 @@ | |||
| extern "C" { | |||
| #endif | |||
| /** Keccak STROBE structure as struct. FUTURE: distinguish. */ | |||
| typedef struct keccak_sponge_s keccak_strobe_s; | |||
| /** Keccak STROBE structure as struct. */ | |||
| typedef struct { | |||
| keccak_sponge_t sponge; /**< Internal sponge object. */ | |||
| } keccak_strobe_s; | |||
| /** Keccak STROBE structure as one-element array */ | |||
| typedef keccak_strobe_s keccak_strobe_t[1]; | |||
| @@ -198,7 +200,9 @@ typedef enum { | |||
| #define STROBE_FLAG_NONDIR (STROBE_FLAG_IMPLICIT) | |||
| /** Automatic flags implied by the mode */ | |||
| /* HACK: SQUEEZE_R is treated as directional because its' MAC */ | |||
| /* NB: SQUEEZE_R is treated as directional because its' MAC. | |||
| * can of course override by orring in IMPLICIT|NONDIR | |||
| */ | |||
| #define STROBE_AUTO_FLAGS(_mode) \ | |||
| ( (((_mode)&1) ? STROBE_FLAG_RUN_F : 0) \ | |||
| | (( ((_mode) & ~2) == STROBE_MODE_ABSORB \ | |||
| @@ -325,7 +329,7 @@ void strobe_prng(keccak_strobe_t strobe, unsigned char *out, uint16_t len) { | |||
| } | |||
| void strobe_destroy (keccak_strobe_t doomed) { | |||
| sponge_destroy(doomed); | |||
| sponge_destroy(doomed->sponge); | |||
| } | |||
| /** @endcond */ /* internal */ | |||
| @@ -63,7 +63,7 @@ typedef struct kparams_s { | |||
| typedef struct keccak_sponge_s { | |||
| kdomain_t state; | |||
| kparams_t params; | |||
| } keccak_sponge_t[1]; | |||
| } keccak_sponge_s, keccak_sponge_t[1]; | |||
| #define INTERNAL_SPONGE_STRUCT 1 | |||
| #include <decaf/shake.h> | |||
| @@ -296,26 +296,27 @@ static void get_cpu_entropy(uint8_t *entropy, size_t len) { | |||
| static const char *SPONGERNG_NAME = "strobe::spongerng"; /* TODO: canonicalize name */ | |||
| void spongerng_next ( | |||
| keccak_sponge_t sponge, | |||
| keccak_prng_t prng, | |||
| uint8_t * __restrict__ out, | |||
| size_t len | |||
| ) { | |||
| keccak_sponge_s *sponge = prng->sponge; | |||
| if (sponge->params->client) { | |||
| /* nondet */ | |||
| uint8_t cpu_entropy[32]; | |||
| get_cpu_entropy(cpu_entropy, sizeof(cpu_entropy)); | |||
| strobe_transact(sponge,NULL,cpu_entropy,sizeof(cpu_entropy),STROBE_CW_PRNG_CPU_SEED); | |||
| strobe_transact((keccak_strobe_s*)sponge,NULL,cpu_entropy,sizeof(cpu_entropy),STROBE_CW_PRNG_CPU_SEED); | |||
| } | |||
| strobe_transact(sponge,out,NULL,len,STROBE_CW_PRNG); | |||
| strobe_transact((keccak_strobe_s*)sponge,out,NULL,len,STROBE_CW_PRNG); | |||
| } | |||
| void spongerng_stir ( | |||
| keccak_sponge_t sponge, | |||
| keccak_prng_t sponge, | |||
| const uint8_t * __restrict__ in, | |||
| size_t len | |||
| ) { | |||
| strobe_transact(sponge,NULL,in,len,STROBE_CW_PRNG_USER_SEED); | |||
| strobe_transact((keccak_strobe_s*)sponge,NULL,in,len,STROBE_CW_PRNG_USER_SEED); | |||
| } | |||
| static const struct kparams_s spongerng_params = { | |||
| @@ -323,22 +324,24 @@ static const struct kparams_s spongerng_params = { | |||
| }; | |||
| void spongerng_init_from_buffer ( | |||
| keccak_sponge_t sponge, | |||
| keccak_prng_t prng, | |||
| const uint8_t * __restrict__ in, | |||
| size_t len, | |||
| int deterministic | |||
| ) { | |||
| strobe_init(sponge, &spongerng_params, SPONGERNG_NAME, !deterministic); | |||
| spongerng_stir(sponge, in, len); | |||
| keccak_sponge_s *sponge = prng->sponge; | |||
| strobe_init((keccak_strobe_s*)sponge, &spongerng_params, SPONGERNG_NAME, !deterministic); | |||
| spongerng_stir(prng, in, len); | |||
| } | |||
| decaf_error_t spongerng_init_from_file ( | |||
| keccak_sponge_t sponge, | |||
| keccak_prng_t prng, | |||
| const char *file, | |||
| size_t len, | |||
| int deterministic | |||
| ) { | |||
| strobe_init(sponge, &spongerng_params, SPONGERNG_NAME, !deterministic); | |||
| keccak_sponge_s *sponge = prng->sponge; | |||
| strobe_init((keccak_strobe_s*)sponge, &spongerng_params, SPONGERNG_NAME, !deterministic); | |||
| if (!len) return DECAF_FAILURE; | |||
| int fd = open(file, O_RDONLY); | |||
| @@ -352,7 +355,7 @@ decaf_error_t spongerng_init_from_file ( | |||
| close(fd); | |||
| return DECAF_FAILURE; | |||
| } | |||
| strobe_transact(sponge,NULL,buffer,red, | |||
| strobe_transact((keccak_strobe_s*)sponge,NULL,buffer,red, | |||
| first ? STROBE_CW_PRNG_USER_SEED : (STROBE_CW_PRNG_USER_SEED | STROBE_FLAG_MORE)); | |||
| len -= red; | |||
| first = 0; | |||
| @@ -363,7 +366,7 @@ decaf_error_t spongerng_init_from_file ( | |||
| } | |||
| decaf_error_t spongerng_init_from_dev_urandom ( | |||
| keccak_sponge_t sponge | |||
| keccak_prng_t sponge | |||
| ) { | |||
| return spongerng_init_from_file(sponge, "/dev/urandom", 64, 0); | |||
| } | |||
| @@ -375,11 +378,12 @@ const struct kparams_s STROBE_KEYED_128 = { 0, 0, 200-128/4, 12, 0, 0, 0, 0 }; | |||
| /* Strobe is different in that its rate is padded by one byte. */ | |||
| void strobe_init( | |||
| keccak_sponge_t sponge, | |||
| keccak_strobe_t strobe, | |||
| const struct kparams_s *params, | |||
| const char *proto, | |||
| uint8_t am_client | |||
| ) { | |||
| keccak_sponge_s *sponge = strobe->sponge; | |||
| sponge_init(sponge,params); | |||
| const char *a_string = "STROBE full v0.2"; | |||
| @@ -390,7 +394,7 @@ void strobe_init( | |||
| len | |||
| ); | |||
| strobe_transact(sponge, NULL, (const unsigned char *)proto, strlen(proto), STROBE_CW_INIT); | |||
| strobe_transact(strobe, NULL, (const unsigned char *)proto, strlen(proto), STROBE_CW_INIT); | |||
| sponge->state->b[sponge->params->rate+1] = 1; | |||
| sponge->params->client = !!am_client; | |||
| @@ -524,12 +528,13 @@ static const int STROBE_FORGET_BYTES = 32; | |||
| static const uint8_t FLAG_NOPARSE = 1; | |||
| void strobe_transact ( | |||
| keccak_sponge_t sponge, | |||
| keccak_strobe_t strobe, | |||
| unsigned char *out, | |||
| const unsigned char *in, | |||
| size_t len, | |||
| uint32_t cw_flags | |||
| ) { | |||
| keccak_sponge_s *sponge = strobe->sponge; | |||
| if ( (cw_flags & STROBE_FLAG_NONDIR) == 0 | |||
| /* extraneous nots to change ints to bools :-/ */ | |||
| && !(cw_flags & STROBE_FLAG_RECV) != !(sponge->params->client) ) { | |||
| @@ -588,12 +593,13 @@ void strobe_transact ( | |||
| } | |||
| decaf_error_t strobe_verify_auth ( | |||
| keccak_sponge_t sponge, | |||
| keccak_strobe_t strobe, | |||
| const unsigned char *in, | |||
| uint16_t len | |||
| ) { | |||
| keccak_sponge_s *sponge = strobe->sponge; | |||
| if (len > sponge->params->rate) return DECAF_FAILURE; | |||
| strobe_transact(sponge, NULL, in, len, strobe_cw_recv(STROBE_CW_MAC)); | |||
| strobe_transact(strobe, NULL, in, len, strobe_cw_recv(STROBE_CW_MAC)); | |||
| int32_t residue = 0; | |||
| int i; | |||
| @@ -605,12 +611,13 @@ decaf_error_t strobe_verify_auth ( | |||
| } | |||
| void strobe_respec ( | |||
| keccak_sponge_t sponge, | |||
| keccak_strobe_t strobe, | |||
| const struct kparams_s *params | |||
| ) { | |||
| keccak_sponge_s *sponge = strobe->sponge; | |||
| uint8_t in[] = { params->rate, params->startRound }; | |||
| strobe_transact( sponge, NULL, in, sizeof(in), STROBE_CW_RESPEC_INFO ); | |||
| strobe_transact( sponge, NULL, NULL, 0, STROBE_CW_RESPEC ); | |||
| strobe_transact( strobe, NULL, in, sizeof(in), STROBE_CW_RESPEC_INFO ); | |||
| strobe_transact( strobe, NULL, NULL, 0, STROBE_CW_RESPEC ); | |||
| assert(sponge->params->position == 0); | |||
| sponge->params->rate = params->rate; | |||
| sponge->params->startRound = params->startRound; | |||