Cosmetic fix (value did not conform to its announced bit length, but this did not...
[BearSSL] / inc / bearssl_rand.h
index 37379d2..0a9f544 100644 (file)
@@ -28,6 +28,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "bearssl_block.h"
+#include "bearssl_hash.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -93,6 +96,32 @@ extern "C" {
  * no currently known security penalty for exceeding the NIST limits,
  * and, in any case, HMAC_DRBG usage in implementing SSL/TLS always
  * stays much below these thresholds.
+ *
+ *
+ * ## AESCTR_DRBG
+ *
+ * AESCTR_DRBG is a custom PRNG based on AES-128 in CTR mode. This is
+ * meant to be used only in situations where you are desperate for
+ * speed, and have an hardware-optimized AES/CTR implementation. Whether
+ * this will yield perceptible improvements depends on what you use the
+ * pseudorandom bytes for, and how many you want; for instance, RSA key
+ * pair generation uses a substantial amount of randomness, and using
+ * AESCTR_DRBG instead of HMAC_DRBG yields a 15 to 20% increase in key
+ * generation speed on a recent x86 CPU (Intel Core i7-6567U at 3.30 GHz).
+ *
+ * Internally, it uses CTR mode with successive counter values, starting
+ * at zero (counter value expressed over 128 bits, big-endian convention).
+ * The counter is not allowed to reach 32768; thus, every 32768*16 bytes
+ * at most, the `update()` function is run (on an empty seed, if none is
+ * provided). The `update()` function computes the new AES-128 key by
+ * applying a custom hash function to the concatenation of a state-dependent
+ * word (encryption of an all-one block with the current key) and the new
+ * seed. The custom hash function uses Hirose's construction over AES-256;
+ * see the comments in `aesctr_drbg.c` for details.
+ *
+ * This DRBG does not follow an existing standard, and thus should be
+ * considered as inadequate for production use until it has been properly
+ * analysed.
  */
 
 /**
@@ -279,7 +308,7 @@ typedef int (*br_prng_seeder)(const br_prng_class **ctx);
  * is returned.
  *
  * If `name` is not `NULL`, then `*name` is set to a symbolic string
- * that identifies the seeder implemention. If no seeder is returned
+ * that identifies the seeder implementation. If no seeder is returned
  * and `name` is not `NULL`, then `*name` is set to a pointer to the
  * constant string `"none"`.
  *
@@ -288,6 +317,79 @@ typedef int (*br_prng_seeder)(const br_prng_class **ctx);
  */
 br_prng_seeder br_prng_seeder_system(const char **name);
 
+/**
+ * \brief Context for AESCTR_DRBG.
+ *
+ * The context contents are opaque, except the first field, which
+ * supports OOP.
+ */
+typedef struct {
+       /**
+        * \brief Pointer to the vtable.
+        *
+        * This field is set with the initialisation method/function.
+        */
+       const br_prng_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
+       br_aes_gen_ctr_keys sk;
+       uint32_t cc;
+#endif
+} br_aesctr_drbg_context;
+
+/**
+ * \brief Statically allocated, constant vtable for AESCTR_DRBG.
+ */
+extern const br_prng_class br_aesctr_drbg_vtable;
+
+/**
+ * \brief AESCTR_DRBG initialisation.
+ *
+ * The context to initialise is provided as a pointer to its first field
+ * (the vtable pointer); this function sets that first field to a
+ * pointer to the vtable.
+ *
+ * The internal AES key is first set to the all-zero key; then, the
+ * `br_aesctr_drbg_update()` function is called with the provided `seed`.
+ * The call is performed even if the seed length (`seed_len`) is zero.
+ *
+ * The `aesctr` parameter defines the underlying AES/CTR implementation.
+ *
+ * \param ctx        AESCTR_DRBG context to initialise.
+ * \param aesctr     vtable for the AES/CTR implementation.
+ * \param seed       initial seed (can be `NULL` if `seed_len` is zero).
+ * \param seed_len   initial seed length (in bytes).
+ */
+void br_aesctr_drbg_init(br_aesctr_drbg_context *ctx,
+       const br_block_ctr_class *aesctr, const void *seed, size_t seed_len);
+
+/**
+ * \brief Random bytes generation with AESCTR_DRBG.
+ *
+ * This method produces `len` pseudorandom bytes, in the `out`
+ * buffer. The context is updated accordingly.
+ *
+ * \param ctx   AESCTR_DRBG context.
+ * \param out   output buffer.
+ * \param len   number of pseudorandom bytes to produce.
+ */
+void br_aesctr_drbg_generate(br_aesctr_drbg_context *ctx,
+       void *out, size_t len);
+
+/**
+ * \brief Inject additional seed bytes in AESCTR_DRBG.
+ *
+ * The provided seed bytes are added into the AESCTR_DRBG internal
+ * entropy pool. The process does not _replace_ existing entropy,
+ * thus pushing non-random bytes (i.e. bytes which are known to the
+ * attackers) does not degrade the overall quality of generated bytes.
+ *
+ * \param ctx        AESCTR_DRBG context.
+ * \param seed       additional seed.
+ * \param seed_len   additional seed length (in bytes).
+ */
+void br_aesctr_drbg_update(br_aesctr_drbg_context *ctx,
+       const void *seed, size_t seed_len);
+
 #ifdef __cplusplus
 }
 #endif