Intel Software Guard Extensions Tutorial Part 3 Designing for Intel SGX

Original author: John M.
  • Transfer
In Part Three of the Intel Software Guard Extensions (Intel SGX) tutorial series, we’ll talk about designing applications that use Intel SGX. We use the principles learned in the first part and apply them to the general concept of the example Tutorial Password Manager application, which was discussed in the second part . We will discuss the general structure of the application and the impact of Intel SGX on it; we will create a class model that will enable us to design and integrate an enclave.



While we will not write the code for enclaves and enclave interfaces, an example of code is provided in this part of the article. A non-Intel SGX version of the application kernel, without a user interface, is available for download. It is accompanied by a small test program - a console application in C # - and a sample password storage file.

Design for enclaves


Here is a general approach that we will use when designing the Tutorial Password Manager for Intel SGX:

  1. Identify application secrets.
  2. Identification of suppliers and consumers of these secrets.
  3. Determining the boundary of the enclave.
  4. Fixture application components for the enclave.

Identify application secrets


The first step in designing an application using Intel SGX is to identify application secrets.

A secret is any information that others should not see and know. Access to the secret should only be with the user or the application for which this secret is intended; Access should not be granted to other users and applications, regardless of their level of rights. Possible secrets include financial data, medical records, personal information, identification data, licensed multimedia content, passwords and encryption keys.

In Tutorial Password Manager, some items are immediately considered secrets, as shown in Table 1. Table 1. Preliminary list of application secrets.
________________________________________
Секрет
________________________________________
Пароли учетных записей пользователя
Имена пользователя учетных записей пользователя
Главный пароль или парольная фраза пользователя
Главный ключ хранилища паролей
Ключ шифрования базы данных учетной записи
________________________________________



These are obvious secrets, but we will expand this list: we will add to it all the information of user accounts, and not just usernames. The revised sheet is shown in Table 2. Table 2. Revised list of application secrets. Even if passwords are hidden, account information (for example, service names, URLs) is valuable to attackers. Disclosure of this data in the password manager will allow attackers to gain more opportunities for hacking the system. In particular, having this data, they will be able to carry out attacks aimed directly at services, possibly using social engineering methods or password reset attacks, in order to gain access to the owner’s account, since they know who should be attacked.
________________________________________
Секрет
________________________________________
Пароли учетных записей пользователя
Информация об именах пользователя учетных записях пользователя
Главный пароль или парольная фраза пользователя
Главный ключ хранилища паролей
Ключ шифрования базы данных учетной записи
________________________________________





Identification of suppliers and consumers of application secrets


After identifying the secrets of the application, you should determine their sources and destinations.
In the current version of Intel SGX, the enclave code is not encrypted. This means that any user with access to application files can disassemble and parse them. Data open for viewing, by definition, cannot be a secret. This means that secrets cannot be statically compiled into enclave code. Application secrets must come from outside enclaves and be loaded into enclaves when executed. In Intel SGX terminology, this is called providing secrets to the enclave.

When the source of the secret is located in a component outside the trusted computing base (TCB), it is important to reduce the vulnerability of the secret to untrusted code. (One of the main reasons for the importance of remote certification for Intel SGX is that thanks to it, the service provider can establish a trust relationship with the Intel SGX application, and then generate an encryption key that can be used to transfer encrypted secrets to the application, and only they can decrypt them trusted enclave in the client system.) Similar precautions must be observed when exporting secret from the enclave. As a rule, application secrets should not be sent to untrusted code without prior encryption inside the enclave.

Unfortunately, in Tutorial Password Manager we are forced tosend secrets to and from the enclave, and at some point these secrets will be in plain text, without encryption. The end user will enter their credentials and password using the keyboard or touch screen and recall them in the future if necessary. Account passwords should be displayed on the screen and even copied to the Windows * clipboard at the user's request. Without this, the application, which should be a password manager, simply will not work as expected.

This means that we cannot completely eliminate vulnerable areas: we can only reduce them, and we need some kind of secret protection strategy when they go beyond the enclave in an unencrypted form.
Secret A source Destination
User Account PasswordsUser input *
Password storage file
User Interface *
Clipboard *
Password Vault File
User Account Information User input *
Password storage file
User Interface *
Password Vault File
User master password or passphrase User input Key generation function
Password Vault Master Key Key generation function Database key cipher
Password Vault Encryption KeyRandomization
Password Vault File
Password Vault Cipher Password
Vault File

Table 3. Secrets of the application, their sources and destinations. Possible safety risks are marked with an asterisk (*).

Table 3 lists the sources and destinations for the Tutorial Password Manager secrets. Possible problems — areas in which secrets may be available for an untrusted code — are indicated by an asterisk (*).

Defining the enclave boundary


Once secrets have been established, the boundary of the enclave should be delineated. First of all, consider the flow of secrets data through the main components of the application. The enclave boundary should:

  • Contain a minimum set of critical components that work with application secrets.
  • Inside as many secrets as possible.
  • Minimize interaction with untrusted code and the number of dependencies on it.

