Skip to content

Commit

Permalink
Fix IBM SE verifier
Browse files Browse the repository at this point in the history
Added the missing se_parse_hdr.py file to the IBM SE verifier code

Signed-off-by: Leonardo Milleri <lmilleri@redhat.com>
  • Loading branch information
lmilleri committed Sep 9, 2024
1 parent b4aff9b commit 370b581
Show file tree
Hide file tree
Showing 4 changed files with 277 additions and 42 deletions.
107 changes: 93 additions & 14 deletions attestation-service/verifier/src/se/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
# Deployment of KBS with IBM SE verifier

# KBS with IBM SE verifier

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

## Index

- [Deployment of KBS with IBM SE verifier](#deployment-of-kbs-with-ibm-se-verifier)
- [Set attestation policy for IBM SE verifier](#set-attestation-policy)



# Deployment of KBS with IBM SE verifier

This section is about deployment of KBS without rvps checking.

## Generate RSA keys
Generate RSA 4096 key pair following commands:
```
```bash
openssl genrsa -aes256 -passout pass:test1234 -out encrypt_key-psw.pem 4096
openssl rsa -in encrypt_key-psw.pem -passin pass:test1234 -pubout -out encrypt_key.pub
openssl rsa -in encrypt_key-psw.pem -out encrypt_key.pem
Expand All @@ -20,30 +32,41 @@ ibm-z-host-key-signing-gen2.crt
DigiCertCA.crt

### CRL
ibm-z-host-key-gen2.crl
ibm-z-host-key-gen2.crl
DigiCertTrustedRootG4.crl
DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl

Note: `DigiCertTrustedRootG4.crl` and `DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl` come from commands as below:
```bash
# openssl x509 -in DigiCertCA.crt --text --noout |grep crl
URI:http://crl3.digicert.com/DigiCertTrustedRootG4.crl
# openssl x509 -in ibm-z-host-key-signing-gen2.crt --text --noout |grep crl
URI:http://crl3.digicert.com/DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl
URI:http://crl4.digicert.com/DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl
```

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

## Get SE Header
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.
```
```bash
./pvextract-hdr -o hdr.bin se.img
```

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`.

## Generate KBS key
Generate keys used by KBS service.
```
```bash
openssl genpkey -algorithm ed25519 > kbs.key
openssl pkey -in kbs.key -pubout -out kbs.pem
```

## (Option 1) Launch KBS as a program

- Build KBS
```
```bash
cargo install --locked --debug --path kbs/src/kbs --no-default-features --features coco-as-builtin,openssl,resource,opa
```

Expand All @@ -56,6 +79,8 @@ cargo install --locked --debug --path kbs/src/kbs --no-default-features --featur
| └── DigiCertCA.crt
├── crls
│ └── ibm-z-host-key-gen2.crl
│ └── DigiCertTrustedRootG4.crl
│ └── DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl
├── hdr
│ └── hdr.bin
├── hkds
Expand Down Expand Up @@ -92,25 +117,24 @@ remote_addr = ""
```

- Launch the KBS program
```
```bash
export RUST_LOG=debug
export SE_SKIP_CERTS_VERIFICATION=true
./kbs --config-file ./kbs-config.toml
```

> Note: `SE_SKIP_CERTS_VERIFICATION=true` only required for a development machine.
> Note: `export SE_SKIP_CERTS_VERIFICATION=true` only required for a development machine. Use `export CERTS_OFFLINE_VERIFICATION=true` to verifiy the certificates offline.
## (Option 2) Launch KBS via docker-compose
- Build the docker image
```
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
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
```
>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.

- Prepare a docker compose file, similar as:
```
services:
web:
kbs:
image: ghcr.io/confidential-containers/staged-images/kbs:latest
command: [
"/usr/local/bin/kbs",
Expand All @@ -135,7 +159,7 @@ services:
- ./data/rsa/encrypt_key.pem:/run/confidential-containers/ibmse/rsa/encrypt_key.pem
- ./data/rsa/encrypt_key.pub:/run/confidential-containers/ibmse/rsa/encrypt_key.pub
```
> Note: `SE_SKIP_CERTS_VERIFICATION=true` only required for a development machine.
> Note: `export SE_SKIP_CERTS_VERIFICATION=true` only required for a development machine. Use `export CERTS_OFFLINE_VERIFICATION=true` to verifiy the certificates offline.
- Prepare the material, similar as:
```
Expand All @@ -149,6 +173,8 @@ services:
│   │   └── DigiCertCA.crt
│   ├── crls
│   │   └── ibm-z-host-key-gen2.crl
│ │ └── DigiCertTrustedRootG4.crl
│ │ └── DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crl
│   ├── hdr.bin
│   ├── hkds
│   │   └── HKD-3931-0275D38.crt
Expand All @@ -167,10 +193,63 @@ services:
```

- Launch KBS as docker compose application
```
```bash
docker-compose up -d
docker-compose logs web
docker-compose logs kbs
docker-compose down
```


# Set attestation policy

This section is about setting attestation policy.

### Retrive the attestation policy fields for IBM SE

Using [se_parse_hdr.py](se_parse_hdr.py) on a s390x instance to retrieve the IBM SE fields for attestation policy.

```bash
python3 se_parse_hdr.py hdr.bin HKD-3931.crt

...
================================================
se.image_phkh: xxx
se.version: 256
se.tag: xxx
se.attestation_phkh: xxx
```

We get following fields and will set these fields in rvps for attestation policy.
`se.version: 256`
`se.tag: xxx`
`se.attestation_phkh: xxx`
`se.image_phkh: xxx`


### Set attestation policy

#### Generate attestation policy file
```bash
cat << EOF > ibmse-policy.rego
package policy
import rego.v1
default allow = false
converted_version := sprintf("%v", [input["se.version"]])
allow if {
input["se.attestation_phkh"] == "xxx"
input["se.image_phkh"] == "xxx"
input["se.tag"] == "xxx"
input["se.user_data"] == "xxx"
converted_version == "256"
}
EOF
```

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.

#### Set the attestation policy
```bash
kbs-client --url http://127.0.0.1:8080 config --auth-private-key ./kbs/kbs.key set-attestation-policy --policy-file ./ibmse-policy.rego
```
41 changes: 18 additions & 23 deletions attestation-service/verifier/src/se/ibmse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ pub struct SeAttestationResponse {
pub struct SeAttestationClaims {
#[serde_as(as = "Hex")]
cuid: ConfigUid,
#[serde_as(as = "Hex")]
user_data: Vec<u8>,
user_data: String,
version: u32,
#[serde_as(as = "Hex")]
image_phkh: Vec<u8>,
Expand Down Expand Up @@ -160,12 +159,12 @@ impl SeVerifierImpl {
fn encrypt(&self, text: &[u8]) -> Result<Vec<u8>> {
let mut encrypter = Encrypter::new(&self.public_key)?;
encrypter.set_rsa_padding(Padding::PKCS1)?;

let buffer_len = encrypter.encrypt_len(text)?;
let mut encrypted = vec![0; buffer_len];
let len = encrypter.encrypt(text, &mut encrypted)?;
encrypted.truncate(len);

Ok(encrypted)
}

Expand Down Expand Up @@ -218,7 +217,7 @@ impl SeVerifierImpl {

let claims = SeAttestationClaims {
cuid: se_response.cuid,
user_data: se_response.user_data.clone(),
user_data: String::from_utf8(se_response.user_data.clone())?,
version: AttestationVersion::One as u32,
image_phkh: image_phkh.to_vec(),
attestation_phkh: attestation_phkh.to_vec(),
Expand Down Expand Up @@ -277,22 +276,19 @@ impl SeVerifierImpl {
let c = certs
.first()
.ok_or(anyhow!("File does not contain a X509 certificate"))?;
#[cfg(debug_assertions)]
{
const DEFAULT_SE_SKIP_CERTS_VERIFICATION: &str = "false";
let skip_certs_env = env_or_default!(
"SE_SKIP_CERTS_VERIFICATION",
DEFAULT_SE_SKIP_CERTS_VERIFICATION
);
let skip_certs: bool = skip_certs_env.parse::<bool>().unwrap_or(false);
if !skip_certs {
let verifier = CertVerifier::new(ca_certs.as_slice(), crls.as_slice(), ca_option.clone(), offline_certs_verify)?;
verifier.verify(c)?;
}
}
#[cfg(not(debug_assertions))]
{
let verifier = CertVerifier::new(ca_certs.as_slice(), crls.as_slice(), ca_option.clone(), offline_certs_verify)?;
const DEFAULT_SE_SKIP_CERTS_VERIFICATION: &str = "false";
let skip_certs_env = env_or_default!(
"SE_SKIP_CERTS_VERIFICATION",
DEFAULT_SE_SKIP_CERTS_VERIFICATION
);
let skip_certs: bool = skip_certs_env.parse::<bool>().unwrap_or(false);
if !skip_certs {
let verifier = CertVerifier::new(
ca_certs.as_slice(),
crls.as_slice(),
ca_option.clone(),
offline_certs_verify,
)?;
verifier.verify(c)?;
}
arcb.add_hostkey(c.public_key()?);
Expand All @@ -301,8 +297,7 @@ impl SeVerifierImpl {
let encr_ctx = ReqEncrCtx::random(SymKeyType::Aes256)?;
let request_blob = arcb.encrypt(&encr_ctx)?;
let conf_data = arcb.confidential_data();
let encr_measurement_key =
self.encrypt(conf_data.measurement_key())?;
let encr_measurement_key = self.encrypt(conf_data.measurement_key())?;
let nonce = conf_data
.nonce()
.as_ref()
Expand Down
9 changes: 4 additions & 5 deletions attestation-service/verifier/src/se/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,12 @@ impl Verifier for SeVerifier {
se_verifier.evaluate(evidence)
}

async fn generate_supplemental_challenge(
&self,
_tee_parameters: String,
) -> Result<String> {
async fn generate_supplemental_challenge(&self, _tee_parameters: String) -> Result<String> {
let se_verifier = VERIFIER
.get_or_try_init(|| async { SeVerifierImpl::new() })
.await?;
se_verifier.generate_supplemental_challenge(_tee_parameters).await
se_verifier
.generate_supplemental_challenge(_tee_parameters)
.await
}
}
Loading

0 comments on commit 370b581

Please sign in to comment.