Inheritance: ICipherParameters
Exemplo n.º 1
0
		public override void PerformTest()
		{
			ICipherParameters kp = new KeyParameter(
				Hex.Decode("9661410AB797D8A9EB767C21172DF6C7"));
			ICipherParameters kpwiv = new ParametersWithIV(kp,
				Hex.Decode("4B5C2F003E67F39557A8D26F3DA2B155"));

            int offset = 117;
            byte[] m = new byte[512];
			for (int i = 0; i < 256; i++)
			{
				m[offset + i] = (byte)i;
			}

            VmpcMac mac = new VmpcMac();
			mac.Init(kpwiv);

			mac.BlockUpdate(m, offset, 256);

			byte[] output = new byte[20];
			mac.DoFinal(output, 0);

			if (!Arrays.AreEqual(output, output1))
			{
				Fail("Fail",
					Hex.ToHexString(output1),
					Hex.ToHexString(output));
			}
		}
Exemplo n.º 2
0
		public override void PerformTest()
		{
			byte[] key = Hex.Decode("9661410AB797D8A9EB767C21172DF6C7");
			byte[] iv = Hex.Decode("4B5C2F003E67F39557A8D26F3DA2B155");
			ICipherParameters kp = new KeyParameter(key);
			ICipherParameters kpwiv = new ParametersWithIV(kp, iv);

			VmpcKsa3Engine engine = new VmpcKsa3Engine();

			try
			{
				engine.Init(true, kp);
				Fail("Init failed to throw expected exception");
			}
			catch (ArgumentException)
			{
				// Expected
			}

			engine.Init(true, kpwiv);
			checkEngine(engine);

			engine.Reset();
			byte[] output = checkEngine(engine);

			engine.Init(false, kpwiv);
			byte[] recovered = new byte[output.Length];
			engine.ProcessBytes(output, 0, output.Length, recovered, 0);

			if (!Arrays.AreEqual(input, recovered))
			{
				Fail("decrypted bytes differ from original bytes");
			}
		}
Exemplo n.º 3
0
        protected virtual ParametersWithIV CreateParametersWithIV(KeyParameter key,
			byte[] buf, ref int off, int len)
		{
			ParametersWithIV ivParams = new ParametersWithIV(key, buf, off, len);
			off += len;
			return ivParams;
		}
		public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
		{
			byte[] keyBytes = contentEncryptionKey.GetKey();

			string rfc3211WrapperName = Helper.GetRfc3211WrapperName(keyEncryptionKeyOID);
			IWrapper keyWrapper = Helper.CreateWrapper(rfc3211WrapperName);

			// Note: In Java build, the IV is automatically generated in JCE layer
			int ivLength = Platform.StartsWith(rfc3211WrapperName, "DESEDE") ? 8 : 16;
			byte[] iv = new byte[ivLength];
			random.NextBytes(iv);

			ICipherParameters parameters = new ParametersWithIV(keyEncryptionKey, iv);
			keyWrapper.Init(true, new ParametersWithRandom(parameters, random));
        	Asn1OctetString encryptedKey = new DerOctetString(
				keyWrapper.Wrap(keyBytes, 0, keyBytes.Length));

			DerSequence seq = new DerSequence(
				new DerObjectIdentifier(keyEncryptionKeyOID),
				new DerOctetString(iv));

			AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier(
				PkcsObjectIdentifiers.IdAlgPwriKek, seq);

			return new RecipientInfo(new PasswordRecipientInfo(
				keyDerivationAlgorithm, keyEncryptionAlgorithm, encryptedKey));
		}
		/**
		 * decrypt the content and return an input stream.
		 */
		public override CmsTypedStream GetContentStream(
			ICipherParameters key)
		{
			try
			{
				AlgorithmIdentifier kekAlg = AlgorithmIdentifier.GetInstance(info.KeyEncryptionAlgorithm);
				Asn1Sequence        kekAlgParams = (Asn1Sequence)kekAlg.Parameters;
				byte[]              encryptedKey = info.EncryptedKey.GetOctets();
				string              kekAlgName = DerObjectIdentifier.GetInstance(kekAlgParams[0]).Id;
				string				cName = CmsEnvelopedHelper.Instance.GetRfc3211WrapperName(kekAlgName);
				IWrapper			keyWrapper = WrapperUtilities.GetWrapper(cName);

				byte[] iv = Asn1OctetString.GetInstance(kekAlgParams[1]).GetOctets();

				ICipherParameters parameters = ((CmsPbeKey)key).GetEncoded(kekAlgName);
				parameters = new ParametersWithIV(parameters, iv);

				keyWrapper.Init(false, parameters);

				KeyParameter sKey = ParameterUtilities.CreateKeyParameter(
					GetContentAlgorithmName(), keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length));

				return GetContentFromSessionKey(sKey);
			}
			catch (SecurityUtilityException e)
			{
				throw new CmsException("couldn't create cipher.", e);
			}
			catch (InvalidKeyException e)
			{
				throw new CmsException("key invalid in message.", e);
			}
		}
Exemplo n.º 6
0
		private static ParametersWithIV CreateParametersWithIV(KeyParameter key,
			byte[] buf, ref int off, int len)
		{
			ParametersWithIV ivParams = new ParametersWithIV(key, buf, off, len);
			off += len;
			return ivParams;
		}
Exemplo n.º 7
0
 /** Creates a new instance of AESCipher */
 public AESCipher(bool forEncryption, byte[] key, byte[] iv) {
     IBlockCipher aes = new AesFastEngine();
     IBlockCipher cbc = new CbcBlockCipher(aes);
     bp = new PaddedBufferedBlockCipher(cbc);
     KeyParameter kp = new KeyParameter(key);
     ParametersWithIV piv = new ParametersWithIV(kp, iv);
     bp.Init(forEncryption, piv);
 }
		private void initCipher(bool forEncryption, IBlockCipher cipher,
								byte[] key_block, int key_size, int key_offset, int iv_offset)
		{
			KeyParameter key_parameter = new KeyParameter(key_block, key_offset,
				key_size);
			ParametersWithIV parameters_with_iv = new ParametersWithIV(
				key_parameter, key_block, iv_offset, cipher.GetBlockSize());
			cipher.Init(forEncryption, parameters_with_iv);
		}
