Skip to content

Commit f697be2

Browse files
committed
chore(ao_app): testing attestations and verification on GCP
1 parent affd5b1 commit f697be2

File tree

9 files changed

+638
-87
lines changed

9 files changed

+638
-87
lines changed

GCP-notes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
## Variables
1818

1919
```sh
20-
export GCI_NAME=PETES-SEV-SNP-TEST-0
20+
export GCI_NAME=petes-sev-snp-test-5
2121
export GCI_PROJECT=arweave-437622
22-
export GCI_IMAGE=packer-1730219529
22+
export GCI_IMAGE=packer-1731351804
2323
export GCI_ZONE=us-central1-a
2424
```
2525

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
-----BEGIN CERTIFICATE-----
2+
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
37+
-----END CERTIFICATE-----
38+
-----BEGIN CERTIFICATE-----
39+
MIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC
40+
BQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS
41+
BgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg
42+
Q2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp
43+
Y2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy
44+
MTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS
45+
BgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j
46+
ZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG
47+
9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg
48+
W41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta
49+
1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2
50+
SzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0
51+
60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05
52+
gmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg
53+
bKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs
54+
+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi
55+
Qi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ
56+
eTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18
57+
fHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j
58+
WhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI
59+
rFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG
60+
KWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG
61+
SIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI
62+
AWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel
63+
ETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw
64+
STjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK
65+
dHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq
66+
zT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp
67+
KGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e
68+
pmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq
69+
HnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh
70+
3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn
71+
JZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH
72+
CViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4
73+
AFZEAwoKCQ==
74+
-----END CERTIFICATE-----