The data flows and the selected boundary of the Tutorial Password Manager enclave are shown in Figure 2. 1.


Figure 1. Secrets data streams in Tutorial Password Manager.

Application secrets are shown as circles, and blue circles are secrets that exist in plain text (without encryption) at any stage of application execution, and green circles are secrets encrypted by the application. The enclave boundary is circumscribed around encryption and decryption procedures, a key generation function (KDF), and a random number generator. This solution ensures the achievement of several goals at once:

  1. The database / storage key used to encrypt some of the application's secrets (account information and passwords) is generated inside the enclave and is never transmitted outside in plain text.

  2. The master key is generated from the user's passphrase inside the enclave and is used to encrypt and decrypt the database / storage key. The master key is temporary and is never transferred outside the enclave in any form.

  3. The database / storage key, account information and account passwords are encrypted inside the enclave using encryption keys hidden from an untrusted code (see No. 1 and No. 2).

Unfortunately, unencrypted secrets will cross the border of the enclave, this cannot be avoided. At a certain stage during the work of Tutorial Password Manager, the user will have to enter the password using the keyboard or copy the password to the Windows clipboard. These are unsafe channels, they cannot be placed inside the enclave, and these operations are necessary for the application to work. There could potentially be a serious problem, complicated by the decision to create an application based on a managed code base.

Protecting secrets outside the enclave


There are no complete solutions to protect unencrypted secrets from outside the enclave. There are only strategies to reduce vulnerability. The best you can do is minimize the time that information exists in a vulnerable form.
Here are some general guidelines for handling sensitive data in untrusted code:

  • When you finish working with data buffers, fill them with zeros. Use functions such as SecureZeroMemory (Windows) and memzero_explicit (Linux), which are not guaranteed to be optimized by the compiler.

  • Do not use the standard C ++ Template Library (STL) containers to store sensitive data. STL containers use their own memory management algorithms, which is why it is not easy to make sure that the memory allocated to an object is safely cleared after deleting this object. (For some containers, you can solve this problem using custom dispensers.)

  • When working with managed code such as .NET, or with languages ​​with automatic memory management, use storage types specifically designed to store protected data. The security of other types of storages depends on the work of the garbage collector and JIT compilation, such storages cannot be cleaned and freed up on demand (or impossible at all).

  • If you need to put data on the clipboard, do not forget to clear the buffer after a short time. In particular, do not let the data remain in the buffer after the application terminates.

For the Tutorial Password Manager project, we will have to work with both our own and managed code. In the native code, we select the wchar_t and char buffers , and with SecureZeroMemory we clear them before they are freed. In managed code, we use the .NET SecureString class.

When sending SecureString to unmanaged code, we will use auxiliary functions from System :: Runtime :: InteropServices to direct the data.

using namespace System::Runtime::InteropServices;
LPWSTR PasswordManagerCore::M_SecureString_to_LPWSTR(SecureString ^ss)
{
	IntPtr wsp= IntPtr::Zero;
	if (!ss) return NULL;
	wsp = Marshal::SecureStringToGlobalAllocUnicode(ss);
	return (wchar_t *) wsp.ToPointer();
}

When sending data in the opposite direction, from native code to managed code, two methods can be used. If the SecureString object already exists, use the Clear and AppendChar methods to set the new value from the wchar_t string .

password->Clear();
for (int i = 0; i < wpass_len; ++i) password->AppendChar(wpass[i]);

When creating a new SecureString object, we use the constructor form that creates the SecureString from the existing wchar_t string .

try {
	name = gcnew SecureString(wname, (int) wcslen(wname));
	login = gcnew SecureString(wlogin, (int) wcslen(wlogin));
	url = gcnew SecureString(wurl, (int) wcslen(wurl));
}
catch (...) {
	rv = NL_STATUS_ALLOC;
}

Our password manager also supports transferring passwords to the Windows clipboard. The clipboard is an insecure storage place that other users can access. Therefore, Microsoft does not recommend posting sensitive data there. The purpose of the password manager is to enable users to create strong passwords that they don’t need to remember. It will also be possible to create long passwords consisting of a random set of characters that would be difficult to enter manually. The clipboard provides much-needed convenience at a certain degree of risk.

Additional precautions must be taken to eliminate this risk. First of all, you need to clear the clipboard when the application terminates. This is done in the destructor of one of our own code objects.

PasswordManagerCoreNative::~PasswordManagerCoreNative(void)
{
	if (!OpenClipboard(NULL)) return;
	EmptyClipboard();
	CloseClipboard();
}

We also set the clipboard timer. When copying the password to the clipboard, the timer is set for 15 seconds, after which the function of cleaning the clipboard is performed. If the timer is already running, that is, the new password is placed on the clipboard before the expiration of the previous one, then the previous timer is canceled, and a new one is started instead.