Exemplo n.º 9
0
 public byte[] GenerateAesCtrCipher(byte[] iv, byte[] encryptKey, byte[] input)
 {
     //ctr https://gist.github.com/hanswolff/8809275 
     var key = ParameterUtilities.CreateKeyParameter("AES", encryptKey);
     var parametersWithIv = new ParametersWithIV(key, iv);
     var cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");
     cipher.Init(true, parametersWithIv);
     return cipher.DoFinal(input);
 }
Exemplo n.º 10
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;
		}
Exemplo n.º 11
0
 public override ICipherParameters GenParam()
 {
     string pass = SafeUtil.GenPass(_Uk.TbPass.Text, _Uk.TbPass.MaxLength);
     ICipherParameters param = new KeyParameter(Encoding.Default.GetBytes(pass));
     if (_Uk.TbSalt.Visible)
     {
         pass = SafeUtil.GenPass(_Uk.TbSalt.Text, _Uk.TbSalt.MaxLength);
         param = new ParametersWithIV(param, Encoding.Default.GetBytes(pass));
     }
     return param;
 }
Exemplo n.º 12
0
        /// <summary>
        /// Generates a key from a password and salt and IV
        /// </summary>
        /// <param name="password"></param>
        /// <param name="saltBytes"></param>
        /// <param name="ivBytes"></param>
        /// <returns></returns>
        private static ParametersWithIV GenerateKey(string password, byte[] saltBytes, byte[] ivBytes)
        {
            var passBytes = PbeParametersGenerator.Pkcs5PasswordToUtf8Bytes(password.ToCharArray());

            //create key generator
            var generator = new Pkcs5S2ParametersGenerator();
            //initialize
            generator.Init(passBytes, saltBytes, KEY_DERIVATION_ITERATION);

            //generate with a 256bit key, and a 128bit IV
            var kp = new ParametersWithIV(generator.GenerateDerivedParameters(ALGORITHM_NAME, KEY_SIZE), ivBytes);

            return kp;
        }
Exemplo n.º 13
0
        public static byte[] AESGetEncrypt(byte[] key, byte[] plain_data_array, UInt64 counter)
        {
            if (key == null || key.Length == 0 || key.Length != 16)
                throw new ArgumentException("AESGetEncrypt: The key cannot be null/empty and must be 16 bytes in length");

            if (plain_data_array == null || plain_data_array.Length == 0)
                throw new ArgumentException("AESGetEncrypt: The plain data be null/empty");

            var _cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");
            ParametersWithIV _parameter_with_iv = new ParametersWithIV(new KeyParameter(key), GetAESCounterBytes(counter));
            _cipher.Init(true, _parameter_with_iv);

            return _cipher.DoFinal(plain_data_array);
        }
Exemplo n.º 14
0
 public static string myDecrypt(string cipherText)
 {
     // encryption key... 
     var key = Encoding.UTF8.GetBytes("0123456789abcdef");
     var iv = Encoding.UTF8.GetBytes("fedcba9876543210");
     var cipher = CipherUtilities.GetCipher("AES/CBC/NoPadding");
     ParametersWithIV par = new ParametersWithIV(new KeyParameter(key), iv);
     // Initialise the cipher... 
     cipher.Init(false, par);
     var bytes = cipher.DoFinal(StringToByteArray(cipherText));
     string result = Encoding.UTF8.GetString(bytes, 0, bytes.Length); //result is Always \0\0\0\0\0\0\0\0\0\0\0.... 
     string[] words = result.Split('\0');
     return words[0];
 }
Exemplo n.º 15
0
		/**
        * Method init
        *
        * @param forWrapping
        * @param param
        */
        public virtual void Init(
			bool				forWrapping,
			ICipherParameters	parameters)
        {
            this.forWrapping = forWrapping;
            this.engine = new CbcBlockCipher(new DesEdeEngine());

			SecureRandom sr;
			if (parameters is ParametersWithRandom)
			{
				ParametersWithRandom pr = (ParametersWithRandom) parameters;
				parameters = pr.Parameters;
				sr = pr.Random;
			}
			else
			{
				sr = new SecureRandom();
			}

			if (parameters is KeyParameter)
            {
                this.param = (KeyParameter) parameters;
                if (this.forWrapping)
				{
                    // Hm, we have no IV but we want to wrap ?!?
                    // well, then we have to create our own IV.
                    this.iv = new byte[8];
					sr.NextBytes(iv);

					this.paramPlusIV = new ParametersWithIV(this.param, this.iv);
                }
            }
            else if (parameters is ParametersWithIV)
            {
				if (!forWrapping)
					throw new ArgumentException("You should not supply an IV for unwrapping");

				this.paramPlusIV = (ParametersWithIV) parameters;
                this.iv = this.paramPlusIV.GetIV();
                this.param = (KeyParameter) this.paramPlusIV.Parameters;

				if (this.iv.Length != 8)
					throw new ArgumentException("IV is not 8 octets", "parameters");
            }
        }
Exemplo n.º 16
0
        public static AesEncyrption getInstance()
        {


            if (instance == null)
            {

                try
                {
                    if (string.IsNullOrEmpty(_encryptionKey))
                    {
                        Initalize();
                    }
                    AesEncyrption bcEngine = new AesEncyrption();
                    KeyParameter keyParam = new KeyParameter(Encoding.UTF8.GetBytes(_encryptionKey));
                    ICipherParameters param = new ParametersWithIV(keyParam, iv);

                    //create decrypt/encryptor cipher
                    IBlockCipherPadding padding = new Pkcs7Padding();
                    BufferedBlockCipher decrypt = new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesEngine()), padding);
                    decrypt.Reset();
                    decrypt.Init(false, param);
                    bcEngine.setDecryptCipher(decrypt);

                    BufferedBlockCipher encrypt = new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesEngine()), padding);
                    encrypt.Reset();
                    encrypt.Init(true, param);
                    bcEngine.setEncryptCipher(encrypt);

                    instance = bcEngine;
                }
                catch (Exception)
                {

                    throw;
                }



            }
            return instance;

        }
