Load an application into Intel SGX enclave - sgx

Is there a way to load an existing application into an Intel SGX enclave directly?

While hmofrad is right with the statement that SGX is not designed to run an entire existing application, there are approaches to achieve exactly this: There is SCONE (closed source) and Graphene (open source). So you could read up on Graphene with SGX and check if this fits your need.

Intel SGX is designed for securing data and not loading the entire application. You can perform secure computations inside the SGX enclaves on your data by sending temporary buffers from the user space program (app.cpp) to your SGX enclave (Enclave.cpp). But why?
The enclave size is small and you can't load all your data inside it at the same time.
Inside enclaves, you're limited to a set of programming primitives like if-then-else, for-loop, and etc. Also, you can't have syscalls like open for opening a file.
Thus, if your application is large or contains some syscalls or even some forbidden standard C library functions by SGX implementation, it is impossible to import it entirely inside an enclave. But, if your application is doing some primitive operations without the need for any special syscall or function call, you can freely port it inside an enclave. Still, you can't directly load it inside an enclave you have to change your implementation to make it as a trusted enclave call inside the Enclave.cpp.
As an example, I've implemented a set of cryptographic operations e.g. SHA-2, HMAC SHA-2, AES, and etc. inside an enclave. I send/receive temporary buffers of pliantext/ciphertext data to/from enclave performing the encryption/decryption operations inside the enclave and storing the results of computation like a hash digest, or ciphertexts in userspace. In this way, I ensure that no one can tamper the results of operations because they're running inside the enclave which is secured by CPU instructions.
You can read more about this example here and check the implementation here.

As pointed out by previous answers, the Intel SGX default design does not permit to run ummodified applications in general, because the latter contain (most probably) routines which are unsupported (all syscalls) by the trusted libc provided by the Intel SGX SDK. Tools such as Scone, Graphene SGX, Haven, or SGX-LKL allow to run unmodified applications in Intel SGX enclaves.
Most of the above mentioned tools run mini-OSs inside the enclave to handle (via emulation) the unsupported syscalls. This leads to a large enclave size which is very detrimental for applications which require large memory resources; the enclave memory is limited to 128MB (or 256MB in more recent SGX versions).
The solution you choose to use will depend largely on the application you are trying to run. If the latter is not that large, you could try porting it to Intel SGX. Porting involves separating your application into trusted and untrusted parts. Only the trusted part will run in the enclave, and may communicate securely with the untrusted part (a helper) out of the enclave runtime. During porting you may still have trusted code which depends on unsupported routines like syscalls. You could solve this problem by implementing/extending your own trusted libc (just the syscalls you need) in the enclave which redefines the syscalls as wrappers to ocalls which then invoke the real routines (securely) out of the enclave; good example here. This approach however is not for newbies though. This way you will maximize enclave memory and prevent bloating it will a full-blown library OS.
On the other hand, if you are dealing with a very complex application where porting is not feasible, then I will advice you to go for a solution such as Graphene-SGX which is opensource and well documented.

Related

Can I write a file to a specific cluster location?

You know, when an application opens a file and write to it, the system chooses in which cluster will be stored. I want to choose myself ! Let me tell you what I really want to do... In fact, I don't necessarily want to write anything. I have a HDD with a BAD range of clusters in the middle and I want to mark that space as it is occupied by a file, and eventually set it as a hidden-unmoveable-system one (like page file in windows) so that it won't be accessed anymore. Any ideas on how to do that ?
Later Edit:
I think THIS is my last hope. I just found it, but I need to investigate... Maybe a file could be created anywhere and then relocated to the desired cluster. But that requires writing, and the function may fail if that cluster is bad.
I believe the answer to your specific question: "Can I write a file to a specific cluster location" is, in general, "No".
The reason for that is that the architecture of modern operating systems is layered so that the underlying disk store is accessed at a lower level than you can access, and of course disks can be formatted in different ways so there will be different kernel mode drivers that support different formats. Even so, an intelligent disk controller can remap the addresses used by the kernel mode driver anyway. In short there are too many levels of possible redirection for you to be sure that your intervention is happening at the correct level.
If you are talking about Windows - which you haven't stated but which appears to assumed - then you need to be looking at storage drivers in the kernel (see https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/). I think the closest you could reasonably come would be to write your own Installable File System driver (see https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_ifsk/). This is really a 'filter' as it sits in the IO request chain and can intercept and change IO Request Packets (IRPs). Of course this would run in the kernel, not in userspace, and normally this would be written in C and I note your question is tagged for Delphi.
Your IFS Driver can sit at differnt levels in the request chain. I have used this technique to intercept calls to specific file system locations (paths / file names) and alter the IRP so as to virtualise the request - even calling back to user space from the kernel to resolve how the request should be handled. Using the provided examples implementing basic functionality with an IFS driver is not too involved because it's a filter and not a complete storgae system.
However the very nature of this approach means that another filter can also alter what you are doing in your driver.
You could look at replacing the file system driver that interfaces to the hardware, but I think that's likely to be an excessive task under the circumstances ... and as pointed out already by #fpiette the disk controller hardware can remap your request anyway.
In the days of MSDOS the access to the hardware was simpler and provided by the BIOS which could be hooked to allow the requests to be intercepted. Modern environments aren't that simple anymore. The IFS approach does allow IO to be hooked, but it does not provide the level of control you need.
EDIT regarding suggestion by the OP of using FSCTL_MOVE_FILE
For simple environment this may well do what you want, it is designed to support a defragmentation process.
However I still think there's no guarantee that this actually will do what you want.
You will note from the page you have linked to it states that it is moving one or more virtual clusters of a file from one logical cluster to another within the same volume
This is a code that's passed to the underlying storage drivers which I have referred to above. What the storage layer does is up to the storage layer and will depend on the underlying technology. With more advanced storage there's no guarantee this actually addresses the physical locations which I believe your question is asking about.
However that's entirely dependent on the underlying storage system. For some types of storage relocation by the OS may not be honoured in the same way. As an example consider an enterprise storage array that has a built in data-tiering function. Without the awareness of the OS data will be relocated within the storage based on the tiering algorithms. Also consider that there are technologies which allow data to be directly accessed (like NVMe) and that you are working with 'virtual' and 'logical' clusters, not physical locations.
However, you may well find that in a simple case, with support in the underlying drivers and no remapping done outside the OS and kernel, this does what you need.
Since you problem is to mark bad cluster, you don't need to write any program. Use the command line utility CHKDSK that Windows provides.
I an elevated command prompt (Run as administrator), run the command:
chkdsk /r c:
The check will be done on the next reboot.
Don't forget to read the documentation.

Device driver inside Intel SGX enclosure?

Is it possible to run a device driver inside an Intel SGX enclave? Or is it impossible for an enclave to access DMA memory and perform memory-mapped I/O?
I already have a device driver that has mapped all of the necessary memory but I don't know if it will be possible to create an enclave that shares these mappings. I am essentially confused about whether enclaves can only access their own private memory or whether they can also access arbitrary physical memory that I would map to them.
The documentation seems to say that the enclave cannot access code at arbitrary locations but I want to know the rules for data and MMIO.
Enclaves are Statically Linked libraries, as so they share the Process with the application it gets loaded into. Multiple enclaves can be loaded into one process.
An Enclave owns one or more Page Tables, these pages are encrypted and protected from outside access. This is better explained on: https://software.intel.com/sites/default/files/332680-002.pdf, page 28.
Enclaves can access memory from the process they run, but their memory can only be accessed by themselves. DMA access attempts are rejected/aborted, is not possible to map to an enclave's memory, however, you can map to the memory of the process and access it from within the enclave.
Enclaves are by concept isolated from the outside world, they don't have I/O capabilites appart of the Protected File System Library. So, I don't think it's possible to run a driver inside sgx.

Is there an API to detect CPU features on iOS?

