locksmith: secure android keystore based on virtualized

76
Locksmith: Secure Android Keystore Based on Virtualized Trusted Environments Luís Miguel da Silveira Freitas Fernandes Tonicha Thesis to obtain the Master of Science Degree in Information Systems and Computer Engineering Supervisor(s): Prof. Nuno Miguel Carvalho dos Santos Examination Committee Chairperson: Prof. Paolo Romano Supervisor: Prof. Nuno Miguel Carvalho dos Santos Member of the Committee: Prof. Bernardo Luís da Silva Ferreira November 2020

Upload: others

Post on 19-May-2022

12 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Locksmith: Secure Android Keystore Based on Virtualized

Locksmith: Secure Android Keystore Based on VirtualizedTrusted Environments

Luís Miguel da Silveira Freitas Fernandes Tonicha

Thesis to obtain the Master of Science Degree in

Information Systems and Computer Engineering

Supervisor(s): Prof. Nuno Miguel Carvalho dos Santos

Examination Committee

Chairperson: Prof. Paolo RomanoSupervisor: Prof. Nuno Miguel Carvalho dos Santos

Member of the Committee: Prof. Bernardo Luís da Silva Ferreira

November 2020

Page 2: Locksmith: Secure Android Keystore Based on Virtualized

ii

Page 3: Locksmith: Secure Android Keystore Based on Virtualized

Acknowledgments

I would like to start by thanking my professor Nuno Santos, whose expertise and guidance was invalu-

able. Furthermore, his patience and support were essential to me, as I’ve never tackled a project of this

complexity before. I dealt with several hardships thanks to his knowledge and availability.

I want to also thank and congratulate David Cerdeira (and his team), of Universidade do Minho, for

his excellent work on the main technology we are focusing this project on. Thank you for the unending

hours you spent debugging and improving the integration of your project with ours, and I hope the rest

of your doctorate keeps going as well as it is now.

To my sister and parents, that once more offered me their unconditional support, and always had my

back for the best and for the worst.

And last but definitely not least, I thank my friend Francisco Canana for his support and camaraderie

throughout this Master’s degree.

iii

Page 4: Locksmith: Secure Android Keystore Based on Virtualized

iv

Page 5: Locksmith: Secure Android Keystore Based on Virtualized

Resumo

O Sistema Operativo e tecnologia Android representam uma grande fatia do mercado de dispositivos

moveis. Estes aparelhos sao utilizados para guardar e trabalhar com informacao pessoal e privada.

Para proteger esses dados, o Android utiliza uma tecnologia chamada ARM TrustZone – uma arquitec-

tura de hardware que isola funcionalidades crıticas do resto do Sistema Operativo. Essas funcionali-

dades sao executadas num ambiente protegido por software altamente privilegiado chamado Trusted

Execution Environment (TEE). No entanto, este software tem sido alvo de ataques complexos, levando

a perdas catastroficas como a exposicao e hijacking do sistema de ficheiros Android cifrado e protegido,

resultando na divulgacao de chaves aplicacionais e material altamente confidencial. De modo a evitar

a utilizacao de codigo especıfico a determinadas aplicacoes dentro do TEE, propomos o Locksmith –

uma arquitectura de seguranca para o modulo de seguranca Keymaster, que atraves de um hipervi-

sor leve, usa uma enclave de confianca onde operacoes de carater confidencial realizar-se-ao e onde

chaves/segredos serao armazenados. A nossa arquitectura demonstra que a migracao de algumas

operacoes crıticas outrora realizadas dentro da TEE podem ser migradas para enclaves suportados por

um hipervisor. Esta abordagem tem por efeito uma reducao da superfıcie de ataque da TEE e portanto

um incremento da seguranca do dispositivo movel.

Palavras-chave: Android, Seguranca, TEE, TrustZone, Keymaster, Enclave

v

Page 6: Locksmith: Secure Android Keystore Based on Virtualized

vi

Page 7: Locksmith: Secure Android Keystore Based on Virtualized

Abstract

The Android Operating System has been adopted by a large share of the mobile device market. An-

droid devices are widely used for storing and processing personal and privacy-sensitive information.

To protect such data, Android uses a technology called ARM TrustZone – a hardware architecture that

isolates critical operations from the rest of the Operating System. Such operations are executed inside

a protected environment which is maintained by highly privileged software named Trusted Execution

Environment (TEE). However, this kind of software has increasingly been the target of complex attacks,

leading to catastrophic losses such as exposure and hijacking of the encrypted and protected Android

file system, resulting in the disclosure of application keys and highly confidential data. To avoid using

specific code for certain applications within the TEE, we propose Locksmith – a security architecture

for the Keymaster security module, which, by leveraging a light hypervisor, creates a reliable enclave

where confidential operations will take place and where keys/secrets will be stored. Our architecture

demonstrates that the migration of some critical operations that were formerly performed inside the TEE

can be safely migrated into enclaves backed by a hypervisor. This approach brings about a reduction in

the attack surface of the TEE thereby increasing the overall security of Android mobile devices.

Keywords: Android, Security, TEE, TrustZone, Keymaster, Enclave

vii

Page 8: Locksmith: Secure Android Keystore Based on Virtualized

viii

Page 9: Locksmith: Secure Android Keystore Based on Virtualized

Contents

Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii

Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v

Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii

List of Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi

List of Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii

Nomenclature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1 Introduction 1

1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.2.1 Contributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.3 Document Outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Background 5

2.1 ARM TrustZone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.1.1 Android Security Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.1.2 Android Keystore Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3 Related Work 13

3.1 Communication Between Worlds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.2 Simplifying Trust Inside the TrustZone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.3 Virtualizing ARM TrustZone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.4 Integrating TrustZone With a Mobile Operating System . . . . . . . . . . . . . . . . . . . . 16

3.5 Software Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3.6 User-space Enclaves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.7 Kernel-level protection for ARM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4 Architecture 23

4.1 Motivational Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

4.2 Threat Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

4.3 Locksmith Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

ix

Page 10: Locksmith: Secure Android Keystore Based on Virtualized

4.3.1 Locker: Intercepting Keymaster Calls . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4.3.2 Bao: Containing Code and Data inside Enclaves . . . . . . . . . . . . . . . . . . . 27

4.3.3 Lockpick: Guaranteeing Functionality inside a Minimal Environment . . . . . . . . 27

4.4 Initial System Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.5 System Bootstrap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

4.6 Lockpick API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

4.7 Communication between Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

4.8 Storage and Persistence of Key Material . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

5 Implementation 35

5.1 Initial Prototypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

5.1.1 Emulating Enclaves via QEMU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5.1.2 Communication between Software Keymaster and the Emulated Enclave . . . . . 36

5.1.3 Modifying Android Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

5.2 Locker Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

5.2.1 Choosing a Design Pattern for the Locker Code . . . . . . . . . . . . . . . . . . . . 39

5.2.2 Handling Keymaster API Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

5.3 Lockpick Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

5.3.1 Implementing Lockpick as a Rust Library . . . . . . . . . . . . . . . . . . . . . . . 41

5.3.2 Lightweight C Binary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5.4 Locksmith Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5.4.1 Deploying Locker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

5.4.2 Preparing Lockpick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

5.5 Issues with Bao Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

6 Evaluation 47

6.1 Evaluation Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

6.2 Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

6.2.1 Global Benchmarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

6.2.2 Micro Benchmarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

6.3 TCB Size and Memory Footprint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

6.4 Security Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.4.1 Effective Security Guarantees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.4.2 Non mitigated attacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

7 Conclusions 55

7.1 Achievements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

7.2 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

Bibliography 59

x

Page 11: Locksmith: Secure Android Keystore Based on Virtualized

List of Tables

2.1 Keymaster functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

4.1 Lockpick API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

6.1 System’s global benchmark. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

6.2 RTT/Communication establishment benchmark. . . . . . . . . . . . . . . . . . . . . . . . . 51

6.3 Locksmith codebase statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

xi

Page 12: Locksmith: Secure Android Keystore Based on Virtualized

xii

Page 13: Locksmith: Secure Android Keystore Based on Virtualized

List of Figures

2.1 Cortex-A TrustZone. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.2 Architecture of the Android Keystore service. . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.1 SeCReT design overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.2 Pearl-TEE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.3 vTZ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.4 PrivateZone architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3.5 Samsung’s KNOX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3.6 Sanctuary overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.7 SKEE’s design. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.1 Secure authentication and communication between a user and an online banking service. 24

4.2 Man-in-the-middle attack via certificate forgery. . . . . . . . . . . . . . . . . . . . . . . . . 24

4.3 Locksmith architecture: its specific components are highlighted in yellow. . . . . . . . . . 25

4.4 Initial Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.5 Possible Keymaster devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

4.6 Bao’s communication architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4.7 Storage solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

5.1 Android running Debian via QEMU. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5.2 Initial protocol’s main loop. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

5.3 First prototype’s structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

5.4 Locker singleton object. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

5.5 liblockworker’s basic state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5.6 The import function and unsafe tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

5.7 Lockpick’s build process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

5.8 ROCK960 development board. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

6.1 Keystore testing Application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

6.2 Simple speed measurement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

6.3 Micro/API benchmarks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

xiii

Page 14: Locksmith: Secure Android Keystore Based on Virtualized

xiv

Page 15: Locksmith: Secure Android Keystore Based on Virtualized

Chapter 1

Introduction

Personal mobile devices are becoming increasingly more ubiquitous and as such, users are trusting

these devices with sensitive and confidential data due to its convenience and portability. They are seen

as everyday utilities, and users might not even realize the amount and quality of the information they

store and access on their personal devices.

Simultaneously, defensive measures need to keep evolving – as users get exposed to more complex

threats, they don’t necessarily become more aware of them. Studies [1] show that users in general

have a lax policy regarding security measures, and are more worried with malware from applications

they install than targeted information theft. For example, Mylonas et al. [2] report that official application

repositories are trusted blindly and most security messages on permission oriented systems such as

Android are disregarded. This also happens with more “obvious” security measures such as locking

mechanisms – many users still underestimate the extent and nature of the data they are storing and

choose to not use any authentication system [3]. Alsaleh et al. [4] also confirm that the usefulness and

convenience of applications affect users’ decision to act in a safe manner. Mobile technology keeps

evolving and user awareness needs to be constantly growing in order to avoid problems as these.

However, user awareness alone is not enough. The Google Android team stays pushing for stronger

security on each Android release, but “pure” Android phones are a small minority, and vendors tend to

keep their implementations behind a proprietary wall, often not disclosing major flaws until it’s too late.

All of these factors motivate the need to develop a more robust security system, since there is a limit

on the effort that is educating users of good security practices. This thesis aims at contributing to the

enhancement of the security mechanisms of modern Android platforms.

1.1 Motivation

Currently, Android is the most widely-deployed, user-centered operating system (OS) [5] for mobile

devices. It provides a common interface for global users to interact with digital services, across a range

of different form factors. Android is designed to achieve a mix of security and usability, while addressing

a host of practical threats in various scenarios and being useful to regular, non-tech-savvy users.

1

Page 16: Locksmith: Secure Android Keystore Based on Virtualized

From the security perspective, ARM TrustZone technology plays a fundamental role in the Android

OS. Today, this mobile operating system depends on a Trusted Computing Base (TCB) which starts with

the boot loader (which in itself represents multiple stages), and includes the Linux kernel and other priv-

ileged components of the Android framework, including hardware drivers and userspace components.

The TCB also includes software components allocated inside a Trusted Execution Environment (TEE)

provided by ARM TrustZone technology. The TEE aims to provide defense mechanisms against a poten-

tial security breach in the Android OS kernel. In particular, Android uses a mobile phone’s TEE to host

isolated security modules such as the Keymaster and Strongbox. Keymaster, for instance, is a Keystore

implementation that runs inside a TEE, typically inside ARM TrustZone’s security world, which protects

cryptographic keys and confidential data, meaning that even an attacker that compromises the kernel of

the Android OS cannot access this sensitive material.

However, despite the security benefits of TrustZone-assisted TEEs, there are also risks involved.

Even though this technology has been around for more than a decade now, only in the recent years

have TrustZone-based TEEs seen an increase in overall interest, mostly due to its low exposure to the

world outside vendor development. Software development for TEE has been largely kept “private” by

vendors, and it essentially consists in the implementation of applications named Trusted Application (TA).

TAs run inside the TEE, and have typically to deal with security-sensitive data: some TAs implement OS-

level logic, such as Android’s Keymaster; others implement user-level logic, e.g., mobile payments, DRM

protection. Unfortunately, recent studies [6] show that TAs often contain critical security vulnerabilities

which can lead malicious actors to exploit and perform privilege escalation attacks, extract confidential

data or even compromise the entire system, due to the privileged nature of this ecosystem. Moreover,

TAs are also growing in number, thereby increasing the TCB size and the attack surface.

1.2 Objectives

The goal of this work is to reduce the attack surface of current TrustZone-aware TEEs by displacing TA-

specific logic from the highly-privileged secure world into less-privileged sandboxes instantiated in the

normal world. This approach would reduce the attack surface of a potential adversary by restricting the

opportunity to exploit a vulnerability inside the TEE and escalate privileges to control the whole Android

OS. To demonstrate the benefits of this approach, we propose to implement a secure Keymaster for

Android that does not require to run a Trusted Application code inside TEE, and yet offers similar or

even stronger security guarantees for end-users. By showing that this engineering can be performed for

such a critical OS module as the Android’s Keymaster, we demonstrate that this architecture is general

and that it can be applied for arbitrary user-level TAs.

Concretely, we aim to design, implement, and evaluate Locksmith, a security architecture for Android

devices, which doesn’t use any TEE or Trusted Applications, and instead executes Keymaster inside

