SW: Add TEK/KEK selection; fixes #21

This commit is contained in:
Daniel Dugger 2020-03-15 18:53:24 -04:00
parent 64547c9cfc
commit 739f33dd22
13 changed files with 378 additions and 95 deletions

View File

@ -16,6 +16,13 @@
<Label Content="SLN/CKR" HorizontalAlignment="Left" Margin="34,78,0,0" VerticalAlignment="Top"/> <Label Content="SLN/CKR" HorizontalAlignment="Left" Margin="34,78,0,0" VerticalAlignment="Top"/>
<TextBox Name="txtSlnDec" TextChanged="SlnDec_TextChanged" HorizontalAlignment="Left" Height="23" Margin="109,81,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <TextBox Name="txtSlnDec" TextChanged="SlnDec_TextChanged" HorizontalAlignment="Left" Height="23" Margin="109,81,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox Name="txtSlnHex" TextChanged="SlnHex_TextChanged" HorizontalAlignment="Left" Height="23" Margin="247,81,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <TextBox Name="txtSlnHex" TextChanged="SlnHex_TextChanged" HorizontalAlignment="Left" Height="23" Margin="247,81,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<Button Content="Erase" Click="Erase_Button_Click" HorizontalAlignment="Left" Margin="109,119,0,0" VerticalAlignment="Top" Width="75"/> <Label Content="Key Type" HorizontalAlignment="Left" Margin="34,111,0,0" VerticalAlignment="Top"/>
<ComboBox Name="cboType" SelectionChanged="OnTypeChanged" HorizontalAlignment="Left" Margin="109,115,0,0" VerticalAlignment="Top" Width="120">
<ComboBoxItem Name="AUTO" Content="Auto" />
<ComboBoxItem Name="TEK" Content="TEK" />
<ComboBoxItem Name="KEK" Content="KEK" />
</ComboBox>
<Label Name="lblType" Content="Label" HorizontalContentAlignment="Center" HorizontalAlignment="Left" Margin="247,111,0,0" VerticalAlignment="Top" Width="120"/>
<Button Content="Erase" Click="Erase_Button_Click" HorizontalAlignment="Left" Margin="109,148,0,0" VerticalAlignment="Top" Width="75"/>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -23,25 +23,16 @@ namespace KFDtool.Gui.Control
/// </summary> /// </summary>
public partial class P25KeyErase : UserControl public partial class P25KeyErase : UserControl
{ {
private bool IsKek { get; set; }
public P25KeyErase() public P25KeyErase()
{ {
InitializeComponent(); InitializeComponent();
IsKek = false;
cbActiveKeyset.IsChecked = true; // check here to trigger the cb/txt logic on load cbActiveKeyset.IsChecked = true; // check here to trigger the cb/txt logic on load
} cboType.SelectedIndex = 0; // set to the first item here to trigger the cbo/lbl logic on load
private void OnActiveKeysetChecked(object sender, RoutedEventArgs e)
{
txtKeysetIdDec.Text = string.Empty;
txtKeysetIdHex.Text = string.Empty;
txtKeysetIdDec.IsEnabled = false;
txtKeysetIdHex.IsEnabled = false;
}
private void OnActiveKeysetUnchecked(object sender, RoutedEventArgs e)
{
txtKeysetIdDec.IsEnabled = true;
txtKeysetIdHex.IsEnabled = true;
} }
private void KeysetIdDec_TextChanged(object sender, TextChangedEventArgs e) private void KeysetIdDec_TextChanged(object sender, TextChangedEventArgs e)
@ -78,6 +69,20 @@ namespace KFDtool.Gui.Control
} }
} }
private void OnActiveKeysetChecked(object sender, RoutedEventArgs e)
{
txtKeysetIdDec.Text = string.Empty;
txtKeysetIdHex.Text = string.Empty;
txtKeysetIdDec.IsEnabled = false;
txtKeysetIdHex.IsEnabled = false;
}
private void OnActiveKeysetUnchecked(object sender, RoutedEventArgs e)
{
txtKeysetIdDec.IsEnabled = true;
txtKeysetIdHex.IsEnabled = true;
}
private void SlnDec_TextChanged(object sender, TextChangedEventArgs e) private void SlnDec_TextChanged(object sender, TextChangedEventArgs e)
{ {
if (txtSlnDec.IsFocused) if (txtSlnDec.IsFocused)
@ -92,6 +97,8 @@ namespace KFDtool.Gui.Control
{ {
txtSlnHex.Text = string.Empty; txtSlnHex.Text = string.Empty;
} }
UpdateType();
} }
} }
@ -109,9 +116,65 @@ namespace KFDtool.Gui.Control
{ {
txtSlnDec.Text = string.Empty; txtSlnDec.Text = string.Empty;
} }
UpdateType();
} }
} }
private void UpdateType()
{
if (cboType.SelectedItem != null)
{
string name = ((ComboBoxItem)cboType.SelectedItem).Name as string;
if (name == "AUTO")
{
int num;
if (int.TryParse(txtSlnHex.Text, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out num))
{
if (num >= 0 && num <= 61439)
{
lblType.Content = "TEK";
IsKek = false;
}
else if (num >= 61440 && num <= 65535)
{
lblType.Content = "KEK";
IsKek = true;
}
else
{
lblType.Content = "Auto";
}
}
else
{
lblType.Content = "Auto";
}
}
else if (name == "TEK")
{
lblType.Content = "TEK";
IsKek = false;
}
else if (name == "KEK")
{
lblType.Content = "KEK";
IsKek = true;
}
else
{
// error
}
}
}
private void OnTypeChanged(object sender, SelectionChangedEventArgs e)
{
UpdateType();
}
private void Erase_Button_Click(object sender, RoutedEventArgs e) private void Erase_Button_Click(object sender, RoutedEventArgs e)
{ {
int keysetId = 0; int keysetId = 0;
@ -158,13 +221,13 @@ namespace KFDtool.Gui.Control
if (!slnValidateResult) if (!slnValidateResult)
{ {
MessageBox.Show("SLN invalid - valid range 1 to 65553 (dec), 0x0001 to 0x1999 (hex)", "Error", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show("SLN invalid - valid range 0 to 65535 (dec), 0x0000 to 0xFFFF (hex)", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return; return;
} }
try try
{ {
Interact.EraseKey(Settings.Port, useActiveKeyset, keysetId, sln); Interact.EraseKey(Settings.Port, useActiveKeyset, keysetId, sln, IsKek);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -7,8 +7,8 @@
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
<Grid> <Grid>
<Label Content="Dec" HorizontalAlignment="Left" Margin="154,16,0,0" VerticalAlignment="Top"/> <Label Content="Dec" HorizontalContentAlignment="Center" HorizontalAlignment="Left" Margin="109,16,0,0" VerticalAlignment="Top" Width="120"/>
<Label Content="Hex" HorizontalAlignment="Left" Margin="291,16,0,0" VerticalAlignment="Top"/> <Label Content="Hex" HorizontalContentAlignment="Center" HorizontalAlignment="Left" Margin="247,16,0,0" VerticalAlignment="Top" Width="120"/>
<Label Content="Keyset ID" HorizontalAlignment="Left" Margin="34,44,0,0" VerticalAlignment="Top"/> <Label Content="Keyset ID" HorizontalAlignment="Left" Margin="34,44,0,0" VerticalAlignment="Top"/>
<TextBox Name="txtKeysetIdDec" TextChanged="KeysetIdDec_TextChanged" HorizontalAlignment="Left" Height="23" Margin="109,47,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <TextBox Name="txtKeysetIdDec" TextChanged="KeysetIdDec_TextChanged" HorizontalAlignment="Left" Height="23" Margin="109,47,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox Name="txtKeysetIdHex" TextChanged="KeysetIdHex_TextChanged" HorizontalAlignment="Left" Height="23" Margin="247,47,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <TextBox Name="txtKeysetIdHex" TextChanged="KeysetIdHex_TextChanged" HorizontalAlignment="Left" Height="23" Margin="247,47,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
@ -16,24 +16,31 @@
<Label Content="SLN/CKR" HorizontalAlignment="Left" Margin="34,78,0,0" VerticalAlignment="Top"/> <Label Content="SLN/CKR" HorizontalAlignment="Left" Margin="34,78,0,0" VerticalAlignment="Top"/>
<TextBox Name="txtSlnDec" TextChanged="SlnDec_TextChanged" HorizontalAlignment="Left" Height="23" Margin="109,81,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <TextBox Name="txtSlnDec" TextChanged="SlnDec_TextChanged" HorizontalAlignment="Left" Height="23" Margin="109,81,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox Name="txtSlnHex" TextChanged="SlnHex_TextChanged" HorizontalAlignment="Left" Height="23" Margin="247,81,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <TextBox Name="txtSlnHex" TextChanged="SlnHex_TextChanged" HorizontalAlignment="Left" Height="23" Margin="247,81,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<Label Content="Key ID" HorizontalAlignment="Left" Margin="34,113,0,0" VerticalAlignment="Top"/> <Label Content="Key Type" HorizontalAlignment="Left" Margin="34,111,0,0" VerticalAlignment="Top"/>
<TextBox Name="txtKeyIdDec" TextChanged="KeyIdDec_TextChanged" HorizontalAlignment="Left" Height="23" Margin="109,116,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <ComboBox Name="cboType" SelectionChanged="OnTypeChanged" HorizontalAlignment="Left" Margin="109,115,0,0" VerticalAlignment="Top" Width="120">
<TextBox Name="txtKeyIdHex" TextChanged="KeyIdHex_TextChanged" HorizontalAlignment="Left" Height="23" Margin="247,116,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <ComboBoxItem Name="AUTO" Content="Auto" />
<Label Content="Algorithm" HorizontalAlignment="Left" Margin="34,147,0,0" VerticalAlignment="Top"/> <ComboBoxItem Name="TEK" Content="TEK" />
<TextBox Name="txtAlgoDec" TextChanged="AlgoDec_TextChanged" HorizontalAlignment="Left" Height="23" Margin="109,150,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <ComboBoxItem Name="KEK" Content="KEK" />
<TextBox Name="txtAlgoHex" TextChanged="AlgoHex_TextChanged" HorizontalAlignment="Left" Height="23" Margin="247,150,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> </ComboBox>
<ComboBox Name="cboAlgo" SelectionChanged="OnAlgoChanged" HorizontalAlignment="Left" Margin="383,151,0,0" VerticalAlignment="Top" Width="120"> <Label Name="lblType" Content="Label" HorizontalContentAlignment="Center" HorizontalAlignment="Left" Margin="247,111,0,0" VerticalAlignment="Top" Width="120"/>
<Label Content="Key ID" HorizontalAlignment="Left" Margin="34,145,0,0" VerticalAlignment="Top"/>
<TextBox Name="txtKeyIdDec" TextChanged="KeyIdDec_TextChanged" HorizontalAlignment="Left" Height="23" Margin="109,148,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox Name="txtKeyIdHex" TextChanged="KeyIdHex_TextChanged" HorizontalAlignment="Left" Height="23" Margin="247,148,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<Label Content="Algorithm" HorizontalAlignment="Left" Margin="34,179,0,0" VerticalAlignment="Top"/>
<TextBox Name="txtAlgoDec" TextChanged="AlgoDec_TextChanged" HorizontalAlignment="Left" Height="23" Margin="109,182,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox Name="txtAlgoHex" TextChanged="AlgoHex_TextChanged" HorizontalAlignment="Left" Height="23" Margin="247,182,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<ComboBox Name="cboAlgo" SelectionChanged="OnAlgoChanged" HorizontalAlignment="Left" Margin="383,183,0,0" VerticalAlignment="Top" Width="120">
<ComboBoxItem Name="AES256" Content="AES-256" /> <ComboBoxItem Name="AES256" Content="AES-256" />
<ComboBoxItem Name="DESOFB" Content="DES-OFB" /> <ComboBoxItem Name="DESOFB" Content="DES-OFB" />
<ComboBoxItem Name="DESXL" Content="DES-XL" /> <ComboBoxItem Name="DESXL" Content="DES-XL" />
<ComboBoxItem Name="ADP" Content="ADP/RC4" /> <ComboBoxItem Name="ADP" Content="ADP/RC4" />
<ComboBoxItem Name="OTHER" Content="Other" /> <ComboBoxItem Name="OTHER" Content="Other" />
</ComboBox> </ComboBox>
<Label Content="Key (hex)" HorizontalAlignment="Left" Margin="34,181,0,0" VerticalAlignment="Top"/> <Label Content="Key (hex)" HorizontalAlignment="Left" Margin="34,213,0,0" VerticalAlignment="Top"/>
<PasswordBox Name="txtKeyHidden" HorizontalAlignment="Left" Height="23" Margin="109,184,0,0" VerticalAlignment="Top" Width="500"/> <PasswordBox Name="txtKeyHidden" HorizontalAlignment="Left" Height="23" Margin="109,216,0,0" VerticalAlignment="Top" Width="500"/>
<TextBox Name="txtKeyVisible" HorizontalAlignment="Left" Height="23" Margin="109,184,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="500"/> <TextBox Name="txtKeyVisible" HorizontalAlignment="Left" Height="23" Margin="109,216,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="500"/>
<Button Content="Generate" Click="Generate_Button_Click" HorizontalAlignment="Left" Margin="626,187,0,0" VerticalAlignment="Top" Width="75"/> <Button Content="Generate" Click="Generate_Button_Click" HorizontalAlignment="Left" Margin="626,219,0,0" VerticalAlignment="Top" Width="75"/>
<CheckBox Name="cbHide" Content="Hide" Checked="OnHideChecked" Unchecked="OnHideUnchecked" HorizontalAlignment="Left" Margin="564,220,0,0" VerticalAlignment="Top"/> <CheckBox Name="cbHide" Content="Hide" Checked="OnHideChecked" Unchecked="OnHideUnchecked" HorizontalAlignment="Left" Margin="564,252,0,0" VerticalAlignment="Top"/>
<Button Content="Load" Click="Load_Button_Click" HorizontalAlignment="Left" Margin="109,220,0,0" VerticalAlignment="Top" Width="75"/> <Button Content="Load" Click="Load_Button_Click" HorizontalAlignment="Left" Margin="109,252,0,0" VerticalAlignment="Top" Width="75"/>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -26,29 +26,20 @@ namespace KFDtool.Gui.Control
/// </summary> /// </summary>
public partial class P25Keyload : UserControl public partial class P25Keyload : UserControl
{ {
private bool IsKek { get; set; }
public P25Keyload() public P25Keyload()
{ {
InitializeComponent(); InitializeComponent();
IsKek = false;
cbActiveKeyset.IsChecked = true; // check here to trigger the cb/txt logic on load cbActiveKeyset.IsChecked = true; // check here to trigger the cb/txt logic on load
cboType.SelectedIndex = 0; // set to the first item here to trigger the cbo/lbl logic on load
cboAlgo.SelectedIndex = 0; // set to the first item here to trigger the cbo/txt logic on load cboAlgo.SelectedIndex = 0; // set to the first item here to trigger the cbo/txt logic on load
cbHide.IsChecked = true; // check here to trigger the cb/txt logic on load cbHide.IsChecked = true; // check here to trigger the cb/txt logic on load
} }
private void OnActiveKeysetChecked(object sender, RoutedEventArgs e)
{
txtKeysetIdDec.Text = string.Empty;
txtKeysetIdHex.Text = string.Empty;
txtKeysetIdDec.IsEnabled = false;
txtKeysetIdHex.IsEnabled = false;
}
private void OnActiveKeysetUnchecked(object sender, RoutedEventArgs e)
{
txtKeysetIdDec.IsEnabled = true;
txtKeysetIdHex.IsEnabled = true;
}
private void KeysetIdDec_TextChanged(object sender, TextChangedEventArgs e) private void KeysetIdDec_TextChanged(object sender, TextChangedEventArgs e)
{ {
if (txtKeysetIdDec.IsFocused) if (txtKeysetIdDec.IsFocused)
@ -83,6 +74,20 @@ namespace KFDtool.Gui.Control
} }
} }
private void OnActiveKeysetChecked(object sender, RoutedEventArgs e)
{
txtKeysetIdDec.Text = string.Empty;
txtKeysetIdHex.Text = string.Empty;
txtKeysetIdDec.IsEnabled = false;
txtKeysetIdHex.IsEnabled = false;
}
private void OnActiveKeysetUnchecked(object sender, RoutedEventArgs e)
{
txtKeysetIdDec.IsEnabled = true;
txtKeysetIdHex.IsEnabled = true;
}
private void SlnDec_TextChanged(object sender, TextChangedEventArgs e) private void SlnDec_TextChanged(object sender, TextChangedEventArgs e)
{ {
if (txtSlnDec.IsFocused) if (txtSlnDec.IsFocused)
@ -97,6 +102,8 @@ namespace KFDtool.Gui.Control
{ {
txtSlnHex.Text = string.Empty; txtSlnHex.Text = string.Empty;
} }
UpdateType();
} }
} }
@ -114,9 +121,65 @@ namespace KFDtool.Gui.Control
{ {
txtSlnDec.Text = string.Empty; txtSlnDec.Text = string.Empty;
} }
UpdateType();
} }
} }
private void UpdateType()
{
if (cboType.SelectedItem != null)
{
string name = ((ComboBoxItem)cboType.SelectedItem).Name as string;
if (name == "AUTO")
{
int num;
if (int.TryParse(txtSlnHex.Text, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out num))
{
if (num >= 0 && num <= 61439)
{
lblType.Content = "TEK";
IsKek = false;
}
else if (num >= 61440 && num <= 65535)
{
lblType.Content = "KEK";
IsKek = true;
}
else
{
lblType.Content = "Auto";
}
}
else
{
lblType.Content = "Auto";
}
}
else if (name == "TEK")
{
lblType.Content = "TEK";
IsKek = false;
}
else if (name == "KEK")
{
lblType.Content = "KEK";
IsKek = true;
}
else
{
// error
}
}
}
private void OnTypeChanged(object sender, SelectionChangedEventArgs e)
{
UpdateType();
}
private void KeyIdDec_TextChanged(object sender, TextChangedEventArgs e) private void KeyIdDec_TextChanged(object sender, TextChangedEventArgs e)
{ {
if (txtKeyIdDec.IsFocused) if (txtKeyIdDec.IsFocused)
@ -384,7 +447,7 @@ namespace KFDtool.Gui.Control
return; return;
} }
Tuple<ValidateResult, string> validateResult = FieldValidator.KeyloadValidate(keysetId, sln, keyId, algId, key); Tuple<ValidateResult, string> validateResult = FieldValidator.KeyloadValidate(keysetId, sln, IsKek, keyId, algId, key);
if (validateResult.Item1 == ValidateResult.Warning) if (validateResult.Item1 == ValidateResult.Warning)
{ {
@ -401,7 +464,7 @@ namespace KFDtool.Gui.Control
try try
{ {
Interact.Keyload(Settings.Port, useActiveKeyset, keysetId, sln, keyId, algId, key); Interact.Keyload(Settings.Port, useActiveKeyset, keysetId, sln, IsKek, keyId, algId, key);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -53,7 +53,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Constant\AlgorithmId.cs" /> <Compile Include="Constant\AlgorithmId.cs" />
<Compile Include="Generator\KeyGenerator.cs" /> <Compile Include="Generator\KeyGenerator.cs" />
<Compile Include="Kmm\AckStatus.cs" /> <Compile Include="Kmm\OperationStatus.cs" />
<Compile Include="Kmm\InventoryCommandListRsiItems.cs" /> <Compile Include="Kmm\InventoryCommandListRsiItems.cs" />
<Compile Include="Kmm\InventoryResponseListRsiItems.cs" /> <Compile Include="Kmm\InventoryResponseListRsiItems.cs" />
<Compile Include="Kmm\NegativeAcknowledgment.cs" /> <Compile Include="Kmm\NegativeAcknowledgment.cs" />

View File

@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KFDtool.P25.Kmm
{
public enum AckStatus : byte
{
CommandWasNotPerformed = 0x01,
ItemDoesNotExist = 0x02,
InvalidMessageId = 0x03,
InvalidMac = 0x04,
InvalidMessageNumber = 0x07
}
}

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -65,10 +66,13 @@ namespace KFDtool.P25.Kmm
} }
} }
public bool KEK { get; set; }
public bool Erase { get; set; } public bool Erase { get; set; }
public KeyItem() public KeyItem()
{ {
KEK = false;
Erase = false; Erase = false;
} }
@ -77,14 +81,10 @@ namespace KFDtool.P25.Kmm
byte[] contents = new byte[5 + Key.Length]; byte[] contents = new byte[5 + Key.Length];
/* key format */ /* key format */
if (Erase) BitArray keyFormat = new BitArray(8, false);
{ keyFormat.Set(7, KEK);
contents[0] = 0x20; keyFormat.Set(5, Erase);
} keyFormat.CopyTo(contents, 0);
else
{
contents[0] = 0x00;
}
/* sln */ /* sln */
contents[1] = (byte)(SLN >> 8); contents[1] = (byte)(SLN >> 8);
@ -115,6 +115,7 @@ namespace KFDtool.P25.Kmm
} }
/* key format */ /* key format */
KEK = (contents[0] & 0x80) == 1;
Erase = (contents[0] & 0x20) == 1; Erase = (contents[0] & 0x20) == 1;
/* sln */ /* sln */

View File

@ -13,7 +13,7 @@ namespace KFDtool.P25.Kmm
public int MessageNumber { get; set; } public int MessageNumber { get; set; }
public AckStatus Status { get; set; } public OperationStatus Status { get; set; }
public override MessageId MessageId public override MessageId MessageId
{ {
@ -67,7 +67,7 @@ namespace KFDtool.P25.Kmm
MessageNumber |= contents[2]; MessageNumber |= contents[2];
/* status */ /* status */
Status = (AckStatus)contents[3]; Status = (OperationStatus)contents[3];
} }
} }
} }

View File

@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KFDtool.P25.Kmm
{
public enum OperationStatus : byte
{
CommandWasPerformed = 0x00,
CommandWasNotPerformed = 0x01,
ItemDoesNotExist = 0x02,
InvalidMessageId = 0x03,
InvalidMac = 0x04,
OutOfMemory = 0x05,
CouldNotDecryptTheMessage = 0x06,
InvalidMessageNumber = 0x07,
InvalidKeyId = 0x08,
InvalidAlgorithmId = 0x09,
InvalidMfid = 0x0A,
ModuleFailure = 0x0B,
MiAllZeros = 0x0C,
Keyfail = 0x0D,
Unknown = 0xFF
}
public static class OperationStatusExtensions
{
public static string ToStatusString(OperationStatus status)
{
switch (status)
{
case OperationStatus.CommandWasPerformed:
return "Command was performed";
case OperationStatus.CommandWasNotPerformed:
return "Command not performed";
case OperationStatus.ItemDoesNotExist:
return "Item does not exist";
case OperationStatus.InvalidMessageId:
return "Invalid Message ID";
case OperationStatus.InvalidMac:
return "Invalid MAC";
case OperationStatus.OutOfMemory:
return "Out of Memory";
case OperationStatus.CouldNotDecryptTheMessage:
return "Could not decrypt the message";
case OperationStatus.InvalidMessageNumber:
return "Invalid Message Number";
case OperationStatus.InvalidKeyId:
return "Invalid Key ID";
case OperationStatus.InvalidAlgorithmId:
return "Invalid Algorithm ID";
case OperationStatus.InvalidMfid:
return "Invalid MFID";
case OperationStatus.ModuleFailure:
return "Module Failure";
case OperationStatus.MiAllZeros:
return "MI all zeros";
case OperationStatus.Keyfail:
return "Keyfail";
case OperationStatus.Unknown:
return "Unknown";
default:
return "Reserved";
}
}
public static string ToReasonString(OperationStatus status)
{
switch (status)
{
case OperationStatus.CommandWasPerformed:
return "Command was executed successfully";
case OperationStatus.CommandWasNotPerformed:
return "Command could not be performed due to an unspecified reason";
case OperationStatus.ItemDoesNotExist:
return "Key / Keyset needed to perform the operation does not exist";
case OperationStatus.InvalidMessageId:
return "Message ID is invalid/unsupported";
case OperationStatus.InvalidMac:
return "MAC is invalid";
case OperationStatus.OutOfMemory:
return "Memory unavailable to process the command / message";
case OperationStatus.CouldNotDecryptTheMessage:
return "KEK does not exist";
case OperationStatus.InvalidMessageNumber:
return "Message Number is invalid";
case OperationStatus.InvalidKeyId:
return "Key ID is invalid or not present";
case OperationStatus.InvalidAlgorithmId:
return "ALGID is invalid or not present";
case OperationStatus.InvalidMfid:
return "MFID is invalid";
case OperationStatus.ModuleFailure:
return "Encryption Hardware failure";
case OperationStatus.MiAllZeros:
return "Received MI was all zeros";
case OperationStatus.Keyfail:
return "Key identified by ALGID/Key ID is erased";
case OperationStatus.Unknown:
return "Unknown";
default:
return "Reserved";
}
}
}
}

View File

@ -51,7 +51,7 @@ namespace KFDtool.P25.ManualRekey
} }
/* TIA 102.AACD-A 3.8.1 */ /* TIA 102.AACD-A 3.8.1 */
public void Keyload(bool useActiveKeyset, int keysetId, int sln, int keyId, int algId, List<byte> key) public void Keyload(bool useActiveKeyset, int keysetId, int sln, bool isKek, int keyId, int algId, List<byte> key)
{ {
Begin(); Begin();
@ -79,6 +79,10 @@ namespace KFDtool.P25.ManualRekey
{ {
ksid = keysetId; ksid = keysetId;
} }
else if (useActiveKeyset && isKek)
{
ksid = 0xFF;
}
else if (useActiveKeyset && kmm.KsetIds.Count > 0) else if (useActiveKeyset && kmm.KsetIds.Count > 0)
{ {
ksid = kmm.KsetIds[0]; ksid = kmm.KsetIds[0];
@ -92,7 +96,9 @@ namespace KFDtool.P25.ManualRekey
{ {
NegativeAcknowledgment kmm = rspKmmBody1 as NegativeAcknowledgment; NegativeAcknowledgment kmm = rspKmmBody1 as NegativeAcknowledgment;
throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status)); string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
} }
else else
{ {
@ -105,6 +111,7 @@ namespace KFDtool.P25.ManualRekey
keyItem.SLN = sln; keyItem.SLN = sln;
keyItem.KeyId = keyId; keyItem.KeyId = keyId;
keyItem.Key = key.ToArray(); keyItem.Key = key.ToArray();
keyItem.KEK = isKek;
keyItem.Erase = false; keyItem.Erase = false;
ModifyKeyCommand modifyKeyCommand = new ModifyKeyCommand(); ModifyKeyCommand modifyKeyCommand = new ModifyKeyCommand();
@ -133,7 +140,9 @@ namespace KFDtool.P25.ManualRekey
if (status.Status != 0) if (status.Status != 0)
{ {
throw new Exception("unexpected status"); string statusDescr = OperationStatusExtensions.ToStatusString((OperationStatus)status.Status);
string statusReason = OperationStatusExtensions.ToReasonString((OperationStatus)status.Status);
throw new Exception(string.Format("received unexpected key status{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, status.Status, statusReason));
} }
} }
} }
@ -141,11 +150,13 @@ namespace KFDtool.P25.ManualRekey
{ {
NegativeAcknowledgment kmm = rspKmmBody2 as NegativeAcknowledgment; NegativeAcknowledgment kmm = rspKmmBody2 as NegativeAcknowledgment;
throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status)); string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
} }
else else
{ {
throw new Exception("unexpected kmm"); throw new Exception("received unexpected kmm");
} }
} }
catch catch
@ -177,7 +188,7 @@ namespace KFDtool.P25.ManualRekey
} }
/* TIA 102.AACD-A 3.8.5 */ /* TIA 102.AACD-A 3.8.5 */
public void EraseKeys(bool useActiveKeyset, int keysetId, int sln) public void EraseKeys(bool useActiveKeyset, int keysetId, int sln, bool isKek)
{ {
Begin(); Begin();
@ -205,6 +216,10 @@ namespace KFDtool.P25.ManualRekey
{ {
ksid = keysetId; ksid = keysetId;
} }
else if (useActiveKeyset && isKek)
{
ksid = 0xFF;
}
else if (useActiveKeyset && kmm.KsetIds.Count > 0) else if (useActiveKeyset && kmm.KsetIds.Count > 0)
{ {
ksid = kmm.KsetIds[0]; ksid = kmm.KsetIds[0];
@ -218,7 +233,9 @@ namespace KFDtool.P25.ManualRekey
{ {
NegativeAcknowledgment kmm = rspKmmBody1 as NegativeAcknowledgment; NegativeAcknowledgment kmm = rspKmmBody1 as NegativeAcknowledgment;
throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status)); string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
} }
else else
{ {
@ -231,6 +248,7 @@ namespace KFDtool.P25.ManualRekey
keyItem.SLN = sln; keyItem.SLN = sln;
keyItem.KeyId = 65535; // to match KVL3000+ R3.53.03 behavior keyItem.KeyId = 65535; // to match KVL3000+ R3.53.03 behavior
keyItem.Key = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // to match KVL3000+ R3.53.03 behavior keyItem.Key = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // to match KVL3000+ R3.53.03 behavior
keyItem.KEK = isKek;
keyItem.Erase = true; keyItem.Erase = true;
ModifyKeyCommand modifyKeyCommand = new ModifyKeyCommand(); ModifyKeyCommand modifyKeyCommand = new ModifyKeyCommand();
@ -259,7 +277,9 @@ namespace KFDtool.P25.ManualRekey
if (status.Status != 0) if (status.Status != 0)
{ {
throw new Exception("unexpected status"); string statusDescr = OperationStatusExtensions.ToStatusString((OperationStatus)status.Status);
string statusReason = OperationStatusExtensions.ToReasonString((OperationStatus)status.Status);
throw new Exception(string.Format("received unexpected key status{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, status.Status, statusReason));
} }
} }
} }
@ -267,7 +287,9 @@ namespace KFDtool.P25.ManualRekey
{ {
NegativeAcknowledgment kmm = rspKmmBody2 as NegativeAcknowledgment; NegativeAcknowledgment kmm = rspKmmBody2 as NegativeAcknowledgment;
throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status)); string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
} }
else else
{ {
@ -303,7 +325,9 @@ namespace KFDtool.P25.ManualRekey
{ {
NegativeAcknowledgment kmm = responseKmmBody as NegativeAcknowledgment; NegativeAcknowledgment kmm = responseKmmBody as NegativeAcknowledgment;
throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status)); string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
} }
else else
{ {
@ -379,7 +403,9 @@ namespace KFDtool.P25.ManualRekey
{ {
NegativeAcknowledgment kmm = responseKmmBody as NegativeAcknowledgment; NegativeAcknowledgment kmm = responseKmmBody as NegativeAcknowledgment;
throw new Exception(string.Format("recieved negative acknowledgment, status {0} (0x{1:X2})", kmm.Status.ToString(), (byte)kmm.Status)); string statusDescr = OperationStatusExtensions.ToStatusString(kmm.Status);
string statusReason = OperationStatusExtensions.ToReasonString(kmm.Status);
throw new Exception(string.Format("received negative acknowledgment{0}status: {1} (0x{2:X2}){0}{3}", Environment.NewLine, statusDescr, kmm.Status, statusReason));
} }
else else
{ {

View File

@ -412,7 +412,7 @@ namespace KFDtool.P25.ThreeWire
NegativeAcknowledgment kmm = new NegativeAcknowledgment(); NegativeAcknowledgment kmm = new NegativeAcknowledgment();
kmm.AcknowledgedMessageId = (MessageId)message[0]; kmm.AcknowledgedMessageId = (MessageId)message[0];
kmm.Status = AckStatus.InvalidMessageId; kmm.Status = OperationStatus.InvalidMessageId;
KmmFrame frame = new KmmFrame(kmm); KmmFrame frame = new KmmFrame(kmm);

View File

@ -468,7 +468,7 @@ namespace KFDtool.P25.TransferConstructs
} }
} }
public static void Keyload(string port, bool useActiveKeyset, int keysetId, int sln, int keyId, int algId, List<byte> key) public static void Keyload(string port, bool useActiveKeyset, int keysetId, int sln, bool isKek, int keyId, int algId, List<byte> key)
{ {
if (port == string.Empty) if (port == string.Empty)
{ {
@ -487,7 +487,7 @@ namespace KFDtool.P25.TransferConstructs
ManualRekeyApplication mra = new ManualRekeyApplication(ap); ManualRekeyApplication mra = new ManualRekeyApplication(ap);
mra.Keyload(useActiveKeyset, keysetId, sln, keyId, algId, key); mra.Keyload(useActiveKeyset, keysetId, sln, isKek, keyId, algId, key);
} }
catch (Exception) catch (Exception)
{ {
@ -509,7 +509,7 @@ namespace KFDtool.P25.TransferConstructs
} }
} }
public static void EraseKey(string port, bool useActiveKeyset, int keysetId, int sln) public static void EraseKey(string port, bool useActiveKeyset, int keysetId, int sln, bool isKek)
{ {
if (port == string.Empty) if (port == string.Empty)
{ {
@ -528,7 +528,7 @@ namespace KFDtool.P25.TransferConstructs
ManualRekeyApplication mra = new ManualRekeyApplication(ap); ManualRekeyApplication mra = new ManualRekeyApplication(ap);
mra.EraseKeys(useActiveKeyset, keysetId, sln); mra.EraseKeys(useActiveKeyset, keysetId, sln, isKek);
} }
catch (Exception) catch (Exception)
{ {

View File

@ -26,7 +26,7 @@ namespace KFDtool.P25.Validator
public static bool IsValidSln(int sln) public static bool IsValidSln(int sln)
{ {
/* TIA 102.AACA-A 10.3.25 */ /* TIA 102.AACA-A 10.3.25 */
if (sln < 1 || sln > 65535) if (sln < 0 || sln > 65535)
{ {
return false; return false;
} }
@ -97,7 +97,7 @@ namespace KFDtool.P25.Validator
return result; return result;
} }
public static Tuple<ValidateResult,string> KeyloadValidate(int keysetId, int sln, int keyId, int algId, List<byte> key) public static Tuple<ValidateResult,string> KeyloadValidate(int keysetId, int sln, bool isKek, int keyId, int algId, List<byte> key)
{ {
if (!IsValidKeysetId(keysetId)) if (!IsValidKeysetId(keysetId))
{ {
@ -106,7 +106,7 @@ namespace KFDtool.P25.Validator
if (!IsValidSln(sln)) if (!IsValidSln(sln))
{ {
return Tuple.Create(ValidateResult.Error, "SLN invalid - valid range 1 to 65553 (dec), 0x0001 to 0x1999 (hex)"); return Tuple.Create(ValidateResult.Error, "SLN invalid - valid range 0 to 65535 (dec), 0x0000 to 0xFFFF (hex)");
} }
if (!IsValidKeyId(keyId)) if (!IsValidKeyId(keyId))
@ -321,6 +321,31 @@ namespace KFDtool.P25.Validator
return Tuple.Create(ValidateResult.Warning, string.Format("Algorithm ID 0x{0:X2} is unassigned - no key validation has been performed", algId)); return Tuple.Create(ValidateResult.Warning, string.Format("Algorithm ID 0x{0:X2} is unassigned - no key validation has been performed", algId));
} }
// good practice validators
if (sln == 0)
{
return Tuple.Create(ValidateResult.Warning, "While the SLN 0 is valid, some equipment may have issues using it"); // *cough* Motorola KVLs *cough*
}
if (sln >= 1 && sln <= 4095)
{
if (isKek)
{
return Tuple.Create(ValidateResult.Warning, "This SLN is in the range for TEKs, but the key type KEK is selected");
}
}
else if (sln >= 4096 && sln <= 61439)
{
return Tuple.Create(ValidateResult.Warning, "While this SLN is valid, it uses a crypto group other than 0 or 15, some equipment may have issues using it");
}
else if (sln >= 61440 && sln <= 65535)
{
if (!isKek)
{
return Tuple.Create(ValidateResult.Warning, "This SLN is in the range for KEKs, but the key type TEK is selected");
}
}
return Tuple.Create(ValidateResult.Success, string.Empty); return Tuple.Create(ValidateResult.Success, string.Empty);
} }
} }