-
Notifications
You must be signed in to change notification settings - Fork 710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for x86_64-fortanix-unknown-sgx target #738
Conversation
@akash-fortanix Thanks. I guess it is hopeless to expect to be able to test this in CI. However, I do have a SGX-enabled laptop myself (IIUC). Please supply a script that allows me to run the ring test suite in SGX that people can run manually. |
@briansmith Unfortunately, Rust's |
OK, thanks. I think that we can handle this like Android, where for some reason we had trouble getting the tests to run. Let's change the CI to add one new target that will do everything except run the tests, and then leave the lines that run the tests commented out. |
Right now, this is a tier 3 target, meaning no binaries for |
We need some script that can be run by somebody who wants to test this code. If it requires Xargo then please include the installation of Xargo and its build dependencies in the script. I suggest just adding this https://github.com/rust-embedded/cross since cross already uses xargo for some plaforms. |
I am working on moving all of the non-i686/non-x86_64 builds to use |
In the documentation for the ring normally uses CPUID to detect CPU features. How is that supposed to work on this target? In particular, how does ring know whether or not it is OK to use AES-NI, AVX2, etc. |
I don't know. The lack of feature detection is tracked in fortanix/rust-sgx#26. So far I've always assumed AES-NI will be available on SGX because EREPORT uses AES-CMAC, however I think you can disable AES-NI in BIOS and that will actually disable the instruction. You can call XGETBV(0) in the enclave and use those results, but that doesn't give you everything. Intel's runtime calls CPUID on the host, but I'm not too keen on that. |
Can we assume that at least SSSE3 is available? If so then the difference between a trustworthy CPUID and an untrustworthy one would be primarily performance + the possibility of crashing on an illegal instruction. If we can't even rely on SSSE3 always being available then that is more problematic. In particular, in the AES-GCM code, there is logic to fall back from AES-NI to other implementations if AES-NI isn't detected. the "VPAES" implementation is (probably, mostly) free of side channels but it requires SSSE3. The "fallback" implementation isn't free of side-channels at all. So, it seems like on SGX the best course of action would be to do whatever SGX gives us for an untrustworthy CPUID, but then hard-code the "SSSE3 enabled" bit so that the VPAES implementation would always be used, and also completely disable via a Similarly, in gcm.rs, we probably want to assume in SGX that the hardware polynomial multiplication instructions are always available, again via We also need to document these assumptions somewhere and note the consequence, namely the possibility of getting an illegal instruction exception. On Twitter, it was suggested that we could detect certain CPU instruction extensions via |
I don't think this may be assumed from the standpoint of the documentation, but all processors released so far with SGX have it.
No. Something that's been brewing in the back of my mind is to have an enclave that just tries to execute various instructions with an exception handler. If it succeeds, record that it's available. If you get |
I'm totally fine with requiring and documenting the existence of various features and relying on those in a hard-coded manner. |
abd3819
to
38a0030
Compare
It's not clear to me what rings story is w.r.t. // src/lib.rs
#![no_std]
...
extern crate std; It looks like you briefly tried to be In that case, I'm going to suggest Somewhat relatedly, I think this is also how #357 should be implemented once |
80206fc
to
2065c83
Compare
AppVeyor build failures are not caused by this PR. |
There is no
I would accept a PR to do that. (The main difficulty is figuring out which bits even need to be checked.) |
The current
Ok. Do you want to land that with this or separately? |
Fixed in master, along with a couple of other
This still remains; we depend on
That's in the |
It should be done in a separate PR. I think it is a non-trivial amount of work because the person making the PR needs to communicate clearly how to interpret what the OpenSSL/BoringSSL (assembly) language code is doing, so the reviewer can efficiently verify the correctness of the changes. That means, basically, documenting every access of |
According to rust-lang/stdarch#464 (comment), we can't use |
Just FYI, the error output in #738 (comment) was just an excerpt. There were many more errors, I didn't want to put all the lines in my comment. You can trivially discover this by running
Well, yes, in my discussion I think I was pretty clear that std support was required for this. I thought this was ok because ring doesn't actually work without std. There is no "lower level interface" in libcore, feature detection requires |
Thanks. I've done this and reduced (in my private tree) the instances of problems to the need for
I need to think more about this. In general I would like to use the Rust built-in feature detection instead of implementing it in ring, but there are several issues to consider, of which |
You might want to consider https://crates.io/crates/spin |
I fixed most, but not all, of the The issue of how to make ring working in A proposal for changing how we do feature detection should be in a separate issue. I'll email @jethrogb next week about how make progress on this. |
NB I've documented how to build & run for the target at fortanix/rust-sgx#49. As you can see, it's kind of unwieldy right now, but I expect things to get better quickly. |
@briansmith Any update on how to take this ahead? |
2065c83
to
d44577d
Compare
I've completed all the tasks mentioned in #775 for This still needs rust-lang/rust#57914 to land in the compiler to work with LTO. Alternatively, I can disable LTO for the SGX target in CI for now to make the tests pass. Travis is configured to allow failures of nightly. I don't know how to configure Travis to not allow failures of SGX even though nightly is used. |
ef7853f
to
98b51c2
Compare
NB. The commit message of d15e9d2 has an audit of all the CPU features currently used by ring. Some of them are pretty strange. |
Filed a PR for MOVBE: rust-lang/rust#57999 |
78eb140
to
4cf77cc
Compare
Well, looks like LTO is now failing on every platform. But on the plus side, it should work for SGX on the latest nightly (if you disable incremental compilation). |
@briansmith this PR has been open for 2 months. What is blocking merging this? |
src/rand.rs
Outdated
|
||
#[must_use] | ||
#[repr(transparent)] | ||
pub struct OneMeansSuccess(c::int); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use bssl::Result
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks
src/rand.rs
Outdated
|
||
if !rest.is_empty() { | ||
let mut buf = [0; 8]; | ||
Result::from(CRYPTO_rdrand(&mut buf))?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to do everything withCRYPTO_rdrand
and avoid CRYPTO_rdrand_multiple8_buf
. Then we can implement the retry 10 times
advice from Intel in this Rust code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
I agree to license my contributions to each file under the terms given at the top of each file I changed. Co-authored-by: Akash Anand <akash.anand@fortanix.com>
I agree to license my contributions to each file under the terms given at the top of each file I changed.
Audit of all CPUID features use by *ring* at the time of the commit: | | chacha | aesni | mont5 | mont | ghash | sha512 | poly1305 | Rust | |--------------|--------|-------|-------|------|-------|--------|----------|------| | ADX | | | * | * | | | | | | AES | | | | | | | | * | | AVX | | * | | | | * | * | * | | AVX2 | * | | | * | | * | * | | | AVX512F | * | | | | | | | | | BMI1 | | | * | | | * | | | | BMI2 | | | * | * | | * | | | | FXSR | | | | | | | | 5 | | “intel CPU” | | | | | | * | | | | MOVBE | 1,2 | * | | | 1,3 | | | 6 | | PCLMULQDQ | | | | | | | | * | | SHA | | | | | | * | | | | SSSE3 | * | | | | | * | | * | | XOP | | 4 | | | | | | | | XSAVE | 1 | 1 | | | 1 | | | | 1. Instruction not used, only used to detect Atom processors 2. If Atom, change the input lengths for which different code paths are taken (presumably for performance) 3. If Atom, avoid one code path for performance 4. Instruction not used 5. Instruction not used, only used to detect PCLMULQDQ 6. Instruction not used, only used to detect AVX I agree to license my contributions to each file under the terms given at the top of each file I changed.
I agree to license my contributions to each file under the terms given at the top of each file I changed.
I agree to license my contributions to each file under the terms given at the top of each file I changed.
Ping... |
@briansmith do you have any other comments on this PR? |
I've been successfully using this branch for the past few weeks, it would be great if it could be merged barring any other concerns? |
I think this is substantially easier now. See #744 (comment) and the review I did for UEFI support in #1406. |
Closing due to inactivity. |
The x86_64-fortanix-unknown-sgx recently gained Tier 3 support upstream.