a protected environment – an enclave, created by a lightweight hypervisor. This way it runs entirely

separated of the rest of the system, with its own CPU core and memory region. With this we are trying

to ensure that there is no way of tampering sensitive/private material typically stored in a TEE, even if

2

Page 17: Locksmith: Secure Android Keystore Based on Virtualized

the rest of the machine is compromised.

Furthermore, to reduce the chance of vulnerabilities in the code responsible for performing encryption

and key management operations, we aim to implement it in Rust [7], a modern systems programming

language with security as one of its pillars, featuring capabilities like memory safety and automatic bound

checking, leading to much fewer developer mistakes and increased performance.

1.2.1 Contributions

This work focuses on improving the current Keymaster system and overall Android security architecture

by building Locksmith. Specifically, we produce the following contributions:

• Improvement of the integrity, confidentiality, and privacy of data on Android devices by developing

a new Keymaster security component, using a modern and safer programming language;

• Detachment of Android key management/storage from TEE;

• Isolation of the developed components and the rest of the device;

• No significant performance overhead over the existing solutions;

• A thorough experimental evaluation simulating real workloads and different environments

1.3 Document Outline

This thesis is structured in the following manner. Chapters 2 and 3 lay the foundations for our project,

providing theoretical and practical background and showcasing relevant work done in this field, where

the Android Operating System is dissected from a security point-of-view. Chapter 4 presents the pro-

posed architecture of Locksmith, and the following Chapter 5 the steps needed to implement it and the

reasoning behind our choices. Finally, Chapter 6 presents our experimental evaluation of the whole

system and Chapter 7 concludes this report and presents ideas to enhance Locksmith in the future.

3

Page 18: Locksmith: Secure Android Keystore Based on Virtualized

4

Page 19: Locksmith: Secure Android Keystore Based on Virtualized

Chapter 2

Background

This section provides some necessary background information in order to understand our work. It spans

several technological domains from low level hardware technology like the TrustZone to the Android

Operating System, whose security principles must be understood to justify our architectural choices.

We finish this chapter by introducing the key component in Android security, the Keystore.

2.1 ARM TrustZone

ARM is one of the most licensed and used microcontrollers in the world. These processors are used in

a range of settings and devices, from mobile phones to medical devices and other embedded systems.

Their low power usage and reasonable performance make them an attractive architecture for mobile

devices, since these are two main factors that users search for.

There have been several generations of ARM cores, and the most recent one is the Cortex series,

comprised of the Cortex-A, Cortex-M and Cortex-R microarchitectures. The first one is specially im-

portant since it is an application processor designed to run fully fledged Operating Systems, supporting

both 32 bit (ARMv7) and 64 bit (ARMv8) applications. The less powerful Cortex-M is sometimes used

to complement another processor, for example on a System-on-Chip dedicated to cryptographic opera-

tions [8].

The sensitive and private data of personal devices has made them attractive targets for malicious

actors, which has led to the development of security measures on all layers of these devices. Well

developed applications and a robust OS are not enough if the base of the “trust chain” is compromised.

In order to harden these devices, ARM developers sought to develop a hardware technology, de-

ployed first in 2004 on ARM Cortex-A processors [9]. It is a system-wide approach at the hardware level

that uses the concept of a normal and secure worlds, shown in Figure 2.1. This means that any software

running on a processor with TrustZone is either on a normal/non-secure state or in a secure state.

The secure world is a “mirrored” version of the normal world, which means it also has applications

running on an operating system (normally a much smaller sized one). It hosts a Trusted Execution

Environment, which will later be explored.

5

Page 20: Locksmith: Secure Android Keystore Based on Virtualized

Secure Monitor

Non-Secure (Rich)OS

Non-SecureApplications

NormalWorld

SecureWorld

Secure OS

Secure Applications

Figure 2.1: Cortex-A TrustZone.

Context switching between the two worlds is provided on demand by a Secure Monitor, running

typically on EL3. A Secure Monitor Call instruction is issued every time a component on the normal

world needs to perform security-sensitive operations, switching to the secure world, which is also used

to switch back.

TrustZone technology and its security extensions facilitates the development of security applications

on the ARM architecture, and so it has seen a plethora of several use cases. Software frameworks like

TrustFrame [10] and even a full .NET mobile runtime [11] were developed for safer and faster TrustZone

development. Regarding software isolation, several tools like ARMlock [12], NaCL [13] and ARMor [14]

make use of the TrustZone’s sandboxing capabilities to protect a running Real Time Operating System

and its critical loops while keeping control-flow and and memory integrity.

Regarding virtualization, Sandro et al. [15] worked on the possibility of the TrustZone providing a

hardware-based form of system isolation and proposed an architecture consisting of a Virtual Machine

for each one of the world states, controlled by a hypervisor working above the Secure Monitor. This ar-

chitecture, with some modifications, is in part what Android devices use nowadays – a Trusted Execution

Environment supervised by a hypervisor above the hardware.

2.1.1 Android Security Model

So far we have explored security measures deployed at the hardware level. Hardware is the start of the

trust chain, however security measures need to reach all layers and components of the device. In the

following section we will explore Android’s security architecture and some of its most important features,

which need to be understood in order to maintain and improve upon them.

6

Page 21: Locksmith: Secure Android Keystore Based on Virtualized

Android ecosystem:

Android developers recognize the need for a mutual growth between all parties involved with the sys-

tem [5]. This means that their platform must have an environment that is safe by default, and the

meaningful parties (end users, developers and the OS) can have beneficial terms of engagement. If

by any reason these parties cannot reach an agreement on a certain action, then the security model is

designed to prohibit said action (default-deny).

Since Android is an operating system focused on the end user, it aims for simplicity while being

remaining attractive to developers. Being the user the primary target, Android’s interfaces and user

experience need to be secure by default and ask for explicit consent for actions that may be a threat to

the user’s privacy or security. Non-expert users should not have to deal with technical security questions

since they may not be able to answer in a safe way.

Due to the immense adoption of Android devices, which encompasses hundreds of different OEMs

and OMDs, devices using Android as a trademarked name need to pass a Compatibility Test Suite so

developers can deploy to a multitude of different devices. Applications can also be developed in any

language, as long as they have a Java wrapper which can bootstrap and interact with the OS. This

allows for greater flexibility when designing applications while keeping safety and boundary checks in

runtime.

Android security principles:

There are major principles on which Android’s security model is based on. First, agents control access

to data that they create. This means that any agent that creates a data item has implicit control over it.

Second, consent is informed and explicit. Consent decisions should be based on information about the

action about to be taken and must have meaningful ways of being granted or denied.

Another principle is that by design, any component should respect security and privacy assumptions,

even if it means blocking potentially harmful use cases. This serves as an incentive for developers and

device manufacturers to refine and work on new interfaces deemed more secure.

Finally, Android aims to achieve defense in depth – its approach on security makes it that even if a

security assumption fails or has any bugs, it will not compromise the rest of the system. This is specially

important due to the huge variety of environments that Android runs on and the different approaches

that application developers and device vendors can take on.

Authentication:

The main authentication method on mobile devices is the lockscreen. Lockscreens on other mobile

devices nowadays use mostly a binary model: either the device is fully accessible or most functions,

especially privacy sensitive ones like telephony, are disabled. Since end users want fast interactions with

their mobile phones and not be hindered by long passwords, but still need some for of authentication

(swipe-only lockscreens are not safe at all), a balance between usability and safety is essential.

7

Page 22: Locksmith: Secure Android Keystore Based on Virtualized

Android achieves this with tiered authentication: a knowledge-factor based authentication system

that can be used with convenient mechanisms constrained by the level of security they offer. A pri-

mary authentication provides access to all functions of the device, which by default include PIN, pattern

and password methods. Secondary authentication are biometrics considered strong enough that they

unlock most features yet critical operations, like file-based or full-disk decryption aren’t still accessible.

Finally, tertiary authentication is left for “weak” biometrics or alternative unlocking methods, e.g., use a

bluetooth-paired device.

Isolation:

One of the most used security techniques used by the Android infrastructure is sandboxing, which occurs

not just in applications [16] but in other layers of the system. The original Discretionary Access Control

(DAC) [17] sandbox created a barrier between apps and the system by providing each one with an

unique UNIX user ID and a directory owned exclusively by that user.

This approach comes with a number of disadvantages, such as processes that ran as root were

not isolated at all and could manipulate apps, the system and confidential data. However on recent

Android releases, following applications, system processes get sandboxed too, which limits a set of

UID sandboxes for several system processes. Other important processes such as WiFi, Bluetooth and

telephony have UID isolation too.

Below the application layer which gets increasingly more secure, the kernel starts becoming an

alluring target for privilege escalation attacks [18]. With this in mind, Android uses technologies like

TEEs and the TrustZone to mitigate attacks on the kernel.

Data encryption:

Data encryption is needed in order to enforce the security model, especially the “all actors consent”

tenet. Android has had Full Disk Encryption (FDE) since version 5.0, which is a mechanism that through

a credential protected key encrypted the entire user data partition. One of the main disadvantages of

this method is that some important parts of the device, like the emergency dialer, remained inaccessible

until the user unlocked it.

Android 7.0 introduces File Based Encryption (FBE), which allows encryption of specific files for

multiple users, effectively protecting data on a per-user basis. In contrast to FDE, devices with FBE can

get their keys derived from a TEE or similar environment, which strengthens the system a lot by mixing

hardware-bound cryptography (inaccessible to the kernel and above) and user knowledge. Direct Boot,

which comes with FBE, removes the restriction on using basic functions with a locked screen. Regarding

encryption at the network level, Android provides and promotes the use of TLS options, since link level

encryption is insufficient.

8

Page 23: Locksmith: Secure Android Keystore Based on Virtualized

Figure 2.2: Architecture of the Android Keystore service.

System integrity:

Android supports Verified Boot and the dm-verity kernel feature since version 4.4. This ensures that all

executed code comes from a trusted source, establishing a full chain of trust, starting from the hardware

and its lower level components, to important partitions like system and vendor. During boot, each stage

verifies and authenticates the next stage before proceeding.

Verified Boot also employs rollback protection, which checks if the correct version of the OS is run-

ning, ensuring devices only update to a newer version and can be used to inform the user of the integrity

of the system. Furthermore, starting on Android 7.0, compromised devices aren’t allowed to boot and

forward error correction has been deployed to tackle non-malicious data corruption.

2.1.2 Android Keystore Service

From the application point of view, Keystore is the library responsible for storing private keys in a con-

tainer, protecting key material from unauthorized use. However this is just the high level interface ex-

posed to clients, since Keymaster (Figure 2.2), is the underlying component that performs these ser-

vices.

The current ecosystem, Figure 2.2, can be split in two worlds: the normal world, also known as

legacy world, where the Android stack and Linux Kernel resides, and a secure world, which runs inside

a TEE. Hardware wise, the TEE is normally implemented based on ARM TrustZone technology.

The normal world contains the Android operating system and all its components, such as user ap-

9

Page 24: Locksmith: Secure Android Keystore Based on Virtualized

plications and system services. We’re interested specifically in the Keymaster, which performs security

services such as accessing and storing confidential data.

Keymaster is divided into several parts, starting with Keystore, which is the Java library that user

applications interact with. After an API call is performed from an application, the Keymaster Hardware

Abstraction Layer (HAL) – which is an OEM-provided, dynamically loadable library – marshals this re-

quest, with semantics defined in a generic HIDL (HAL language), to a specific kernel driver.

This driver works as a secure channel between the normal and secure world. The Keymaster allows

custom implementations of the underlying API via the HAL. The functions that a working Keymaster

(version 3) should support, along with a brief explanation, are represented in Table 2.1. Normally, as

explained next, Android provides two underlying Keymaster implementation: a hardware-backed one

that resides in the TEE, and a local implementation inside the Android OS.

Hardware-backed Keymaster:

Before Android 6.0, Keystore already supported digital signing and verification operations, and the gen-

eration and import of asymmetric key pairs. With this version came support for symmetric cryptographic

primitives (AES and HMAC) and an access control for hardware-backed keys.

Devices with TEEs (the majority nowadays) such as the one provided by TrustZone can use the

Hardware Abstraction Layer to communicate with the normal world and vice-versa, so confidential ma-

terial like encrypted blobs and keys never leave the secure world, which are handled by Keymaster’s TA,

as shown in Figure 2.2. No security sensitive operations happen outside the TEE.

API Function DescriptiongetHardwareFeatures Returns characteristics about the underlying secure hardwareaddRngEntropy Adds caller-provided entropy to the pool for generating random numbersgenerateKey Generates a new cryptographic keygetKeyCharacteristics Returns parameters and authorizations associated with the provided keyimportKey Imports key material into Keymaster hardwareexportKey Exports a public key from a Keymaster RSA or EC key pairdeleteKey Deletes the provided keydeleteAllKeys Deletes all keysdestroyAttestationIds Permanently disable the ID attestation featurebegin Begins a cryptographic operationupdate Provides data to process in an ongoing operation started with “begin”finish Finishes an ongoing operation started with “begin”abort Aborts the in-progress operationget supported * Returns the list of algorithms/modes/formats supported

Table 2.1: Keymaster functions.

Softkeymaster:

Before hardware-backed cryptography became common in mobile devices, the original Keystore imple-

mentation worked as a single daemon which managed key blobs and encryption in a single binary. With

10

Page 25: Locksmith: Secure Android Keystore Based on Virtualized

Android 4.1 came the HAL [19], a global interface that allowed third party vendors to interact with their

own Keymaster implementations through a standardised format.

In order for the HAL to work on devices with no hardware-backed implementations, a softkeymaster

software module performs all key operations using the OpenSSL library and without any hardware de-

pendencies. To the best of our knowledge, this module is present up until Android 8.1, and no longer

