Beispiel #1
0
        /// <summary>
        /// Try get legal nonce sizes.
        /// </summary>
        /// <param name="mode">Symmetric algorithm cipher mode.</param>
        /// <param name="padding">Symmetric algorithm padding mode.</param>
        /// <param name="nonceSizes">Legal nonce size bits.</param>
        /// <returns></returns>
        public bool TryGetNonceSizes(SymmetricCipherMode mode, SymmetricPaddingMode padding, out KeySizes[] nonceSizes)
        {
            switch (padding)
            {
            case SymmetricPaddingMode.NoPadding: break;

            default: nonceSizes = null; return(false);
            }
            switch (mode)
            {
            case SymmetricCipherMode.CCM:
                if (this.BlockSize == 128)
                {
                    nonceSizes = new KeySizes[] { new KeySizes(56, 104, 8) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.EAX:
                if (this.BlockSize == 64 || this.BlockSize == 128)
                {
                    nonceSizes = new KeySizes[] { new KeySizes(8, 2147483640, 8) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.GCM:
                if (this.BlockSize == 128)
                {
                    nonceSizes = new KeySizes[] { new KeySizes(8, 2147483640, 8) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.OCB:
                if (this.BlockSize == 128)
                {
                    nonceSizes = new KeySizes[] { new KeySizes(0, 120, 8) };
                    return(true);
                }
                break;

            default: break;
            }
            nonceSizes = null;
            return(false);
        }
Beispiel #2
0
        /// <summary>
        /// Try get legal mac sizes.
        /// </summary>
        /// <param name="mode">Symmetric algorithm cipher mode.</param>
        /// <param name="padding">Symmetric algorithm padding mode.</param>
        /// <param name="macSizes">Legal mac size bits.</param>
        /// <returns></returns>
        public bool TryGetMacSizes(SymmetricCipherMode mode, SymmetricPaddingMode padding, out KeySizes[] macSizes)
        {
            switch (padding)
            {
            case SymmetricPaddingMode.NoPadding: break;

            default: macSizes = null; return(false);
            }
            switch (mode)
            {
            case SymmetricCipherMode.CCM:
                if (this.BlockSize == 128)
                {
                    macSizes = new KeySizes[] { new KeySizes(32, 128, 16) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.EAX:
                if (this.BlockSize == 64 || this.BlockSize == 128)
                {
                    macSizes = new KeySizes[] { new KeySizes(8, this.BlockSize, 8) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.GCM:
                if (this.BlockSize == 128)
                {
                    macSizes = new KeySizes[] { new KeySizes(32, 128, 8) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.OCB:
                if (this.BlockSize == 128)
                {
                    macSizes = new KeySizes[] { new KeySizes(64, 128, 8) };
                    return(true);
                }
                break;

            default: break;
            }
            macSizes = null;
            return(false);
        }
Beispiel #3
0
        private static void Test1()
        {
            Array modes    = Enum.GetValues(typeof(SymmetricCipherMode));
            Array paddings = Enum.GetValues(typeof(SymmetricPaddingMode));

            byte[] test = Utilities.ScoopBytes(37);
            //
            Type type = typeof(SymmetricAlgorithmHelper);

            PropertyInfo[] properties = type.GetProperties(BindingFlags.Static | BindingFlags.Public);
            foreach (PropertyInfo property in properties)
            {
                if (property.GetValue(type, null) is IBlockAlgorithm algorithm)
                {
                    foreach (int modeValue in modes)
                    {
                        SymmetricCipherMode mode = (SymmetricCipherMode)modeValue;
                        foreach (int paddingValue in paddings)
                        {
                            _total++;
                            SymmetricPaddingMode padding = (SymmetricPaddingMode)paddingValue;
                            string mechanism             = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}", algorithm.Mechanism, mode.ToString(), padding.ToString());

                            if (algorithm.TryGetIVSizes(mode, padding, out KeySizes[] ivSizes))
Beispiel #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);
        }
Beispiel #5
0
        /// <summary>
        /// Try get legal sizes.
        /// </summary>
        /// <param name="mode">Symmetric algorithm cipher mode.</param>
        /// <param name="padding">Symmetric algorithm padding mode.</param>
        /// <param name="ivSizes">Legal iv size bits.</param>
        /// <returns></returns>
        public bool TryGetIVSizes(SymmetricCipherMode mode, SymmetricPaddingMode padding, out KeySizes[] ivSizes)
        {
            bool pad;

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

            case SymmetricPaddingMode.PKCS7:
            case SymmetricPaddingMode.Zeros:
            case SymmetricPaddingMode.X923:
            case SymmetricPaddingMode.ISO10126:
            case SymmetricPaddingMode.ISO7816_4:
            case SymmetricPaddingMode.TBC: pad = true; break;

            default: ivSizes = null; return(false);
            }
            switch (mode)
            {
            case SymmetricCipherMode.CBC: ivSizes = new KeySizes[] { new KeySizes(this.BlockSize, this.BlockSize, 0) }; return(true);

            case SymmetricCipherMode.ECB: ivSizes = new KeySizes[] { new KeySizes(0, 0, 0) }; return(true);

            case SymmetricCipherMode.OFB: ivSizes = new KeySizes[] { new KeySizes(8, this.BlockSize, 8) }; return(true);

            case SymmetricCipherMode.CFB: ivSizes = new KeySizes[] { new KeySizes(8, this.BlockSize, 8) }; return(true);

            case SymmetricCipherMode.CTS:
                if (!pad)
                {
                    ivSizes = new KeySizes[] { new KeySizes(this.BlockSize, this.BlockSize, 0) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.CTR:
            {
                int min = Math.Max(this.BlockSize / 2, this.BlockSize - 64);
                ivSizes = new KeySizes[] { new KeySizes(min, this.BlockSize, 8) };
                return(true);
            }

            case SymmetricCipherMode.CTS_ECB:
                if (!pad)
                {
                    ivSizes = new KeySizes[] { new KeySizes(0, 0, 0) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.GOFB:
                if (this.BlockSize == 64)
                {
                    ivSizes = new KeySizes[] { new KeySizes(this.BlockSize, this.BlockSize, 0) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.OpenPGPCFB:
                ivSizes = new KeySizes[] { new KeySizes(8, this.BlockSize, 8) };
                return(true);

            case SymmetricCipherMode.SIC:
                if (this.BlockSize >= 128)
                {
                    int min = Math.Max(this.BlockSize / 2, this.BlockSize - 64);
                    ivSizes = new KeySizes[] { new KeySizes(min, this.BlockSize, 8) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.CCM:
                if (!pad && this.BlockSize == 128)
                {
                    ivSizes = new KeySizes[] { new KeySizes(56, 104, 8) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.EAX:
                if (!pad && (this.BlockSize == 64 || this.BlockSize == 128))
                {
                    ivSizes = new KeySizes[] { new KeySizes(8, 2147483640, 8) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.GCM:
                if (!pad && this.BlockSize == 128)
                {
                    ivSizes = new KeySizes[] { new KeySizes(8, 2147483640, 8) };
                    return(true);
                }
                break;

            case SymmetricCipherMode.OCB:
                if (!pad && this.BlockSize == 128)
                {
                    ivSizes = new KeySizes[] { new KeySizes(0, 120, 8) };
                    return(true);
                }
                break;

            default: break;
            }
            ivSizes = null;
            return(false);
        }