Exemplo n.º 17
0
		public void Init(
			bool				forWrapping,
			ICipherParameters	param)
		{
			this.forWrapping = forWrapping;

			if (param is ParametersWithRandom)
			{
				ParametersWithRandom p = (ParametersWithRandom) param;

				this.rand = p.Random;
				this.param = (ParametersWithIV) p.Parameters;
			}
			else
			{
				if (forWrapping)
				{
					rand = new SecureRandom();
				}

				this.param = (ParametersWithIV) param;
			}
		}
Exemplo n.º 18
0
		protected void oidTest(
			string[]	oids,
			string[]	names,
			int			groupSize)
		{
			byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};

			for (int i = 0; i != oids.Length; i++)
			{
				IBufferedCipher c1 = CipherUtilities.GetCipher(oids[i]);
				IBufferedCipher c2 = CipherUtilities.GetCipher(names[i]);
				CipherKeyGenerator kg = GeneratorUtilities.GetKeyGenerator(oids[i]);

				KeyParameter k = ParameterUtilities.CreateKeyParameter(oids[i], kg.GenerateKey());

				ICipherParameters cp = k;
				if (names[i].IndexOf("/ECB/") < 0)
				{
					cp = new ParametersWithIV(cp, new byte[16]);
				}

				c1.Init(true, cp);
				c2.Init(false, cp);

				byte[] result = c2.DoFinal(c1.DoFinal(data));

				if (!AreEqual(data, result))
				{
					Fail("failed OID test");
				}

				if (k.GetKey().Length != (16 + ((i / groupSize) * 8)))
				{
					Fail("failed key length test");
				}
			}
		}
Exemplo n.º 19
0
        private static byte[] decrypt28147cfb(byte[] key, byte[] input)
        {
            ICipherParameters param = new ParametersWithIV(
                new ParametersWithSBox(
                    new KeyParameter(key), //key
                    Gost28147Engine.GetSBox("E-A")), //type S-box
                Hex.Decode("0000000000000000")); //IV

            byte[] output = new byte[input.Length];

            BufferedBlockCipher cipher = new BufferedBlockCipher(new CfbBlockCipher(new Gost28147Engine(), 64));
            cipher.Init(false, param);
            int len1 = cipher.ProcessBytes(input, 0, input.Length, output, 0);
            try
            {
                cipher.DoFinal(output, len1);
            }
            catch (CryptoException ex)
            {
                //MessageBox.Show("Error: " + ex.Message);
            }

            return output;
        }
Exemplo n.º 20
0
		static uint[] Run (IBlockCipher algo, byte[] key, byte[] iv)
		{
			IBlockCipher cipher = new Org.BouncyCastle.Crypto.Modes.CbcBlockCipher (algo);
			ParametersWithIV param = new ParametersWithIV (new KeyParameter (key), iv);
			Stopwatch sw = new Stopwatch ();
			uint[] result = new uint[2];
			sw.Reset (); sw.Start ();
			for (int i = 0; i < LOOP; i++) {
				cipher.Init (true, param);
				cipher.Reset ();
			}
			sw.Stop ();
			result[0] = (uint)(LOOP / sw.Elapsed.TotalSeconds);

			sw.Reset (); sw.Start ();
			for (int i = 0; i < LOOP; i++) {
				cipher.Init (false, param);
				cipher.Reset ();
			}
			sw.Stop ();
			result[1] = (uint)(LOOP / sw.Elapsed.TotalSeconds);

			return result;
		}
