/// <summary> /// Initialises a new instance of the <see cref="MacStream" /> class. /// </summary> /// <param name="binding">Stream to write to or read from.</param> /// <param name="writing">If set to <c>true</c>, writing; otherwise, reading.</param> /// <param name="function">MAC function to instantiate.</param> /// <param name="key">Cryptographic key to use in the MAC operation.</param> /// <param name="salt">Cryptographic salt to use in the MAC operation, if any.</param> /// <param name="output">Byte array where the finished MAC will be output to. Does not need to be initialised.</param> /// <param name="config"></param> /// <param name="nonce"></param> /// <param name="closeOnDispose">If set to <c>true</c>, bound stream will be closed on dispose/close.</param> public MacStream(Stream binding, bool writing, MacFunction function, out byte[] output, byte[] key, byte[] salt = null, byte[] config = null, byte[] nonce = null, bool closeOnDispose = true) : this(binding, writing, function, key, salt, config, nonce, closeOnDispose) { output = _output; }
/// <summary> /// Creates a new <see cref="AuthenticationConfiguration" />. /// HMAC, CMAC/OMAC1, or Poly1305 selection will use default basis primitives (BLAKE2B256, AES, and AES, respectively). /// </summary> /// <remarks> /// The MAC configuration generated may be used with a MacStream, /// e.g. package payload item authentication. /// </remarks> /// <param name="macFunctionEnum">MAC function.</param> /// <param name="outputSize">Size of the output from the function in bytes.</param> /// <returns>The authentication configuration as a <see cref="AuthenticationConfiguration" />.</returns> public static AuthenticationConfiguration CreateAuthenticationConfiguration(MacFunction macFunctionEnum, out int outputSize) { if (Athena.Cryptography.MacFunctions[macFunctionEnum].OutputSize.HasValue == false) { // Either HMAC or CMAC/OMAC1 is being used. switch (macFunctionEnum) { case MacFunction.Hmac: return(CreateAuthenticationConfigurationHmac(DefaultHmacFunction, out outputSize)); case MacFunction.Cmac: return(CreateAuthenticationConfigurationCmac(DefaultCmacCipher, out outputSize)); default: throw new NotSupportedException(); } } if (macFunctionEnum == MacFunction.Poly1305) { outputSize = 16; return(CreateAuthenticationConfigurationPoly1305(DefaultPoly1305BlockCipher)); } outputSize = Athena.Cryptography.MacFunctions[macFunctionEnum].OutputSize.Value / 8; return(CreateAuthConf(macFunctionEnum.ToString(), outputSize * 8, outputSize * 8, null, null)); }
/// <summary> /// Creates a configuration for key confirmation using a MAC construction. /// </summary> /// <param name="macFunctionEnum">Hash function to use as basis of HMAC construction.</param> /// <returns>A key confirmation configuration as a <see cref="AuthenticationConfiguration"/>.</returns> public static AuthenticationConfiguration GenerateConfiguration(MacFunction macFunctionEnum) { int outputSize; var config = AuthenticationConfigurationFactory.CreateAuthenticationConfiguration(macFunctionEnum, out outputSize); return(config); }
/// <summary> /// Initialises a new instance of the <see cref="MacStream" /> class. /// </summary> /// <param name="binding">Stream to write to or read from.</param> /// <param name="writing">If set to <c>true</c>, writing; otherwise, reading.</param> /// <param name="function">MAC function to instantiate.</param> /// <param name="key">Cryptographic key to use in the MAC operation.</param> /// <param name="salt">Cryptographic salt to use in the MAC operation, if any.</param> /// <param name="nonce"></param> /// <param name="closeOnDispose">If set to <c>true</c>, bound stream will be closed on dispose/close.</param> /// <param name="config"></param> public MacStream(Stream binding, bool writing, MacFunction function, byte[] key, byte[] salt = null, byte[] config = null, byte[] nonce = null, bool closeOnDispose = true) { Contract.Requires <ArgumentNullException>(binding != null); Contract.Requires <ArgumentNullException>(key != null); _streamBinding = binding; Writing = writing; _closeOnDispose = closeOnDispose; _mac = AuthenticatorFactory.CreateMacPrimitive(function, key, salt, config, nonce); _output = new byte[_mac.OutputSize]; _buffer = new byte[BufferSize]; }
protected void RunMacTest(MacFunction function, byte[] config = null, byte[] nonce = null, byte[] overrideKey = null, byte[] overrideSalt = null) { byte[] outputMac; var sw = new Stopwatch(); using (var output = new MemoryStream((int)LargeBinaryFile.Length)) { using (var macS = new MacStream(output, true, function, out outputMac, overrideKey ?? Key, overrideSalt ?? Salt, config, nonce, false)) { sw.Start(); LargeBinaryFile.CopyTo(macS); sw.Stop(); } } Debug.Print(outputMac.ToHexString()); Assert.Pass("{0:N0} ms ({1:N2} MB/s)", sw.ElapsedMilliseconds, ((double)LargeBinaryFile.Length / 1048576) / sw.Elapsed.TotalSeconds); }
/// <summary> /// Instantiates and initialises a Message Authentication Code (MAC) primitive. /// If salt is used, it is applied as: salt||message, where || is concatenation. /// </summary> /// <param name="macEnum">MAC function to instantiate.</param> /// <param name="key">Cryptographic key to use in the MAC operation.</param> /// <param name="salt">Cryptographic salt to use in the MAC operation, if any.</param> /// <param name="config"> /// Configuration for the function, where applicable. For example, /// CMAC and HMAC use cipher and hash function names, repectively, encoded as UTF-8. /// </param> /// <param name="nonce">Nonce for the function, where applicable (rare, very specific) - null if N/A.</param> /// <returns> /// An MAC object deriving from <see cref="IMac" />. /// </returns> public static IMac CreateMacPrimitive(MacFunction macEnum, byte[] key, byte[] salt = null, byte[] config = null, byte[] nonce = null) { IMac macObj; switch (macEnum) { case MacFunction.Hmac: if (config == null) { throw new ArgumentException("No hash function specified (encoded as UTF-8 bytes).", "config"); } macObj = CreateHmacPrimitive(Encoding.UTF8.GetString(config).ToEnum <HashFunction>(), key, salt); break; case MacFunction.Cmac: if (config == null) { throw new ArgumentException("No block cipher specified (encoded as UTF-8 bytes).", "config"); } macObj = CreateCmacPrimitive(Encoding.UTF8.GetString(config).ToEnum <BlockCipher>(), key, salt); break; case MacFunction.Poly1305: if (config != null && nonce == null) { throw new ArgumentException("No nonce/IV supplied for the block cipher.", "nonce"); } macObj = CreatePoly1305Primitive(Encoding.UTF8.GetString(config).ToEnum <BlockCipher>(), key, nonce, salt); break; default: macObj = MacInstantiators[macEnum](); macObj.Init(key); if (salt.IsNullOrZeroLength() == false) { macObj.BlockUpdate(salt, 0, salt.Length); } break; } return(macObj); }
/// <summary> /// Instantiate a new MAC function engine. /// </summary> /// <param name="macIdentity">Identity of the MAC function.</param> protected MacEngine(MacFunction macIdentity) { MacIdentity = macIdentity; Key = null; }