Exemplo n.º 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);
            }
Exemplo n.º 2
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);
        }
            /// <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));
        }