private int calculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock) { IMac cMac = new CbcBlockCipherMac(cipher, parameters.MacSize); byte[] nonce = parameters.GetNonce(); byte[] associatedText = parameters.GetAssociatedText(); cMac.Init(parameters.Key); // // build b0 // byte[] b0 = new byte[16]; if (associatedText != null && associatedText.Length != 0) { b0[0] |= 0x40; } b0[0] |= (byte)((((cMac.GetMacSize() - 2) / 2) & 0x7) << 3); b0[0] |= (byte)(((15 - nonce.Length) - 1) & 0x7); Array.Copy(nonce, 0, b0, 1, nonce.Length); int q = dataLen; int count = 1; while (q > 0) { b0[b0.Length - count] = (byte)(q & 0xff); q >>= 8; count++; } cMac.BlockUpdate(b0, 0, b0.Length); // // process associated text // if (associatedText != null) { int extra; if (associatedText.Length < ((1 << 16) - (1 << 8))) { cMac.Update((byte)(associatedText.Length >> 8)); cMac.Update((byte)associatedText.Length); extra = 2; } else // can't go any higher than 2^32 { cMac.Update((byte)0xff); cMac.Update((byte)0xfe); cMac.Update((byte)(associatedText.Length >> 24)); cMac.Update((byte)(associatedText.Length >> 16)); cMac.Update((byte)(associatedText.Length >> 8)); cMac.Update((byte)associatedText.Length); extra = 6; } cMac.BlockUpdate(associatedText, 0, associatedText.Length); extra = (extra + associatedText.Length) % 16; if (extra != 0) { for (int i = 0; i != 16 - extra; i++) { cMac.Update((byte)0x00); } } } // // add the text // cMac.BlockUpdate(data, dataOff, dataLen); return cMac.DoFinal(macBlock, 0); }
private int calculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock) { IMac cMac = new CbcBlockCipherMac(cipher, macSize * 8); cMac.Init(keyParam); // // build b0 // byte[] b0 = new byte[16]; if (HasAssociatedText()) { b0[0] |= 0x40; } b0[0] |= (byte)((((cMac.GetMacSize() - 2) / 2) & 0x7) << 3); b0[0] |= (byte)(((15 - nonce.Length) - 1) & 0x7); Array.Copy(nonce, 0, b0, 1, nonce.Length); int q = dataLen; int count = 1; while (q > 0) { b0[b0.Length - count] = (byte)(q & 0xff); q >>= 8; count++; } cMac.BlockUpdate(b0, 0, b0.Length); // // process associated text // if (HasAssociatedText()) { int extra; int textLength = GetAssociatedTextLength(); if (textLength < ((1 << 16) - (1 << 8))) { cMac.Update((byte)(textLength >> 8)); cMac.Update((byte)textLength); extra = 2; } else // can't go any higher than 2^32 { cMac.Update((byte)0xff); cMac.Update((byte)0xfe); cMac.Update((byte)(textLength >> 24)); cMac.Update((byte)(textLength >> 16)); cMac.Update((byte)(textLength >> 8)); cMac.Update((byte)textLength); extra = 6; } if (initialAssociatedText != null) { cMac.BlockUpdate(initialAssociatedText, 0, initialAssociatedText.Length); } if (associatedText.Position > 0) { cMac.BlockUpdate(associatedText.ToArray() /*GetBuffer()*/, 0, (int)associatedText.Position); } extra = (extra + textLength) % 16; if (extra != 0) { for (int i = extra; i < 16; ++i) { cMac.Update((byte)0x00); } } } // // add the text // cMac.BlockUpdate(data, dataOff, dataLen); return cMac.DoFinal(macBlock, 0); }
public virtual ITestResult Perform() { KeyParameter key = new KeyParameter(keyBytes); IBlockCipher cipher = new DesEngine(); IMac mac = new CbcBlockCipherMac(cipher); // // standard DAC - zero IV // mac.Init(key); mac.BlockUpdate(input1, 0, input1.Length); byte[] outBytes = new byte[4]; mac.DoFinal(outBytes, 0); if (!Arrays.AreEqual(outBytes, output1)) { return new SimpleTestResult(false, Name + ": Failed - expected " + Hex.ToHexString(output1) + " got " + Hex.ToHexString(outBytes)); } // // mac with IV. // ParametersWithIV param = new ParametersWithIV(key, ivBytes); mac.Init(param); mac.BlockUpdate(input1, 0, input1.Length); outBytes = new byte[4]; mac.DoFinal(outBytes, 0); if (!Arrays.AreEqual(outBytes, output2)) { return new SimpleTestResult(false, Name + ": Failed - expected " + Hex.ToHexString(output2) + " got " + Hex.ToHexString(outBytes)); } // // CFB mac with IV - 8 bit CFB mode // param = new ParametersWithIV(key, ivBytes); mac = new CfbBlockCipherMac(cipher); mac.Init(param); mac.BlockUpdate(input1, 0, input1.Length); outBytes = new byte[4]; mac.DoFinal(outBytes, 0); if (!Arrays.AreEqual(outBytes, output3)) { return new SimpleTestResult(false, Name + ": Failed - expected " + Hex.ToHexString(output3) + " got " + Hex.ToHexString(outBytes)); } // // word aligned data - zero IV // mac.Init(key); mac.BlockUpdate(input2, 0, input2.Length); outBytes = new byte[4]; mac.DoFinal(outBytes, 0); if (!Arrays.AreEqual(outBytes, output4)) { return new SimpleTestResult(false, Name + ": Failed - expected " + Hex.ToHexString(output4) + " got " + Hex.ToHexString(outBytes)); } // // word aligned data - zero IV - CBC padding // mac = new CbcBlockCipherMac(cipher, new Pkcs7Padding()); mac.Init(key); mac.BlockUpdate(input2, 0, input2.Length); outBytes = new byte[4]; mac.DoFinal(outBytes, 0); if (!Arrays.AreEqual(outBytes, output5)) { return new SimpleTestResult(false, Name + ": Failed - expected " + Hex.ToHexString(output5) + " got " + Hex.ToHexString(outBytes)); } // // non-word aligned data - zero IV - CBC padding // mac.Reset(); mac.BlockUpdate(input1, 0, input1.Length); outBytes = new byte[4]; mac.DoFinal(outBytes, 0); if (!Arrays.AreEqual(outBytes, output6)) { return new SimpleTestResult(false, Name + ": Failed - expected " + Hex.ToHexString(output6) + " got " + Hex.ToHexString(outBytes)); } // // non-word aligned data - zero IV - CBC padding // mac.Init(key); mac.BlockUpdate(input1, 0, input1.Length); outBytes = new byte[4]; mac.DoFinal(outBytes, 0); if (!Arrays.AreEqual(outBytes, output6)) { return new SimpleTestResult(false, Name + ": Failed - expected " + Hex.ToHexString(output6) + " got " + Hex.ToHexString(outBytes)); } return new SimpleTestResult(true, Name + ": Okay"); }