diff --git a/Documentation/index.rst b/Documentation/index.rst index c6a3c894..b1954dfd 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -52,6 +52,12 @@ Table of Contents sgx-intro glossary +.. toctree:: + :caption: Tutorials + :maxdepth: 2 + + tutorials/pytorch/index.rst + .. toctree:: :caption: Manual pages :maxdepth: 1 diff --git a/Documentation/tutorials/pytorch/img/intro-01.svg b/Documentation/tutorials/pytorch/img/intro-01.svg new file mode 100644 index 00000000..8a18b81f --- /dev/null +++ b/Documentation/tutorials/pytorch/img/intro-01.svg @@ -0,0 +1,3 @@ + + + Produced by OmniGraffle 6.6.2 2020-07-14 23:28:53 +0000Canvas 1Layer 1New DataUntrained ModelTrainingTraining DataTrained ModelInferenceResultcatno cat“cat” diff --git a/Documentation/tutorials/pytorch/img/workflow.svg b/Documentation/tutorials/pytorch/img/workflow.svg new file mode 100644 index 00000000..af6c507e --- /dev/null +++ b/Documentation/tutorials/pytorch/img/workflow.svg @@ -0,0 +1 @@ +Secret Prov libPyTorchGraphene LibOSUntrusted machineRA-TLS libTrusted machineSecret ProviderRA-TLS libSecret Prov libQuote VerificationIntel® Provisioning Certification ServiceExpected measure-mentsCertificatesCRLsFile storageModelInput imageOutput \ No newline at end of file diff --git a/Documentation/tutorials/pytorch/index.rst b/Documentation/tutorials/pytorch/index.rst new file mode 100644 index 00000000..78cb3eba --- /dev/null +++ b/Documentation/tutorials/pytorch/index.rst @@ -0,0 +1,573 @@ +PyTorch PPML Framework Tutorial +=============================== + +.. highlight:: sh + +This tutorial presents a framework for developing PPML (Privacy-Preserving +Machine Learning) applications with Intel SGX and Graphene. We use `PyTorch +`__ as an example ML framework. However, this tutorial can +be applied to other ML frameworks like OpenVINO, TensorFlow, etc. + +Introduction +------------ + +Machine Learning (ML) is increasingly utilized in many real-world applications. +ML algorithms are first trained on massive amounts of known past data and then +deployed to interpret unknown future data, which allows us to forecast weather, +classify images, recommend content, and so on. + +As machine learning pervades our daily lives, privacy concerns emerge as one of +the key issues about this technology. In this tutorial, we focus on protecting +the confidentiality and integrity of the input data when the computation takes +place on an untrusted platform such as a public cloud virtual machine. We also +protect the model for cases where the model owner is concerned about protecting +their IP. In particular, we highlight how to build the PPML framework based on +PyTorch in an untrusted cloud using Intel SGX and Graphene. + +.. image:: ./img/intro-01.svg + :target: ./img/intro-01.svg + :alt: Figure: Training and inference in ML workloads + +In general, ML workloads have two phases: training and inference. Both can be +viewed as an application that takes inputs and produces an output. Training +applications take a training dataset as input and produce a trained model. +Inference applications take new data and the trained model as inputs and produce +the result (the prediction). + +The goal of this tutorial is to show how these applications -- PyTorch workloads +in particular -- can run in an untrusted environment (like a public cloud), +while still ensuring the confidentiality and integrity of sensitive input data +and the model. To this end, we use Intel SGX enclaves to isolate PyTorch's +execution to protect data confidentiality and integrity, and to provide a +cryptographic proof that the program is correctly initialized and running on +legitimate hardware with the latest patches. We also use Graphene to simplify +the task of porting PyTorch to SGX, without any changes to the ML application +and scripts. + +.. image:: ./img/workflow.svg + :target: ./img/workflow.svg + :alt: Figure: Complete workflow of PyTorch with Graphene + +In this tutorial, we will show the complete workflow for PyTorch running inside +an SGX enclave using Graphene and its features of Secret Provisioning and +Protected Files. We rely on the new ECDSA/DCAP remote attestation scheme +developed by Intel for untrusted cloud environments. + +To run the PyTorch application on a particular SGX platform, the owner of the +SGX platform must retrieve the corresponding SGX certificate from the Intel +Provisioning Certification Service, along with Certificate Revocation Lists +(CRLs) and other SGX-identifying information (1). Typically, this is a part of +provisioning the SGX platform in a cloud or a data center environment, and the +end user can access it as a service (in other words, the end user doesn't need +to deal with the details of this SGX platform provisioning but instead uses a +simpler interface provided by the cloud/data center vendor). + +As a second preliminary step, the user must encrypt the input and model files +with her cryptographic (wrap) key and send these protected files to the remote +storage accessible from the SGX platform (2). + +Next, the remote platform starts PyTorch inside of the SGX enclave. Meanwhile, +the user starts the secret provisioning application on her own machine. The two +machines establish a TLS connection using RA-TLS (3), the user verifies that the +remote platform has a genuine up-to-date SGX processor and that the application +runs in a genuine SGX enclave (4), and finally provisions the cryptographic wrap +key to this remote platform (5). Note that during build time, Graphene informs +the user of the expected measurements of the SGX application. + +After the cryptographic wrap key is provisioned, the remote platform may start +executing the application. Graphene uses Protected FS to transparently decrypt +the input and the model files using the provisioned key when the PyTorch +application starts (6). The application then proceeds with execution on +plaintext files (7). When the PyTorch script is finished, the output file is +encrypted with the same cryptographic key and saved to the cloud provider's file +storage (8). At this point, the protected output may be forwarded to the remote +user who will decrypt it and analyze its contents. + +Prerequisites +------------- + +- Ubuntu 18.04. This tutorial should work on other Linux distributions as well, + but for simplicity we provide the steps for Ubuntu 18.04 only. + + Please install the following dependencies:: + + sudo apt install libnss-mdns libnss-myhostname + +- PyTorch (Python3). PyTorch is a framework for machine learning based on + Python. Please `install PyTorch `__ + before you proceed (don't forget to choose Linux as the target OS). We will + use Python3 in this tutorial. + +- Intel SGX Driver and SDK/PSW. You need a machine that supports Intel SGX and + FLC/DCAP. Please follow `this guide + `__ + to install the Intel SGX driver and SDK/PSW. Make sure to install the driver + with ECDSA/DCAP attestation. + +- Graphene. Follow `Quick Start + `__ to build + Graphene. In this tutorial, we will use both non-SGX and SGX-backed versions + of Graphene. Make sure you build both Graphene loaders (``Runtime/pal-Linux`` + for non-SGX version and ``Runtime/pal-Linux-SGX`` for SGX version). + +Executing Native PyTorch +------------------------ + +We start with a very simple example script written in Python3 for PyTorch-based +ML inferencing. Graphene already provides a minimalistic and *insecure* `PyTorch +example `__ +which does not have confidentiality guarantees for input/output files and does +not use remote attestation. In this tutorial, we will use this existing PyTorch +example as a basis and will improve it to protect all user files. + +Go to the directory with Graphene's PyTorch example:: + + cd /Examples/pytorch + +The directory contains a Python script ``pytorchexample.py`` and other relevant +files. The script reads a `pretrained AlexNet model +`__ and an image +``input.jpg``, and infers the class of an object in the image. Then, the script +writes the top-5 classification results to a file ``result.txt``. + +We first download and save the pre-trained AlexNet model:: + + make download_model + +This command uses the ``download-pretrained-model.py`` script to download a +pretrained model and save it as a serialized file ``alexnet-pretrained.pt``. +See `Saving and Loading Models in PyTorch +`__ for more +details. + +Now simply run the following command to run PyTorch inferencing:: + + python3 pytorchexample.py + +This will execute native PyTorch which will write the classification results to +``result.txt``. The provided example image is a photo of a dog, therefore the +output file contains "Labrador retriever" as a first result. + +In later sections, we will run exactly the same Python script but with Graphene +and inside SGX enclaves. + +Executing PyTorch with Graphene +------------------------------- + +In the next two sections, we will run the exact same PyTorch example with +Graphene. We will first run PyTorch with non-SGX Graphene (for illustrative +purposes) and then with SGX-backed Graphene. Note that this part of the tutorial +still only shows the non-PPML workflow where Graphene doesn't protect +input/output user files; the end-to-end PPML workflow will be described below. + +The porting effort to run PyTorch in Graphene is minimal and boils down to +creation of the *Graphene PyTorch-specific manifest file*. When Graphene runs +an executable, it reads a manifest file that describes the execution environment +including the security posture, environment variables, dynamic libraries, +arguments, and so on. In the rest of this tutorial, we will create this +manifest file and explain its options and rationale behind them. Note that the +manifest file contains both general non-SGX options for Graphene and +SGX-specific ones. Please refer to `this +`__ for further +details about the syntax of Graphene manifests. + +Executing PyTorch with non-SGX Graphene +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Let's run the PyTorch example using Graphene, but without an SGX enclave. + +Navigate to the PyTorch example directory we examined in the previous section:: + + cd /Examples/pytorch + +Let's take a look at the template manifest file ``pytorch.manifest.template``. +For illustrative purposes, we will look at only a few entries of the file. Note +that we can simply ignore SGX-specific keys (starting with the ``sgx.`` prefix) +for our non-SGX run. + +The executable for the PyTorch workload is ``python3`` (recall that PyTorch is a +collection of libraries and utilities but it uses Python as an actual +executable), which is located at the host path ``/usr/bin/python3``:: + + loader.exec = file:/usr/bin/python3 + +Notice that the manifest file is not fully secure because it propagates +untrusted command-line arguments and environment variables into the enclave. We +keep these work-arounds in this tutorial for simplicity, but this configuration +must not be used in production:: + + loader.insecure__use_cmdline_argv = 1 + loader.insecure__use_host_env = 1 + +We mount the entire ``/Runtime/`` host-level directory to +the ``/lib`` directory seen inside Graphene. This trick allows to transparently +replace standard C libraries with Graphene-patched libraries:: + + fs.mount.lib.type = chroot + fs.mount.lib.path = /lib + fs.mount.lib.uri = file:$(GRAPHENEDIR)/Runtime/ + +We also mount other directories such as ``/usr``, ``/etc``, and ``/tmp`` +required by Python and PyTorch (they search for libraries and utility files in +these system directories). + +Finally, we mount the path containing the Python packages installed via pip:: + + fs.mount.pip.type = chroot + fs.mount.pip.path = $(HOME)/.local/lib + fs.mount.pip.uri = file:$(HOME)/.local/lib + +Now we can run ``make`` to build/copy all required Graphene files:: + + make + +This command will autogenerate a couple new files: + +#. Generate the actual non-SGX Graphene manifest (``pytorch.manifest``) from the + template manifest file. This file will be used by Graphene to decide on + different manifest options how to execute PyTorch inside Graphene. + +#. Create a symbolic link to the generic Graphene loader (``pal_loader``). This + is just for convenience. + +Now, launch Graphene with the generated manifest via ``pal_loader``. You can +simply append the arguments after the manifest name. Our example takes +``pytorchexample.py`` as an argument:: + + ./pal_loader pytorch.manifest pytorchexample.py + +That's it. You have run the PyTorch example with Graphene. You can check +``result.txt`` to make sure it ran correctly. + +Executing PyTorch with Graphene in SGX Enclave +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In this section, we will learn how to use Graphene to run the same PyTorch +example inside an Intel SGX enclave. Let's go back to the manifest template +(recall that the manifest keys starting with ``sgx.`` are SGX-specific syntax; +these entries are ignored if Graphene runs in non-SGX mode). + +Below, we will highlight some of the SGX-specific manifest options in +``pytorch.manifest.template``. SGX syntax is fully described `here +`__. + +First, here are the following SGX-specific lines in the manifest template:: + + sgx.trusted_files.ld = file:$(GRAPHENEDIR)/Runtime/ld-linux-x86-64.so.2 + sgx.trusted_files.libc = file:$(GRAPHENEDIR)/Runtime/libc.so.6 + ... + +``sgx.trusted_files.`` specifies a file that will be verified and trusted +by the SGX enclave. Note that the key string ```` may be an arbitrary +legal string (but without ``-`` and other special symbols) and does not have to +be the same as the actual file name. + +The way these Trusted Files work is before Graphene runs PyTorch inside the SGX +enclave, Graphene generates the final SGX manifest file using ``pal-sgx-sign`` +Graphene utility. This utility calculates hashes of each trusted file and +appends them as ``sgx.trusted_checksum.`` to the final SGX manifest. When +running PyTorch with SGX, Graphene reads trusted files, finds their +corresponding trusted checksums, and compares the calculated-at-runtime checksum +against the expected value in the manifest. + +The PyTorch manifest template also contains ``sgx.allowed_files.`` +entries. They specify files unconditionally allowed by the enclave:: + + sgx.allowed_files.pythonhome = file:$(HOME)/.local/lib + +This line unconditionally allows all Python libraries in the path to be loaded +into the enclave. Ideally, the developer needs to replace it with +``sgx.trusted_files`` for each of the dependent Python libraries. + +Allowed files are *not* cryptographically hashed and verified. Thus, this is +*insecure* and discouraged for production use (unless you are sure that the +contents of the files are irrelevant to security of your workload). Here, we use +these allowed files only for simplicity. A next tutorial on PyTorch (with Docker +integration) replaces all allowed files with trusted/protected files (that +tutorial is work in progress). + +There is also the following line in the manifest template:: + + sgx.allow_file_creation = 1 + +This allows the enclave to generate new files. We need this since the PyTorch +Python script writes the result to ``result.txt``. + +Now we desribed how the manifest template looks like and what the SGX-specific +manifest entries represent. Let's prepare all the files needed to run PyTorch in +an SGX enclave:: + + make SGX=1 + +The above command performs the following tasks: + +#. Generates the final SGX manifest file ``pytorch.manifest.sgx``. + +#. Signs the manifest and generates the SGX signature file containing SIGSTRUCT + (``pytorch.sig``). + +#. Creates a dummy EINITTOKEN token file ``pytorch.token`` (this file is used + for backwards compatibility with SGX platforms with EPID and without Flexible + Launch Control). + +After running this command and building all the required files, we can simply +set ``SGX=1`` environment variable and use ``pal_loader`` to launch the PyTorch +workload inside an SGX enclave:: + + SGX=1 ./pal_loader pytorch.manifest.sgx pytorchexample.py + +It will run exactly the same Python script but inside the SGX enclave. Again, +you can verify that PyTorch ran correctly by examining ``result.txt``. + +End-To-End Confidential PyTorch Workflow +---------------------------------------- + +Background on Remote Attestation, RA-TLS and Secret Provisioning +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Intel SGX provides a way for the SGX enclave to attest itself to the remote +user. This way the user gains trust in the SGX enclave running in an untrusted +environment, ships the application code and data, and is sure that the *correct* +application was executed inside a *genuine* SGX enclave. This process of gaining +trust in a remote SGX machine is called Remote Attestation (RA). + +Graphene has two features that transparently add SGX RA to the application: (1) +RA-TLS augments normal SSL/TLS sessions with an SGX-specific handshake callback, +and (2) Secret Provisioning establishes a secure SSL/TLS session between the SGX +enclave and the remote user so that the user may gain trust in the remote +enclave and provision secrets to it. Secret Provisioning builds on top of RA-TLS +and typically runs before the application. Both features are provided as opt-in +libraries. + +The Secret Provisioning library provides a simple non-programmatic API to +applications: it transparently initializes the environment variable +``SECRET_PROVISION_SECRET_STRING`` with a secret obtained from the remote user +during remote attestation. In our PyTorch example, the provisioned secret is the +confidential (master, or wrap) key to encrypt/decrypt user files. To inform +Graphene that the obtained secret is indeed the key for file encryption, it is +enough to set the environment variable ``SECRET_PROVISION_SET_PF_KEY``. + +Note that RA-TLS and Secret Provisioning work both with the EPID-based and the +ECDSA/DCAP schemes of SGX remote attestation. Since this tutorial concentrates +on an untrusted-cloud scenario, we use the ECDSA/DCAP attestation framework. + +Background on Protected Files +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Graphene provides a feature of `Protected Files +`__, +which encrypts files and transparently decrypts them when the application reads +or writes them. Integrity- or confidentiality-sensitive files (or whole +directories) accessed by the application must be marked as protected files in +the Graphene manifest. New files created in a protected directory are +automatically treated as protected. The encryption format used for protected +files is borrowed from the similar feature of Intel SGX SDK. + +This feature can be combined with Secret Provisioning such that the files are +encrypted/decrypted using the provisioned wrap key, as explained in the previous +section. + +Preparing Confidential PyTorch Example +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In this section, we will transform our native PyTorch application into an +end-to-end confidential application. We will encrypt all user files before +starting the enclave, mark them as protected, let the enclave communicate with +the secret provisioning server to get attested and receive the master wrap key +for encryption and decryption of protected files, and finally run the actual +PyTorch inference. + +We will use the previous non-confidential PyTorch example as a starting point, +so copy the entire PyTorch directory:: + + cd /Examples + cp -R pytorch pytorch-confidential + +We will also use the reference implementation of Secret Provisioning found under +``Examples/ra-tls-secret-prov`` directory, so build and copy all the relevant +files from there:: + + cd /Examples/ra-tls-secret-prov + make -C ../../Pal/src/host/Linux-SGX/tools/ra-tls dcap + make dcap pf_crypt + +The second line in the above snippet creates Graphene-specific DCAP libraries +for preparation and verification of SGX quotes (needed for SGX remote +attestation). The last line builds the required DCAP binaries and copies +relevant Graphene utilities such as ``pf_crypt`` to encrypt input files. + +The last line also builds the secret provisioning server +``secret_prov_server_dcap``. We will use this server to provision the master +wrap key (used to encrypt/decrypt protected input and output files) to the +PyTorch enclave. See `Secret Provisioning Minimal Examples +`__ +for more information. + +Preparing Input Files +^^^^^^^^^^^^^^^^^^^^^ + +The user must encrypt all input files: ``input.jpg``, ``classes.txt``, and +``alexnet-pretrained.pt``. For simplicity, we re-use the already-existing stuff +from the ``Examples/ra-tls-secret-prov`` directory. In particular, we re-use +the confidential wrap key:: + + cd /Examples/pytorch-confidential + mkdir files + cp ../ra-tls-secret-prov/files/wrap-key files/ + +In real deployments, the user must replace this ``wrap-key`` with her own +128-bit encryption key. + +We also re-use the ``pf_crypt`` utility (with its ``libsgx_util.so`` helper +library and required mbedTLS libraries) that encrypts/decrypts the files:: + + cp ../ra-tls-secret-prov/libsgx_util.so . + cp ../ra-tls-secret-prov/libmbed*.so* . + cp ../ra-tls-secret-prov/pf_crypt . + +Let's also make sure that ``alexnet-pretrained.pt`` network-model file exists +under our new directory:: + + make download_model + +Now let's encrypt the original plaintext files. We first move these files under +the ``plaintext/`` directory and then encrypt them using the wrap key:: + + mkdir plaintext/ + mv input.jpg classes.txt alexnet-pretrained.pt plaintext/ + + LD_LIBRARY_PATH=. ./pf_crypt encrypt -w files/wrap-key -i plaintext/input.jpg -o input.jpg + LD_LIBRARY_PATH=. ./pf_crypt encrypt -w files/wrap-key -i plaintext/classes.txt -o classes.txt + LD_LIBRARY_PATH=. ./pf_crypt encrypt -w files/wrap-key -i plaintext/alexnet-pretrained.pt -o alexnet-pretrained.pt + +You can verify now that the input files are encrypted. In real deployments, +these files must be shipped to the remote untrusted cloud. + +Preparing Secret Provisioning +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The user must prepare the secret provisioning server and start it. For this, +copy the secret provisioning executable and its helper library from +``Examples/ra-tls-secret-prov`` to the current directory:: + + cp ../ra-tls-secret-prov/libsecret_prov_verify_dcap.so . + cp ../ra-tls-secret-prov/secret_prov_server_dcap . + +Also, copy the server-identifying certificates so that in-Graphene secret +provisioning library can verify the provisioning server (via classical X.509 +PKI):: + + cp -R ../ra-tls-secret-prov/certs ./ + +These certificates are dummy mbedTLS-provided certificates; in production, you +would want to generate real certificates for your secret-provisioning server and +use them. + +Now we can launch the secret provisioning server:: + + ./secret_prov_server_dcap & + +In this tutorial, we simply run it locally (``localhost:4433`` as configured in +the manifest) for simplicity. In reality, the user must run it on a trusted +remote machine. In that case, ``loader.env.SECRET_PROVISION_SERVERS`` in the +manifest (see below) must point to the address of the remote-user machine. We +launch the server in the background. + +Preparing Manifest File +^^^^^^^^^^^^^^^^^^^^^^^ + +Finally, let's modify the manifest file. Open ``pytorch.manifest.template`` +with your favorite text editor. + +Replace ``trusted_files`` with ``protected_files`` for the input files:: + + # sgx.trusted_files.classes = file:classes.txt + sgx.protected_files.classes = file:classes.txt + + # sgx.trusted_files.image = file:input.jpg + sgx.protected_files.image = file:input.jpg + + # sgx.trusted_files.model = file:alexnet-pretrained.pt + sgx.protected_files.model = file:alexnet-pretrained.pt + +Also add ``result.txt`` as a protected file so that PyTorch writes the +*encrypted* result into it:: + + sgx.protected_files.result = file:result.txt + +Now, let's add the secret provisioning library to the manifest. Append the +current directory ``./`` to ``LD_LIBRARY_PATH`` so that PyTorch and Graphene +add-ons search for libraries in the current directory:: + + # this instructs in-Graphene dynamic loader to search for dependencies in the current directory + loader.env.LD_LIBRARY_PATH = /lib:/usr/lib:$(ARCH_LIBDIR):/usr/$(ARCH_LIBDIR):./ + +Add the following lines to enable remote secret provisioning and allow protected +files to be transparently decrypted by the provisioned key. Recall that we +launched the secret provisioning server locally on the same machine, so we +re-use the same ``certs/`` directory and specify ``localhost``. For more info on +the used environment variables and other manifest options, see `here +`__:: + + sgx.remote_attestation = 1 + + loader.env.LD_PRELOAD = libsecret_prov_attest.so + loader.env.SECRET_PROVISION_CONSTRUCTOR = 1 + loader.env.SECRET_PROVISION_SET_PF_KEY = 1 + loader.env.SECRET_PROVISION_CA_CHAIN_PATH = "certs/test-ca-sha256.crt" + loader.env.SECRET_PROVISION_SERVERS = "localhost:4433" + + sgx.trusted_files.libsecretprovattest = file:libsecret_prov_attest.so + sgx.trusted_files.cachain = file:certs/test-ca-sha256.crt + +The ``libsecret_prov_attest.so`` library provides the in-enclave logic to attest +the SGX enclave, Graphene instance, and the application running in it to the +remote secret-provisioning server. Graphene needs to locate this library, so +let's copy it to our working directory:: + + cp ../ra-tls-secret-prov/libsecret_prov_attest.so ./ + +Building and Executing End-To-End PyTorch Example +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now that we prepared the files and the manifest, let's re-generate the manifest +files, tokens, and signatures:: + + make clean + make SGX=1 + +It is also important to remove the file ``result.txt`` if it exists. Otherwise +the Protected FS will detect the already-existing file and fail. So let's remove +it unconditionally:: + + rm -f result.txt + +We are ready to run the end-to-end PyTorch example. Notice that we didn't change +a line of code in the Python script. Moreover, we can run it with exactly the +same command used in the previous section:: + + SGX=1 ./pal_loader pytorch.manifest pytorchexample.py + +This should run PyTorch with encrypted input files and generate the encrypted +``result.txt`` output file. Note that we already launched the secret +provisioning server on the same machine, so secret provisioning will run +locally. + +Decrypting Output File +^^^^^^^^^^^^^^^^^^^^^^ + +After our protected PyTorch inference is finished, you'll see ``result.txt`` in +the directory. This file is encrypted with the same key as was used for +encryption of input files. In order to decrypt it, use the following command:: + + LD_LIBRARY_PATH=. ./pf_crypt decrypt -w files/wrap-key -i result.txt -o plaintext/result.txt + +You can check the result written in ``plaintext/result.txt``. It must be the +same as in our previous runs. + +Cleaning Up +^^^^^^^^^^^ + +When done, don't forget to terminate the secret provisioning server:: + + killall secret_prov_server_dcap diff --git a/Examples/pytorch/Makefile b/Examples/pytorch/Makefile index f2be2a8f..a58d32b8 100644 --- a/Examples/pytorch/Makefile +++ b/Examples/pytorch/Makefile @@ -31,7 +31,7 @@ endif UBUNTU_VERSION = $(DISTRIB_ID)$(DISTRIB_RELEASE) .PHONY: all -all: pytorch.manifest python3.manifest pal_loader alexnet-pretrained.pt +all: pytorch.manifest python3.manifest pal_loader ifeq ($(SGX),1) all: pytorch.token python3.token endif @@ -65,7 +65,7 @@ python3.manifest: pytorch.manifest cp $< $@ sed -i '/trusted_children/d' $@ -python3.sig: python3.manifest alexnet-pretrained.pt +python3.sig: python3.manifest $(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/pal-sgx-sign \ -libpal $(GRAPHENEDIR)/Runtime/libpal-Linux-SGX.so \ -key $(SGX_SIGNER_KEY) \ @@ -74,15 +74,14 @@ python3.sig: python3.manifest alexnet-pretrained.pt pal_loader: ln -s $(GRAPHENEDIR)/Runtime/pal_loader $@ -alexnet-pretrained.pt: download_model - .PHONY: download_model download_model: $(PYTHON3) download-pretrained-model.py .PHONY: clean clean: - $(RM) *.token *.sig *.manifest.sgx *.manifest pal_loader *.pt result.txt + $(RM) *.token *.sig *.manifest.sgx *.manifest pal_loader .PHONY: distclean distclean: clean + $(RM) *.pt result.txt diff --git a/Examples/pytorch/README.md b/Examples/pytorch/README.md index 9c50f574..6b239ef4 100644 --- a/Examples/pytorch/README.md +++ b/Examples/pytorch/README.md @@ -19,7 +19,8 @@ With high probability (41%) the classifier detected the image to contain a Labra The following steps should suffice to run the workload on a stock Ubuntu 16.04 and 18.04 installation. -- `sudo apt-get install python3-pip lsb-release` to install `pip` and `lsb_release`. The former is +- `sudo apt install libnss-mdns libnss-myhostname` to install additional DNS-resolver libraries. +- `sudo apt install python3-pip lsb-release` to install `pip` and `lsb_release`. The former is required to install additional Python packages while the latter is used by the Makefile. - `pip3 install --user torchvision pillow` to install the torchvision and pillow Python packages and their dependencies (usually in $HOME/.local). WARNING: This downloads several hundred megabytes of diff --git a/Examples/pytorch/pytorch.manifest.template b/Examples/pytorch/pytorch.manifest.template index 5d4527f5..e21ef733 100644 --- a/Examples/pytorch/pytorch.manifest.template +++ b/Examples/pytorch/pytorch.manifest.template @@ -20,6 +20,8 @@ loader.insecure__use_cmdline_argv = 1 # Propagate environment variables from the host. Don't use this on production! loader.insecure__use_host_env = 1 + +# Overwrite some environment variables loader.env.LD_LIBRARY_PATH = /lib:/usr/lib:$(ARCH_LIBDIR):/usr/$(ARCH_LIBDIR) # Default glibc files, mounted from the Runtime directory in GRAPHENEDIR @@ -86,6 +88,7 @@ sgx.trusted_files.libpthread = file:$(GRAPHENEDIR)/Runtime/libpthread.so.0 sgx.trusted_files.libresolv = file:$(GRAPHENEDIR)/Runtime/libresolv.so.2 sgx.trusted_files.librt = file:$(GRAPHENEDIR)/Runtime/librt.so.1 sgx.trusted_files.libutil = file:$(GRAPHENEDIR)/Runtime/libutil.so.1 +sgx.trusted_files.libnssdns = file:$(GRAPHENEDIR)/Runtime/libnss_dns.so.2 sgx.trusted_files.libstdc = file:/usr/$(ARCH_LIBDIR)/libstdc++.so.6 sgx.trusted_files.libgccs = file:$(ARCH_LIBDIR)/libgcc_s.so.1 @@ -108,10 +111,12 @@ sgx.trusted_files.libmpdec = file:/usr/$(ARCH_LIBDIR)/libmpdec.so.2 # Ubuntu18.04 sgx.trusted_files.libssl = file:/usr/$(ARCH_LIBDIR)/libssl.so.1.1 # Name Service Switch (NSS) libraries (Glibc dependencies) -sgx.trusted_files.libnssfiles = file:$(ARCH_LIBDIR)/libnss_files.so.2 -sgx.trusted_files.libnsscompat = file:$(ARCH_LIBDIR)/libnss_compat.so.2 -sgx.trusted_files.libnssnis = file:$(ARCH_LIBDIR)/libnss_nis.so.2 -sgx.trusted_files.libnsl = file:$(ARCH_LIBDIR)/libnsl.so.1 +sgx.trusted_files.libnssfiles = file:$(ARCH_LIBDIR)/libnss_files.so.2 +sgx.trusted_files.libnsscompat = file:$(ARCH_LIBDIR)/libnss_compat.so.2 +sgx.trusted_files.libnssnis = file:$(ARCH_LIBDIR)/libnss_nis.so.2 +sgx.trusted_files.libnsl = file:$(ARCH_LIBDIR)/libnsl.so.1 +sgx.trusted_files.libnssmyhostname = file:$(ARCH_LIBDIR)/libnss_myhostname.so.2 +sgx.trusted_files.libnssmdns = file:$(ARCH_LIBDIR)/libnss_mdns4_minimal.so.2 # The script to run sgx.trusted_files.script = file:pytorchexample.py @@ -146,16 +151,24 @@ sgx.allowed_files.python3 = file:/usr/lib/python3 sgx.allowed_files.pythonhome = file:$(HOME)/.local/lib # Ubuntu16.04 sgx.allowed_files.python35 = file:/usr/lib/python3.5 # Ubuntu18.04 sgx.allowed_files.python36 = file:/usr/lib/python3.6 +# Ubuntu16.04 sgx.allowed_files.python35local = file:/usr/local/lib/python3.5 +# Ubuntu18.04 sgx.allowed_files.python36local = file:/usr/local/lib/python3.6 -# Some Python package wants to access these files on Ubuntu 16.04 -# Ubuntu16.04 sgx.allowed_files.aptconfd = file:/etc/apt/apt.conf.d -# Ubuntu16.04 sgx.allowed_files.aptconf = file:/etc/apt/apt.conf -# Ubuntu16.04 sgx.allowed_files.apport = file:/etc/default/apport +# APT config files +sgx.allowed_files.aptconfd = file:/etc/apt/apt.conf.d +sgx.allowed_files.aptconf = file:/etc/apt/apt.conf +sgx.allowed_files.apport = file:/etc/default/apport # Name Service Switch (NSS) files (Glibc reads these files) -sgx.trusted_files.nsswitch = file:/etc/nsswitch.conf -sgx.trusted_files.group = file:/etc/group -sgx.trusted_files.passwd = file:/etc/passwd +sgx.allowed_files.nsswitch = file:/etc/nsswitch.conf +sgx.allowed_files.group = file:/etc/group +sgx.allowed_files.passwd = file:/etc/passwd + +# DNS hostname resolution files (Glibc reads these files) +sgx.allowed_files.hostconf = file:/etc/host.conf +sgx.allowed_files.hosts = file:/etc/hosts +sgx.allowed_files.gaiconf = file:/etc/gai.conf +sgx.allowed_files.resolv = file:/etc/resolv.conf # Graphene optionally provides patched OpenMP runtime library that runs faster # inside SGX enclaves (execute `make -C LibOS gcc` to generate it). Uncomment