1
1
mirror of https://github.com/henrydcase/pqc.git synced 2024-11-27 18:01:34 +00:00
pqcrypto/crypto_kem/ledakemlt12/leaktime/rng.c

111 lines
3.2 KiB
C
Raw Normal View History

#include "rng.h"
#include <string.h> // void *memset(void *s, int c, size_t n);
2019-05-24 17:38:54 +01:00
#include "aes.h"
#include "qc_ldpc_parameters.h"
/*
seedexpander_init()
ctx - stores the current state of an instance of the seed expander
seed - a 32 byte random value
diversifier - an 8 byte diversifier
maxlen - maximum number of bytes (less than 2**32) generated under this seed and diversifier
*/
static void seedexpander_init(AES_XOF_struct *ctx,
2019-08-24 14:48:38 +01:00
uint8_t *seed,
uint8_t *diversifier,
size_t maxlen) {
ctx->length_remaining = maxlen;
memset(ctx->key, 0, 32);
int max_accessible_seed_len = TRNG_BYTE_LENGTH < 32 ? 32 : TRNG_BYTE_LENGTH;
memcpy(ctx->key, seed, max_accessible_seed_len);
memcpy(ctx->ctr, diversifier, 8);
ctx->ctr[11] = maxlen % 256;
maxlen >>= 8;
ctx->ctr[10] = maxlen % 256;
maxlen >>= 8;
ctx->ctr[9] = maxlen % 256;
maxlen >>= 8;
ctx->ctr[8] = maxlen % 256;
memset(ctx->ctr + 12, 0x00, 4);
ctx->buffer_pos = 16;
memset(ctx->buffer, 0x00, 16);
}
2019-06-16 16:01:29 +01:00
void PQCLEAN_LEDAKEMLT12_LEAKTIME_seedexpander_from_trng(AES_XOF_struct *ctx,
2019-08-24 14:48:38 +01:00
const uint8_t *trng_entropy
2019-05-24 17:38:54 +01:00
/* TRNG_BYTE_LENGTH wide buffer */) {
/*the NIST seedexpander will however access 32B from this buffer */
unsigned int prng_buffer_size = TRNG_BYTE_LENGTH < 32 ? 32 : TRNG_BYTE_LENGTH;
2019-08-24 14:48:38 +01:00
uint8_t prng_buffer[TRNG_BYTE_LENGTH < 32 ? 32 : TRNG_BYTE_LENGTH] = {0x00};
uint8_t diversifier[8] = {0};
2019-05-24 17:38:54 +01:00
memcpy(prng_buffer,
trng_entropy,
TRNG_BYTE_LENGTH < prng_buffer_size ? TRNG_BYTE_LENGTH : prng_buffer_size);
/* the required seed expansion will be quite small, set the max number of
* bytes conservatively to 10 MiB*/
seedexpander_init(ctx, prng_buffer, diversifier, RNG_MAXLEN);
2019-05-24 17:38:54 +01:00
}
/*
seedexpander()
ctx - stores the current state of an instance of the seed expander
x - returns the XOF data
xlen - number of bytes to return
*/
2019-08-24 14:48:38 +01:00
int PQCLEAN_LEDAKEMLT12_LEAKTIME_seedexpander(AES_XOF_struct *ctx, uint8_t *x, size_t xlen) {
2019-06-11 16:09:28 +01:00
size_t offset;
2019-05-24 17:38:54 +01:00
aes256ctx ctx256;
if ( x == NULL ) {
return RNG_BAD_OUTBUF;
}
if ( xlen >= ctx->length_remaining ) {
return RNG_BAD_REQ_LEN;
}
2019-05-24 17:38:54 +01:00
aes256_keyexp(&ctx256, ctx->key);
ctx->length_remaining -= xlen;
offset = 0;
while ( xlen > 0 ) {
if ( xlen <= (16 - ctx->buffer_pos) ) { // buffer has what we need
memcpy(x + offset, ctx->buffer + ctx->buffer_pos, xlen);
ctx->buffer_pos += xlen;
2020-02-19 19:56:02 +00:00
goto end;
}
// take what's in the buffer
memcpy(x + offset, ctx->buffer + ctx->buffer_pos, 16 - ctx->buffer_pos);
xlen -= 16 - ctx->buffer_pos;
offset += 16 - ctx->buffer_pos;
2019-05-24 17:38:54 +01:00
aes256_ecb(ctx->buffer, ctx->ctr, 16 / AES_BLOCKBYTES, &ctx256);
ctx->buffer_pos = 0;
//increment the counter
for (int i = 15; i >= 12; i--) {
if ( ctx->ctr[i] == 0xff ) {
ctx->ctr[i] = 0x00;
} else {
ctx->ctr[i]++;
break;
}
}
}
2020-02-19 19:56:02 +00:00
end:
aes256_ctx_release(&ctx256);
2020-02-26 18:16:19 +00:00
return RNG_SUCCESS;
}