void PasswordManagerCoreNative::start_clipboard_timer()
{
	// Use the default Timer Queue
	// Stop any existing timer
	if (timer != NULL) DeleteTimerQueueTimer(NULL, timer, NULL);
	// Start a new timer
	if (!CreateTimerQueueTimer(&timer, NULL, (WAITORTIMERCALLBACK)clear_clipboard_proc,
		NULL, CLIPBOARD_CLEAR_SECS * 1000, 0, 0)) return;
}
static void CALLBACK clear_clipboard_proc(PVOID param, BOOLEAN fired)
{
	if (!OpenClipboard(NULL)) return;
	EmptyClipboard();
	CloseClipboard();
}

Enclosure application components adaptation


So, when secrets are identified and the boundaries of the enclave are outlined, it's time to think about the structure of the application, taking into account the enclave. There are strict restrictions on the actions allowed within the enclave. These restrictions determine which components can be located inside the enclave, which can be externally, and which may need to be split into two when converting existing applications.

The most important limitation affecting the Tutorial Password Manager is that enclaves cannot perform I / O. The enclave cannot receive text from the keyboard and display data on the screen, therefore, all secrets - passwords and account data - must be entered into and removed from the enclave. In addition, the enclave cannot read the storage file and write data to it: components that analyze the storage file must be separated from components that perform physical I / O. This means that it will be necessary to transfer not only secrets across the borders of the enclave: the contents of the file will also need to be transferred.


Figure 2. Class diagram in the Tutorial Password Manager.

In fig. Figure 2 shows a simplified class diagram for the core of the application (except for the user interface), including classes that play the role of source and destination for secrets. Note that the PasswordManagerCore class is considered the source and destination for secrets, in this diagram it interacts with the graphical user interface for the sake of simplicity. Table 4 provides a brief description of all classes and their purpose.
ClassA type Function
PasswordManagerCore Managed Interaction with the C # graphical user interface and data collection for the native code level.
PasswordManagerCoreNative Native code not trustedInteraction with the PasswordManagerCore class. He is also responsible for the conversion between Unicode and multibyte character data (this will be discussed in more detail in Part 4).
Vault file Managed Reading the storage file and writing to it.
Storage Own code, enclaveSaving password storage data in AccountRecord members. Deserialization of the repository file while reading, re-serialization for writing.
AccountRecord Own code, enclave Storing account information and passwords for all accounts in the user's password repository.
Crypto Own code, enclave Performing encryption functions.
DRNG Own code, enclave Random Number Generator Interface.
Table 4. Class Descriptions.

Please note that the processing of the storage file is divided into two parts: one part is devoted to I / O operations at the physical level, the other stores the contents after reading and analysis. It also required adding serialization and deserialization methods to the Vault object as intermediate sources and destinations for secrets. This is necessary because the VaultFile class does not have any information about the structure of the repository file, since this would require access to the encryption functions inside the enclave.

We also connected the PasswordManagerCoreNative class with the Vault classdashed line. As you may recall from the second part of the training course, enclaves can only be associated with C functions. These two C ++ classes cannot directly communicate with each other: they need an intermediary, which is indicated by the "Bridge Functions" block.

Code Branch Without Using Intel Software Guard Extensions


The circuit in fig. 2 refers to the Intel SGX code branch. The PasswordManagerCoreNative class cannot communicate directly with the Vault class because the latter is inside the enclave. But there is no such restriction in the code branch without using Intel SGX: PasswordManagerCoreNative can directly contain a member of the Vault class . This is the only simplification we will make in an application that does not use Intel SGX. To simplify enclave integration, enclave processing in the code branch without using an enclave will be allocated to the Vault and VaultFile classes .

Another important difference between the code branches is that the encryption functions in the code using Intel SGX are taken from the Intel SGX SDK. Code that does not use Intel SGX cannot contain these functions, so they are taken from the Microsoft Cryptography: Next Generation * (CNG) API. This means that you will need to maintain two different copies of the Crypto class : one for use in enclaves, the other for use in untrusted space. (The same thing will have to be done with other classes; this will be described in the fifth part.)

Code example


As mentioned above, this part provides sample code to download . The attached archive includes the source code for the Tutorial Password Manager core DLL before integration with the enclave. In other words, this is the kernel version of the application that does not use Intel SGX.

There is no user interface, but we have added the simplest test application in C # that performs a sequence of test operations. It performs two sets of tests: one creates a new repository file and performs various operations with it, the other acts with the repository reference file, which is part of the source code distribution. At the time of this writing, the test application requires that the test repository be in the Documents folder, but you can change the location in the TestSetup class if necessary.

This source code was developed in Microsoft Visual Studio * Professional 2013 according to the requirements specified in the introduction to this series of tutorials . At this stage, the Intel SGX SDK is not required, but you will need a system that supports Intel data protection technology with a secure key.

In future releases


In the fourth part of the tutorial, we will develop an enclave and bridge functions. Follow the news!

Also popular now: