Skip to content
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

nixos/security/sgx: init #129432

Closed
wants to merge 2 commits into from
Closed

Conversation

RealityAnomaly
Copy link
Member

@RealityAnomaly RealityAnomaly commented Jul 6, 2021

Motivation for this change

Adds packages and a module for the Intel SGX (Software Guard Extensions) service, including the SDK and PSW (Platform Software) binaries.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • 21.11 Release Notes (or backporting 21.05 Relase notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-ready-for-review/3032/556

pkgs/os-specific/linux/intel-sgx/default.nix Outdated Show resolved Hide resolved
pkgs/os-specific/linux/intel-sgx/default.nix Outdated Show resolved Hide resolved
pkgs/os-specific/linux/intel-sgx/default.nix Outdated Show resolved Hide resolved
pkgs/os-specific/linux/intel-sgx/default.nix Outdated Show resolved Hide resolved
pkgs/os-specific/linux/intel-sgx/default.nix Outdated Show resolved Hide resolved
pkgs/os-specific/linux/intel-sgx/sgx1/default.nix Outdated Show resolved Hide resolved
pkgs/os-specific/linux/intel-sgx/sgx1/default.nix Outdated Show resolved Hide resolved
pkgs/os-specific/linux/intel-sgx/sgx1/default.nix Outdated Show resolved Hide resolved
pkgs/os-specific/linux/intel-sgx/dcap/default.nix Outdated Show resolved Hide resolved
pkgs/os-specific/linux/intel-sgx/dcap/default.nix Outdated Show resolved Hide resolved
Copy link
Member

@Mic92 Mic92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not in favor in packaging out-dated kernel drivers in nixpkgs. Kernel modules need a lot of maintenance so the latest version is often necessary. Also this old driver requires applying kernel patches applied to all kernels. SGX also has strict security requirements, which is why I would very much prefer the latest version. I am not aware of version incompatibilities with the later SGX kernel driver. The other components aesmd et all, are fine.

@RealityAnomaly
Copy link
Member Author

I am not in favor in packaging out-dated kernel drivers in nixpkgs. Kernel modules need a lot of maintenance so the latest version is often necessary. Also this old driver requires applying kernel patches applied to all kernels. SGX also has strict security requirements, which is why I would very much prefer the latest version. I am not aware of version incompatibilities with the later SGX kernel driver. The other components aesmd et all, are fine.

Since the current isgx driver appears to work fine on my system, I'm going to drop my SGX1 and DCAP commits along with the kernel patch.

@RealityAnomaly
Copy link
Member Author

Did some more testing, and apparently the current version of the isgx module we have is not supported by all platforms, namely, the Intel CPU in my tablet that does not support FLC. The version I had was using the latest unstable master version. I will add a commit to this PR that updates it to the unstable version.

@sbellem
Copy link
Contributor

sbellem commented Jul 10, 2021

Hi @citadelcore! Thanks for your work! I attempted a pull request (#126990) a few weeks ago for the SGX SDK alone. Our works partially overlap, and it probably will not make sense to keep my PR up.

The main motivation for my approach was reproducibility. Consequently, the IPP Crypto library is built from source, addressing concerns expressed in intel/linux-sgx#363. Also, since recent versions of binutils contain the mitigations that Intel includes in their prebuilt binaries, (see intel/linux-sgx#719 (comment)), I simply used the recent binutils from nixpkgs.

From the point of view of reproducible builds, if the IPP Crypto is not built from source, a verifier will need to use Intel's toolchain to verify the reproducibility of the IPP Crypto, which is very cumbersome. Same reasoning goes for binutils.

@RealityAnomaly
Copy link
Member Author

Thanks, this is interesting! I'll look into integrating an ippcrypto derviation into this PR in order to make things reproductible.

@sbellem
Copy link
Contributor

sbellem commented Jul 10, 2021

Although the IPP Crypto library has its own repository, for the SGX SDK, it is built from the source code of the linux-sgx repository. I wrote a derivation for it at https://github.com/NixOS/nixpkgs/pull/126990/files#diff-bcead6f21cf360352863772a4cc6011209461ecba27e7b5f39540f2c64c26f36.

As mentioned in intel/linux-sgx#719, the header file sgx_ippcp,h is missing. I added it in a linux-sgx fork, for the above derivation, as a proof-of-concept. It seems to me that this is something Intel could address.

You probably won't need this, but just in case it can be useful: https://github.com/initc3/sgx-ipp-crypto gives an idea of what is more or less strictly necessary to build IPP Crypto for SGX.

@sbellem
Copy link
Contributor

sbellem commented Jul 10, 2021

@citadelcore Out of curiosity, for the sdk, is there a specific reason why you install things "manually" via multiple cp commands as opposed to using the installer generated when invoking make sdk_install_pkg

sdk_install_pkg: sdk
	./linux/installer/bin/build-installpkg.sh sdk cve-2020-0551

I did this in my PR https://github.com/NixOS/nixpkgs/blob/f00ed27355fab3584fa5bba97cac347b0cb81fd7/pkgs/os-specific/linux/sgxsdk/default.nix#L77-L86

I am just curious. I assume you had a good reason to do so, especially given the extra tedious work required.


substituteInPlace psw/ae/aesm_service/source/CMakeLists.txt \
--replace '/usr/bin/getconf' '${getconf}/bin/getconf'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick to make editorconfig-checker happy:

Suggested change

@@ -0,0 +1,296 @@
{ type, debug ? false }:
assert builtins.elem type [ "sdk" "psw" ];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert builtins.elem type [ "sdk" "psw" ];
# SDK: Software development kit for developing enclave applications
# PSW: Platform software to run the enclaves
assert builtins.elem type [ "sdk" "psw" ];

@sbellem
Copy link
Contributor

sbellem commented Jul 10, 2021

Regarding the sgx version, 2.13.3 is the latest and contains bug fixes.

@veehaitch
Copy link
Member

FWIW, we created packages for the SGX SDK & PSW and a module as well. I just published our flake: https://github.com/yaxitech/nix-linux-sgx

Maybe it is helpful to advance this PR 🙂

Copy link
Member

@veehaitch veehaitch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your work (and also @sbellem)! Looking forward to having this merged.

serviceConfig = {
ExecStart = "${path}/aesm_service --no-daemon";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
ExecStartPre = [ "${pkgs.coreutils}/bin/mkdir -p /var/opt/aesmd/data /var/opt/aesmd/fwdir/data" ];
Copy link
Member

@veehaitch veehaitch Aug 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also leverage systemd sandboxing using StateDirectory and BindPaths to avoid the system-wide FHS path and tmpfiles.

RuntimeDirectoryMode = "0755";
ReadWritePaths = [ "/var/opt/aesmd" ];

# Hardening
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really appreciate all the effort you've put into hardening. We should definitely have that but I wonder how tried and tested this configuration is as the upstream service definition does not declare any hardening. Do you run this service in production somewhere or can you share any other experiences?

Copy link
Member

@Mic92 Mic92 Aug 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my own experience with running aesmd and systemd hardening option, the option chosen here looks fine.
It looks scary of the high number but to be honest most services should not do the majority of options that were disabled here. I also prefer remove hardening afterwards rather than breaking existing setups by adding more hardening later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upstream probably don't care as much about adding them because they might target some old redhat linux that does not have those hardening options yet.

installPhase =
let build = "build/linux";
in
if type == "sdk" then ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I'd prefer a common base derivation with two distinct derivations over a flag. In fact, the SDK is a dependency of the PSW package and also in general they have different dependencies.

homepage = "https://01.org/intel-softwareguard-extensions";
license = licenses.bsd3;
maintainers = with maintainers; [ citadelcore ];
platforms = platforms.linux;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The packages also only work on x86_64:

Suggested change
platforms = platforms.linux;
platforms = [ "x86_64-linux" ];

mkdir -p $out/etc/udev/rules.d
cp linux/installer/common/libsgx-enclave-common/91-sgx-enclave.rules $out/etc/udev/rules.d/
cp linux/installer/common/sgx-aesm-service/92-sgx-provision.rules $out/etc/udev/rules.d/
'';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea to compile and run some of the SDK samples in simulation mode in the installCheckPhase. That way we can have some confidence the SDK is working.

https://github.com/yaxitech/nix-linux-sgx/blob/7aea4d11910d011b37a3f5bc1daa9307a86b15c2/pkgs/intel-sgx/sdk.nix#L205-L241

@sbellem
Copy link
Contributor

sbellem commented Aug 4, 2021

Hey @citadelcore, @veehaitch, @arcz, and @SuperSandro2000, I am a bit confused about what to do with my PR at #126990. It has received reviews from @arcz and @SuperSandro2000 which I have tried to address as best as I could so far. @arcz has also been helping to improve the nix pkg for the IPP Crypto library in the original PR (#126990). His proof-of-concept is at https://github.com/arcz/nixpkgs/tree/553f8e22d35ef060f5c4de19d0d0d575206c9a66/pkgs/os-specific/linux/sgx-sdk.

My PR was primarily focused on the SDK and IPP-Crypto library (a dependency), as the goal is to provide a reproducible SDK build, fully built from source, which can be used as a building block in user-defined enclaves, thus allowing these enclaves to also be built reproducibly. This is very important for audits.

After consulting with Intel, I did not bother to work on the PSW, because from the point of view of reproducible enclave builds, the PSW is not involved, as it's a runtime component.

Now, my understanding is that this PR addresses a broader set of concerns, most notably that of making the SGX SDK & PSW available on NixOS, which is great.

It does not however fully address the issue of reproducible builds, as pointed out in comments #129432 (comment) &
#129432 (comment). The IPP Crypto library can be built from source, and from the point of view of reproducible builds and audits my understanding is that it's preferable to do so, as explained in the comments.

So this brings us back to the opening statement of this comment, which is that we have 2 partially overlapping pull requests, both proposing to add a package for the SGX SDK.

Moreover, in addition to the two PRs, we have works in:

It seems to me that a consolidating effort would make sense (?) ... Any feedback welcome!

Please note that I am new to the nix community, and hence I am not aware of how this particular repository manages its very high number of pull requests.

@Mic92
Copy link
Member

Mic92 commented Aug 4, 2021

Hey @citadelcore, @veehaitch, @arcz, and @SuperSandro2000, I am a bit confused about what to do with my PR at #126990. It has received reviews from @arcz and @SuperSandro2000 which I have tried to address as best as I could so far. @arcz has also been helping to improve the nix pkg for the IPP Crypto library in the original PR (#126990). His proof-of-concept is at https://github.com/arcz/nixpkgs/tree/553f8e22d35ef060f5c4de19d0d0d575206c9a66/pkgs/os-specific/linux/sgx-sdk.

I was about to merge this PR when you came up and proposed to build it from source, which @citadelcore also confirmed.
I would be still ok with merging this PR here first and than adding improvements on top. Also your PR is still marked as draft, which usually people don't merge or even look at.

@veehaitch
Copy link
Member

My PR was primarily focused on the SDK and IPP-Crypto library (a dependency), as the goal is to provide a reproducible SDK build, fully built from source, which can be used as a building block in user-defined enclaves, thus allowing these enclaves to also be built reproducibly. This is very important for audits.

I wholeheartedly agree that having a fully reproducible SDK is very important and that reproducibility didn't yet get the attention it should. Ideally, we'd have bit-perfect reproducibility of the SDK and all its (transitive) dependencies (maybe similar to what we have for the minimal ISO). Therefore, it makes a lot of sense to integrate your efforts and we should continue to go down that road.

Maybe an incremental approach makes sense: First, add working packages for the SDK and PSW. Together with a module, this would already allow anybody to create and test SGX applications on NixOS. This is what the present PR does. Second, make the SDK reproducible. As far as I understand, this also requires upstream changes and, ideally, Intel should also adopt the approach we come up with to supersede the Nix derivation they—after a fashion—currently use. I don't know how eager they are to achieve proper reproducibility with Nix although it makes a lot of sense for all parties involved. Nevertheless, we should push for that. Happy to lend a hand and join forces.

@RealityAnomaly
Copy link
Member Author

It doesn't look like it'd be much effort to add reproducibility from @sbellem's PR into mine. As it seems fairly straightforward, I'll do that as soon as I can and update this.

@veehaitch
Copy link
Member

Any news here, @citadelcore 🙂

@Artturin
Copy link
Member

Artturin commented Oct 2, 2021

fyi #131618 (comment)

Found warning on systemlog:

/nix/store/69fq5zlibddvbx46km0xcn0y3li1bnqf-systemd-249.4/lib/udev/rules.d/50-udev-default.rules:42  Unknown group 'sgx', ignoring

cat /nix/store/69fq5zlibddvbx46km0xcn0y3li1bnqf-systemd-249.4/lib/udev/rules.d/50-udev-default.rules

...
SUBSYSTEM=="misc", KERNEL=="sgx_enclave", GROUP="sgx", MODE="0660"
...


driver = mkOption {
type = types.package;
default = pkgs.linuxPackages.isgx;
Copy link
Contributor

@blitz blitz Oct 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be config.boot.kernelPackages.isgx. Otherwise, it will mix up kernel modules and kernel with different versions.

As a side note: Newer kernels come with SGX support built-in, but I'm not sure whether this is a realistic option just yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the in-tree SGX support works just fine! 🙂

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we could flip the SGX kernel option on for newer kernels by default and get rid of the third-party module.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have a modern Atom to test this on next week or so.

@blitz
Copy link
Contributor

blitz commented Oct 14, 2021

@citadelcore It would be really awesome to get this into nixpkgs! If there is something, you need help with, just say so. :)

@tomberek
Copy link
Contributor

tomberek commented Nov 8, 2021

I've been seeing this:

Oct 29 09:20:35 tframe systemd-udevd[1214]: /nix/store/27855idyr8dkmh0xrzg7jln7a3fa7viy-systemd-249.4/lib/udev/rules.d/50-udev-default.rules:42 Unknown group 'sgx', ignoring

Is this related? Should there be a users.groups.sgx.gid?

Due to systemd/systemd-stable@c9c4899

assert builtins.elem type [ "sdk" "psw" ];

{ lib
, pkgs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
, pkgs


makeFlags = [ type ]
# include the path to the SDK for PSW builds which depend on it
++ lib.optional (type == "psw") "SGX_SDK=${pkgs.intel-sgx-sdk}/usr/share/sgxsdk"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
++ lib.optional (type == "psw") "SGX_SDK=${pkgs.intel-sgx-sdk}/usr/share/sgxsdk"
++ lib.optional (type == "psw") "SGX_SDK=${intel-sgx-sdk}/usr/share/sgxsdk"

buildInputs = [
curl
openssl
] ++ (lib.optional (type == "psw") pkgs.intel-sgx-sdk);
Copy link
Member

@SuperSandro2000 SuperSandro2000 Nov 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
] ++ (lib.optional (type == "psw") pkgs.intel-sgx-sdk);
] ++ lib.optional (type == "psw") intel-sgx-sdk;

@@ -20603,6 +20603,9 @@ in

intel-ocl = callPackage ../os-specific/linux/intel-ocl { };

intel-sgx-sdk = callPackage (import ../os-specific/linux/intel-sgx { type = "sdk"; }) { };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With #126990 in the tree, I think this PR now needs to be rebased.

@veehaitch veehaitch mentioned this pull request Dec 4, 2021
13 tasks
@Artturin Artturin mentioned this pull request Dec 4, 2021
13 tasks
@veehaitch
Copy link
Member

Following #126990, #148584, and #147693, I created a PR to add the sgx-psw package and the aesmd module: #148593. It's supposed to replace this PR and incorporates some work from it. I'd appreciate your reviews 🙂

@blitz
Copy link
Contributor

blitz commented Dec 6, 2021

Following #126990, #148584, and #147693, I created a PR to add the sgx-psw package and the aesmd module: #148593. It's supposed to replace this PR and incorporates some work from it. I'd appreciate your reviews slightly_smiling_face

#148593 looks very good. From my point this PR is obsolete and can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants