public virtual void Init( bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; byte[] nonce, associatedText; ICipherParameters keyParam; if (parameters is AeadParameters) { AeadParameters param = (AeadParameters)parameters; nonce = param.GetNonce(); associatedText = param.GetAssociatedText(); macSize = param.MacSize / 8; keyParam = param.Key; } else if (parameters is ParametersWithIV) { ParametersWithIV param = (ParametersWithIV)parameters; nonce = param.GetIV(); associatedText = new byte[0]; macSize = mac.GetMacSize() / 2; keyParam = param.Parameters; } else { throw new ArgumentException("invalid parameters passed to EAX"); } byte[] tag = new byte[blockSize]; mac.Init(keyParam); tag[blockSize - 1] = (byte)Tag.H; mac.BlockUpdate(tag, 0, blockSize); mac.BlockUpdate(associatedText, 0, associatedText.Length); mac.DoFinal(associatedTextMac, 0); tag[blockSize - 1] = (byte)Tag.N; mac.BlockUpdate(tag, 0, blockSize); mac.BlockUpdate(nonce, 0, nonce.Length); mac.DoFinal(nonceMac, 0); tag[blockSize - 1] = (byte)Tag.C; mac.BlockUpdate(tag, 0, blockSize); cipher.Init(true, new ParametersWithIV(keyParam, nonceMac)); }
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; }
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); }