Revise DRBG to split between internal and external flags.
[openssl.git] / fips / rand / fips_rand_lcl.h
index e3859163a3e3a9c6b0f7a54dd92c010fb807924b..fc649c003b5235bdb46f84bf8461a597e3397c09 100644 (file)
@@ -52,7 +52,9 @@
  */
 
 typedef struct drbg_hash_ctx_st DRBG_HASH_CTX;
+typedef struct drbg_hmac_ctx_st DRBG_HMAC_CTX;
 typedef struct drbg_ctr_ctx_st DRBG_CTR_CTX;
+typedef struct drbg_ec_ctx_st DRBG_EC_CTX;
 
 /* 888 bits from 10.1 table 2 */
 #define HASH_PRNG_MAX_SEEDLEN  111
@@ -67,6 +69,14 @@ struct drbg_hash_ctx_st
        unsigned char vtmp[HASH_PRNG_MAX_SEEDLEN];
        };
 
+struct drbg_hmac_ctx_st
+       {
+       const EVP_MD *md;
+       HMAC_CTX hctx;
+       unsigned char K[EVP_MAX_MD_SIZE];
+       unsigned char V[EVP_MAX_MD_SIZE];
+       };
+
 struct drbg_ctr_ctx_st
        {
        AES_KEY ks;
@@ -82,10 +92,42 @@ struct drbg_ctr_ctx_st
        unsigned char KX[48];
        };
 
-/* DRBG flags */
+/* Maximum seed length */
+#define EC_PRNG_MAX_SEEDLEN    66
+
+struct drbg_ec_ctx_st
+       {
+       /* Message digest to use */
+       const EVP_MD *md;
+       /* Curve to use: generator is point P */
+       EC_GROUP *curve;
+       /* Point Q */
+       EC_POINT *Q;
+       /* Temporary point */
+       EC_POINT *ptmp;
+       size_t exbits;
+       /* Secret s value */
+       BIGNUM *s;
+       /* Buffer to store byte version of s value */
+       unsigned char sbuf[EC_PRNG_MAX_SEEDLEN];
+       /* Buffer to store byte version of t value */
+       unsigned char tbuf[EC_PRNG_MAX_SEEDLEN];
+       /* Digest context */
+       EVP_MD_CTX mctx;
+       /* Temporary value storage: should always exceed max digest length */
+       unsigned char vtmp[EC_PRNG_MAX_SEEDLEN];
+       /* Flag to indicate s = s * P has been deferred */
+       int sp_defer;
+       /* Temp BN context */
+       BN_CTX *bctx;
+       };
+
+/* DRBG internal flags */
 
 /* Functions shouldn't call err library */
-#define        DRBG_FLAG_NOERR                 0x4
+#define        DRBG_FLAG_NOERR                 0x1
+/* Custom reseed checking */
+#define        DRBG_CUSTOM_RESEED              0x2
 
 /* DRBG status values */
 /* not initialised */
@@ -100,6 +142,12 @@ struct drbg_ctr_ctx_st
 /* A default maximum length: larger than any reasonable value used in pratice */
 
 #define DRBG_MAX_LENGTH                        0x7ffffff0
+/* Maximum DRBG block length: all md sizes are bigger than cipher blocks sizes
+ * so use max digest length.
+ */
+#define DRBG_MAX_BLOCK                 EVP_MAX_MD_SIZE
+
+#define DRBG_HEALTH_INTERVAL           (1 << 24)
 
 /* DRBG context structure */
 
@@ -108,8 +156,12 @@ struct drbg_ctx_st
        /* First types common to all implementations */
        /* DRBG type: a NID for the underlying algorithm */
        int type;
-       /* Various flags */
-       unsigned int flags;
+       /* Various external flags */
+       unsigned int xflags;
+       /* Various internal use only flags */
+       unsigned int iflags;
+       /* Used for periodic health checks */
+       int health_check_cnt, health_check_interval;
 
        /* The following parameters are setup by mechanism drbg_init() call */
        int strength;
@@ -129,7 +181,9 @@ struct drbg_ctx_st
        union 
                {
                DRBG_HASH_CTX hash;
+               DRBG_HMAC_CTX hmac;
                DRBG_CTR_CTX  ctr;
+               DRBG_EC_CTX  ec;
                } d;
        /* Initialiase PRNG and setup callbacks below */
        int (*init)(DRBG_CTX *ctx, int nid, int security, unsigned int flags);
@@ -149,6 +203,9 @@ struct drbg_ctx_st
        /* uninstantiate */
        int (*uninstantiate)(DRBG_CTX *ctx);
 
+       /* Entropy source block length */
+       size_t entropy_blocklen;
+
        /* entropy gathering function */
        size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char **pout,
                                int entropy, size_t min_len, size_t max_len);
@@ -163,7 +220,7 @@ struct drbg_ctx_st
 
        /* Continuous random number test temporary area */
        /* Last block */        
-       unsigned char lb[16];
+       unsigned char lb[EVP_MAX_MD_SIZE];
        /* set if lb is valid */
        int lb_valid;
 
@@ -180,4 +237,7 @@ struct drbg_ctx_st
 
 int fips_drbg_ctr_init(DRBG_CTX *dctx);
 int fips_drbg_hash_init(DRBG_CTX *dctx);
+int fips_drbg_hmac_init(DRBG_CTX *dctx);
+int fips_drbg_ec_init(DRBG_CTX *dctx);
 int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags);
+int fips_drbg_cprng_test(DRBG_CTX *dctx, const unsigned char *out);