present after.

Summary

In this chapter we presented the main concepts and technologies that serve as a theoretical background

needed to understand our work. We deconstructed the Android Security Model and its tenets, after

which we provided insight on the current embedded systems state-of-the-art technology, the TrustZone,

finishing with a brief explanation on the Keystore/Keymaster symbiosis. In the next chapter we present

alternative solutions to some of the flaws our project is targeting.

11

Page 26: Locksmith: Secure Android Keystore Based on Virtualized

12

Page 27: Locksmith: Secure Android Keystore Based on Virtualized

Chapter 3

Related Work

A Trusted Execution Environment, or TEE, is a special, integrity-protected environment with common

capabilities such as processing, memory and storage [20]. Even though these solutions do not directly

affect the internal workings of the Android security model, all of them can be adapted for deployment on

mobile devices running modern hardware and the Android OS.

In this chapter, we will explore the impact and flaws of the TrustZone/TEE architecture and some

proposed solutions in related work, alongside a comparison with our own work.

3.1 Communication Between Worlds

Communication between the REE (the “Rich” Execution Environment) and TEE is not supervised by

TrustZone. The current architecture does not authenticate the access to its resources, so a process in

the REE that wants to use them needs to ask another process to open a channel of communication.

This special process then synchronously invokes a specific instruction with the arguments written on

domain-shared memory leading to a channel between the requesting process and the TrustZone getting

opened. However, an attacker with kernel privilege in the REE can still create a process that crafts

malicious requests to that channel in order to access TrustZone resources.

Jang et al. propose SeCReT [21], which works by creating a session key to sign the messages sent

during inter-domain (REE and TrustZone) communication. This session key is symmetrically assigned

for both the REE and TrustZone. It verifies every access to the memory page that contains the session

key, ensuring only predefined and legitimate user processes can read it, as seen in Figure 3.1.Every

time the processor mode switches to kernel, the session key memory page gets flushed and shadows

the register values, in order to prevent an attacker from reading it directly. Additionally, registers that

contain critical values like return addresses are verified by the framework.

Keymaster relies on communication with its TA counterpart for most of it services, since the con-

fidential data and services reside in the TEE. SeCReT presents an additional layer of security while

communicating with the TrustZone, which makes sure its resources are only accessed by authorized

users. This strengthens TrustZone usage but still relies on it heavily and our solution aims to reduce

13

Page 28: Locksmith: Secure Android Keystore Based on Virtualized

dependency on the TEE. By having Keymaster working solely on the “pseudo” normal world that our

hypervisor will provide, no special measures like SeCReT will be needed.

Figure 3.1: SeCReT design overview.

3.2 Simplifying Trust Inside the TrustZone

Even though its present in most recent smartphones, neither Android nor iOS expose a public API that

enables application code to access the TrustZone. Many commercially deployed TEE OSes do not allow

any third party applications, or have a development and deployment process so complicated that it does

not provide any incentives for developers wanting to work with them.

Also, unlike third-party applications that can freely be installed in an Android device, TAs need mutual

trust between all of them, so third-party applications can’t be installed at all. This is partly due to vendors

fearing that their TEE OS will not stand against intentional attacks from applications, so small size and

simplicity is preferred to maintain the high-assurance level of the TEE OS.

Huang et al. [22] developed Pearl-TEE, Figure 3.2, which removes the need for applications to mu-

tually trust each other. It defines an abstract TEE application model, which encompasses the types of

applications that can benefit from TrustZone’s security guarantees. Four types of applications are de-

fined: key storage; integrity and confidentiality; secure communication with a server and with a user. For

app isolation, Pearl-TEE runs on EL1 while the apps run on EL0. To prevent denial-of-service attacks, it

implements batch scheduling, which in absence of user interaction, each application gets a fixed amount

of time to run before another app takes it place.

Additionally, it also provides a storage implementation that’s optimized for storing keys (which is

mainly what Trusted Applications need to store) – each app gets an application-specific key that depends

on the Pearl-TEE master key (only accessible to the OS via secure boot), generated by encrypting the

14

Page 29: Locksmith: Secure Android Keystore Based on Virtualized

Pearl-TEE OS

TEE Applications

Secure Element

Pearl-TEE Master Key

OS

User Applications

File system

Public Key of TrustedApplications

Network Stack

Pearl-TEENormalWorld

ARM & Secure Input

Application Servers

Private Key ofTrusted

Applications

Syscall Bridge

Figure 3.2: Pearl-TEE.

hash of the app itself with the master key. This way it reveals nothing about the master key while being

unique for each application. The OS can then use that application key to cipher and sign data that needs

to be stored in the normal world OS.

The authors report a TCB increase of just 3% and a processing overhead of under 20%. With this

model, Keymaster’s services could be broken down in to several Trusted Applications, depending on the

services that were being fragmented. This however, would just increase the dependency on the TEE

OS and its underlying limitations. For example, communication from the normal to the secure world isn’t

hardened, and an attacker could target and snoop this channel in order to find secrets.

3.3 Virtualizing ARM TrustZone

Typically, mobile phones have a device dependent, vendor deployed TEE-kernel, inaccessible in any

way after deployment. Even though there are open implementations, vendors like Samsung, Apple and

Huawei use their own TEE kernel, leading to exploits avoidable with proper collaboration [23–26]. No

third party TEE kernels can be installed (even after iOS jailbreak or Android root), leaving end-users

open to these attacks until they are patched. Since each TEE has a specific rootkey, and this key

authenticates all Trusted Applications, a new Trusted Application needs to be signed by the root key in

order to run on that specific device’s TEE. Furthermore, the TrustZone is designed to run exactly one

TEE, provided by hardware, which makes it impossible to run TEEs with different purposes.

Hua et al. [27] aim to safely provide virtualization of TrustZone while maintaining strong isolation

between guest TEEs. The proposed idea is splitting functionality from security by keeping one secure,

co-running VM to serve as a guest TEE, while utilizing the TrustZone to enforce isolation among the

guest TEEs and the running, untrusted hypervisor, as seen in Figure 3.3. They leverage a tiny monitor

inside the physical TrustZone that virtualizes and interposes world switching and memory mappings.

This way, more than one TEE is allowed to run on the device, with an acceptable overhead and strong

15

Page 30: Locksmith: Secure Android Keystore Based on Virtualized

Non TEE Virtual Machine

Hypervisor

OS

User Applications

NormalWorld

SecureWorld

TEE Virtual Machine

Trusted OS

TrustedApplications

IsolatedEnvironment

Secured Modules(TCB)

Figure 3.3: vTZ.

isolation.

vTZ further leverages a few pieces of protected, self-contained code running in a Constrained Iso-

lated Execution Environment (CIEE) to provide secure virtualization and isolation among multiple guest

TEEs.

To enforce the booting integrity, the authors use the secure world to check the booting sequence,

as well as to perform integrity checking. Furthermore, vTZ uses Secured Memory Mapping, a module

in the secure world, to control all the stage-2 translation tables as well as hypervisor’s translation table,

providing efficient memory protection.

While leveraging several TEEs increase the user freedom and effectively stops malicious virtualized

TEEs from reaching other environments, it still poses all the disadvantages of relying solely on the

TrustZone: vendors can still deploy bug ridden TEEs, and inside them the Keymaster TA can still be

targeted.

3.4 Integrating TrustZone With a Mobile Operating System

Android applications leverage the TEE either by trusted applications being directly developed by the

vendor or developers have access to vendor’s SDK. Both of these solutions are a hindrance to TrustZone

adoption and development, since they are limited to the vendor’s interests (which are mainly commercial)

and most of the time they are behind a heavy paywall (access to vendor SDKs can cost thousands).

Aggravating this is the fact that TrustZone is locked down in commercial phones before shipment so no

code changes can happen in the actual end-user product.

Ying et al. [28] propose TruZ-Droid. It enables TrustZone support at the OS level, letting apps reuse

existing Android components for a smooth integration with TrustZone. To do this, two modules were

developed. At the user input level, TruZ-UI provides cross-OS binding support between secure world

UI interaction and normal world app code. A Keyboard Input trusted application gets the user input

16

Page 31: Locksmith: Secure Android Keystore Based on Virtualized

OS PrEE KernelComponents Trusted OS

Normal World

User Applications PrivateZone-awareApplications

PrEE

SecurityCriticalLogic

TEE

TEEServicesControl Flow

PrivateZoneFramework

Monitor Switch

UserMode

KernelMode

MonitorMode

Software-basedIsolation

Hardware-basedIsolation

Figure 3.4: PrivateZone architecture.

via the trusted world which it then stores. In order for user apps to use this sensitive data, TruZ-HTTP

establishes a secure HTTPS connection between the app and its destination server, performing the SSL

protocol in the secure world too.

TruZ-Droid aims for a seamless integration of the TrustZone by allowing developers to access its

functionalities without any app logic inside the secure world. While this simplifies application develop-

ment, security-sensitive operations, like user input from the keyboard, it still relies heavily on the TEE

and specific trusted applications.

Jang et al. solution [29] creates an exclusive zone (PrEE) between the Rich OS (REE) and Secure

OS (TEE). PrivateZone allows for developers to protect and execute specific code inside this privileged

area. It utilizes ARM virtualization extensions so that during secure boot, two stage-2 page tables are

created for the PrEE and REE, thereby providing context switching between the three logical environ-

ments, represented in Figure 3.4. The TEE is physically isolated from the PrEE and REE, thanks to a

hardware-based access-control mechanism. A PrivateZone Library provides developers several opera-

tions that can be utilized to build PrivateZone-aware applications.

This approach is a radical one, since it essentially replaces the TrustZone by an architecture some-

what similar but more friendly to application developers. However, like stated, part of the TEE is still

used and now it needs manual validation by vendors before framework deployment. Additionally, be-

cause the current PrivateZone prototype does not support multi-threaded applications, this would hinder

most of Keymaster’s cryptographic operations. Overall, PrivateZone represents an increase in the TCB

that Locksmith won’t have since it operate in a trusted enclave.

3.5 Software Containers

Over the past years, there has been a growing trend among enterprises of “Bring Your Own Device”,

which means workers being encouraged to use their personal phones to work – running enterprise

17

Page 32: Locksmith: Secure Android Keystore Based on Virtualized

software on their own machines. This keeps employees satisfied and productive, now that they can work

from anywhere. However, this also means having to deal with security policy enforcement, lost/stolen

devices with sensitive information and common threats like unsafe networks and malware.

Samsung’s KNOX [30] deploys a secure environment alongside the user’s environment, much like

a TEE. Depicted in Figure 3.5, it is a multi layer architecture that deploys several technologies, each

one secured by its predecessor. SEAndroid makes use of SELinux to enforce a fine-grained security

policy. TIMA, makes use of TrustZone’s feature to mainly perform periodic validations on the kernel code

and data (PKM) and the main element, Real-time Kernel Protection, which does several tasks, mainly

protecting memory pages from normal world reads all while logging everything, and setting the “warranty

bit” in case of device compromise.

Samsung’s solution is a fully fledged security model, with major changes to Android’s original security

platform. It makes no changes to the Keymaster system, but it’s used for security sensitive data, whose

applications run alongside the user environment.

This creates a constant security threat, because the container needs to check data from the within

too and not just from outside. The fact that it depends on a strong chain of trust between components,

starting on SEAndroid, exposes it to a bigger attack vector, like shown in early exploits [31–33].

There is another problem surrounding this solution, which is the authentication process. It requires

both a password and a PIN to launch secured apps and access files in a Knox container. In case the

user forgets this password, the user is prompted to enter an assigned PIN in order to get a hint for

the password. This hint generates the first and last character of the forgotten password, as well as the

total number of characters. This leads to a much smaller search space which could be guessed by a

malicious actor.

Furthermore, this PIN is stored in a plaintext format, inside Knox’s support application, which could

also be targeted and easily obtained.

Overall, this system is quite complex and ambitious, targeting every layer of the Android Operating

System, which in the end amounts to a big Trusted Computing Base, unlike our proposed solution.

Figure 3.5: Samsung’s KNOX.

18

Page 33: Locksmith: Secure Android Keystore Based on Virtualized

3.6 User-space Enclaves

Another way to tackle the constrained use of TEEs and avoid strict deployment policies imposed by

device vendors is the creation of user-space enclaves. Brasser et al. propose Sanctuary, a novel system

architecture that allows unconstrained use of TEES in the TrustZone, without relying on virtualization

[34].

Sanctuary inherently de-privileges TrustZone enabled apps by moving them away from the secure

world to a special, isolated normal world division, thereby reducing the code based exposed in the

secure world. The authors call these special, security sensitive applications, “Sanctuary Apps” (or SA

for short), similar to Intel SGX’s user-space enclaves, represented in Figure 3.6.

These applications are isolated by partitioning and re-allocating system resources dynamically. Pro-

cessor cores and physical memory are temporarily exclusive for the isolated compartments to execute

SAs without halting the rest of the system. Particularly, they leverage the TrustZone’s Address-Space-

Controller (TZASC) to guarantee a hardware-enforced, two-way isolation between Sanctuary Applica-

tions and all the other system components.

The initial content of an SA gets loaded from normal, unprotected memory – therefore it can be

manipulated and should not contain any sensitive data. In order to counter this, Sanctuary provides

a mechanism to ensure the integrity and authenticity of an SA. This is achieved by a set of Trusted

Applications, providing security services, running in the secure world OS.

The first TA provides remote attestation. Through the TZ’s platform identity feature, an authentic

report of the system’s integrity can be delivered to a third party, creating a secure and authenticated

channel where critical data can be sent.

The second security service is Sealing, which allows SAs to store sensitive data in a way that just

instances of the provided SA can access that data. The system provides each SA an encryption key

unique to it by hashing its contents, a mechanism typically used for this kind of operation.

Overall, this system is a less intrusive approach compared to the previous one, and shares a lot

of similarities with our chosen hypervisor. However, it still focuses on the use of TEEs, choosing to

“containerize” its contents.

Figure 3.6: Sanctuary overview.

19

Page 34: Locksmith: Secure Android Keystore Based on Virtualized

3.7 Kernel-level protection for ARM

To conclude this study on methods to harden ARM systems employing TrustZone technology without de-

pending on Trusted Execution Environments, we examine a novel way of strengthening kernel protection

and monitoring.

Ahmed et al. developed SKEE, a system that provides an isolated lightweight execution environment

at the privilege level of the kernel [35]. It does this by preventing the kernel from managing its own

memory translation tables, which separates isolated environments and the kernel since they typically

operate on the same level.

SKEE (represented in Figure 3.7) uses a two phase solution in order to achieve the requires isolation.

First, it creates a separate protected virtual address space just for itself. The memory layout of the entire

system is modified in a way that the memory regions used by the kernel overlap with SKEE. It achieves

this by changing the memory translation tables in a way that the kernel’s translation entries point to its

physical memory regions instead.

The second phase is depriving the kernel from the control of certain MMU functions, so the CPU

doesn’t get directed to memory translation tables other than what SKEE uses. This is done by instru-

menting the kernel code: removing these instruction if they change the location of memory translation

tables. A constant monitoring of the memory layout is also performed to guarantee that no other unveri-

fied privileged code is allowed to execute.

The isolation is kept throughout the system by forcing the kernel to go through a designated switch

gate, jumping to the isolated environment. This gate, also represented in Figure 3.7, was designed to

enforce a strict execution flow, both atomic and deterministic.

This novel system has a scope much smaller than our system, focusing on providing hard isolation

between a kernel and other isolated systems, such as TEEs. As is, it would only stop threats at a kernel

level, leaving the rest of the OS and the secure world a target for malicious actors.

Figure 3.7: SKEE’s design.

20

Page 35: Locksmith: Secure Android Keystore Based on Virtualized

Summary

In this chapter we analysed several projects and their proposed solutions to some flaws with the current

TEE/Android architecture. We took a look at simpler proposals like secure channels between both worlds

and more complex, system wide solutions like Samsung’s multi layered KNOX. The following chapter we

reveal our solution and detail its proposed architecture.

21

Page 36: Locksmith: Secure Android Keystore Based on Virtualized

22

Page 37: Locksmith: Secure Android Keystore Based on Virtualized

Chapter 4

Architecture

The following chapter presents Locksmith and all its components, our proposed system for a reliable and

safe Keymaster, less exposed to the risks of current TEE implementations. We start with a motivational

example in order to provide a use case and establish a threat model, after which we explore in depth

each module and features/limitations.

4.1 Motivational Example

Android’s design and functionality has changed a lot during the course of the years, but security has

always been one of Google’s focus. With the advent of secure communications, thanks to Transport

Layer Security and its predecessor, SSL, many services once considered to critical or confidential to

be provided remotely like monetary transactions or the signature of important documents are now al-

most exclusively performed over a secure network, like HTTPS. In order to understand our solution’s

architecture and functionality, we propose the following example, based on a real world interaction.

Figure 4.1 shows a typical interaction between a client and its bank of choice, accessing it on an

Android device. Typically, these interactions are secured via HTTPS, whose underlying protocol/layer is

TLS. TLS has several steps, but essentially it is based on a key (present in a public certificate, generated

by a trusted Certificate Authority) known beforehand to the client, which is then verified and used for the

rest of the session. Assuming the client is really connected to the desired machine and that the certificate

is legit, the established session is private and secure.

However, if an attacker diverts traffic from the server to its machine and installs his own fake cer-

tificate in the client’s device (e.g., via malware), the attacker can disguise himself as the legit service,

getting the client’s secrets like his username and password credentials to the real banking service, and

provide these to the banking server, who sees him as a legit actor, as shown in Figure 4.2. Attacks like

this are not that rare. Malware toolkits like Telerik’s Fiddler can even automate them. To avoid such

attacks, server side logic and code must be hardened against spoofing, but if the user’s mobile device

is susceptible to tampering, a malicious actor can install or even replace a legitimate certificate for his

own. Therefore, it is essential secure these certificates/secrets: this is one of Locksmith’s purposes.

23

Page 38: Locksmith: Secure Android Keystore Based on Virtualized

1: Generates Certificate

TrustedCA

1: Initiates TLS protocol

2: Provides Certificate

3: Secure connection

Figure 4.1: Secure authentication and communication between a user and an online banking service.

0: Connects to attacker's machine

2: Implants fake certificate

1: Initiates legit connection

3: Log in

4: Attacker can now act as the victim

Figure 4.2: Man-in-the-middle attack via certificate forgery.

4.2 Threat Model

In the section above, we described a typical Man-in-the-Middle attack against an authenticated and

confidential transaction, without going in depth on the attack vector. Such attacks take in consideration

several factors such as the victim’s behaviour and awareness, how easy is to spoof the target service,

and so on. However, our solution’s scope does not encompass the whole environment in which security

is a factor when operating an Android device (from the hardware to the application layer) – instead it fo-

cuses on the component responsible for the handling and management of client-side, security-sensitive

data, which has repercussions on the entire system. In said example, such data would be the authentic

certificates of the online banking service.

With this in mind, Locksmith aims to protect sensitive application code and secrets inside special

enclave environments by relying on a trusted hypervisor. We consider three main attack vectors:

• User space attacks: Any attack at the application or user space level – even Locksmith’s normal

24

Page 39: Locksmith: Secure Android Keystore Based on Virtualized

User Apps Keystore

Keymaster(Client side)

Locker

Bao

Lockpick

KeyMaterial

Android Enclave SecureEnclave

ARM TrustZone

Figure 4.3: Locksmith architecture: its specific components are highlighted in yellow.

world counterpart – doesn’t compromise any confidential data protected by our solution, even with

a high privilege level.

• Kernel exploits: A compromised kernel may attempt to access or modify secret keys residing

inside an enclave; however, this must not be allowed.

• Attempts to break into enclave environments: The attacker may attempt to find flaws in the

interface to the enclave where the sensitive application code and secrets are located. We aim

to make the system robust against such attacks by reducing the possibility of code vulnerabilities

inside the trusted runtime environment running inside the enclave.

Locksmith’s TCB includes not only its specific components but also a preexisting trusted hypervisor.

The utilized hypervisor has the capacity for several “enclaves” to run side-by-side. These environments

have the ability to interact with each other. However, the hypervisor ensures that they can’t force or

disrupt any other environment without its permission. Thus, our solution runs enclosed inside the hyper-

visor which leverages the TrustZone, depending on its correctness. If somehow it gets compromised the

attacker may gain access to the enclave and read or modify protected keys; this attack, however, is out

of scope of this work. In addition, Locksmith does not take in consideration attacks against TrustZone

itself. We assume that the TrustZone hardware is correctly implemented.

4.3 Locksmith Overview

Our proposed solution consists of a system named Locksmith. It aims to overcome the inherent risks

with giving full trust to TEEs and undisclosed development from vendors, we started by breaking apart

each component in the complex system that is Android’s Keystore and Keymaster. As described pre-

25

Page 40: Locksmith: Secure Android Keystore Based on Virtualized

viously, the Keystore is Android’s system responsible for the execution of security-related operations

and managing the life cycle of key material and ciphered data. It is where application developers make

requests via the Java API, which are then forwarded to the Keystore daemon. Confidential blob material

is actually stored here, but it’s encrypted so it can be stored but not used or disclosed. After the request

is processed by the daemon, the desired operation is sent to the “client” side Keymaster, keymasterd,

which then serializes the request in a certain format for the Secure World Keymaster.

To reduce these risks, we designed Locksmith according to the architecture depicted in Figure 4.3.

It is composed of two main elements – Locker and Lockpick – which interact via the Bao hypervisor’s

shared memory system. Starting with the Android OS, we made several adaptations to the client-side

Keymaster component, in order to deploy Locker – our “driver” component between the normal world

and the Bao enclave. Inside the enclave, runs only our main component in a bare-metal component

– Lockpick – which acts a “server” for Keymaster calls, much like the current TEE solutions. The dif-

ference being that it has no persistent storage, so the ciphered key material is entirely stored in Bao’s

protected memory region, and as described later, temporarily ciphered and saved in the normal world for

device shutdown. So, for instance, in the usage scenario described in Section 4.1, Lockpick would run

the software in change of managing the certificates and key material involved in the secure interactions

between the local mobile app and the banking server. Next, we briefly describe how Locksmith’s com-

ponents inter-operate as we follow the path of an invocation from an application running on the Android

OS to the software hosted inside the enclave, i.e.: Locker, Bao, and Lockpick.

4.3.1 Locker: Intercepting Keymaster Calls

Locker ’s goal is to seamlessly intercept invocations to the Android Keymaster without requiring changes

to applications and involving minimal changes to the Android OS. To this end, we took advantage of

the preexisting Keymaster HAL architecture. We dedicate a few lines to better explain this architecture

before we clarify how we leverage it to build Locker.

The Android Operating System is based on a modified version of a Linux Kernel, and so it follows

a Unix-like architecture. Built from the ground up, the kernel contains device drivers like input/output

and display drivers. Then, in order to provide an easier and faster way for the development and deploy-

ment of newer Android versions, there’s the HAL (Hardware Abstraction Layer), which through a special

definition language, provides a standard interface for hardware vendors to develop low-level driver im-

plementations. This removes the burden of having to maintain specific vendor implementations and

allows Android to be as agnostic as possible. Immediately after the HAL comes the System services,

which are modular, focused components like the Notification Manager or less user oriented like logcat

or netd. These services can be reached via the Binder IPC, a mechanism that allows applications to

cross process boundaries without the need of any knowledge or logic of those services itself. Finally,

in the userland is the application framework itself, where application developers can use a set of Java

libraries connected to system services like the Keystore, or even interact with the HAL itself.

The Keymaster HAL has been present since early versions of Android, and with each iteration came

26

Page 41: Locksmith: Secure Android Keystore Based on Virtualized

new features, like AES and HMAC in Android 6.0. Android 8.0 introduced Keymaster 3.0, which transi-

tioned from the C programming language to a C++ definition automatically generated by a tool. Since

TEEs were already being used before, it made sense to implement the “execution” side of this compo-

nent inside one, so the interface was left in the normal world and the key content and operations were

handled inside the TEE.

Our objective was then to strip Android off this dependency, which means using the TEE as less as

possible. As so, our solution has a driver-like implementation between the client side Keymaster and

the HAL, which won’t be used any more. Locker, working as a driver, intercepts calls to the Keymaster

API and handles them accordingly, exposing its own API to the enclave side Keymaster. This API

supports most Keymaster functions and it’s strongly based on the HAL definitions. All the requests (and

corresponding responses) issued by user applications to the Keymaster will then be intercepted and

forwarded to Lockpick via the Bao hypervisor.

4.3.2 Bao: Containing Code and Data inside Enclaves

Typically, any calls to the Keymaster API would pass through the HAL, where they are serialized and

forwarded to the corresponding endpoint, which would be a TEE where the actual Keymaster implemen-

tation is in the form of a Trusted Application. These Trusted Applications depend on a Trusted Operating

System in order to have features such as attestation and secure storage. As with any Operating System,

it depends on a Kernel with direct access to the TrustZone, greatly increasing the attack vector. Our idea

is instead to allocate the Android OS and the sensitive Keymaster implementation inside independent

enclaves managed by the Bao hypervisor.

Bao [36] is an open-source embedded hypervisor, currently in development stage, that performs

static partitioning, and can leverage several enclaves – virtual machines with a 1-1 mapping of virtual

to physical CPUs, with no need for a scheduler. Since it is designed for critical systems, it focuses on

isolation for fault-containment and real-time behaviour, which is essential when performing computation

heavy tasks like public-key cryptography. Besides the required firmware, it has no external dependen-

cies which represents a small footprint on the device and an even smaller Trusted Computing Base. Its

configuration is simple and the interaction between enclaves is performed via a shared memory mech-

anism based on GlobalPlatform’s TEE Client API, which is standard in the industry and already used by

the existing TEEs, thus reducing the learning curve and enabling faster development.

Due to Bao’s architecture, the unsafe/normal world now runs entirely on an enclave alongside our

Keymaster implementation. Furthermore, Bao provides all the necessary communication infrastructure

that allows Locker to exchange messages securely with Lockpick.

4.3.3 Lockpick: Guaranteeing Functionality inside a Minimal Environment

Lockpick serves as the counterpart for Trusted Applications running inside a typical TEE, but which will

now run inside an enclave powered by Bao. Since Bao uses static partitioning, resources used by each

enclave (like memory addresses) are well-defined and can’t be altered after being deployed. Due to its

27

Page 42: Locksmith: Secure Android Keystore Based on Virtualized

Host OS

QEMU

Android OS

QEMU (Limbo)

Lockpick

Figure 4.4: Initial Design

lightweight nature it can be suited to run an entire OS, complete with a kernel, or a simple bare-metal

implementation. Good performance and a small TCB are important goals of this project, and so we

developed Lockpick, the core of this entire system, with an additional concern of keeping its codebase

size small and its implementation robust.

In order to facilitate the deployment of the enclave and reducing overhead, we chose to implement

Lockpick in a mixture of C and Rust. The communication depends on the aforementioned GlobalPlatform

API, whose most stable implementation is written in C. This can be considered Lockpick’s “front-end”

component, since it exposes the internal API to the Android OS. However, the computation and storage

component is written entirely in Rust since this systems programming language is well suited to identify

