Inheritance: IBlockCipher
示例#1
0
 /// <summary>
 /// Instance of AES with pre-defined key and IV.
 /// </summary>
 /// <param name="encoding"></param>
 /// <param name="key"></param>
 /// <param name="iv"></param>
 public AES(Encoding encoding, byte[] key, byte[] iv)
 {
     this.encoding = encoding;
     this.mode = new SicBlockCipher(new AesFastEngine());
     this.key = key;
     this.iv = iv;
 }
 private SicBlockCipher CreateDecryptor(string key)
 {
     SicBlockCipher decryptor = new SicBlockCipher(aes);
     
     decryptor.Init(false, new ParametersWithIV(new KeyParameter(DecodeKey(key)), new byte[aes.GetBlockSize()]));
     
     return decryptor;
 }
示例#3
0
 /// <summary>
 /// Generate a new key and IV.
 /// </summary>
 /// <param name="encoding"></param>
 public AES(Encoding encoding)
 {
     this.mode = new SicBlockCipher(new AesFastEngine());
     RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
     // Generate random key and IV
     rngCsp.GetBytes(key);
     rngCsp.GetBytes(iv);
     this.encoding = encoding;
 }
示例#4
0
 /// <summary>
 /// Load the key and IV from a file.
 /// </summary>
 /// <param name="encoding"></param>
 /// <param name="encryptionFile"></param>
 public AES(Encoding encoding, string encryptionFile)
 {
     this.mode = new SicBlockCipher(new AesFastEngine());
     byte[] combinedKey = new byte[32 * 2];
     combinedKey = File.ReadAllBytes(encryptionFile);
     combinedKey.Take(32).ToArray().CopyTo(key, 0);
     combinedKey.Skip(32).Take(32).ToArray().CopyTo(iv, 0);
     this.encoding = encoding;
 }
示例#5
0
 public EaxBlockCipher(IBlockCipher cipher)
 {
     this.blockSize         = cipher.GetBlockSize();
     this.mac               = new CMac(cipher);
     this.macBlock          = new byte[this.blockSize];
     this.associatedTextMac = new byte[this.mac.GetMacSize()];
     this.nonceMac          = new byte[this.mac.GetMacSize()];
     this.cipher            = new SicBlockCipher(cipher);
 }
