/// <summary> /// Initializes a new instance of the <see cref="SymmetricCryptographicKey" /> class. /// </summary> /// <param name="provider">The provider that created this instance.</param> /// <param name="name">The name of the base algorithm to use.</param> /// <param name="mode">The algorithm's mode (i.e. streaming or some block mode).</param> /// <param name="padding">The padding to use.</param> /// <param name="keyMaterial">The key.</param> internal SymmetricCryptographicKey(SymmetricKeyAlgorithmProvider provider, SymmetricAlgorithmName name, SymmetricAlgorithmMode mode, SymmetricAlgorithmPadding padding, byte[] keyMaterial) { Requires.NotNull(provider, nameof(provider)); Requires.NotNull(keyMaterial, nameof(keyMaterial)); if (name == SymmetricAlgorithmName.Aes && mode == SymmetricAlgorithmMode.Ccm && padding == SymmetricAlgorithmPadding.None) { // On Android encryption misbehaves causing our unit tests to fail. throw new NotSupportedException(); } this.provider = provider; this.Name = name; this.Mode = mode; this.Padding = padding; this.key = new SecretKeySpec(keyMaterial, this.Name.GetString()); this.KeySize = keyMaterial.Length * 8; }
/// <summary> /// Initializes a new instance of the <see cref="SymmetricCryptographicKey" /> class. /// </summary> /// <param name="keyMaterial">The symmetric key.</param> /// <param name="symmetricAlgorithmProvider">The symmetric algorithm of the provider creating this key.</param> internal SymmetricCryptographicKey(byte[] keyMaterial, SymmetricKeyAlgorithmProvider symmetricAlgorithmProvider) { Requires.NotNullOrEmpty(keyMaterial, nameof(keyMaterial)); Requires.NotNull(symmetricAlgorithmProvider, nameof(symmetricAlgorithmProvider)); this.symmetricAlgorithmProvider = symmetricAlgorithmProvider; // Copy the key material so our caller can reuse their buffer. this.keyMaterial = new byte[keyMaterial.Length]; Array.Copy(keyMaterial, this.keyMaterial, keyMaterial.Length); this.Name = symmetricAlgorithmProvider.Name; this.Mode = symmetricAlgorithmProvider.Mode; this.Padding = symmetricAlgorithmProvider.Padding; if (this.Padding == SymmetricAlgorithmPadding.PKCS7) { this.flags |= BCryptEncryptFlags.BCRYPT_BLOCK_PADDING; } }
/// <summary> /// Initializes a new instance of the <see cref="CryptographicKey" /> class. /// </summary> /// <param name="key">The WinRT cryptographic key.</param> /// <param name="symmetricAlgorithmProvider">The symmetric algorithm of the provider creating this key.</param> /// <param name="canExportPrivateKey"> /// A value indicating whether <see cref="Export(CryptographicPrivateKeyBlobType)"/> /// can be expected to work. /// </param> internal CryptographicKey(Platform.CryptographicKey key, SymmetricKeyAlgorithmProvider symmetricAlgorithmProvider, bool canExportPrivateKey) : this(key, canExportPrivateKey) { this.symmetricAlgorithmProvider = symmetricAlgorithmProvider; }
/// <summary> /// Checks whether the given length is a valid one for an input buffer to the symmetric algorithm. /// </summary> /// <param name="lengthInBytes">The length of the input buffer in bytes.</param> /// <param name="cipher">The cipher that dictates the allowed input sizes.</param> /// <returns><c>true</c> if the size is allowed; <c>false</c> otherwise.</returns> private bool IsValidInputSize(int lengthInBytes, Cipher cipher) { int blockSizeInBytes = SymmetricKeyAlgorithmProvider.GetBlockSize(this.Mode, cipher); return(lengthInBytes % blockSizeInBytes == 0); }