예제 #1
0
        private void init(IDigest digest, int securityStrength, IEntropySource entropySource, byte[] personalizationString, byte[] nonce)
        {
            if (securityStrength > DrbgUtilities.GetMaxSecurityStrength(digest))
            {
                throw new ArgumentException("Requested security strength is not supported by the derivation function");
            }

            if (entropySource.EntropySize < securityStrength)
            {
                throw new ArgumentException("Not enough entropy for security strength required");
            }

            mDigest           = digest;
            mEntropySource    = entropySource;
            mSecurityStrength = securityStrength;
            mSeedLength       = (int)seedlens[digest.AlgorithmName];

            // 1. seed_material = entropy_input || nonce || personalization_string.
            // 2. seed = Hash_df (seed_material, seedlen).
            // 3. V = seed.
            // 4. C = Hash_df ((0x00 || V), seedlen). Comment: Preceed V with a byte
            // of zeros.
            // 5. reseed_counter = 1.
            // 6. Return V, C, and reseed_counter as the initial_working_state

            byte[] entropy      = getEntropy();
            byte[] seedMaterial = Arrays.ConcatenateAll(entropy, nonce, personalizationString);
            Arrays.Fill(entropy, (byte)0);

            reseedFromSeedMaterial(seedMaterial);
        }
예제 #2
0
        private void init(IMac hMac, int securityStrength, IEntropySource entropySource, byte[] personalizationString, byte[] nonce)
        {
            if (securityStrength > DrbgUtilities.GetMaxSecurityStrength(hMac))
            {
                throw new ArgumentException("Requested security strength is not supported by the derivation function");
            }

            if (entropySource.EntropySize < securityStrength)
            {
                throw new ArgumentException("Not enough entropy for security strength required");
            }

            mSecurityStrength = securityStrength;
            mEntropySource    = entropySource;
            mHMac             = hMac;
            mEntropySource    = entropySource;
            mK = new byte[hMac.GetMacSize()];
            mV = new byte[mK.Length];
            Arrays.Fill(mV, (byte)1);

            byte[] entropy      = getEntropy();
            byte[] seedMaterial = Arrays.ConcatenateAll(entropy, nonce, personalizationString);
            Arrays.Fill(entropy, (byte)0);

            reseedFromSeedMaterial(seedMaterial);
        }
예제 #3
0
 private byte[] hashSeedMaterial(byte[] seedMaterial)
 {
     try
     {
         return(DrbgUtilities.HashDF(mDigest, seedMaterial, mSeedLength));
     }
     finally
     {
         Arrays.Fill(seedMaterial, (byte)0);
     }
 }
예제 #4
0
            internal override void Evaluate()
            {
                byte[]         origV                = parent.mV;
                byte[]         origC                = parent.mC;
                long           origReseedCounter    = parent.mReseedCounter;
                IEntropySource origEntropySource    = parent.mEntropySource;
                int            origSeedLength       = parent.mSeedLength;
                int            origSecurityStrength = parent.mSecurityStrength;

                try
                {
                    byte[] additionalInput = Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576");

                    int entropyStrength = DrbgUtilities.GetMaxSecurityStrength(parent.mDigest);

                    byte[][] expected = (byte[][])reseedKats[algorithm.Name];

                    parent.mV = Arrays.Clone((byte[])reseedVs[algorithm.Name]);

                    parent.mEntropySource = new DrbgUtilities.KatEntropyProvider().Get(entropyStrength);

                    parent.Reseed(additionalInput);

                    if (parent.mReseedCounter != 1)
                    {
                        Fail("DRBG reseedCounter failed to reset");
                    }

                    byte[] output = new byte[expected[0].Length];

                    parent.Generate(output, null, false);
                    if (!Arrays.AreEqual(expected[0], output))
                    {
                        Fail("DRBG Block 1 reseed KAT failure");
                    }

                    output = new byte[expected[1].Length];

                    parent.Generate(output, null, false);
                    if (!Arrays.AreEqual(expected[1], output))
                    {
                        Fail("DRBG Block 2 reseed KAT failure");
                    }

                    try
                    {
                        parent.mEntropySource = new DrbgUtilities.LyingEntropySource(entropyStrength);

                        parent.Reseed(null);

                        Fail("DRBG LyingEntropySource not detected on reseed");
                    }
                    catch (InvalidOperationException e)
                    {
                        if (!e.Message.Equals("Insufficient entropy provided by entropy source"))
                        {
                            Fail("DRBG self test failed reseed entropy check");
                        }
                    }
                }
                finally
                {
                    parent.mV                = origV;
                    parent.mC                = origC;
                    parent.mReseedCounter    = origReseedCounter;
                    parent.mEntropySource    = origEntropySource;
                    parent.mSeedLength       = origSeedLength;
                    parent.mSecurityStrength = origSecurityStrength;
                }
            }
예제 #5
0
            internal override void Evaluate()
            {
                byte[]         origV                = parent.mV;
                byte[]         origC                = parent.mC;
                long           origReseedCounter    = parent.mReseedCounter;
                IEntropySource origEntropySource    = parent.mEntropySource;
                int            origSeedLength       = parent.mSeedLength;
                int            origSecurityStrength = parent.mSecurityStrength;

                try
                {
                    byte[] personalization = Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F70717273747576");
                    byte[] nonce           = Hex.Decode("2021222324");

                    int entropyStrength = DrbgUtilities.GetMaxSecurityStrength(parent.mDigest);

                    byte[][] expected = (byte[][])kats[algorithm.Name];

                    parent.init(parent.mDigest, parent.mSecurityStrength, new DrbgUtilities.KatEntropyProvider().Get(entropyStrength), personalization, nonce);

                    byte[] output = new byte[expected[0].Length];

                    parent.Generate(output, null, true);
                    if (!Arrays.AreEqual(expected[0], output))
                    {
                        Fail("DRBG Block 1 KAT failure");
                    }

                    output = new byte[expected[1].Length];

                    parent.Generate(output, null, true);
                    if (!Arrays.AreEqual(expected[1], output))
                    {
                        Fail("DRBG Block 2 KAT failure");
                    }

                    try
                    {
                        parent.init(parent.mDigest, parent.mSecurityStrength, new DrbgUtilities.LyingEntropySource(entropyStrength), personalization, nonce);

                        Fail("DRBG LyingEntropySource not detected in init");
                    }
                    catch (InvalidOperationException e)
                    {
                        if (!e.Message.Equals("Insufficient entropy provided by entropy source"))
                        {
                            Fail("DRBG self test failed init entropy check");
                        }
                    }

                    try
                    {
                        parent.init(parent.mDigest, parent.mSecurityStrength, new DrbgUtilities.LyingEntropySource(20), personalization, nonce);

                        Fail("DRBG insufficient EntropySource not detected");
                    }
                    catch (ArgumentException e)
                    {
                        if (!e.Message.Equals("Not enough entropy for security strength required"))
                        {
                            Fail("DRBG self test failed init entropy check");
                        }
                    }

                    try
                    {
                        parent.mEntropySource = new DrbgUtilities.LyingEntropySource(entropyStrength);

                        parent.Reseed(null);

                        Fail("DRBG LyingEntropySource not detected in reseed");
                    }
                    catch (InvalidOperationException e)
                    {
                        if (!e.Message.Equals("Insufficient entropy provided by entropy source"))
                        {
                            Fail("DRBG self test failed reseed entropy check");
                        }
                    }

                    try
                    {
                        parent.init(parent.mDigest, entropyStrength + 1, new DrbgUtilities.KatEntropyProvider().Get(entropyStrength), personalization, nonce);

                        Fail("DRBG successful initialise with too high security strength");
                    }
                    catch (ArgumentException e)
                    {
                        if (!e.Message.Equals("Requested security strength is not supported by the derivation function"))
                        {
                            Fail("DRBG self test failed init security strength check");
                        }
                    }
                }
                finally
                {
                    parent.mV                = origV;
                    parent.mC                = origC;
                    parent.mReseedCounter    = origReseedCounter;
                    parent.mEntropySource    = origEntropySource;
                    parent.mSeedLength       = origSeedLength;
                    parent.mSecurityStrength = origSecurityStrength;
                }
            }
예제 #6
0
        /**
         * Populate a passed in array with random data.
         *
         * @param output output array for generated bits.
         * @param additionalInput additional input to be added to the DRBG in this step.
         * @param predictionResistant true if a reseed should be forced, false otherwise.
         *
         * @return number of bits generated, -1 if a reseed required.
         */
        public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant)
        {
            if (predictionResistant)
            {
                CTR_DRBG_Reseed_algorithm(additionalInput);
                additionalInput = null;
            }

            if (mIsTDEA)
            {
                if (mReseedCounter > TDEA_RESEED_MAX)
                {
                    return(-1);
                }

                if (DrbgUtilities.IsTooLarge(output, TDEA_MAX_BITS_REQUEST / 8))
                {
                    throw new ArgumentException("Number of bits per request limited to " + TDEA_MAX_BITS_REQUEST);
                }
            }
            else
            {
                if (mReseedCounter > AES_RESEED_MAX)
                {
                    return(-1);
                }

                if (DrbgUtilities.IsTooLarge(output, AES_MAX_BITS_REQUEST / 8))
                {
                    throw new ArgumentException("Number of bits per request limited to " + AES_MAX_BITS_REQUEST);
                }
            }

            byte[] seedMaterial;
            if (additionalInput != null)
            {
                seedMaterial = Block_Cipher_df(additionalInput, mSeedLength);

                // _Key & _V are modified by this call
                CTR_DRBG_Update(seedMaterial);
            }
            else
            {
                seedMaterial = new byte[mSeedLength];
            }

            byte[] requested = new byte[mV.Length];

            mEngine.Init(true, new KeyParameter(mKey));

            for (int i = 0; i <= output.Length / requested.Length; i++)
            {
                int bytesToCopy = ((output.Length - i * requested.Length) > requested.Length)
                                        ? requested.Length
                                        : (output.Length - i * mV.Length);

                if (bytesToCopy != 0)
                {
                    addOneTo(mV);

                    mEngine.ProcessBlock(mV, 0, requested, 0);

                    Array.Copy(requested, 0, output, i * requested.Length, bytesToCopy);
                }
            }

            // _Key & _V are modified by this call
            CTR_DRBG_Update(seedMaterial);
            Arrays.Fill(seedMaterial, (byte)0);

            mReseedCounter++;

            return(output.Length * 8);
        }