/// <inheritdoc /> public override unsafe byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { switch (this.baseKey.Padding) { case SymmetricAlgorithmPadding.None: Requires.Argument(this.baseKey.IsValidInputSize(inputCount), nameof(inputCount), "Length is not a non-zero multiple of block size and no padding is selected."); if (inputCount == 0) { return(EmptyBuffer); } break; case SymmetricAlgorithmPadding.PKCS7: break; case SymmetricAlgorithmPadding.Zeros: // We have to implement this padding ourselves. if (inputCount == 0) { return(EmptyBuffer); } CryptoUtilities.ApplyZeroPadding( ref inputBuffer, this.baseKey.symmetricAlgorithmProvider.BlockLength, ref inputOffset, ref inputCount); break; default: throw new NotSupportedException(); } int cbResult; BCryptEncrypt( this.platformKey, new ArraySegment <byte>(inputBuffer, inputOffset, inputCount), null, this.iv.AsArraySegment(), default(ArraySegment <byte>), out cbResult, this.baseKey.flags).ThrowOnError(); byte[] output = new byte[cbResult]; BCryptEncrypt( this.platformKey, new ArraySegment <byte>(inputBuffer, inputOffset, inputCount), null, this.iv.AsArraySegment(), new ArraySegment <byte>(output), out cbResult, this.baseKey.flags).ThrowOnError(); Array.Resize(ref output, cbResult); return(output); }
/// <inheritdoc /> protected internal override bool VerifySignature(byte[] data, byte[] signature) { using (var algorithm = MacAlgorithmProvider.GetAlgorithm(this.algorithm)) { byte[] computedMac; #if Android algorithm.Init(MacAlgorithmProvider.GetSecretKey(this.algorithm, this.key)); computedMac = algorithm.DoFinal(data); #else algorithm.Key = this.key; computedMac = algorithm.ComputeHash(data); #endif return(CryptoUtilities.BufferEquals(computedMac, signature)); } }
/// <inheritdoc /> protected internal override byte[] Encrypt(byte[] plaintext, byte[] iv) { Verify.Operation(!this.Mode.IsAuthenticated(), "Cannot encrypt using this function when using an authenticated block chaining mode."); var key = this.GetInitializedKey(ref this.encryptorKey, iv); switch (this.Padding) { case SymmetricAlgorithmPadding.None: Requires.Argument(this.IsValidInputSize(plaintext.Length), nameof(plaintext), "Length is not a non-zero multiple of block size and no padding is selected."); break; case SymmetricAlgorithmPadding.PKCS7: break; case SymmetricAlgorithmPadding.Zeros: // We have to implement this padding ourselves. if (plaintext.Length == 0) { return(plaintext); } CryptoUtilities.ApplyZeroPadding(ref plaintext, this.symmetricAlgorithmProvider.BlockLength); break; default: throw new NotSupportedException(); } // We use the IV if the caller passes it in, or use // the resulting IV of the last cipher operation if the caller // did not specify an IV. // Copy the IV because the native code changes it, and // our contract with the caller is that we don't. this.encryptorIv = CopyBufferOrNull(iv) ?? this.encryptorIv; byte[] cipherText = BCryptEncrypt( key, plaintext, IntPtr.Zero, this.encryptorIv, this.flags).ToArray(); return(cipherText); }
/// <summary> /// Fills out the rest of an <see cref="RSAParameters"/> structure /// given the public key data and the secrets P and Q. /// </summary> /// <param name="p">The P parameter (Big endian)</param> /// <param name="q">The Q parameter (Big endian)</param> /// <param name="exponent">The e (public exponent) (big endian)</param> /// <param name="modulus">The modulus (big endian)</param> /// <returns>The fully calculated <see cref="RSAParameters"/></returns> private static RSAParameters Create(byte[] p, byte[] q, byte[] exponent, byte[] modulus) { var addlParameters = GetFullPrivateParameters( p: CryptoUtilities.FromPositiveBigEndian(p), q: CryptoUtilities.FromPositiveBigEndian(q), e: CryptoUtilities.FromPositiveBigEndian(exponent), n: CryptoUtilities.FromPositiveBigEndian(modulus)); return(new RSAParameters { P = p, Q = q, Exponent = exponent, Modulus = modulus, D = addlParameters.D, DP = addlParameters.DP, DQ = addlParameters.DQ, InverseQ = addlParameters.InverseQ, }); }
/// <inheritdoc /> public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { if (this.mode.IsBlockCipher()) { if (this.padding == SymmetricAlgorithmPadding.Zeros) { // We apply Zeros padding ourselves because BouncyCastle for some reason // does it wrong. For example, if the input buffer is a block length already, // it will return an extra block of ciphertext (as if it added a block of // zeros, perhaps.) CryptoUtilities.ApplyZeroPadding(ref inputBuffer, this.transform.BlockSize, ref inputOffset, ref inputCount); } return(this.transform.DoFinal(inputBuffer, inputOffset, inputCount)); } else { return(this.transform.Update(inputBuffer, inputOffset, inputCount)); } }
/// <inheritdoc /> protected internal override byte[] Encrypt(byte[] data, byte[] iv) { bool paddingInUse = this.Padding != SymmetricAlgorithmPadding.None; Requires.Argument(iv == null || this.Mode.UsesIV(), nameof(iv), "IV supplied but does not apply to this cipher."); Verify.Operation(!this.Mode.IsAuthenticated(), "Cannot encrypt using this function when using an authenticated block chaining mode."); this.InitializeCipher(CipherMode.EncryptMode, iv, ref this.encryptingCipher); Requires.Argument(paddingInUse || this.IsValidInputSize(data.Length), nameof(data), "Length is not a multiple of block size and no padding is selected."); if (this.Padding == SymmetricAlgorithmPadding.Zeros) { // We apply Zeros padding ourselves because BouncyCastle for some reason // does it wrong. For example, if the input buffer is a block length already, // it will return an extra block of ciphertext (as if it added a block of // zeros, perhaps.) CryptoUtilities.ApplyZeroPadding(ref data, this.encryptingCipher.BlockSize); } return(this.DoCipherOperation(this.encryptingCipher, data)); }
/// <summary> /// Creates an <see cref="RSAParameters"/> structure initialized with /// the values for D, DP, DQ, InverseQ. /// </summary> /// <param name="p">The P parameter.</param> /// <param name="q">The Q parameter.</param> /// <param name="e">The e parameter.</param> /// <param name="n">The modulus (<paramref name="p"/> * <paramref name="q"/>)</param> /// <returns>An <see cref="RSAParameters"/> structure initialized with /// the values for D, DP, DQ, InverseQ.</returns> private static RSAParameters GetFullPrivateParameters(BigInteger p, BigInteger q, BigInteger e, BigInteger n) { Requires.Argument(p > 0, nameof(p), "Must be positive"); Requires.Argument(q > 0, nameof(q), "Must be positive"); Requires.Argument(e > 0, nameof(e), "Must be positive"); Requires.Argument(n > 0, nameof(n), "Must be positive"); var phiOfN = n - p - q + 1; // OR: (p - 1) * (q - 1); var d = ModInverse(e, phiOfN); var dp = d % (p - 1); var dq = d % (q - 1); var qInv = ModInverse(q, p); return(new RSAParameters { D = CryptoUtilities.CopyAndReverse(d.ToByteArray()), DP = CryptoUtilities.CopyAndReverse(dp.ToByteArray()), DQ = CryptoUtilities.CopyAndReverse(dq.ToByteArray()), InverseQ = CryptoUtilities.CopyAndReverse(qInv.ToByteArray()), }); }
/// <inheritdoc/> public bool Compare(byte[] object1, byte[] object2) { return(CryptoUtilities.BufferEquals(object1, object2)); }