snpguest 0.9.2

Navigation utility for AMD SEV-SNP guest environment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# snpguest

`snpguest` is a Command Line Interface utility for managing an AMD SEV-SNP enabled guest. This tool allows users to interact with the AMD SEV-SNP guest firmware device enabling various operations such as: attestation, certificate management, derived key fetching, and more.

- [Usage](#usage)
  - [1. help](#1-help)
  - [2. certificates](#2-certificates)
  - [3. display](#3-display)
  - [4. fetch](#4.fetch)
  - [5. key](#5-key)
  - [6. report](#6-report)
  - [7. verify](#7-verify)
  - [Global Options](#global-options)
- [Extended Attestation Workflow](#extended-attestation-workflow)
- [Regular Attestation Workflow](#regular-attestation-workflow)
- [Extended Attestation Flowchart](#extended-attestation-flowchart)
- [Regular Attestation Flowchart](#regular-attestation-flowchart)
- [Building](#building)
  - [Ubuntu Dependencies](#ubuntu-dependencies)
  - [RHEL and its compatible distributions dependencies](#rhel-and-its-compatible-distributions-dependencies)
  - [openSUSE and its compatible distributions dependencies](#opensuse-and-its-compatible-distributions-dependencies)
  - [Building for Azure Confidential VMs](#building-for-azure-confidential-vms)
- [Reporting Bugs](#reporting-bugs)

## Usage

### 1. `help`

Every `snpguest` (sub)command comes with a `--help` option for a description on its use. 

**Usage**
```bash
snpguest --help
```

### 2. `certificates` 

Requests the VEK certificate chain (ARK, ASK/ASVK and VCEK/VLEK) from host memory (requests extended-config). The user needs to specify the certificate encoding to store the certificates in (PEM or DER). Currently, only PEM and DER encodings are supported. All certificates will be in the same encoding. The user also needs to provide the path to the directory where the certificates will be stored. If certificates already exist in the provided directory, they will be overwritten.

**Usage**
```bash
snpguest certificates $ENCODING $CERTS_DIR
```

**Arguments**

- `$ENCODING` : Specifies the certificate encoding to store the certificates in (PEM or DER).

- `$CERTS_DIR` : Specifies the directory to store the certificates in. This is required only when requesting an extended attestation report.

**Example**
```bash
snpguest certificates pem ./certs
```

### 3. `display` 

Displays files in human readable form. 

**Usage**
```bash
snpguest display <SUBCOMMAND>
```

**Subcommands**

1. `report`

    When used for displaying a report, it prints the attestation report contents into the terminal. The user has to provide the path of the stored attestation report to display.

    **Usage**
    ```bash
    snpguest display report $ATT_REPORT_PATH
    ```

    **Argument**

    - `$ATT_REPORT_PATH` : Specifies the path of the stored attestation report to display.

    **Example**
    ```bash
    snpguest display report attestation-report.bin
    ```

2. `key`

    When used for displaying the fetched derived key's contents, it prints the derived key in hex format into the terminal. The user has to provide the path of a stored derived key to display.

    **Usage**

    ```bash
    snpguest display key $KEY_PATH
    ```
    **Argument**

    - `$KEY_PATH` : Specifies the path of the stored derived key to display.

    **Example**
    ```bash
    snpguest display key derived-key.bin
    ```

### 4. `fetch`

Command to Requests certificates from the KDS.

**Usage**
```bash
snpguest fetch <SUBCOMMAND>
```

**Subcommands**
1. `ca`

    Requests the certificate authority chain (ARK & ASK/ASVK) from the KDS. The user needs to specify the certificate encoding to store the certificates in (PEM or DER). Currently, only PEM and DER encodings are supported. Both certificates will be in the same encoding. The user must specify their host processor model. The user also needs to provide the path to the directory where the certificates will be stored. If the certificates already exist in the provided directory, they will be overwritten. The `--endorser` argument specifies the type of attestation signing key (defaults to VCEK).

    **Usage**
    ```bash
    # Fetch CA chain of the user-provided processor model
    snpguest fetch ca $ENCODING $CERTS_DIR $PROCESSOR_MODEL --endorser $ENDORSER
    # Fetch CA chain of the processor-model written in the attestation report
    snpguest fetch ca $ENCODING $CERTS_DIR --report $ATT_REPORT_PATH --endorser $ENDORSER
    ```
    
    **Arguments**
    | Argument | Description | Default |
    | :--      | :--        | :--    |
    | `$ENCODING` | Specifies the certificate encoding to store the certificates in (PEM or DER). | required |
    | `$CERTS_DIR` | Specifies the directory to store the certificates in. | required |
    | `$PROCESSOR_MODEL` | Specifies the host processor model (conflict with `$ATT_REPORT_PATH`). | required |
    | `-r, --report $ATT_REPORT_PATH` | Specifies the attestation report to detect the host processor model (conflict with `$PROCESSOR_MODEL`) | — |
    | `-e, --endorser $ENDORSER` | Specifies the endorser type, possible values: "vcek", "vlek". | "vcek" |

    Example
    ```bash
    snpguest fetch ca der ./certs-kds milan -e vlek
    ```
    ```bash
    snpguest fetch ca pem ./certs-kds -r attestation-report.bin -e vcek
    ```

2. `vcek`

    Requests the VCEK certificate from the KDS. The user needs to specify the certificate encoding to store the certificate in (PEM or DER). Currently, only PEM and DER encodings are supported. The user must specify their host processor model. The user also needs to provide the path to the directory where the VCEK will be stored and the path to a stored attestation report that will be used to request the VCEK. If the certificate already exists in the provided directory, it will be overwritten.

    **Usage**
    ```bash
    snpguest fetch vcek $ENCODING $CERTS_DIR $ATT_REPORT_PATH --processor-model $PROCESSOR_MODEL
    ```

    **Arguments**
    | Argument | Description | Default |
    | :--      | :--        | :--    |
    | `$ENCODING` | Specifies the certificate encoding to store the certificates in (PEM or DER). | required |
    | `$CERTS_DIR` | Specifies the directory to store the certificates in. | required |
    | `$ATT_REPORT_PATH` | Specifies the path of the stored attestation report. | required |
    | `-p, --processor-model $PROCESSOR_MODEL` | Specifies the host processor model. | — |

    **Example**
    ```bash
    snpguest fetch vcek pem ./certs-kds attestation-report.bin
    ```

### 5. `key` 

Creates the derived key based on input parameters and stores it. `$KEY_PATH` is the path to store the derived key. `$ROOT_KEY_SELECT` is the root key from which to derive the key (either "vcek" or "vmrk"). The `--guest_field_select` option specifies which Guest Field Select bits to enable as a binary string of length 6 or 7. Each of the bits from *right to left* correspond to Guest Policy, Image ID, Family ID, Measurement, SVN and TCB Version, Launch Mitigation Vector, respectively. For each bit, 0 denotes off, and 1 denotes on. The `--guest_svn` option specifies the guest SVN to mix into the key, the `--tcb_version` option specifies the TCB version to mix into the derived key, and the `--launch_mit_vector` option specifies the launch mitigation vector value to mix into the derived key. The `--vmpl` option specifies the VMPL level the Guest is running on and defaults to 1.

**Usage**
```bash
snpguest key $KEY_PATH $ROOT_KEY_SELECT [-v, --vmpl] [-g, --guest_field_select] [-s, --guest_svn] [-t, --tcb_version]
```

**Arguments**
| Argument | Description | Default |
| :--      | :--        | :--    |
| `$KEY_PATH` | The path to store the derived key. | required |
| `$ROOT_KEY_SELECT` | is the root key from which to derive the key (either "vcek" or "vmrk"). | required |
| `-v, --vmpl $VMPL` | option specifies the VMPL level the Guest is running on. | 1 |
| `-g, --guest_field_select $GFS` | option specifies which Guest Field Select bits to enable as a binary string (length 6 or 7). For each bit, 0 denotes off, and 1 denotes on. | all 0s |
| `-s, --guest_svn $GSVN` | option specifies the guest SVN to mix into the key. | — |
| `-t, --tcb_version $TCBV` | option specifies the TCB version to mix into the derived key. | — |
| `-l, --launch_mit_vector $LMV` | option specifies the launch mitigation vector value to mix into the derived key (only available for `MSG_KEY_REQ` version ≥ 2 ). | — |

**Guest Field Select**

| Bit      | Field             | Note |
| :--      | :--               | :--  |
| 0 (LSB)  | Guest Policy      |      |
| 1        | Image ID          |      |
| 2        | Family ID         |      |
| 3        | Measurement       |      |
| 4        | SVN               |      |
| 5        | TCB Version       |      |
| 6 (MSB)  | Launch MIT Vector | Set to 0 if not specified; supported for `MSG_KEY_REQ` version ≥ 2. |
| (7–63)   | (Reserved)        | Currently not supported. |

For example, `--guest_field_select 110001` denotes 
```
Guest Policy:On (1), 
Image ID:Off (0), 
Family ID: Off (0), 
Measurement: Off (0), 
SVN:On (1), 
TCB Version:On (1),
Launch MIT Vector: Off (none).
```

**Example**
```bash
# Creating and storing a derived key
snpguest key derived-key.bin vcek --guest_field_select 110001 --guest_svn 2 --tcb_version 1 --vmpl 3
```

### 6. `report` 

Requests an attestation report from the host and writes it to a file with the provided request data and VMPL. The attestation report is written in binary format to the specified report path. The user can pass 64 bytes of data in any file format into `$REQUEST_FILE` to request the attestation report. This data will be bound to the REPORT_DATA field of the attestation report. The `--random` flag can be used to generate and use random data for the request, which will be written into `$REQUEST_FILE`. For Microsoft Azure Confidential VM, the `--platform` flag is required to get an attestation report from the vTPM. With this flag, the request data provided by the hypervisor will be written into the `$REQUEST_FILE`. `VMPL` is an optional parameter that defaults to 1.

**Usage**
```bash
snpguest report $ATT_REPORT_PATH $REQUEST_FILE [-v, --vmpl] [-r, --random] [-p, --platform]
```

**Arguments**
| Argument | Description | Default |
| :--      | :--        | :--    |
| `$ATT_REPORT_PATH` | Specifies the path where the attestation report would be stored. | required |
| `$REQUEST_FILE` | Specifies the path to the 64-byte request file. <br>• With `-r` flag, 64 random bytes will be written. <br>• With `-p` flag, writes 64 bytes provided by the hypervisor will be written. <br>• Without flags, the existing file contents are read as-is. | required |
| `-v, --vmpl $VMPL` | option specifies the VMPL level the Guest is running on.| 1 |
| `-r, --random` | Generate 64 random bytes of data for the report request. | false |
| `-p, --platform` | Fetch an attestation report from the vTPM NV index (Only available for Azure CVMs). | false |

**Example**
```bash
# Requesting Attestation Report with user-generated data
snpguest report attestation-report.bin request-file.bin
# Requesting Attestation Report using random data
snpguest report attestation-report.bin random-request-file.bin --random
# Get Pregenerated Attestation Report and Request Data from vTPM
snpguest report attestation-report.bin platform-request-file.bin --platform
```

### 7. `verify` 

Verifies certificates and the attestation report.

**Usage**
```bash
snpguest verify <SUBCOMMAND>
```

**Subcommands**
1. `certs`

    Verifies that the provided certificate chain has been properly signed by each certificate. The user needs to provide a directory where all three certificates (ARK, ASK/ASVK and VCEK/VLEK) are stored. An error will be raised if any of the certificates fail verification.

    **Usage**
    ```bash
    snpguest verify certs $CERTS_DIR
    ```
    **Argument**

    - `$CERTS_DIR` : Specifies the directory where the certificates are stored in. 

    **Example**
    ```bash
    snpguest verify certs ./certs
    ```

2. `attestation`

    Verifies the contents of the Attestation Report using the VCEK/VLEK certificate. The user needs to provide the path to the directory containing the VCEK/VLEK certificate and the path to a stored attestation report to be verified. An error will be raised if the attestation verification fails at any point. The user can use the `-t, --tcb` flag to only validate the TCB contents of the report and the `-s, --signature` flag to only validate the report's signature.

    **Usage**
    ```bash
    snpguest verify attestation $CERTS_DIR $ATT_REPORT_PATH [-t, --tcb] [-s, --signature]
    ```
    **Arguments**

    - `$CERTS_DIR` : Specifies the directory where the certificates are stored in. 

    - `$ATT_REPORT_PATH` : Specifies the path of the stored attestation report.

    **Options**

    - `-t, --tcb`: Verify the Reported TCB section of the report only.
    - `-s, --signature`: Verify the signature of the report only.

    **Example**
    ```bash
    # Verify Attestation
    snpguest verify attestation ./certs attestation-report.bin
    # Verify Attestation Reported TCB only
    snpguest verify attestation ./certs attestation-report.bin --tcb
    # Verify Attestation Signature only
    snpguest verify attestation ./certs attestation-report.bin --signature
    ```

### Global Options

- **-q, --quiet**: Suppress console output.

**Usage**
```bash
snpguest -q <SUBCOMMAND>
```

### [Extended Attestation Workflow](#extended-attestation-flowchart)

**Step 1.** Request the attestation report by providing the two mandatory parameters - `$ATT_REPORT_PATH` which is the path pointing to where the user wishes to store the attestation report and `$REQUEST_FILE` which is the path pointing to where the request file used to request the attestation report is stored. The optional parameter \[`-v, --vmpl`\] specifies the vmpl level for the attestation report and is set to 1 by default. The flag \[`-r, --random`\] generates random data to be used as request data for the attestation report. Lastly, the flag \[`-p, --platform`\] obtains both the attestation report and the request data from the platform (only available for a Microsoft Azure CVM where Hyper-V guest is enabled).

```bash
snpguest report $ATT_REPORT_PATH $REQUEST_FILE [-v, --vmpl] [-r, --random] [-p, --platform]
```

**Step 2.** Request certificates from the extended memory by providing the two mandatory parameters - `$ENCODING` which specifies whether to use PEM or DER encoding to store the certificates and $CERTS_DIR which specifies the path in the user's directory where the certificates will be saved.

```bash
snpguest certificates $ENCODING $CERTS_DIR
```

In some environments, only the VCEK/VLEK certificate can be obtained. In this case, you must follow the procedure described in [Regular Attestation Workflow](#regular-attestation-workflow) to obtain an AMD CA certificates.

**Step 3.** Verify the certificates obtained from the extended memory by providing `$CERTS_DIR` which specifies the path in the user's directory where the certificates were saved from Step 2.

```bash
snpguest verify certs $CERTS_DIR
```

**Step 4.** Verify the attestation by providing the two mandatory parameters - `$CERTS_DIR` which specifies the path in the user's directory where the certificates were saved from Step 2 and `$ATT_REPORT_PATH` which is the path pointing to the stored attestation report which the user wishes to verify. The optional parameters \[`-t, --tcb`\] is used to verify just the Reported TCB contents of the attestaion report and \[`-s, --signature`\] is used to verify just the signature of the attestaion report.

```bash
snpguest verify attestation $CERTS_DIR $ATT_REPORT_PATH [-t, --tcb] [-s, --signature]
```

### [Regular Attestation Workflow](#regular-attestation-flowchart)

**Step 1.** Request the attestation report by providing the two mandatory parameters - `$ATT_REPORT_PATH` which is the path pointing to where the user wishes to store the attestation report and `$REQUEST_FILE` which is the path pointing to where the request file used to request the attestation report is stored. The optional parameter \[`-v, --vmpl`\] specifies the vmpl level for the attestation report and is set to 1 by default. The flag \[`-r, --random`\] generates random data to be used as request data for the attestation report. Lastly, the flag \[`-p, --platform`\] obtains both the attestation report and the request data from the platform (only available for a Microsoft Azure CVM where Hyper-V guest is enabled).

```bash
snpguest report $ATT_REPORT_PATH $REQUEST_FILE [-v, --vmpl] [-r, --random] [-p, --platform]
```

**Step 2.** Request AMD Root Key (ARK) and AMD SEV Key (ASK) (or AMD SEV-VLEK Key (ASVK) for VLEK) from the AMD Key Distribution Service (KDS) by providing the three mandatory parameters - `$ENCODING` which specifies whether to use PEM or DER encoding to store the certificates, `$CERTS_DIR` which specifies the path in the user's directory where the certificates will be saved, and `$PROCESSOR_MODEL` - which specifies the AMD Processor model for which the certificates are to be fetched. The optional `-e, --endorser` argument specifies the type of attestation signing key (defaults to VCEK).

```bash
snpguest fetch ca $ENCODING $CERTS_DIR $PROCESSOR_MODEL [-e, --endorser] $ENDORSER
```

**Step 3.** Request the Versioned Chip Endorsement Key (VCEK) from the AMD Key Distribution Service (KDS) by providing the three mandatory parameters - `$ENCODING` which specifies whether to use PEM or DER encoding to store the certificates, `$CERTS_DIR` which specifies the path in the user's directory where the certificates will be saved, and `$ATT_REPORT_PATH` which is the path pointing to the stored attestation report for detecting Chip ID and Reported TCB Version. The optional \[`-p, --processor-model`\] argument specifies the AMD Processor model for which the certificates are to be fetched.

```bash
snpguest fetch vcek $ENCODING $CERTS_DIR $ATT_REPORT_PATH [-p, --processor-model] $PROCESSOR_MODEL
```

**Step 4.** Verify the certificates obtained by providing `$CERTS_DIR` which specifies the path in the user's directory where the certificates were saved from Step 2.

```bash
snpguest verify certs $CERTS_DIR
```

**Step 5.** Verify the attestation by providing the two mandatory parameters - `$CERTS_DIR` which specifies the path in the user's directory where the certificates were saved from Step 2 and `$ATT_REPORT_PATH` which is the path pointing to the stored attestation report which the user wishes to verify. The optional parameters \[`-t, --tcb`\] is used to verify just the Reported TCB contents of the attestaion report and \[`-s, --signature`\] is used to verify just the signature of the attestaion report.

```bash
snpguest verify attestation $CERTS_DIR $ATT_REPORT_PATH [-t, --tcb] [-s, --signature]
```

## Extended Attestation Flowchart
![alt text](https://github.com/virtee/snpguest/blob/main/docs/extended.PNG?raw=true)
## Regular Attestation Flowchart
![alt text](https://github.com/virtee/snpguest/blob/main/docs/regular.PNG?raw=true)

## Building

Some packages may need to be installed on the host system in order to build `snpguest`.

```bash
#Rust Installation
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"

#Building snpguest after cloning
cargo build -r
```
### Ubuntu Dependencies

```bash
sudo apt install build-essential
```

### RHEL and its compatible distributions Dependencies

```bash
sudo dnf groupinstall "Development Tools" "Development Libraries"
```

### openSUSE and its compatible distributions Dependencies

```bash
sudo zypper in -t pattern "devel_basis"
```

### Building for Azure Confidential VMs
On Azure CVMs with AMD SEV-SNP, the paravisor fetches the report from AMD-SP once at VM boot time, and stores it in the vTPM NV index. The native `/dev/sev-guest` interface is hidden from the guest OS, so the guest OS must retrieve the report from the vTPM NV index using the `--platform` flag, which is available only in builds compiled with the `hyperv` feature.

```bash
git clone https://github.com/virtee/snpguest
cd ./snpguest
cargo build -r --features hyperv
```

## Reporting Bugs

Please report all bugs to the [Github snpguest](https://github.com/virtee/snpguest/issues) repository.