@@ -23,7 +23,7 @@ void decaf_255_derive_private_key ( | |||
keccak_strobe_t strobe; | |||
strobe_init(strobe, &STROBE_256, magic, 0); | |||
strobe_key(strobe, proto, sizeof(decaf_255_symmetric_key_t)); | |||
strobe_fixed_key(strobe, proto, sizeof(decaf_255_symmetric_key_t)); | |||
strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar)); | |||
strobe_destroy(strobe); | |||
@@ -109,7 +109,7 @@ decaf_255_sign_strobe ( | |||
/* Derive nonce */ | |||
keccak_strobe_t strobe2; | |||
memcpy(strobe2,strobe,sizeof(strobe2)); | |||
strobe_key(strobe2,priv->sym,sizeof(decaf_255_symmetric_key_t)); | |||
strobe_fixed_key(strobe2,priv->sym,sizeof(decaf_255_symmetric_key_t)); | |||
strobe_prng(strobe2,overkill,sizeof(overkill)); | |||
strobe_destroy(strobe2); | |||
@@ -24,7 +24,7 @@ void decaf_448_derive_private_key ( | |||
keccak_strobe_t strobe; | |||
strobe_init(strobe, &STROBE_256, magic, 0); | |||
strobe_key(strobe, proto, sizeof(decaf_448_symmetric_key_t)); | |||
strobe_fixed_key(strobe, proto, sizeof(decaf_448_symmetric_key_t)); | |||
strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar)); | |||
strobe_destroy(strobe); | |||
@@ -110,7 +110,7 @@ decaf_448_sign_strobe ( | |||
/* Derive nonce */ | |||
keccak_strobe_t strobe2; | |||
memcpy(strobe2,strobe,sizeof(strobe2)); | |||
strobe_key(strobe2,priv->sym,sizeof(decaf_448_symmetric_key_t)); | |||
strobe_fixed_key(strobe2,priv->sym,sizeof(decaf_448_symmetric_key_t)); | |||
strobe_prng(strobe2,overkill,sizeof(overkill)); | |||
strobe_destroy(strobe2); | |||
@@ -189,11 +189,6 @@ void spongerng_init_from_buffer ( | |||
size_t len, | |||
int deterministic | |||
) NONNULL2 API_VIS; | |||
/* FIXME!! This interface has the opposite retval convention from other functions | |||
* in the library. (0=success). Should they be harmonized? | |||
*/ | |||
/** | |||
* @brief Initialize a sponge-based CSPRNG from a file. | |||
* | |||
@@ -203,33 +198,27 @@ void spongerng_init_from_buffer ( | |||
* @param [in] deterministic If zero, allow RNG to stir in nondeterministic | |||
* data from RDRAND or RDTSC. | |||
* | |||
* @retval 0 Success. | |||
* @retval positive An error has occurred, and this was the errno. | |||
* @retval -1 An unknown error has occurred. | |||
* @retval -2 len was 0. | |||
* @retval DECAF_SUCCESS success. | |||
* @retval DECAF_FAILURE failure. | |||
* @note On failure, errno can be used to determine the cause. | |||
*/ | |||
int spongerng_init_from_file ( | |||
decaf_error_t spongerng_init_from_file ( | |||
keccak_prng_t prng, | |||
const char *file, | |||
size_t len, | |||
int deterministic | |||
) NONNULL2 API_VIS WARN_UNUSED; | |||
/* FIXME!! This interface has the opposite retval convention from other functions | |||
* in the library. (0=success). Should they be harmonized? | |||
*/ | |||
/** | |||
* @brief Initialize a nondeterministic sponge-based CSPRNG from /dev/urandom. | |||
* | |||
* @param [out] sponge The sponge object. | |||
* | |||
* @retval 0 Success. | |||
* @retval positive An error has occurred, and this was the errno. | |||
* @retval -1 An unknown error has occurred. | |||
* @retval DECAF_SUCCESS success. | |||
* @retval DECAF_FAILURE failure. | |||
* @note On failure, errno can be used to determine the cause. | |||
*/ | |||
int spongerng_init_from_dev_urandom ( | |||
decaf_error_t spongerng_init_from_dev_urandom ( | |||
keccak_prng_t prng | |||
) API_VIS WARN_UNUSED; | |||
@@ -312,8 +301,8 @@ STROBE_CONTROL_WORD(STROBE_CW_PRNG, 0x18, STROBE_MODE_SQUEEZE, S | |||
STROBE_CONTROL_WORD(STROBE_CW_SESSION_HASH, 0x19, STROBE_MODE_SQUEEZE, 0); | |||
/* Reuse for PRNG */ | |||
STROBE_CONTROL_WORD(STROBE_CW_PRNG_INITIAL_SEED, 0x10, STROBE_MODE_ABSORB, STROBE_FLAG_LENGTH_64); | |||
STROBE_CONTROL_WORD(STROBE_CW_PRNG_RESEED, 0x11, STROBE_MODE_ABSORB, STROBE_FLAG_LENGTH_64); | |||
STROBE_CONTROL_WORD(STROBE_CW_PRNG_INITIAL_SEED, 0x10, STROBE_MODE_ABSORB, STROBE_FLAG_NO_LENGTH); | |||
STROBE_CONTROL_WORD(STROBE_CW_PRNG_RESEED, 0x11, STROBE_MODE_ABSORB, STROBE_FLAG_NO_LENGTH); | |||
STROBE_CONTROL_WORD(STROBE_CW_PRNG_CPU_SEED, 0x12, STROBE_MODE_ABSORB, 0); | |||
STROBE_CONTROL_WORD(STROBE_CW_PRNG_USER_SEED, 0x13, STROBE_MODE_ABSORB, STROBE_FLAG_LENGTH_64); | |||
STROBE_CONTROL_WORD(STROBE_CW_PRNG_PRNG, 0x14, STROBE_MODE_SQUEEZE, STROBE_FLAG_LENGTH_64 | STROBE_FLAG_FORGET); | |||
@@ -452,18 +441,33 @@ static INLINE UNUSED void strobe_nonce ( | |||
} | |||
/** | |||
* @brief Set key in strobe context. | |||
* @brief Set fixed key in strobe context. | |||
* @param [inout] The initialized strobe object. | |||
* @param [in] in The key. | |||
* @param [in] len The length of the key. | |||
*/ | |||
static INLINE UNUSED void | |||
strobe_fixed_key ( | |||
keccak_strobe_t strobe, | |||
const unsigned char *in, | |||
uint16_t len | |||
) { | |||
strobe_transact( strobe, NULL, in, len, STROBE_CW_FIXED_KEY ); | |||
} | |||
/** | |||
* @brief Set Diffie-Hellman key in strobe context. | |||
* @param [inout] The initialized strobe object. | |||
* @param [in] in The key. | |||
* @param [in] len The length of the key. | |||
*/ | |||
static INLINE UNUSED void | |||
strobe_key ( | |||
strobe_dh_key ( | |||
keccak_strobe_t strobe, | |||
const unsigned char *in, | |||
uint16_t len | |||
) { | |||
strobe_transact( strobe, NULL, in, len, STROBE_CW_DH_KEY ); /* FIXME: what about other kinds of keys? */ | |||
strobe_transact( strobe, NULL, in, len, STROBE_CW_DH_KEY ); | |||
} | |||
@@ -15,6 +15,7 @@ | |||
#include <decaf/shake.h> | |||
#include <string> | |||
#include <sys/types.h> | |||
#include <errno.h> | |||
/** @cond internal */ | |||
#if __cplusplus >= 201103L | |||
@@ -167,9 +168,9 @@ public: | |||
inline SpongeRng( const std::string &in = "/dev/urandom", size_t len = 32, bool deterministic = false ) | |||
throw(RngException) | |||
: KeccakSponge((NOINIT())) { | |||
int ret = spongerng_init_from_file(sp,in.c_str(),len,deterministic); | |||
if (ret) { | |||
throw RngException(ret, "Couldn't load from file"); | |||
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"); | |||
} | |||
} | |||
@@ -205,18 +206,30 @@ public: | |||
keyed = false; | |||
} | |||
/* TODO: add a key type keyword */ | |||
inline void key ( | |||
inline void fixed_key ( | |||
const Block &data | |||
) throw(ProtocolException) { | |||
strobe_key(sp, data.data(), data.size()); | |||
strobe_fixed_key(sp, data.data(), data.size()); | |||
keyed = true; | |||
} | |||
template<class T> inline void key ( | |||
template<class T> inline void fixed_key ( | |||
const Serializable<T> &data | |||
) throw(ProtocolException) { | |||
key(data.serialize()); | |||
fixed_key(data.serialize()); | |||
} | |||
inline void dh_key ( | |||
const Block &data | |||
) throw(ProtocolException) { | |||
strobe_dh_key(sp, data.data(), data.size()); | |||
keyed = true; | |||
} | |||
template<class T> inline void dh_key ( | |||
const Serializable<T> &data | |||
) throw(ProtocolException) { | |||
dh_key(data.serialize()); | |||
} | |||
inline void nonce(const Block &data) NOEXCEPT { | |||
@@ -21,7 +21,6 @@ | |||
#include <sys/types.h> | |||
#include <sys/stat.h> | |||
#include <fcntl.h> | |||
#include <errno.h> | |||
#include <unistd.h> | |||
/* Subset of Mathias Panzenböck's portable endian code, public domain */ | |||
@@ -292,9 +291,7 @@ static void get_cpu_entropy(uint8_t *entropy, size_t len) { | |||
#endif | |||
} | |||
static const uint16_t SPONGERNG_MAX_BLOCK_SIZE = 1<<12; /* TODO: standardize and freeze */ | |||
static const uint16_t SPONGERNG_FILE_BLOCK_SIZE = 1<<12; /* TODO: standardize and freeze */ | |||
static const char *SPONGERNG_NAME = "spongerng"; /* TODO: canonicalize name */ | |||
static const char *SPONGERNG_NAME = "strobe::spongerng"; /* TODO: canonicalize name */ | |||
void spongerng_next ( | |||
keccak_sponge_t sponge, | |||
@@ -308,12 +305,7 @@ void spongerng_next ( | |||
strobe_transact(sponge,NULL,cpu_entropy,sizeof(cpu_entropy),STROBE_CW_PRNG_CPU_SEED); | |||
} | |||
while (len) { | |||
uint16_t cando = (len > SPONGERNG_MAX_BLOCK_SIZE) ? SPONGERNG_MAX_BLOCK_SIZE : len; | |||
strobe_transact(sponge,out,NULL,cando,STROBE_CW_PRNG); | |||
out += cando; | |||
len -= cando; | |||
} | |||
strobe_transact(sponge,out,NULL,len,STROBE_CW_PRNG); | |||
} | |||
void spongerng_stir ( | |||
@@ -321,12 +313,7 @@ void spongerng_stir ( | |||
const uint8_t * __restrict__ in, | |||
size_t len | |||
) { | |||
while (len) { | |||
uint16_t cando = (len > SPONGERNG_MAX_BLOCK_SIZE) ? SPONGERNG_MAX_BLOCK_SIZE : len; | |||
strobe_transact(sponge,NULL,in,cando,STROBE_CW_PRNG_USER_SEED); | |||
in += cando; | |||
len -= cando; | |||
} | |||
strobe_transact(sponge,NULL,in,len,STROBE_CW_PRNG_USER_SEED); | |||
} | |||
static const struct kparams_s spongerng_params = { | |||
@@ -343,34 +330,37 @@ void spongerng_init_from_buffer ( | |||
spongerng_stir(sponge, in, len); | |||
} | |||
int spongerng_init_from_file ( | |||
decaf_error_t spongerng_init_from_file ( | |||
keccak_sponge_t sponge, | |||
const char *file, | |||
size_t len, | |||
int deterministic | |||
) { | |||
strobe_init(sponge, &spongerng_params, SPONGERNG_NAME, !deterministic); | |||
if (!len) return -2; | |||
if (!len) return DECAF_FAILURE; | |||
int fd = open(file, O_RDONLY); | |||
if (fd < 0) return errno ? errno : -1; | |||
if (fd < 0) return DECAF_FAILURE; | |||
uint8_t buffer[SPONGERNG_FILE_BLOCK_SIZE]; | |||
uint8_t buffer[128]; | |||
int first = 1; | |||
while (len) { | |||
ssize_t red = read(fd, buffer, (len > sizeof(buffer)) ? sizeof(buffer) : len); | |||
if (red <= 0) { | |||
close(fd); | |||
return errno ? errno : -1; | |||
return DECAF_FAILURE; | |||
} | |||
spongerng_stir(sponge,buffer,red); | |||
strobe_transact(sponge,NULL,buffer,red, | |||
first ? STROBE_CW_PRNG_USER_SEED : (STROBE_CW_PRNG_USER_SEED | STROBE_FLAG_MORE)); | |||
len -= red; | |||
first = 0; | |||
}; | |||
close(fd); | |||
return 0; | |||
return DECAF_SUCCESS; | |||
} | |||
int spongerng_init_from_dev_urandom ( | |||
decaf_error_t spongerng_init_from_dev_urandom ( | |||
keccak_sponge_t sponge | |||
) { | |||
return spongerng_init_from_file(sponge, "/dev/urandom", 64, 0); | |||
@@ -547,7 +537,7 @@ void strobe_transact ( | |||
uint64_t my_len = len, len_cw = (cw_flags & STROBE_FLAG_LENGTH_64) ? 10 : 4; | |||
if (cw_flags & STROBE_FLAG_NO_LENGTH) { | |||
my_len = 0; | |||
} else { | |||
} else if ((cw_flags & STROBE_FLAG_LENGTH_64)==0) { | |||
assert(my_len < 1<<16); | |||
} | |||
@@ -586,6 +576,7 @@ void strobe_transact ( | |||
len -= len_cw; /* HACK */ | |||
if (cw_flags & STROBE_FLAG_NO_LENGTH) len = 2*STROBE_FORGET_BYTES; | |||
assert(!(cw_flags & STROBE_FLAG_MORE)); | |||
strobe_duplex( | |||
sponge, NULL, NULL, len, | |||
@@ -615,7 +606,7 @@ void strobe_respec ( | |||
keccak_sponge_t sponge, | |||
const struct kparams_s *params | |||
) { | |||
uint8_t in[] = { params->rate, params->startRound }; /* TODO: nail down */ | |||
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 ); | |||
assert(sponge->params->position == 0); | |||
@@ -171,23 +171,23 @@ static void tdh ( | |||
client.recv_plaintext(gye); | |||
Point pgxe(gxe); | |||
server.key(pgxe*ye); | |||
server.dh_key(pgxe*ye); | |||
SecureBuffer tag1 = server.produce_auth(); | |||
//SecureBuffer ct = server.encrypt(gy); | |||
server.key(pgxe*y); | |||
server.dh_key(pgxe*y); | |||
SecureBuffer tag2 = server.produce_auth(); | |||
Point pgye(gye); | |||
client.key(pgye*xe); | |||
client.dh_key(pgye*xe); | |||
client.verify_auth(tag1); | |||
client.key(Point(gy) * xe); | |||
client.dh_key(Point(gy) * xe); | |||
client.verify_auth(tag2); | |||
// ct = client.encrypt(gx); | |||
client.key(pgye * x); | |||
client.dh_key(pgye * x); | |||
tag1 = client.produce_auth(); | |||
client.respec(STROBE_KEYED_128); | |||
server.key(Point(gx) * ye); | |||
server.dh_key(Point(gx) * ye); | |||
server.verify_auth(tag1); | |||
server.respec(STROBE_KEYED_128); | |||
} | |||
@@ -217,14 +217,14 @@ static void fhmqv ( | |||
Scalar schx(server.prng(Scalar::SER_BYTES)); | |||
Scalar schy(server.prng(Scalar::SER_BYTES)); | |||
Scalar yec = y + ye*schy; | |||
server.key(Point::double_scalarmul(Point(gx),yec,Point(gxe),yec*schx)); | |||
server.dh_key(Point::double_scalarmul(Point(gx),yec,Point(gxe),yec*schx)); | |||
SecureBuffer as = server.produce_auth(); | |||
client.recv_plaintext(gye); | |||
Scalar cchx(client.prng(Scalar::SER_BYTES)); | |||
Scalar cchy(client.prng(Scalar::SER_BYTES)); | |||
Scalar xec = x + xe*schx; | |||
client.key(Point::double_scalarmul(Point(gy),xec,Point(gye),xec*schy)); | |||
client.dh_key(Point::double_scalarmul(Point(gy),xec,Point(gye),xec*schy)); | |||
client.verify_auth(as); | |||
SecureBuffer ac = client.produce_auth(); | |||
client.respec(STROBE_KEYED_128); | |||
@@ -264,19 +264,19 @@ static void spake2ee( | |||
server.send_plaintext(gy); | |||
client.recv_plaintext(gy); | |||
server.key(h1); | |||
server.key((Point(gx) - hc)*y); | |||
server.dh_key(h1); | |||
server.dh_key((Point(gx) - hc)*y); | |||
if(aug) { | |||
/* This step isn't actually online but whatever, it's fastish */ | |||
SecureBuffer serverAug((Precomputed::base() * gs).serialize()); | |||
server.key(Point(serverAug)*y); | |||
server.dh_key(Point(serverAug)*y); | |||
} | |||
SecureBuffer tag = server.produce_auth(); | |||
client.key(h1); | |||
client.dh_key(h1); | |||
Point pgy(gy); pgy -= hs; | |||
client.key(pgy*x); | |||
if (aug) client.key(pgy * gs); | |||
client.dh_key(pgy*x); | |||
if (aug) client.dh_key(pgy * gs); | |||
client.verify_auth(tag); | |||
tag = client.produce_auth(); | |||
client.respec(STROBE_KEYED_128); | |||
@@ -395,7 +395,7 @@ int main(int argc, char **argv) { | |||
for (Benchmark b("SHAKE128 1kiB", 30); b.iter(); ) { shake1 += Buffer(b1024,1024); } | |||
for (Benchmark b("SHAKE256 1kiB", 30); b.iter(); ) { shake2 += Buffer(b1024,1024); } | |||
for (Benchmark b("SHA3-512 1kiB", 30); b.iter(); ) { sha5 += Buffer(b1024,1024); } | |||
strobe.key(Buffer(b1024,1024)); | |||
strobe.dh_key(Buffer(b1024,1024)); | |||
strobe.respec(STROBE_128); | |||
for (Benchmark b("STROBE128 1kiB", 10); b.iter(); ) { | |||
strobe.encrypt_no_auth(Buffer(b1024,1024),Buffer(b1024,1024)); | |||