Initial work to calculate LSFR for future use

pull/1/head
firealarmss 11 months ago
parent 46a3b60810
commit 3abc4aa463

@ -57,6 +57,7 @@ namespace WhackerLinkConsoleV2.Controls
public int p25N { get; set; } = 0;
public int p25SeqNo { get; set; } = 0;
public int p25Errs { get; set; } = 0;
public byte[] mi = new byte[P25Defines.P25_MI_LENGTH]; // Message Indicator
public byte algId = 0; // Algorithm ID

@ -453,11 +453,9 @@ namespace WhackerLinkConsoleV2
{
DateTime pktTime = DateTime.Now;
if ( e.DUID == P25DUID.TSDU || e.DUID == P25DUID.PDU)
if (e.DUID == P25DUID.HDU || e.DUID == P25DUID.TSDU || e.DUID == P25DUID.PDU)
return;
byte control = e.Data[14U];
if (e.CallType == CallType.GROUP)
{
if (e.SrcId == 0)

@ -48,6 +48,7 @@ using System.Security.Cryptography;
using fnecore.P25.LC.TSBK;
using WebSocketSharp;
using NWaves.Signals;
using static WhackerLinkConsoleV2.P25Crypto;
namespace WhackerLinkConsoleV2
{
@ -92,7 +93,7 @@ namespace WhackerLinkConsoleV2
public MainWindow()
{
#if DEBUG
#if !DEBUG
ConsoleNative.ShowConsole();
#endif
InitializeComponent();
@ -1837,34 +1838,23 @@ namespace WhackerLinkConsoleV2
//Log.Logger.Debug($"Decoding IMBE buffer: {FneUtils.HexDump(imbe)}");
short[] samples = new short[FneSystemBase.MBE_SAMPLES_LENGTH];
int errs = 0;
#if WIN32
if (cryptodev)
{
//Console.WriteLine($"MI: {FneUtils.HexDump(channel.mi)}");
//Console.WriteLine($"Algorithm ID: {channel.algId}");
//Console.WriteLine($"Key ID: {channel.kId}");
channel.crypter.Process(imbe, frameType, n);
}
#if WIN32
if (channel.extFullRateVocoder == null)
channel.extFullRateVocoder = new AmbeVocoder(true);
errs = channel.extFullRateVocoder.decode(imbe, out samples);
channel.p25Errs = channel.extFullRateVocoder.decode(imbe, out samples);
#else
if (cryptodev)
{
Console.WriteLine($"MI: {FneUtils.HexDump(channel.mi)}");
Console.WriteLine($"Algorithm ID: {channel.algId}");
Console.WriteLine($"Key ID: {channel.kId}");
channel.crypter.Process(imbe, frameType, n);
}
//Console.WriteLine(FneUtils.HexDump(imbe));
errs = channel.decoder.decode(imbe, samples);
channel.p25Errs = channel.decoder.decode(imbe, samples);
#endif
if (emergency)
@ -2020,7 +2010,7 @@ namespace WhackerLinkConsoleV2
}
// Is the call over?
if (((e.DUID == P25DUID.TDU) || (e.DUID == P25DUID.TDULC)) && (slot.RxType != FrameType.TERMINATOR))
if (((e.DUID == P25DUID.TDU) || (e.DUID == P25DUID.TDULC)) && (slot.RxType != fnecore.FrameType.TERMINATOR))
{
channel.IsReceiving = false;
TimeSpan callDuration = pktTime - slot.RxStart;
@ -2032,6 +2022,8 @@ namespace WhackerLinkConsoleV2
if ((channel.algId != cpgChannel.GetAlgoId() || channel.kId != cpgChannel.GetKeyId()) && channel.algId != P25Defines.P25_ALGO_UNENCRYPT)
continue;
byte[] newMI = new byte[P25Defines.P25_MI_LENGTH];
int count = 0;
switch (e.DUID)
@ -2107,23 +2099,23 @@ namespace WhackerLinkConsoleV2
// The '6D' record - IMBE Voice 12 + Encryption Sync
Buffer.BlockCopy(data, count, channel.netLDU2, 50, 17);
channel.mi[0] = data[count + 1];
channel.mi[1] = data[count + 2];
channel.mi[2] = data[count + 3];
newMI[0] = data[count + 1];
newMI[1] = data[count + 2];
newMI[2] = data[count + 3];
count += 17;
// The '6E' record - IMBE Voice 13 + Encryption Sync
Buffer.BlockCopy(data, count, channel.netLDU2, 75, 17);
channel.mi[3] = data[count + 1];
channel.mi[4] = data[count + 2];
channel.mi[5] = data[count + 3];
newMI[3] = data[count + 1];
newMI[4] = data[count + 2];
newMI[5] = data[count + 3];
count += 17;
// The '6F' record - IMBE Voice 14 + Encryption Sync
Buffer.BlockCopy(data, count, channel.netLDU2, 100, 17);
channel.mi[6] = data[count + 1];
channel.mi[7] = data[count + 2];
channel.mi[8] = data[count + 3];
newMI[6] = data[count + 1];
newMI[7] = data[count + 2];
newMI[8] = data[count + 3];
count += 17;
// The '70' record - IMBE Voice 15 + Encryption Sync
@ -2144,6 +2136,13 @@ namespace WhackerLinkConsoleV2
Buffer.BlockCopy(data, count, channel.netLDU2, 200, 16);
count += 16;
if (channel.p25Errs > 0) // temp, need to actually get erros I guess
P25Crypto.CycleP25Lfsr(channel.mi);
else
Array.Copy(newMI, channel.mi, P25Defines.P25_MI_LENGTH);
Console.WriteLine(channel.p25Errs);
// decode 9 IMBE codewords into PCM samples
P25DecodeAudioFrame(channel.netLDU2, e, handler, channel, isEmergency, P25Crypto.FrameType.LDU2);
}

@ -116,6 +116,41 @@ namespace WhackerLinkConsoleV2
return false;
}
/// <summary>
/// Cycles the P25 LFSR (Linear Feedback Shift Register) based on the given polynomial.
/// </summary>
/// <param name="MI">The message indicator array to be processed.</param>
public static void CycleP25Lfsr(byte[] MI)
{
if (MI == null || MI.Length < 9)
throw new ArgumentException("MI must be at least 9 bytes long.");
ulong lfsr = 0;
// Load the first 8 bytes into the LFSR
for (int i = 0; i < 8; i++)
{
lfsr = (lfsr << 8) | MI[i];
}
// Perform 64-bit LFSR cycling using the polynomial:
// C(x) = x^64 + x^62 + x^46 + x^38 + x^27 + x^15 + 1
for (int cnt = 0; cnt < 64; cnt++)
{
ulong bit = ((lfsr >> 63) ^ (lfsr >> 61) ^ (lfsr >> 45) ^ (lfsr >> 37) ^ (lfsr >> 26) ^ (lfsr >> 14)) & 0x1;
lfsr = (lfsr << 1) | bit;
}
// Store the result back into MI
for (int i = 7; i >= 0; i--)
{
MI[i] = (byte)(lfsr & 0xFF);
lfsr >>= 8;
}
MI[8] = 0; // Last byte is always set to zero
}
/// <summary>
/// Process RC4
/// </summary>

Loading…
Cancel
Save

Powered by TurnKey Linux.