Skip to content

Commit 93a27a2

Browse files
authored
Merge pull request #40 from lmilleri/ibmse
Fix IBM SE verifier
2 parents 417ea0e + 321ad89 commit 93a27a2

File tree

4 files changed

+277
-42
lines changed

4 files changed

+277
-42
lines changed

attestation-service/verifier/src/se/README.md

Lines changed: 93 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
1-
# Deployment of KBS with IBM SE verifier
1+
2+
# KBS with IBM SE verifier
23

34
This is a document to guide developer run a KBS with IBM SE verifier locally for development purpose.
45

6+
## Index
7+
8+
- [Deployment of KBS with IBM SE verifier](#deployment-of-kbs-with-ibm-se-verifier)
9+
- [Set attestation policy for IBM SE verifier](#set-attestation-policy)
10+
11+
12+
13+
# Deployment of KBS with IBM SE verifier
14+
15+
This section is about deployment of KBS without rvps checking.
16+
517
## Generate RSA keys
618
Generate RSA 4096 key pair following commands:
7-
```
19+
```bash
820
openssl genrsa -aes256 -passout pass:test1234 -out encrypt_key-psw.pem 4096
921
openssl rsa -in encrypt_key-psw.pem -passin pass:test1234 -pubout -out encrypt_key.pub
1022
openssl rsa -in encrypt_key-psw.pem -out encrypt_key.pem
@@ -20,30 +32,41 @@ ibm-z-host-key-signing-gen2.crt
2032
DigiCertCA.crt
2133

2234
### CRL
23-
ibm-z-host-key-gen2.crl
35+
ibm-z-host-key-gen2.crl
36+
DigiCertTrustedRootG4.crl
37+
DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl
38+
39+
Note: `DigiCertTrustedRootG4.crl` and `DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl` come from commands as below:
40+
```bash
41+
# openssl x509 -in DigiCertCA.crt --text --noout |grep crl
42+
URI:http://crl3.digicert.com/DigiCertTrustedRootG4.crl
43+
# openssl x509 -in ibm-z-host-key-signing-gen2.crt --text --noout |grep crl
44+
URI:http://crl3.digicert.com/DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl
45+
URI:http://crl4.digicert.com/DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl
46+
```
2447

2548
## Download HKD
2649
Download IBM Secure Execution Host Key Document following: https://www.ibm.com/docs/en/linux-on-z?topic=execution-verify-host-key-document
2750

2851
## Get SE Header
2952
Build `se.img` following [Generate an IBM Secure Execution image](https://www.ibm.com/docs/en/linux-on-systems?topic=commands-genprotimg) and retrieve the hdr.bin via command like below.
30-
```
53+
```bash
3154
./pvextract-hdr -o hdr.bin se.img
3255
```
3356

3457
Refer [ibm-s390-linux](https://github.com/ibm-s390-linux/s390-tools/blob/v2.33.1/rust/pvattest/tools/pvextract-hdr) to get `pvextract-hdr`.
3558

3659
## Generate KBS key
3760
Generate keys used by KBS service.
38-
```
61+
```bash
3962
openssl genpkey -algorithm ed25519 > kbs.key
4063
openssl pkey -in kbs.key -pubout -out kbs.pem
4164
```
4265

4366
## (Option 1) Launch KBS as a program
4467

4568
- Build KBS
46-
```
69+
```bash
4770
cargo install --locked --debug --path kbs/src/kbs --no-default-features --features coco-as-builtin,openssl,resource,opa
4871
```
4972

@@ -56,6 +79,8 @@ cargo install --locked --debug --path kbs/src/kbs --no-default-features --featur
5679
| └── DigiCertCA.crt
5780
├── crls
5881
│ └── ibm-z-host-key-gen2.crl
82+
│ └── DigiCertTrustedRootG4.crl
83+
│ └── DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl
5984
├── hdr
6085
│ └── hdr.bin
6186
├── hkds
@@ -92,25 +117,24 @@ remote_addr = ""
92117
```
93118

94119
- Launch the KBS program
95-
```
120+
```bash
96121
export RUST_LOG=debug
97122
export SE_SKIP_CERTS_VERIFICATION=true
98123
./kbs --config-file ./kbs-config.toml
99124
```
100125

101-
> Note: `SE_SKIP_CERTS_VERIFICATION=true` only required for a development machine.
126+
> Note: `export SE_SKIP_CERTS_VERIFICATION=true` only required for a development machine. Use `export CERTS_OFFLINE_VERIFICATION=true` to verifiy the certificates offline.
102127
103128
## (Option 2) Launch KBS via docker-compose
104129
- Build the docker image
105130
```
106-
DOCKER_BUILDKIT=1 docker build -t ghcr.io/confidential-containers/staged-images/kbs:latest --build-arg KBS_FEATURES=coco-as-builtin,openssl,resource,opa . -f kbs/docker/Dockerfile
131+
DOCKER_BUILDKIT=1 docker build --build-arg HTTPS_CRYPTO="openssl" --build-arg ARCH="s390x" -t ghcr.io/confidential-containers/staged-images/kbs:latest . -f kbs/docker/Dockerfile
107132
```
108-
>Note: Please add `--debug` in statement like `cargo install` in file `kbs/docker/Dockerfile` if you're using a development host key document to skip HKD's signature verification.
109133

110134
- Prepare a docker compose file, similar as:
111135
```
112136
services:
113-
web:
137+
kbs:
114138
image: ghcr.io/confidential-containers/staged-images/kbs:latest
115139
command: [
116140
"/usr/local/bin/kbs",
@@ -135,7 +159,7 @@ services:
135159
- ./data/rsa/encrypt_key.pem:/run/confidential-containers/ibmse/rsa/encrypt_key.pem
136160
- ./data/rsa/encrypt_key.pub:/run/confidential-containers/ibmse/rsa/encrypt_key.pub
137161
```
138-
> Note: `SE_SKIP_CERTS_VERIFICATION=true` only required for a development machine.
162+
> Note: `export SE_SKIP_CERTS_VERIFICATION=true` only required for a development machine. Use `export CERTS_OFFLINE_VERIFICATION=true` to verifiy the certificates offline.
139163
140164
- Prepare the material, similar as:
141165
```
@@ -149,6 +173,8 @@ services:
149173
│   │   └── DigiCertCA.crt
150174
│   ├── crls
151175
│   │   └── ibm-z-host-key-gen2.crl
176+
│ │ └── DigiCertTrustedRootG4.crl
177+
│ │ └── DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl
152178
│   ├── hdr.bin
153179
│   ├── hkds
154180
│   │   └── HKD-3931-0275D38.crt
@@ -167,10 +193,63 @@ services:
167193
```
168194

169195
- Launch KBS as docker compose application
170-
```
196+
```bash
171197
docker-compose up -d
172-
docker-compose logs web
198+
docker-compose logs kbs
173199
docker-compose down
174200
```
175201

176202

203+
# Set attestation policy
204+
205+
This section is about setting attestation policy.
206+
207+
### Retrive the attestation policy fields for IBM SE
208+
209+
Using [se_parse_hdr.py](se_parse_hdr.py) on a s390x instance to retrieve the IBM SE fields for attestation policy.
210+
211+
```bash
212+
python3 se_parse_hdr.py hdr.bin HKD-3931.crt
213+
214+
...
215+
================================================
216+
se.image_phkh: xxx
217+
se.version: 256
218+
se.tag: xxx
219+
se.attestation_phkh: xxx
220+
```
221+
222+
We get following fields and will set these fields in rvps for attestation policy.
223+
`se.version: 256`
224+
`se.tag: xxx`
225+
`se.attestation_phkh: xxx`
226+
`se.image_phkh: xxx`
227+
228+
229+
### Set attestation policy
230+
231+
#### Generate attestation policy file
232+
```bash
233+
cat << EOF > ibmse-policy.rego
234+
package policy
235+
import rego.v1
236+
default allow = false
237+
238+
converted_version := sprintf("%v", [input["se.version"]])
239+
240+
allow if {
241+
input["se.attestation_phkh"] == "xxx"
242+
input["se.image_phkh"] == "xxx"
243+
input["se.tag"] == "xxx"
244+
input["se.user_data"] == "xxx"
245+
converted_version == "256"
246+
}
247+
EOF
248+
```
249+
250+
Where the values `se.version`, `se.attestation_phkh`, `se.image_phkh` and `se.tag` come from [retrive-the-rvps-field-for-an-ibm-se-image](#retrive-the-rvps-field-for-an-ibm-se-image). The value `se.user_data` comes from [initdata](https://github.com/confidential-containers/cloud-api-adaptor/blob/main/src/cloud-api-adaptor/docs/initdata.md). Please remove `input["se.user_data"] == "xxx"` if `initdata` is not used.
251+
252+
#### Set the attestation policy
253+
```bash
254+
kbs-client --url http://127.0.0.1:8080 config --auth-private-key ./kbs/kbs.key set-attestation-policy --policy-file ./ibmse-policy.rego
255+
```

attestation-service/verifier/src/se/ibmse.rs

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ pub struct SeAttestationResponse {
9090
pub struct SeAttestationClaims {
9191
#[serde_as(as = "Hex")]
9292
cuid: ConfigUid,
93-
#[serde_as(as = "Hex")]
94-
user_data: Vec<u8>,
93+
user_data: String,
9594
version: u32,
9695
#[serde_as(as = "Hex")]
9796
image_phkh: Vec<u8>,
@@ -160,12 +159,12 @@ impl SeVerifierImpl {
160159
fn encrypt(&self, text: &[u8]) -> Result<Vec<u8>> {
161160
let mut encrypter = Encrypter::new(&self.public_key)?;
162161
encrypter.set_rsa_padding(Padding::PKCS1)?;
163-
162+
164163
let buffer_len = encrypter.encrypt_len(text)?;
165164
let mut encrypted = vec![0; buffer_len];
166165
let len = encrypter.encrypt(text, &mut encrypted)?;
167166
encrypted.truncate(len);
168-
167+
169168
Ok(encrypted)
170169
}
171170

@@ -218,7 +217,7 @@ impl SeVerifierImpl {
218217

219218
let claims = SeAttestationClaims {
220219
cuid: se_response.cuid,
221-
user_data: se_response.user_data.clone(),
220+
user_data: String::from_utf8(se_response.user_data.clone())?,
222221
version: AttestationVersion::One as u32,
223222
image_phkh: image_phkh.to_vec(),
224223
attestation_phkh: attestation_phkh.to_vec(),
@@ -277,22 +276,19 @@ impl SeVerifierImpl {
277276
let c = certs
278277
.first()
279278
.ok_or(anyhow!("File does not contain a X509 certificate"))?;
280-
#[cfg(debug_assertions)]
281-
{
282-
const DEFAULT_SE_SKIP_CERTS_VERIFICATION: &str = "false";
283-
let skip_certs_env = env_or_default!(
284-
"SE_SKIP_CERTS_VERIFICATION",
285-
DEFAULT_SE_SKIP_CERTS_VERIFICATION
286-
);
287-
let skip_certs: bool = skip_certs_env.parse::<bool>().unwrap_or(false);
288-
if !skip_certs {
289-
let verifier = CertVerifier::new(ca_certs.as_slice(), crls.as_slice(), ca_option.clone(), offline_certs_verify)?;
290-
verifier.verify(c)?;
291-
}
292-
}
293-
#[cfg(not(debug_assertions))]
294-
{
295-
let verifier = CertVerifier::new(ca_certs.as_slice(), crls.as_slice(), ca_option.clone(), offline_certs_verify)?;
279+
const DEFAULT_SE_SKIP_CERTS_VERIFICATION: &str = "false";
280+
let skip_certs_env = env_or_default!(
281+
"SE_SKIP_CERTS_VERIFICATION",
282+
DEFAULT_SE_SKIP_CERTS_VERIFICATION
283+
);
284+
let skip_certs: bool = skip_certs_env.parse::<bool>().unwrap_or(false);
285+
if !skip_certs {
286+
let verifier = CertVerifier::new(
287+
ca_certs.as_slice(),
288+
crls.as_slice(),
289+
ca_option.clone(),
290+
offline_certs_verify,
291+
)?;
296292
verifier.verify(c)?;
297293
}
298294
arcb.add_hostkey(c.public_key()?);
@@ -301,8 +297,7 @@ impl SeVerifierImpl {
301297
let encr_ctx = ReqEncrCtx::random(SymKeyType::Aes256)?;
302298
let request_blob = arcb.encrypt(&encr_ctx)?;
303299
let conf_data = arcb.confidential_data();
304-
let encr_measurement_key =
305-
self.encrypt(conf_data.measurement_key())?;
300+
let encr_measurement_key = self.encrypt(conf_data.measurement_key())?;
306301
let nonce = conf_data
307302
.nonce()
308303
.as_ref()

attestation-service/verifier/src/se/mod.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,12 @@ impl Verifier for SeVerifier {
3838
se_verifier.evaluate(evidence)
3939
}
4040

41-
async fn generate_supplemental_challenge(
42-
&self,
43-
_tee_parameters: String,
44-
) -> Result<String> {
41+
async fn generate_supplemental_challenge(&self, _tee_parameters: String) -> Result<String> {
4542
let se_verifier = VERIFIER
4643
.get_or_try_init(|| async { SeVerifierImpl::new() })
4744
.await?;
48-
se_verifier.generate_supplemental_challenge(_tee_parameters).await
45+
se_verifier
46+
.generate_supplemental_challenge(_tee_parameters)
47+
.await
4948
}
5049
}

0 commit comments

Comments
 (0)