internal static IFreeformEntity_Msg InitKeyExchangeEndG2H_SIM(this FreeformSecurityTableCollection secTables,
                                                                      IFreeformEntity_Msg request)
        {
            // store the partial key of the host
            FFTgt_B2B_Security_KeyExchange_PartialKey tgt = request.EntityPrimaryTarget as FFTgt_B2B_Security_KeyExchange_PartialKey;
            SECURITY_KEY_INDEX keyIndex = FreeformEncryptionHelper.GetSecurityKeyIndex(request);

            byte[] gmuPartialKey = secTables.CreatePartialKeyGmu(keyIndex);
            secTables.StoreOtherPartialKeyGmu(keyIndex, tgt.PartialKey);
            secTables.CreateCommonKey(keyIndex);

            // send the partial key of the gmu
            IFreeformEntity_Msg response = request.CopyTo(FF_FlowDirection.G2H, new FFCreateEntityRequest_G2H_ResponseRequired()
            {
                MessageType       = FF_AppId_G2H_MessageTypes.FreeForm,
                Command           = FF_AppId_G2H_Commands.ResponseRequest,
                SkipTransactionId = true,
            });
            FFTgt_B2B_Security tgt2 = new FFTgt_B2B_Security()
            {
                SecurityData = new FFTgt_B2B_Security_KeyExchange_End()
                {
                    PartialKey = gmuPartialKey,
                }
            };

            response.AddTarget(tgt2);
            return(response);
        }
        internal static IFreeformEntity_Msg InitKeyExchangePartialKeyH2G_GMU(this FreeformSecurityTableCollection secTables,
                                                                             IFreeformEntity_Msg request)
        {
            SECURITY_KEY_INDEX keyIndex = FreeformEncryptionHelper.GetSecurityKeyIndex(request);

            byte[] hostPartialKey       = secTables.CreatePartialKeyHost(keyIndex);
            IFreeformEntity_Msg message = request.CopyTo(FF_FlowDirection.H2G, new FFCreateEntityRequest_H2G_ResponseRequired()
            {
                PollCode = FF_AppId_H2G_PollCodes.FreeformResponse,
            });

            InitSecurityData(message,
                             new FFTgt_B2B_Security_KeyExchange_PartialKey()
            {
                PartialKey = hostPartialKey,
            });
            return(message);
        }
        internal static IFreeformEntity_Msg InitKeyExchangeStatusH2G_GMU(this FreeformSecurityTableCollection secTables,
                                                                         IFreeformEntity_Msg request)
        {
            // store the partial key of the gmu
            FFTgt_B2B_Security_KeyExchange_End tgt = request.EntityPrimaryTarget as FFTgt_B2B_Security_KeyExchange_End;
            SECURITY_KEY_INDEX keyIndex            = FreeformEncryptionHelper.GetSecurityKeyIndex(request);

            secTables.StoreOtherPartialKeyHost(keyIndex, tgt.PartialKey);
            secTables.CreateCommonKey(keyIndex);

            IFreeformEntity_Msg message = request.CopyTo(FF_FlowDirection.H2G, new FFCreateEntityRequest_H2G_ResponseRequired()
            {
                PollCode = FF_AppId_H2G_PollCodes.FreeformNoResponse,
            });

            InitSecurityData(message,
                             new FFTgt_B2B_Security_KeyExchange_Status()
            {
                Status = (request.EntityPrimaryTarget is FFTgt_B2B_Security_PartialKey ?
                          FF_AppId_ResponseStatus_Types.Success :
                          FF_AppId_ResponseStatus_Types.Fail),
            });
            return(message);
        }