possible flaws and security risks in the code itself, has a big emphasis on memory safety and a strong

type system – all enforced at compile time. No garbage collection or interpreters means its performance

is just bounded by the implementation quality and the tasks being run.

Lockpick is stateless, which means once the enclave gets shutdown (via a machine shutdown),

its execution leaves no traces behind and the allocated memory is wiped, as with any other memory

used (like the shared memory used for communication). However, we designed a mechanism to prevent

losing any sensitive material. When a shutdown signal is processed, Locker requests every key currently

being used to Lockpick, which ciphers them with its own key and proceeds to store them on the Android’s

persistent storage. At boot, Locker uploads back the stored keys via another API call to Lockpick.

4.4 Initial System Design

Before we delve into the details of our current design, we provide a brief description of how the final

Locksmith architecture came to be. The current architecture evolved from a much simpler concept,

which was trying to split Keymaster functionality as best as possible, even if it would mean still running

28

Page 43: Locksmith: Secure Android Keystore Based on Virtualized

Trusted OS

Keymaster TrustedApplication

Android OS

Keystore

Service List

[email protected]

[email protected]

...

Trusted KM Device

Software KeymasterDevice

Figure 4.5: Possible Keymaster devices

most of it the insecure world. We wanted to observe the system in action, and in order to do this we

developed two prototypes first, the second one having a slight difference in the isolation method.

Software implementation of Keymaster: In older versions of Android, where TEEs weren’t as com-

mon or dedicated processor for cryptographic operations didn’t exist yet, Keymaster’s API was imple-

mented in the normal world, using OpenSSL. When it started using more advanced features like public-

key cryptography, TEEs were deployed and thanks to the HAL and its definition language, the Android

component was independent of the vendor component, and was up to the vendor to incorporate its API

implementation via a service. However, in order to provide support to older devices, the original Key-

master implementation still exists in Android’s code base. Internally, when Keystore boots, it creates a

Keymaster device which will handle requests and forward them to the corresponding implementation. A

Software Keymaster device is created when a TEE or a Keymaster service isn’t detected, as shown in

Figure 4.5. This implements the full Keymaster API but has the disadvantage of running in the insecure

Android OS, susceptible to attacks.

Creating an isolated environment inside emulated Android: Our solution targets arm64 devices

and was tested on one. Arm64 devices are becoming increasingly more common and their performance

alongside with their power consumption makes them an attractive target for Android and not just smart-

phones. However, in order to speed up the development and testing process, we first opted for an

emulated version of Android 8 that we could run on our local device. This enabled faster bootstrap-

ping and debugging, which can be quite time consuming when dealing with actual development boards.

Since this Android image doesn’t use any TEEs or special environments, the KM falls back to the original

software implementation. There are only a few virtualization options for Android and most of them have

a specific purpose, so we used QEMU to provide an environment where Lockpick could run. Figure 4.4

represents this “nested” architecture.

Splitting Keymaster functionality: In this initial prototype we wanted to understand the capabilities

and limitations of detaching the execution from the API calls and running them in a separate environ-

29

Page 44: Locksmith: Secure Android Keystore Based on Virtualized

ment, completely detached of Android functionality. To do this, the first version of our main component,

Lockpick, provides support for an auxiliary function used to generate RSA keypairs. Even though it is

simple in nature, it’s analog to most of the other functions in term of dependencies/requirements.

Communication layer: As described previously, the Keystore framework gets its requests from appli-

cations, forwarding them to Keymaster, if needed (some security operations might not need, like check-

ing authentication tags). In our initial prototype, since the Software Keymaster is being used, there is no

need for a HAL or communication interface between the Keystore and KM, because they share the same

Operating System and resources. However, since actual execution of the API is being performed outside

of this environment, there still exists a need for a communication layer between the two components.

Since both virtualization (Android and Lockpick ) are happening on QEMU, we can use its default capa-

bilities and as such chose to use SSH to serve as a “wrapper” for our protocol, which will be explained

in Chapter 5.

Contained OpenSSL: Vendor implementations, or at least the ones that are publicly available (like

OPTEE and Trusty), resort to their own implementations of cryptographic libraries, as low level as pos-

sible (secure Operating Systems have practically the same resources as normal OSes, and sometimes

even a dedicated processor). Since it’s not in the scope of this project to implement from scratch well

established cryptographic primitives, we use OpenSSL as our cryptography library. This allows us to:

• Support the entirety of the underlying requirements for the Keymaster API without additional low-

level programming

• Use the comprehensive and thorough documentation of the OpenSSL API

• Easily change if needed the programming language used to build Lockpick, since it has extensive

bindings for most modern languages

Next, in the following sections, we describe our final design in more detail. We refer the reader to

Figure 4.3 which shows the final architecture of Locksmith.

4.5 System Bootstrap

When the device powers on, the modified U-boot starts the Bao hypervisor. The built-in, compiled

configuration is read and the enclaves are started automatically. One enclave for Android, which boots

normally, another for our implementation, Lockpick, and finally one that is used for shared memory

access, a space where both enclaves can read/write values. This way they can’t access one another

directly, just through the communication API which deters several possible attacks.

Depending on the target device, different processing power can be allocated to each enclave, being

the default value one core. Since Lockpick is simple enough to perform its task with just one core,

we chose to keep it this way. However, some cryptographic primitives could benefit in having more

30

Page 45: Locksmith: Secure Android Keystore Based on Virtualized

Function Input Output Descriptionreload key Key type, id, hex 0 if ok Loads back a stored keystore key for shutdown Key type, id Hex Ciphers a key for shutdowngenerate key Key type Key id Generate a keyimport key Key type, PKCS8 Key id Imports a key in PKCS8 formatexport key Key id, Cert. params X509 Exports a public key in X509 formatdelete key Key type, id 0 if ok Deletes a specific key in memorydelete all keys - 0 if ok Deletes all keys in memory

Table 4.1: Lockpick API.

than one core, which would enable parallel execution for them. One core could be allocated to the

communication and another for the calls themselves, which could yield faster executions, as long as

they were properly synced. Being Keystore/Keymaster one of the first services started by Android’s

service manager, zygote, it needs to be ready early in the boot process. Since our enclave is very

lightweight with no external dependencies, once the third enclave – the shared memory – is ready,

Lockpick is ready to go.

4.6 Lockpick API

In section Background/Keymaster API we showed Keymaster’s full API. Its arguments and return values

are described in a generic way since they are based on the HAL interface definition language, which can

technically be ported to any language, but current implementation is in C++.

Lockpick’s API implements the most important functions, and the ones that make sense in our en-

vironment, which is somewhat limited due to storage and memory constraints. Table 4.1 lists our API’s

function and input/output parameters in an agnostic way, similar to Keymaster’s specifications.

Some functionalities, like adding entropy to the system (via the addRNGEntropy call) aren’t present,

since they depend on specific hardware features that might not be present in the processor being used

by Bao. Multi threading support isn’t currently available on Bao, so it is not possible to implement KM’s

concept of “operation”, as in a task that can occur concurrently with others, and like a mutex, locks

access to the object in use.

4.7 Communication between Components

As mentioned previously in Section 4.3.2, Bao has a shared memory access system based on libteec,

which is a universal API for communication with TEEs, following the standard GlobalPlatform specifica-

tion. This is a well documented and thoroughly tested library that offers several high level interfaces.

Once the communication enclave starts running, it’s possible for the other enclaves to start interacting

with each other.

These interactions are performed inside a Context. Even though we are not actually running a secure

Operating system inside the enclave, the communication library treats Lockpick as a Trusted Application,

and as such there is a Session attached to it. It is by referencing this session that commands can be

31

Page 46: Locksmith: Secure Android Keystore Based on Virtualized

Android OS

Bao

Libteec Commands

TEE Client API

Locker

Shared memory

Enclave

Lockpick

Shared memory

Figure 4.6: Bao’s communication architecture

invoked. These commands are compiled unto the TA itself, and the resulting values/outputs can be

accessed via the shared memory. Figure 4.6 exemplifies this behaviour. Since both components were

built against the same interface the developer just needs to specify the memory addresses intended to

be read/written to.

Firstlaunch

New keysget

generated

Deviceshutdowns

Device bootsagain

AndroidOS

Enclave(Lockpick)

generate_key(import_key)

Plaintextkey

material,inside

dedicatedenclavememory

store_key_for_shutdown

Keys getciphered byLockpick'sKEK andsent to

persistantstorage

Lockpickonly has

itsencoded

KEK

reload_key

Keys getloaded backinto memory

Figure 4.7: Storage solution

32

Page 47: Locksmith: Secure Android Keystore Based on Virtualized

4.8 Storage and Persistence of Key Material

Key material is not ephemeral and several keys can have use during the entire life cycle of a device, and

as such a safe, permanent storage is needed. Our solution abandons the traditional TEE and with it,

some native capabilities that come with secure Operating Systems, like persistent storage.

Our solution to this drawback is simple: use them as normal when the device is turned on and stored

them encrypted when it’s off. To achieve this, Lockpick has a hard coded 256 bit AES key, used as

a Key-Encryption-Key (KEK). Figure 4.7 exemplifies this behaviour. Once everything is installed in the

device, the first boot ensues, and at this point no keys are generated yet (at least in the Keystore domain,

other keys like the Master Key aren’t included). Once keys start getting created, or even imported, for

example from X509 certificates, they are temporarily in Lockpick’s allocated memory.

When the device is booted, these keys never leave the enclave’s memory. If an intent to shutdown is

detected, Locker will start making requests to Lockpick to get each key back and store it in its domain.

These keys are ciphered with Lockpick’s KEK so even if a bad actor has access to them, they can’t

be read. If modified, they will be considered invalid. Every time the Keystore starts, if there were keys

stored by Locker, they will be reloaded unto the enclave and deciphered by the KEK.

Summary

In this chapter, we provided an in-depth overview of our solution and its components, alongside their

strengths and weaknesses. Lockpick is composed of two parts, one in each virtualized environment

(enclaves). The Android component makes requests in the form of commands to the enclave which

executes them and returns the output in a shared memory, on a third enclave. The enclave itself doesn’t

have persistent storage, however the key material is protected in the normal world when the device isn’t

running and restored when it boots again, thanks to asymmetric cryptography. The following chapter

takes a look at our implementation stage and the challenges we had.

33

Page 48: Locksmith: Secure Android Keystore Based on Virtualized

34

Page 49: Locksmith: Secure Android Keystore Based on Virtualized

Chapter 5

Implementation

This chapter presents our implementation of Locksmith. We iterated through several prototypes be-

fore obtaining a stable one that was up to par with the Keymaster API. We targeted a ROCK960 – an

ARMv8 development board suited for the latest Android version. While building these prototypes we

went through several challenges. This chapter consists of a more practical view of the development

process and the explanation behind our technical decisions. The first section is dedicated to the initial

prototypes: we developed one first prototype, which then modified with a relatively minor change result-

ing in a second second prototype. Sections 5.2 and 5.3 are specific to the final implementation, even

though they share some similarities with the initial prototypes.

5.1 Initial Prototypes

The initial stage of this project was dedicated to learning about Android security and how the Keymaster

interacts with the Keystore and its TA counterpart running in the TEE. To achieve this, we needed to

observe, modify and debug the Android Operating System as hassle-free as possible. As so, we opted

to use a x86 port of Android 8.0, called Android-x86, and to develop our prototypes for a software-

emulated platform – deployment on a real ARM hardware board was carried out in a later stage.

In its inception, Android-x86 was just a set of different patches that enabled Android emulation on

specific x86 machines, but soon evolved to a fully fledged Android “clone”. Based on Android’s main

branch, one of the key differences is that since it runs emulated (on QEMU by default) it has no access

to hardware specific technology like the TrustZone. This initially might have seemed counter-intuitive

since most recent Android devices have TEEs provided by the hardware, however:

• this approach allows for much faster development since there is no setup/bootstrap for the hard-

ware (like flashing after each build);

• debugging is simplified, since QEMU seamlessly integrates an ADB shell;

• the lack of a local hardware-supported TEE, forces the OS to use the default Software Keymaster

implementation, which uses the same API and very similar underlying mechanics.

35

Page 50: Locksmith: Secure Android Keystore Based on Virtualized

Figure 5.1: Android running Debian via QEMU.

5.1.1 Emulating Enclaves via QEMU

After choosing our target Android-x86 environment, we looked into possible isolation mechanisms that

could be instantiated inside Android OS and emulate the enclave environment where Lockpick was to

be deployed. Due to the nature of our hardware-stricken system, we were limited to software solutions.

Unfortunately, there are not many virtualization options lingering in the Android ecosystem. Most of them

are user applications that are intended to run a “containerized” Linux image, being the main purpose the

possibility of running non-mobile versions of programs like Firefox or LibreOffice.

Finally we found an app suited to our needs, called Limbo. Cross-compiled for several targets, it em-

ulates several architectures like x86 and PowerPC, through the use of QEMU. Limbo has a rudimentary

interface, since it’s essentially just a front-end for QEMU on Android. Thus, we use Limbo to emulate

an enclave in the form of a virtual machine managed by QEMU. Before we could Lockpick inside this

emulated enclave, the virtual machine needed to be configured with a guest operating system image.

For practical reasons, we picked the latest Debian “lite” image available to run in the enclave. This im-

age allows us to have similar kernel versions both in the host (i.e., Android-x86) and in the guest (i.e.,

inside the enclave). Using QEMU also allowed us to establish a communication channel between both

these components without large performance overhead or more complicated setups. Figure 5.1 shows

a screenshot of Limbo creating an instance of a Debian virtual machine inside Android.

5.1.2 Communication between Software Keymaster and the Emulated Enclave

