/// <summary> /// DtmIdentity partial constructor; used for the <c>Init</c> exchange and contains an empty Secret Id /// </summary> /// /// <param name="Identity">The active Identity field; used to first identify a host during the <c>Init</c> stage of a key exchange</param> /// <param name="PkeId">The Asymmetric parameters Id; can be the Asymmetric cipher parameters OId, or a serialized Asymmetric Parameters class</param> /// <param name="Session">The Symmetric sessions cipher parameters; contains a complete description of the Symmetric cipher</param> /// <param name="OptionFlag">This flag can be used as a time stamp indicating the expiry time of the corresponding session key</param> public DtmIdentity(byte[] Identity, byte[] PkeId, DtmSession Session, long OptionFlag) { this.Identity = new byte[Identity.Length]; Array.Copy(Identity, this.Identity, Identity.Length); this.PkeId = new byte[PkeId.Length]; Array.Copy(PkeId, this.PkeId, PkeId.Length); this.Session = Session; this.OptionFlag = OptionFlag; }
/// <summary> /// Initialize the symmetric cipher /// </summary> private ICipherMode SymmetricInit(DtmSession Session, KeyParams Key) { ICipherMode cipher = GetSymmetricCipher(Session); cipher.Initialize(true, Key); return cipher; }
/// <summary> /// Processes the clients public identity and clients Auth-Stage PKE parameter set Id; <see cref="IAsymmetricParameters"/>. /// <para>Process the clients Auth-Stage public identity structure; <see cref="DtmIdentity"/></para> /// </summary> /// /// <param name="PacketStream">A Stream containing the raw packet data</param> /// /// <remarks>Fires the <see cref="IdentityReceived"/> event; returning the <see cref="DtmIdentityEventArgs"/> object containing the clients public id structure. /// <para>The session can be aborted by setting the DtmIdentityEventArgs Cancel flag to true.</para> /// </remarks> private void ProcessInit(MemoryStream PacketStream) { // seek past header PacketStream.Seek(DtmPacket.GetHeaderSize(), SeekOrigin.Begin); // get the clients id structure _cltIdentity = new DtmIdentity(PacketStream); // get client asymmetric params _cltAsmParams = GetAsymmetricParams(_cltIdentity.PkeId); // store the auth session _cltAuthSession = _cltIdentity.Session; // pass it to the client again, so it can be refused on basis of params long resp = 0; if (IdentityReceived != null) { DtmIdentityEventArgs args = new DtmIdentityEventArgs(DtmExchangeFlags.Init, 0, _cltIdentity); IdentityReceived(this, args); resp = args.Flag; if (args.Cancel) { // back out of session TearDown(); } } }
/// <summary> /// Get the symmetric cipher instance /// </summary> /// /// <param name="Session">The session parameters</param> /// /// <returns>The initialized cipher instance</returns> private ICipherMode GetSymmetricCipher(DtmSession Session) { switch ((BlockCiphers)Session.EngineType) { case BlockCiphers.RDX: return new CTR(new RDX()); case BlockCiphers.RHX: return new CTR(new RHX((int)Session.RoundCount, (int)Session.IvSize, (Digests)Session.KdfEngine)); case BlockCiphers.RSM: return new CTR(new RSM((int)Session.RoundCount, (int)Session.IvSize, (Digests)Session.KdfEngine)); case BlockCiphers.SHX: return new CTR(new SHX((int)Session.RoundCount, (Digests)Session.KdfEngine)); case BlockCiphers.SPX: return new CTR(new SPX((int)Session.RoundCount)); case BlockCiphers.TFX: return new CTR(new TFX((int)Session.RoundCount)); case BlockCiphers.THX: return new CTR(new THX((int)Session.RoundCount, (Digests)Session.KdfEngine)); case BlockCiphers.TSM: return new CTR(new TSM((int)Session.RoundCount, (Digests)Session.KdfEngine)); default: throw new CryptoProcessingException("DtmKex:GetSymmetricCipher", "The symmetric cipher type is unknown!", new ArgumentException()); } }
/// <summary> /// Generate a symmetric key /// </summary> private KeyParams GenerateSymmetricKey(DtmSession Session) { return new KeyParams(_rndGenerator.GetBytes(Session.KeySize), _rndGenerator.GetBytes(Session.IvSize)); }
/// <summary> /// Constructs a DtmIdentity from a stream /// </summary> /// /// <param name="ParametersStream">Stream containing a serialized DtmParameters</param> /// /// <returns>A populated DtmParameters</returns> public DtmParameters(Stream ParametersStream) { BinaryReader reader = new BinaryReader(ParametersStream); int len; byte[] data; len = reader.ReadInt32(); OId = reader.ReadBytes(len); len = reader.ReadInt32(); AuthPkeId = reader.ReadBytes(len); len = reader.ReadInt32(); PrimaryPkeId = reader.ReadBytes(len); len = reader.ReadInt32(); data = reader.ReadBytes(len); AuthSession = new DtmSession(data); len = reader.ReadInt32(); data = reader.ReadBytes(len); PrimarySession = new DtmSession(data); RandomEngine = (Prngs)reader.ReadByte(); MaxAsmKeyAppend = reader.ReadInt32(); MaxAsmKeyPrePend = reader.ReadInt32(); MaxAsmParamsAppend = reader.ReadInt32(); MaxAsmParamsPrePend = reader.ReadInt32(); MaxSymKeyAppend = reader.ReadInt32(); MaxSymKeyPrePend = reader.ReadInt32(); MaxMessageAppend = reader.ReadInt32(); MaxMessagePrePend = reader.ReadInt32(); MaxAsmKeyDelayMS = reader.ReadInt32(); MaxSymKeyDelayMS = reader.ReadInt32(); MaxMessageDelayMS = reader.ReadInt32(); }
/// <summary> /// The DtmParameters primary constructor /// </summary> /// /// <param name="OId">The DtmParameters Identifier field; must be 16 bytes in length</param> /// <param name="AuthPkeId">The <c>Auth-Phase</c> Asymmetric parameters OId; can be the Asymmetric cipher parameters OId, or a serialized Asymmetric Parameters class</param> /// <param name="PrimaryPkeId">The <c>Primary-Phase</c> Asymmetric parameters OId; can be the Asymmetric cipher parameters OId, or a serialized Asymmetric Parameters class</param> /// <param name="AuthSession">The <c>Auth-Phase</c> Symmetric sessions cipher parameters; contains a complete description of the Symmetric cipher</param> /// <param name="PrimarySession">The <c>Primary-Phase</c> Symmetric sessions cipher parameters; contains a complete description of the Symmetric cipher</param> /// <param name="RandomEngine">(Optional) The Prng used to pad messages, defaults to CTRPrng</param> /// <param name="MaxAsmKeyAppend">(Optional) The maximum number of pseudo-random bytes to append to the <c>Primary-Phase</c> Asymmetric Public key before encryption</param> /// <param name="MaxAsmKeyPrePend">(Optional) The maximum number of pseudo-random bytes to prepend to the <c>Primary-Phase</c> Asymmetric Public key before encryption</param> /// <param name="MaxAsmParamsAppend">(Optional) The maximum number of pseudo-random bytes to append to the <c>Primary-Phase</c> Client Identity before encryption</param> /// <param name="MaxAsmParamsPrePend">(Optional) The maximum number of pseudo-random bytes to prepend to the <c>Primary-Phase</c> Asymmetric Client Identity before encryption</param> /// <param name="MaxSymKeyAppend">(Optional) The maximum number of pseudo-random bytes to append to the <c>Primary-Phase</c> Symmetric key before encryption</param> /// <param name="MaxSymKeyPrePend">(Optional) The maximum number of pseudo-random bytes to prepend to the <c>Primary-Phase</c> Symmetric key before encryption</param> /// <param name="MaxMessageAppend">(Optional) The maximum number of pseudo-random bytes to append to a <c>Post-Exchange</c> message before encryption</param> /// <param name="MaxMessagePrePend">(Optional) The maximum number of pseudo-random bytes to prepend to a <c>Post-Exchange</c> message before encryption</param> /// <param name="MaxAsmKeyDelayMS">(Optional) The maximum delay time before sending the <c>Primary-Phase</c> Asymmetric key; the minimum time is 1 half max, a value of <c>0</c> has no delay</param> /// <param name="MaxSymKeyDelayMS">(Optional) The maximum delay time before sending the <c>Primary-Phase</c> Symmetric key; the minimum time is 1 half max, a value of <c>0</c> has no delay</param> /// <param name="MaxMessageDelayMS">(Optional) The maximum delay time before sending message traffic; the minimum time is <c>0</c>, a value of <c>0</c> has no delay</param> public DtmParameters(byte[] OId, byte[] AuthPkeId, byte[] PrimaryPkeId, DtmSession AuthSession, DtmSession PrimarySession, Prngs RandomEngine = Prngs.CTRPrng, int MaxAsmKeyAppend = 0, int MaxAsmKeyPrePend = 0, int MaxAsmParamsAppend = 0, int MaxAsmParamsPrePend = 0, int MaxSymKeyAppend = 0, int MaxSymKeyPrePend = 0, int MaxMessageAppend = 0, int MaxMessagePrePend = 0, int MaxAsmKeyDelayMS = 0, int MaxSymKeyDelayMS = 0, int MaxMessageDelayMS = 0) { this.OId = OId; this.AuthPkeId = AuthPkeId; this.PrimaryPkeId = PrimaryPkeId; this.AuthSession = AuthSession; this.PrimarySession = PrimarySession; this.RandomEngine = RandomEngine; this.MaxAsmKeyAppend = MaxAsmKeyAppend; this.MaxAsmKeyPrePend = MaxAsmKeyPrePend; this.MaxAsmParamsAppend = MaxAsmParamsAppend; this.MaxAsmParamsPrePend = MaxAsmParamsPrePend; this.MaxSymKeyAppend = MaxSymKeyAppend; this.MaxSymKeyPrePend = MaxSymKeyPrePend; this.MaxMessageAppend = MaxMessageAppend; this.MaxMessagePrePend = MaxMessagePrePend; this.MaxAsmKeyDelayMS = MaxAsmKeyDelayMS; this.MaxSymKeyDelayMS = MaxSymKeyDelayMS; this.MaxMessageDelayMS = MaxMessageDelayMS; }
/// <summary> /// Get this is a valid header file /// </summary> /// /// <param name="Key">The stream containing a key header</param> /// /// <returns>Valid</returns> public static bool IsValid(DtmSession Key) { // not guaranteed, but should be ok return (Key.EngineType < Enum.GetValues(typeof(SymmetricEngines)).Length); }
/// <summary> /// Get the key data from the key stream /// </summary> /// /// <param name="KeyStream">The stream containing a session key</param> /// /// <returns>KeyParams structure</returns> public static KeyParams GetKey(Stream KeyStream) { DtmSession session = new DtmSession(KeyStream); byte[] key = new byte[session.KeySize]; byte[] iv = new byte[session.IvSize]; KeyStream.Seek(HDR_SIZE, SeekOrigin.Begin); KeyStream.Read(key, 0, key.Length); KeyStream.Read(iv, 0, iv.Length); return new KeyParams(key, iv); }
/// <summary> /// Extracts a DtmIdentity from a Stream /// </summary> /// /// <param name="IdentityStream">The Stream containing the DtmIdentity structure</param> public DtmIdentity(Stream IdentityStream) { BinaryReader reader = new BinaryReader(IdentityStream); int len; byte[] data; len = reader.ReadInt32(); Identity = reader.ReadBytes(len); len = reader.ReadInt32(); PkeId = reader.ReadBytes(len); len = reader.ReadInt32(); data = reader.ReadBytes(len); Session = new DtmSession(data); OptionFlag = reader.ReadInt64(); }