Exemplo n.º 21
0
        /// <exception cref="IOException"></exception>
        public TlsStreamCipher(TlsContext context, IStreamCipher clientWriteCipher,
            IStreamCipher serverWriteCipher, IDigest clientWriteDigest, IDigest serverWriteDigest,
            int cipherKeySize, bool usesNonce)
        {
            bool isServer = context.IsServer;

            this.context = context;
            this.usesNonce = usesNonce;

            this.encryptCipher = clientWriteCipher;
            this.decryptCipher = serverWriteCipher;

            int key_block_size = (2 * cipherKeySize) + clientWriteDigest.GetDigestSize()
                + serverWriteDigest.GetDigestSize();

            byte[] key_block = TlsUtilities.CalculateKeyBlock(context, key_block_size);

            int offset = 0;

            // Init MACs
            TlsMac clientWriteMac = new TlsMac(context, clientWriteDigest, key_block, offset,
                clientWriteDigest.GetDigestSize());
            offset += clientWriteDigest.GetDigestSize();
            TlsMac serverWriteMac = new TlsMac(context, serverWriteDigest, key_block, offset,
                serverWriteDigest.GetDigestSize());
            offset += serverWriteDigest.GetDigestSize();

            // Build keys
            KeyParameter clientWriteKey = new KeyParameter(key_block, offset, cipherKeySize);
            offset += cipherKeySize;
            KeyParameter serverWriteKey = new KeyParameter(key_block, offset, cipherKeySize);
            offset += cipherKeySize;

            if (offset != key_block_size)
            {
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            ICipherParameters encryptParams, decryptParams;
            if (isServer)
            {
                this.writeMac = serverWriteMac;
                this.readMac = clientWriteMac;
                this.encryptCipher = serverWriteCipher;
                this.decryptCipher = clientWriteCipher;
                encryptParams = serverWriteKey;
                decryptParams = clientWriteKey;
            }
            else
            {
                this.writeMac = clientWriteMac;
                this.readMac = serverWriteMac;
                this.encryptCipher = clientWriteCipher;
                this.decryptCipher = serverWriteCipher;
                encryptParams = clientWriteKey;
                decryptParams = serverWriteKey;
            }

            if (usesNonce)
            {
                byte[] dummyNonce = new byte[8];
                encryptParams = new ParametersWithIV(encryptParams, dummyNonce);
                decryptParams = new ParametersWithIV(decryptParams, dummyNonce);
            }

            this.encryptCipher.Init(true, encryptParams);
            this.decryptCipher.Init(false, decryptParams);
        }
        private Asn1Object CreateDERForRecipient(byte[] inp, X509Certificate cert) {
            
            String s = "1.2.840.113549.3.2";
            
            byte[] outp = new byte[100];
            DerObjectIdentifier derob = new DerObjectIdentifier(s);
            byte[] keyp = IVGenerator.GetIV(16);
            IBufferedCipher cf = CipherUtilities.GetCipher(derob);
            KeyParameter kp = new KeyParameter(keyp);
            byte[] iv = IVGenerator.GetIV(cf.GetBlockSize());
            ParametersWithIV piv = new ParametersWithIV(kp, iv);
            cf.Init(true, piv);
            int len = cf.DoFinal(inp, outp, 0);

            byte[] abyte1 = new byte[len];
            System.Array.Copy(outp, 0, abyte1, 0, len);
            DerOctetString deroctetstring = new DerOctetString(abyte1);
            KeyTransRecipientInfo keytransrecipientinfo = ComputeRecipientInfo(cert, keyp);
            DerSet derset = new DerSet(new RecipientInfo(keytransrecipientinfo));
            Asn1EncodableVector ev = new Asn1EncodableVector();
            ev.Add(new DerInteger(58));
            ev.Add(new DerOctetString(iv));
            DerSequence seq = new DerSequence(ev);
            AlgorithmIdentifier algorithmidentifier = new AlgorithmIdentifier(derob, seq);
            EncryptedContentInfo encryptedcontentinfo = 
                new EncryptedContentInfo(PkcsObjectIdentifiers.Data, algorithmidentifier, deroctetstring);
            Asn1Set set = null;
            EnvelopedData env = new EnvelopedData(null, derset, encryptedcontentinfo, set);
            Org.BouncyCastle.Asn1.Cms.ContentInfo contentinfo = 
                new Org.BouncyCastle.Asn1.Cms.ContentInfo(PkcsObjectIdentifiers.EnvelopedData, env);
            return contentinfo.ToAsn1Object();        
        }
        /**
        * Method unwrap
        *
        * @param in
        * @param inOff
        * @param inLen
        * @return
        * @throws InvalidCipherTextException
        */
        public byte[] Unwrap(
			byte[]	input,
			int		inOff,
			int		length)
        {
            if (forWrapping)
            {
                throw new InvalidOperationException("Not set for unwrapping");
            }
            if (input == null)
            {
                throw new InvalidCipherTextException("Null pointer as ciphertext");
            }

            int blockSize = engine.GetBlockSize();

            if (length % blockSize != 0)
            {
                throw new InvalidCipherTextException("Ciphertext not multiple of " + blockSize);
            }

            /*
            // Check if the length of the cipher text is reasonable given the key
            // type. It must be 40 bytes for a 168 bit key and either 32, 40, or
            // 48 bytes for a 128, 192, or 256 bit key. If the length is not supported
            // or inconsistent with the algorithm for which the key is intended,
            // return error.
            //
            // we do not accept 168 bit keys. it has to be 192 bit.
            int lengthA = (estimatedKeyLengthInBit / 8) + 16;
            int lengthB = estimatedKeyLengthInBit % 8;
            if ((lengthA != keyToBeUnwrapped.Length) || (lengthB != 0)) {
                throw new XMLSecurityException("empty");
            }
            */

            // Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK
            // and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3.
            ParametersWithIV param2 = new ParametersWithIV(this.param, IV2);
            this.engine.Init(false, param2);

            byte [] TEMP3 = new byte[length];

            for (int currentBytePos = 0; currentBytePos != TEMP3.Length; currentBytePos += blockSize)
            {
                engine.ProcessBlock(input, inOff + currentBytePos, TEMP3, currentBytePos);
            }

            // Reverse the order of the octets in TEMP3 and call the result TEMP2.
            byte[] TEMP2 = reverse(TEMP3);

            // Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets.
            this.iv = new byte[8];
            byte[] TEMP1 = new byte[TEMP2.Length - 8];
            Array.Copy(TEMP2, 0, this.iv, 0, 8);
            Array.Copy(TEMP2, 8, TEMP1, 0, TEMP2.Length - 8);

            // Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV
            // found in the previous step. Call the result WKCKS.
            this.paramPlusIV = new ParametersWithIV(this.param, this.iv);
            this.engine.Init(false, this.paramPlusIV);

            byte[] WKCKS = new byte[TEMP1.Length];

            for (int currentBytePos = 0; currentBytePos != WKCKS.Length; currentBytePos += blockSize)
            {
                engine.ProcessBlock(TEMP1, currentBytePos, WKCKS, currentBytePos);
            }

            // Decompose WKCKS. CKS is the last 8 octets and WK, the wrapped key, are
            // those octets before the CKS.
            byte[] result = new byte[WKCKS.Length - 8];
            byte[] CKStoBeVerified = new byte[8];
            Array.Copy(WKCKS, 0, result, 0, WKCKS.Length - 8);
            Array.Copy(WKCKS, WKCKS.Length - 8, CKStoBeVerified, 0, 8);

            // Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare
            // with the CKS extracted in the above step. If they are not equal, return error.
            if (!CheckCmsKeyChecksum(result, CKStoBeVerified)) {
                throw new InvalidCipherTextException(
                    "Checksum inside ciphertext is corrupted");
            }

            // WK is the wrapped key, now extracted for use in data decryption.
            return result;
        }
Exemplo n.º 24
0
		public byte[] Cloak()
		{
			Encode ();

			byte[] outData = new byte[FullPacket.Length + 8];

			// Get our nonce
			Random rnd = new Random ();
			byte[] nonce = new byte[8];
			rnd.NextBytes (nonce);
			// We can't have a leading 0 byte
			if (nonce [0] == 0) {
				nonce [0] = 1;
			}

			var parms = new ParametersWithIV(new KeyParameter(cloakKey), nonce);
			var chacha = new ChaChaEngine(20);
			chacha.Init(true, parms);
			chacha.ProcessBytes (FullPacket, 0, FullPacket.Length, outData, 8);
			Buffer.BlockCopy (nonce, 0, outData, 0, 8);

			return outData;
		}
Exemplo n.º 25
0
		public override void PerformTest()
		{
			base.PerformTest();

			//advanced tests with Gost28147KeyGenerator:
			//encrypt on hesh message; ECB mode:
			byte[] inBytes = Hex.Decode("4e6f77206973207468652074696d6520666f7220616c6c20");
			byte[] output = Hex.Decode("8ad3c8f56b27ff1fbd46409359bdc796bc350e71aac5f5c0");
			byte[] outBytes = new byte[inBytes.Length];

			byte[] key = generateKey(Hex.Decode("0123456789abcdef"));  //!!! heshing start_key - get 256 bits !!!
	//        System.out.println(new string(Hex.Encode(key)));
			ICipherParameters  param = new ParametersWithSBox(new KeyParameter(key), Gost28147Engine.GetSBox("E-A"));
			//CipherParameters  param = new Gost28147Parameters(key,"D-Test");
			BufferedBlockCipher cipher = new BufferedBlockCipher(new Gost28147Engine());

			cipher.Init(true, param);
			int len1 = cipher.ProcessBytes(inBytes, 0, inBytes.Length, outBytes, 0);
			try
			{
				cipher.DoFinal(outBytes, len1);
			}
			catch (CryptoException e)
			{
				Fail("failed - exception " + e.ToString(), e);
			}

			if (outBytes.Length != output.Length)
			{
				Fail("failed - "
					+ "expected " + Hex.ToHexString(output) + " got "
					+ Hex.ToHexString(outBytes));
			}

			for (int i = 0; i != outBytes.Length; i++)
			{
				if (outBytes[i] != output[i])
				{
					Fail("failed - "
						+ "expected " + Hex.ToHexString(output)
						+ " got " + Hex.ToHexString(outBytes));
				}
			}


			//encrypt on hesh message; CFB mode:
			inBytes = Hex.Decode("bc350e71aac5f5c2");
			output = Hex.Decode("0ebbbafcf38f14a5");
			outBytes = new byte[inBytes.Length];

			key = generateKey(Hex.Decode("0123456789abcdef"));  //!!! heshing start_key - get 256 bits !!!
			param = new ParametersWithIV(
				new ParametersWithSBox(
					new KeyParameter(key), //key
					Gost28147Engine.GetSBox("E-A")), //type S-box
				Hex.Decode("1234567890abcdef")); //IV

			cipher = new BufferedBlockCipher(new CfbBlockCipher(new Gost28147Engine(), 64));

			cipher.Init(true, param);
			len1 = cipher.ProcessBytes(inBytes, 0, inBytes.Length, outBytes, 0);
			try
			{
				cipher.DoFinal(outBytes, len1);
			}
			catch (CryptoException e)
			{
				Fail("failed - exception " + e.ToString(), e);
			}
			if (outBytes.Length != output.Length)
			{
				Fail("failed - "
					+ "expected " + Hex.ToHexString(output)
					+ " got " + Hex.ToHexString(outBytes));
			}
			for (int i = 0; i != outBytes.Length; i++)
			{
				if (outBytes[i] != output[i])
				{
					Fail("failed - "
						+ "expected " + Hex.ToHexString(output)
						+ " got " + Hex.ToHexString(outBytes));
				}
			}


			//encrypt on hesh message; CFB mode:
			inBytes = Hex.Decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f");
			output = Hex.Decode("64988982819f0a1655e226e19ecad79d10cc73bac95c5d7da034786c12294225");
			outBytes = new byte[inBytes.Length];

			key = generateKey(Hex.Decode("aafd12f659cae63489b479e5076ddec2f06cb58faafd12f659cae63489b479e5"));  //!!! heshing start_key - get 256 bits !!!
			param = new ParametersWithIV(
				new ParametersWithSBox(
					new KeyParameter(key), //key
					Gost28147Engine.GetSBox("E-A")), //type S-box
				Hex.Decode("aafd12f659cae634")); //IV

			cipher = new BufferedBlockCipher(new CfbBlockCipher(new Gost28147Engine(), 64));

			cipher.Init(true, param);
			len1 = cipher.ProcessBytes(inBytes, 0, inBytes.Length, outBytes, 0);

			cipher.DoFinal(outBytes, len1);

			if (outBytes.Length != output.Length)
			{
				Fail("failed - "
					+ "expected " + Hex.ToHexString(output)
					+ " got " + Hex.ToHexString(outBytes));
			}

			for (int i = 0; i != outBytes.Length; i++)
			{
				if (outBytes[i] != output[i])
				{
					Fail("failed - "
						+ "expected " + Hex.ToHexString(output)
						+ " got " + Hex.ToHexString(outBytes));
				}
			}

			//encrypt on hesh message; OFB mode:
			inBytes = Hex.Decode("bc350e71aa11345709acde");
			output = Hex.Decode("1bcc2282707c676fb656dc");
			outBytes = new byte[inBytes.Length];

			key = generateKey(Hex.Decode("0123456789abcdef"));  //!!! heshing start_key - get 256 bits !!!
			param = new ParametersWithIV(
				new ParametersWithSBox(
					new KeyParameter(key), //key
					Gost28147Engine.GetSBox("E-A")), //type S-box
				Hex.Decode("1234567890abcdef")); //IV

			cipher = new BufferedBlockCipher(new GOfbBlockCipher(new Gost28147Engine()));

			cipher.Init(true, param);
			len1 = cipher.ProcessBytes(inBytes, 0, inBytes.Length, outBytes, 0);

			cipher.DoFinal(outBytes, len1);

			if (outBytes.Length != output.Length)
			{
				Fail("failed - "
					+ "expected " + Hex.ToHexString(output)
					+ " got " + Hex.ToHexString(outBytes));
			}

			for (int i = 0; i != outBytes.Length; i++)
			{
				if (outBytes[i] != output[i])
				{
					Fail("failed - "
						+ "expected " + Hex.ToHexString(output)
						+ " got " + Hex.ToHexString(outBytes));
				}
			}
		}
Exemplo n.º 26
0
		/// <summary>
		/// Decloak the given buffer and return the valid Packet from it
		/// </summary>
		/// <param name="buffer">A cloaked packet buffer.</param>
		static public Packet Decloak(byte[] buffer)
		{
			if (buffer.Length < 8 || buffer [0] == 0) {
				return Packet.DecodePacket (buffer);
			}

			byte[] nonce = buffer.Take (8).ToArray ();
			var parms = new ParametersWithIV(new KeyParameter(cloakKey), nonce);

			var chacha = new ChaChaEngine(20);
			chacha.Init(false, parms);
			byte[] outBuff = new byte[buffer.Length - 8];
			chacha.ProcessBytes(buffer, 8, buffer.Length - 8, outBuff, 0);

			return Decloak (outBuff);
		}
Exemplo n.º 27
0
        public static ICipherParameters GenerateCipherParameters(
			string          algorithm,
			char[]          password,
			bool			wrongPkcs12Zero,
			Asn1Encodable   pbeParameters)
        {
            string	mechanism = (string) algorithms[algorithm.ToUpperInvariant()];

            byte[] keyBytes = null;
            byte[] salt = null;
            int iterationCount = 0;

            if (IsPkcs12(mechanism))
            {
                Pkcs12PbeParams pbeParams = Pkcs12PbeParams.GetInstance(pbeParameters);
                salt = pbeParams.GetIV();
                iterationCount = pbeParams.Iterations.IntValue;
                keyBytes = PbeParametersGenerator.Pkcs12PasswordToBytes(password, wrongPkcs12Zero);
            }
            else if (IsPkcs5Scheme2(mechanism))
            {
                // See below
            }
            else
            {
                PbeParameter pbeParams = PbeParameter.GetInstance(pbeParameters);
                salt = pbeParams.GetSalt();
                iterationCount = pbeParams.IterationCount.IntValue;
                keyBytes = PbeParametersGenerator.Pkcs5PasswordToBytes(password);
            }

            ICipherParameters parameters = null;

            if (IsPkcs5Scheme2(mechanism))
            {
                PbeS2Parameters s2p = PbeS2Parameters.GetInstance(pbeParameters.ToAsn1Object());
                AlgorithmIdentifier encScheme = s2p.EncryptionScheme;
                DerObjectIdentifier encOid = encScheme.ObjectID;
                Asn1Object encParams = encScheme.Parameters.ToAsn1Object();

                // TODO What about s2p.KeyDerivationFunc.ObjectID?
                Pbkdf2Params pbeParams = Pbkdf2Params.GetInstance(s2p.KeyDerivationFunc.Parameters.ToAsn1Object());

                byte[] iv;
                if (encOid.Equals(PkcsObjectIdentifiers.RC2Cbc)) // PKCS5.B.2.3
                {
                    RC2CbcParameter rc2Params = RC2CbcParameter.GetInstance(encParams);
                    iv = rc2Params.GetIV();
                }
                else
                {
                    iv = Asn1OctetString.GetInstance(encParams).GetOctets();
                }

                salt = pbeParams.GetSalt();
                iterationCount = pbeParams.IterationCount.IntValue;
                keyBytes = PbeParametersGenerator.Pkcs5PasswordToBytes(password);

                int keyLength = pbeParams.KeyLength != null
                    ?	pbeParams.KeyLength.IntValue * 8
                    :	GeneratorUtilities.GetDefaultKeySize(encOid);

                PbeParametersGenerator gen = MakePbeGenerator(
                    (string)algorithmType[mechanism], null, keyBytes, salt, iterationCount);

                parameters = gen.GenerateDerivedParameters(encOid.Id, keyLength);

                if (iv != null)
                {
                    // FIXME? OpenSSL weirdness with IV of zeros (for ECB keys?)
                    if (Arrays.AreEqual(iv, new byte[iv.Length]))
                    {
                        //System.Diagnostics.Debug.Error.Write("***** IV all 0 (length " + iv.Length + ") *****");
                    }
                    else
                    {
                        parameters = new ParametersWithIV(parameters, iv);
                    }
                }
            }
            else if (mechanism.StartsWith("PBEwithSHA-1"))
            {
                PbeParametersGenerator generator = MakePbeGenerator(
                    (string) algorithmType[mechanism], new Sha1Digest(), keyBytes, salt, iterationCount);

                if (mechanism.Equals("PBEwithSHA-1and128bitRC4"))
                {
                    parameters = generator.GenerateDerivedParameters("RC4", 128);
                }
                else if (mechanism.Equals("PBEwithSHA-1and40bitRC4"))
                {
                    parameters = generator.GenerateDerivedParameters("RC4", 40);
                }
                else if (mechanism.Equals("PBEwithSHA-1and3-keyDESEDE-CBC"))
                {
                    parameters = generator.GenerateDerivedParameters("DESEDE", 192, 64);
                }
                else if (mechanism.Equals("PBEwithSHA-1and2-keyDESEDE-CBC"))
                {
                    parameters = generator.GenerateDerivedParameters("DESEDE", 128, 64);
                }
                else if (mechanism.Equals("PBEwithSHA-1and128bitRC2-CBC"))
                {
                    parameters = generator.GenerateDerivedParameters("RC2", 128, 64);
                }
                else if (mechanism.Equals("PBEwithSHA-1and40bitRC2-CBC"))
                {
                    parameters = generator.GenerateDerivedParameters("RC2", 40, 64);
                }
                else if (mechanism.Equals("PBEwithSHA-1andDES-CBC"))
                {
                    parameters = generator.GenerateDerivedParameters("DES", 64, 64);
                }
                else if (mechanism.Equals("PBEwithSHA-1andRC2-CBC"))
                {
                    parameters = generator.GenerateDerivedParameters("RC2", 64, 64);
                }
                else if (mechanism.Equals("PBEwithSHA-1and128bitAES-CBC-BC"))
                {
                    parameters = generator.GenerateDerivedParameters("AES", 128, 128);
                }
                else if (mechanism.Equals("PBEwithSHA-1and192bitAES-CBC-BC"))
                {
                    parameters = generator.GenerateDerivedParameters("AES", 192, 128);
                }
                else if (mechanism.Equals("PBEwithSHA-1and256bitAES-CBC-BC"))
                {
                    parameters = generator.GenerateDerivedParameters("AES", 256, 128);
                }
            }
            else if (mechanism.StartsWith("PBEwithSHA-256"))
            {
                PbeParametersGenerator generator = MakePbeGenerator(
                    (string) algorithmType[mechanism], new Sha256Digest(), keyBytes, salt, iterationCount);

                if (mechanism.Equals("PBEwithSHA-256and128bitAES-CBC-BC"))
                {
                    parameters = generator.GenerateDerivedParameters("AES", 128, 128);
                }
                else if (mechanism.Equals("PBEwithSHA-256and192bitAES-CBC-BC"))
                {
                    parameters = generator.GenerateDerivedParameters("AES", 192, 128);
                }
                else if (mechanism.Equals("PBEwithSHA-256and256bitAES-CBC-BC"))
                {
                    parameters = generator.GenerateDerivedParameters("AES", 256, 128);
                }
            }
            else if (mechanism.StartsWith("PBEwithMD5"))
            {
                PbeParametersGenerator generator = MakePbeGenerator(
                    (string)algorithmType[mechanism], new MD5Digest(), keyBytes, salt, iterationCount);

                if (mechanism.Equals("PBEwithMD5andDES-CBC"))
                {
                    parameters = generator.GenerateDerivedParameters("DES", 64, 64);
                }
                else if (mechanism.Equals("PBEwithMD5andRC2-CBC"))
                {
                    parameters = generator.GenerateDerivedParameters("RC2", 64, 64);
                }
                else if (mechanism.Equals("PBEwithMD5and128bitAES-CBC-OpenSSL"))
                {
                    parameters = generator.GenerateDerivedParameters("AES", 128, 128);
                }
                else if (mechanism.Equals("PBEwithMD5and192bitAES-CBC-OpenSSL"))
                {
                    parameters = generator.GenerateDerivedParameters("AES", 192, 128);
                }
                else if (mechanism.Equals("PBEwithMD5and256bitAES-CBC-OpenSSL"))
                {
                    parameters = generator.GenerateDerivedParameters("AES", 256, 128);
                }
            }
            else if (mechanism.StartsWith("PBEwithMD2"))
            {
                PbeParametersGenerator generator = MakePbeGenerator(
                    (string)algorithmType[mechanism], new MD2Digest(), keyBytes, salt, iterationCount);
                if (mechanism.Equals("PBEwithMD2andDES-CBC"))
                {
                    parameters = generator.GenerateDerivedParameters("DES", 64, 64);
                }
                else if (mechanism.Equals("PBEwithMD2andRC2-CBC"))
                {
                    parameters = generator.GenerateDerivedParameters("RC2", 64, 64);
                }
            }
            else if (mechanism.StartsWith("PBEwithHmac"))
            {
                string digestName = mechanism.Substring("PBEwithHmac".Length);
                IDigest digest = DigestUtilities.GetDigest(digestName);

                PbeParametersGenerator generator = MakePbeGenerator(
                    (string) algorithmType[mechanism], digest, keyBytes, salt, iterationCount);

                int bitLen = digest.GetDigestSize() * 8;
                parameters = generator.GenerateDerivedMacParameters(bitLen);
            }

            Array.Clear(keyBytes, 0, keyBytes.Length);

            return FixDesParity(mechanism, parameters);
        }
Exemplo n.º 28
0
		private void doRunTest(
			string	name,
			int		ivLength)
		{
			string lCode = "ABCDEFGHIJKLMNOPQRSTUVWXY0123456789";

			string baseName = name;
			if (name.IndexOf('/') >= 0)
			{
				baseName = name.Substring(0, name.IndexOf('/'));
			}

			CipherKeyGenerator kGen = GeneratorUtilities.GetKeyGenerator(baseName);

			IBufferedCipher inCipher = CipherUtilities.GetCipher(name);
			IBufferedCipher outCipher = CipherUtilities.GetCipher(name);
			KeyParameter key = ParameterUtilities.CreateKeyParameter(baseName, kGen.GenerateKey());
			MemoryStream bIn = new MemoryStream(Encoding.ASCII.GetBytes(lCode), false);
			MemoryStream bOut = new MemoryStream();

			// In the Java build, this IV would be implicitly created and then retrieved with getIV()
			ICipherParameters cipherParams = key;
			if (ivLength > 0)
			{
				cipherParams = new ParametersWithIV(cipherParams, new byte[ivLength]);
			}

			inCipher.Init(true, cipherParams);

			// TODO Should we provide GetIV() method on IBufferedCipher?
			//if (inCipher.getIV() != null)
			//{
			//	outCipher.Init(false, new ParametersWithIV(key, inCipher.getIV()));
			//}
			//else
			//{
			//	outCipher.Init(false, key);
			//}
			outCipher.Init(false, cipherParams);

			CipherStream cIn = new CipherStream(bIn, inCipher, null);
			CipherStream cOut = new CipherStream(bOut, null, outCipher);

			int c;

			while ((c = cIn.ReadByte()) >= 0)
			{
				cOut.WriteByte((byte)c);
			}

			cIn.Close();

			cOut.Flush();
			cOut.Close();

			byte[] bs = bOut.ToArray();
			string res = Encoding.ASCII.GetString(bs, 0, bs.Length);

			if (!res.Equals(lCode))
			{
				Fail("Failed - decrypted data doesn't match.");
			}
		}
Exemplo n.º 29
0
		private void doTestException(
			string	name,
			int		ivLength)
		{
			try
			{
				byte[] key128 = {
					(byte)128, (byte)131, (byte)133, (byte)134,
					(byte)137, (byte)138, (byte)140, (byte)143,
					(byte)128, (byte)131, (byte)133, (byte)134,
					(byte)137, (byte)138, (byte)140, (byte)143
				};

				byte[] key256 = {
					(byte)128, (byte)131, (byte)133, (byte)134,
					(byte)137, (byte)138, (byte)140, (byte)143,
					(byte)128, (byte)131, (byte)133, (byte)134,
					(byte)137, (byte)138, (byte)140, (byte)143,
					(byte)128, (byte)131, (byte)133, (byte)134,
					(byte)137, (byte)138, (byte)140, (byte)143,
					(byte)128, (byte)131, (byte)133, (byte)134,
					(byte)137, (byte)138, (byte)140, (byte)143 };

				byte[] keyBytes;
				if (name.Equals("HC256"))
				{
					keyBytes = key256;
				}
				else
				{
					keyBytes = key128;
				}

				KeyParameter cipherKey = ParameterUtilities.CreateKeyParameter(name, keyBytes);

				ICipherParameters cipherParams = cipherKey;
				if (ivLength > 0)
				{
					cipherParams = new ParametersWithIV(cipherParams, new byte[ivLength]);
				}

				IBufferedCipher ecipher = CipherUtilities.GetCipher(name);
				ecipher.Init(true, cipherParams);

				byte[] cipherText = new byte[0];
				try
				{
					// According specification Method engineUpdate(byte[] input,
					// int inputOffset, int inputLen, byte[] output, int
					// outputOffset)
					// throws ShortBufferException - if the given output buffer is
					// too
					// small to hold the result
					ecipher.ProcessBytes(new byte[20], 0, 20, cipherText, 0);

//					Fail("failed exception test - no ShortBufferException thrown");
					Fail("failed exception test - no DataLengthException thrown");
				}
//				catch (ShortBufferException e)
				catch (DataLengthException)
				{
					// ignore
				}

				// NB: The lightweight engine doesn't take public/private keys
//				try
//				{
//					IBufferedCipher c = CipherUtilities.GetCipher(name);
//
//					//                Key k = new PublicKey()
//					//                {
//					//
//					//                    public string getAlgorithm()
//					//                    {
//					//                        return "STUB";
//					//                    }
//					//
//					//                    public string getFormat()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                    public byte[] getEncoded()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                };
//					AsymmetricKeyParameter k = new AsymmetricKeyParameter(false);
//					c.Init(true, k);
//
//					Fail("failed exception test - no InvalidKeyException thrown for public key");
//				}
//				catch (InvalidKeyException)
//				{
//					// okay
//				}
//
//				try
//				{
//					IBufferedCipher c = CipherUtilities.GetCipher(name);
//
//					//				Key k = new PrivateKey()
//					//                {
//					//
//					//                    public string getAlgorithm()
//					//                    {
//					//                        return "STUB";
//					//                    }
//					//
//					//                    public string getFormat()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                    public byte[] getEncoded()
//					//                    {
//					//                        return null;
//					//                    }
//					//
//					//                };
//
//					AsymmetricKeyParameter k = new AsymmetricKeyParameter(true);
//					c.Init(false, k);
//
//					Fail("failed exception test - no InvalidKeyException thrown for private key");
//				}
//				catch (InvalidKeyException)
//				{
//					// okay
//				}
			}
			catch (Exception e)
			{
				Fail("unexpected exception.", e);
			}
		}
        /**
        * Method wrap
        *
        * @param in
        * @param inOff
        * @param inLen
        * @return
        */
        public byte[] Wrap(
			byte[]	input,
			int		inOff,
			int		length)
        {
            if (!forWrapping)
            {
                throw new InvalidOperationException("Not initialized for wrapping");
            }

            byte[] keyToBeWrapped = new byte[length];
            Array.Copy(input, inOff, keyToBeWrapped, 0, length);

            // Compute the CMS Key Checksum, (section 5.6.1), call this CKS.
            byte[] CKS = CalculateCmsKeyChecksum(keyToBeWrapped);

            // Let WKCKS = WK || CKS where || is concatenation.
            byte[] WKCKS = new byte[keyToBeWrapped.Length + CKS.Length];
            Array.Copy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.Length);
            Array.Copy(CKS, 0, WKCKS, keyToBeWrapped.Length, CKS.Length);

            // Encrypt WKCKS in CBC mode using KEK as the key and IV as the
            // initialization vector. Call the results TEMP1.

            int blockSize = engine.GetBlockSize();

            if (WKCKS.Length % blockSize != 0)
                throw new InvalidOperationException("Not multiple of block length");

            engine.Init(true, paramPlusIV);

            byte [] TEMP1 = new byte[WKCKS.Length];

            for (int currentBytePos = 0; currentBytePos != WKCKS.Length; currentBytePos += blockSize)
            {
                engine.ProcessBlock(WKCKS, currentBytePos, TEMP1, currentBytePos);
            }

            // Let TEMP2 = IV || TEMP1.
            byte[] TEMP2 = new byte[this.iv.Length + TEMP1.Length];
            Array.Copy(this.iv, 0, TEMP2, 0, this.iv.Length);
            Array.Copy(TEMP1, 0, TEMP2, this.iv.Length, TEMP1.Length);

            // Reverse the order of the octets in TEMP2 and call the result TEMP3.
            byte[] TEMP3 = reverse(TEMP2);

            // Encrypt TEMP3 in CBC mode using the KEK and an initialization vector
            // of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired
            // result. It is 40 octets long if a 168 bit key is being wrapped.
            ParametersWithIV param2 = new ParametersWithIV(this.param, IV2);
            this.engine.Init(true, param2);

            for (int currentBytePos = 0; currentBytePos != TEMP3.Length; currentBytePos += blockSize)
            {
                engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos);
            }

            return TEMP3;
        }