Add entropy pool and strong random number generator
Entropy pool gathers environmental noise from device drivers, user-space, etc., and returns good random numbers, suitable for cryptographic use. Based on entropy pool design from *BSDs and uses BLAKE2Xs algorithm for CSPRNG output. Patch also adds /dev/urandom support for using entropy pool RNG and new 'getrandom' system call for getting randomness without file-descriptor usage (thus avoiding file-descriptor exhaustion attacks). The 'getrandom' interface is similar as 'getentropy' and 'getrandom' available on OpenBSD and Linux respectively.
This commit is contained in:
parent
21545ab643
commit
dffb8a67e3
50 changed files with 2005 additions and 9 deletions
|
|
@ -2015,6 +2015,27 @@ config BOARD_RESET_ON_CRASH
|
|||
If selected the board_crashdump should reset the machine after
|
||||
saveing the state of the machine
|
||||
|
||||
config BOARD_ENTROPY_POOL
|
||||
bool "Enable Board level storing of entropy pool structure"
|
||||
default n
|
||||
depends on CRYPTO_RANDOM_POOL
|
||||
---help---
|
||||
Entropy pool structure can be provided by board source.
|
||||
Use for this is, for example, to allocate entropy pool
|
||||
from special area of RAM which content is kept over
|
||||
system reset.
|
||||
|
||||
config BOARD_INITRNGSEED
|
||||
bool "Enable Board level initial seeding of entropy pool RNG"
|
||||
default n
|
||||
depends on CRYPTO_RANDOM_POOL
|
||||
---help---
|
||||
If enabled, entropy pool random number generator will call
|
||||
board_init_rndseed() upon initialization. This function
|
||||
can then provide early entropy seed to the pool through
|
||||
entropy injection APIs provided at 'nuttx/random.h'.
|
||||
#endif
|
||||
|
||||
config LIB_BOARDCTL
|
||||
bool "Enable boardctl() interface"
|
||||
default n
|
||||
|
|
|
|||
|
|
@ -50,4 +50,35 @@ config CRYPTO_SW_AES
|
|||
implemenations. This needs to support up_aesinitialize() and
|
||||
aes_cypher() per include/nuttx/crypto/crypto.h.
|
||||
|
||||
config CRYPTO_BLAKE2S
|
||||
bool "BLAKE2s hash algorithm"
|
||||
default n
|
||||
---help---
|
||||
Enable the BLAKE2s hash algorithm
|
||||
|
||||
config CRYPTO_RANDOM_POOL
|
||||
bool "Entropy pool and strong randon number generator"
|
||||
default n
|
||||
select CRYPTO_BLAKE2S
|
||||
---help---
|
||||
Entropy pool gathers environmental noise from device drivers,
|
||||
user-space, etc., and returns good random numbers, suitable
|
||||
for cryptographic use. Based on entropy pool design from
|
||||
*BSDs and uses BLAKE2Xs algorithm for CSPRNG output.
|
||||
|
||||
NOTE: May not actually be cyptographically secure, if
|
||||
not enough entropy is made available to the entropy pool.
|
||||
|
||||
if CRYPTO_RANDOM_POOL
|
||||
|
||||
config CRYPTO_RANDOM_POOL_COLLECT_IRQ_RANDOMNESS
|
||||
bool "Use interrupts to feed timing randomness to entropy pool"
|
||||
default y
|
||||
---help---
|
||||
Feed entropy pool with interrupt randomness from interrupt
|
||||
dispatch function 'irq_dispatch'. This adds some overhead
|
||||
for every interrupt handled.
|
||||
|
||||
endif # CRYPTO_RANDOM_POOL
|
||||
|
||||
endif # CRYPTO
|
||||
|
|
|
|||
|
|
@ -56,6 +56,18 @@ ifeq ($(CONFIG_CRYPTO_SW_AES),y)
|
|||
CRYPTO_CSRCS += aes.c
|
||||
endif
|
||||
|
||||
# BLAKE2s hash algorithm
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO_BLAKE2S),y)
|
||||
CRYPTO_CSRCS += blake2s.c
|
||||
endif
|
||||
|
||||
# Entropy pool random number generator
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO_RANDOM_POOL),y)
|
||||
CRYPTO_CSRCS += random_pool.c
|
||||
endif
|
||||
|
||||
endif # CONFIG_CRYPTO
|
||||
|
||||
ASRCS = $(CRYPTO_ASRCS)
|
||||
|
|
@ -97,4 +109,4 @@ distclean: clean
|
|||
$(call DELFILE, Make.dep)
|
||||
$(call DELFILE, .depend)
|
||||
|
||||
-include Make.dep
|
||||
-include Make.dep
|
||||
|
|
|
|||
606
crypto/blake2s.c
Normal file
606
crypto/blake2s.c
Normal file
|
|
@ -0,0 +1,606 @@
|
|||
/****************************************************************************
|
||||
* crypto/blake2s.c
|
||||
*
|
||||
* This code is based on public-domain/CC0 BLAKE2 reference implementation
|
||||
* by Samual Neves, at https://github.com/BLAKE2/BLAKE2/tree/master/ref
|
||||
* Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
|
||||
*
|
||||
* Copyright (C) 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name NuttX 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 THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <debug.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/crypto/blake2s.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const uint32_t blake2s_IV[8] =
|
||||
{
|
||||
0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful,
|
||||
0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
|
||||
};
|
||||
|
||||
static const uint8_t blake2s_sigma[10][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t rotr32(const uint32_t w, const unsigned int c)
|
||||
{
|
||||
return (w >> (c & 31)) | (w << ((32 - c) & 31));
|
||||
}
|
||||
|
||||
static void blake2_memcpy(FAR void *dst, FAR const void *src, size_t len)
|
||||
{
|
||||
#ifdef BLAKE2_UNALIGNED
|
||||
FAR uint32_alias_t *idst = dst;
|
||||
FAR const uint32_alias_t *isrc = src;
|
||||
FAR uint8_t *bdst;
|
||||
FAR const uint8_t *bsrc;
|
||||
|
||||
while (len >= sizeof(uint32_alias_t))
|
||||
{
|
||||
*idst = *isrc;
|
||||
idst++;
|
||||
isrc++;
|
||||
len -= sizeof(uint32_alias_t);
|
||||
}
|
||||
|
||||
bdst = (FAR uint8_t *)idst;
|
||||
bsrc = (FAR const uint8_t *)isrc;
|
||||
while (len)
|
||||
{
|
||||
*bdst = *bsrc;
|
||||
bdst++;
|
||||
bsrc++;
|
||||
len--;
|
||||
}
|
||||
#else
|
||||
memcpy(dst, set, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void blake2_memset(FAR void *dst, int set, size_t len)
|
||||
{
|
||||
#ifdef BLAKE2_UNALIGNED
|
||||
FAR uint32_alias_t *idst = dst;
|
||||
FAR uint8_t *bdst;
|
||||
uint32_t mset;
|
||||
|
||||
set &= 0xff;
|
||||
mset = (uint32_t)set * 0x01010101UL;
|
||||
|
||||
while (len >= sizeof(uint32_alias_t))
|
||||
{
|
||||
*idst = mset;
|
||||
idst++;
|
||||
len -= sizeof(uint32_alias_t);
|
||||
}
|
||||
|
||||
bdst = (FAR uint8_t *)idst;
|
||||
set &= 0xff;
|
||||
while (len)
|
||||
{
|
||||
*bdst = set;
|
||||
bdst++;
|
||||
len--;
|
||||
}
|
||||
#else
|
||||
memset(dst, set, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void secure_zero_memory(FAR void *v, size_t n)
|
||||
{
|
||||
explicit_bzero(v, n);
|
||||
}
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
|
||||
static int blake2s_is_lastblock(FAR const blake2s_state *S)
|
||||
{
|
||||
return S->f[0] != 0;
|
||||
}
|
||||
|
||||
static void blake2s_set_lastblock(FAR blake2s_state *S)
|
||||
{
|
||||
S->f[0] = (uint32_t)-1;
|
||||
}
|
||||
|
||||
static void blake2s_increment_counter(FAR blake2s_state *S, const uint32_t inc)
|
||||
{
|
||||
S->t[0] += inc;
|
||||
S->t[1] += (S->t[0] < inc);
|
||||
}
|
||||
|
||||
static void blake2s_init0(FAR blake2s_state *S)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
blake2_memset(S, 0, sizeof(*S) - sizeof(S->buf));
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
S->h[i] = blake2s_IV[i];
|
||||
}
|
||||
|
||||
static void blake2s_compress(FAR blake2s_state *S,
|
||||
const uint8_t in[BLAKE2S_BLOCKBYTES])
|
||||
{
|
||||
uint32_t m[16];
|
||||
uint32_t v[16];
|
||||
size_t i;
|
||||
unsigned int round;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
m[i] = blake2_load32(in + i * sizeof(m[i]));
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
v[i] = S->h[i];
|
||||
}
|
||||
|
||||
v[8] = blake2s_IV[0];
|
||||
v[9] = blake2s_IV[1];
|
||||
v[10] = blake2s_IV[2];
|
||||
v[11] = blake2s_IV[3];
|
||||
v[12] = S->t[0] ^ blake2s_IV[4];
|
||||
v[13] = S->t[1] ^ blake2s_IV[5];
|
||||
v[14] = S->f[0] ^ blake2s_IV[6];
|
||||
v[15] = S->f[1] ^ blake2s_IV[7];
|
||||
|
||||
#define G(r,i,a,b,c,d) \
|
||||
do { \
|
||||
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
|
||||
d = rotr32(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr32(b ^ c, 12); \
|
||||
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
|
||||
d = rotr32(d ^ a, 8); \
|
||||
c = c + d; \
|
||||
b = rotr32(b ^ c, 7); \
|
||||
} while(0)
|
||||
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
||||
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
||||
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
||||
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
||||
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
||||
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
||||
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
||||
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
||||
} while(0)
|
||||
|
||||
/* Size vs performance trade-off. With unrolling, on ARMv7-M function text
|
||||
* is ~4 KiB and without ~1 KiB. Without unrolling we take ~25% performance
|
||||
* hit. */
|
||||
|
||||
#if 1
|
||||
/* Smaller, slightly slower. */
|
||||
|
||||
for (round = 0; round < 10; round++)
|
||||
{
|
||||
ROUND(round);
|
||||
}
|
||||
#else
|
||||
/* Larger, slightly faster. */
|
||||
|
||||
(void)(round=0);
|
||||
ROUND(0);
|
||||
ROUND(1);
|
||||
ROUND(2);
|
||||
ROUND(3);
|
||||
ROUND(4);
|
||||
ROUND(5);
|
||||
ROUND(6);
|
||||
ROUND(7);
|
||||
ROUND(8);
|
||||
ROUND(9);
|
||||
#endif
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLAKE2_SELFTEST
|
||||
/* BLAKE2s self-test from RFC 7693 */
|
||||
|
||||
static void selftest_seq(FAR uint8_t *out, size_t len, uint32_t seed)
|
||||
{
|
||||
size_t i;
|
||||
uint32_t t, a, b;
|
||||
|
||||
a = 0xDEAD4BAD * seed; /* prime */
|
||||
b = 1;
|
||||
/* fill the buf */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
t = a + b;
|
||||
a = b;
|
||||
b = t;
|
||||
out[i] = (t >> 24) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
static int blake2s_selftest(void)
|
||||
{
|
||||
/* Grand hash of hash results. */
|
||||
|
||||
static const uint8_t blake2s_res[32] =
|
||||
{
|
||||
0x6a, 0x41, 0x1f, 0x08, 0xce, 0x25, 0xad, 0xcd, 0xfb, 0x02, 0xab, 0xa6,
|
||||
0x41, 0x45, 0x1c, 0xec, 0x53, 0xc5, 0x98, 0xb2, 0x4f, 0x4f, 0xc7, 0x87,
|
||||
0xfb, 0xdc, 0x88, 0x79, 0x7f, 0x4c, 0x1d, 0xfe
|
||||
};
|
||||
|
||||
/* Parameter sets. */
|
||||
|
||||
static const size_t b2s_md_len[4] = { 16, 20, 28, 32 };
|
||||
static const size_t b2s_in_len[6] = { 0, 3, 64, 65, 255, 1024 };
|
||||
size_t i, j, outlen, inlen;
|
||||
FAR uint8_t *in;
|
||||
uint8_t md[32], key[32];
|
||||
blake2s_state ctx;
|
||||
int ret = -1;
|
||||
|
||||
in = malloc(1024);
|
||||
if (!in)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 256-bit hash for testing. */
|
||||
|
||||
if (blake2s_init(&ctx, 32))
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
outlen = b2s_md_len[i];
|
||||
for (j = 0; j < 6; j++)
|
||||
{
|
||||
inlen = b2s_in_len[j];
|
||||
|
||||
selftest_seq(in, inlen, inlen); /* unkeyed hash */
|
||||
blake2s(md, outlen, in, inlen, NULL, 0);
|
||||
blake2s_update(&ctx, md, outlen); /* hash the hash */
|
||||
|
||||
selftest_seq(key, outlen, outlen); /* keyed hash */
|
||||
blake2s(md, outlen, in, inlen, key, outlen);
|
||||
blake2s_update(&ctx, md, outlen); /* hash the hash */
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute and compare the hash of hashes. */
|
||||
|
||||
blake2s_final(&ctx, md, 32);
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (md[i] != blake2s_res[i])
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
free(in);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* init2 xors IV with input parameter block */
|
||||
|
||||
int blake2s_init_param(FAR blake2s_state *S, FAR const blake2s_param *P)
|
||||
{
|
||||
FAR const unsigned char *p = (FAR const unsigned char *)(P);
|
||||
size_t i;
|
||||
#ifdef CONFIG_BLAKE2_SELFTEST
|
||||
static bool selftest_done = false;
|
||||
int ret;
|
||||
|
||||
if (!selftest_done)
|
||||
{
|
||||
selftest_done = true;
|
||||
ret = blake2s_selftest();
|
||||
DEBUGASSERT(ret == 0);
|
||||
if (ret)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
blake2s_init0(S);
|
||||
|
||||
/* IV XOR ParamBlock */
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
S->h[i] ^= blake2_load32(&p[i * 4]);
|
||||
}
|
||||
|
||||
S->outlen = P->digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sequential blake2s initialization */
|
||||
|
||||
int blake2s_init(FAR blake2s_state *S, size_t outlen)
|
||||
{
|
||||
blake2s_param P[1];
|
||||
|
||||
/* Move interval verification here? */
|
||||
|
||||
if ((!outlen) || (outlen > BLAKE2S_OUTBYTES))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
P->digest_length = (uint8_t)outlen;
|
||||
P->key_length = 0;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
blake2_store32(P->leaf_length, 0);
|
||||
blake2_store32(P->node_offset, 0);
|
||||
blake2_store16(P->xof_length, 0);
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
/* memset(P->reserved, 0, sizeof(P->reserved)); */
|
||||
blake2_memset(P->salt, 0, sizeof(P->salt));
|
||||
blake2_memset(P->personal, 0, sizeof(P->personal));
|
||||
return blake2s_init_param(S, P);
|
||||
}
|
||||
|
||||
int blake2s_init_key(FAR blake2s_state *S, size_t outlen, FAR const void *key,
|
||||
size_t keylen)
|
||||
{
|
||||
blake2s_param P[1];
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
|
||||
if ((!outlen) || (outlen > BLAKE2S_OUTBYTES))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!key || !keylen || keylen > BLAKE2S_KEYBYTES)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
P->digest_length = (uint8_t) outlen;
|
||||
P->key_length = (uint8_t) keylen;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
blake2_store32(P->leaf_length, 0);
|
||||
blake2_store32(P->node_offset, 0);
|
||||
blake2_store16(P->xof_length, 0);
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
/* memset(P->reserved, 0, sizeof(P->reserved)); */
|
||||
blake2_memset(P->salt, 0, sizeof(P->salt));
|
||||
blake2_memset(P->personal, 0, sizeof(P->personal));
|
||||
|
||||
blake2s_init_param(S, P);
|
||||
|
||||
blake2_memset(block, 0, BLAKE2S_BLOCKBYTES);
|
||||
blake2_memcpy(block, key, keylen);
|
||||
blake2s_update(S, block, BLAKE2S_BLOCKBYTES);
|
||||
secure_zero_memory(block, BLAKE2S_BLOCKBYTES); /* Burn the key from stack */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2s_update(FAR blake2s_state *S, FAR const void *pin, size_t inlen)
|
||||
{
|
||||
FAR const unsigned char * in = FAR (const unsigned char *)pin;
|
||||
size_t left, fill;
|
||||
|
||||
if (inlen <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
left = S->buflen;
|
||||
fill = BLAKE2S_BLOCKBYTES - left;
|
||||
if (inlen > fill)
|
||||
{
|
||||
S->buflen = 0;
|
||||
if (fill)
|
||||
{
|
||||
blake2_memcpy(S->buf + left, in, fill); /* Fill buffer */
|
||||
}
|
||||
|
||||
blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
|
||||
blake2s_compress(S, S->buf); /* Compress */
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
while (inlen > BLAKE2S_BLOCKBYTES)
|
||||
{
|
||||
blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
|
||||
blake2s_compress(S, in);
|
||||
in += BLAKE2S_BLOCKBYTES;
|
||||
inlen -= BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
|
||||
blake2_memcpy(S->buf + S->buflen, in, inlen);
|
||||
S->buflen += inlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2s_final(FAR blake2s_state *S, FAR void *out, size_t outlen)
|
||||
{
|
||||
FAR uint8_t *outbuf = out;
|
||||
uint32_t tmp = 0;
|
||||
size_t outwords;
|
||||
size_t padding;
|
||||
size_t i;
|
||||
|
||||
if (out == NULL || outlen < S->outlen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (blake2s_is_lastblock(S))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
blake2s_increment_counter(S, (uint32_t)S->buflen);
|
||||
blake2s_set_lastblock(S);
|
||||
padding = BLAKE2S_BLOCKBYTES - S->buflen;
|
||||
if (padding)
|
||||
{
|
||||
blake2_memset(S->buf + S->buflen, 0, padding);
|
||||
}
|
||||
blake2s_compress(S, S->buf);
|
||||
|
||||
/* Output hash to out buffer */
|
||||
|
||||
outwords = outlen / sizeof(uint32_t);
|
||||
outwords = (outwords < 8) ? outwords : 8;
|
||||
for (i = 0; i < outwords; ++i)
|
||||
{
|
||||
/* Store full words */
|
||||
|
||||
blake2_store32(outbuf, S->h[i]);
|
||||
outlen -= sizeof(uint32_t);
|
||||
outbuf += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
if (outwords < 8 && outlen > 0 && outlen < sizeof(uint32_t))
|
||||
{
|
||||
/* Store partial word */
|
||||
|
||||
blake2_store32(&tmp, S->h[i]);
|
||||
blake2_memcpy(outbuf, &tmp, outlen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2s(FAR void *out, size_t outlen, FAR const void *in, size_t inlen,
|
||||
FAR const void *key, size_t keylen)
|
||||
{
|
||||
blake2s_state S[1];
|
||||
|
||||
/* Verify parameters */
|
||||
|
||||
if (NULL == in && inlen > 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == out)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == key && keylen > 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!outlen || outlen > BLAKE2S_OUTBYTES)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (keylen > BLAKE2S_KEYBYTES)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (keylen > 0)
|
||||
{
|
||||
if (blake2s_init_key(S, outlen, key, keylen) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (blake2s_init(S, outlen) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
blake2s_update(S, (const uint8_t *)in, inlen);
|
||||
blake2s_final(S, out, outlen);
|
||||
return 0;
|
||||
}
|
||||
561
crypto/random_pool.c
Normal file
561
crypto/random_pool.c
Normal file
|
|
@ -0,0 +1,561 @@
|
|||
/****************************************************************************
|
||||
* crypto/random_pool.c
|
||||
*
|
||||
* Copyright (C) 2015-2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Juha Niskanen <juha.niskanen@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name NuttX 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 THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <debug.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/random.h>
|
||||
#include <nuttx/board.h>
|
||||
|
||||
#include <nuttx/crypto/blake2s.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define ROTL_32(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
|
||||
#define ROTR_32(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct blake2xs_rng_s
|
||||
{
|
||||
uint32_t out_node_offset;
|
||||
blake2s_param param;
|
||||
blake2s_state ctx;
|
||||
char out_root[BLAKE2S_OUTBYTES];
|
||||
};
|
||||
|
||||
struct rng_s
|
||||
{
|
||||
sem_t rd_sem; /* Threads can only exclusively access the RNG */
|
||||
volatile uint32_t rd_addptr;
|
||||
volatile uint32_t rd_newentr;
|
||||
volatile uint8_t rd_rotate;
|
||||
volatile uint8_t rd_prev_time;
|
||||
volatile uint16_t rd_prev_irq;
|
||||
bool output_initialized;
|
||||
struct blake2xs_rng_s blake2xs;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
POOL_SIZE = ENTROPY_POOL_SIZE,
|
||||
POOL_MASK = (POOL_SIZE - 1),
|
||||
|
||||
MIN_SEED_NEW_ENTROPY_WORDS = 128,
|
||||
MAX_SEED_NEW_ENTROPY_WORDS = 1024
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct rng_s g_rng;
|
||||
|
||||
#ifdef CONFIG_BOARD_ENTROPY_POOL
|
||||
/* Entropy pool structure can be provided by board source. Use for this is,
|
||||
* for example, allocate entropy pool from special area of RAM which content
|
||||
* is kept over system reset. */
|
||||
|
||||
# define entropy_pool board_entropy_pool
|
||||
#else
|
||||
static struct entropy_pool_s entropy_pool;
|
||||
#endif
|
||||
|
||||
/* Polynomial from paper "The Linux Pseudorandom Number Generator Revisited"
|
||||
* x^POOL_SIZE + x^104 + x^76 + x^51 + x^25 + x + 1 */
|
||||
|
||||
static const uint32_t pool_stir[] = { POOL_SIZE, 104, 76, 51, 25, 1 };
|
||||
|
||||
/* Derived from IEEE 802.3 CRC-32 */
|
||||
|
||||
static const uint32_t pool_twist[8] =
|
||||
{
|
||||
0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
|
||||
0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: addentropy
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function adds a number of integers into the entropy pool.
|
||||
* The pool is stirred with a polynomial of degree POOL_SIZE over GF(2).
|
||||
*
|
||||
* Code is inspired by add_entropy_words() function of OpenBSD kernel.
|
||||
*
|
||||
* Parameters:
|
||||
* buf - Buffer of integers to be added
|
||||
* n - Number of elements in buf
|
||||
* inc_new - Count element as new entry
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void addentropy(FAR const uint32_t *buf, size_t n, bool inc_new)
|
||||
{
|
||||
/* Compile time check for that POOL_SIZE is power of two. */
|
||||
|
||||
static char pool_size_p2_check[1 - ((POOL_SIZE & (POOL_SIZE - 1)) * 2)];
|
||||
|
||||
UNUSED(pool_size_p2_check);
|
||||
|
||||
while (n-- > 0)
|
||||
{
|
||||
uint32_t rotate;
|
||||
uint32_t w;
|
||||
uint32_t i;
|
||||
|
||||
rotate = g_rng.rd_rotate;
|
||||
w = ROTL_32(*buf, rotate);
|
||||
i = g_rng.rd_addptr = (g_rng.rd_addptr - 1) & POOL_MASK;
|
||||
|
||||
/* Normal round, we add 7 bits of rotation to the pool.
|
||||
* At the beginning of the pool, we add extra 7 bits
|
||||
* rotation, in order for successive passes spread the
|
||||
* input bits across the pool evenly.
|
||||
*/
|
||||
|
||||
g_rng.rd_rotate = (rotate + (i ? 7 : 14)) & 31;
|
||||
|
||||
/* XOR pool contents corresponding to polynomial terms */
|
||||
|
||||
w ^= entropy_pool.pool[(i + pool_stir[1]) & POOL_MASK];
|
||||
w ^= entropy_pool.pool[(i + pool_stir[2]) & POOL_MASK];
|
||||
w ^= entropy_pool.pool[(i + pool_stir[3]) & POOL_MASK];
|
||||
w ^= entropy_pool.pool[(i + pool_stir[4]) & POOL_MASK];
|
||||
w ^= entropy_pool.pool[(i + pool_stir[5]) & POOL_MASK];
|
||||
w ^= entropy_pool.pool[i]; /* 2^POOL_SIZE */
|
||||
|
||||
entropy_pool.pool[i] = (w >> 3) ^ pool_twist[w & 7];
|
||||
buf++;
|
||||
|
||||
if (inc_new)
|
||||
{
|
||||
g_rng.rd_newentr += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: getentropy
|
||||
*
|
||||
* Description:
|
||||
* Hash entropy pool to BLAKE2s context. This is an internal interface for
|
||||
* seeding out-facing BLAKE2Xs random bit generator from entropy pool.
|
||||
*
|
||||
* Code is inspired by extract_entropy() function of OpenBSD kernel.
|
||||
*
|
||||
* Note that this function cannot fail, other than by asserting.
|
||||
*
|
||||
* Warning: In protected kernel builds, this interface MUST NOT be
|
||||
* exported to userspace. This interface MUST NOT be used as a
|
||||
* general-purpose random bit generator!
|
||||
*
|
||||
* Parameters:
|
||||
* S - BLAKE2s instance that will absorb entropy pool
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void getentropy(FAR blake2s_state *S)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_CPULOAD
|
||||
struct cpuload_s load;
|
||||
#endif
|
||||
uint32_t tmp;
|
||||
|
||||
add_sw_randomness(g_rng.rd_newentr);
|
||||
|
||||
/* Absorb the entropy pool */
|
||||
|
||||
blake2s_update(S, (FAR const uint32_t *)entropy_pool.pool,
|
||||
sizeof(entropy_pool.pool));
|
||||
|
||||
/* Add something back so repeated calls to this function
|
||||
* return different values.
|
||||
*/
|
||||
|
||||
tmp = sizeof(entropy_pool.pool);
|
||||
tmp <<= 27;
|
||||
#ifdef CONFIG_SCHED_CPULOAD
|
||||
clock_cpuload(0, &load);
|
||||
tmp += load.total ^ ROTL_32(load.active, 23);
|
||||
#endif
|
||||
add_sw_randomness(tmp);
|
||||
|
||||
g_rng.rd_newentr = 0;
|
||||
}
|
||||
|
||||
/* The BLAKE2Xs based random number generator algorithm.
|
||||
*
|
||||
* BLAKE2X is a extensible-output function (XOF) variant of BLAKE2 hash
|
||||
* function. One application of XOFs is use as deterministic random bit
|
||||
* number generator (DRBG) as used here. BLAKE2 specification is available
|
||||
* at https://blake2.net/
|
||||
*
|
||||
* BLAKE2Xs here implementation is based on public-domain/CC0 BLAKE2 reference
|
||||
* implementation by Samual Neves, at
|
||||
* https://github.com/BLAKE2/BLAKE2/tree/master/ref
|
||||
* Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
|
||||
*/
|
||||
|
||||
static void rng_reseed(void)
|
||||
{
|
||||
blake2s_param P = {};
|
||||
|
||||
/* Reset output node counter. */
|
||||
|
||||
g_rng.blake2xs.out_node_offset = 0;
|
||||
|
||||
/* Initialize parameter block */
|
||||
|
||||
P.digest_length = BLAKE2S_OUTBYTES;
|
||||
P.key_length = 0;
|
||||
P.fanout = 1;
|
||||
P.depth = 1;
|
||||
blake2_store32(P.leaf_length, 0);
|
||||
blake2_store32(P.node_offset, 0);
|
||||
blake2_store16(P.xof_length, 0xffff);
|
||||
P.node_depth = 0;
|
||||
P.inner_length = 0;
|
||||
g_rng.blake2xs.param = P;
|
||||
|
||||
blake2s_init_param(&g_rng.blake2xs.ctx, &g_rng.blake2xs.param);
|
||||
|
||||
/* Initialize with randomness from entropy pool */
|
||||
|
||||
getentropy(&g_rng.blake2xs.ctx);
|
||||
|
||||
/* Absorb also the previous root */
|
||||
|
||||
blake2s_update(&g_rng.blake2xs.ctx, g_rng.blake2xs.out_root,
|
||||
sizeof(g_rng.blake2xs.out_root));
|
||||
|
||||
/* Finalize the new root hash */
|
||||
|
||||
blake2s_final(&g_rng.blake2xs.ctx, g_rng.blake2xs.out_root,
|
||||
BLAKE2S_OUTBYTES);
|
||||
|
||||
explicit_bzero(&g_rng.blake2xs.ctx, sizeof(g_rng.blake2xs.ctx));
|
||||
|
||||
/* Setup parameters for output phase. */
|
||||
|
||||
g_rng.blake2xs.param.key_length = 0;
|
||||
g_rng.blake2xs.param.fanout = 0;
|
||||
blake2_store32(g_rng.blake2xs.param.leaf_length, BLAKE2S_OUTBYTES);
|
||||
g_rng.blake2xs.param.inner_length = BLAKE2S_OUTBYTES;
|
||||
g_rng.blake2xs.param.node_depth = 0;
|
||||
|
||||
g_rng.output_initialized = true;
|
||||
}
|
||||
|
||||
static void rng_buf_internal(FAR void *bytes, size_t nbytes)
|
||||
{
|
||||
if (!g_rng.output_initialized)
|
||||
{
|
||||
if (g_rng.rd_newentr < MIN_SEED_NEW_ENTROPY_WORDS)
|
||||
{
|
||||
cryptwarn("Entropy pool RNG initialized with very low entropy. "
|
||||
" Consider implementing CONFIG_BOARD_INITRNGSEED!\n");
|
||||
}
|
||||
|
||||
rng_reseed();
|
||||
}
|
||||
else if (g_rng.rd_newentr >= MAX_SEED_NEW_ENTROPY_WORDS)
|
||||
{
|
||||
/* Initial entropy is low. Reseed when we have accumulated more. */
|
||||
|
||||
rng_reseed();
|
||||
}
|
||||
else if (g_rng.blake2xs.out_node_offset == UINT32_MAX)
|
||||
{
|
||||
/* Maximum BLAKE2Xs output reached (2^32-1 output blocks, maximum 128 GiB
|
||||
* bytes), reseed. */
|
||||
|
||||
rng_reseed();
|
||||
}
|
||||
|
||||
/* Output phase for BLAKE2Xs. */
|
||||
|
||||
for (; nbytes > 0; ++g_rng.blake2xs.out_node_offset)
|
||||
{
|
||||
size_t block_size = MIN(nbytes, BLAKE2S_OUTBYTES);
|
||||
|
||||
/* Initialize state */
|
||||
|
||||
g_rng.blake2xs.param.digest_length = block_size;
|
||||
blake2_store32(g_rng.blake2xs.param.node_offset,
|
||||
g_rng.blake2xs.out_node_offset);
|
||||
blake2s_init_param(&g_rng.blake2xs.ctx, &g_rng.blake2xs.param);
|
||||
|
||||
/* Process state and output random bytes */
|
||||
|
||||
blake2s_update(&g_rng.blake2xs.ctx, g_rng.blake2xs.out_root,
|
||||
sizeof(g_rng.blake2xs.out_root));
|
||||
blake2s_final(&g_rng.blake2xs.ctx, bytes, block_size);
|
||||
|
||||
bytes += block_size;
|
||||
nbytes -= block_size;
|
||||
}
|
||||
}
|
||||
|
||||
static void rng_init(void)
|
||||
{
|
||||
crypinfo("Initializing RNG\n");
|
||||
|
||||
memset(&g_rng, 0, sizeof(struct rng_s));
|
||||
sem_init(&g_rng.rd_sem, 0, 1);
|
||||
|
||||
/* We do not initialize output here because this is called
|
||||
* quite early in boot and there may not be enough entropy.
|
||||
*
|
||||
* Board level may define CONFIG_BOARD_INITRNGSEED if it implements
|
||||
* early random seeding.
|
||||
*/
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_rngaddint
|
||||
*
|
||||
* Description:
|
||||
* Add one integer to entropy pool, contributing a specific kind
|
||||
* of entropy to pool.
|
||||
*
|
||||
* Parameters:
|
||||
* kindof - Enumeration constant telling where val came from
|
||||
* val - Integer to be added
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_rngaddint(enum rnd_source_t kindof, int val)
|
||||
{
|
||||
uint32_t buf[1];
|
||||
|
||||
buf[0] = val;
|
||||
|
||||
up_rngaddentropy(kindof, buf, 1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_rngaddentropy
|
||||
*
|
||||
* Description:
|
||||
* Add buffer of integers to entropy pool.
|
||||
*
|
||||
* Parameters:
|
||||
* kindof - Enumeration constant telling where val came from
|
||||
* buf - Buffer of integers to be added
|
||||
* n - Number of elements in buf
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_rngaddentropy(enum rnd_source_t kindof, FAR const uint32_t *buf,
|
||||
size_t n)
|
||||
{
|
||||
uint32_t tbuf[1];
|
||||
struct timespec ts;
|
||||
bool new_inc = true;
|
||||
|
||||
if (kindof == RND_SRC_IRQ && n > 0)
|
||||
{
|
||||
/* Ignore interrupt randomness if previous interrupt was from same
|
||||
* source. */
|
||||
|
||||
if (buf[0] == g_rng.rd_prev_irq)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_rng.rd_prev_irq = buf[0];
|
||||
}
|
||||
|
||||
/* We don't actually track what kind of entropy we receive,
|
||||
* just add it all to pool. One exception is interrupt
|
||||
* and timer randomness, where we limit rate of new pool entry
|
||||
* counting to prevent high interrupt rate triggering RNG
|
||||
* reseeding too fast.
|
||||
*/
|
||||
|
||||
(void)clock_gettime(CLOCK_REALTIME, &ts);
|
||||
tbuf[0] = ROTL_32(ts.tv_nsec, 17) ^ ROTL_32(ts.tv_sec, 3);
|
||||
tbuf[0] += ROTL_32(kindof, 27);
|
||||
tbuf[0] += ROTL_32((uintptr_t)&tbuf[0], 11);
|
||||
|
||||
if (kindof == RND_SRC_TIME || kindof == RND_SRC_IRQ)
|
||||
{
|
||||
uint8_t curr_time = ts.tv_sec * 8 + ts.tv_nsec / (NSEC_PER_SEC / 8);
|
||||
|
||||
/* Allow interrupts/timers increase entropy counter at max rate
|
||||
* of 8 Hz. */
|
||||
|
||||
if (g_rng.rd_prev_time == curr_time)
|
||||
{
|
||||
new_inc = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_rng.rd_prev_time = curr_time;
|
||||
}
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
tbuf[0] ^= buf[0];
|
||||
buf++;
|
||||
n--;
|
||||
}
|
||||
|
||||
addentropy(tbuf, 1, new_inc);
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
addentropy(buf, n, new_inc);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_rngreseed
|
||||
*
|
||||
* Description:
|
||||
* Force reseeding random number generator from entropy pool
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_rngreseed(void)
|
||||
{
|
||||
while (sem_wait(&g_rng.rd_sem) != 0)
|
||||
{
|
||||
assert(errno == EINTR);
|
||||
}
|
||||
|
||||
if (g_rng.rd_newentr >= MIN_SEED_NEW_ENTROPY_WORDS)
|
||||
{
|
||||
rng_reseed();
|
||||
}
|
||||
|
||||
sem_post(&g_rng.rd_sem);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_randompool_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize entropy pool and random number generator
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_randompool_initialize(void)
|
||||
{
|
||||
rng_init();
|
||||
|
||||
#ifdef CONFIG_BOARD_INITRNGSEED
|
||||
board_init_rngseed();
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: getrandom
|
||||
*
|
||||
* Description:
|
||||
* Fill a buffer of arbitrary length with randomness. This is the
|
||||
* preferred interface for getting random numbers. The traditional
|
||||
* /dev/random approach is susceptible for things like the attacker
|
||||
* exhausting file descriptors on purpose.
|
||||
*
|
||||
* Note that this function cannot fail, other than by asserting.
|
||||
*
|
||||
* Parameters:
|
||||
* bytes - Buffer for returned random bytes
|
||||
* nbytes - Number of bytes requested.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void getrandom(FAR void *bytes, size_t nbytes)
|
||||
{
|
||||
while (sem_wait(&g_rng.rd_sem) != 0)
|
||||
{
|
||||
assert(errno == EINTR);
|
||||
}
|
||||
|
||||
rng_buf_internal(bytes, nbytes);
|
||||
sem_post(&g_rng.rd_sem);
|
||||
}
|
||||
|
|
@ -69,6 +69,15 @@ config DEV_URANDOM_CONGRUENTIAL
|
|||
|
||||
NOTE: Not cyptographically secure
|
||||
|
||||
config DEV_URANDOM_RANDOM_POOL
|
||||
bool "Entropy pool"
|
||||
depends on CRYPTO_RANDOM_POOL
|
||||
---help---
|
||||
Use the entropy pool CPRNG output for urandom algorithm.
|
||||
|
||||
NOTE: May or may not be cyptographically secure, depending upon the
|
||||
quality entropy available to entropy pool.
|
||||
|
||||
config DEV_URANDOM_ARCH
|
||||
bool "Architecture-specific"
|
||||
depends on ARCH_HAVE_RNG
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include <nuttx/arch.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/analog/adc.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
|
|
@ -296,6 +297,10 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Feed ADC data to entropy pool */
|
||||
|
||||
add_sensor_randomness(msg->am_data);
|
||||
|
||||
/* Copy the message to the user buffer */
|
||||
|
||||
if (msglen == 1)
|
||||
|
|
|
|||
|
|
@ -49,11 +49,13 @@
|
|||
#include <string.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/lib/lib.h>
|
||||
#include <nuttx/lib/xorshift128.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/drivers/drivers.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_DEV_URANDOM) && !defined(CONFIG_DEV_URANDOM_ARCH)
|
||||
|
||||
|
|
@ -62,13 +64,18 @@
|
|||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_DEV_URANDOM_CONGRUENTIAL) && \
|
||||
!defined(CONFIG_DEV_URANDOM_XORSHIFT128)
|
||||
# define CONFIG_DEV_URANDOM_XORSHIFT128 1
|
||||
!defined(CONFIG_DEV_URANDOM_XORSHIFT128) && \
|
||||
!defined(CONFIG_DEV_URANDOM_RANDOM_POOL)
|
||||
# ifdef CONFIG_CRYPTO_RANDOM_POOL
|
||||
# define CONFIG_DEV_URANDOM_RANDOM_POOL 1
|
||||
# else
|
||||
# define CONFIG_DEV_URANDOM_XORSHIFT128 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEV_URANDOM_XORSHIFT128
|
||||
# define PRNG() do_xorshift128()
|
||||
#else /* CONFIG_DEV_URANDOM_CONGRUENTIAL */
|
||||
#elif defined(CONFIG_DEV_URANDOM_CONGRUENTIAL)
|
||||
# define PRNG() do_congruential()
|
||||
#endif
|
||||
|
||||
|
|
@ -158,6 +165,12 @@ static inline uint32_t do_congruential(void)
|
|||
static ssize_t devurand_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
#ifdef CONFIG_DEV_URANDOM_RANDOM_POOL
|
||||
if (len)
|
||||
{
|
||||
getrandom(buffer, len);
|
||||
}
|
||||
#else
|
||||
size_t n;
|
||||
uint32_t rnd;
|
||||
|
||||
|
|
@ -208,6 +221,7 @@ static ssize_t devurand_read(FAR struct file *filep, FAR char *buffer,
|
|||
}
|
||||
while (--n > 0);
|
||||
}
|
||||
#endif /* CONFIG_DEV_URANDOM_RANDOM_POOL */
|
||||
|
||||
return len;
|
||||
}
|
||||
|
|
@ -228,6 +242,56 @@ static ssize_t devurand_write(FAR struct file *filep, FAR const char *buffer,
|
|||
memcpy(&seed, buffer, len);
|
||||
srand(seed);
|
||||
return len;
|
||||
#elif defined(CONFIG_DEV_URANDOM_RANDOM_POOL)
|
||||
const unsigned int alignmask = sizeof(uint32_t) - 1;
|
||||
const size_t initlen = len;
|
||||
uint32_t tmp = 0;
|
||||
size_t currlen;
|
||||
|
||||
if (!len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Seed entropy pool with data from user. */
|
||||
|
||||
if ((uintptr_t)buffer & alignmask)
|
||||
{
|
||||
/* Make unaligned input aligned. */
|
||||
|
||||
currlen = min(sizeof(uint32_t) - ((uintptr_t)buffer & alignmask), len);
|
||||
memcpy(&tmp, buffer, currlen);
|
||||
up_rngaddint(RND_SRC_SW, tmp);
|
||||
|
||||
len -= currlen;
|
||||
buffer += currlen;
|
||||
}
|
||||
|
||||
if (len >= sizeof(uint32_t))
|
||||
{
|
||||
/* Handle bulk aligned, word-sized data. */
|
||||
|
||||
DEBUGASSERT(((uintptr_t)buffer & alignmask) == 0);
|
||||
currlen = len / sizeof(uint32_t);
|
||||
up_rngaddentropy(RND_SRC_SW, (FAR uint32_t *)buffer, currlen);
|
||||
buffer += currlen * sizeof(uint32_t);
|
||||
len %= sizeof(uint32_t);
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
/* Handle trailing bytes. */
|
||||
|
||||
DEBUGASSERT(len < sizeof(uint32_t));
|
||||
memcpy(&tmp, buffer, len);
|
||||
up_rngaddint(RND_SRC_SW, tmp);
|
||||
}
|
||||
|
||||
/* Reseeding of random number generator from entropy pool. */
|
||||
|
||||
up_rngreseed();
|
||||
|
||||
return initlen;
|
||||
#else
|
||||
len = min(len, sizeof(g_prng.u));
|
||||
memcpy(&g_prng.u, buffer, len);
|
||||
|
|
@ -274,6 +338,8 @@ void devurandom_register(void)
|
|||
|
||||
#ifdef CONFIG_DEV_URANDOM_CONGRUENTIAL
|
||||
srand(10197);
|
||||
#elif defined(CONFIG_DEV_URANDOM_RANDOM_POOL)
|
||||
up_randompool_initialize();
|
||||
#else
|
||||
g_prng.state.w = 97;
|
||||
g_prng.state.x = 101;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/input/touchscreen.h>
|
||||
|
|
@ -624,6 +625,8 @@ static void ads7843e_worker(FAR void *arg)
|
|||
y = ads7843e_sendcmd(priv, ADS7843_CMD_YPOSITION);
|
||||
#endif
|
||||
|
||||
add_ui_randomness((x << 16) | y);
|
||||
|
||||
/* Perform a thresholding operation so that the results will be more stable.
|
||||
* If the difference from the last sample is small, then ignore the event.
|
||||
* REVISIT: Should a large change in pressure also generate a event?
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/input/ajoystick.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
|
|
@ -321,6 +322,8 @@ static void ajoy_sample(FAR struct ajoy_upperhalf_s *priv)
|
|||
DEBUGASSERT(lower->al_buttons);
|
||||
sample = lower->al_buttons(lower);
|
||||
|
||||
add_ui_randomness(sample);
|
||||
|
||||
#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS)
|
||||
/* Determine which buttons have been newly pressed and which have been
|
||||
* newly released.
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/input/buttons.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
|
|
@ -317,6 +318,8 @@ static void btn_sample(FAR struct btn_upperhalf_s *priv)
|
|||
DEBUGASSERT(lower->bl_buttons);
|
||||
sample = lower->bl_buttons(lower);
|
||||
|
||||
add_ui_randomness(sample);
|
||||
|
||||
#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS)
|
||||
/* Determine which buttons have been newly pressed and which have been
|
||||
* newly released.
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/input/djoystick.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
|
|
@ -321,6 +322,8 @@ static void djoy_sample(FAR struct djoy_upperhalf_s *priv)
|
|||
DEBUGASSERT(lower->dl_sample);
|
||||
sample = lower->dl_sample(lower);
|
||||
|
||||
add_ui_randomness(sample);
|
||||
|
||||
#if !defined(CONFIG_DISABLE_POLL) || !defined(CONFIG_DISABLE_SIGNALS)
|
||||
/* Determine which buttons have been newly pressed and which have been
|
||||
* newly released.
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/input/touchscreen.h>
|
||||
|
|
@ -628,6 +629,8 @@ static void max11802_worker(FAR void *arg)
|
|||
}
|
||||
while (readycount < 2);
|
||||
|
||||
add_ui_randomness((x << 16) | y);
|
||||
|
||||
/* Continue to sample the position while the pen is down */
|
||||
|
||||
wd_start(priv->wdog, MAX11802_WDOG_DELAY, max11802_wdog, 1,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/input/touchscreen.h>
|
||||
|
|
@ -889,6 +890,8 @@ static void mxt_touch_event(FAR struct mxt_dev_s *priv,
|
|||
sample->pressure = pressure;
|
||||
sample->valid = true;
|
||||
|
||||
add_ui_randomness((x << 16) ^ y ^ (area << 9) ^ (pressure << 1));
|
||||
|
||||
/* If this is not the first touch report, then report it as a move:
|
||||
* Same contact, same ID, but with a new, updated position.
|
||||
* The CONTACT_REPORT state means that a contacted has been detected,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include <debug.h>
|
||||
|
||||
#include <nuttx/input/stmpe811.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include "stmpe811.h"
|
||||
|
||||
|
|
@ -139,6 +140,8 @@ uint16_t stmpe811_tempread(STMPE811_HANDLE handle)
|
|||
temp1 = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
|
||||
temp2 = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2+1);
|
||||
|
||||
add_sensor_randomness((temp1 << 8) | temp2);
|
||||
|
||||
/* Scale the temperature (where Vio is assumed to be .33) */
|
||||
|
||||
temp = ((uint32_t)(temp1 & 3) << 8) | temp2;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/input/touchscreen.h>
|
||||
|
|
@ -534,6 +535,8 @@ static ssize_t stmpe811_read(FAR struct file *filep, FAR char *buffer, size_t le
|
|||
report->point[0].y = sample.y;
|
||||
report->point[0].pressure = sample.z;
|
||||
|
||||
add_ui_randomness((sample.x << 16) ^ (sample.y << 8) ^ sample.z);
|
||||
|
||||
/* Report the appropriate flags */
|
||||
|
||||
if (sample.contact == CONTACT_UP)
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/input/touchscreen.h>
|
||||
#include <nuttx/input/tsc2007.h>
|
||||
|
|
@ -619,7 +620,7 @@ static void tsc2007_worker(FAR void *arg)
|
|||
* vertical or horizontal resistive network. The A/D converter converts
|
||||
* the voltage measured at the point where the panel is touched. A measurement
|
||||
* of the Y position of the pointing device is made by connecting the X+
|
||||
* input to a data converter chip, turning on the Y+ and Y– drivers, and
|
||||
* input to a data converter chip, turning on the Y+ and Y- drivers, and
|
||||
* digitizing the voltage seen at the X+ input ..."
|
||||
*
|
||||
* "... it is recommended that whenever the host writes to the TSC2007, the
|
||||
|
|
@ -698,6 +699,8 @@ static void tsc2007_worker(FAR void *arg)
|
|||
priv->sample.y = y;
|
||||
priv->sample.pressure = pressure;
|
||||
priv->sample.valid = true;
|
||||
|
||||
add_ui_randomness((x << 16) ^ y ^ (pressure << 9));
|
||||
}
|
||||
|
||||
/* Note the availability of new measurements */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/sensors/adxl345.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include "adxl345.h"
|
||||
|
||||
|
|
@ -165,6 +166,9 @@ static ssize_t adxl345_read(FAR struct file *filep, FAR char *buffer, size_t len
|
|||
sample.data_z = adxl345_getreg8(priv, ADXL345_DATAZ1);
|
||||
sample.data_z = (sample.data_z << 8) | adxl345_getreg8(priv, ADXL345_DATAZ0);
|
||||
|
||||
add_sensor_randomness(sample.data_x);
|
||||
add_sensor_randomness((sample.data_z << 16) | sample.data_y);
|
||||
|
||||
/* Return read sample */
|
||||
|
||||
buffer = (FAR char *) &sample;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/bh1750fvi.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_BH1750FVI)
|
||||
|
||||
|
|
@ -250,6 +251,8 @@ static ssize_t bh1750fvi_read(FAR struct file *filep, FAR char *buffer,
|
|||
buffer[0] = lux & 0xFF;
|
||||
buffer[1] = (lux & 0xFF00) >> 8;
|
||||
|
||||
add_sensor_randomness(lux);
|
||||
|
||||
return buflen;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/sensors/bmg160.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_SPI) && defined(CONFIG_BMG160)
|
||||
|
||||
|
|
@ -243,6 +244,10 @@ static void bmg160_read_measurement_data(FAR struct bmg160_dev_s *dev)
|
|||
/* Give back the semaphore */
|
||||
|
||||
sem_post(&dev->datasem);
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((x_gyr << 16) ^ (y_gyr << 8) ^ z_gyr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/bmp180.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_BMP180)
|
||||
|
||||
|
|
@ -464,6 +465,10 @@ static int bmp180_getpressure(FAR struct bmp180_dev_s *priv)
|
|||
|
||||
bmp180_read_press_temp(priv);
|
||||
|
||||
/* Feed raw sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((priv->bmp180_utemp << 16) ^ priv->bmp180_upress);
|
||||
|
||||
/* Calculate true temperature */
|
||||
|
||||
x1 = ((priv->bmp180_utemp - priv->bmp180_cal_ac6) * priv->bmp180_cal_ac5) >> 15;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/kxtj9.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_SENSOR_KXTJ9)
|
||||
|
||||
|
|
@ -459,6 +460,12 @@ static int kxtj9_read_sensor_data(FAR struct kxtj9_dev_s *priv,
|
|||
|
||||
kxtj9_reg_read(priv, INT_REL, &data, 1);
|
||||
sem_post(&priv->exclsem);
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((acc_data[0] << 16) ^ (acc_data[1] << 8) ^
|
||||
acc_data[2]);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
|
|
@ -257,6 +258,10 @@ static void l3gd20_read_measurement_data(FAR struct l3gd20_dev_s *dev)
|
|||
/* Give back the semaphore */
|
||||
|
||||
sem_post(&dev->datasem);
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((x_gyr << 16) ^ (y_gyr << 8) ^ (z_gyr << 0));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/lis331dl.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_LIS331DL)
|
||||
|
||||
|
|
@ -414,6 +415,11 @@ lis331dl_getreadings(FAR struct lis331dl_dev_s * dev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((retval[2] << 16) ^ (retval[4] << 8) ^
|
||||
(retval[6] << 0));
|
||||
|
||||
dev->a.x = retval[2];
|
||||
dev->a.y = retval[4];
|
||||
dev->a.z = retval[6];
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/sensors/lis3dsh.h>
|
||||
|
|
@ -245,6 +246,10 @@ static void lis3dsh_read_measurement_data(FAR struct lis3dsh_dev_s *dev)
|
|||
/* Give back the semaphore */
|
||||
|
||||
sem_post(&dev->datasem);
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((x_acc << 16) ^ (y_acc << 8) ^ (z_acc << 0));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/sensors/lis3mdl.h>
|
||||
|
|
@ -251,6 +252,11 @@ static void lis3mdl_read_measurement_data(FAR struct lis3mdl_dev_s *dev)
|
|||
/* Give back the semaphore */
|
||||
|
||||
sem_post(&dev->datasem);
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((x_mag << 16) ^ (y_mag << 10) ^ (z_mag << 2) ^
|
||||
temperature);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/lm75.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_I2C_LM75)
|
||||
|
||||
|
|
@ -269,6 +270,8 @@ static int lm75_readtemp(FAR struct lm75_dev_s *priv, FAR b16_t *temp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
add_sensor_randomness(temp16);
|
||||
|
||||
sninfo("Centigrade: %08x\n", temp16);
|
||||
|
||||
/* Was fahrenheit requested? */
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/lm92.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_LM92)
|
||||
|
||||
|
|
@ -272,6 +273,8 @@ static int lm92_readtemp(FAR struct lm92_dev_s *priv, FAR b16_t *temp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
add_sensor_randomness(temp16);
|
||||
|
||||
sninfo("Centigrade: %08x\n", temp16);
|
||||
|
||||
/* Was Fahrenheit requested? */
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/lsm9ds1.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_SN_LSM9DS1)
|
||||
|
||||
|
|
@ -1244,6 +1245,7 @@ static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer,
|
|||
uint8_t regaddr;
|
||||
uint8_t lo;
|
||||
uint8_t hi;
|
||||
uint32_t merge = 0;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
|
|
@ -1301,6 +1303,10 @@ static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer,
|
|||
|
||||
data = ((uint16_t)hi << 8) | (uint16_t)lo;
|
||||
|
||||
/* Collect entropy */
|
||||
|
||||
merge += data ^ (merge >> 16);
|
||||
|
||||
/* The value is positive */
|
||||
|
||||
if (data < 0x8000)
|
||||
|
|
@ -1329,6 +1335,10 @@ static ssize_t lsm9ds1_read(FAR struct file *filep, FAR char *buffer,
|
|||
}
|
||||
}
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness(merge);
|
||||
|
||||
return nsamples * samplesize;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/sensors/max31855.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_SPI) && defined(CONFIG_MAX31855)
|
||||
|
||||
|
|
@ -220,6 +221,10 @@ static ssize_t max31855_read(FAR struct file *filep, FAR char *buffer, size_t bu
|
|||
|
||||
sninfo("Read from MAX31855 = 0x%08X\n", regval);
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness(regval);
|
||||
|
||||
/* If negative, fix signal bits */
|
||||
|
||||
if (regval & 0x80000000)
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/sensors/max6675.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_SPI) && defined(CONFIG_MAX6675)
|
||||
|
||||
|
|
@ -230,6 +231,10 @@ static ssize_t max6675_read(FAR struct file *filep, FAR char *buffer, size_t buf
|
|||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness(regval);
|
||||
|
||||
/* Get the temperature */
|
||||
|
||||
*temp = (regval & MAX6675_TEMP_COUPLE) >> 3;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/mb7040.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_MB7040)
|
||||
|
||||
|
|
@ -323,6 +324,10 @@ static int mb7040_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||
if (ret == OK)
|
||||
{
|
||||
*ptr = (int32_t)range;
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness(range);
|
||||
}
|
||||
|
||||
sninfo("range: %04x ret: %d\n", *ptr, ret);
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/mcp9844.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_MCP9844)
|
||||
|
||||
|
|
@ -274,6 +275,10 @@ static int mcp9844_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||
|
||||
if (ret == OK)
|
||||
{
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness(raw_temperature);
|
||||
|
||||
/* BIT15 - 13 contain information if preset temperature values
|
||||
* have been exceeded or undercut. BIT12 is now not any longer
|
||||
* needed since we do have the sign information retrieved.
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/sensors/mlx90393.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_SPI) && defined(CONFIG_MLX90393)
|
||||
|
||||
|
|
@ -232,6 +233,11 @@ static void mlx90393_read_measurement_data(FAR struct mlx90393_dev_s *dev)
|
|||
/* Give back the semaphore */
|
||||
|
||||
sem_post(&dev->datasem);
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((x_mag << 17) ^ (y_mag << 9) ^ (z_mag << 1) ^
|
||||
temperature);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/sensors/mpl115a.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_SPI) && defined(CONFIG_MPL115A)
|
||||
|
||||
|
|
@ -227,6 +228,11 @@ static void mpl115a_read_press_temp(FAR struct mpl115a_dev_s *priv)
|
|||
priv->mpl115a_temperature >>= 6; /* Tadc is 10bit unsigned */
|
||||
|
||||
sninfo("Temperature = %d\n", priv->mpl115a_temperature);
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((priv->mpl115a_pressure << 16) ^
|
||||
priv->mpl115a_temperature);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include <nuttx/arch.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/ms58xx.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_MS58XX)
|
||||
|
||||
|
|
@ -725,6 +726,8 @@ static int ms58xx_measure(FAR struct ms58xx_dev_s *priv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
add_sensor_randomness(rawpress ^ rawtemp);
|
||||
|
||||
diff = (int32_t)rawtemp - (int32_t)priv->c5 * ((int32_t)1 << 8);
|
||||
temp = (int32_t)((int64_t)2000 +
|
||||
(int64_t)diff * (int64_t)priv->c6 / ((int64_t)1 << 23));
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/veml6070.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#if defined(CONFIG_I2C) && defined(CONFIG_VEML6070)
|
||||
|
||||
|
|
@ -272,6 +273,10 @@ static ssize_t veml6070_read(FAR struct file *filep, FAR char *buffer,
|
|||
|
||||
buffer[0] = regdata;
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((buffer[1] << 16) ^ buffer[0]);
|
||||
|
||||
return buflen;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/spi/spi.h>
|
||||
#include <nuttx/sensors/xen1210.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include "xen1210.h"
|
||||
|
||||
|
|
@ -442,6 +443,12 @@ void xen1210_getdata(FAR struct xen1210_dev_s *priv)
|
|||
#ifdef CONFIG_XEN1210_REGDEBUG
|
||||
_err("%02x->%02x\n", regaddr, regval);
|
||||
#endif
|
||||
|
||||
/* Feed sensor data to entropy pool */
|
||||
|
||||
add_sensor_randomness((priv->sample.data_x << 8) ^
|
||||
(priv->sample.data_y << 4) ^
|
||||
(priv->sample.data_z << 4));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -646,4 +646,20 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
|
|||
int lineno);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_initrngseed
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_BOARD_INITRNGSEED is selected then board_init_rngseed is
|
||||
* called at up_randompool_initialize() to feed initial random seed
|
||||
* to RNG. Implemenation of this functions should feed at least
|
||||
* MIN_SEED_NEW_ENTROPY_WORDS 32-bit random words to entropy-pool using
|
||||
* up_rngaddentropy() or up_rngaddint().
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BOARD_INITRNGSEED
|
||||
void board_init_rngseed(void);
|
||||
#endif
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_BOARD_H */
|
||||
|
|
|
|||
197
include/nuttx/crypto/blake2s.h
Normal file
197
include/nuttx/crypto/blake2s.h
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/crypto/blake2s.h
|
||||
*
|
||||
* This code is based on public-domain/CC0 BLAKE2 reference implementation
|
||||
* by Samual Neves, at https://github.com/BLAKE2/BLAKE2/tree/master/ref
|
||||
* Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
|
||||
*
|
||||
* Copyright (C) 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name NuttX 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 THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS 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 __INCLUDE_NUTTX_CRYPTO_BLAKE2S_H
|
||||
#define __INCLUDE_NUTTX_CRYPTO_BLAKE2S_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
enum blake2s_constant
|
||||
{
|
||||
BLAKE2S_BLOCKBYTES = 64,
|
||||
BLAKE2S_OUTBYTES = 32,
|
||||
BLAKE2S_KEYBYTES = 32,
|
||||
BLAKE2S_SALTBYTES = 8,
|
||||
BLAKE2S_PERSONALBYTES = 8
|
||||
};
|
||||
|
||||
typedef struct blake2s_state__
|
||||
{
|
||||
uint32_t h[8];
|
||||
uint32_t t[2];
|
||||
uint32_t f[2];
|
||||
size_t buflen;
|
||||
size_t outlen;
|
||||
uint8_t buf[BLAKE2S_BLOCKBYTES];
|
||||
} blake2s_state;
|
||||
|
||||
typedef struct blake2s_param__
|
||||
{
|
||||
uint8_t digest_length; /* 1 */
|
||||
uint8_t key_length; /* 2 */
|
||||
uint8_t fanout; /* 3 */
|
||||
uint8_t depth; /* 4 */
|
||||
uint8_t leaf_length[4]; /* 8 */
|
||||
uint8_t node_offset[4]; /* 12 */
|
||||
uint8_t xof_length[2]; /* 14 */
|
||||
uint8_t node_depth; /* 15 */
|
||||
uint8_t inner_length; /* 16 */
|
||||
/* uint8_t reserved[0]; */
|
||||
uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */
|
||||
uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */
|
||||
} blake2s_param;
|
||||
|
||||
#ifdef __GNUC__ > 3
|
||||
#define BLAKE2_UNALIGNED 1
|
||||
typedef uint32_t uint32_alias_t __attribute__((may_alias, aligned(1)));
|
||||
typedef uint16_t uint16_alias_t __attribute__((may_alias, aligned(1)));
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Streaming API */
|
||||
|
||||
int blake2s_init(FAR blake2s_state *S, size_t outlen);
|
||||
int blake2s_init_key(FAR blake2s_state *S, size_t outlen, FAR const void *key,
|
||||
size_t keylen);
|
||||
int blake2s_init_param(FAR blake2s_state *S, FAR const blake2s_param *P);
|
||||
int blake2s_update(FAR blake2s_state *S, FAR const void *in, size_t inlen);
|
||||
int blake2s_final(FAR blake2s_state *S, FAR void *out, size_t outlen);
|
||||
|
||||
/* Simple API */
|
||||
|
||||
int blake2s(FAR void *out, size_t outlen, FAR const void *in, size_t inlen,
|
||||
FAR const void *key, size_t keylen);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Inline Functions
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t blake2_load32(FAR const void *src)
|
||||
{
|
||||
#if defined(BLAKE2_UNALIGNED) && !defined(CONFIG_ENDIAN_BIG)
|
||||
return *(FAR uint32_alias_t *)src;
|
||||
#elif !defined(CONFIG_ENDIAN_BIG)
|
||||
FAR const uint8_t *p = (FAR const uint8_t *)src;
|
||||
return ((uint32_t)(p[0]) << 24) |
|
||||
((uint32_t)(p[1]) << 16) |
|
||||
((uint32_t)(p[2]) << 8) |
|
||||
((uint32_t)(p[3]) << 0);
|
||||
#else
|
||||
FAR const uint8_t *p = (FAR const uint8_t *)src;
|
||||
return ((uint32_t)(p[0]) << 0) |
|
||||
((uint32_t)(p[1]) << 8) |
|
||||
((uint32_t)(p[2]) << 16) |
|
||||
((uint32_t)(p[3]) << 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint16_t blake2_load16(FAR const void *src)
|
||||
{
|
||||
#if defined(BLAKE2_UNALIGNED) && !defined(CONFIG_ENDIAN_BIG)
|
||||
return *(FAR uint16_alias_t *)src;
|
||||
#elif !defined(CONFIG_ENDIAN_BIG)
|
||||
const uint8_t *p = (FAR const uint8_t *)src;
|
||||
return ((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0);
|
||||
#else
|
||||
const uint8_t *p = (FAR const uint8_t *)src;
|
||||
return ((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void blake2_store16(FAR void *dst, uint16_t w)
|
||||
{
|
||||
#if defined(BLAKE2_UNALIGNED) && !defined(CONFIG_ENDIAN_BIG)
|
||||
*(FAR uint16_alias_t *)dst = w;
|
||||
#elif !defined(CONFIG_ENDIAN_BIG)
|
||||
FAR uint8_t *p = (FAR uint8_t *)dst;
|
||||
p[1] = (uint8_t)w; w >>= 8;
|
||||
p[0] = (uint8_t)w;
|
||||
#else
|
||||
FAR uint8_t *p = (FAR uint8_t *)dst;
|
||||
p[0] = (uint8_t)w; w >>= 8;
|
||||
p[1] = (uint8_t)w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void blake2_store32(FAR void *dst, uint32_t w)
|
||||
{
|
||||
#if defined(BLAKE2_UNALIGNED) && !defined(CONFIG_ENDIAN_BIG)
|
||||
*(FAR uint32_alias_t *)dst = w;
|
||||
#elif !defined(CONFIG_ENDIAN_BIG)
|
||||
FAR uint8_t *p = (FAR uint8_t *) dst;
|
||||
p[0] = (uint8_t)(w >> 24);
|
||||
p[1] = (uint8_t)(w >> 16);
|
||||
p[2] = (uint8_t)(w >> 8);
|
||||
p[3] = (uint8_t)(w >> 0);
|
||||
#else
|
||||
FAR uint8_t *p = (FAR uint8_t *) dst;
|
||||
p[0] = (uint8_t)(w >> 0);
|
||||
p[1] = (uint8_t)(w >> 8);
|
||||
p[2] = (uint8_t)(w >> 16);
|
||||
p[3] = (uint8_t)(w >> 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_CRYPTO_BLAKE2S_H */
|
||||
171
include/nuttx/random.h
Normal file
171
include/nuttx/random.h
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/random.h
|
||||
*
|
||||
* Copyright (C) 2015-2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Juha Niskanen <juha.niskanen@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name NuttX 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 THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS 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 __INCLUDE_NUTTX_RANDOM_H
|
||||
#define __INCLUDE_NUTTX_RANDOM_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <sys/random.h> /* getrandom() */
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Size of entropy pool in 32-bit integers, must be power of two */
|
||||
|
||||
#define ENTROPY_POOL_SIZE 128
|
||||
|
||||
#define add_irq_randomness(x) up_rngaddint(RND_SRC_IRQ, (x))
|
||||
#define add_sensor_randomness(x) up_rngaddint(RND_SRC_SENSOR, (x))
|
||||
#define add_time_randomness(x) up_rngaddint(RND_SRC_TIME, (x))
|
||||
#define add_hw_randomness(x) up_rngaddint(RND_SRC_HW, (x))
|
||||
#define add_sw_randomness(x) up_rngaddint(RND_SRC_SW, (x))
|
||||
#define add_ui_randomness(x) up_rngaddint(RND_SRC_UI, (x))
|
||||
|
||||
/* Allow above macros to always exist in source without ifdefs */
|
||||
|
||||
#ifndef CONFIG_CRYPTO_RANDOM_POOL
|
||||
# define up_rngaddint(k, x) ((void)(k),(void)(x))
|
||||
# define up_rngaddentropy(k, buf, n) ((void)(k),(void)(buf),(void)(x))
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Entropy pool structure */
|
||||
|
||||
struct entropy_pool_s
|
||||
{
|
||||
volatile uint32_t pool[ENTROPY_POOL_SIZE];
|
||||
};
|
||||
|
||||
/* Randomness sources */
|
||||
|
||||
enum rnd_source_t
|
||||
{
|
||||
RND_SRC_TIME = 0,
|
||||
RND_SRC_IRQ,
|
||||
RND_SRC_SENSOR,
|
||||
RND_SRC_HW, /* unique per HW UID or coming from factory line. */
|
||||
RND_SRC_SW, /* unique per SW version. */
|
||||
RND_SRC_UI /* buttons etc. user-visible interface elements. */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BOARD_ENTROPY_POOL
|
||||
/* Entropy pool structure can be provided by board source. Use for this is,
|
||||
* for example, allocate entropy pool from special area of RAM which content
|
||||
* is kept over system reset. */
|
||||
|
||||
extern struct entropy_pool_s board_entropy_pool;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CRYPTO_RANDOM_POOL
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_rngaddint
|
||||
*
|
||||
* Description:
|
||||
* Add one integer to entropy pool, contributing a specific kind
|
||||
* of entropy to pool.
|
||||
*
|
||||
* Parameters:
|
||||
* kindof - Enumeration constant telling where val came from
|
||||
* val - Integer to be added
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_rngaddint(enum rnd_source_t kindof, int val);
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_rngaddentropy
|
||||
*
|
||||
* Description:
|
||||
* Add buffer of integers to entropy pool.
|
||||
*
|
||||
* Parameters:
|
||||
* kindof - Enumeration constant telling where val came from
|
||||
* buf - Buffer of integers to be added
|
||||
* n - Number of elements in buf
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_rngaddentropy(enum rnd_source_t kindof, FAR const uint32_t *buf,
|
||||
size_t n);
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_rngreseed
|
||||
*
|
||||
* Description:
|
||||
* Force reseeding random number generator from entropy pool
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_rngreseed(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Function: up_randompool_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize entropy pool and random number generator
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_randompool_initialize(void);
|
||||
|
||||
#endif /* CONFIG_CRYPTO_RANDOM_POOL */
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_RANDOM_H */
|
||||
|
|
@ -93,6 +93,8 @@ FAR void *memcpy(FAR void *dest, FAR const void *src, size_t n);
|
|||
FAR void *memmove(FAR void *dest, FAR const void *src, size_t count);
|
||||
FAR void *memset(FAR void *s, int c, size_t n);
|
||||
|
||||
void explicit_bzero(FAR void *s, size_t n);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
|||
77
include/sys/random.h
Normal file
77
include/sys/random.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/****************************************************************************
|
||||
* include/sys/random.h
|
||||
*
|
||||
* Copyright (C) 2015-2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Juha Niskanen <juha.niskanen@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name NuttX 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 THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS 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 __INCLUDE_SYS_RANDOM_H
|
||||
#define __INCLUDE_SYS_RANDOM_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CRYPTO_RANDOM_POOL
|
||||
|
||||
/****************************************************************************
|
||||
* Function: getrandom
|
||||
*
|
||||
* Description:
|
||||
* Fill a buffer of arbitrary length with randomness. This is the
|
||||
* preferred interface for getting random numbers. The traditional
|
||||
* /dev/random approach is susceptible for things like the attacker
|
||||
* exhausting file descriptors on purpose.
|
||||
*
|
||||
* Note that this function cannot fail, other than by asserting.
|
||||
*
|
||||
* Parameters:
|
||||
* bytes - Buffer for returned random bytes
|
||||
* nbytes - Number of bytes requested.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void getrandom(FAR void *bytes, size_t nbytes);
|
||||
|
||||
#endif /* CONFIG_CRYPTO_RANDOM_POOL */
|
||||
|
||||
#endif /* __INCLUDE_SYS_RANDOM_H */
|
||||
|
|
@ -524,10 +524,19 @@
|
|||
/* The following is defined only if CONFIG_TASK_NAME_SIZE > 0 */
|
||||
|
||||
#if CONFIG_TASK_NAME_SIZE > 0
|
||||
# define SYS_prctl (SYS_nnetsocket+0)
|
||||
# define SYS_maxsyscall (SYS_nnetsocket+1)
|
||||
# define SYS_prctl (SYS_nnetsocket+1)
|
||||
#else
|
||||
# define SYS_maxsyscall SYS_nnetsocket
|
||||
# define SYS_prctl SYS_nnetsocket
|
||||
#endif
|
||||
|
||||
/* The following is defined only if entropy pool random number generator
|
||||
* is enabled. */
|
||||
|
||||
#ifdef CONFIG_CRYPTO_RANDOM_POOL
|
||||
# define SYS_getrandom (SYS_prctl+1)
|
||||
# define SYS_maxsyscall (SYS_prctl+2)
|
||||
#else
|
||||
# define SYS_maxsyscall SYS_prctl
|
||||
#endif
|
||||
|
||||
/* Note that the reported number of system calls does *NOT* include the
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ CSRCS += lib_strerror.c lib_strlen.c lib_strnlen.c lib_strncasecmp.c
|
|||
CSRCS += lib_strncat.c lib_strncmp.c lib_strncpy.c lib_strndup.c
|
||||
CSRCS += lib_strcasestr.c lib_strpbrk.c lib_strrchr.c lib_strspn.c
|
||||
CSRCS += lib_strstr.c lib_strtok.c lib_strtokr.c lib_strerrorr.c
|
||||
CSRCS += lib_explicit_bzero.c
|
||||
|
||||
ifneq ($(CONFIG_LIBC_ARCH_MEMCPY),y)
|
||||
ifeq ($(CONFIG_MEMCPY_VIK),y)
|
||||
|
|
|
|||
56
libc/string/lib_explicit_bzero.c
Normal file
56
libc/string/lib_explicit_bzero.c
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/****************************************************************************
|
||||
* libc/string/lib_explicit_bzero.c
|
||||
*
|
||||
* Copyright (C) 2015,2017 Haltian Ltd. All rights reserved.
|
||||
* Author: Juha Niskanen <juha.niskanen@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name NuttX 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 THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* memset that must not be optimized away by compiler (not even with LTO). */
|
||||
|
||||
void explicit_bzero(FAR void *s, size_t n)
|
||||
{
|
||||
static FAR void *(*FAR const volatile memset_v)(FAR void *, int, size_t) =
|
||||
&memset;
|
||||
|
||||
memset_v(s, 0, n);
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/random.h>
|
||||
|
||||
#include "irq/irq.h"
|
||||
|
||||
|
|
@ -53,7 +54,7 @@
|
|||
* Name: irq_dispatch
|
||||
*
|
||||
* Description:
|
||||
* This function must be called from the achitecture-specific logic in
|
||||
* This function must be called from the architecture-specific logic in
|
||||
* order to dispatch an interrupt to the appropriate, registered handling
|
||||
* logic.
|
||||
*
|
||||
|
|
@ -97,6 +98,12 @@ void irq_dispatch(int irq, FAR void *context)
|
|||
arg = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CRYPTO_RANDOM_POOL_COLLECT_IRQ_RANDOMNESS
|
||||
/* Add interrupt timing randomness to entropy pool */
|
||||
|
||||
add_irq_randomness(irq);
|
||||
#endif
|
||||
|
||||
/* Then dispatch to the interrupt handler */
|
||||
|
||||
vector(irq, context, arg);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
"get_errno_ptr","errno.h","defined(__DIRECT_ERRNO_ACCESS)","FAR int*"
|
||||
"getenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","FAR char*","FAR const char*"
|
||||
"getpid","unistd.h","","pid_t"
|
||||
"getrandom","sys/random.h","defined(CONFIG_CRYPTO_RANDOM_POOL)","void","FAR void*","size_t"
|
||||
"getsockopt","sys/socket.h","CONFIG_NSOCKET_DESCRIPTORS > 0 && defined(CONFIG_NET)","int","int","int","int","FAR void*","FAR socklen_t*"
|
||||
"insmod","nuttx/module.h","defined(CONFIG_MODULE)","FAR void *","FAR const char *","FAR const char *"
|
||||
"ioctl","sys/ioctl.h","!defined(CONFIG_LIBC_IOCTL_VARIADIC) && (CONFIG_NSOCKET_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0)","int","int","int","unsigned long"
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
|
@ -379,6 +379,13 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert)
|
|||
SYSCALL_LOOKUP(prctl, 5, STUB_prctl)
|
||||
#endif
|
||||
|
||||
/* The following is defined only if entropy pool random number generator
|
||||
* is enabled. */
|
||||
|
||||
#ifdef CONFIG_CRYPTO_RANDOM_POOL
|
||||
SYSCALL_LOOKUP(getrandom, 2, STUB_getrandom)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -391,6 +391,11 @@ uintptr_t STUB_socket(int nbr, uintptr_t parm1, uintptr_t parm2,
|
|||
uintptr_t STUB_prctl(int nbr, uintptr_t parm1, uintptr_t parm2,
|
||||
uintptr_t parm3, uintptr_t parm4, uintptr_t parm5);
|
||||
|
||||
/* The following is defined only if entropy pool random number generator
|
||||
* is enabled. */
|
||||
|
||||
uintptr_t STUB_getrandom(int nbr, uintptr_t parm1, uintptr_t parm2);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue