public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant)
        {
            lock (this)
            {
                lazyInitDRBG();

                if (predictionResistant)
                {
                    // FSM_STATE:5.7, "DRBG RESEED HEALTH CHECK", "The module is performing DRBG Reseed Health Check self-test"
                    // FSM_TRANS:5.7, "CONDITIONAL TEST", "DRBG RESEED HEALTH CHECKS", "Invoke DRBG Reseed Health Check"
                    SelfTestExecutor.Validate(algorithm, drbg.CreateReseedSelfTest(algorithm));    // reseed health test
                    // FSM_TRANS:5.8, "DRBG RESEED HEALTH CHECKS", "CONDITIONAL TEST", "DRBG Reseed Health Check successful"
                }

                // check if a reseed is required...
                if (drbg.Generate(output, additionalInput, predictionResistant) < 0)
                {
                    // FSM_STATE:5.7, "DRBG RESEED HEALTH CHECK", "The module is performing DRBG Reseed Health Check self-test"
                    // FSM_TRANS:5.7, "CONDITIONAL TEST", "DRBG RESEED HEALTH CHECKS", "Invoke DRBG Reseed Health Check"
                    SelfTestExecutor.Validate(algorithm, drbg.CreateReseedSelfTest(algorithm));    // reseed health test
                    // FSM_TRANS:5.8, "DRBG RESEED HEALTH CHECKS", "CONDITIONAL TEST", "DRBG Reseed Health Check successful"

                    drbg.Reseed(null);
                    return(drbg.Generate(output, additionalInput, predictionResistant));
                }

                return(output.Length);
            }
        }
Example #2
0
 public override void NextBytes(byte[] bytes)
 {
     lock (drbg)
     {
         // check if a reseed is required...
         if (drbg.Generate(bytes, null, predictionResistant) < 0)
         {
             drbg.Reseed(null);
             drbg.Generate(bytes, null, predictionResistant);
         }
     }
 }
        public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant)
        {
            if (CryptoStatus.IsErrorStatus())
            {
                throw new CryptoOperationError(CryptoStatus.GetStatusMessage());
            }

            lock (this)
            {
                int rv;

                if (block.Length != output.Length)
                {
                    if (block.Length < output.Length)
                    {
                        block     = new byte[GetTestBlockSize(output.Length)];
                        nextBlock = new byte[block.Length];

                        if (initialAdditionalInput != null)
                        {
                            rv = drbg.Generate(block, initialAdditionalInput, predictionResistant);
                            initialAdditionalInput = null;
                        }
                        else
                        {
                            rv = drbg.Generate(block, null, predictionResistant);
                        }

                        if (rv < 0)
                        {
                            CryptoStatus.MoveToErrorStatus("DRBG unable to initialise");
                        }
                    }
                    else if (block.Length != MIN_RESOLUTION)
                    {
                        byte[] tmp = new byte[GetTestBlockSize(output.Length)];

                        Array.Copy(block, block.Length - tmp.Length, tmp, 0, tmp.Length);

                        block     = tmp;
                        nextBlock = new byte[GetTestBlockSize(output.Length)];
                    }
                }

                rv = drbg.Generate(nextBlock, additionalInput, predictionResistant);
                if (rv < 0)
                {
                    return(rv);
                }

                // FSM_STATE:5.2, "CONTINUOUS DRBG TEST", "The module is performing Continuous DRBG self-test"
                // FSM_TRANS:5.3, "CONDITIONAL TEST", "CONTINUOUS DRBG TEST", "Invoke Continuous DRBG test"
                if (areEqual(block, nextBlock, 0))
                {
                    CryptoStatus.MoveToErrorStatus("Duplicate block detected in DRBG output");
                }
                // FSM_TRANS:5.4, "CONTINUOUS DRBG TEST", "CONDITIONAL TEST", "Continuous DRBG test successful"

                // note we only return output bytes to output array when we are sure there is no issue.
                Array.Copy(nextBlock, 0, output, 0, output.Length);
                Array.Copy(nextBlock, 0, block, 0, block.Length);
            }

            if (CryptoStatus.IsErrorStatus())
            {
                throw new CryptoOperationError(CryptoStatus.GetStatusMessage());
            }

            return(output.Length);
        }