Skip to content

Commit

Permalink
Added P25 DES Encryption support
Browse files Browse the repository at this point in the history
  • Loading branch information
x27 committed Aug 13, 2024
1 parent a2e4d16 commit b4d7693
Show file tree
Hide file tree
Showing 16 changed files with 624 additions and 44 deletions.
11 changes: 11 additions & 0 deletions src/CFT.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@
<Compile Include="DebugLogsFilteringForm.Designer.cs">
<DependentUpon>DebugLogsFilteringForm.cs</DependentUpon>
</Compile>
<Compile Include="P25DESEncryptionMethodForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="P25DESEncryptionMethodForm.Designer.cs">
<DependentUpon>P25DESEncryptionMethodForm.cs</DependentUpon>
</Compile>
<Compile Include="P25ADPEncryptionMethodForm.cs">
<SubType>Form</SubType>
</Compile>
Expand Down Expand Up @@ -149,6 +155,7 @@
</Compile>
<Compile Include="NxdnActivateOptions.cs" />
<Compile Include="NxdnCypherTypeEnum.cs" />
<Compile Include="P25DESEncryptionRow.cs" />
<Compile Include="P25ADPEncryptionRow.cs" />
<Compile Include="P25SelectedActivateOptionsEnum.cs" />
<Compile Include="NxdnSelectedActivateOptionsEnum.cs" />
Expand Down Expand Up @@ -214,6 +221,10 @@
<EmbeddedResource Include="AboutForm.resx">
<DependentUpon>AboutForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="P25DESEncryptionMethodForm.resx">
<DependentUpon>P25DESEncryptionMethodForm.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="P25ADPEncryptionMethodForm.resx">
<DependentUpon>P25ADPEncryptionMethodForm.cs</DependentUpon>
<SubType>Designer</SubType>
Expand Down
41 changes: 41 additions & 0 deletions src/CftFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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<IEncryptionRow>();
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion src/EncryptionMethodEnum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
18 changes: 18 additions & 0 deletions src/ImportForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
1 change: 1 addition & 0 deletions src/Licensing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
}
59 changes: 41 additions & 18 deletions src/LicensingForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 17 additions & 1 deletion src/LicensingForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand All @@ -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();
Expand Down
Loading

0 comments on commit b4d7693

Please sign in to comment.