Secrecy included : confidentiality enforcement for machine code

Pfeffer, Tobias Ferdinand

FG Software and Embedded Systems Engineering

Confidential software is an important requirement for the ongoing digitalization. Yet, since confidentiality is a program-wide property, this requirement is at odds with modern software development. In order to produce software cheaply and quickly, existing software components from third-party manufacturers are regularly included in new products. Consequently, a method is needed to ensure the confidentiality across third-party components, which are usually shipped in compiled form. In this thesis we present a new method that enforces confidentiality for compiled programs. Our approach protects against leaks through data flow, control flow, termination behavior, and timing of outputs. At the same time, it achieves per-channel transparency, thereby preserving the functionality of secure components. Our solution is the first practical application of the concept of Secure Multi-Execution to machine code. Secure Multi-Execution is an enforcement mechanism that achieves confidentiality by design. The target program is executed multiple times, where each copy has restricted access to input and output channels. Unfortunately, this multi-execution comes with a significant performance overhead. Thus, we propose two optimizations that significantly increase the efficiency of the protection mechanism. Our principle is to avoid redundant calculations as much as possible. On the one hand, we show how creation of multiplied executions can be delayed through our dynamic instancing method. On the other hand, we show how multiplied executions can be terminated early through our bounding method. In order not to reduce the security guarantees of Secure Multi-Execution through our optimizations, we additionally present a new scheduling strategy for the multiple executions. This strategy allows us to ensure independent progress of executions, while maintaining external dependencies in their output behavior. We also present our contributions to static analysis of binary code, which serves as a basis for further research into the automatic determination of suitable termination points for our optimizations. We have successfully applied our method to the Linux operating system and the widely used x86_x64 architecture. In our evaluation of benchmark programs and real-world targets, we show that our system protects against the above mentioned information leaks while changing the functionality of the target program as little as possible. With our work we enable for the first time the protected use of existing components and thus a fast and cost-effective development of confidential programs.
Vertrauliche Software ist eine wichtige Voraussetzung für die fortschreitende Digitalisierung. Da Vertraulichkeit jedoch eine programmweite Eigenschaft ist, steht diese Anforderung im Widerspruch zur modernen Softwareentwicklung. Bestehende Softwarekomponenten von Drittherstellern werden regelmäßig in neue Produkte integriert, um Software kostengünstig und schnell entwickeln zu können. Folglich ist eine Methode erforderlich, um die Vertraulichkeit von Komponenten von Drittherstellern, die in der Regel in kompilierter Form ausgeliefert werden, zu gewährleisten. In dieser Arbeit stellen wir eine neue Methode vor, die die Vertraulichkeit für kompilierte Programme garantiert. Unser Ansatz schützt vor Informationsverlust durch Datenfluss, Kontrollfluss, Terminierungsverhalten und den Zeitpunkten der Ausgaben. Gleichzeitig wird eine Transparenz für pro Kanal erreicht, wodurch die Funktionalität der sicheren Komponenten erhalten bleibt. Unsere Lösung ist die erste praktische Anwendung des Konzepts der Secure Multi-Execution auf Maschinencode. Secure Multi-Execution ist ein Enforcement Mechanismus, der Vertraulichkeit per Konstruktion erreicht. Das Zielprogramm wird mehrfach ausgeführt, wobei jede Kopie einen eingeschränkten Zugang zu den Ein- und Ausgabekanälen hat. Allerdings ist diese Mehrfachausführung mit einem erheblichen Performance-Overhead verbunden.Daher präsentieren wir zwei Optimierungen, die die Effizienz des Schutzmechanismus erheblich steigern. Unser Prinzip ist es, redundante Berechnungen so weit wie möglich zu vermeiden. Einerseits zeigen wir, wie die Erstellung von Mehrfachausführungen durch unser dynamisches Instantiieren verzögert werden kann. Zum anderen zeigen wir, wie multiplizierte Ausführungen durch unser Bounding vorzeitig beendet werden können. Um die Sicherheitsgarantien von Secure Multi-Execution durch unsere Optimierungen nicht zu verringern, stellen wir zusätzlich eine neue Ablaufplanung für die Mehrfachausführungen vor. Diese Strategie ermöglicht es uns, einen unabhängigen Fortschritt der Ausführungen zu gewährleisten und gleichzeitig externe Abhängigkeiten in ihrem Ausgabeverhalten beizubehalten. Wir stellen auch unsere Beiträge zur statischen Analyse des Binärcodes vor, die als Grundlage für weitere Forschungen zur automatischen Bestimmung geeigneter Endpunkte für unsere Optimierungen dient. Wir haben unsere Methode erfolgreich auf das Linux-Betriebssystem und die weit verbreitete x86_x64-Architektur angewandt. Bei der Auswertung von Benchmarkprogrammen und echten Zielen zeigen wir, dass unser System gegen die oben genannten Informationslecks schützt und gleichzeitig die Funktionalität des Zielprogramms so wenig wie möglich verändert. Mit unserer Arbeit ermöglichen wir erstmals die geschützte Nutzung bestehender Komponenten und damit eine schnelle und kostengünstige Entwicklung von vertraulichen Programmen.