xmos / lib_random

Random number generation
Other
1 stars 8 forks source link

Extend (& deprecate) lib_random #4

Open ghost opened 6 years ago

ghost commented 6 years ago

Work to date - please review it is what we want. (history should be squashed)

ghost commented 6 years ago

I think that we should be able to provide that via a simple wrapper to the pool and prng APIs of this library, do you see any problem with that?

No, apart from extra code. It may be possible to reduce the footprint for distinct use cases.

ghost commented 6 years ago

I will need to confirm that we will not need a CSPRNG for this

The PRNG is revealing 32bits out of either 57, 88 or 113 bits, the other bits remain hidden (unless the user connects a debugger).

It is up to the user to decide: how many hidden bits are required; how much entropy the seeds must start with; how often entropy needs to be injected into the state;

I believe this is best left as an explicit implementation detail.

ghost commented 6 years ago

Are the functions in random.h ...

This is deprecated backward comparability. Initially it attempted as adding entropy to the initial seed. It now offers little over the version in stdlib.h viz rand(), srand(), drand48() etc.

ghost commented 6 years ago

I think that we should be able to provide that via a simple wrapper to the pool and prng APIs of this library, do you see any problem with that?

Simple wrapper? The problem is the creation of interfaces and placement of the interfaced tasks - along with the passing of these parameters.

It would be nice if the XC language allowed collections of select-case statements to be built up and dynamically dispatched opaquely. However, in the current language the list is statically presented at compiler time (select statement) and dynamically dispatched via guard statement etc.

Until that day arrives, I am not sure of the best way to mix C and XC, along with adding the necessary top level knitting, especially in an easy to use library. May be we should leave this as an implementors business until a clear idiom (or XC v3) becomes available.

samchesney commented 6 years ago

I think that we should be able to provide that via a simple wrapper to the pool and prng APIs of this library, do you see any problem with that?

Simple wrapper? The problem is the creation of interfaces and placement of the interfaced tasks - along with the passing of these parameters.

Starting the lib_random server as a task in xC is not an issue. However, we'll need C compatible API to access the client side, which we can use to set defines when building 3rd party libraries. These 3rd party libraries are configured as follows.

Kernel config:

#define configRAND32()    ulRand()

IP stack config:

#define ipconfigRAND32()    ulRand()

PKCS11 config:

/* Random number generation */

/* C_SeedRandom mixes additional seed material into the token's
 * random number generator. */
CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
#ifdef CK_NEED_ARG_LIST
(
  CK_SESSION_HANDLE hSession,  /* the session's handle */
  CK_BYTE_PTR       pSeed,     /* the seed material */
  CK_ULONG          ulSeedLen  /* length of seed material */
);
#endif

/* C_GenerateRandom generates random data. */
CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
#ifdef CK_NEED_ARG_LIST
(
  CK_SESSION_HANDLE hSession,    /* the session's handle */
  CK_BYTE_PTR       RandomData,  /* receives the random data */
  CK_ULONG          ulRandomLen  /* # of bytes to generate */
);
#endif

TLS library config:

#define MBEDTLS_ENTROPY_HARDWARE_ALT

int mbedtls_hardware_poll(void * data, unsigned char * output, size_t len, size_t * olen) {
...
}

The following mbedTLS documentation looks useful:

ghost commented 6 years ago

Erm.... I'll read the documentation and see if I can work out how it works.

ghost commented 6 years ago

However, we'll need C compatible API to access the client side, which we can use to set defines when building 3rd party libraries. These 3rd party libraries are configured as follows.

This looks like an adapter is needed into a particular 3rd party library. Such a specific adapter is not appropriate for a library - although having a general purpose C API that can be used by the adapter and others may be useful... but this is speculation.

I'll write suitable code and you can decide if it lives in the libraries 'examples', the libraries API or alongside the client (mbed) code.

ghost commented 6 years ago

define configRAND32() ulRand()

define ipconfigRAND32() ulRand()

These could use the stdlib.h rand() function. As they will probably expose information to the outside world, they should not use the same seed as the tls - even if they share the same library code viz via a C wrapped random_prng.h.

ghost commented 6 years ago

p.s. here is the 'good enough' prng behind rand().... good enough for Donald good enough for me:

__extension__ static __thread unsigned long long _rand_next = 1;
void srand(unsigned int seed) {
  _rand_next = seed;
}
int rand(void) {
  /* This multiplier was obtained from Knuth, D.E., "The Art of
     Computer Programming," Vol 2, Seminumerical Algorithms, Third
     Edition, Addison-Wesley, 1998, p. 106 (line 26) & p. 108 */
  _rand_next =_rand_next * __extension__ 6364136223846793005LL + 1;
  return (int)((_rand_next >> 32) & RAND_MAX);
}
ghost commented 6 years ago

I've taken a 'quick' look at the cryptsoft API: https://www.cryptsoft.com/pkcs11doc/v220/group__SEC__11__15__RANDOM__NUMBER__GENERATION__FUNCTIONS.html

This is generating random numbers for you, I believe. So I assume all that is needed is the seed: pSeed, /* the seed material */ This could be got from the random_pool.h. I have no idea how, when & how often C_SeedRandom() is called to add entropy... p.s. It could call random_bit.h directly, rather than having random_pool.h running too)

ghost commented 6 years ago

The TLS library looks like it need hooks into the entropy. https://tls.mbed.org/api/entropy__poll_8h.html#a45ce4792a68304d592fb711bd8f2fc86 This is probably best done by implementing specific code for the TLS that sits ontop of the randome_bit.h API (I assume it keeps it's own pool)

ghost commented 6 years ago

Please do comment if I am incorrect regarding how these components work, or if the application architecture needs additional components that require something else.

samchesney commented 6 years ago

define configRAND32() ulRand()

define ipconfigRAND32() ulRand()

These could use the stdlib.h rand() function. As they will probably expose information to the outside world, they should not use the same seed as the tls - even if they share the same library code viz via a C wrapped random_prng.h.

Understood, thank you. I've created https://github.com/xmos/amazon_freertos_experiment/issues/29 to track this.

samchesney commented 6 years ago

I've taken a 'quick' look at the cryptsoft API: https://www.cryptsoft.com/pkcs11doc/v220/group__SEC__11__15__RANDOM__NUMBER__GENERATION__FUNCTIONS.html

This is generating random numbers for you, I believe. So I assume all that is needed is the seed: pSeed, /* the seed material */ This could be got from the random_pool.h. I have no idea how, when & how often C_SeedRandom() is called to add entropy... p.s. It could call random_bit.h directly, rather than having random_pool.h running too)

If we use random_bit() for this would it mean we were always passing a seed with of 0b00000000 or 0b00000001 and setting ulSeedLen to 1?

ghost commented 6 years ago

If we use random_bit() for this would it mean we were always passing a seed with of 0b00000000 or 0b00000001 and setting ulSeedLen to 1?

I have not looked at the implementation, but yes, that looks like one way of doing it. Another way would be to have a timer interrupt gathering bits at a rate of 1bit/20000ticks (see #define TIME_FOR_ONE_BIT 20000) and then when it had 32bits it could send them all. I have not looked at the expectations of the implementation so would not know what is better/more efficient.

It should be noted that random_pool.h could be used to gather the bits, but it seems too heavy weight an API (and it is written in XC). Thus implementing a really simple pooling function seems sensible in this case.

ghost commented 6 years ago

N.B. If the 'cryptsoft' and 'mbed tls' libraries are running on differnt cores, they can each have their own random_bit.h source of entropy.

If they are running on the same core, they will need to share the bits co-operatively to prevent starvation or a race condition - the library is not logical-core safe by design! The random_bit_claim() is there to make this sharing safe.

samchesney commented 6 years ago

I found this documentation on how to port mbed TLS. So I agree, we can start off using the random_bit API for this too (and hopefully find that it performs well enough polling for a byte of entropy at a time in mbedtls_hardware_poll().

samchesney commented 6 years ago

I think all of the abov means that in actual fact this pull request is almost ready to merge?

samchesney commented 6 years ago

I've taken a 'quick' look at the cryptsoft API: https://www.cryptsoft.com/pkcs11doc/v220/group__SEC__11__15__RANDOM__NUMBER__GENERATION__FUNCTIONS.html

This is generating random numbers for you, I believe.

Looking into this further, I'm not sure if I'm missing something. I thought this was specifying an API, but not providing an implementation? I think we need to provide a matching implementation for C_GenerateRandom().