Пример #1
0
        public void Encrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> source,
                            Span <byte> destination, Span <byte> tag, ReadOnlySpan <byte> associatedData = default)
        {
            var input = ArrayPool <byte> .Shared.Rent(source.Length);

            var output = ArrayPool <byte> .Shared.Rent(destination.Length + tag.Length);

            try
            {
                _engine = new BufferedAeadBlockCipher(new GcmBlockCipher(_aes));
                _engine.Init(true, new AeadParameters(_key, 128, nonce.ToArray(), associatedData.ToArray()));

                source.CopyTo(input);

                _engine.DoFinal(input, 0, source.Length, output, 0);

                output.AsSpan(0, destination.Length).CopyTo(destination);
                output.AsSpan(destination.Length, tag.Length).CopyTo(tag);
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(input);

                ArrayPool <byte> .Shared.Return(output);
            }
        }
Пример #2
0
        public BcAesGcmCrypto(byte[] key)
        {
            _aes = new AesFastEngine();
            _key = new KeyParameter(key);

            _engine = new BufferedAeadBlockCipher(new GcmBlockCipher(_aes));
        }
        /// <summary>
        /// Create a buffered cipher to encrypt or decrypt a stream as it is being read
        /// </summary>
        /// <param name="forEncryption">forEncryption if true the cipher is initialised for encryption, if false for decryption</param>
        /// <param name="key">Key to be used for encryption</param>
        /// <param name="nonce">Nonce to be used for encryption</param>
        /// <param name="tagSize">Tag size in bits for the tag appended in the end of the stream</param>
        /// <param name="associatedText">Additional associated data</param>
        /// <returns></returns>
        internal static IBufferedCipher CreateCipher(bool forEncryption, byte[] key, int tagSize, byte[] nonce, byte[] associatedText)
        {
            var aesEngine       = new AesEngine();
            var blockCipher     = new GcmBlockCipher(aesEngine);
            var aeadBlockCipher = new BufferedAeadBlockCipher(blockCipher);
            var parameters      = new AeadParameters(new KeyParameter(key), tagSize, nonce, associatedText);

            aeadBlockCipher.Init(forEncryption, parameters);
            return(aeadBlockCipher);
        }
Пример #4
0
        /// <summary>
        /// Generate cipher. The cipher can be reused. Except GCM cipher mode.
        /// </summary>
        /// <param name="forEncryption"></param>
        /// <param name="mode">Symmetric algorithm cipher mode.</param>
        /// <param name="padding">Symmetric algorithm padding mode.</param>
        /// <param name="parameters">Parameters.</param>
        /// <returns></returns>
        /// <exception cref="Exception"/>
        public IBufferedCipher GenerateCipher(bool forEncryption, SymmetricCipherMode mode, SymmetricPaddingMode padding, ICipherParameters parameters)
        {
            IBlockCipherPadding pad;

            switch (padding)
            {
            case SymmetricPaddingMode.NoPadding: pad = null; break;

            case SymmetricPaddingMode.PKCS7: pad = Common.PKCS7Padding; break;

            case SymmetricPaddingMode.Zeros: pad = Common.ZEROBYTEPadding; break;

            case SymmetricPaddingMode.X923: pad = Common.X923Padding; break;

            case SymmetricPaddingMode.ISO10126: pad = Common.ISO10126d2Padding; break;

            case SymmetricPaddingMode.ISO7816_4: pad = Common.ISO7816d4Padding; break;

            case SymmetricPaddingMode.TBC: pad = Common.TBCPadding; break;

            default: throw new CryptographicException("Unsupported padding mode.");
            }
            IBlockCipher    engine = GenerateEngine();
            IBufferedCipher cipher;

            switch (mode)
            {
            case SymmetricCipherMode.CBC:
                cipher = pad is null ? new BufferedBlockCipher(new CbcBlockCipher(engine))
                        : new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), pad);
                break;

            case SymmetricCipherMode.ECB:
                cipher = pad is null ? new BufferedBlockCipher(engine) : new PaddedBufferedBlockCipher(engine, pad);
                break;

            case SymmetricCipherMode.OFB:
                int ofbs = ((ParametersWithIV)parameters).GetIV().Length * 8;
                cipher = pad is null ? new BufferedBlockCipher(new OfbBlockCipher(engine, ofbs))
                        : new PaddedBufferedBlockCipher(new OfbBlockCipher(engine, ofbs), pad);
                break;

            case SymmetricCipherMode.CFB:
                int cfbs = ((ParametersWithIV)parameters).GetIV().Length * 8;
                cipher = pad is null ? new BufferedBlockCipher(new CfbBlockCipher(engine, cfbs))
                        : new PaddedBufferedBlockCipher(new CfbBlockCipher(engine, cfbs), pad);
                break;

            case SymmetricCipherMode.CTS:
                if (pad is null)
                {
                    cipher = new CtsBlockCipher(new CbcBlockCipher(engine));
                    break;
                }
                throw new CryptographicException("CTS cipher mode can only select SymmetricPaddingMode.NoPadding padding mode.");

            case SymmetricCipherMode.CTR:
                cipher = pad is null ? new BufferedBlockCipher(new SicBlockCipher(engine))
                        : new PaddedBufferedBlockCipher(new SicBlockCipher(engine), pad);
                break;

            case SymmetricCipherMode.CTS_ECB:
                if (pad is null)
                {
                    cipher = new CtsBlockCipher(engine);
                    break;
                }
                throw new CryptographicException("CTS cipher mode can only select SymmetricPaddingMode.NoPadding padding mode.");

            case SymmetricCipherMode.GOFB:
                if (this.BlockSize == 64)
                {
                    cipher = pad is null ? new BufferedBlockCipher(new GOfbBlockCipher(engine))
                            : new PaddedBufferedBlockCipher(new GOfbBlockCipher(engine), pad);
                    break;
                }
                throw new CryptographicException("GOFB cipher mode uses with a block size of 64 bits algorithm (e.g. DESede).");

            case SymmetricCipherMode.OpenPGPCFB:
                cipher = pad is null ? new BufferedBlockCipher(new OpenPgpCfbBlockCipher(engine))
                        : new PaddedBufferedBlockCipher(new OpenPgpCfbBlockCipher(engine), pad);
                break;

            case SymmetricCipherMode.SIC:
                if (this.BlockSize >= 128)
                {
                    cipher = pad is null ? new BufferedBlockCipher(new SicBlockCipher(engine))
                            : new PaddedBufferedBlockCipher(new SicBlockCipher(engine), pad);
                    break;
                }
                throw new CryptographicException("SIC cipher mode uses with a block size of at least 128 bits algorithm (e.g. AES).");

            case SymmetricCipherMode.CCM:
                if (pad is null)
                {
                    if (this.BlockSize == 128)
                    {
                        cipher = new BufferedAeadBlockCipher(new CcmBlockCipher(engine));
                        break;
                    }
                    throw new CryptographicException("CCM cipher mode uses with a block size of 128 bits algorithm (e.g. AES).");
                }
                throw new CryptographicException("CCM cipher mode can only select SymmetricPaddingMode.NoPadding padding mode.");

            case SymmetricCipherMode.EAX:
                if (pad is null)
                {
                    if (this.BlockSize == 64 || this.BlockSize == 128)
                    {
                        cipher = new BufferedAeadBlockCipher(new EaxBlockCipher(engine));
                        break;
                    }
                    throw new CryptographicException("EAX cipher mode uses with a block size of 64 or 128 bits algorithm (e.g. DESede, AES).");
                }
                throw new CryptographicException("EAX cipher mode can only select SymmetricPaddingMode.NoPadding padding mode.");

            case SymmetricCipherMode.GCM:
                if (pad is null)
                {
                    if (this.BlockSize == 128)
                    {
                        cipher = new BufferedAeadBlockCipher(new GcmBlockCipher(engine));
                        break;
                    }
                    throw new CryptographicException("GCM cipher mode uses with a block size of 128 bits algorithm (e.g. AES).");
                }
                throw new CryptographicException("GCM cipher mode can only select SymmetricPaddingMode.NoPadding padding mode.");

            case SymmetricCipherMode.OCB:
                if (pad is null)
                {
                    if (this.BlockSize == 128)
                    {
                        cipher = new BufferedAeadBlockCipher(new OcbBlockCipher(engine, GenerateEngine()));
                        break;
                    }
                    throw new CryptographicException("OCB cipher mode uses with a block size of 128 bits algorithm (e.g. AES).");
                }
                throw new CryptographicException("OCB cipher mode can only select SymmetricPaddingMode.NoPadding padding mode.");

            default: throw new CryptographicException("Unsupported cipher mode.");
            }
            cipher.Init(forEncryption, parameters);
            return(cipher);
        }