Пример #1
0
            /// <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);
            }
Пример #2
0
        /// <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));
            }
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <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));
        }
Пример #7
0
        /// <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()),
            });
        }
Пример #8
0
 /// <inheritdoc/>
 public bool Compare(byte[] object1, byte[] object2)
 {
     return(CryptoUtilities.BufferEquals(object1, object2));
 }