Sunday 21 August 2016

[Gsoc] [ lowRISC] A Trusted Execution Environment on seL4 - Full Report


In this blog post, I will be talking about my Google Summer of Code 2016 project with lowRISC and will include a walkthrough on installation and usage as well. My project was to build a standalone open source project, A trusted execution environment called "tee-os" which models the functionality of OPTEE but can be portable across architectures.

Motivation:


lowRISC is an open source organization who is aiming to create a fully open source System on chip computer based on the RISC-V architecture.

My project for Google summer of code 2016 was to build a Trusted Execution Environment which models the features and architecture of OPTEE by Linaro and also is compliant to the Global Platform standards.

RISC-V platform saw a port of seL4 operating system in the previous Google Summer of Code, So I built the Trusted Execution Environment on top of the seL4 kernel so that I could use the microkernel as a base and also encourage developers as an Architecture independent solution for a TEE would be mutual beneficial for all.

I was mentored by



Architecture:

seL4 is a formally verified kernel with complete end to end proofs, therefore it is suitable for building a system which can be trusted.


The seL4 kernel provides very limited functionality like IPC's and memory management  in accordance to microkernel design, which is the reason for its secure nature.

seL4 kernel:
The sel4 kernel provides basic functionality like IPC and memory management. It also allows two threads/processes to be completely isolated with the concept of capability spaces.

tee-os container: This is the root task of the system, this is loaded first and basically spawns the rich-os and Trusted applications in separate isolated threads. It allows manages communicated between the client and the trusted app.

Rich-OS: rich os is an operating system with a wealth features eg. Linux, Android. For the sake if this project the rich-os is just a simple stub os. This is preferably virtualized in the real world. A hypervisor would sit above this level in that case.

client app: The client app is the client facing part of the application It is started in the rich-os , it makes use of tee_client_api to communicate with the Trusted application/tee-container.

trusted application: The trusted application sits in an isolated container and has access to the tee_internal_api to communicate with the tee-container/client app and the tee_crpyto_api which provides cryptographic operations.


Features:

This section will explain the features of TEE-OS. The design principles and features have been heavily inspired by OPTEE-OS and are in compliance with the GlobalPlatform standard for TEE's. The process of writing client and secure apps for seL4 TEE-OS is very similar to OPTEE-OS. A number of functions need to be implemented on both the components and function names and TA names are provided in config files.


void encrypt(char *arr){
 uint8_t key[16];
 uint8_t plaintext[16];
 uint8_t ciphertext[16];
 int param_len = strlen(arr);
 char plaintext_string[16 * ceil_num(param_len/16.0)]; 
 strcpy(plaintext_string,arr);
 for(int i= strlen(arr); i < strlen(plaintext_string);++i){
  plaintext_string[i] = 0;
 }
 AES128_STRING_parse(key_string, key);
 AES128_STRING_parse(plaintext_string, plaintext);
 AES128_ECB_encrypt(plaintext, key, ciphertext);
 strcpy(arr,ciphertext);
 int i,j=0;
 for (i = 0; i < 16; i++){
  sprintf(arr+j,"%02x", ciphertext[i]);
  j+=2;
 } 
}

void decrypt(char *arr){
 uint8_t key[16];
 uint8_t plaintext[16];
 uint8_t ciphertext[16];
 int param_len = strlen(arr);
 char plaintext_string[16 * ceil_num(param_len/16.0)];
 strcpy(plaintext_string,arr);
 for(int i= strlen(arr); i < strlen(plaintext_string);++i){
  plaintext_string[i] = 0;
 }
 AES128_STRING_parse(key_string, key);  
 AES128_STRING_parse(plaintext_string, plaintext);
 AES128_ECB_decrypt(plaintext, key, ciphertext);
 strcpy(arr,ciphertext);
 int i,j=0;
 for (i = 0; i < 16; i++){
  sprintf(arr+j,"%02x", ciphertext[i]);
  j+=2;
 } 
}

//Every ta must have a function handler.
tee_result function_handler(int msg, int func_id ,seL4_Word* param_arr,int length){
 if(func_id == HELLO_TA_INCREMENT ){
  
  return tee_make_result(increment(msg),NULL,0);
 }else if(func_id == HELLO_TA_DECRYPT){
  char *temp = (char *)param_arr;
  decrypt(temp);
  return tee_make_result(0,temp,length * sizeof(seL4_Word));  
 }
 else if(func_id == HELLO_TA_ENCRYPT){
  char *temp = (char *)param_arr;
  encrypt(temp);
  return tee_make_result(0,temp,length * sizeof(seL4_Word));  
 }else if(func_id == HELLO_TA_DECRYPT){
  char *temp = (char *)param_arr;
  decrypt(temp);
  return tee_make_result(0,temp,length * sizeof(seL4_Word));
 }
 else{
  return tee_ta_failure();
 }
}

The function handler is similar to the OPTEE entry point function, It calls respective functions based on ID.

Some features of TEE-OS are:

  1. Multiple TA support.
  2. Cryptographic library with AES and hash algorithms
  3. Multiple function call interface
  4. Portable to other architectures
  5. Runs on RISC-V (experimental) : not everything works yet



Github Repos:

Installation:

pre-requisites:
For building sel4 based systems the following packages are necessary
sudo add-apt-repository universe
sudo apt-get install -y python-software-properties
sudo apt-get update

sudo apt-get install -y build-essential realpath
sudo apt-get install -y gcc-multilib ccache ncurses-dev
sudo apt-get install -y gcc-arm-linux-gnueabi
sudo apt-get install -y gcc-arm-none-eabi

sudo apt-get install -y python-pip python-jinja2 python-ply  python-tempita
sudo pip install --upgrade pip
sudo pip install pyelftools

Toolchains and cross-compilers:

sudo apt-get update
sudo apt-get install build-essential realpath
sudo apt-get install gcc-multilib ccache ncurses-dev
sudo add-apt-repository universe
sudo apt-get update
sudo apt-get install gcc-arm-linux-gnueabi
sudo apt-get install gcc-arm-none-eabi

Miscellaneous tools:

sudo apt-get install qemu-system-arm qemu-system-x86
sudo apt-get install git phablet-tools

If you want to build it for RISC-V you will require risc-v-gnu-toolchain and spike emulator . sel4 branch for RISC-V is available at link.


Installing tee-os:
The following steps download and install tee-os along with a sample client and trusted app. The manifest fest contains links to all other sub modules.

repo init -u https://github.com/hybridNeo/tee-os-manifest -m tee-os.xml
repo sync
make kzm_debug_xml_defconfig
make silentoldconfig
make
make simulate-kzm


The sample app demonstrates a client calling the TA(trusted app) for three functions, firstly it sends a string to be encrypted, then it passes the encrypted string to be decrypted. The third function just increments a number in the secure world.. The result is shown below.



Achievements:
Some notable achievements are,

  • Built proof of concept system which shows the working of a sample trusted app which runs isolated from the operating system.
  • Implemented client and internal libraries which have the same interface as OPTEE-OS libraries
  • Implemented some cryptographic libraries like AES as a part of crypto api.
  • Built it for ARM as well as RISC-V and have successfully tested it out.
  • Good starting point for a future collaborated project.

Future work:

There is a lot of room for future work in this project, Firstly an important component of TEE's is secure storage, secure storage is used to store cryptographic keys and ciphers. Sadly seL4 did not have support for file systems at the moment, Secure storage should be implemented with the help of a client OS like linux.

The seL4 build for RISC-V is still experimental as some libraries like muslc for RISC-V have not been ported fully yet.

More people must be encouraged to contribute to this project as an architecture independent TEE is beneficial for everyone. Also since I built this project from scratch I haven't been able to perform detailed tests. Writing a test package is also necessary.