示例#6
0
		public Packet MessageEncrypt(ICipherSetRemoteInfo remoteInfo, Packet inner)
		{
			CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo;

			var agreedValue = ECDHAgree (ri.RemotePublicKey, ri.EphemeralKeys.PrivateKey);

			// Hash the agreed key
			var hashedValue = Helpers.SHA256Hash (Helpers.ToByteArray(agreedValue, 20));

			// Fold to get the actual key for AES
			byte[] aesKey = Helpers.Fold (hashedValue);
			Random rnd = new Random ();

			// Setup and encrypt the actual data
			byte[] aesIV = new byte[16];
			rnd.NextBytes (aesIV);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (aesKey), aesIV);
			cipher.Init (true, parameters);

			var encryptedInner = new byte[inner.FullPacket.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (inner.FullPacket, encryptedInner, 0);
			bufferCipher.DoFinal (encryptedInner, offset);

			// Construct the packet minus the hmac
			Packet outPacket = new Packet ();
			outPacket.Body = new byte[29 + encryptedInner.Length];
			Buffer.BlockCopy (ri.EphemeralKeys.PublicKey, 0, outPacket.Body, 0, ri.EphemeralKeys.PublicKey.Length);
			Buffer.BlockCopy (aesIV, 0, outPacket.Body, 21, 4);
			Buffer.BlockCopy (encryptedInner, 0, outPacket.Body, 25, encryptedInner.Length);

			// ECDH for the hmac key using 
			var idAgreedValue = ECDHAgree (ri.RemotePublicKey, Key.PrivateKey);

			// Mash on the IV for the compound key
			byte[] macKey = new byte[24];
			byte[] idAgreedValueArray = Helpers.ToByteArray(idAgreedValue, 20);
			Buffer.BlockCopy(idAgreedValueArray, 0, macKey, 0, idAgreedValueArray.Length);
			Buffer.BlockCopy(aesIV, 0, macKey, idAgreedValueArray.Length, 4);

			// Actually hmac all the data now
			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (macKey, 0, 24));
			hmac.BlockUpdate(outPacket.Body, 0, 25 + encryptedInner.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);

			// Fold it up, shove it in and we're done
			var foldedMac = Helpers.Fold(mac, 3);
			Buffer.BlockCopy(foldedMac, 0, outPacket.Body, 25 + encryptedInner.Length, foldedMac.Length);

			return outPacket;
		}
		/**
		* Constructor that accepts an instance of a block cipher engine.
		*
		* @param cipher the engine to use
		*/
		public EaxBlockCipher(
			IBlockCipher cipher)
		{
			blockSize = cipher.GetBlockSize();
			mac = new CMac(cipher);
			macBlock = new byte[blockSize];
			associatedTextMac = new byte[mac.GetMacSize()];
			nonceMac = new byte[mac.GetMacSize()];
			this.cipher = new SicBlockCipher(cipher);
		}
 /**
  * Constructor that accepts an instance of a block cipher engine.
  *
  * @param cipher the engine to use
  */
 public EaxBlockCipher(
     IBlockCipher cipher)
 {
     blockSize         = cipher.GetBlockSize();
     mac               = new CMac(cipher);
     macBlock          = new byte[blockSize];
     bufBlock          = new byte[blockSize * 2];
     associatedTextMac = new byte[mac.GetMacSize()];
     nonceMac          = new byte[mac.GetMacSize()];
     this.cipher       = new SicBlockCipher(cipher);
 }
        public static IBufferedCipher GetCipher(
            string algorithm)
        {
            if (algorithm == null)
                throw new ArgumentNullException("algorithm");

            algorithm = Platform.ToUpperInvariant(algorithm);

            {
                string aliased = (string) algorithms[algorithm];

                if (aliased != null)
                    algorithm = aliased;
            }

            IBasicAgreement iesAgreement = null;
            if (algorithm == "IES")
            {
                iesAgreement = new DHBasicAgreement();
            }
            else if (algorithm == "ECIES")
            {
                iesAgreement = new ECDHBasicAgreement();
            }

            if (iesAgreement != null)
            {
                return new BufferedIesCipher(
                    new IesEngine(
                    iesAgreement,
                    new Kdf2BytesGenerator(
                    new Sha1Digest()),
                    new HMac(
                    new Sha1Digest())));
            }



            if (algorithm.StartsWith("PBE"))
            {
                if (algorithm.EndsWith("-CBC"))
                {
                    if (algorithm == "PBEWITHSHA1ANDDES-CBC")
                    {
                        return new PaddedBufferedBlockCipher(
                            new CbcBlockCipher(new DesEngine()));
                    }
                    else if (algorithm == "PBEWITHSHA1ANDRC2-CBC")
                    {
                        return new PaddedBufferedBlockCipher(
                            new CbcBlockCipher(new RC2Engine()));
                    }
                    else if (Strings.IsOneOf(algorithm,
                        "PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"))
                    {
                        return new PaddedBufferedBlockCipher(
                            new CbcBlockCipher(new DesEdeEngine()));
                    }
                    else if (Strings.IsOneOf(algorithm,
                        "PBEWITHSHAAND128BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC"))
                    {
                        return new PaddedBufferedBlockCipher(
                            new CbcBlockCipher(new RC2Engine()));
                    }
                }
                else if (algorithm.EndsWith("-BC") || algorithm.EndsWith("-OPENSSL"))
                {
                    if (Strings.IsOneOf(algorithm,
                        "PBEWITHSHAAND128BITAES-CBC-BC",
                        "PBEWITHSHAAND192BITAES-CBC-BC",
                        "PBEWITHSHAAND256BITAES-CBC-BC",
                        "PBEWITHSHA256AND128BITAES-CBC-BC",
                        "PBEWITHSHA256AND192BITAES-CBC-BC",
                        "PBEWITHSHA256AND256BITAES-CBC-BC",
                        "PBEWITHMD5AND128BITAES-CBC-OPENSSL",
                        "PBEWITHMD5AND192BITAES-CBC-OPENSSL",
                        "PBEWITHMD5AND256BITAES-CBC-OPENSSL"))
                    {
                        return new PaddedBufferedBlockCipher(
                            new CbcBlockCipher(new AesFastEngine()));
                    }
                }
            }



            string[] parts = algorithm.Split('/');

            IBlockCipher blockCipher = null;
            IAsymmetricBlockCipher asymBlockCipher = null;
            IStreamCipher streamCipher = null;

            string algorithmName = parts[0];

            {
                string aliased = (string)algorithms[algorithmName];

                if (aliased != null)
                    algorithmName = aliased;
            }

            CipherAlgorithm cipherAlgorithm;
            try
            {
                cipherAlgorithm = (CipherAlgorithm)Enums.GetEnumValue(typeof(CipherAlgorithm), algorithmName);
            }
            catch (ArgumentException)
            {
                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }

            switch (cipherAlgorithm)
            {
                case CipherAlgorithm.AES:
                    blockCipher = new AesFastEngine();
                    break;
                case CipherAlgorithm.ARC4:
                    streamCipher = new RC4Engine();
                    break;
                case CipherAlgorithm.BLOWFISH:
                    blockCipher = new BlowfishEngine();
                    break;
                case CipherAlgorithm.CAMELLIA:
                    blockCipher = new CamelliaEngine();
                    break;
                case CipherAlgorithm.CAST5:
                    blockCipher = new Cast5Engine();
                    break;
                case CipherAlgorithm.CAST6:
                    blockCipher = new Cast6Engine();
                    break;
                case CipherAlgorithm.DES:
                    blockCipher = new DesEngine();
                    break;
                case CipherAlgorithm.DESEDE:
                    blockCipher = new DesEdeEngine();
                    break;
                case CipherAlgorithm.ELGAMAL:
                    asymBlockCipher = new ElGamalEngine();
                    break;
                case CipherAlgorithm.GOST28147:
                    blockCipher = new Gost28147Engine();
                    break;
                case CipherAlgorithm.HC128:
                    streamCipher = new HC128Engine();
                    break;
                case CipherAlgorithm.HC256:
                    streamCipher = new HC256Engine();
                    break;
                case CipherAlgorithm.IDEA:
                    blockCipher = new IdeaEngine();
                    break;
                case CipherAlgorithm.NOEKEON:
                    blockCipher = new NoekeonEngine();
                    break;
                case CipherAlgorithm.PBEWITHSHAAND128BITRC4:
                case CipherAlgorithm.PBEWITHSHAAND40BITRC4:
                    streamCipher = new RC4Engine();
                    break;
                case CipherAlgorithm.RC2:
                    blockCipher = new RC2Engine();
                    break;
                case CipherAlgorithm.RC5:
                    blockCipher = new RC532Engine();
                    break;
                case CipherAlgorithm.RC5_64:
                    blockCipher = new RC564Engine();
                    break;
                case CipherAlgorithm.RC6:
                    blockCipher = new RC6Engine();
                    break;
                case CipherAlgorithm.RIJNDAEL:
                    blockCipher = new RijndaelEngine();
                    break;
                case CipherAlgorithm.RSA:
                    asymBlockCipher = new RsaBlindedEngine();
                    break;
                case CipherAlgorithm.SALSA20:
                    streamCipher = new Salsa20Engine();
                    break;
                case CipherAlgorithm.SEED:
                    blockCipher = new SeedEngine();
                    break;
                case CipherAlgorithm.SERPENT:
                    blockCipher = new SerpentEngine();
                    break;
                case CipherAlgorithm.SKIPJACK:
                    blockCipher = new SkipjackEngine();
                    break;
                case CipherAlgorithm.TEA:
                    blockCipher = new TeaEngine();
                    break;
                case CipherAlgorithm.TWOFISH:
                    blockCipher = new TwofishEngine();
                    break;
                case CipherAlgorithm.VMPC:
                    streamCipher = new VmpcEngine();
                    break;
                case CipherAlgorithm.VMPC_KSA3:
                    streamCipher = new VmpcKsa3Engine();
                    break;
                case CipherAlgorithm.XTEA:
                    blockCipher = new XteaEngine();
                    break;
                default:
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }

            if (streamCipher != null)
            {
                if (parts.Length > 1)
                    throw new ArgumentException("Modes and paddings not used for stream ciphers");

                return new BufferedStreamCipher(streamCipher);
            }


            bool cts = false;
            bool padded = true;
            IBlockCipherPadding padding = null;
            IAeadBlockCipher aeadBlockCipher = null;

            if (parts.Length > 2)
            {
                if (streamCipher != null)
                    throw new ArgumentException("Paddings not used for stream ciphers");

                string paddingName = parts[2];

                CipherPadding cipherPadding;
                if (paddingName == "")
                {
                    cipherPadding = CipherPadding.RAW;
                }
                else if (paddingName == "X9.23PADDING")
                {
                    cipherPadding = CipherPadding.X923PADDING;
                }
                else
                {
                    try
                    {
                        cipherPadding = (CipherPadding)Enums.GetEnumValue(typeof(CipherPadding), paddingName);
                    }
                    catch (ArgumentException)
                    {
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                }

                switch (cipherPadding)
                {
                    case CipherPadding.NOPADDING:
                        padded = false;
                        break;
                    case CipherPadding.RAW:
                        break;
                    case CipherPadding.ISO10126PADDING:
                    case CipherPadding.ISO10126D2PADDING:
                    case CipherPadding.ISO10126_2PADDING:
                        padding = new ISO10126d2Padding();
                        break;
                    case CipherPadding.ISO7816_4PADDING:
                    case CipherPadding.ISO9797_1PADDING:
                        padding = new ISO7816d4Padding();
                        break;
                    case CipherPadding.ISO9796_1:
                    case CipherPadding.ISO9796_1PADDING:
                        asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
                        break;
                    case CipherPadding.OAEP:
                    case CipherPadding.OAEPPADDING:
                        asymBlockCipher = new OaepEncoding(asymBlockCipher);
                        break;
                    case CipherPadding.OAEPWITHMD5ANDMGF1PADDING:
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
                        break;
                    case CipherPadding.OAEPWITHSHA1ANDMGF1PADDING:
                    case CipherPadding.OAEPWITHSHA_1ANDMGF1PADDING:
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
                        break;
                    case CipherPadding.OAEPWITHSHA224ANDMGF1PADDING:
                    case CipherPadding.OAEPWITHSHA_224ANDMGF1PADDING:
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
                        break;
                    case CipherPadding.OAEPWITHSHA256ANDMGF1PADDING:
                    case CipherPadding.OAEPWITHSHA_256ANDMGF1PADDING:
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
                        break;
                    case CipherPadding.OAEPWITHSHA384ANDMGF1PADDING:
                    case CipherPadding.OAEPWITHSHA_384ANDMGF1PADDING:
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
                        break;
                    case CipherPadding.OAEPWITHSHA512ANDMGF1PADDING:
                    case CipherPadding.OAEPWITHSHA_512ANDMGF1PADDING:
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
                        break;
                    case CipherPadding.PKCS1:
                    case CipherPadding.PKCS1PADDING:
                        asymBlockCipher = new Pkcs1Encoding(asymBlockCipher);
                        break;
                    case CipherPadding.PKCS5:
                    case CipherPadding.PKCS5PADDING:
                    case CipherPadding.PKCS7:
                    case CipherPadding.PKCS7PADDING:
                        padding = new Pkcs7Padding();
                        break;
                    case CipherPadding.TBCPADDING:
                        padding = new TbcPadding();
                        break;
                    case CipherPadding.WITHCTS:
                        cts = true;
                        break;
                    case CipherPadding.X923PADDING:
                        padding = new X923Padding();
                        break;
                    case CipherPadding.ZEROBYTEPADDING:
                        padding = new ZeroBytePadding();
                        break;
                    default:
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            string mode = "";
            if (parts.Length > 1)
            {
                mode = parts[1];

                int di = GetDigitIndex(mode);
                string modeName = di >= 0 ? mode.Substring(0, di) : mode;

                try
                {
                    CipherMode cipherMode = modeName == ""
                        ? CipherMode.NONE
                        : (CipherMode)Enums.GetEnumValue(typeof(CipherMode), modeName);

                    switch (cipherMode)
                    {
                        case CipherMode.ECB:
                        case CipherMode.NONE:
                            break;
                        case CipherMode.CBC:
                            blockCipher = new CbcBlockCipher(blockCipher);
                            break;
                        case CipherMode.CCM:
                            aeadBlockCipher = new CcmBlockCipher(blockCipher);
                            break;
                        case CipherMode.CFB:
                        {
                            int bits = (di < 0)
                                ?	8 * blockCipher.GetBlockSize()
                                :	int.Parse(mode.Substring(di));
    
                            blockCipher = new CfbBlockCipher(blockCipher, bits);
                            break;
                        }
                        case CipherMode.CTR:
                            blockCipher = new SicBlockCipher(blockCipher);
                            break;
                        case CipherMode.CTS:
                            cts = true;
                            blockCipher = new CbcBlockCipher(blockCipher);
                            break;
                        case CipherMode.EAX:
                            aeadBlockCipher = new EaxBlockCipher(blockCipher);
                            break;
                        case CipherMode.GCM:
                            aeadBlockCipher = new GcmBlockCipher(blockCipher);
                            break;
                        case CipherMode.GOFB:
                            blockCipher = new GOfbBlockCipher(blockCipher);
                            break;
                        case CipherMode.OCB:
                            aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm));
                            break;
                        case CipherMode.OFB:
                        {
                            int bits = (di < 0)
                                ?	8 * blockCipher.GetBlockSize()
                                :	int.Parse(mode.Substring(di));
    
                            blockCipher = new OfbBlockCipher(blockCipher, bits);
                            break;
                        }
                        case CipherMode.OPENPGPCFB:
                            blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
                            break;
                        case CipherMode.SIC:
                            if (blockCipher.GetBlockSize() < 16)
                            {
                                throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
                            }
                            blockCipher = new SicBlockCipher(blockCipher);
                            break;
                        default:
                            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                }
                catch (ArgumentException)
                {
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            if (aeadBlockCipher != null)
            {
                if (cts)
                    throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers.");
                if (padded && parts.Length > 2 && parts[2] != "")
                    throw new SecurityUtilityException("Bad padding specified for AEAD cipher.");

                return new BufferedAeadBlockCipher(aeadBlockCipher);
            }

            if (blockCipher != null)
            {
                if (cts)
                {
                    return new CtsBlockCipher(blockCipher);
                }

                if (padding != null)
                {
                    return new PaddedBufferedBlockCipher(blockCipher, padding);
                }

                if (!padded || blockCipher.IsPartialBlockOkay)
                {
                    return new BufferedBlockCipher(blockCipher);
                }

                return new PaddedBufferedBlockCipher(blockCipher);
            }

            if (asymBlockCipher != null)
            {
                return new BufferedAsymmetricBlockCipher(asymBlockCipher);
            }

            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
        }
示例#10
0
        /**
         * Process a packet of data for either CCM decryption or encryption.
         *
         * @param in data for processing.
         * @param inOff offset at which data starts in the input array.
         * @param inLen length of the data in the input array.
         * @param output output array.
         * @param outOff offset into output array to start putting processed bytes.
         * @return the number of bytes added to output.
         * @throws IllegalStateException if the cipher is not appropriately set up.
         * @throws InvalidCipherTextException if the input data is truncated or the mac check fails.
         * @throws DataLengthException if output buffer too short.
         */
        public virtual int ProcessPacket(byte[] input, int inOff, int inLen, byte[] output, int outOff)
        {
            // TODO: handle null keyParam (e.g. via RepeatedKeySpec)
            // Need to keep the CTR and CBC Mac parts around and reset
            if (keyParam == null)
            {
                throw new InvalidOperationException("CCM cipher unitialized.");
            }

            int n = nonce.Length;
            int q = 15 - n;

            if (q < 4)
            {
                int limitLen = 1 << (8 * q);
                if (inLen >= limitLen)
                {
                    throw new InvalidOperationException("CCM packet too large for choice of q.");
                }
            }

            byte[] iv = new byte[BlockSize];
            iv[0] = (byte)((q - 1) & 0x7);
            nonce.CopyTo(iv, 1);

            IBlockCipher ctrCipher = new SicBlockCipher(cipher);

            ctrCipher.Init(forEncryption, new ParametersWithIV(keyParam, iv));

            int outputLen;
            int inIndex  = inOff;
            int outIndex = outOff;

            if (forEncryption)
            {
                outputLen = inLen + macSize;
                Check.OutputLength(output, outOff, outputLen, "Output buffer too short.");

                calculateMac(input, inOff, inLen, macBlock);

                ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);   // S0

                while (inIndex < (inOff + inLen - BlockSize))       // S1...
                {
                    ctrCipher.ProcessBlock(input, inIndex, output, outIndex);
                    outIndex += BlockSize;
                    inIndex  += BlockSize;
                }

                byte[] block = new byte[BlockSize];

                Array.Copy(input, inIndex, block, 0, inLen + inOff - inIndex);

                ctrCipher.ProcessBlock(block, 0, block, 0);

                Array.Copy(block, 0, output, outIndex, inLen + inOff - inIndex);

                Array.Copy(macBlock, 0, output, outOff + inLen, macSize);
            }
            else
            {
                if (inLen < macSize)
                {
                    throw new InvalidCipherTextException("data too short");
                }

                outputLen = inLen - macSize;
                Check.OutputLength(output, outOff, outputLen, "Output buffer too short.");

                Array.Copy(input, inOff + outputLen, macBlock, 0, macSize);

                ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);

                for (int i = macSize; i != macBlock.Length; i++)
                {
                    macBlock[i] = 0;
                }

                while (inIndex < (inOff + outputLen - BlockSize))
                {
                    ctrCipher.ProcessBlock(input, inIndex, output, outIndex);
                    outIndex += BlockSize;
                    inIndex  += BlockSize;
                }

                byte[] block = new byte[BlockSize];

                Array.Copy(input, inIndex, block, 0, outputLen - (inIndex - inOff));

                ctrCipher.ProcessBlock(block, 0, block, 0);

                Array.Copy(block, 0, output, outIndex, outputLen - (inIndex - inOff));

                byte[] calculatedMacBlock = new byte[BlockSize];

                calculateMac(output, outOff, outputLen, calculatedMacBlock);

                if (!Arrays.ConstantTimeAreEqual(macBlock, calculatedMacBlock))
                {
                    throw new InvalidCipherTextException("mac check in CCM failed");
                }
            }

            return(outputLen);
        }
示例#11
0
        public static IBufferedCipher GetCipher(
            string algorithm)
        {
            if (algorithm == null)
                throw new ArgumentNullException("algorithm");

            algorithm = algorithm.ToUpper(CultureInfo.InvariantCulture);

            string aliased = (string) algorithms[algorithm];

            if (aliased != null)
                algorithm = aliased;

            IBasicAgreement iesAgreement = null;
            if (algorithm == "IES")
            {
                iesAgreement = new DHBasicAgreement();
            }
            else if (algorithm == "ECIES")
            {
                iesAgreement = new ECDHBasicAgreement();
            }

            if (iesAgreement != null)
            {
                return new BufferedIesCipher(
                    new IesEngine(
                    iesAgreement,
                    new Kdf2BytesGenerator(
                    new Sha1Digest()),
                    new HMac(
                    new Sha1Digest())));
            }

            if (algorithm.StartsWith("PBE"))
            {
                switch (algorithm)
                {
                    case "PBEWITHSHAAND2-KEYTRIPLEDES-CBC":
                    case "PBEWITHSHAAND3-KEYTRIPLEDES-CBC":
                        return new PaddedBufferedBlockCipher(
                            new CbcBlockCipher(new DesEdeEngine()));

                    case "PBEWITHSHAAND128BITRC2-CBC":
                    case "PBEWITHSHAAND40BITRC2-CBC":
                        return new PaddedBufferedBlockCipher(
                            new CbcBlockCipher(new RC2Engine()));

                    case "PBEWITHSHAAND128BITAES-CBC-BC":
                    case "PBEWITHSHAAND192BITAES-CBC-BC":
                    case "PBEWITHSHAAND256BITAES-CBC-BC":
                    case "PBEWITHSHA256AND128BITAES-CBC-BC":
                    case "PBEWITHSHA256AND192BITAES-CBC-BC":
                    case "PBEWITHSHA256AND256BITAES-CBC-BC":
                    case "PBEWITHMD5AND128BITAES-CBC-OPENSSL":
                    case "PBEWITHMD5AND192BITAES-CBC-OPENSSL":
                    case "PBEWITHMD5AND256BITAES-CBC-OPENSSL":
                        return new PaddedBufferedBlockCipher(
                            new CbcBlockCipher(new AesFastEngine()));

                    case "PBEWITHSHA1ANDDES-CBC":
                        return new PaddedBufferedBlockCipher(
                            new CbcBlockCipher(new DesEngine()));

                    case "PBEWITHSHA1ANDRC2-CBC":
                        return new PaddedBufferedBlockCipher(
                            new CbcBlockCipher(new RC2Engine()));
                }
            }

            string[] parts = algorithm.Split('/');

            IBlockCipher blockCipher = null;
            IAsymmetricBlockCipher asymBlockCipher = null;
            IStreamCipher streamCipher = null;

            switch (parts[0])
            {
                case "AES":
                    blockCipher = new AesFastEngine();
                    break;
                case "ARC4":
                    streamCipher = new RC4Engine();
                    break;
                case "BLOWFISH":
                    blockCipher = new BlowfishEngine();
                    break;
                case "CAMELLIA":
                    blockCipher = new CamelliaEngine();
                    break;
                case "CAST5":
                    blockCipher = new Cast5Engine();
                    break;
                case "CAST6":
                    blockCipher = new Cast6Engine();
                    break;
                case "DES":
                    blockCipher = new DesEngine();
                    break;
                case "DESEDE":
                    blockCipher = new DesEdeEngine();
                    break;
                case "ELGAMAL":
                    asymBlockCipher = new ElGamalEngine();
                    break;
                case "GOST28147":
                    blockCipher = new Gost28147Engine();
                    break;
                case "HC128":
                    streamCipher = new HC128Engine();
                    break;
                case "HC256":
                    streamCipher = new HC256Engine();
                    break;
            #if INCLUDE_IDEA
                case "IDEA":
                    blockCipher = new IdeaEngine();
                    break;
            #endif
                case "NOEKEON":
                    blockCipher = new NoekeonEngine();
                    break;
                case "PBEWITHSHAAND128BITRC4":
                case "PBEWITHSHAAND40BITRC4":
                    streamCipher = new RC4Engine();
                    break;
                case "RC2":
                    blockCipher = new RC2Engine();
                    break;
                case "RC5":
                    blockCipher = new RC532Engine();
                    break;
                case "RC5-64":
                    blockCipher = new RC564Engine();
                    break;
                case "RC6":
                    blockCipher = new RC6Engine();
                    break;
                case "RIJNDAEL":
                    blockCipher = new RijndaelEngine();
                    break;
                case "RSA":
                    asymBlockCipher = new RsaBlindedEngine();
                    break;
                case "SALSA20":
                    streamCipher = new Salsa20Engine();
                    break;
                case "SEED":
                    blockCipher = new SeedEngine();
                    break;
                case "SERPENT":
                    blockCipher = new SerpentEngine();
                    break;
                case "SKIPJACK":
                    blockCipher = new SkipjackEngine();
                    break;
                case "TEA":
                    blockCipher = new TeaEngine();
                    break;
                case "TWOFISH":
                    blockCipher = new TwofishEngine();
                    break;
                case "VMPC":
                    streamCipher = new VmpcEngine();
                    break;
                case "VMPC-KSA3":
                    streamCipher = new VmpcKsa3Engine();
                    break;
                case "XTEA":
                    blockCipher = new XteaEngine();
                    break;
                default:
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }

            if (streamCipher != null)
            {
                if (parts.Length > 1)
                    throw new ArgumentException("Modes and paddings not used for stream ciphers");

                return new BufferedStreamCipher(streamCipher);
            }

            bool cts = false;
            bool padded = true;
            IBlockCipherPadding padding = null;
            IAeadBlockCipher aeadBlockCipher = null;

            if (parts.Length > 2)
            {
                if (streamCipher != null)
                    throw new ArgumentException("Paddings not used for stream ciphers");

                switch (parts[2])
                {
                    case "NOPADDING":
                        padded = false;
                        break;
                    case "":
                    case "RAW":
                        break;
                    case "ISO10126PADDING":
                    case "ISO10126D2PADDING":
                    case "ISO10126-2PADDING":
                        padding = new ISO10126d2Padding();
                        break;
                    case "ISO7816-4PADDING":
                    case "ISO9797-1PADDING":
                        padding = new ISO7816d4Padding();
                        break;
                    case "ISO9796-1":
                    case "ISO9796-1PADDING":
                        asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
                        break;
                    case "OAEP":
                    case "OAEPPADDING":
                        asymBlockCipher = new OaepEncoding(asymBlockCipher);
                        break;
                    case "OAEPWITHMD5ANDMGF1PADDING":
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
                        break;
                    case "OAEPWITHSHA1ANDMGF1PADDING":
                    case "OAEPWITHSHA-1ANDMGF1PADDING":
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
                        break;
                    case "OAEPWITHSHA224ANDMGF1PADDING":
                    case "OAEPWITHSHA-224ANDMGF1PADDING":
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
                        break;
                    case "OAEPWITHSHA256ANDMGF1PADDING":
                    case "OAEPWITHSHA-256ANDMGF1PADDING":
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
                        break;
                    case "OAEPWITHSHA384ANDMGF1PADDING":
                    case "OAEPWITHSHA-384ANDMGF1PADDING":
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
                        break;
                    case "OAEPWITHSHA512ANDMGF1PADDING":
                    case "OAEPWITHSHA-512ANDMGF1PADDING":
                        asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
                        break;
                    case "PKCS1":
                    case "PKCS1PADDING":
                        asymBlockCipher = new Pkcs1Encoding(asymBlockCipher);
                        break;
                    case "PKCS5":
                    case "PKCS5PADDING":
                    case "PKCS7":
                    case "PKCS7PADDING":
                        padding = new Pkcs7Padding();
                        break;
                    case "TBCPADDING":
                        padding = new TbcPadding();
                        break;
                    case "WITHCTS":
                        cts = true;
                        break;
                    case "X9.23PADDING":
                    case "X923PADDING":
                        padding = new X923Padding();
                        break;
                    case "ZEROBYTEPADDING":
                        padding = new ZeroBytePadding();
                        break;
                    default:
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            string mode = "";
            if (parts.Length > 1)
            {
                mode = parts[1];

                int di = GetDigitIndex(mode);
                string modeName = di >= 0 ? mode.Substring(0, di) : mode;

                switch (modeName)
                {
                    case "":
                    case "ECB":
                    case "NONE":
                        break;
                    case "CBC":
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;
                    case "CCM":
                        aeadBlockCipher = new CcmBlockCipher(blockCipher);
                        break;
                    case "CFB":
                    {
                        int bits = (di < 0)
                            ?	8 * blockCipher.GetBlockSize()
                            :	int.Parse(mode.Substring(di));

                        blockCipher = new CfbBlockCipher(blockCipher, bits);
                        break;
                    }
                    case "CTR":
                        blockCipher = new SicBlockCipher(blockCipher);
                        break;
                    case "CTS":
                        cts = true;
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;
                    case "EAX":
                        aeadBlockCipher = new EaxBlockCipher(blockCipher);
                        break;
                    case "GCM":
                        aeadBlockCipher = new GcmBlockCipher(blockCipher);
                        break;
                    case "GOFB":
                        blockCipher = new GOfbBlockCipher(blockCipher);
                        break;
                    case "OFB":
                    {
                        int bits = (di < 0)
                            ?	8 * blockCipher.GetBlockSize()
                            :	int.Parse(mode.Substring(di));

                        blockCipher = new OfbBlockCipher(blockCipher, bits);
                        break;
                    }
                    case "OPENPGPCFB":
                        blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
                        break;
                    case "SIC":
                        if (blockCipher.GetBlockSize() < 16)
                        {
                            throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
                        }
                        blockCipher = new SicBlockCipher(blockCipher);
                        break;
                    default:
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            if (aeadBlockCipher != null)
            {
                if (cts)
                    throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers.");
                if (padded && parts.Length > 2 && parts[2] != "")
                    throw new SecurityUtilityException("Bad padding specified for AEAD cipher.");

                return new BufferedAeadBlockCipher(aeadBlockCipher);
            }

            if (blockCipher != null)
            {
                if (cts)
                {
                    return new CtsBlockCipher(blockCipher);
                }

                if (padding != null)
                {
                    return new PaddedBufferedBlockCipher(blockCipher, padding);
                }

                if (!padded || blockCipher.IsPartialBlockOkay)
                {
                    return new BufferedBlockCipher(blockCipher);
                }

                return new PaddedBufferedBlockCipher(blockCipher);
            }

            if (asymBlockCipher != null)
            {
                return new BufferedAsymmetricBlockCipher(asymBlockCipher);
            }

            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
        }
示例#12
0
        public byte[] ProcessPacket(
            byte[]  input,
            int inOff,
            int inLen)
        {
            if (keyParam == null)
            {
                throw new InvalidOperationException("CCM cipher unitialized.");
            }

            IBlockCipher ctrCipher = new SicBlockCipher(cipher);

            byte[] iv = new byte[BlockSize];
            byte[] output;

            iv[0] = (byte)(((15 - nonce.Length) - 1) & 0x7);

            Array.Copy(nonce, 0, iv, 1, nonce.Length);

            ctrCipher.Init(forEncryption, new ParametersWithIV(keyParam, iv));

            if (forEncryption)
            {
                int index  = inOff;
                int outOff = 0;

                output = new byte[inLen + macSize];

                calculateMac(input, inOff, inLen, macBlock);

                ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);   // S0

                while (index < inLen - BlockSize)                   // S1...
                {
                    ctrCipher.ProcessBlock(input, index, output, outOff);
                    outOff += BlockSize;
                    index  += BlockSize;
                }

                byte[] block = new byte[BlockSize];

                Array.Copy(input, index, block, 0, inLen - index);

                ctrCipher.ProcessBlock(block, 0, block, 0);

                Array.Copy(block, 0, output, outOff, inLen - index);

                outOff += inLen - index;

                Array.Copy(macBlock, 0, output, outOff, output.Length - outOff);
            }
            else
            {
                int index  = inOff;
                int outOff = 0;

                output = new byte[inLen - macSize];

                Array.Copy(input, inOff + inLen - macSize, macBlock, 0, macSize);

                ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);

                for (int i = macSize; i != macBlock.Length; i++)
                {
                    macBlock[i] = 0;
                }

                while (outOff < output.Length - BlockSize)
                {
                    ctrCipher.ProcessBlock(input, index, output, outOff);
                    outOff += BlockSize;
                    index  += BlockSize;
                }

                byte[] block = new byte[BlockSize];

                Array.Copy(input, index, block, 0, output.Length - outOff);

                ctrCipher.ProcessBlock(block, 0, block, 0);

                Array.Copy(block, 0, output, outOff, output.Length - outOff);

                byte[] calculatedMacBlock = new byte[BlockSize];

                calculateMac(output, 0, output.Length, calculatedMacBlock);

                if (!Arrays.ConstantTimeAreEqual(macBlock, calculatedMacBlock))
                {
                    throw new InvalidCipherTextException("mac check in CCM failed");
                }
            }

            return(output);
        }
示例#13
0
        public virtual int ProcessPacket(byte[] input, int inOff, int inLen, byte[] output, int outOff)
        {
            if (this.keyParam == null)
            {
                throw new InvalidOperationException("CCM cipher unitialized.");
            }
            int num  = this.nonce.Length;
            int num2 = 15 - num;

            if (num2 < 4)
            {
                int num3 = 1 << 8 * num2;
                if (inLen >= num3)
                {
                    throw new InvalidOperationException("CCM packet too large for choice of q.");
                }
            }
            byte[] array = new byte[CcmBlockCipher.BlockSize];
            array[0] = (byte)(num2 - 1 & 7);
            this.nonce.CopyTo(array, 1);
            IBlockCipher blockCipher = new SicBlockCipher(this.cipher);

            blockCipher.Init(this.forEncryption, new ParametersWithIV(this.keyParam, array));
            int i    = inOff;
            int num4 = outOff;
            int num5;

            if (this.forEncryption)
            {
                num5 = inLen + this.macSize;
                Check.OutputLength(output, outOff, num5, "Output buffer too short.");
                this.calculateMac(input, inOff, inLen, this.macBlock);
                blockCipher.ProcessBlock(this.macBlock, 0, this.macBlock, 0);
                while (i < inOff + inLen - CcmBlockCipher.BlockSize)
                {
                    blockCipher.ProcessBlock(input, i, output, num4);
                    num4 += CcmBlockCipher.BlockSize;
                    i    += CcmBlockCipher.BlockSize;
                }
                byte[] array2 = new byte[CcmBlockCipher.BlockSize];
                Array.Copy(input, i, array2, 0, inLen + inOff - i);
                blockCipher.ProcessBlock(array2, 0, array2, 0);
                Array.Copy(array2, 0, output, num4, inLen + inOff - i);
                Array.Copy(this.macBlock, 0, output, outOff + inLen, this.macSize);
            }
            else
            {
                if (inLen < this.macSize)
                {
                    throw new InvalidCipherTextException("data too short");
                }
                num5 = inLen - this.macSize;
                Check.OutputLength(output, outOff, num5, "Output buffer too short.");
                Array.Copy(input, inOff + num5, this.macBlock, 0, this.macSize);
                blockCipher.ProcessBlock(this.macBlock, 0, this.macBlock, 0);
                for (int num6 = this.macSize; num6 != this.macBlock.Length; num6++)
                {
                    this.macBlock[num6] = 0;
                }
                while (i < inOff + num5 - CcmBlockCipher.BlockSize)
                {
                    blockCipher.ProcessBlock(input, i, output, num4);
                    num4 += CcmBlockCipher.BlockSize;
                    i    += CcmBlockCipher.BlockSize;
                }
                byte[] array3 = new byte[CcmBlockCipher.BlockSize];
                Array.Copy(input, i, array3, 0, num5 - (i - inOff));
                blockCipher.ProcessBlock(array3, 0, array3, 0);
                Array.Copy(array3, 0, output, num4, num5 - (i - inOff));
                byte[] b = new byte[CcmBlockCipher.BlockSize];
                this.calculateMac(output, outOff, num5, b);
                if (!Arrays.ConstantTimeAreEqual(this.macBlock, b))
                {
                    throw new InvalidCipherTextException("mac check in CCM failed");
                }
            }
            return(num5);
        }
示例#14
0
        public byte[] ProcessPacket(
			byte[]	input,
			int		inOff,
			int		inLen)
        {
            // TODO: handle null keyParam (e.g. via RepeatedKeySpec)
            // Need to keep the CTR and CBC Mac parts around and reset
            if (keyParam == null)
                throw new InvalidOperationException("CCM cipher unitialized.");

			IBlockCipher ctrCipher = new SicBlockCipher(cipher);
            byte[] iv = new byte[BlockSize];
            byte[] output;

            iv[0] = (byte)(((15 - nonce.Length) - 1) & 0x7);

            Array.Copy(nonce, 0, iv, 1, nonce.Length);

			ctrCipher.Init(forEncryption, new ParametersWithIV(keyParam, iv));

			if (forEncryption)
            {
                int index = inOff;
                int outOff = 0;

                output = new byte[inLen + macSize];

                calculateMac(input, inOff, inLen, macBlock);

                ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);   // S0

                while (index < inLen - BlockSize)                   // S1...
                {
                    ctrCipher.ProcessBlock(input, index, output, outOff);
                    outOff += BlockSize;
                    index += BlockSize;
                }

                byte[] block = new byte[BlockSize];

                Array.Copy(input, index, block, 0, inLen - index);

                ctrCipher.ProcessBlock(block, 0, block, 0);

                Array.Copy(block, 0, output, outOff, inLen - index);

                outOff += inLen - index;

                Array.Copy(macBlock, 0, output, outOff, output.Length - outOff);
            }
            else
            {
                int index = inOff;
                int outOff = 0;

                output = new byte[inLen - macSize];

                Array.Copy(input, inOff + inLen - macSize, macBlock, 0, macSize);

                ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);

                for (int i = macSize; i != macBlock.Length; i++)
                {
                    macBlock[i] = 0;
                }

                while (outOff < output.Length - BlockSize)
                {
                    ctrCipher.ProcessBlock(input, index, output, outOff);
                    outOff += BlockSize;
                    index += BlockSize;
                }

                byte[] block = new byte[BlockSize];

                Array.Copy(input, index, block, 0, output.Length - outOff);

                ctrCipher.ProcessBlock(block, 0, block, 0);

                Array.Copy(block, 0, output, outOff, output.Length - outOff);

                byte[] calculatedMacBlock = new byte[BlockSize];

                calculateMac(output, 0, output.Length, calculatedMacBlock);

				if (!Arrays.ConstantTimeAreEqual(macBlock, calculatedMacBlock))
                    throw new InvalidCipherTextException("mac check in CCM failed");
            }

			return output;
        }
示例#15
0
文件: AWiz.cs 项目: burstas/rmps
        private BufferedBlockCipher CreateScryptoEngine()
        {
            IBlockCipher engine;
            switch (_MSec.Algorithm)
            {
                case ESec.SCRYPTO_AES:
                    engine = new AesEngine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_AESFAST:
                    engine = new AesFastEngine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_AESLIGHT:
                    engine = new AesLightEngine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_BLOWFISH:
                    engine = new BlowfishEngine();
                    _MSec.KeySize = 56;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_CAMELLIA:
                    engine = new CamelliaEngine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_CAMELLIALIGHT:
                    engine = new CamelliaLightEngine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_CAST5:
                    engine = new Cast5Engine();
                    _MSec.KeySize = 16;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_CAST6:
                    engine = new Cast6Engine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_DES:
                    engine = new DesEngine();
                    _MSec.KeySize = 8;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_DESEDE:
                    engine = new DesEdeEngine();
                    _MSec.KeySize = 24;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_GOST28147:
                    engine = new Gost28147Engine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_NOEKEON:
                    engine = new NoekeonEngine();
                    _MSec.KeySize = 16;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_NULL:
                    engine = new NullEngine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 16;
                    break;
                case ESec.SCRYPTO_RC2:
                    engine = new RC2Engine();
                    _MSec.KeySize = 128;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_RC532:
                    engine = new RC532Engine();
                    _MSec.KeySize = 16;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_RC564:
                    engine = new RC564Engine();
                    _MSec.KeySize = 16;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_RC6:
                    engine = new RC6Engine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_RIJNDAEL:
                    engine = new RijndaelEngine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_SEED:
                    engine = new SeedEngine();
                    _MSec.KeySize = 16;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_SERPENT:
                    engine = new SerpentEngine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_SKIPJACK:
                    engine = new SkipjackEngine();
                    _MSec.KeySize = 16;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_TEA:
                    engine = new TeaEngine();
                    _MSec.KeySize = 16;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_TWOFISH:
                    engine = new TwofishEngine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
                case ESec.SCRYPTO_XTEA:
                    engine = new XteaEngine();
                    _MSec.KeySize = 16;
                    _MSec.IVSize = 0;
                    break;
                default:
                    engine = new AesEngine();
                    _MSec.KeySize = 32;
                    _MSec.IVSize = 0;
                    break;
            }

            switch (_MSec.Mode)
            {
                case ESec.MODE_CBC:
                    engine = new CbcBlockCipher(engine);
                    break;
                case ESec.MODE_CFB:
                    engine = new CfbBlockCipher(engine, 8);
                    break;
                case ESec.MODE_GOFB:
                    engine = new GOfbBlockCipher(engine);
                    break;
                case ESec.MODE_OFB:
                    engine = new OfbBlockCipher(engine, 8);
                    break;
                case ESec.MODE_OPENPGPCFB:
                    engine = new OpenPgpCfbBlockCipher(engine);
                    break;
                case ESec.MODE_SIC:
                    engine = new SicBlockCipher(engine);
                    break;
                default:
                    engine = new CbcBlockCipher(engine);
                    break;
            }

            IBlockCipherPadding padding = null;
            switch (_MSec.Padding)
            {
                case ESec.PADDING_ISO10126d2:
                    padding = new ISO10126d2Padding();
                    break;
                case ESec.PADDING_ISO7816d4:
                    padding = new ISO7816d4Padding();
                    break;
                case ESec.PADDING_PKCS7:
                    padding = new Pkcs7Padding();
                    break;
                case ESec.PADDING_TBC:
                    padding = new TbcPadding();
                    break;
                case ESec.PADDING_X923:
                    padding = new X923Padding();
                    break;
                case ESec.PADDING_ZEROBYTE:
                    padding = new ZeroBytePadding();
                    break;
                default:
                    padding = new Pkcs7Padding();
                    break;
            }

            return new PaddedBufferedBlockCipher(engine, padding);
        }
示例#16
0
        /**
         * Process a packet of data for either CCM decryption or encryption.
         *
         * @param in data for processing.
         * @param inOff offset at which data starts in the input array.
         * @param inLen length of the data in the input array.
         * @param output output array.
         * @param outOff offset into output array to start putting processed bytes.
         * @return the number of bytes added to output.
         * @throws IllegalStateException if the cipher is not appropriately set up.
         * @throws InvalidCipherTextException if the input data is truncated or the mac check fails.
         * @throws DataLengthException if output buffer too short.
         */
        public virtual int ProcessPacket(byte[] input, int inOff, int inLen, byte[] output, int outOff)
        {
            // TODO: handle null keyParam (e.g. via RepeatedKeySpec)
            // Need to keep the CTR and CBC Mac parts around and reset
            if (keyParam == null)
                throw new InvalidOperationException("CCM cipher unitialized.");

            int n = nonce.Length;
            int q = 15 - n;
            if (q < 4)
            {
                int limitLen = 1 << (8 * q);
                if (inLen >= limitLen)
                    throw new InvalidOperationException("CCM packet too large for choice of q.");
            }

            byte[] iv = new byte[BlockSize];
            iv[0] = (byte)((q - 1) & 0x7);
            nonce.CopyTo(iv, 1);

            IBlockCipher ctrCipher = new SicBlockCipher(cipher);
            ctrCipher.Init(forEncryption, new ParametersWithIV(keyParam, iv));

            int outputLen;
            int inIndex = inOff;
            int outIndex = outOff;

            if (forEncryption)
            {
                outputLen = inLen + macSize;
                Check.OutputLength(output, outOff, outputLen, "Output buffer too short.");

                calculateMac(input, inOff, inLen, macBlock);

                ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);   // S0

                while (inIndex < (inOff + inLen - BlockSize))                 // S1...
                {
                    ctrCipher.ProcessBlock(input, inIndex, output, outIndex);
                    outIndex += BlockSize;
                    inIndex += BlockSize;
                }

                byte[] block = new byte[BlockSize];

                Array.Copy(input, inIndex, block, 0, inLen + inOff - inIndex);

                ctrCipher.ProcessBlock(block, 0, block, 0);

                Array.Copy(block, 0, output, outIndex, inLen + inOff - inIndex);

                Array.Copy(macBlock, 0, output, outOff + inLen, macSize);
            }
            else
            {
                if (inLen < macSize)
                    throw new InvalidCipherTextException("data too short");

                outputLen = inLen - macSize;
                Check.OutputLength(output, outOff, outputLen, "Output buffer too short.");

                Array.Copy(input, inOff + outputLen, macBlock, 0, macSize);

                ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);

                for (int i = macSize; i != macBlock.Length; i++)
                {
                    macBlock[i] = 0;
                }

                while (inIndex < (inOff + outputLen - BlockSize))
                {
                    ctrCipher.ProcessBlock(input, inIndex, output, outIndex);
                    outIndex += BlockSize;
                    inIndex += BlockSize;
                }

                byte[] block = new byte[BlockSize];

                Array.Copy(input, inIndex, block, 0, outputLen - (inIndex - inOff));

                ctrCipher.ProcessBlock(block, 0, block, 0);

                Array.Copy(block, 0, output, outIndex, outputLen - (inIndex - inOff));

                byte[] calculatedMacBlock = new byte[BlockSize];

                calculateMac(output, outOff, outputLen, calculatedMacBlock);

                if (!Arrays.ConstantTimeAreEqual(macBlock, calculatedMacBlock))
                    throw new InvalidCipherTextException("mac check in CCM failed");
            }

            return outputLen;
        }
