private void UpdateGrid(string filter = "") { DataTable dt = new DataTable(); dt.Columns.Add("Index"); dt.Columns.Add("Name"); dt.Columns.Add("Origin"); dt.Columns.Add("Level"); dt.Columns.Add("Seed Size"); dt.Columns.Add("Key Size"); dt.Columns.Add("Security Provider"); List <SecurityProvider> providers = SecurityProvider.GetSecurityProviders(); for (int i = 0; i < Definitions.Count; i++) { Definition definition = Definitions[i]; if (providers.Find(x => x.GetProviderName() == definition.Provider) is null) { continue; } if (!definition.Origin.ToLower().Contains(filter.ToLower())) { continue; } dt.Rows.Add(new string[] { i.ToString(), definition.EcuName, definition.Origin, definition.AccessLevel.ToString(), definition.SeedLength.ToString(), definition.KeyLength.ToString(), definition.Provider }); } dgvMain.DataSource = dt; dgvMain.Columns[0].Visible = false; dgvMain.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; dgvMain.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; dgvMain.Columns[3].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; dgvMain.Columns[4].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; dgvMain.Columns[5].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; dgvMain.Columns[6].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; }
public void VerifyOutputWithOfficialDLLs() { string dbPath = $"{GetLibraryFolder()}db.json"; string definitionJson = File.ReadAllText(dbPath); List <Definition> definitions = System.Text.Json.JsonSerializer.Deserialize <List <Definition> >(definitionJson); List <SecurityProvider> providers = SecurityProvider.GetSecurityProviders(); QuickTest(definitions.Find(x => (x.EcuName == "CRD3S2SEC9A") && (x.AccessLevel == 9) && (x.Provider == "DaimlerStandardSecurityAlgo")), providers); QuickTest(definitions.Find(x => (x.EcuName == "RBS222") && (x.AccessLevel == 11) && (x.Provider == "DaimlerStandardSecurityAlgoMod")), providers); QuickTest(definitions.Find(x => (x.EcuName == "IC177") && (x.AccessLevel == 11) && (x.Provider == "DaimlerStandardSecurityAlgoRefG")), providers); QuickTest(definitions.Find(x => (x.EcuName == "MED40") && (x.AccessLevel == 5) && (x.Provider == "PowertrainSecurityAlgo")), providers); QuickTest(definitions.Find(x => (x.EcuName == "CR6NFZ") && (x.AccessLevel == 1) && (x.Provider == "PowertrainSecurityAlgo2")), providers); QuickTest(definitions.Find(x => (x.EcuName == "DCDC223") && (x.AccessLevel == 17) && (x.Provider == "EsLibEd25519")), providers); VWTest(definitions, providers); Assert.Pass(); }
public void TryGenerateKey(byte[] inByte) { if (dgvMain.SelectedRows.Count != 1) { txtKeyValue.Text = "Please select a definition first"; return; } int selectedIndex = int.Parse(dgvMain.SelectedRows[0].Cells[0].Value.ToString()); Definition definition = Definitions[selectedIndex]; groupBox2.Text = $"Key Generation ({definition})"; if (definition.SeedLength != inByte.Length) { txtKeyValue.Text = $"Expecting a {definition.SeedLength}-byte seed. Current length is {inByte.Length}"; return; } SecurityProvider provider = SecurityProvider.GetSecurityProviders().Find(x => x.GetProviderName() == definition.Provider); if (provider is null) { txtKeyValue.Text = $"Could not load security provider for {definition.Provider}"; return; } byte[] outKey = new byte[definition.KeyLength]; if (provider.GenerateKey(inByte, outKey, definition.AccessLevel, definition.Parameters)) { txtKeyValue.Text = BitUtility.BytesToHex(outKey, true); } else { txtKeyValue.Text = $"Key generation was unsuccessful ({definition.Provider})"; return; } }
static void Main(string[] args) { bool showHelp = false; bool showDefinitions = false; int accessLevel = 1; string databasePath = "db.json"; string seedText = ""; string ecuName = ""; string prefix = ""; OptionSet options = new OptionSet() { { "d|database=", "Path to the JSON definition database", (string v) => databasePath = v }, { "s|seed=", "Seed value as received from ECU", (string v) => seedText = v }, { "n|name=", "Target ECU name", (string v) => ecuName = v }, { "l|level=", "Access level", (int v) => accessLevel = v }, { "h|help", "Show this message and exit", v => showHelp = v != null }, { "e|list", "Show a list of ECU definitions, then exit", v => showDefinitions = v != null }, { "p|prefix=", "Prefix this string on successful key generation", (string v) => prefix = v }, }; List <string> extraArgs; try { extraArgs = options.Parse(args); } catch (OptionException ex) { Console.WriteLine($"UnlockECU exception: {ex.Message}"); Console.WriteLine("Try `consoleunlockecu --help' for more information."); return; } if (showHelp) { ShowHelp(options); return; } // check params if they are valid first if (!File.Exists(databasePath)) { Console.WriteLine($"Could not open definition database file. Please check if the database exists at \"{databasePath}\""); return; } string definitionJson = ""; try { definitionJson = File.ReadAllText(databasePath); } catch (Exception ex) { Console.WriteLine($"UnlockECU exception while reading database : {ex.Message}"); return; } List <Definition> definitions = new List <Definition>(); try { definitions = System.Text.Json.JsonSerializer.Deserialize <List <Definition> >(definitionJson); } catch (Exception ex) { Console.WriteLine($"UnlockECU exception while parsing database : {ex.Message}. Please check if the JSON database file is valid."); return; } if (showDefinitions) { Console.WriteLine($"UnlockECU: {definitions.Count} definitions available in {databasePath}"); foreach (Definition d in definitions) { Console.Write($"{d.EcuName} ({d.Origin}): Level {d.AccessLevel}, Seed Length: {d.SeedLength}, Key Length: {d.KeyLength}, Provider: {d.Provider}\n"); } return; } if (ecuName.Length == 0) { Console.WriteLine($"UnlockECU: ECU name cannot be empty."); ShowHelp(options); return; } Definition matchingDefinition = Definition.FindDefinition(definitions, ecuName, accessLevel); if (matchingDefinition is null) { Console.WriteLine($"UnlockECU exception: Could not find a definition that matches {ecuName} (level {accessLevel})"); return; } // clean up user's seed input bool validHex = true; string cleanedText = seedText.Replace(" ", "").Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("-", "").ToUpper(); if (cleanedText.Length % 2 != 0) { validHex = false; } if (!System.Text.RegularExpressions.Regex.IsMatch(cleanedText, @"\A\b[0-9a-fA-F]+\b\Z")) { validHex = false; } byte[] seed = new byte[] { }; if (validHex) { seed = BitUtility.BytesFromHex(cleanedText); } else if (matchingDefinition.SeedLength == 0) { // do nothing, array is already empty } else { Console.WriteLine($"UnlockECU exception: ECU {matchingDefinition.EcuName} requires a valid {matchingDefinition.SeedLength}-byte seed"); return; } // attempt to generate the key SecurityProvider provider = SecurityProvider.GetSecurityProviders().Find(x => x.GetProviderName() == matchingDefinition.Provider); if (provider is null) { Console.WriteLine($"UnlockECU exception: Could not load security provider for {matchingDefinition.EcuName} ({matchingDefinition.Provider})"); return; } byte[] outKey = new byte[matchingDefinition.KeyLength]; if (provider.GenerateKey(seed, outKey, matchingDefinition.AccessLevel, matchingDefinition.Parameters)) { Console.Write($"{prefix}{BitUtility.BytesToHex(outKey)}"); return; } else { Console.WriteLine($"UnlockECU exception: Key generation was unsuccessful for {matchingDefinition.EcuName} ({matchingDefinition.Provider})"); return; } }