packer.pkr.hcl

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,45 @@ source "googlecompute" "ubuntu" {
4141
build {
4242
sources = ["source.googlecompute.ubuntu"]
4343

44-
# Add a provisioner to download and install go-tpm-tools
44+
# # Add a provisioner to download and install go-tpm-tools
45+
# provisioner "shell" {
46+
# inline = [
47+
# "sudo apt-get update -y",
48+
# "sudo apt-get install -y wget tar",
49+
50+
# # Download the go-tpm-tools binary archive
51+
# "wget https://github.com/google/go-tpm-tools/releases/download/v0.4.4/go-tpm-tools_Linux_x86_64.tar.gz -O /tmp/go-tpm-tools.tar.gz",
52+
53+
# # Extract the binary
54+
# "tar -xzf /tmp/go-tpm-tools.tar.gz -C /tmp",
55+
56+
# # Move the gotpm binary to /usr/local/bin
57+
# "sudo mv /tmp/gotpm /usr/local/bin/",
58+
59+
# # Clean up
60+
# "rm -f /tmp/go-tpm-tools.tar.gz /tmp/LICENSE /tmp/README.md"
61+
# ]
62+
# }
63+
64+
# Add a provisioner to install Rust and snpguest
4565
provisioner "shell" {
4666
inline = [
47-
"sudo apt-get update -y",
48-
"sudo apt-get install -y wget tar",
49-
50-
# Download the go-tpm-tools binary archive
51-
"wget https://github.com/google/go-tpm-tools/releases/download/v0.4.4/go-tpm-tools_Linux_x86_64.tar.gz -O /tmp/go-tpm-tools.tar.gz",
52-
53-
# Extract the binary
54-
"tar -xzf /tmp/go-tpm-tools.tar.gz -C /tmp",
67+
# Install Rust
68+
"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y",
69+
". ~/.cargo/env",
5570

56-
# Move the gotpm binary to /usr/local/bin
57-
"sudo mv /tmp/gotpm /usr/local/bin/",
58-
59-
# Clean up
60-
"rm -f /tmp/go-tpm-tools.tar.gz /tmp/LICENSE /tmp/README.md"
71+
# Install snpguest
72+
"sudo apt-get update -y",
73+
"sudo apt-get install -y build-essential",
74+
"git clone https://github.com/virtee/snpguest.git",
75+
"cd snpguest",
76+
"cargo build -r",
77+
"sudo cp target/release/snpguest /usr/local/bin/",
78+
"cd ..",
79+
"rm -rf snpguest"
6180
]
6281
}
6382

64-
6583
# Upload the pre-built release (with ERTS included) to the instance
6684
provisioner "file" {
6785
source = "./_build/default/rel/ao"
@@ -73,7 +91,7 @@ build {
7391
# Move the release to /opt with sudo
7492
"sudo mv /tmp/ao /opt/ao",
7593
"sudo chmod -R 755 /opt/ao",
76-
94+
7795
# Create a symlink to make it easier to run the app
7896
"sudo ln -s /opt/ao/bin/ao /usr/local/bin/ao",
7997

@@ -86,19 +104,18 @@ build {
86104
"echo 'Restart=on-failure' | sudo tee -a /etc/systemd/system/ao.service",
87105
"echo '[Install]' | sudo tee -a /etc/systemd/system/ao.service",
88106
"echo 'WantedBy=multi-user.target' | sudo tee -a /etc/systemd/system/ao.service",
89-
107+
90108
# Enable and start the service
91109
"sudo systemctl enable ao",
92110
"sudo systemctl start ao"
93111
]
94112
}
95113

96-
# Disable ssh
114+
# Disable ssh if desired
97115
# provisioner "shell" {
98-
# inline = [
99-
# "sudo systemctl stop ssh",
100-
# "sudo systemctl disable ssh"
101-
# ]
116+
# inline = [
117+
# "sudo systemctl stop ssh",
118+
# "sudo systemctl disable ssh"
119+
# ]
102120
# }
103121
}
104-

rebar.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
{eunit_opts, [verbose]}.
4646

4747
{relx, [
48-
{release, {'ao', "0.0.1"}, [ao, jiffy, cowboy, gun, gproc, b64fast]},
48+
{release, {'ao', "0.0.1"}, [ao, jiffy, cowboy, b64fast]},
4949
{include_erts, true},
5050
{extended_start_script, true}
5151
]}.

src/ao_app.erl

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -8,73 +8,12 @@
88
-behaviour(application).
99

1010
-export([start/2, stop/1]).
11-
-export([attest_key/0]).
12-
13-
-include("include/ao.hrl").
14-
15-
-ao_debug(print).
1611

1712
start(_StartType, _StartArgs) ->
18-
attest_key(),
1913
ao_sup:start_link(),
2014
ok = su_registry:start(),
2115
_TimestampServer = su_timestamp:start(),
2216
{ok, _} = ao_http_router:start().
2317

2418
stop(_State) ->
2519
ok.
26-
27-
attest_key() ->
28-
W = ao:wallet(),
29-
Addr = ar_wallet:to_address(W),
30-
31-
% Pad the address to 32 bytes (64 hex characters) for the TPM nonce
32-
Nonce = pad_to_size(Addr, 32),
33-
34-
% Pad the address to 64 bytes (128 hex characters) for the TEE nonce
35-
TeeNonce = pad_to_size(Addr, 64),
36-
37-
% Determine tee-technology based on the existence of TEE devices
38-
TeeTech = case os:cmd("test -e /dev/tdx_guest && echo tdx || (test -e /dev/sev_guest && echo sev-snp)") of
39-
"tdx\n" -> "tdx";
40-
"sev-snp\n" -> "sev-snp";
41-
_ -> {error, "No TEE device found"}
42-
end,
43-
44-
% Proceed if a valid TEE technology is found
45-
case TeeTech of
46-
{error, _} -> {error, "Required TEE device not found"};
47-
_ ->
48-
Cmd = lists:flatten(io_lib:format("sudo gotpm attest --key AK --nonce ~s --tee-nonce ~s --tee-technology ~s", [Nonce, TeeNonce, TeeTech])),
49-
CommandResult = os:cmd(Cmd),
50-
case is_list(CommandResult) of
51-
true ->
52-
% If CommandResult is a list of integers, convert it to binary
53-
BinaryResult = list_to_binary(CommandResult),
54-
?c(BinaryResult),
55-
Signed = ar_bundles:sign_item(
56-
#tx{
57-
tags = [
58-
{<<"Type">>, <<"TEE-Attestation">>},
59-
{<<"Address">>, ar_util:id(Addr)}
60-
],
61-
data = BinaryResult
62-
},
63-
W
64-
),
65-
?c(Signed),
66-
ao_client:upload(Signed),
67-
ok;
68-
false ->
69-
{error, "Unexpected output format from gotpm attest command"}
70-
end
71-
end.
72-
73-
% Pads an address to the specified byte size (in hex characters)
74-
pad_to_size(Addr, SizeInBytes) ->
75-
HexAddr = binary:encode_hex(Addr),
76-
RequiredLength = SizeInBytes * 2, % Convert bytes to hex characters
77-
Padding = RequiredLength - byte_size(HexAddr),
78-
lists:duplicate(Padding, $0) ++ HexAddr.
79-
80-
%% internal functions

src/sec.erl

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
%%%---------------------------------------------------------------------
2+
%%% Module: sec
3+
%%%---------------------------------------------------------------------
4+
%%% Purpose:
5+
%%% This module handles the generation and verification of attestation
6+
%%% reports using both TPM and SEV-SNP. It combines attestation reports
7+
%%% from both technologies into a single binary and provides functionality
8+
%%% to verify the combined reports.
9+
%%%
10+
%%% It uses the `sec_tpm` and `sec_tee` modules to interact with the TPM
11+
%%% hardware and SEV-SNP for generating and verifying attestation reports.
12+
%%%---------------------------------------------------------------------
13+
%%% Exports
14+
%%%---------------------------------------------------------------------
15+
%%% generate_attestation(Nonce)
16+
%%% Generates a combined attestation report using the provided nonce.
17+
%%% It generates attestation reports from both TPM and SEV-SNP, calculates
18+
%%% their sizes, creates a header containing the sizes, and combines them
19+
%%% into a single binary.
20+
%%%
21+
%%% verify_attestation(AttestationBinary)
22+
%%% Verifies the provided attestation binary by extracting the TPM and
23+
%%% SEV-SNP reports, verifying them using their respective verification
24+
%%% methods, and then combining the results into a single binary.
25+
%%%---------------------------------------------------------------------
26+
27+
-module(sec).
28+
-export([generate_attestation/1, verify_attestation/1]).
29+
30+
-include("include/ao.hrl").
31+
32+
-ao_debug(print).
33+
34+
%% Generate attestation based on the provided nonce (both TPM and SEV-SNP)
35+
generate_attestation(Nonce) ->
36+
?c({"Generating TPM attestation..."}),
37+
38+
case sec_tpm:generate_attestation(Nonce) of
39+
{ok, TPMAttestation} ->
40+
?c({"TPM attestation generated, size:", byte_size(TPMAttestation)}),
41+
42+
?c({"Generating SEV-SNP attestation..."}),
43+
44+
case sec_tee:generate_attestation(Nonce) of
45+
{ok, TEEAttestation} ->
46+
?c({"SEV-SNP attestation generated, size:", byte_size(TEEAttestation)}),
47+
48+
%% Calculate sizes of the two attestation binaries
49+
TPMSize = byte_size(TPMAttestation),
50+
TEESize = byte_size(TEEAttestation),
51+
52+
%% Create the header containing the sizes
53+
Header = <<TPMSize:32/unit:8, TEESize:32/unit:8>>,
54+
?c({"Header created, TPMSize:", TPMSize, "TEESize:", TEESize}),
55+
56+
%% Combine the header with the two attestation binaries
57+
CombinedAttestation = <<Header/binary, TPMAttestation/binary, TEEAttestation/binary>>,
58+
?c({"Combined attestation binary created, total size:", byte_size(CombinedAttestation)}),
59+
60+
{ok, CombinedAttestation};
61+
62+
{error, Reason} ->
63+
?c({"Error generating SEV-SNP attestation:", Reason}),
64+
{error, Reason}
65+
end;
66+
67+
{error, Reason} ->
68+
?c({"Error generating TPM attestation:", Reason}),
69+
{error, Reason}
70+
end.
71+
72+
%% Verify attestation report based on the provided binary (both TPM and SEV-SNP)
73+
verify_attestation(AttestationBinary) ->
74+
?c("Verifying attestation..."),
75+
76+
%% Extract the header (size info) and the attestation binaries
77+
<<TPMSize:32/unit:8, TEESize:32/unit:8, Rest/binary>> = AttestationBinary,
78+
?c({"Header extracted, TPMSize:", TPMSize, "TEESize:", TEESize}),
79+
80+
%% Extract the TPM and SEV-SNP attestation binaries based on their sizes
81+
<<TPMAttestation:TPMSize/binary, TEEAttestation:TEESize/binary>> = Rest,
82+
?c({"Extracted TPM and SEV-SNP attestation binaries"}),
83+
84+
%% Verify TPM attestation
85+
case sec_tpm:verify_attestation(TPMAttestation) of
86+
{ok, _TPMVerification} ->
87+
?c({"TPM attestation verification completed"}),
88+
89+
%% Verify SEV-SNP attestation
90+
case sec_tee:verify_attestation(TEEAttestation) of
91+
{ok, _TEEVerification} ->
92+
?c({"SEV-SNP attestation verification completed"}),
93+
94+
%% Return success if both verifications succeeded
95+
{ok, "Verified"};
96+
97+
{error, Reason} ->
98+
?c({"Error verifying SEV-SNP attestation:", Reason}),
99+
{error, Reason}
100+
end;
101+
102+
{error, Reason} ->
103+
?c({"Error verifying TPM attestation:", Reason}),
104+
{error, Reason}
105+
end.

0 commit comments

Comments
 (0)