/// <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));
     }
 }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <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.");
            }
        }
Example #5
0
        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.");
                    }
                }
            }
        }
Example #6
0
        /// <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);
 }
Example #9
0
    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);
    }