I have some cryptography code that has multiple implementations, selecting which implementation at runtime based on the features of the CPU it is running on. Porting this has been straightforward so far, with Windows, Linux and Android being easy.
But in iOS it does not seem easy. While x86 CPUs have the cpuid instruction to detect features, even from user mode, the ARM equivalent is privileged. It is not possible to detect CPU features on ARM without OS cooperation.
In Windows, IsProcessorFeaturePresent works for detecting ARM CPU features. On Linux, /proc/cpuinfo is the way to go. Android has a cpufeatures library (and /proc/cpuinfo still works anyway). Mac OS has sysctlbyname with hw.optional.*.
But what about iOS? The iOS kernel has hw.optional.* like Mac OS, but it is locked down in iOS 10. (Thus, my question is not a duplicate of this one, as circumstances have since changed.) Also, getting a list of those seems difficult - Apple's open source web site runs an automated process to scrub all ARM-specific code from the OS source they give out publicly in order to make jailbreakers work harder.
You may take a look on the iOS Security Guide for business
Apparently, if you can get the CPU series name, you may also deduce which cryptographic component and how it works from the documentation.
You may note that some devices have a Security Enclave:
The Secure Enclave is a coprocessor fabricated in the Apple T1, Apple
S2, Apple S3, Apple A7, or later A-series processors.
Page 6
And you may deduce that any older CPU version has not.
Every iOS device has a dedicated AES-256 crypto engine built into the
DMA path between the flash storage and main system memory
[...]
On T1, S2, S3, and A9 or later A-series processors, each Secure Enclave
generates its own UID (Unique ID).
Page 12
Method to access cryptographic components will depend of which kind of data or storage you would to get an access ( local data storage / sync / home data / app / siri / icloud / secure note / keybag / payment / applepay / vpn / wifi password / SSO / airdrop / etc...)
Could you precise which part of the cryptographic part you need to access in your use case?
You may also take a look here and here to get additional information relative to iOS native security and cryptography API.
The reason behind iOS blocking certain hardware information is very simple. Please read about Apple A11 processor. There is so much stuff in it, also stuff, which will never be documented.
Apple simply does not want developers to be aware of it and use it. I would not expect any progress on this topic.
The only way forward at this moment is to bypass the OS and talk directly to the hardware. You would be amazed what is inside and how quickly it responds!

Trusted Computing, iPad, Certifying Unmodified Apps

