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

sgxs-sign support offline signing #327

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
112 changes: 110 additions & 2 deletions sgxs-tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,117 @@ token.
## sgxs-sign

`sgxs-sign` generates a SIGSTRUCT given an SGX stream and user-specified
parameters. You can generate a fresh private key using the `openssl genrsa`
command like so:
parameters. It also supports a multi-step signing process, which is suggested to
keep the enclave signing key protected.

### Subcommands

#### sign

This is the one step signing process. It is also the default command. If the
`sgxs-sign` tool is used without a specified subcommand, this is the command
that is executed as to maintain backward compatibility with previous versions of
the `sgxs-sign` tool.

#### gendata

This is the first step in the multi-step signing process. It outputs the hash of
the sigstruct that must be signed by the the enclave signing key.

#### catsig

This is the final step in the multi-step signing process. It takes the
signature, public key, and the enclave parameters used in `gendata` to generate
a SIGSTRUCT. If the same options are _not_ used in both `gendata` and `catsig`,
`catsig` will fail to create a valid SIGSTRUCT.

#### verify

This command takes a public key of an enclave signer and a previously created
SIGSTRUCT and validates that the signature matches the public key. This _does
not_ validate an enclave hash to be correct. This simply ensures correctness in
the SIGSTRUCT itself.

### Usage

#### Generating a key

You can generate a fresh private key using the `openssl genrsa` command like so:

```
openssl genrsa -3 3072 > private.pem
```

#### Multi-step Signing Example

Multi-step signing allows enclave signing keys to be kept offline, preferrably
in some HSM. The following example uses `openssl` and a locally generated key as
an example, however, it is suggested that the key be stored in a more secure
location than in plaintext on disk.

##### Generate a key

Like above, we will generate a valid key for enclave signing. This must be a
3072-bit RSA key with a public exponent of 3. Do this like so:

```bash
openssl genrsa -3 3072 > private.pem
```

We will also need the public key in a later step so let's also generate this
now.

```bash
openssl rsa -in private.pem -pubout > public.pem
```

##### Generate signing data for your enclave

Generating signing data is done with the `gendata` subcommand, like so:

```bash
sgxs-sign gendata [options] [enclave_input] [sigstruct_hash_output]
```

_See `sgxs-sign gendata --help` for details on available options_

For purposes of this example, let's assume your enclave is named `foo.sgxs`. You
would generate data to sign like so:

```bash
sgxs-sign gendata foo.sgxs foo.sigstruct.sha256.bin
```

The output file `foo.sigstruct.sha256.bin` contains the sha256 hash of the
SIGSTRUCT fields to be signed.

##### Sign the SIGSTRUCT hash

To sign the SIGSTRUCT you must create a signature using the `RSASSA-PKCS1-v1_5`
scheme. The following command will do so with `openssl`. If you're using an HSM,
your device may have a different process for generating a signature of this
type.

```bash
openssl pkeyutl -sign \
-in foo.sigstruct.sha256.bin \
-inkey private.pem \
-out foo.sigstruct.sha256.sig \
-pkeyopt digest:sha256
```

##### Create the SIGSTRUCT with catsig

With the signature in `foo.sigstruct.sha256.sig` we can now generate a valid
SIGSTRUCT.

```bash
sgxs-sign catsig \
--signature foo.sigstruct.sha256.sig \
--public-key public.pem \
foo.sgxs \
foo.sig
```

If there are no errors, `foo.sig` will contain a valid SIGSTRUCT that was signed
by `private.pem`.