In the first prototype, we just wanted to perform small exchanges between the Software Keymaster run-

ning in Android-x86 and our isolated enclave-emulated environment. QEMU has native port forwarding

36

Page 51: Locksmith: Secure Android Keystore Based on Virtualized

Figure 5.2: Initial protocol’s main loop.

which maps a guest port to a host port, and also socket support, which opens UNIX like sockets in both

systems. Android manages resources very strictly, and a socket would be to complex for what we intend

to do, which is simple message passing. Therefore, we chose TCP for the transport layer. Since parsing

raw TCP packets from scratch was out of the scope of this project, we picked SSH has a “wrapper” for

our basic API-like calls. SSH is a proven, secure communication protocol that works out-of-the-box on

both Android and Debian, our guest machine.

In order to maximize the performance and not encumber the development with external dependen-

cies, C was the programming language of choice. It features a powerful compiler and complete control

over resources. There are currently two C SSH libraries: libssh and libssh2. The first one is the oldest,

and can work both as a client and a server. The second one is newer and can act only as a client,

which doesn’t fit our requirements. We then developed a simple protocol (Figure 5.2) for communication

between Android and our “pseudo enclave”. The first part is just the normal establishment of a SSH

session, entirely via libshh. After that, a BEGIN string is expected to be received, after which it waits

for one of the available commands. A simple logging framework was developed since libssh only logs

37

Page 52: Locksmith: Secure Android Keystore Based on Virtualized

Figure 5.3: First prototype’s structure.

SSH-specific events. Along with some serialization testing commands, we were able to execute and

successfully run some commands from the OpenSSL 1.1.1d API.

5.1.3 Modifying Android Modules

Our final step in this first prototype was to enable us to intercept the calls issued by Android applications

to the Software Keymaster so that we could later forward such calls to the emulated so as to be served

in the future by Lockpick. To this end, it was necessary to modify some Android modules which was one

amongst the most laborious tasks of this project.

Android’s source code is structured based on compartmentalization. Sources are grouped into mod-

ules, which is either a static library, a shared library or a standalone executable. In our case, we need a

mixture of these elements, especially having an external library – libssh2. This library is relatively easier

to use compared to libssh, and we just need client features on the Android component. In order to use

libssh2, we created a module system/libssh2. system/ contains the main modules that make up the

Operating System, like Keystore and Keymaster. Initially we tried to use libssh2 as a shared library, and

for such we compiled its dependencies, OpenSSL (as a shared library too) via the Android NDK version

21. This was a lengthy process since we had to manage conflicts between shared dependencies of

the Android target and our own machine, and unfortunately we could not use it as a shared library. By

switching to a static build we were able to import it as a library for the main Keymaster module.

In order to run our test commands, some slight modifications to Software Keymaster were made in

order to call our functions. We were able to establish a successful interaction between both components.

Figure 5.3 shows all files that were added or altered in this development. This set of modification has

concluded our first prototype. Next, we explain how we have developed our second prototype, and then

how it was deployed and tested on several different environments.

38

Page 53: Locksmith: Secure Android Keystore Based on Virtualized

5.2 Locker Implementation

The initial prototype just described served as a testing ground for the second prototype which includes

the implementation of Locker and Lockpick. This section describes the implementation of the former,

and Section 5.3 the implementation of the latter.

For our implementation of Locker, we first targeted the enclave emulated setup based on QEMU

described above. This logic didn’t change much after the replacement of this emulation scheme with the

Bao hypervisor, just the environment and communication channels. However, as stated in the sections

above, we initially used an emulated version of Android that was stripped off its hardware capabilities

like the TrustZone, which our Bao hypervisor depended on. On a real device, especially one running the

latest Android, this would not be the case, being highly likely the present of dedicated TEE hardware.

To incorporate Locker into Android OS, we proceeded as follows. Google’s master branch, on which

vendors base their implementations, provides the HAL for each component and its up to manufacturers

that have their own flavour of Android to implement a service that uses the HAL as a bridge for its

implementation. In order to avoid adding unnecessary complexity and having to add SELinux policies,

we did not go through this route and simply disabled our Android’s TEE solution, OPTEE. OPTEE is

an open source Secure Operating System common to many Android devices, especially development

boards. This way, Keystore defaults to the Software Keymaster which has our Locker component acting

instead of it. Next, we describe the main steps of how Locker was implemented.

5.2.1 Choosing a Design Pattern for the Locker Code

After disabling the external TEE Keymaster, we wanted to implement actual API calls instead of some

partial operations performed by OpenSSL. The first prototype had our logic implemented by modifying

already existing calls. Since the Software Keymaster is a legacy option and is not up to par with the

current implementations, Keymaster 3 and 4, we wanted to create an interface to our enclave counterpart

that was light, unobtrusive and simple to use.

After examining the rest of the Keymaster module, we found that the code adhered to a design that

was overly complicated for what we were trying to achieve. The majority of the OS is written in C++, with

some C features enabled, so there were plenty of options for the architecture. As a result, we ended up

choosing a Singleton pattern for Locker. This was based on the fact that:

• only one Keymaster runs at any time;

• it assures proper creation and destruction of the corresponding object;

• it keeps the implementation simple and clean.

A short snippet of Locker’s code is shown in Figure 5.4.

39

Page 54: Locksmith: Secure Android Keystore Based on Virtualized

Figure 5.4: Locker singleton object.

5.2.2 Handling Keymaster API Requests

Although not shown in the code listed in Figure 5.4, Locker implements the main components of the the

Keymaster API. Essentially, it forwards all the requests transparently to the enclave. Now that the “client”

side logic was implemented, we needed to be able to communicate with the enclave. When emulating

enclaves using QEMU, we used the communication channel described in Section 5.1.2.

However, when replacing our QEMU-enabled enclaves with enclaves powered by the Bao hypervisor,

we performed additional chances. In particular, we integrated our Keymaster API inside Bao’s “applica-

tion” layer, which is heavily based on libteec. Our methods and parameters had to be wrapped around

specific structures, in order to perform TEE-like calls to the enclave. This was an ongoing process as

we had to tweak several times the API, since both sides, Android and secure world enclave, most use

exactly the same interface. In order to call our enclave/TEE-like commands we did a static build of the

library and similar to libssh2, created a module and imported it.

5.3 Lockpick Implementation

Lockpick was initially implemented and tested for an enclave that was emulated by a virtual machine

managed by QEMU. As described above, this virtual machine was running Debian. However, for our

40

Page 55: Locksmith: Secure Android Keystore Based on Virtualized

second prototype, we needed to find an alternative that would not require the deployment of a full-blown

Linux kernel inside the enclave as this approach would bloat the TCB. Thus, during this process, several

possibilities for the environment in which Lockpick would run were considered.

In particular, fully fledged operating systems, like how Debian was used for the initial prototype, were

quickly discarded as an option since they are too heavy on the system’s resources, and most of what

they provide are completely unnecessary to our implementation. As an alternative, lighter options like

Buildroot – an automated tool that generates an embedded Linux image were also considered, but even

an image as stripped down as possible still represents too much overhead. Our final solution consisted

of extending a basic application developed for Bao. The Bao hypervisor is still in heavy development. It

had to be adjusted several times during this process, by the team at Universidade do Minho, in order to

work on our target device. The Bao team initially developed a simple “Hello World” like application, which

we used as a baseline for our implementation. It was linked statically to basic dependencies like libc,

and its memory had to be initialized manually. This need of speed and fine-grained resource allocation

supported even more our decision to use Rust as the main component of our Keymaster implementation.

5.3.1 Implementing Lockpick as a Rust Library

Rust was chosen as Lockpick’s “engine” even though our small prototype codebase was in C. It has

a strong type system and emphasis on memory safety which we deemed crucial to a system-critical

application like Keymaster.

Since almost all Keymaster’s operations are cryptographic, we first analyzed several libraries and

frameworks to use. Options like ring and sodiumoxide seem sound at first, but both lack asymmetri-

cal encryption, which is one of the main types of encryption used. Rust is a relatively new language

and even though it has a strong community and development ecosystem, there still isn’t a completely

mature cryptography library. Due to this, we used Rust’s bindings for OpenSSL, a crate which can call

OpenSSL’s API and even has the capabilities of downloading, building and embedding a static copy of

OpenSSL, through the vendored feature. This way, there was no need to have a special setup in the

enclave since OpenSSL was already linked to the Rust library. liblockworker, our Rust library, had to

adapt to its environment, which would be very bare-metal. The lack of persistent storage in the enclave

led us to a memory based implementation, by storing the keys directly in memory, as seen in Figure 5.5.

The API itself is implemented in a straightforward fashion, as simple as possible. In Figure 5.6, we

present the implementation of the import API call. Note the use of the unsafe Rust tag, needed in order

to communicate values back and forth between its C counterpart. Since this is the only application

running inside the enclave, there is no risk associated with using the unsafe tag. Even with the Key-

Encryption-Key present in memory and the used IVs, this memory is completely out-of-bounds from the

rest of the system, and is only readable and writable to the enclave itself. Our API was relatively simple

to test – thanks to the existing Softkeymaster implementation, and since we were also using OpenSSL,

we could easily compare the results between the two implementations.

41

Page 56: Locksmith: Secure Android Keystore Based on Virtualized

Figure 5.5: liblockworker’s basic state

5.3.2 Lightweight C Binary

Now that the functional part of Lockpick was finished, all that was left was “packaging” everything so

that it could run and communicate outside our enclave. As referenced previously in Section 5.2.2, there

are currently no Rust ports of libteec, which is what Bao’s communication API is based on. Since the

code written in C would only serve to serialize and pass values between Locker and the Rust library, it

wouldn’t compromise any of the sensitive operations performed.

Bao’s implementation is entirely written in C so there was no need to write bindings of any sort. Rust

has the possibility of interoperability with C code, which is performed by specifying a system ABI with the

extern ”C” keyword. The no mangle annotation also tells the compiler to not mangle the following block

of code. These two features combined allow for an external C application to call the specified functions

(shown in Figure 5.6), if its arguments and return values are specified. The process of converting native

C types like integers and pointers is facilitated by a tool called cbindgen, which scans Rust source code,

looks for the annotations/tags previously described and generates a C header file with the corresponding

function headers. The last step is compiling everything as one would normally compile a C application

and binding statically against our Rust library, which has OpenSSL already embedded. Figure 5.7

summarizes this entire process.

5.4 Locksmith Deployment

We now discuss the main aspects related to the deployment of Locksmith. In particular, deploying

Lockpick requires several phases, independent of where it will be isolated, whether in a Bao enclave, or

running on the same machine locally with QEMU. In the following sections we present the deployment

process, albeit a resumed version, since our solution requires modifying every layer of our target device,

from the bootloader to the Operating System (of each Bao enclave). Our target device, shown in Figure

5.8, has a set of ports and peripherals that facilitate the deployment and debugging process.

42

Page 57: Locksmith: Secure Android Keystore Based on Virtualized

Figure 5.6: The import function and unsafe tag

5.4.1 Deploying Locker

We built Locker using the Android 9 tree. Specifically, the Box image, an image intended to be used on

Android TV devices, which was the only working image provided for the ROCK960. Unfortunately, we

tried older images in order to have a codebase similar to Android-x86, but the only maintained public

repositories had several bugs and development wasn’t active anymore.

This is the step also where we “inject” our Keystore testing application, simply by putting in the vendor

directory, which is where system applications reside. Doing this accelerates the testing process as we

don’t have to reinstall it every time we make a modification to the system. Compiling an Android image

is a lengthy process, and every time we performed the slightest modification to the system, we had to

recompile parts of it, which was quite time consuming. Due to bigger priorities and time constraints, our

Locker “module” has to be inserted directly where the client side Keymaster resides. This is achieved by

adding our single C++ class, modifying the Keymasters “.bp” file, which is Android’s flavour of a Makefile,

and adding the corresponding communication layer libraries, libssh or libteec, depending on what is

being used. After this is done, Android’s build script produces several partitions of the system. We are

specifically interested in the gpt one, since it contains the main system components, like Keymaster.

5.4.2 Preparing Lockpick

Building Lockpick is a different process. Half of it, liblockworker can be compiled in a standalone fashion

with Rust’s compiler, independent of the chosen communication mechanism, since it’s linked against the

C counterpart and communicates via the binary’s shared memory, as exemplified in Figure 5.7.

43

Page 58: Locksmith: Secure Android Keystore Based on Virtualized

lib.rs (andsmaller

dependencies)

OpenSSLcrate

rustc

liblockworker.a

lockpick.c

libteec.so

Makefile

lockpick.h

cbindgen

gcc

lockpick

Figure 5.7: Lockpick’s build process

Now, if the target environment is a local, emulated environment, libssh needs to be manually com-

piled and linked against Lockpick and the Rust library. All libraries should be compiled statically, in order

to avoid any dependency problems on the target machine, which also enables a seamless switching of

architectures/devices for testing.

Since it is part of the enclave itself, Lockpick must be compiled unto the enclave image, which is a part

of the Bao system. Bao works immediately above the hardware layer, so some firmware modifications

are required and the device’s bootloader (our target device uses U-Boot) must be configured to launch

it which will then start the enclaves according to their configurations.

Finally, the Android image must be first flashed (typically only the main gpt partition is needed),

followed by the modified Bao partitions. This entire process is applicable to any application deployed

on a Bao enclave and not exclusive to Locksmith. To ease this whole process we wrote a script which

compiles both Lockpick and Bao, setups our development board for flashing, flashes it and reboots it

into the new system.

5.5 Issues with Bao Integration

Both Locksmith-specific components – Locker and Lockpick – were ready to be deployed as stated in

the previous section. In the very early stages of this project, we had already modified the Android OS

for running on our target board (see Figure 5.8), without any issues arising. However, targeting the

