# HyperIO: A Hypervisor-Based Framework for Secure IO
## 3 System Design
### Initialization and Handshake  
HyperIO uses public-key cryptography for sensitive data encryption and certificate verification. In particular, when sensitive data needs to be displayed, it is decrypted using HyperIO's private-key. Similarly, when sensitive information is input from the user, HyperIO encrypts it using the requester's public-key. HyperIO verifies the validity of the requester's public-key using the attached certificate.  
HyperIO retrieves its private-key from the TPM during the initialization process and stores it in a secure memory region. To protect the secrecy of the private-key, HyperIO binds it to specific values of the PCR registers. The firmware updates the PCR registers with the hashes of the loaded EFI applications. Changing the boot order or the HyperIO's  
Figure 1: HyperIO’s architecture. HyperIO is embedded in an EFI application, which is stored on a disk. During the boot, the EFI application is loaded, HyperIO is initialized and its private key is loaded from the TPM. HyperIO executes in an isolated execution environment, in which it can store its secret private key. HyperIO can obtain partial control over the screen and keyboard (depicted by dashed arrows), while the operating system has direct access to them (depicted by solid arrows). The operating system and the applications can communicate with the hypervisor via the exported hypercalls.  
EFI application's content will result in different PCR register values. Therefore, the retrieval of the private-key is possible only by the HyperIO's EFI application.  
In the current implementation, the public-keys of the root certificate authorities are hard-coded in HyperIO. HyperIO implements RSA [19] for public-key cryptography and AES [20] for symmetric cryptography. We assume that the public-key of HyperIO is known to a remote server. However, this assumption can be relaxed by distributing HyperIO's public-key with a certificate that proves its authenticity.  
The encryption scheme is similar to TLS [21]. HyperIO encrypts the sensitive information using AES and a randomized key. The key itself is encrypted using RSA.  
Assume that the requester wishes to display the secret message \(m\). The requester performs the following steps:  
1. Generates a random number \(r\).
2. Computes \(c_{1}\leftarrow\text{AES}_{r}(m)\).
3. Computes \(c_{2}\leftarrow\text{RSA}_{pk_{H}}(c_{1})\), where \(pk_{H}\) is HyperIO's public key.
4. Computes \(s\leftarrow\text{RSA-Sign}_{sk_{R}}(c_{1}||c_{2})\), where \(sk_{R}\) is the requester's private key.
5. Computes the full payload \(p\leftarrow\text{cert}_{1}||...||\text{cert}_{k}||s||c_{1}||c_{2}\) where \(\text{cert}_{k}\) is the requester's certificate signed by \(\text{cert}_{k-1}\) and so on, and \(\text{cert}_{1}\) is a certificate hard-coded in HyperIO.
6. Performs \(\texttt{HcDisplay}(p)\)  
When HyperIO receives the request, it validates the chain of certificates, decrypts using its private key, the random key \(r\) and then decrypts the message \(m\). If an error occurs in one of the decryption/validation steps, HyperIO terminates the hypercall and returns to the guest.  
If the requester wishes to input sensitive information, HyperIO encrypts the input using a random key \(r\) and AES, encrypts \(r\) using the requester's public key and RSA, signs everything using HyperIO's private key and RSA and sends the result back to the requester.