示例#17
0
		public Packet ChannelDecrypt(ICipherSetRemoteInfo channelInfo, Packet outer)
		{
			// We gotta have the primary components and something to decrypt
			if (outer.Body.Length < 25) {
				return null;
			}

			var ci = (CS1ARemoteInfo)channelInfo;

			// Rip apart our packet
			byte[] token = outer.Body.Take (16).ToArray ();
			byte[] iv = outer.Body.Skip (16).Take (4).ToArray ();
			byte[] encryptedData = outer.Body.Skip (20).Take (outer.Body.Length - 24).ToArray ();
			byte[] dataMac = outer.Body.Skip (outer.Body.Length - 4).Take (4).ToArray ();

			// Make sure we're on the right channel
			if (!token.SequenceEqual (ci.Token)) {
				return null;
			}

			// Validate us some hmac
			byte[] hmacKey = new byte[20];
			Buffer.BlockCopy (ci.DecryptionKey, 0, hmacKey, 0, 16);
			Buffer.BlockCopy (iv, 0, hmacKey, 16, 4);

			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (hmacKey));
			hmac.BlockUpdate(encryptedData, 0, encryptedData.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);
			var foldedMac = Helpers.Fold (mac, 3);

			if (!foldedMac.SequenceEqual (dataMac)) {
				// Get out of here with your bad data
				return null;
			}

			// Everything seems ok.  Get it decrypted
			byte[] aesIV = new byte[16];
			Buffer.BlockCopy (iv, 0, aesIV, 0, 4);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (ci.DecryptionKey), aesIV);
			cipher.Init (false, parameters);

			var decryptedData = new byte[encryptedData.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (encryptedData, decryptedData, 0);
			bufferCipher.DoFinal (decryptedData, offset);

			// Build a packet and ship it off
			return Packet.DecodePacket (decryptedData);
		}
示例#18
0
		public Packet ChannelEncrypt(ICipherSetRemoteInfo channelInfo, Packet inner)
		{
			var ci = (CS1ARemoteInfo)channelInfo;

			// TODO:  Validate we don't care about endianess of IV here

			// Setup and encrypt the actual data
			byte[] aesIV = new byte[16];
			Buffer.BlockCopy (BitConverter.GetBytes(ci.IV), 0, aesIV, 0, 4);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (ci.EncryptionKey), aesIV);
			cipher.Init (true, parameters);

			var encryptedInner = new byte[inner.FullPacket.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (inner.FullPacket, encryptedInner, 0);
			bufferCipher.DoFinal (encryptedInner, offset);

			// Hmac the output
			byte[] hmacKey = new byte[20];
			Buffer.BlockCopy (ci.EncryptionKey, 0, hmacKey, 0, 16);
			Buffer.BlockCopy (BitConverter.GetBytes(ci.IV), 0, hmacKey, 16, 4);

			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (hmacKey));
			hmac.BlockUpdate(encryptedInner, 0, encryptedInner.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);
			var foldedMac = Helpers.Fold (mac, 3);

			// Create the outgoing packet
			Packet outPacket = new Packet();
			outPacket.Body = new byte[encryptedInner.Length + 24];
			Buffer.BlockCopy(ci.Token, 0, outPacket.Body, 0, 16);
			Buffer.BlockCopy(BitConverter.GetBytes(ci.IV), 0, outPacket.Body, 16, 4);
			Buffer.BlockCopy(encryptedInner, 0, outPacket.Body, 20, encryptedInner.Length);
			Buffer.BlockCopy(foldedMac, 0, outPacket.Body, outPacket.Body.Length - 4, 4);

			// Next IV next packet
			++ci.IV;

			return outPacket;
		}
示例#19
0
        public virtual int ProcessPacket(byte[] input, int inOff, int inLen, byte[] output, int outOff)
        {
            int num4;

            if (this.keyParam == null)
            {
                throw new InvalidOperationException("CCM cipher unitialized.");
            }
            int length = this.nonce.Length;
            int num2   = 15 - length;

            if (num2 < 4)
            {
                int num3 = ((int)1) << (8 * num2);
                if (inLen >= num3)
                {
                    throw new InvalidOperationException("CCM packet too large for choice of q.");
                }
            }
            byte[] array = new byte[BlockSize];
            array[0] = (byte)((num2 - 1) & 7);
            this.nonce.CopyTo(array, 1);
            IBlockCipher cipher = new SicBlockCipher(this.cipher);

            cipher.Init(this.forEncryption, new ParametersWithIV(this.keyParam, array));
            int num5 = inOff;
            int num6 = outOff;

            if (this.forEncryption)
            {
                num4 = inLen + this.macSize;
                Check.OutputLength(output, outOff, num4, "Output buffer too short.");
                this.CalculateMac(input, inOff, inLen, this.macBlock);
                byte[] outBuf = new byte[BlockSize];
                cipher.ProcessBlock(this.macBlock, 0, outBuf, 0);
                while (num5 < ((inOff + inLen) - BlockSize))
                {
                    cipher.ProcessBlock(input, num5, output, num6);
                    num6 += BlockSize;
                    num5 += BlockSize;
                }
                byte[] buffer3 = new byte[BlockSize];
                Array.Copy(input, num5, buffer3, 0, (inLen + inOff) - num5);
                cipher.ProcessBlock(buffer3, 0, buffer3, 0);
                Array.Copy(buffer3, 0, output, num6, (inLen + inOff) - num5);
                Array.Copy(outBuf, 0, output, outOff + inLen, this.macSize);
                return(num4);
            }
            if (inLen < this.macSize)
            {
                throw new InvalidCipherTextException("data too short");
            }
            num4 = inLen - this.macSize;
            Check.OutputLength(output, outOff, num4, "Output buffer too short.");
            Array.Copy(input, inOff + num4, this.macBlock, 0, this.macSize);
            cipher.ProcessBlock(this.macBlock, 0, this.macBlock, 0);
            for (int i = this.macSize; i != this.macBlock.Length; i++)
            {
                this.macBlock[i] = 0;
            }
            while (num5 < ((inOff + num4) - BlockSize))
            {
                cipher.ProcessBlock(input, num5, output, num6);
                num6 += BlockSize;
                num5 += BlockSize;
            }
            byte[] destinationArray = new byte[BlockSize];
            Array.Copy(input, num5, destinationArray, 0, num4 - (num5 - inOff));
            cipher.ProcessBlock(destinationArray, 0, destinationArray, 0);
            Array.Copy(destinationArray, 0, output, num6, num4 - (num5 - inOff));
            byte[] macBlock = new byte[BlockSize];
            this.CalculateMac(output, outOff, num4, macBlock);
            if (!Arrays.ConstantTimeAreEqual(this.macBlock, macBlock))
            {
                throw new InvalidCipherTextException("mac check in CCM failed");
            }
            return(num4);
        }