board was soon proven to be much slower than developing in the QEMU version of Android, being,

nevertheless, our final target.

44

Page 59: Locksmith: Secure Android Keystore Based on Virtualized

(a) front (b) back

Figure 5.8: ROCK960 development board.

Unfortunately, Bao was not entirely stable throughout the duration of this project, and there were

numerous configuration and deployment obstacles with our target machine and implementations. Due

to these factors, coupled with time constraints, we weren’t able to deploy our final prototype using Bao

and its enclave system on the board.

Summary

There were several challenges implementing our solution. Most were due to the complexity and number

of different systems that it makes use of. Due to the enclave’s resource constraints everything had to

be as lightweight and simple as possible, while guaranteeing functionality and safety. This chapter has

described the implementation process, and the challenges that we had to face and how we overcame

them. The next chapter presents our experimental evaluation performed and the results obtained.

45

Page 60: Locksmith: Secure Android Keystore Based on Virtualized

46

Page 61: Locksmith: Secure Android Keystore Based on Virtualized

Chapter 6

Evaluation

In this chapter, we present our experimental results. The previous chapter detailed some of our short-

comings, the main one not being able to use Bao’s enclaves. However, we are still capable of comparing

our minimalist Keymaster implementation with existing ones, such as the Softkeymaster implementa-

tion, in terms of performance and resource usage. Section 6.1 lists our main objectives and metrics

used for evaluation, while Sections 6.2 and 6.3 show the results of these two measured aspects. Finally,

Section 6.4 analysis some security aspects of our implementation.

6.1 Evaluation Objectives

Our main goals with this experimental evaluation are to measure the difference of overall performance

and resource usage against the current existing Keymaster implementation and architecture. Even

though the current Locksmith prototype provides a simple implementation of the Keymaster, it features

its essential API functionality without needing a fully fledged TEE or OS.

Since the Keymaster is not exposed directly to the user nor to a regular application developer, it’s

not possible to directly evaluate its impact on the overall usability and user experience, since it doesn’t

concern these domains. However, traditional measurements like speed can still be performed accurately.

Due to the impossibility of deploying our implementation on a Bao enclave, we are limited to an

emulated environment and a development similar to what we originally intended to run on. However, we

can assess with some certainty that the values we obtained in both our benchmarks won’t differ much

from the intended environment (apart from the communication), since at this level architecture and code

quality have a higher impact than Bao’s lightweight impact and the target board’s capabilities.

With this in mind, we also take a look at a less obvious and direct parameter of our implementation,

which is overall security of the system. Once again, we have to perform a simple analysis on our system

and strengthen it with the already given security guarantees of the Bao hypervisor, since these two

system overlap as intended.

47

Page 62: Locksmith: Secure Android Keystore Based on Virtualized

6.2 Performance

As described in the previous section, we established different setups and environments in order to have

an approximation to the intended final system as close as possible. Like Chapter 5 mentioned, our main

environment development was an emulated, x86 version of Android 8.1, called Android-x86. This OS

features the latest Keymaster architecture in use and its last software implementation, which is much

simpler to understand and modify for testing purposes. It also runs on QEMU, which is has a small

overhead and footprint on the system, and allows us to tweak parameters like CPU core usage and

available memory to the system.

We split this section into two different views of the system, in order to perform a fine-grained evalua-

tion of the system: the first, which we deemed as “Global”, analyzes the overall impact on the usability

of the system, taking into account just the impact on a macro level of the whole OS, while the second

group, named “Micro”, performs measurements just at the implementation level, disregarding the normal

context in which it usually operates.

It is important to note that all of these tests were realized using our own communication mechanism

and not Bao’s, due to its unavailability at the time of writing, which means the actual values would be

lower in theory (according to our personal and the team’s assessment).

6.2.1 Global Benchmarks

To evaluate our implementation with typical workloads, we had to force Keymaster calls. Since they

can only be evoked via the Keystore, we compiled an application used to test the Keystore developed

by Google. Due to architectural changes in Android 10, this application no longer works in the latest

Android, however we were able to backport it to our target version, 8.1, as shown in Figure 6.1.

Our main metric for performance is completion time, which is the time needed to perform a normal

workload, from start to finish. We measure this by using the standard time C library and its time and

timediff functions which allows us to get a duration in milliseconds of the workload tested. An example

of this is shown in Figure 6.2, using the API’s default GenerateKey implementation.

It is important at this point to remember Locksmith’s proposed architecture and the communication

layer we used while developing and ultimately for the final prototype. As shown in Figure 4.6, the

communication mechanism between both components, Locker and Lockpick, is performed by Bao’s

shared memory mechanism. At this stage integrating with Bao was deemed impossible, so we resorted

to our initial communication layer via SSH. To simulate the enclave counterpart, we ran Lockpick waiting

for commands on an open SSH port in the same machine, which features an Intel i5-8250U CPU (8

cores, 4 physical) and 16 GB of memory, running Ubuntu 20.04 (64 bit).

The application used to test, represented in Figure 6.1, provides the 3 most common operations

which are key generation, signing and verifying a signature, all performed on the same entity. We used

our time difference technique to instrument the operations responsible for these operations. However,

Keymaster is not responsible for some of these operations. Instead, Keystore calls some parts of it,

like obtaining key material to perform signatures. Due to this fact, part of the numbers displayed will

48

Page 63: Locksmith: Secure Android Keystore Based on Virtualized

Figure 6.1: Keystore testing Application.

also account for operations not performed by our implementation, and compared the system running a

normal Keymaster implementation to our own.

Operation Normal Locksmith

Create 0.0020 0.0200Sign 0.005 0.0120Verify 0.009 0.0117

Table 6.1: System’s global benchmark.

Table 6.1 shows our results. As expected, our implementation has higher completion times, even

though they don’t deviate much in terms of order of magnitude. While performing these tests, we didn’t

observe any noticeable slowdown, apart from some delay in adb while logging the calls to Keymas-

ter. We primarily attribute these higher times to the communication layer which depends on an SSH

handshake completion before Lockpick gets any requests and executes them.

Occasionally we had some crashes, which we attributed to how Android handles the SSH connection.

Since the protocol is not being performed at an application level but rather at the system level via the

SSH library, this sometimes triggers some alarms with Android’s policy mechanism, SELinux. Our first

49

Page 64: Locksmith: Secure Android Keystore Based on Virtualized

Figure 6.2: Simple speed measurement.

choice for enabling communication wasn’t SSH but raw sockets. However, we found that opening them

required heavy modifications to SELinux and it would be harder to develop a protocol on top of it.

We also note that this particular experiment wasn’t much flexible in terms of what it could explore.

These 3 operations represent the most common ones but they are static in a sense that the data they

are manipulating is always the same and the arguments never change. A good improvement would be

modifying the application’s source code in order to test several types of keys and key sizes.

6.2.2 Micro Benchmarks

Our global evaluation of the system provides a good first analysis of the design and implementation of

our system. The results we had give strength to the hypothesis that the communication layer is what

has the most impact on the performance. To find out, we analysed the time it took to establish an SSH

session between Locker and our local running instance of Lockpick.

This was performed in a simple fashion: Locker gets instantiated, performs the typical session es-

tablishment and pings Locksmith, which replies back. We measure both ends in order to establish a

Round Trip Time, but the main segment we are interested in is the protocol handshake, since after this

step there is little overhead on the communication.

Table 6.2 confirms our suspicions that the communication establishment is the main bottleneck. “Initi-

50

Page 65: Locksmith: Secure Android Keystore Based on Virtualized

Step Time (ms)

Initiate Protocol 3Session Established 8Pong 9

Table 6.2: RTT/Communication establishment benchmark.

ate Protocol” refers to the point where most of the initial SSH protocol starts (port binding, authentication

methods exchanged and authentication is performed) and “Session Established” means it is ready to

communicate. libssh first creates a channel to accept connections and then it establishes a session with

the client, which in theory allows multiple streams inside one channel. Being the difference between the

last protocol step and the reply (Pong) just 1 millisecond, it is in fact the SSH bootstrapping that takes up

most of the total duration. This in theory would be negligible with Bao’s shared memory access, much

faster than relying on a complex Application Layer protocol.

With these values established, all that is left to determine is the API’s performance isolated in its re-

spective environment. This means analysing each API call one by one with no communication overhead.

This is possible by calling directly each Lockpick function directly on the C “server” that handles requests

to the Rust library and instrumenting them to get their duration. In order to get more “realistic” values,

we compiled Lockpick to the ARM64 architecture similar to our target ROCK960 development board and

performed the same tests on Raspberry Pi 4 model B. We use the Softkeymaster implementation as a

baseline and compare it against these two different setups.

All generate import export delete store reload

0

5 · 10−2

0.1

0.15

0.2

Tim

e(m

s)

Original Local RPI

Figure 6.3: Micro/API benchmarks.

51

Page 66: Locksmith: Secure Android Keystore Based on Virtualized

The bar labels in Figure 6.3 correspond to the Android implementation, the local Ubuntu 64 bit

environment and the Raspberry Pi ARM64 environment, respectively. The first X axis label, “All”, refers

to a typical workload inside Lockpick itself, mainly simulating the life cycle of key, from creation to usage

and proper storage and destruction.

Without the communication layer and just the raw API calls, we observe that our implementation is

quite similar to the original one in terms of speed. It is important to note that these values don’t represent

single function calls, but averages of several iterations of different orders of magnitude, in order to obtain

meaningful values. Some of the arguments themselves were tweaked, for example while generating a

new key, we tested for both symmetric and asymmetric keypairs.

In fact this means that we had to resort to very big, somewhat unrealistic workloads, in order to

get discernible values, which strengthens our argument for this reliable and fast alternative to current

Keymaster alternatives. We can observe a slightly worst performance on the Raspberry Pi, which is

expected since it has weaker hardware and an overall slower architecture compared to x86.

6.3 TCB Size and Memory Footprint

While developing Lockpick, we strove for a minimal TCB and overall codebase. Working with C and Rust

is a double edged sword in the sense that it allows for very fast code at the expense of security, in the

form of bugs or unwanted erratic behaviour, which is a huge risk for a component as critical as KM.

In particular, we aimed for a small, yet reliable and fully functional implementation of both system

counterparts. Locker, as previously mentioned, features no external dependencies apart from libssh,

and if integrated with Bao, it would use libteec to use the shared memory access, which is a battle-

tested and reliable library. Lockpick was also made to be as less complex as possible, being essentially

a “wrapper” to the embedded OpenSSL library, featuring easy to understand code. The C half of this

binary is also quite trivial, acting as server listening for API requests.

Language Files Lines Blanks Comments Code

C Header 2 178 18 19 141C 1 424 72 6 346C++ 1 146 29 0 117Rust 1 295 31 19 245

Table 6.3: Locksmith codebase statistics

We present our statistics on the developed code in Table 6.3. Some of it is boilerplate code like

the testing framework and SSH functionality, but overall it is much smaller compared to our chosen

implementation of reference, Softkeymaster. These programming languages come with great, mature

tooling which we used to optimize further our final implementations, in order to have smaller and faster

binaries. Using rustc’s build flags, which can be set to either “debug” or “release” depending on the

target environment, and gcc’s “Optimize Options”, we were able to strongly reduce our footprint on the

enclave, which is vital since each one only has a CPU core.

52

Page 67: Locksmith: Secure Android Keystore Based on Virtualized

Our initial “debug” version of the Rust library was 64.7 MB in size, quite large since it was not

optimised and featured a static embedded version of OpenSSL, but after using the “release” build flag it

was now 24.2 MB, cutting almost a third in size. This may seem big but it features everything it needs to

run by itself in the enclave or another isolated environment, without any dependencies such as an OS.

While collaborating with the Bao team, we thought of several setups for the enclave. From fully

fledged Operating Systems, like the Debian “lite” image we used in the first prototype, to minimalist,

kernel only systems (via the Buildroot tool, for example). Their initial experiments with applications more

complex than a simple bare metal “Hello World” yielded good results, but had to be thoroughly tweaked

and still had several bugs which couldn’t be present in such a system critical application like ours.

6.4 Security Analysis

Security wise, we wanted to achieve at least the guarantees provided by the current Keymaster imple-

mentation, like ciphered material isolation and no possibility of tampering the code, as a starting point.

By running our main component, Lockpick, in a completely isolated environment provided by the Bao

hypervisor, we guarantee these two essential points.

Even though it’s a much smaller implementation compared to typical TEE Keymasters, Locksmith

practically exposes the same API, so in this sense it’s subjected to possible flaws of the Keymaster

architecture itself. However, this security component has been present and used since much older

Android versions, and we believe most flaws with the API architecture have been worked out by the KM

team. With this in mind, we now present both strong points and weaknesses of our implementation.

6.4.1 Effective Security Guarantees

A malicious actor typically starts by targeting the Operating System. In older Android versions, this

meant that the Keystore and Keymaster were exposed to these adversaries and could get tampered,

eventually leaking keys or even ciphered, sensitive material directly to the attacker.

In recent Android systems running TEEs, this is much harder to achieve, however still possible as

some attacks have shown. It is harder since the secure material isn’t present in the same world as the

Operating System, and sometimes resides in a different processor/chip, but due to proprietary kernels

and code not audited publicly adversaries can still find a way through firmwares or side-channel attacks

if it is different hardware.

Our Bao hypervisor makes sure the memory zone where our enclave resides is inaccessible and

even further than that, guarantees that the allocated CPU core is exclusive, which makes it impossible

for any attacker to reach it. With no TEEs running in the machine, an attacker can only target the OS,

which has no way of directly obtaining the protected material. When the system is offline, as explained

in Section 4.8, we use the following system as to not lose any information (Bao enclaves are stateless,

there is no permanent storage):

