/// <summary> /// Generates a new <see cref="SecureSymmetricKey" />. /// </summary> /// <param name="algorithm"> /// The symmetric-key algorithm that the generated key is derived to interoperate with. The default value is /// <see cref="SymmetricAlgorithmSpecification.Aes256Cbc" />. /// </param> /// <param name="derivationMode"> /// The mode used to derive the generated key. The default value is /// <see cref="SecureSymmetricKeyDerivationMode.XorLayeringWithSubstitution" />. /// </param> /// <returns> /// A new <see cref="SecureSymmetricKey" />. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="algorithm" /> is equal to <see cref="SymmetricAlgorithmSpecification.Unspecified" /> or /// <paramref name="derivationMode" /> is equal to <see cref="SecureSymmetricKeyDerivationMode.Unspecified" />. /// </exception> public static SecureSymmetricKey New(SymmetricAlgorithmSpecification algorithm, SecureSymmetricKeyDerivationMode derivationMode) { using (var keySource = new PinnedBuffer(KeySourceLengthInBytes, true)) { RandomnessProvider.GetBytes(keySource); return(New(algorithm, derivationMode, keySource)); } }
/// <summary> /// Generates cryptographically secure pseudo-random bytes that are pinned in memory and encrypted at rest. /// </summary> /// <remarks> /// This method is useful for generating keys and other sensitive random values. /// </remarks> /// <param name="length"> /// The length of the random buffer, in bytes. /// </param> /// <returns> /// A cryptographically secure pseudo-random byte array of specified length. /// </returns> public static SecureBuffer GenerateHardenedRandomBytes(Int32 length) { var hardenedRandomBytes = new SecureBuffer(length); hardenedRandomBytes.Access((pinnedBuffer) => { RandomnessProvider.GetBytes(pinnedBuffer); }); return(hardenedRandomBytes); }
/// <summary> /// Initializes a new instance of the <see cref="SecureBuffer" /> class. /// </summary> /// <param name="length"> /// The length of the buffer, in bytes. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="length" /> is less than or equal to zero. /// </exception> public SecureBuffer(Int32 length) : base(ConcurrencyControlMode.SingleThreadLock) { Length = length.RejectIf().IsLessThanOrEqualTo(0, nameof(length)); Entropy = new PinnedBuffer(EntropyLength, true); RandomnessProvider.GetBytes(Entropy); var ciphertextBytes = ProtectedData.Protect(new Byte[length], Entropy, Scope); Ciphertext = new PinnedBuffer(ciphertextBytes.Length, true); Array.Copy(ciphertextBytes, Ciphertext, Ciphertext.Length); }
/// <summary> /// Converts the value of the current <see cref="SecureSymmetricKey" /> to its equivalent binary representation. /// </summary> /// <returns> /// A binary representation of the current <see cref="SecureSymmetricKey" />. /// </returns> public SecureBuffer ToBuffer() { var resultBuffer = new SecureBuffer(SerializedLength); try { using (var controlToken = StateControl.Enter()) { using (var plaintextBuffer = new PinnedBuffer(SerializedPlaintextLength, true)) { KeySource.Access(pinnedKeySourceBuffer => { Array.Copy(pinnedKeySourceBuffer, 0, plaintextBuffer, KeySourceBufferIndex, KeySourceLengthInBytes); }); plaintextBuffer[AlgorithmBufferIndex] = (Byte)Algorithm; plaintextBuffer[DerivationModeBufferIndex] = (Byte)DerivationMode; using (var cipher = BufferEncryptionAlgorithm.ToCipher(RandomnessProvider)) { using (var initializationVector = new PinnedBuffer(cipher.BlockSizeInBytes, true)) { RandomnessProvider.GetBytes(initializationVector); resultBuffer.Access(pinnedResultBuffer => { using (var ciphertext = cipher.Encrypt(plaintextBuffer, BufferEncryptionKey, initializationVector)) { Array.Copy(ciphertext, 0, pinnedResultBuffer, 0, SerializedLength); } }); } } } } return(resultBuffer); } catch { resultBuffer.Dispose(); throw new SecurityException("Key serialization failed."); } }
private Byte[] Encrypt(T plaintextObject, PinnedBuffer key, SymmetricAlgorithmSpecification algorithm, Byte[] initializationVector) { var plaintext = BinarySerializer.Serialize(plaintextObject); var plaintextLength = plaintext.Length; using (var pinnedPlaintext = new PinnedBuffer(plaintextLength, true)) { Array.Copy(plaintext, pinnedPlaintext, plaintextLength); using (var cipher = algorithm.ToCipher(RandomnessProvider)) { switch (cipher.Mode) { case CipherMode.CBC: using (var processedInitializationVector = new PinnedBuffer(cipher.BlockSizeInBytes, true)) { if (initializationVector is null) { RandomnessProvider.GetBytes(processedInitializationVector); } else { Array.Copy(initializationVector.RejectIf(argument => argument.Length < cipher.BlockSizeInBytes, nameof(initializationVector)), processedInitializationVector, cipher.BlockSizeInBytes); } return(cipher.Encrypt(pinnedPlaintext, key, processedInitializationVector)); } case CipherMode.ECB: return(cipher.Encrypt(pinnedPlaintext, key, null)); default: throw new InvalidOperationException($"The specified cipher mode, {cipher.Mode}, is not supported."); } } } }
/// <summary> /// Calculates a hash value for the specified plaintext object. /// </summary> /// <param name="plaintextObject"> /// The plaintext object to hash. /// </param> /// <param name="algorithm"> /// The algorithm specification used to transform the plaintext. /// </param> /// <param name="saltingMode"> /// A value specifying whether or not salt is applied to the plaintext. /// </param> /// <returns> /// The resulting hash value. /// </returns> /// <exception cref="SecurityException"> /// An exception was raised during hashing or serialization. /// </exception> public Byte[] CalculateHash(T plaintextObject, HashingAlgorithmSpecification algorithm, SaltingMode saltingMode) { try { switch (saltingMode) { case SaltingMode.Salted: var salt = new Byte[SaltLengthInBytes]; RandomnessProvider.GetBytes(salt); return(CalculateHash(plaintextObject, algorithm, salt)); default: return(CalculateHash(plaintextObject, algorithm, null)); } } catch { throw new SecurityException("The hashing operation failed."); } }
public override void GenerateKey() { Key = new Byte[(KeySize / 8)]; RandomnessProvider.GetBytes(Key); }
public override void GenerateIV() { IV = new Byte[(BlockSize / 8)]; RandomnessProvider.GetBytes(IV); }
private TileData[,] GenerateTileTypeMatrix() { var tiles = new TileData[Width, Height]; // atmosphere for (int j = 0; j < AtmosphereEndsAt; j++) { for (int i = 0; i < Width; i++) { tiles[i, j] = GetDefaultTileForHeight(j); } } // mineral, deposit, granite, magma, default for (int j = AtmosphereEndsAt; j < Soil3EndsAt; j++) { var y = (float)(j - AtmosphereEndsAt) / (Soil3EndsAt - AtmosphereEndsAt); var td = new List <TileData>(); var mineralCount = (int)(Width * MineralProbabilityByHeight.Evaluate(y)); td.AddRange(Enumerable.Repeat(GetMineralTileForHeight(j), mineralCount).ToList()); var depositCount = (int)(Width * DepositProbabilityByHeight.Evaluate(y)); td.AddRange(Enumerable.Repeat(GetDepositTileForHeight(j), depositCount).ToList()); var graniteCount = (int)(Width * GraniteProbabilityByHeight.Evaluate(y)); td.AddRange(Enumerable.Repeat(GetGraniteTileForHeight(j), graniteCount).ToList()); var magmaCount = (int)(Width * MagmaProbabilityByHeight.Evaluate(y)); td.AddRange(Enumerable.Repeat(GetMagmaTileForHeight(j), magmaCount).ToList()); var defaultCount = Width - (mineralCount + depositCount + graniteCount + magmaCount); td.AddRange(Enumerable.Repeat(GetDefaultTileForHeight(j), defaultCount).ToList()); td = RandomnessProvider.Shuffle(td); for (int i = 0; i < Width; i++) { tiles[i, j] = td[i]; } } // better mineral if (BetterMineralsOn) { for (int j = AtmosphereEndsAt; j < Soil3EndsAt; j++) { for (int i = 0; i < Width; i++) { if (tiles[i, j].TileType != TileType.Mineral) { continue; } if (tiles[i, j].Layer == Layer.C) { continue; } var x = 2f * i / (Width - 2) - 1; var betterMineralProbability = BetterMineralProbabilityByWidth.Evaluate(x); if (RandomnessProvider.GetFloat() > betterMineralProbability) { continue; } tiles[i, j].Layer++; } } } // core for (int j = Soil3EndsAt; j < Height; j++) { for (int i = 0; i < Width; i++) { tiles[i, j] = GetDefaultTileForHeight(j); } } // place lander var startPoint = TerraformingFacilityInitialPosition; tiles[startPoint.x, startPoint.y] = tiles[startPoint.x, startPoint.y] .WithFacility(FacilityType.TerraformingFacility, TileType.Surface); tiles[startPoint.x, startPoint.y + 1] = tiles[startPoint.x, startPoint.y + 1] .WithFacility(FacilityType.TerraformingFacility, TileType.Soil); return(tiles); }