示例#20
0
        public byte[] ProcessPacket(byte[] input, int inOff, int inLen)
        {
            if (parameters == null)
            {
                throw new InvalidOperationException("CCM cipher unitialized.");
            }

            IBlockCipher ctrCipher = new SicBlockCipher(cipher);
            byte[] iv = new byte[blockSize];
            byte[] nonce = parameters.GetNonce();
            int    macSize = parameters.MacSize / 8;
            byte[] output;

            iv[0] = (byte)(((15 - nonce.Length) - 1) & 0x7);

            Array.Copy(nonce, 0, iv, 1, nonce.Length);

            ctrCipher.Init(forEncryption, new ParametersWithIV(parameters.Key, iv));

            if (forEncryption)
            {
                int index = inOff;
                int outOff = 0;

                output = new byte[inLen + macSize];

                calculateMac(input, inOff, inLen, macBlock);

                ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);   // S0

                while (index < inLen - blockSize)                   // S1...
                {
                    ctrCipher.ProcessBlock(input, index, output, outOff);
                    outOff += blockSize;
                    index += blockSize;
                }

                byte[] block = new byte[blockSize];

                Array.Copy(input, index, block, 0, inLen - index);

                ctrCipher.ProcessBlock(block, 0, block, 0);

                Array.Copy(block, 0, output, outOff, inLen - index);

                outOff += inLen - index;

                Array.Copy(macBlock, 0, output, outOff, output.Length - outOff);
            }
            else
            {
                int index = inOff;
                int outOff = 0;

                output = new byte[inLen - macSize];

                Array.Copy(input, inOff + inLen - macSize, macBlock, 0, macSize);

                ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0);

                for (int i = macSize; i != macBlock.Length; i++)
                {
                    macBlock[i] = 0;
                }

                while (outOff < output.Length - blockSize)
                {
                    ctrCipher.ProcessBlock(input, index, output, outOff);
                    outOff += blockSize;
                    index += blockSize;
                }

                byte[] block = new byte[blockSize];

                Array.Copy(input, index, block, 0, output.Length - outOff);

                ctrCipher.ProcessBlock(block, 0, block, 0);

                Array.Copy(block, 0, output, outOff, output.Length - outOff);

                byte[] calculatedMacBlock = new byte[blockSize];

                calculateMac(output, 0, output.Length, calculatedMacBlock);

                if (!areEqual(macBlock, calculatedMacBlock))
                {
                    throw new InvalidCipherTextException("mac check in CCM failed");
                }
            }

            return output;
        }
