Anforderung RQ-10-05 der Norm ISO/SAE 21434 legt die Verwendung einer geeigneten Sprachteilmenge nahe – häufig auch als Codierstandard bezeichnet. Es gibt viele solche Codierstandards wie etwa C/CYBERSECURITY+, MISRA C/CYBERSECURITY+ und CERTC/CYBERSECURITY+. In der ISO/SAE 21434 sind MISRA und SEI CERT als Beispiele für geeignete Codierstandards angeführt. In der Norm ISO 26262 werden die MISRA-Sprachteilmengen – hier aus der Functional-Safety-Perspektive – ebenfalls empfohlen.
Traditionell wird die Einhaltung dieser Richtlinien mithilfe von Peer Reviews des Codes durchgesetzt, und tatsächlich können diese als gegenseitige Lernhilfe unter Kollegen sinnvoll sein. Deutlich effizienter und weniger fehleranfällig ist jedoch das Automatisieren dieser mühsamen Checks (Bild 3).
Die ISO/SAE 21434 zwingt nicht zur Verwendung eines bestimmten Codierstandards. Entwicklern steht es somit frei, projektspezifische Codierregeln zu benutzen oder sich für einen etablierten Standard zu entscheiden. Wenn ein Tool unter solchen Umständen sinnvoll einsetzbar sein soll, muss es sich an diese Modifikationen adaptieren lassen (Bild 4).
Anforderung RQ-10-10 der ISO/SAE 21434 hebt die nachfolgend beschriebenen Verifikationsmethoden hervor, ohne jedoch Einzelheiten über die Herangehensweise zu formulieren. Da sich diese Verifikationsmethoden aber beim Einsatz in kritischen Applikationen bewährt haben, gibt es solide Argumente dafür, dass sie hier die bestmögliche Vorgehensweise darstellen.
Das anforderungsbasierte Testen sieht dynamische Tests – d. h. die komplette oder partielle Ausführung – des Codes vor, um den Nachweis zu erbringen, dass dieser die Anforderungen an die Software – und an zwischengeschaltete, aus diesen Anforderungen abgeleitete Programmteile – erfüllt. Nicht spezifizierte Funktionen oder redundanter Code werden dagegen nicht einbezogen.
Die strukturelle Überdeckungsanalyse ermittelt, welche Codestrukturen und Komponentenschnittstellen während der Ausführung dieser anforderungsbasierten Testprozeduren nicht erfasst wurden. Solche nicht ausgeführten Teile des Codes machen eine weitere Analyse und entsprechende Abhilfemaßnahmen erforderlich. Auch wenn die Norm die Verwendung von Tools für diese Aufgabe nicht ausdrücklich vorschreibt, ist deren Einsatz auf jeden Fall effizienter, wenn von ganz trivialen Anwendungen abgesehen wird (Bild 5).
Schnittstellentests verifizieren, ob die Kommunikation zwischen Softwaresystemen, Subsystemen und Komponenten korrekt funktioniert (Bild 6).
Die Sicherstellung, dass in Bezug auf Speicher, Timing und Dateisystem genügend Ressourcen zur Verfügung stehen, sowie das Eliminieren etwaiger Konflikte sind wichtige Aspekte bei der Entwicklung eines vernetzten Systems, besonders, wenn dieses zum Angriffsziel böswilliger Akteure werden kann. Durch die Einführung von Multicore-Prozessoren hat sich die Bedeutung adäquater Ressourcen erhöht, aber gleichzeitig ist es zu einer anspruchsvolleren Aufgabe geworden, die Verfügbarkeit dieser Ressourcen zu gewährleisten.
Als Beispiel hierfür sei die Berechnung der Worst-Case Execution Time (WCET) angeführt. Laut Reinhard Wilhelm et al. ist die Berechnung eines definitiven WCET-Werts durch mathematische Analyse in einem allgemeinen Fall nicht möglich. Ein rein statischer Analyseansatz erfordert deshalb Näherungen.
Die Folge ist, dass sich die Tools stets zur sicheren Seite hin irren. Das ist auf jeden Fall besser, als keine Möglichkeit der Analyse zu haben, aber es ist keineswegs ideal in einem Umfeld, in dem Genauigkeit alles ist. Es gibt jedoch bewährte Mechanismen zum Messen der Eigenschaften von Softwarecode, die unabhängig von ihrer Ausführung auf der gewählten Plattform sind.
Die Halstead-Metriken etwa geben die Implementierung von Algorithmen in verschiedenen Sprachen wieder, um die Größe der Softwaremodule, die Komplexität der Software und die Datenflussinformationen zu bewerten. Diese aber lassen sich alle präzise aus der statischen Analyse des Softwarecodes berechnen (Bild 7). Mit diesem Verfahren kann ermittelt werden, welche Codeabschnitte die meiste Verarbeitungszeit brauchen, aber absolute Werte bezüglich der verstrichenen Zeit lassen sich nicht erzeugen.
Die gleiche statische Analyse liefert auch Aufrufdiagramme zur Codebasis, um zu visualisieren, wo sich die anspruchsvollsten Funktionen im Kontext der gesamten Codebasis befinden (Bild 8). Mithilfe von Entwicklungstools lassen sich diese kritischen Verarbeitungszeiten dynamisch messen, anstatt sich auf Näherungen aufgrund statischer Analysen verlassen zu müssen (Bild 9).
Fehler im Daten- oder Kontrollfluss können Schwachstellen im Code zur Folge haben. Mit der Kontroll- und Datenflussanalyse lässt sich bestätigen, dass beide im Einklang mit der Systementwicklung stehen. Tools, die statische und dynamische Analysefunktionen für Host- und Embedded-Software bieten, arbeiten den Kontrollfluss heraus und illustrieren ihn in Form von Flussdiagrammen, die den Verarbeitungswegen überlagert werden können (Bild 10).
Die dynamische Analyse validiert und verifiziert die Software, indem sie ihr Verhalten zur Laufzeit auswertet. Zu den dynamischen Analysetools gehören jene, die für die (strukturelle) Codeüberdeckungs-Analyse und Modultests eingesetzt werden. Mit der dynamischen Analyse (bzw. DAST) im Kontext des Codes während der Entwicklung und Integration ist in der Regel die »White-Box«-Analyse gemeint, in welcher der Quellcode verfügbar ist und auf die Verarbeitung des Objektcodes abgebildet wird.
Traditionellere »Black-Box«-Security-Techniken wie etwa Fuzz- und Penetrationstests haben nach wie vor ihren Platz im Entwicklungszyklus der ISO/SAE 21434. Sie werden jedoch erst nach Komplettierung des Systems genutzt, um den Erfolg der während der Entwicklung ergriffenen Vorsichtsmaßnahmen zu bestätigen.
Die statische Analyse validiert und verifiziert Software durch Auswertung des Quellcodes (Bild 11). Statische Analysetools sind unterschiedlich gut in der Lage, subtile Nuancen von Verletzungen des Codierstandards zu identifizieren, wohingegen ausgefeilte Implementierungen wegen des zusätzlichen Verarbeitungsaufwands möglicherweise langsamer erscheinen. Ein sinnvoller Ansatz ist es, sich für Tools zu entscheiden, die die Option bieten, anfangs einen »Lightweight«-Modus zu wählen und erst mit fortschreitender Entwicklung auf eingehendere Analysen zu wechseln.
Der Autor
Mark Pitchford
verfügt über mehr als 30 Jahre Erfahrung in der Softwareentwicklung für technische Anwendungen. Er hat an vielen bedeutenden Industrie- und Handelsprojekten in den Bereichen Entwicklung und Management gearbeitet, sowohl in Großbritannien als auch international.
Seit 2001 arbeitet Pitchford mit Entwicklungsteams zusammen, die eine konforme Softwareentwicklung in sicherheitskritischen Umgebungen anstreben, mit Standards wie DO-178, IEC 61508, ISO 26262, IIRA und RAMI 4.0.
Er studierte an der Nottingham Trent University mit dem Abschluss Bachelor of Science und wurde vor über 30 Jahren Chartered Engineer. Pitchford arbeitet jetzt als technischer Spezialist bei LDRA Software Technology.
mark.pitchford@ldra.com