{ *********************************************************************************** } { * CryptoLib Library * } { * Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe * } { * Github Repository * } { * Distributed under the MIT software license, see the accompanying file LICENSE * } { * or visit http://www.opensource.org/licenses/mit-license.php. * } { * Acknowledgements: * } { * * } { * Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring * } { * development of this library * } { * ******************************************************************************* * } (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *) unit ClpCryptoApiRandomGenerator; {$I CryptoLib.inc} interface uses ClpIRandomNumberGenerator, ClpRandomNumberGenerator, ClpICryptoApiRandomGenerator, ClpIRandomGenerator, ClpCryptoLibTypes; resourcestring SNegativeOffset = 'Start Offset Cannot be Negative, "Start"'; SArrayTooSmall = 'Byte Array Too Small For Requested Offset and Length'; type /// /// Uses TRandomNumberGenerator.Create() to Get randomness generator /// TCryptoApiRandomGenerator = class(TInterfacedObject, ICryptoApiRandomGenerator, IRandomGenerator) strict private var FrndProv: IRandomNumberGenerator; public /// /// Uses TRandomNumberGenerator.CreateRNG() to Get randomness generator /// constructor Create(); overload; constructor Create(const rng: IRandomNumberGenerator); overload; /// Add more seed material to the generator. /// A byte array to be mixed into the generator's state. procedure AddSeedMaterial(const seed: TCryptoLibByteArray); overload; virtual; /// Add more seed material to the generator. /// A long value to be mixed into the generator's state. procedure AddSeedMaterial(seed: Int64); overload; virtual; /// Fill byte array with random values. /// Array to be filled. procedure NextBytes(const bytes: TCryptoLibByteArray); overload; virtual; /// Fill byte array with random values. /// Array to receive bytes. /// Index to start filling at. /// Length of segment to fill. procedure NextBytes(const bytes: TCryptoLibByteArray; start, len: Int32); overload; virtual; end; implementation { TCryptoApiRandomGenerator } procedure TCryptoApiRandomGenerator.AddSeedMaterial(seed: Int64); begin // We don't care about the seed end; procedure TCryptoApiRandomGenerator.AddSeedMaterial (const seed: TCryptoLibByteArray); begin // We don't care about the seed end; constructor TCryptoApiRandomGenerator.Create(const rng: IRandomNumberGenerator); begin Inherited Create(); FrndProv := rng; end; constructor TCryptoApiRandomGenerator.Create; begin Create(TRandomNumberGenerator.CreateRNG()); end; procedure TCryptoApiRandomGenerator.NextBytes(const bytes: TCryptoLibByteArray); begin FrndProv.GetBytes(bytes); end; procedure TCryptoApiRandomGenerator.NextBytes(const bytes: TCryptoLibByteArray; start, len: Int32); var tmpBuf: TCryptoLibByteArray; begin if (start < 0) then begin raise EArgumentCryptoLibException.CreateRes(@SNegativeOffset); end; if (System.Length(bytes) < (start + len)) then begin raise EArgumentCryptoLibException.CreateRes(@SArrayTooSmall); end; if ((System.Length(bytes) = len) and (start = 0)) then begin NextBytes(bytes); end else begin System.SetLength(tmpBuf, len); NextBytes(tmpBuf); System.Move(tmpBuf[0], bytes[start], len * System.SizeOf(Byte)); end; end; end.