• Store function gets called on shutdown.

53

Page 68: Locksmith: Secure Android Keystore Based on Virtualized

• Every key is ciphered by the private KEK, hardcoded into Lockpick.

• Ciphered keys are stored in Android’s permanent storage.

• On boot, reload is called and transfers the keys back to Lockpick, which get deciphered.

This scheme is simple enough to not have any significant system overheads (as demonstrated in

Figure 6.3) and provides a safe persistent storage to overcome this Bao limitation. Unless the KEK gets

compromised, any tampered keys will get rejected by Lockpick, rendering these type of attacks useless.

6.4.2 Non mitigated attacks

Even with our reduced Trusted Computing Base, there are some attacks that the system is vulnerable to.

Attacks like Denial-of-Service fall off the scope of this project but are still worth mentioning. An adversary

that compromises the entire Operating System and changes Locker behaviour could in theory spam bad

API calls in order to stutter or even crash Lockpick, which currently Bao can only start an enclave at boot.

Bao could also be targeted by this method, if calls to its monitor were intercepted and altered, which is

a highly unlikely scenario.

Furthermore, like previously described, the lack of a better permanent storage solution exposes us

to another type of Denial-of-Service attack that could render the entire system useless. To perform this,

an attacker would need to:

• Intercept the store call on shutdown;

• Capture the ciphered keys’ hex code and modify them;

• Once the system is back on, replace the stored hex data with fake/garbage data, before reload

gets called

In fact, the first step is entirely optional, since merely corrupting the key files on the boot stage would

lead to a faulty reload call, which would render the existing keys useless. This, however, requires that

the attacker has full access to the Operating System, since it depends on reading/writing permissions on

the “system/” partition and intercepting the shutdown/boot call. To deter this, an attestation mechanism

would be enough in order to verify the integrity of the key files.

Summary

With this chapter we presented our experimental results and described our evaluation process, assess-

ing how it stands up against the current implementations, both performance and security wise. Different

scenarios and workloads were evaluated, in order to have a broad spectrum of results. In the next final

chapter, we finish this report by outlining our conclusions and presenting possible future work.

54

Page 69: Locksmith: Secure Android Keystore Based on Virtualized

Chapter 7

Conclusions

Even though Locksmith is not mature enough to be deployed at a production level, in its current stage it

provides several arguments for its usage as a solid alternative to the current TEE Keymaster architecture.

Since it does not implement the entire current Keymaster API, apart from the essential functionalities, it

cannot still fully replace the existing system on an Android device.

On one hand, it is quite easy to build the main application for any Android device since it lacks any

dependencies apart from the embedded OpenSSL library, which gets automatically built and linked in

the build process. On the other hand, the ”driver” component, Locker, is just a small stub that needs

to be ”injected” in each Keymaster call from the client/Android side. This means directly modifying

the Keymaster module which might interfere with Android’s security policies, via SELinux, which most

devices have set to the highest security level.

Performance wise, due to its size and low degree of complexity, it performs on par with current

Keymaster systems. Even though we didn’t test it against in an environment using a Trusted Execution

Environment, we can safely assume it’s as fast or even faster, since our comparison against a local,

“soft” Keymaster yielded very similar results. Systems that use proprietary TEEs are quite hard to debug

and evaluate with our metrics since it requires directly altering them, and we couldn’t perform such a

fined grained evaluation due to this.

Ultimately we weren’t able to deploy our final prototype with the Bao hypervisor, however everything

is in place for it and thanks to our evaluation without the current main burden – the communication layer

– we can conclude the project was successful in attaining its goals.

7.1 Achievements

Our project achieved many of the intended goals, although not all of them. Even though our API doesn’t

fully match the current Keymaster’s, due to some restrictions that were out of our scope (e.g., lack of

persistent storage inside the enclave), it provides the essential functionality needed for most typical

operations used by the Keystore. On the Android side, we provide the OS with a simple interface to

interact with our system, via the Locker driver. Its simple structure and life cycle allows for any developer

55

Page 70: Locksmith: Secure Android Keystore Based on Virtualized

to quickly understand how it works and modify it without breaking any other part of the system.

On the protected/isolated environment side, our implementation is swift and simple. Albeit not perfect,

the Rust programming language already takes care of many bugs and errors that could possibly appear

had we done it with another systems programming language, like C. That we know of, this is the first

Keymaster implementation written in a language other than C/C++, and makes an interesting case study

for it. Google has also recently pushed a Rust compiler and other tools to its main Android repository,

which signals their interest in this new language.

The prototype communication layer took a lot of effort since it was essentially writing another protocol

above SSH, and ultimately it would be replaced by the TEE Client library used by Bao’s shared memory

access. The way it was written, however, already contemplated the message-passing system that the

TEE library and Bao uses, so it could be quickly adapted without any major disruptions.

Nevertheless, even without being able to deploy Locksmith on our intended environment – the Bao

hypervisor – we think the following goals have been attained:

• Isolation and total separation of protected sensitive key material and the normal world.

• No dependencies on Trusted Execution Environments or proprietary vendor technology.

• Successful and safe application of the Rust programming language in order to strengthen our

system.

• Simplicity to understand and modify our API.

• Overall great performance, on par with current implementations.

We conclude this thesis by elaborating on several interesting directions for future work.

7.2 Future Work

Many challenges appeared during the implementation phase, and some even while drawing the archi-

tecture for Locksmith. Through the several iterations of our prototypes we noted several features and

improvements that could greatly improve the project. Our main goal of course was to develop a version

as stable and functional as possible with every component, from the OS to the Bao enclave.

Starting with the Operating System, the code quality and practices aren’t the best. Other parts of

Android development are quite well documented, however the OS itself is not the case, and the only way

to learn is to read code/commentaries, which affected the development process. To follow the correct

Android philosophy, our Locker implementation should be a service, defined by a ”.rc” file, which would

start at launch in an orderly fashion by the process manager, zygote. It would interact with Lockpick via

the Keymaster HAL, and our arguments would have to be adjusted in order to use this interface common

to all Android devices (which can easily be done thanks to a tool that generates these stubs).

Bao also provides several security mechanisms that could be explored. Apart from the creation

and destruction of enclaves, it has a controller used to switch the execution context that in the future will

56

Page 71: Locksmith: Secure Android Keystore Based on Virtualized

provide an attestation mechanism. This is essential in guaranteeing the systems integrity, since currently

our Lockpick binary has the Key-Encryption-Key hardcoded. We could leverage this mechanism to check

on every boot if our binary has changed, or even further, if the stored ciphered keys have been tampered

with. This way we would immediately know if the system has been compromised, and the device would

react as is typical in such cases (normally locking the bootloader).

57

Page 72: Locksmith: Secure Android Keystore Based on Virtualized

58

Page 73: Locksmith: Secure Android Keystore Based on Virtualized

Bibliography

[1] H. Khan and A. Das. Security behaviors of smartphone users. Information Management & Com-

puter Security, 2016.

[2] A. Mylonas, A. Kastania, and D. Gritzalis. Delegate the smartphone user? security awareness in

smartphone platforms. Computers & Security, 2013.

[3] S. Egelman, S. Jain, R. S. Portnoff, K. Liao, S. Consolvo, and D. Wagner. Are you ready to lock? In

Proceedings of the 2014 ACM SIGSAC Conference on Computer and Communications Security,

2014.

[4] M. Alsaleh, N. Alomar, and A. Alarifi. Smartphone users: Understanding how security mechanisms

are perceived and new persuasive methods. PloS one, 2017.

[5] R. Mayrhofer, J. V. Stoep, C. Brubaker, and N. Kralevich. The android platform security model.

ArXiv, 2019.

[6] D. Cerdeira, N. Santos, P. Fonseca, and S. Pinto. Sok: Understanding the prevailing security

vulnerabilities in trustzone-assisted tee systems. In Proceedings of IEEE Symposium on Security

and Privacy, 2020.

[7] K. Mindermann, P. Keck, and S. Wagner. How usable are rust cryptography apis? 2018 IEEE

International Conference on Software Quality, Reliability and Security (QRS), 2018.

[8] ARM. Introducing the ARM architecture, 2019 (accessed December 21,

2019). https://developer.arm.com/architectures/learn-the-architecture/

introducing-the-arm-architecture/single-page.

[9] S. Pinto and N. Santos. Demystifying arm trustzone: A comprehensive survey. ACM Comput. Surv.,

2019.

[10] J. Ramos. TrustFrame, a Software Development Framework for TrustZone-enabled Hardware,

2019.

[11] N. Santos, H. Raj, S. Saroiu, and A. Wolman. Using arm trustzone to build a trusted language run-

time for mobile applications. In Proceedings of the 19th International Conference on Architectural

Support for Programming Languages and Operating Systems, 2014.

59

Page 74: Locksmith: Secure Android Keystore Based on Virtualized

[12] Y. Zhou, X. Wang, Y. Chen, and Z. Wang. Armlock: Hardware-based fault isolation for arm. In

Proceedings of the 2014 ACM SIGSAC Conference on Computer and Communications Security,

2014.

[13] D. Sehr, R. Muth, C. Biffle, V. Khimenko, E. Pasko, K. Schimpf, B. Yee, and B. Chen. Adapting

software fault isolation to contemporary cpu architectures. In Proceedings of the 19th USENIX

Conference on Security, 2010.

[14] L. Zhao, G. Li, B. De Sutter, and J. Regehr. Armor: Fully verified software fault isolation. In 2011

Proceedings of the Ninth ACM International Conference on Embedded Software (EMSOFT), 2011.

[15] S. Pinto, D. Oliveira, J. Pereira, N. Cardoso, M. Ekpanyapong, J. Cabral, and A. Tavares. Towards

a lightweight embedded virtualization architecture exploiting arm trustzone. In Proceedings of the

2014 IEEE Emerging Technology and Factory Automation (ETFA), 2014.

[16] AOSP. Application Sandbox, 2019 (accessed December 21, 2019). https://source.android.

com/security/app-sandbox.

[17] AOSP. Discretionary Access Control (DAC), 2019 (accessed December 21, 2019). https:

//source.android.com/devices/tech/config/filesystem.

[18] MITRE. CVE-2017-0322, 2017 (accessed December 21, 2019). https://nvd.nist.gov/vuln/

detail/CVE-2017-0322.

[19] N. Elenkov. Android Security Internals: An In-Depth Guide to Android’s Security Architecture. 2014.

[20] J. Ekberg, K. Kostiainen, and N. Asokan. The untapped potential of trusted execution environments

on mobile devices. IEEE Security Privacy, 2014.

[21] J. Jang, S. Kong, M. Kim, D. Kim, and B. Kang. SeCReT: Secure Channel between Rich Execution

Environment and Trusted Execution Environment, 2015.

[22] W. Huang, V. Rudchenko, H. Shuang, Z. Huang, and D. Lie. Pearl-tee: Supporting untrusted

applications in trustzone. In Proceedings of the 3rd Workshop on System Software for Trusted

Execution, 2018.

[23] MITRE. CVE-2014-4322, 2014 (accessed December 21, 2019). https://nvd.nist.gov/vuln/

detail/CVE-2014-4322.

[24] MITRE. CVE-2015-4421, 2017 (accessed December 21, 2019). https://nvd.nist.gov/vuln/

detail/CVE-2015-4421.

[25] MITRE. CVE-2015-4422, 2017 (accessed December 21, 2019). https://nvd.nist.gov/vuln/

detail/CVE-2015-4422.

[26] MITRE. CVE-2015-6639, 2016 (accessed December 21, 2019). https://nvd.nist.gov/vuln/

detail/CVE-2015-6639.

60

Page 75: Locksmith: Secure Android Keystore Based on Virtualized

[27] Z. Hua, J. Gu, Y. Xia, H. Chen, B. Zang, and H. Guan. vtz: Virtualizing ARM trustzone. In 26th

USENIX Security Symposium (USENIX Security 17), 2017.

[28] K. Ying, A. Ahlawat, B. Alsharifi, Y. Jiang, P. Thavai, and W. Du. Truz-droid: Integrating trustzone

with mobile operating system. In Proceedings of the 16th Annual International Conference on

Mobile Systems, Applications, and Services, 2018.

[29] J. Jang, C. Choi, J. Lee, N. Kwak, S. Lee, Y. Choi, and B. B. Kang. Privatezone: Providing a

private execution environment using arm trustzone. IEEE Transactions on Dependable and Secure

Computing, 2018.

[30] U. Kanonov and A. Wool. Secure Containers in Android: the Samsung KNOX Case Study, 2016.

[31] MITRE. CVE-2016-1919, 2017 (accessed December 21, 2019). https://nvd.nist.gov/vuln/

detail/CVE-2016-1919.

[32] MITRE. CVE-2016-1920, 2017 (accessed December 21, 2019). https://nvd.nist.gov/vuln/

detail/CVE-2016-1920.

[33] MITRE. CVE-2016-3996, 2017 (accessed December 21, 2019). https://nvd.nist.gov/vuln/

detail/CVE-2016-3996.

[34] F. Brasser, D. Gens, P. Jauernig, A. Sadeghi, and E. Stapf. Sanctuary: Arming trustzone with

user-space enclaves. In NDSS, 2019.

[35] A. Azab, K. Swidowski, R. Bhutkar, J. Ma, W. Shen, R. Wang, and P. Ning. Skee: A lightweight

secure kernel-level execution environment for arm. 2016.

[36] J. Martins, A. Tavares, M. Solieri, M. Bertogna, and S. Pinto. Bao: A lightweight static partitioning

hypervisor for modern multi-core embedded systems. In NG-RES@HiPEAC, 2020.

61

Page 76: Locksmith: Secure Android Keystore Based on Virtualized

62