示例#21
0
        public virtual int ProcessPacket(byte[] input, int inOff, int inLen, byte[] output, int outOff)
        {
            //IL_000d: Unknown result type (might be due to invalid IL or missing references)
            //IL_0037: Unknown result type (might be due to invalid IL or missing references)
            if (keyParam == null)
            {
                throw new InvalidOperationException("CCM cipher unitialized.");
            }
            int num  = nonce.Length;
            int num2 = 15 - num;

            if (num2 < 4)
            {
                int num3 = 1 << 8 * num2;
                if (inLen >= num3)
                {
                    throw new InvalidOperationException("CCM packet too large for choice of q.");
                }
            }
            byte[] array = new byte[BlockSize];
            array[0] = (byte)((uint)(num2 - 1) & 7u);
            ((global::System.Array)nonce).CopyTo((global::System.Array)array, 1);
            IBlockCipher blockCipher = new SicBlockCipher(cipher);

            blockCipher.Init(forEncryption, new ParametersWithIV(keyParam, array));
            int i    = inOff;
            int num4 = outOff;
            int num5;

            if (forEncryption)
            {
                num5 = inLen + macSize;
                Check.OutputLength(output, outOff, num5, "Output buffer too short.");
                CalculateMac(input, inOff, inLen, macBlock);
                byte[] array2 = new byte[BlockSize];
                blockCipher.ProcessBlock(macBlock, 0, array2, 0);
                for (; i < inOff + inLen - BlockSize; i += BlockSize)
                {
                    blockCipher.ProcessBlock(input, i, output, num4);
                    num4 += BlockSize;
                }
                byte[] array3 = new byte[BlockSize];
                global::System.Array.Copy((global::System.Array)input, i, (global::System.Array)array3, 0, inLen + inOff - i);
                blockCipher.ProcessBlock(array3, 0, array3, 0);
                global::System.Array.Copy((global::System.Array)array3, 0, (global::System.Array)output, num4, inLen + inOff - i);
                global::System.Array.Copy((global::System.Array)array2, 0, (global::System.Array)output, outOff + inLen, macSize);
            }
            else
            {
                if (inLen < macSize)
                {
                    throw new InvalidCipherTextException("data too short");
                }
                num5 = inLen - macSize;
                Check.OutputLength(output, outOff, num5, "Output buffer too short.");
                global::System.Array.Copy((global::System.Array)input, inOff + num5, (global::System.Array)macBlock, 0, macSize);
                blockCipher.ProcessBlock(macBlock, 0, macBlock, 0);
                for (int j = macSize; j != macBlock.Length; j++)
                {
                    macBlock[j] = 0;
                }
                for (; i < inOff + num5 - BlockSize; i += BlockSize)
                {
                    blockCipher.ProcessBlock(input, i, output, num4);
                    num4 += BlockSize;
                }
                byte[] array4 = new byte[BlockSize];
                global::System.Array.Copy((global::System.Array)input, i, (global::System.Array)array4, 0, num5 - (i - inOff));
                blockCipher.ProcessBlock(array4, 0, array4, 0);
                global::System.Array.Copy((global::System.Array)array4, 0, (global::System.Array)output, num4, num5 - (i - inOff));
                byte[] b = new byte[BlockSize];
                CalculateMac(output, outOff, num5, b);
                if (!Arrays.ConstantTimeAreEqual(macBlock, b))
                {
                    throw new InvalidCipherTextException("mac check in CCM failed");
                }
            }
            return(num5);
        }