/// <summary> /// Generate a new digest and compute data hash. /// </summary> /// <param name="mode">MAC cipher mode.</param> /// <param name="padding">MAC padding mode.</param> /// <param name="parameters">Parameters.</param> /// <param name="data">Data buffer bytes.</param> /// <param name="offset">The starting offset to read.</param> /// <param name="length">The length to read.</param> /// <returns></returns> public byte[] ComputeHash(MACCipherMode mode, MACPaddingMode padding, ICipherParameters parameters, byte[] data, int offset, int length) { IMac digest = GenerateDigest(mode, padding, parameters); digest.BlockUpdate(data, offset, length); byte[] hash = new byte[this.HashSize]; digest.DoFinal(hash, 0); return(hash); }
/// <summary> /// Try get legal iv sizes. /// </summary> /// <param name="mode">MAC cipher mode.</param> /// <param name="ivSizes">Legal iv size bits.</param> /// <returns></returns> public bool TryGetIVSizes(MACCipherMode mode, out KeySizes[] ivSizes) { switch (mode) { case MACCipherMode.CBC: ivSizes = new KeySizes[] { new KeySizes(this.BlockSize, this.BlockSize, 0) }; return(true); case MACCipherMode.CFB: ivSizes = new KeySizes[] { new KeySizes(8, this.BlockSize, 8) }; return(true); default: break; } ivSizes = null; return(false); }
private static void Test4() { Array modes = Enum.GetValues(typeof(MACCipherMode)); Array paddings = Enum.GetValues(typeof(MACPaddingMode)); byte[] test = Utilities.ScoopBytes(123); // Type type = typeof(MACHelper); PropertyInfo[] properties = type.GetProperties(BindingFlags.Static | BindingFlags.Public); foreach (PropertyInfo property in properties) { if (property.GetValue(type, null) is IMAC algorithm) { foreach (int modeValue in modes) { MACCipherMode mode = (MACCipherMode)modeValue; int keySize = GetQualitySize(algorithm.KeySizes); byte[] key = Utilities.ScoopBytes(keySize / 8); algorithm.TryGetIVSizes(mode, out KeySizes[] ivSizes); int ivSize = GetQualitySize(ivSizes); byte[] iv = Utilities.ScoopBytes(ivSize / 8); ICipherParameters parameters = algorithm.GenerateParameters(key, iv); foreach (int paddingValue in paddings) { _total++; MACPaddingMode padding = (MACPaddingMode)paddingValue; string mechanism = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}", algorithm.Mechanism, mode.ToString(), padding.ToString()); IMac digest = algorithm.GenerateDigest(mode, padding, parameters); try { XTest(mechanism, digest, test); _execute++; } catch (Exception) { Console.WriteLine("{0}-------- Ignored --------", mechanism.PadRight(32)); } } } } } }
/// <summary> /// Generate digest. The digest can be reused. /// </summary> /// <param name="mode">MAC cipher mode.</param> /// <param name="padding">MAC padding mode.</param> /// <param name="parameters">Parameters.</param> /// <returns></returns> /// <exception cref="Exception"/> public IMac GenerateDigest(MACCipherMode mode, MACPaddingMode padding, ICipherParameters parameters) { IBlockCipherPadding pad; switch (padding) { case MACPaddingMode.NoPadding: pad = null; break; case MACPaddingMode.PKCS7: pad = Common.PKCS7Padding; break; case MACPaddingMode.Zeros: pad = Common.ZEROBYTEPadding; break; case MACPaddingMode.X923: pad = Common.X923Padding; break; case MACPaddingMode.ISO7816_4: pad = Common.ISO7816d4Padding; break; case MACPaddingMode.TBC: pad = Common.TBCPadding; break; default: throw new CryptographicException("Unsupported padding mode."); } IMac digest; switch (mode) { case MACCipherMode.CBC: digest = pad is null ? new CbcBlockCipherMac(this.BlockAlgorithm.GenerateEngine(), this.HashSize) : new CbcBlockCipherMac(this.BlockAlgorithm.GenerateEngine(), this.HashSize, pad); break; case MACCipherMode.CFB: int cfbs = ((ParametersWithIV)parameters).GetIV().Length * 8; digest = pad is null ? new CfbBlockCipherMac(this.BlockAlgorithm.GenerateEngine(), cfbs, this.HashSize) : new CfbBlockCipherMac(this.BlockAlgorithm.GenerateEngine(), cfbs, this.HashSize, pad); break; default: throw new CryptographicException("Unsupported cipher mode."); } digest.Init(parameters); return(digest); }
/// <summary> /// Generate a new digest and compute data hash. /// </summary> /// <param name="mode">MAC cipher mode.</param> /// <param name="padding">MAC padding mode.</param> /// <param name="parameters">Parameters.</param> /// <param name="data">Data bytes.</param> /// <returns></returns> public byte[] ComputeHash(MACCipherMode mode, MACPaddingMode padding, ICipherParameters parameters, byte[] data) { return(ComputeHash(mode, padding, parameters, data, 0, data.Length)); }