Since Apple controls the entire hardware/software stack, is it possible to obtain the following (through some type of trusted computing):
the hardware certifies that the software is genuine, non-jail broken iOS
iOS certifies to my server that the app run is an unmodified app
What this achieve is as follows:
when my server sends out data, it is guaranteed that the data can only be used in the way I intend it to be used (since it's running my app unmodified, on an non-jail broken iOS).
This prevents things like a modified app which steals data being transmitted from the server to the client. I realize one could theoretically eavesdrop, but this can be eliminated via encryption.
Thanks!
Briefly, no.
You're talking about Trusted Computing concepts on a platform that does not support TC. IOS does not include anything near Trusted Computing - Remote Attestation. It has no TPM.
The chain of trust established by Apple chip merely tries to stop execution if the signature of the next element in the boot chain is invalid. If one thing fails (jailbroken), their's no real -effective- way of detecting it. It is very similar to Secure Boot introduce by Microsoft but it's very different then Trusted Computing which attest which version of the system it is currently running.
With Trusted Computing, the TPM store the measurements (PCRs) of the system boot (SRTM). At boot, the first thing executed (CRTM - the only thing we really need to trust implicitly) will start the chain by measuring the BIOS, send the measure to the TPM (in a PCR) and pass execution to it (the BIOS). Then the BIOS does the same thing for the next element in the boot chain.
The measurements stored in the PCRs can then be used to encrypt or decrypt information (SEAL/UNSEAL operations) depending on the environment loaded in memory.
The TPM does not take action on the measurements (good or bad). The idea is not to restrain what can be loaded but to being able to know what environment is loaded on the platform. If something has been modified, the TPM will not contain the proper PCRs values and the UNSEAL operation (decrypt using PCRs as the key) will not work.
In the case of Remote Attestation, we're talking about the QUOTE operation. It's basically the same thing then SEAL but uses other keys to make sure the evaluating party can validate the attestation is really coming from a real/compliant TPM.
Sure, a system could use the SEAL operation to protect a secret used to decrypt the operating system and thus produce -in some way- the same effect as secure boot.
For more info, see my other posts.

Cryptography: best practices for keys in memory?

Background:
I got some data encrypted with AES (ie symmetric crypto) in a database. A server side application, running on a (assumed) secure and isolated Linux box, uses this data. It reads the encrypted data from the DB, and writes back encrypted data, only dealing with the unencrypted data in memory.
So, in order to do this, the app is required to have the key stored in memory.
The question is, is there any good best practices for this? Securing the key in memory.
A few ideas:
Keeping it in unswappable memory (for linux: setting SHM_LOCK with shmctl(2) ?)
Splitting the key over multiple memory locations.
Encrypting the key. With what, and how to keep the...key key.. secure?
Loading the key from file each time its required (slow and if the evildoer can read our memory, he can probably read our files too)
Some scenarios on why the key might leak: evildoer getting hold of mem dump/core dump; bad bounds checking in code leading to information leakage;
The first one seems like a good and pretty simple thing to do, but how about the rest? Other ideas? Any standard specifications/best practices?
Thanks for any input!
All depends on the level of your paranoia and the sensitivity of the key/data. In the extreme cases, as soon as you have an unencrypted key in memory, one can retrieve it using coldboot techniques. There is an interesting development at frozencache to try to defeat that. I merely casually read it, did not try it in practice, but it seems like an interesting approach to try.
With the tinfoil hat off, though - (1), (2), (3) do seem reasonable. (4) won't cut it precisely for the reason you mentioned. (Not only it is slow, but assuming you read into the stack, with different stack depths the key might become visible more than once).
Assuming the decrypted data is worth it, and it would be in the swappable memory, you definitely should encrypt the swap itself as well. Also, the root, /tmp partitions should also be encrypted. This is a fairly standard setup which is readily available in most guides for the OSes.
And then, of course, you want to ensure the high level of physical security for the machine itself and minimize the functions that it performs - the less code runs, the less the exposure is. You also might want to see how you can absolutely minimize the possibilities for the remote access to this machine as well - i.e. use the RSA-keys based ssh, which would be blocked by another ACL controlled from another host. portknocking can be used as one of the additional vectors of authentications before being able to log in to that second host. To ensure that if the host is compromised, it is more difficult to get the data out, ensure this host does not have the direct routable connection to the internet.
In general, the more painful you make it to get to the sensitive data, the less chance someone is going to going to get there, however there this is also going to make the life painful for the regular users - so there needs to be a balance.
In case the application is serious and the amount of things at stake is high, it is best to build the more explicit overall threat model and see what are the possible attack vectors that you can foresee, and verify that your setup effectively handles them. (and don't forget to include the human factor :-)
Update: and indeed, you might use the specialized hardware to deal with the encryption/decryption. Then you don't have to deal with the storage of the keys - See Hamish' answer.
If you are serious about security then you might consider a separate cryptographic subsystem. Preferably one that is FIPS 140-2/3 certified (list of certified modules).
Then the key is held in tamper proof memory (non-extractable) and all cryptographic operations are performed inside the crypto boundary.
Expensive but for some applications necessary.
Also don't forget the threat of core dumps and your memory being swapped out!
On both POSIX (like Linux) and Windows systems, there are techniques to prevent that from happening if you're dealing with C language - see this section from CERT Secure Coding Standards:
MEM06-C. Ensure that sensitive data is not written out to disk
The big problem is the program has to read the key from somewhere. Unless you accept direct keyboard input each time the server reboots, it pretty much has to exist on disk somewhere.
In general you have to assume the evildoer doesn't have access to the root level operating system or hardware as when that's the case they'll eventually manage to get the key even if it's only in RAM.
So you assume the server's OS is secure. But let's say somebody can come and steal the hard drive so starting the server would give them the key. Then let the server ask another server for half of the key, the remote server validates the request (using ip, private/public key pairs) and supplies half the key. Then your server has a complete key, and the remote server never has more than half. That seems to me an improved level of protection.
I'd be looking at what
openssh,
openssl,
GnuPG (see related sub-projects via the project-root dropdown), and
GnuTLS
do when handling keys. They're sufficiently paranoid about such security matters...
Use of "super super user" hardware memory is ideal. All Intel Macs have this SecureEnclave memory area and it also includes an AES decryption in hardware such that the application and operating system never have access to the raw private key. When the machine boots, a password is typed in (optional), and the SecureEnclave decrypts its cold flash memory encrypted version of the key into its RAM area, which is not accessible by the main operating system.
Nice side effect is the hardware accelerated encryption: I benchmarked 600 MB/sec writes to my PCIe storage on a freshly formatted encrypted disk.
In the cloud, Amazon have this AWS Key Management Service (KMS) managed service that makes it easy for you to create and control the encryption keys used to encrypt your data, and uses FIPS 140-2 validated hardware security modules to protect the security of your keys: https://aws.amazon.com/kms/

Resources