From b4d769315bbb6f8f341f2226270a4e3921afde1f Mon Sep 17 00:00:00 2001 From: x27 Date: Tue, 13 Aug 2024 11:18:31 +1000 Subject: [PATCH] Added P25 DES Encryption support --- src/CFT.csproj | 11 ++ src/CftFile.cs | 41 +++++ src/EncryptionMethodEnum.cs | 6 +- src/ImportForm.cs | 18 +++ src/Licensing.cs | 1 + src/LicensingForm.Designer.cs | 59 +++++--- src/LicensingForm.cs | 18 ++- src/MainForm.Designer.cs | 48 ++++-- src/MainForm.cs | 49 +++++- src/P25ADPEncryptionMethodForm.cs | 2 +- src/P25ADPEncryptionRow.cs | 5 +- src/P25DESEncryptionMethodForm.Designer.cs | 165 +++++++++++++++++++++ src/P25DESEncryptionMethodForm.cs | 90 +++++++++++ src/P25DESEncryptionMethodForm.resx | 120 +++++++++++++++ src/P25DESEncryptionRow.cs | 31 ++++ src/Properties/AssemblyInfo.cs | 4 +- 16 files changed, 624 insertions(+), 44 deletions(-) create mode 100644 src/P25DESEncryptionMethodForm.Designer.cs create mode 100644 src/P25DESEncryptionMethodForm.cs create mode 100644 src/P25DESEncryptionMethodForm.resx create mode 100644 src/P25DESEncryptionRow.cs diff --git a/src/CFT.csproj b/src/CFT.csproj index ee77bfa..32afe7c 100644 --- a/src/CFT.csproj +++ b/src/CFT.csproj @@ -81,6 +81,12 @@ DebugLogsFilteringForm.cs + + Form + + + P25DESEncryptionMethodForm.cs + Form @@ -149,6 +155,7 @@ + @@ -214,6 +221,10 @@ AboutForm.cs + + P25DESEncryptionMethodForm.cs + Designer + P25ADPEncryptionMethodForm.cs Designer diff --git a/src/CftFile.cs b/src/CftFile.cs index fc6e88e..f742aca 100644 --- a/src/CftFile.cs +++ b/src/CftFile.cs @@ -24,6 +24,7 @@ private enum EncryptionMethodEnum MotorolaEP = 4, AnytoneEnc = 5, P25ADP = 6, + P25DES = 7 } public static void Export(Project project, Scanner scanner, string filename) @@ -45,6 +46,7 @@ public static void Export(Project project, Scanner scanner, string filename) bw.Write(scanner.Licensing.NxdnScramblerUnlockKey); bw.Write(scanner.Licensing.MotorolaEPUnlockKey); bw.Write(scanner.Licensing.P25ADPUnlockKey); + bw.Write(scanner.Licensing.P25DESUnlockKey); } // KEY MAPPING && MUTE @@ -161,6 +163,22 @@ public static void Export(Project project, Scanner scanner, string filename) bw.Write(Swap(item.ActivateOptions.KeyID)); bw.Write(new byte[25]); // key remaining part } + else if (row is P25DESEncryptionRow) + { + var item = row as P25DESEncryptionRow; + bw.Write(Swap((uint)(item.ActivateOptions.Options | P25SelectedActivateOptionsEnum.Frequency))); + bw.Write(Swap(item.ActivateOptions.NAC)); + bw.Write(Swap(UInt32ToFreq(row.Frequency))); + bw.Write(Swap(item.ActivateOptions.SourceID)); + bw.Write((byte)0); + bw.Write((byte)0); + bw.Write((byte)0); + bw.Write((byte)EncryptionMethodEnum.P25DES); + bw.Write(Swap(item.ActivateOptions.GroupID)); + bw.Write(item.Key); // key 8 byte + bw.Write(Swap(item.ActivateOptions.KeyID)); + bw.Write(new byte[22]); // key remaining part + } else bw.BaseStream.Position += ENC_METHOD_STRUCT_SIZE; // enc method struct size @@ -184,6 +202,7 @@ public static Project Import(string filename) licensing.HyteraBPUnlockKey = new byte[Licensing.UNLOCK_KEY_LEN]; licensing.NxdnScramblerUnlockKey = new byte[Licensing.UNLOCK_KEY_LEN]; licensing.P25ADPUnlockKey = new byte[Licensing.UNLOCK_KEY_LEN]; + licensing.P25DESUnlockKey = new byte[Licensing.UNLOCK_KEY_LEN]; var keyMapping = new KeyMapping(); var rows = new List(); @@ -210,6 +229,8 @@ public static Project Import(string filename) Buffer.BlockCopy(bs, 0, licensing.MotorolaEPUnlockKey, 0, Licensing.UNLOCK_KEY_LEN); bs = br.ReadBytes(Licensing.UNLOCK_KEY_LEN); Buffer.BlockCopy(bs, 0, licensing.P25ADPUnlockKey, 0, Licensing.UNLOCK_KEY_LEN); + bs = br.ReadBytes(Licensing.UNLOCK_KEY_LEN); + Buffer.BlockCopy(bs, 0, licensing.P25DESUnlockKey, 0, Licensing.UNLOCK_KEY_LEN); br.BaseStream.Position = ZIPKEY_OFFSET; muteEncrypted = br.ReadByte() == 1; @@ -358,6 +379,26 @@ public static Project Import(string filename) notesSkipList.Add(false); break; } + case EncryptionMethodEnum.P25DES: + { + var row = new P25DESEncryptionRow(); + row.ActivateOptions = new P25ActivateOptions(); + row.ActivateOptions.Options = (P25SelectedActivateOptionsEnum)Swap(br.ReadUInt32()); + row.ActivateOptions.NAC = Swap(br.ReadUInt16()); + row.Frequency = FreqToUint32(Swap(br.ReadUInt32())); + row.ActivateOptions.SourceID = Swap(br.ReadUInt32()); + br.ReadByte(); // skip + br.ReadByte(); // skip + br.ReadByte(); // skip + br.ReadByte(); // skip enc method + row.ActivateOptions.GroupID = Swap(br.ReadUInt32()); + row.Key = br.ReadBytes(8); + row.ActivateOptions.KeyID = Swap(br.ReadUInt16()); + br.ReadBytes(22); // key remaining part + rows.Add(row); + notesSkipList.Add(false); + break; + } default: br.BaseStream.Position += ENC_METHOD_STRUCT_SIZE; diff --git a/src/EncryptionMethodEnum.cs b/src/EncryptionMethodEnum.cs index 4bb91f0..dab136a 100644 --- a/src/EncryptionMethodEnum.cs +++ b/src/EncryptionMethodEnum.cs @@ -11,6 +11,10 @@ public enum EncryptionMethodEnum [DisplayName("Motorola EP")] MotorolaEP = 4, [DisplayName("Anytone Enc")] - EnytoneEnc = 5 + AnytoneEnc = 5, + [DisplayName("P25 ADP")] + P25ADP = 6, + [DisplayName("P25 DES")] + P25DES = 7, } } diff --git a/src/ImportForm.cs b/src/ImportForm.cs index 1a300bf..a038013 100644 --- a/src/ImportForm.cs +++ b/src/ImportForm.cs @@ -106,6 +106,24 @@ private void btnSelectEncryptionMethodOptions_Click(object sender, EventArgs e) } break; } + case EncryptionMethodEnum.P25ADP: + { + var frm = new P25ADPEncryptionMethodForm(_batchEncryptionRow as P25ADPEncryptionRow, true); + if (frm.ShowDialog() == DialogResult.OK) + { + _batchEncryptionRow = frm.EncryptionRow; + } + break; + } + case EncryptionMethodEnum.P25DES: + { + var frm = new P25DESEncryptionMethodForm(_batchEncryptionRow as P25DESEncryptionRow, true); + if (frm.ShowDialog() == DialogResult.OK) + { + _batchEncryptionRow = frm.EncryptionRow; + } + break; + } } UpdateControls(); } diff --git a/src/Licensing.cs b/src/Licensing.cs index 0c9ba0a..6f7a1cc 100644 --- a/src/Licensing.cs +++ b/src/Licensing.cs @@ -18,5 +18,6 @@ public class Licensing public byte[] NxdnScramblerUnlockKey { get; set; } = new byte[UNLOCK_KEY_LEN]; [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public byte[] P25ADPUnlockKey { get; set; } = new byte[UNLOCK_KEY_LEN]; + public byte[] P25DESUnlockKey { get; set; } = new byte[UNLOCK_KEY_LEN]; } } diff --git a/src/LicensingForm.Designer.cs b/src/LicensingForm.Designer.cs index da2ecfb..e41e272 100644 --- a/src/LicensingForm.Designer.cs +++ b/src/LicensingForm.Designer.cs @@ -40,12 +40,14 @@ private void InitializeComponent() this.label4 = new System.Windows.Forms.Label(); this.tbP25ADPUnlockKey = new System.Windows.Forms.TextBox(); this.label5 = new System.Windows.Forms.Label(); + this.tbP25DESUnlockKey = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); this.SuspendLayout(); // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(25, 22); + this.label1.Location = new System.Drawing.Point(22, 22); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(173, 17); this.label1.TabIndex = 0; @@ -53,16 +55,16 @@ private void InitializeComponent() // // tbMotoBPUnlockKey // - this.tbMotoBPUnlockKey.Location = new System.Drawing.Point(25, 42); + this.tbMotoBPUnlockKey.Location = new System.Drawing.Point(22, 42); this.tbMotoBPUnlockKey.Multiline = true; this.tbMotoBPUnlockKey.Name = "tbMotoBPUnlockKey"; - this.tbMotoBPUnlockKey.Size = new System.Drawing.Size(489, 72); + this.tbMotoBPUnlockKey.Size = new System.Drawing.Size(489, 46); this.tbMotoBPUnlockKey.TabIndex = 1; // // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(25, 212); + this.label2.Location = new System.Drawing.Point(22, 160); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(156, 17); this.label2.TabIndex = 2; @@ -70,17 +72,17 @@ private void InitializeComponent() // // tbHyteraBPUnlockKey // - this.tbHyteraBPUnlockKey.Location = new System.Drawing.Point(25, 232); + this.tbHyteraBPUnlockKey.Location = new System.Drawing.Point(22, 180); this.tbHyteraBPUnlockKey.Multiline = true; this.tbHyteraBPUnlockKey.Name = "tbHyteraBPUnlockKey"; - this.tbHyteraBPUnlockKey.Size = new System.Drawing.Size(489, 72); + this.tbHyteraBPUnlockKey.Size = new System.Drawing.Size(489, 46); this.tbHyteraBPUnlockKey.TabIndex = 3; // // btnCancel // this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Location = new System.Drawing.Point(25, 514); + this.btnCancel.Location = new System.Drawing.Point(25, 453); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(102, 32); this.btnCancel.TabIndex = 4; @@ -90,7 +92,7 @@ private void InitializeComponent() // btnOk // this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnOk.Location = new System.Drawing.Point(412, 514); + this.btnOk.Location = new System.Drawing.Point(412, 453); this.btnOk.Name = "btnOk"; this.btnOk.Size = new System.Drawing.Size(102, 32); this.btnOk.TabIndex = 5; @@ -100,16 +102,16 @@ private void InitializeComponent() // // tbNxdnScramblerUnlockKey // - this.tbNxdnScramblerUnlockKey.Location = new System.Drawing.Point(25, 327); + this.tbNxdnScramblerUnlockKey.Location = new System.Drawing.Point(22, 249); this.tbNxdnScramblerUnlockKey.Multiline = true; this.tbNxdnScramblerUnlockKey.Name = "tbNxdnScramblerUnlockKey"; - this.tbNxdnScramblerUnlockKey.Size = new System.Drawing.Size(489, 72); + this.tbNxdnScramblerUnlockKey.Size = new System.Drawing.Size(489, 46); this.tbNxdnScramblerUnlockKey.TabIndex = 7; // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(25, 307); + this.label3.Location = new System.Drawing.Point(22, 229); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(200, 17); this.label3.TabIndex = 6; @@ -117,16 +119,16 @@ private void InitializeComponent() // // tbMotoEPUnlockKey // - this.tbMotoEPUnlockKey.Location = new System.Drawing.Point(25, 137); + this.tbMotoEPUnlockKey.Location = new System.Drawing.Point(22, 111); this.tbMotoEPUnlockKey.Multiline = true; this.tbMotoEPUnlockKey.Name = "tbMotoEPUnlockKey"; - this.tbMotoEPUnlockKey.Size = new System.Drawing.Size(489, 72); + this.tbMotoEPUnlockKey.Size = new System.Drawing.Size(489, 46); this.tbMotoEPUnlockKey.TabIndex = 9; // // label4 // this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(22, 117); + this.label4.Location = new System.Drawing.Point(22, 91); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(173, 17); this.label4.TabIndex = 8; @@ -134,27 +136,46 @@ private void InitializeComponent() // // tbP25ADPUnlockKey // - this.tbP25ADPUnlockKey.Location = new System.Drawing.Point(25, 423); + this.tbP25ADPUnlockKey.Location = new System.Drawing.Point(22, 318); this.tbP25ADPUnlockKey.Multiline = true; this.tbP25ADPUnlockKey.Name = "tbP25ADPUnlockKey"; - this.tbP25ADPUnlockKey.Size = new System.Drawing.Size(489, 72); + this.tbP25ADPUnlockKey.Size = new System.Drawing.Size(489, 46); this.tbP25ADPUnlockKey.TabIndex = 11; // // label5 // this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(25, 403); + this.label5.Location = new System.Drawing.Point(22, 298); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(149, 17); this.label5.TabIndex = 10; this.label5.Text = "Unlock Key for P25 ADP:"; // + // tbP25DESUnlockKey + // + this.tbP25DESUnlockKey.Location = new System.Drawing.Point(22, 387); + this.tbP25DESUnlockKey.Multiline = true; + this.tbP25DESUnlockKey.Name = "tbP25DESUnlockKey"; + this.tbP25DESUnlockKey.Size = new System.Drawing.Size(489, 46); + this.tbP25DESUnlockKey.TabIndex = 13; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(22, 367); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(148, 17); + this.label6.TabIndex = 12; + this.label6.Text = "Unlock Key for P25 DES:"; + // // LicensingForm // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; - this.ClientSize = new System.Drawing.Size(540, 567); + this.ClientSize = new System.Drawing.Size(540, 506); + this.Controls.Add(this.tbP25DESUnlockKey); + this.Controls.Add(this.label6); this.Controls.Add(this.tbP25ADPUnlockKey); this.Controls.Add(this.label5); this.Controls.Add(this.tbMotoEPUnlockKey); @@ -196,5 +217,7 @@ private void InitializeComponent() private System.Windows.Forms.Label label4; private System.Windows.Forms.TextBox tbP25ADPUnlockKey; private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox tbP25DESUnlockKey; + private System.Windows.Forms.Label label6; } } \ No newline at end of file diff --git a/src/LicensingForm.cs b/src/LicensingForm.cs index ccd8f19..ea8c0dd 100644 --- a/src/LicensingForm.cs +++ b/src/LicensingForm.cs @@ -19,12 +19,13 @@ public LicensingForm(Licensing licensing) tbMotoEPUnlockKey.Text = Utils.IsArrayEmpty(licensing.MotorolaEPUnlockKey) ? string.Empty : Utils.BytesToHexString(licensing.MotorolaEPUnlockKey); tbNxdnScramblerUnlockKey.Text = Utils.IsArrayEmpty(licensing.NxdnScramblerUnlockKey) ? string.Empty : Utils.BytesToHexString(licensing.NxdnScramblerUnlockKey); tbP25ADPUnlockKey.Text = Utils.IsArrayEmpty(licensing.P25ADPUnlockKey) ? string.Empty : Utils.BytesToHexString(licensing.P25ADPUnlockKey); + tbP25DESUnlockKey.Text = Utils.IsArrayEmpty(licensing.P25DESUnlockKey) ? string.Empty : Utils.BytesToHexString(licensing.P25DESUnlockKey); } } private void btnOk_Click(object sender, EventArgs e) { - byte[] mb, me, hb, ns, ad; + byte[] mb, me, hb, ns, ad, de; try { hb = Utils.HexStringToBytes(tbHyteraBPUnlockKey.Text); @@ -78,6 +79,17 @@ private void btnOk_Click(object sender, EventArgs e) return; } + try + { + de = Utils.HexStringToBytes(tbP25DESUnlockKey.Text); + } + catch + { + MessageBox.Show("Wrong P25 DES Unlock Key format.\r\nMust be HEX!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + tbP25DESUnlockKey.Focus(); + return; + } + Licensing = new Licensing(); if (Licensing.HyteraBPUnlockKey == null) @@ -95,11 +107,15 @@ private void btnOk_Click(object sender, EventArgs e) if (Licensing.P25ADPUnlockKey == null) Licensing.P25ADPUnlockKey = new byte[Licensing.UNLOCK_KEY_LEN]; + if (Licensing.P25DESUnlockKey == null) + Licensing.P25DESUnlockKey = new byte[Licensing.UNLOCK_KEY_LEN]; + Buffer.BlockCopy(hb, 0, Licensing.HyteraBPUnlockKey, 0, hb.Length > Licensing.UNLOCK_KEY_LEN ? Licensing.UNLOCK_KEY_LEN : hb.Length); Buffer.BlockCopy(mb, 0, Licensing.MotorolaBPUnlockKey, 0, mb.Length > Licensing.UNLOCK_KEY_LEN ? Licensing.UNLOCK_KEY_LEN : mb.Length); Buffer.BlockCopy(me, 0, Licensing.MotorolaEPUnlockKey, 0, me.Length > Licensing.UNLOCK_KEY_LEN ? Licensing.UNLOCK_KEY_LEN : me.Length); Buffer.BlockCopy(ns, 0, Licensing.NxdnScramblerUnlockKey, 0, ns.Length > Licensing.UNLOCK_KEY_LEN ? Licensing.UNLOCK_KEY_LEN : ns.Length); Buffer.BlockCopy(ad, 0, Licensing.P25ADPUnlockKey, 0, ad.Length > Licensing.UNLOCK_KEY_LEN ? Licensing.UNLOCK_KEY_LEN : ad.Length); + Buffer.BlockCopy(de, 0, Licensing.P25DESUnlockKey, 0, de.Length > Licensing.UNLOCK_KEY_LEN ? Licensing.UNLOCK_KEY_LEN : de.Length); DialogResult = DialogResult.OK; Close(); diff --git a/src/MainForm.Designer.cs b/src/MainForm.Designer.cs index 7d63ef5..45ecd02 100644 --- a/src/MainForm.Designer.cs +++ b/src/MainForm.Designer.cs @@ -58,6 +58,7 @@ private void InitializeComponent() this.miHyteraBPEncryptionMethod = new System.Windows.Forms.ToolStripMenuItem(); this.miNxdnScramblerMethod = new System.Windows.Forms.ToolStripMenuItem(); this.anytoneEncryptorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.p25ADPToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); this.miScanners = new System.Windows.Forms.ToolStripMenuItem(); this.miTools = new System.Windows.Forms.ToolStripMenuItem(); @@ -79,6 +80,7 @@ private void InitializeComponent() this.hyteraBPBasicPrivacyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.nXDNScramblerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.anytoneEncryptorToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.p25ADPToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.tsbDuplicateItem = new System.Windows.Forms.ToolStripButton(); this.tsbDeleteItem = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); @@ -96,8 +98,8 @@ private void InitializeComponent() this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.p25ADPToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.p25ADPToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.p25DESToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.p25DESToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.mainMenu.SuspendLayout(); this.mainStatus.SuspendLayout(); this.mainToolbar.SuspendLayout(); @@ -297,7 +299,8 @@ private void InitializeComponent() this.miHyteraBPEncryptionMethod, this.miNxdnScramblerMethod, this.anytoneEncryptorToolStripMenuItem, - this.p25ADPToolStripMenuItem}); + this.p25ADPToolStripMenuItem, + this.p25DESToolStripMenuItem}); this.miAddEncryptionMethodRow.Name = "miAddEncryptionMethodRow"; this.miAddEncryptionMethodRow.Size = new System.Drawing.Size(239, 22); this.miAddEncryptionMethodRow.Text = "Add Encryption Row"; @@ -337,6 +340,13 @@ private void InitializeComponent() this.anytoneEncryptorToolStripMenuItem.Text = "Anytone Encryptor ..."; this.anytoneEncryptorToolStripMenuItem.Click += new System.EventHandler(this.miAnytoneEncryptionMethod_Click); // + // p25ADPToolStripMenuItem + // + this.p25ADPToolStripMenuItem.Name = "p25ADPToolStripMenuItem"; + this.p25ADPToolStripMenuItem.Size = new System.Drawing.Size(255, 22); + this.p25ADPToolStripMenuItem.Text = "P25 ADP ..."; + this.p25ADPToolStripMenuItem.Click += new System.EventHandler(this.miP25ADPEncryptionMethod_Click); + // // toolStripSeparator6 // this.toolStripSeparator6.Name = "toolStripSeparator6"; @@ -475,7 +485,8 @@ private void InitializeComponent() this.hyteraBPBasicPrivacyToolStripMenuItem, this.nXDNScramblerToolStripMenuItem, this.anytoneEncryptorToolStripMenuItem1, - this.p25ADPToolStripMenuItem1}); + this.p25ADPToolStripMenuItem1, + this.p25DESToolStripMenuItem1}); this.tsbAddEncryptionRow.Image = global::CFT.Properties.Resources.add; this.tsbAddEncryptionRow.ImageTransparentColor = System.Drawing.Color.Magenta; this.tsbAddEncryptionRow.Name = "tsbAddEncryptionRow"; @@ -517,6 +528,13 @@ private void InitializeComponent() this.anytoneEncryptorToolStripMenuItem1.Text = "Anytone Encryptor ..."; this.anytoneEncryptorToolStripMenuItem1.Click += new System.EventHandler(this.miAnytoneEncryptionMethod_Click); // + // p25ADPToolStripMenuItem1 + // + this.p25ADPToolStripMenuItem1.Name = "p25ADPToolStripMenuItem1"; + this.p25ADPToolStripMenuItem1.Size = new System.Drawing.Size(255, 22); + this.p25ADPToolStripMenuItem1.Text = "P25 ADP ..."; + this.p25ADPToolStripMenuItem1.Click += new System.EventHandler(this.miP25ADPEncryptionMethod_Click); + // // tsbDuplicateItem // this.tsbDuplicateItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; @@ -665,19 +683,19 @@ private void InitializeComponent() this.selectAllToolStripMenuItem.Text = "Select All"; this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem1_Click); // - // p25ADPToolStripMenuItem + // p25DESToolStripMenuItem // - this.p25ADPToolStripMenuItem.Name = "p25ADPToolStripMenuItem"; - this.p25ADPToolStripMenuItem.Size = new System.Drawing.Size(255, 22); - this.p25ADPToolStripMenuItem.Text = "P25 ADP ..."; - this.p25ADPToolStripMenuItem.Click += new System.EventHandler(this.miP25ADPEncryptionMethod_Click); + this.p25DESToolStripMenuItem.Name = "p25DESToolStripMenuItem"; + this.p25DESToolStripMenuItem.Size = new System.Drawing.Size(255, 22); + this.p25DESToolStripMenuItem.Text = "P25 DES ..."; + this.p25DESToolStripMenuItem.Click += new System.EventHandler(this.miP25DESEncryptionMethod_Click); // - // p25ADPToolStripMenuItem1 + // p25DESToolStripMenuItem1 // - this.p25ADPToolStripMenuItem1.Name = "p25ADPToolStripMenuItem1"; - this.p25ADPToolStripMenuItem1.Size = new System.Drawing.Size(255, 22); - this.p25ADPToolStripMenuItem1.Text = "P25 ADP ..."; - this.p25ADPToolStripMenuItem1.Click += new System.EventHandler(this.miP25ADPEncryptionMethod_Click); + this.p25DESToolStripMenuItem1.Name = "p25DESToolStripMenuItem1"; + this.p25DESToolStripMenuItem1.Size = new System.Drawing.Size(255, 22); + this.p25DESToolStripMenuItem1.Text = "P25 DES ..."; + this.p25DESToolStripMenuItem1.Click += new System.EventHandler(this.miP25DESEncryptionMethod_Click); // // MainForm // @@ -780,6 +798,8 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem anytoneEncryptorToolStripMenuItem1; private System.Windows.Forms.ToolStripMenuItem p25ADPToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem p25ADPToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem p25DESToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem p25DESToolStripMenuItem1; } } diff --git a/src/MainForm.cs b/src/MainForm.cs index 283674a..f96afbc 100644 --- a/src/MainForm.cs +++ b/src/MainForm.cs @@ -62,6 +62,8 @@ private void ControlsUpdate() var licensing = ((cbScanners.Items[cbScanners.SelectedIndex] as DisplayTagObject).Tag as Scanner).Licensing; if (!Utils.IsArrayEmpty(licensing.MotorolaBPUnlockKey) || !Utils.IsArrayEmpty(licensing.HyteraBPUnlockKey) || + !Utils.IsArrayEmpty(licensing.P25ADPUnlockKey) || + !Utils.IsArrayEmpty(licensing.P25DESUnlockKey) || !Utils.IsArrayEmpty(licensing.NxdnScramblerUnlockKey)) { show = false; @@ -321,6 +323,15 @@ private void miAnytoneEncryptionMethod_Click(object sender, EventArgs e) } } + private void miP25DESEncryptionMethod_Click(object sender, EventArgs e) + { + var frm = new P25DESEncryptionMethodForm(null); + if (frm.ShowDialog() == DialogResult.OK) + { + AddEncryptionRow(frm.EncryptionRow); + } + } + private void tsbDuplicateItem_Click(object sender, EventArgs e) { @@ -377,6 +388,14 @@ private void tsbDuplicateItem_Click(object sender, EventArgs e) AddEncryptionRow(frm.EncryptionRow); } } + else if (row is P25DESEncryptionRow) + { + var frm = new P25DESEncryptionMethodForm(row as P25DESEncryptionRow); + if (frm.ShowDialog() == DialogResult.OK) + { + AddEncryptionRow(frm.EncryptionRow); + } + } } private void cmdSelectAll() @@ -749,6 +768,18 @@ private void listView_DoubleClick(object sender, EventArgs e) ControlsUpdate(); } } + else if (row is P25DESEncryptionRow) + { + var frm = new P25DESEncryptionMethodForm((P25DESEncryptionRow)row); + if (frm.ShowDialog() == DialogResult.OK) + { + var item = CreateListViewRow(filter, frm.EncryptionRow); + item.Text = listView.SelectedItems[0].Text; + item.Selected = true; + listView.Items[listView.SelectedIndices[0]] = item; + ControlsUpdate(); + } + } } private void MainForm_FormClosing(object sender, FormClosingEventArgs e) @@ -958,23 +989,29 @@ private void listView_KeyDown(object sender, KeyEventArgs e) var frm = new SelectEncryptionMethodForm(); if (frm.ShowDialog() == DialogResult.OK) { - switch (frm.Selection) + switch ((EncryptionMethodEnum)(frm.Selection+1)) { - case 0: + case EncryptionMethodEnum.MotorolaBP: miMotorolaBPEncryptionMethod_Click(sender, e); break; - case 1: + case EncryptionMethodEnum.HyteraBP: miHyteraBPEncryptionMethod_Click(sender, e); break; - case 2: + case EncryptionMethodEnum.NxdnScrambler: miNxdnScramblerMethod_Click(sender, e); break; - case 3: + case EncryptionMethodEnum.MotorolaEP: miMotorolaEPEncryptionMethod_Click(sender, e); break; - case 4: + case EncryptionMethodEnum.AnytoneEnc: + miAnytoneEncryptionMethod_Click(sender, e); + break; + case EncryptionMethodEnum.P25ADP: miP25ADPEncryptionMethod_Click(sender, e); break; + case EncryptionMethodEnum.P25DES: + miP25DESEncryptionMethod_Click(sender, e); + break; } } } diff --git a/src/P25ADPEncryptionMethodForm.cs b/src/P25ADPEncryptionMethodForm.cs index 6a03f5e..24634a4 100644 --- a/src/P25ADPEncryptionMethodForm.cs +++ b/src/P25ADPEncryptionMethodForm.cs @@ -76,7 +76,7 @@ private void btnOK_Click(object sender, EventArgs e) Array.Clear(EncryptionRow.Key, 0, 5); if (key.Length > 0) - Buffer.BlockCopy(key, 0, EncryptionRow.Key, 0, key.Length > MotorolaEPEncryptionRow.KEY_SIZE ? MotorolaEPEncryptionRow.KEY_SIZE : key.Length); + Buffer.BlockCopy(key, 0, EncryptionRow.Key, 0, key.Length > P25ADPEncryptionRow.KEY_SIZE ? P25ADPEncryptionRow.KEY_SIZE : key.Length); EncryptionRow.Frequency = freq; EncryptionRow.ActivateOptions = optionsControl.Options; diff --git a/src/P25ADPEncryptionRow.cs b/src/P25ADPEncryptionRow.cs index 31da376..9b9be50 100644 --- a/src/P25ADPEncryptionRow.cs +++ b/src/P25ADPEncryptionRow.cs @@ -21,7 +21,10 @@ public override string Description { get { - return $"P25 ADP: {ActivateOptions}"; + if (!string.IsNullOrEmpty($"{ActivateOptions}")) + return $"P25 ADP: {ActivateOptions}"; + else + return $"P25 ADP"; } } } diff --git a/src/P25DESEncryptionMethodForm.Designer.cs b/src/P25DESEncryptionMethodForm.Designer.cs new file mode 100644 index 0000000..38cd181 --- /dev/null +++ b/src/P25DESEncryptionMethodForm.Designer.cs @@ -0,0 +1,165 @@ +namespace CFT +{ + partial class P25DESEncryptionMethodForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.tbFrequency = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.tbNotes = new System.Windows.Forms.TextBox(); + this.btnClose = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.label4 = new System.Windows.Forms.Label(); + this.tbKey = new System.Windows.Forms.TextBox(); + this.optionsControl = new CFT.P25ActivateOptionsControl(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(26, 17); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(104, 17); + this.label1.TabIndex = 0; + this.label1.Text = "Frequency, MHz:"; + // + // tbFrequency + // + this.tbFrequency.Location = new System.Drawing.Point(29, 38); + this.tbFrequency.Name = "tbFrequency"; + this.tbFrequency.Size = new System.Drawing.Size(138, 25); + this.tbFrequency.TabIndex = 1; + // + // label3 + // + this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(26, 298); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(46, 17); + this.label3.TabIndex = 6; + this.label3.Text = "Notes:"; + // + // tbNotes + // + this.tbNotes.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.tbNotes.Location = new System.Drawing.Point(29, 319); + this.tbNotes.Name = "tbNotes"; + this.tbNotes.Size = new System.Drawing.Size(406, 25); + this.tbNotes.TabIndex = 5; + // + // btnClose + // + this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnClose.Location = new System.Drawing.Point(29, 363); + this.btnClose.Name = "btnClose"; + this.btnClose.Size = new System.Drawing.Size(126, 30); + this.btnClose.TabIndex = 6; + this.btnClose.Text = "Close"; + this.btnClose.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnOK.Location = new System.Drawing.Point(309, 363); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(126, 30); + this.btnOK.TabIndex = 0; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(174, 17); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(137, 17); + this.label4.TabIndex = 11; + this.label4.Text = "Key DES (16 symbols):"; + // + // tbKey + // + this.tbKey.Location = new System.Drawing.Point(177, 38); + this.tbKey.MaxLength = 16; + this.tbKey.Name = "tbKey"; + this.tbKey.Size = new System.Drawing.Size(262, 25); + this.tbKey.TabIndex = 3; + // + // optionsControl + // + this.optionsControl.Location = new System.Drawing.Point(29, 69); + this.optionsControl.Name = "optionsControl"; + this.optionsControl.Options = null; + this.optionsControl.Size = new System.Drawing.Size(419, 222); + this.optionsControl.TabIndex = 12; + // + // P25DESEncryptionMethodForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnClose; + this.ClientSize = new System.Drawing.Size(468, 412); + this.Controls.Add(this.optionsControl); + this.Controls.Add(this.tbKey); + this.Controls.Add(this.label4); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.btnClose); + this.Controls.Add(this.tbNotes); + this.Controls.Add(this.label3); + this.Controls.Add(this.tbFrequency); + this.Controls.Add(this.label1); + this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Margin = new System.Windows.Forms.Padding(4); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "P25DESEncryptionMethodForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "P25 DES Encryption "; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox tbFrequency; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox tbNotes; + private System.Windows.Forms.Button btnClose; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox tbKey; + private P25ActivateOptionsControl optionsControl; + } +} \ No newline at end of file diff --git a/src/P25DESEncryptionMethodForm.cs b/src/P25DESEncryptionMethodForm.cs new file mode 100644 index 0000000..bd858e7 --- /dev/null +++ b/src/P25DESEncryptionMethodForm.cs @@ -0,0 +1,90 @@ +using System; +using System.Windows.Forms; + +namespace CFT +{ + public partial class P25DESEncryptionMethodForm : Form + { + public P25DESEncryptionRow EncryptionRow { get; private set; } + public bool IsBatchMode { get; private set; } + + public P25DESEncryptionMethodForm(P25DESEncryptionRow row = null, bool batchMode = false) + { + InitializeComponent(); + + IsBatchMode = batchMode; + if (IsBatchMode) + { + Text += " (Batch mode)"; + tbFrequency.Enabled = false; + tbNotes.Enabled = false; + } + + if (row == null) + { + EncryptionRow = new P25DESEncryptionRow(); + EncryptionRow.Key = new byte[P25DESEncryptionRow.KEY_SIZE]; + if (!IsBatchMode) + tbFrequency.Text = Utils.GetFrequencyString(145500000); + optionsControl.SetOptions(null); + } + else + { + EncryptionRow = row; + if (!IsBatchMode) + tbFrequency.Text = Utils.GetFrequencyString(row.Frequency); + optionsControl.SetOptions(row.ActivateOptions); + + if (Utils.IsArrayEmpty(row.Key)) + tbKey.Text = string.Empty; + else + tbKey.Text = Utils.BytesToHexString(row.Key); + + tbNotes.Text = row.Notes; + } + } + + private void btnOK_Click(object sender, EventArgs e) + { + string errorStr; + + if (optionsControl.IsExistErrors(out errorStr)) + { + MessageBox.Show(errorStr, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + + uint freq = 0; + if (!IsBatchMode && !Utils.ParseFrequency(tbFrequency.Text, out freq, out errorStr)) + { + tbFrequency.Focus(); + MessageBox.Show(errorStr, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + + byte[] key; + try + { + key = Utils.HexStringToBytes(tbKey.Text); + } + catch + { + MessageBox.Show("Wrong Encryption Key Format.\r\nMust be HEX!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + tbKey.Focus(); + return; + } + + Array.Clear(EncryptionRow.Key, 0, 5); + if (key.Length > 0) + Buffer.BlockCopy(key, 0, EncryptionRow.Key, 0, key.Length > P25DESEncryptionRow.KEY_SIZE ? P25DESEncryptionRow.KEY_SIZE : key.Length); + + EncryptionRow.Frequency = freq; + EncryptionRow.ActivateOptions = optionsControl.Options; + + EncryptionRow.Notes = tbNotes.Text.Trim(); + + DialogResult = DialogResult.OK; + Close(); + } + } +} diff --git a/src/P25DESEncryptionMethodForm.resx b/src/P25DESEncryptionMethodForm.resx new file mode 100644 index 0000000..7080a7d --- /dev/null +++ b/src/P25DESEncryptionMethodForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/P25DESEncryptionRow.cs b/src/P25DESEncryptionRow.cs new file mode 100644 index 0000000..58f3c79 --- /dev/null +++ b/src/P25DESEncryptionRow.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; +using System; + +namespace CFT +{ + [DisplayName("P25 DES")] + [Serializable] + public class P25DESEncryptionRow : BaseEncryptionRow + { + public const int KEY_SIZE = 8; + + public byte[] Key { get; set; } + + public P25ActivateOptions ActivateOptions { get; set; } + + [JsonIgnore] + public override ProtocolEnum Protocol => ProtocolEnum.P25; + + [JsonIgnore] + public override string Description + { + get + { + if (!string.IsNullOrEmpty($"{ActivateOptions}")) + return $"P25 DES: {ActivateOptions}"; + else + return $"P25 DES"; + } + } + } +} diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs index e1f5dc0..c221f1b 100644 --- a/src/Properties/AssemblyInfo.cs +++ b/src/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.0.21")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyVersion("2.0.0.22")] +[assembly: AssemblyFileVersion("2.0.0.22")]