Пример #1
0
        /**
         * Construct a SP800-90A Hash DRBG.
         * <p>
         * Minimum entropy requirement is the security strength requested.
         * </p>
         * @param digest  source digest to use for DRB stream.
         * @param securityStrength security strength required (in bits)
         * @param entropySource source of entropy to use for seeding/reseeding.
         * @param personalizationString personalization string to distinguish this DRBG (may be null).
         * @param nonce nonce to further distinguish this DRBG (may be null).
         */
        public HashSP800Drbg(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);
            byte[] seed         = DrbgUtilities.HashDF(mDigest, seedMaterial, mSeedLength);

            mV = seed;
            byte[] subV = new byte[mV.Length + 1];
            Array.Copy(mV, 0, subV, 1, mV.Length);
            mC = DrbgUtilities.HashDF(mDigest, subV, mSeedLength);

            mReseedCounter = 1;
        }
Пример #2
0
        /**
         * Reseed the DRBG.
         *
         * @param additionalInput additional input to be added to the DRBG in this step.
         */
        public void Reseed(byte[] additionalInput)
        {
            // 1. seed_material = 0x01 || V || entropy_input || additional_input.
            //
            // 2. seed = Hash_df (seed_material, seedlen).
            //
            // 3. V = seed.
            //
            // 4. C = Hash_df ((0x00 || V), seedlen).
            //
            // 5. reseed_counter = 1.
            //
            // 6. Return V, C, and reseed_counter for the new_working_state.
            //
            // Comment: Precede with a byte of all zeros.
            byte[] entropy      = GetEntropy();
            byte[] seedMaterial = Arrays.ConcatenateAll(ONE, mV, entropy, additionalInput);
            byte[] seed         = DrbgUtilities.HashDF(mDigest, seedMaterial, mSeedLength);

            mV = seed;
            byte[] subV = new byte[mV.Length + 1];
            subV[0] = 0x00;
            Array.Copy(mV, 0, subV, 1, mV.Length);
            mC = DrbgUtilities.HashDF(mDigest, subV, mSeedLength);

            mReseedCounter = 1;
        }
Пример #3
0
        /**
         * Construct a SP800-90A Hash DRBG.
         * <p>
         * Minimum entropy requirement is the security strength requested.
         * </p>
         * @param hMac Hash MAC to base the DRBG on.
         * @param securityStrength security strength required (in bits)
         * @param entropySource source of entropy to use for seeding/reseeding.
         * @param personalizationString personalization string to distinguish this DRBG (may be null).
         * @param nonce nonce to further distinguish this DRBG (may be null).
         */
        public HMacSP800Drbg(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");
            }

            mHMac             = hMac;
            mSecurityStrength = securityStrength;
            mEntropySource    = entropySource;

            byte[] entropy      = GetEntropy();
            byte[] seedMaterial = Arrays.ConcatenateAll(entropy, nonce, personalizationString);

            mK = new byte[hMac.GetMacSize()];
            mV = new byte[mK.Length];
            Arrays.Fill(mV, (byte)1);

            hmac_DRBG_Update(seedMaterial);

            mReseedCounter = 1;
        }
Пример #4
0
 public int Generate(byte[] output, byte[] additionalInput, bool predictionResistant)
 {
     //IL_003f: Unknown result type (might be due to invalid IL or missing references)
     //IL_007c: Unknown result type (might be due to invalid IL or missing references)
     if (mIsTdea)
     {
         if (mReseedCounter > TDEA_RESEED_MAX)
         {
             return(-1);
         }
         if (DrbgUtilities.IsTooLarge(output, TDEA_MAX_BITS_REQUEST / 8))
         {
             throw new ArgumentException(string.Concat((object)"Number of bits per request limited to ", (object)TDEA_MAX_BITS_REQUEST), "output");
         }
     }
     else
     {
         if (mReseedCounter > AES_RESEED_MAX)
         {
             return(-1);
         }
         if (DrbgUtilities.IsTooLarge(output, AES_MAX_BITS_REQUEST / 8))
         {
             throw new ArgumentException(string.Concat((object)"Number of bits per request limited to ", (object)AES_MAX_BITS_REQUEST), "output");
         }
     }
     if (predictionResistant)
     {
         CTR_DRBG_Reseed_algorithm(additionalInput);
         additionalInput = null;
     }
     if (additionalInput != null)
     {
         additionalInput = Block_Cipher_df(additionalInput, mSeedLength);
         CTR_DRBG_Update(additionalInput, mKey, mV);
     }
     else
     {
         additionalInput = new byte[mSeedLength];
     }
     byte[] array = new byte[mV.Length];
     mEngine.Init(forEncryption: true, new KeyParameter(ExpandKey(mKey)));
     for (int i = 0; i <= output.Length / array.Length; i++)
     {
         int num = ((output.Length - i * array.Length > array.Length) ? array.Length : (output.Length - i * mV.Length));
         if (num != 0)
         {
             AddOneTo(mV);
             mEngine.ProcessBlock(mV, 0, array, 0);
             global::System.Array.Copy((global::System.Array)array, 0, (global::System.Array)output, i * array.Length, num);
         }
     }
     CTR_DRBG_Update(additionalInput, mKey, mV);
     mReseedCounter++;
     return(output.Length * 8);
 }
Пример #5
0
 public void Reseed(byte[] additionalInput)
 {
     byte[] entropy      = GetEntropy();
     byte[] seedMaterial = Arrays.ConcatenateAll(ONE, mV, entropy, additionalInput);
     byte[] array        = (mV = DrbgUtilities.HashDF(mDigest, seedMaterial, mSeedLength));
     byte[] array2       = new byte[mV.Length + 1];
     array2[0] = 0;
     global::System.Array.Copy((global::System.Array)mV, 0, (global::System.Array)array2, 1, mV.Length);
     mC             = DrbgUtilities.HashDF(mDigest, array2, mSeedLength);
     mReseedCounter = 1L;
 }
Пример #6
0
 public HashSP800Drbg(IDigest digest, int securityStrength, IEntropySource entropySource, byte[] personalizationString, byte[] nonce)
 {
     //IL_0014: Unknown result type (might be due to invalid IL or missing references)
     //IL_0028: Unknown result type (might be due to invalid IL or missing references)
     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.get_Item((object)digest.AlgorithmName);
     byte[] entropy      = GetEntropy();
     byte[] seedMaterial = Arrays.ConcatenateAll(entropy, nonce, personalizationString);
     byte[] array        = (mV = DrbgUtilities.HashDF(mDigest, seedMaterial, mSeedLength));
     byte[] array2       = new byte[mV.Length + 1];
     global::System.Array.Copy((global::System.Array)mV, 0, (global::System.Array)array2, 1, mV.Length);
     mC             = DrbgUtilities.HashDF(mDigest, array2, mSeedLength);
     mReseedCounter = 1L;
 }
Пример #7
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 (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, "output");
                }
            }
            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, "output");
                }
            }

            if (predictionResistant)
            {
                CTR_DRBG_Reseed_algorithm(additionalInput);
                additionalInput = null;
            }

            if (additionalInput != null)
            {
                additionalInput = Block_Cipher_df(additionalInput, mSeedLength);
                CTR_DRBG_Update(additionalInput, mKey, mV);
            }
            else
            {
                additionalInput = new byte[mSeedLength];
            }

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

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

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

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

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

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

            CTR_DRBG_Update(additionalInput, mKey, mV);

            mReseedCounter++;

            return(output.Length * 8);
        }