// Public for use in HashConditioningComponent public DrbgResult Hash_Df(BitString data, int bitsToReturn) { // 0 if (bitsToReturn > 255 * HashAttributes.OutputLength) { throw new ArgumentException("Requesting too many bits to return"); } // 1 var temp = new BitString(0); // 2 var len = bitsToReturn.CeilingDivide(HashAttributes.OutputLength); // 3 var counter = new BitString("01"); // 4 for (var i = 0; i < len; i++) { // 4.1 var dataToHash = counter.ConcatenateBits(BitString.To32BitString(bitsToReturn)).ConcatenateBits(data); temp = temp.ConcatenateBits(_sha.HashMessage(dataToHash).Digest); // 4.2 counter = counter.BitStringAddition(BitString.One()); } // 5 var requestedBits = temp.MSBSubstring(0, bitsToReturn); // 6 return(new DrbgResult(requestedBits)); }
public BitString GetNextIV() { var currentIV = _iv.GetLeastSignificantBits(_blockSize).GetDeepCopy(); _iv = _iv.BitStringAddition(BitString.One()); return(currentIV); }
protected override DrbgResult GenerateAlgorithm(int requestedNumberOfBits, BitString additionalInput) { // 1 if (ReseedCounter > Attributes.MaxNumberOfRequestsBetweenReseeds) { return(new DrbgResult(DrbgStatus.ReseedRequired)); } // 2 if (additionalInput.BitLength != 0) { // 2.1 var dataToHash = new BitString("02") .ConcatenateBits(V) .ConcatenateBits(additionalInput); var w = _sha.HashMessage(dataToHash).Digest; // 2.2 V = V.BitStringAddition(w).GetLeastSignificantBits(HashAttributes.SeedLength); } // 3 var returnedBits = HashGen(V, requestedNumberOfBits); // 4 var H = _sha.HashMessage(new BitString("03").ConcatenateBits(V)).Digest; // 5 V = V.BitStringAddition(H); V = V.BitStringAddition(C); V = V.BitStringAddition(BitString.To32BitString(ReseedCounter)); V = V.GetLeastSignificantBits(HashAttributes.SeedLength); // 6 ReseedCounter++; // 7 return(new DrbgResult(returnedBits)); }
public BitString Expand(BitString pseudoRandomKey, BitString otherInfo, int keyLengthBytes) { // keyLength comes in as bytes var keyLengthBits = keyLengthBytes * 8; var n = keyLengthBits.CeilingDivide(_hmac.OutputLength); var t = new BitString(0); var counter = new BitString("00"); var result = new BitString(0); for (short i = 1; i <= n; i++) { counter = counter.BitStringAddition(BitString.One()); t = _hmac.Generate(pseudoRandomKey, t.ConcatenateBits(otherInfo).ConcatenateBits(counter)).Mac; result = result.ConcatenateBits(t); } return(result.GetMostSignificantBits(keyLengthBits)); }
private void Update(BitString seedMaterial) { BitString v = V.GetDeepCopy(); BitString key = Key.GetDeepCopy(); // 1. temp = Null BitString temp = new BitString(0); // 2. While (len(temp)<seedlen) do: while (temp.BitLength < CounterAttributes.SeedLength) { v = v .BitStringAddition(BitString.One()) .ConcatenateBits(new BitString(CounterAttributes.OutputLength - v.BitLength)); // Add zeroes to bitstring to make it the length of the OutputLength BitString outputBlock = BlockEncrypt(key, v); temp = temp.ConcatenateBits(outputBlock); } // 3. temp = Leftmost seedlen bits of temp temp = temp.GetMostSignificantBits(CounterAttributes.SeedLength); // 4. temp = temp xor provided_data Debug.Assert(temp.BitLength == seedMaterial.BitLength); temp = temp.XOR(seedMaterial); // 5. Key = Leftmost keylen bits of temp key = temp.GetMostSignificantBits(CounterAttributes.KeyLength); // 6. V = Rightmost outlen bits of temp v = temp.GetLeastSignificantBits(CounterAttributes.OutputLength); // 7. Return new values of Key and V Key = key.GetDeepCopy(); V = v.GetDeepCopy(); }
private DrbgResult GenerateAlgorithmDf(int requestedNumberOfBits, BitString additionalInput) { additionalInput = additionalInput.GetDeepCopy(); // 1. If reseed_counter > reseed_interval, then return an indication that // a reseed is required if (ReseedCounter > Attributes.MaxNumberOfRequestsBetweenReseeds) { return(new DrbgResult(DrbgStatus.ReseedRequired)); } // 2. If (additional_input != Null), then if (additionalInput.BitLength != 0) { // 2.1 additional_input = Block_Cipher_df(additional_input, seedlen) var blockCipherDf = BlockCipherDf(additionalInput, CounterAttributes.SeedLength); if (blockCipherDf.Success) { additionalInput = blockCipherDf.Bits; } else { ThisLogger.Debug("BlockCipherDf"); return(new DrbgResult(DrbgStatus.Error)); } // 2.2 (Key, V) = Update(additional_input, Key, V) Update(additionalInput); } else { // 2 (cont) Else additional_input = 0^seedlen additionalInput = new BitString(CounterAttributes.SeedLength); } // 3. temp = Null BitString temp = new BitString(0); // 4. While (len(temp) < requested_number_of_bits) do: while (temp.BitLength < requestedNumberOfBits) { // 4.1 V = (V + 1) mod 2^outlen V = V.BitStringAddition(BitString.One()).GetLeastSignificantBits(CounterAttributes.OutputLength); // 4.2 output_block = Block_Encrypt(Key, V) BitString outputBlock = BlockEncrypt(Key, V); // 4.3 temp = temp || output_block temp = temp.ConcatenateBits(outputBlock); } // 5. returned_bits = Leftmost requested_number_of_bits of temp var returnedBits = temp.GetMostSignificantBits(requestedNumberOfBits); // 6. (Key, V) = Update(additional_input, Key, V) // Comment: Update for backtracking resistance Update(additionalInput); // 7. reseed_counter = reseed_counter + 1 ++ReseedCounter; // 8. Return SUCCESS and returned bits; also return Key, V and // reseed_counter as the new_working_state // NOTE: returned_bits is a function parameter passed by non-const // value. m_Key, m_V, and m_reseed_counter hold the new working state return(new DrbgResult(returnedBits)); }