CCF
Loading...
Searching...
No Matches
attestation_sev_snp.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
9
10#include <array>
11#include <cstdint>
12#include <map>
13#include <string>
14
16{
17 // Based on the SEV-SNP ABI Spec document at
18 // https://www.amd.com/system/files/TechDocs/56860.pdf
19
20 static constexpr auto NO_SECURITY_POLICY = "";
21
22 // From https://developer.amd.com/sev/
24 R"(-----BEGIN PUBLIC KEY-----
25MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsV
26mD7FktuotWwX1fNgW41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU
270V5tkKiU1EesNFta1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S
281ju8X93+6dxDUrG2SzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI5
292Naz5m2B+O+vjsC060d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3K
30FYXP59XmJgtcog05gmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd
31/y8KxX7jksTEzAOgbKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBk
32gnlENEWx1UcbQQrs+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V
339TJQqnN3Q53kt5viQi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnq
34z55I0u33wh4r0ZNQeTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+Og
35pCCoMNit2uLo9M18fHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXo
36QPHfbkH0CyPfhl1jWhJFZasCAwEAAQ==
37-----END PUBLIC KEY-----
38)";
40 R"(-----BEGIN PUBLIC KEY-----
41MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3Cd95S/uFOuRIskW9vz9
42VDBF69NDQF79oRhL/L2PVQGhK3YdfEBgpF/JiwWFBsT/fXDhzA01p3LkcT/7Ldjc
43RfKXjHl+0Qq/M4dZkh6QDoUeKzNBLDcBKDDGWo3v35NyrxbA1DnkYwUKU5AAk4P9
444tKXLp80oxt84ahyHoLmc/LqsGsp+oq1Bz4PPsYLwTG4iMKVaaT90/oZ4I8oibSr
45u92vJhlqWO27d/Rxc3iUMyhNeGToOvgx/iUo4gGpG61NDpkEUvIzuKcaMx8IdTpW
46g2DF6SwF0IgVMffnvtJmA68BwJNWo1E4PLJdaPfBifcJpuBFwNVQIPQEVX3aP89H
47JSp8YbY9lySS6PlVEqTBBtaQmi4ATGmMR+n2K/e+JAhU2Gj7jIpJhOkdH9firQDn
48mlA2SFfJ/Cc0mGNzW9RmIhyOUnNFoclmkRhl3/AQU5Ys9Qsan1jT/EiyT+pCpmnA
49+y9edvhDCbOG8F2oxHGRdTBkylungrkXJGYiwGrR8kaiqv7NN8QhOBMqYjcbrkEr
500f8QMKklIS5ruOfqlLMCBw8JLB3LkjpWgtD7OpxkzSsohN47Uom86RY6lp72g8eX
51HP1qYrnvhzaG1S70vw6OkbaaC9EjiH/uHgAJQGxon7u0Q7xgoREWA/e7JcBQwLg8
520Hq/sbRuqesxz7wBWSY254cCAwEAAQ==
53-----END PUBLIC KEY-----
54)";
56 R"(-----BEGIN PUBLIC KEY-----
57MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwaAriB7EIuVc4ZB1wD3Y
58fDxL+9eyS7+izm0Jj3W772NINCWl8Bj3w/JD2ZjmbRxWdIq/4d9iarCKorXloJUB
591jRdgxqccTx1aOoig4+2w1XhVVJT7K457wT5ZLNJgQaxqa9Etkwjd6+9sOhlCDE9
60l43kQ0R2BikVJa/uyyVOSwEk5w5tXKOuG9jvq6QtAMJasW38wlqRDaKEGtZ9VUgG
61on27ZuL4sTJuC/azz9/iQBw8kEilzOl95AiTkeY5jSEBDWbAqnZk5qlM7kISKG20
62kgQm14mhNKDI2p2oua+zuAG7i52epoRF2GfU0TYk/yf+vCNB2tnechFQuP2e8bLk
6395ZdqPi9/UWw4JXjtdEA4u2JYplSSUPQVAXKt6LVqujtJcM59JKr2u0XQ75KwxcM
64p15gSXhBfInvPAwuAY4dEwwGqT8oIg4esPHwEsmChhYeDIxPG9R4fx9O0q6p8Gb+
65HXlTiS47P9YNeOpidOUKzDl/S1OvyhDtSL8LJc24QATFydo/iD/KUdvFTRlD0crk
66AMkZLoWQ8hLDGc6BZJXsdd7Zf2e4UW3tI/1oh/2t23Ot3zyhTcv5gDbABu0LjVe9
678uRnS15SMwK//lJt9e5BqKvgABkSoABf+B4VFtPVEX0ygrYaFaI9i5ABrxnVBmzX
68pRb21iI1NlNCfOGUPIhVpWECAwEAAQ==
69-----END PUBLIC KEY-----
70)";
71
72 inline const std::map<ProductName, const char*> amd_root_signing_keys{
75 // Disabled until we can test this
76 //{ProductName::turin, amd_turin_root_signing_public_key},
77 };
78
79#pragma pack(push, 1)
80 // Table 3
82 {
83 uint8_t boot_loader;
84 uint8_t tee;
85 uint8_t reserved[4];
86 uint8_t snp;
87 uint8_t microcode;
88
89 bool operator==(const TcbVersion&) const = default;
90 };
91#pragma pack(pop)
92 static_assert(
93 sizeof(TcbVersion) == sizeof(uint64_t),
94 "Can't cast TcbVersion to uint64_t");
95
96#pragma pack(push, 1)
97 struct Signature
98 {
99 uint8_t r[72];
100 uint8_t s[72];
101 uint8_t reserved[512 - 144];
102 };
103#pragma pack(pop)
104
105 // Table 105
106 enum class SignatureAlgorithm : uint32_t
107 {
108 invalid = 0,
110 };
111
112#pragma pack(push, 1)
113 // Table 8
115 {
116 uint8_t abi_minor;
117 uint8_t abi_major;
118 uint8_t smt : 1;
119 uint8_t reserved : 1;
120 uint8_t migrate_ma : 1;
121 uint8_t debug : 1;
122 uint8_t single_socket : 1;
123 uint64_t reserved2 : 43;
124 };
125#pragma pack(pop)
126 static_assert(
127 sizeof(GuestPolicy) == sizeof(uint64_t),
128 "Can't cast GuestPolicy to uint64_t");
129
130 static constexpr uint8_t attestation_flags_signing_key_vcek = 0;
131
132#pragma pack(push, 1)
133 struct Flags
134 {
135 uint8_t author_key_en : 1;
136 uint8_t mask_chip_key : 1;
137 uint8_t signing_key : 3;
138 uint64_t reserved : 27;
139 };
140#pragma pack(pop)
141 static_assert(
142 sizeof(Flags) == sizeof(uint32_t), "Can't cast Flags to uint32_t");
143
144#pragma pack(push, 1)
145 // Table 22
147 {
148 uint8_t smt_en : 1;
149 uint8_t tsme_en : 1;
150 uint64_t reserved : 62;
151 };
152#pragma pack(pop)
153 static_assert(
154 sizeof(PlatformInfo) == sizeof(uint64_t),
155 "Can't cast PlatformInfo to uint64_t");
156
157#pragma pack(push, 1)
158 // Table 21
159
160 static constexpr uint32_t minimum_attestation_version = 2;
161 static constexpr uint32_t attestation_policy_abi_major = 1;
162
164 {
165 uint32_t version; /* 0x000 */
166 uint32_t guest_svn; /* 0x004 */
167 struct GuestPolicy policy; /* 0x008 */
168 uint8_t family_id[16]; /* 0x010 */
169 uint8_t image_id[16]; /* 0x020 */
170 uint32_t vmpl; /* 0x030 */
172 struct TcbVersion platform_version; /* 0x038 */
174 Flags flags; /* 0x048 */
175 uint32_t reserved0; /* 0x04C */
176 uint8_t report_data[snp_attestation_report_data_size]; /* 0x050 */
177 uint8_t measurement[snp_attestation_measurement_size]; /* 0x090 */
178 uint8_t host_data[32]; /* 0x0C0 */
179 uint8_t id_key_digest[48]; /* 0x0E0 */
180 uint8_t author_key_digest[48]; /* 0x110 */
181 uint8_t report_id[32]; /* 0x140 */
182 uint8_t report_id_ma[32]; /* 0x160 */
183 struct TcbVersion reported_tcb; /* 0x180 */
184 uint8_t cpuid_fam_id; /* 0x188*/
185 uint8_t cpuid_mod_id; /* 0x189 */
186 uint8_t cpuid_step; /* 0x18A */
187 uint8_t reserved1[21]; /* 0x18B */
188 uint8_t chip_id[64]; /* 0x1A0 */
189 struct TcbVersion committed_tcb; /* 0x1E0 */
190 uint8_t current_minor; /* 0x1E8 */
191 uint8_t current_build; /* 0x1E9 */
192 uint8_t current_major; /* 0x1EA */
193 uint8_t reserved2; /* 0x1EB */
194 uint8_t committed_build; /* 0x1EC */
195 uint8_t committed_minor; /* 0x1ED */
196 uint8_t committed_major; /* 0x1EE */
197 uint8_t reserved3; /* 0x1EF */
198 struct TcbVersion launch_tcb; /* 0x1F0 */
199 uint8_t reserved4[168]; /* 0x1F8 */
200 struct Signature signature; /* 0x2A0 */
201 };
202#pragma pack(pop)
203
204 static HostPort get_endpoint_loc(
205 const EndorsementsServer& server, const HostPort& default_values)
206 {
207 if (server.url.has_value())
208 {
209 auto url = server.url.value();
210 auto pos = url.find(':');
211 if (pos == std::string::npos)
212 {
213 return {url, default_values.port};
214 }
215 else
216 {
217 return {url.substr(0, pos), url.substr(pos + 1)};
218 }
219 }
220
221 return default_values;
222 }
223
224 static EndorsementEndpointsConfiguration
225 make_endorsement_endpoint_configuration(
226 const Attestation& quote,
227 const snp::EndorsementsServers& endorsements_servers = {})
228 {
229 EndorsementEndpointsConfiguration config;
230
231 auto chip_id_hex = fmt::format("{:02x}", fmt::join(quote.chip_id, ""));
232 auto reported_tcb = fmt::format("{:0x}", *(uint64_t*)(&quote.reported_tcb));
233
234 if (endorsements_servers.empty())
235 {
236 // Default to Azure server if no servers are specified
237 config.servers.emplace_back(make_azure_endorsements_server(
238 default_azure_endorsements_endpoint, chip_id_hex, reported_tcb));
239 return config;
240 }
241
242 for (auto const& server : endorsements_servers)
243 {
244 switch (server.type)
245 {
247 {
248 auto loc =
249 get_endpoint_loc(server, default_azure_endorsements_endpoint);
250 config.servers.emplace_back(
251 make_azure_endorsements_server(loc, chip_id_hex, reported_tcb));
252 break;
253 }
255 {
256 auto boot_loader = fmt::format("{}", quote.reported_tcb.boot_loader);
257 auto tee = fmt::format("{}", quote.reported_tcb.tee);
258 auto snp = fmt::format("{}", quote.reported_tcb.snp);
259 auto microcode = fmt::format("{}", quote.reported_tcb.microcode);
260 auto product =
261 get_sev_snp_product(quote.cpuid_fam_id, quote.cpuid_mod_id);
262
263 auto loc =
264 get_endpoint_loc(server, default_amd_endorsements_endpoint);
265 config.servers.emplace_back(make_amd_endorsements_server(
266 loc, chip_id_hex, boot_loader, tee, snp, microcode, product));
267 break;
268 }
270 {
271 auto loc =
272 get_endpoint_loc(server, default_thim_endorsements_endpoint);
273 config.servers.emplace_back(
274 make_thim_endorsements_server(loc, chip_id_hex, reported_tcb));
275 break;
276 }
277 default:
278 {
279 throw std::logic_error(fmt::format(
280 "Unsupported endorsements server type: {}", server.type));
281 }
282 }
283 }
284
285 return config;
286 }
287
289 {
290 public:
291 virtual const snp::Attestation& get() const = 0;
292 virtual std::vector<uint8_t> get_raw() = 0;
293
294 virtual ~AttestationInterface() = default;
295 };
296}
Definition attestation_sev_snp.h:289
virtual std::vector< uint8_t > get_raw()=0
virtual ~AttestationInterface()=default
virtual const snp::Attestation & get() const =0
Definition attestation_sev_snp.h:16
constexpr auto amd_genoa_root_signing_public_key
Definition attestation_sev_snp.h:39
SignatureAlgorithm
Definition attestation_sev_snp.h:107
@ Azure
Definition attestation_sev_snp_endorsements.h:61
@ THIM
Definition attestation_sev_snp_endorsements.h:63
@ AMD
Definition attestation_sev_snp_endorsements.h:62
constexpr auto amd_milan_root_signing_public_key
Definition attestation_sev_snp.h:23
ProductName get_sev_snp_product(AMDFamily family, AMDModel model)
Definition sev_snp_cpuid.h:42
constexpr auto amd_turin_root_signing_public_key
Definition attestation_sev_snp.h:55
std::vector< EndorsementsServer > EndorsementsServers
Definition attestation_sev_snp_endorsements.h:81
const std::map< ProductName, const char * > amd_root_signing_keys
Definition attestation_sev_snp.h:72
Definition attestation_sev_snp.h:164
uint8_t reserved3
Definition attestation_sev_snp.h:197
struct TcbVersion committed_tcb
Definition attestation_sev_snp.h:189
uint32_t guest_svn
Definition attestation_sev_snp.h:166
uint8_t committed_major
Definition attestation_sev_snp.h:196
struct Signature signature
Definition attestation_sev_snp.h:200
uint8_t current_build
Definition attestation_sev_snp.h:191
uint8_t id_key_digest[48]
Definition attestation_sev_snp.h:179
PlatformInfo platform_info
Definition attestation_sev_snp.h:173
uint8_t chip_id[64]
Definition attestation_sev_snp.h:188
uint8_t committed_minor
Definition attestation_sev_snp.h:195
uint8_t reserved2
Definition attestation_sev_snp.h:193
uint32_t reserved0
Definition attestation_sev_snp.h:175
struct GuestPolicy policy
Definition attestation_sev_snp.h:167
uint32_t version
Definition attestation_sev_snp.h:165
uint8_t measurement[snp_attestation_measurement_size]
Definition attestation_sev_snp.h:177
uint8_t host_data[32]
Definition attestation_sev_snp.h:178
uint8_t current_minor
Definition attestation_sev_snp.h:190
uint8_t report_data[snp_attestation_report_data_size]
Definition attestation_sev_snp.h:176
uint8_t family_id[16]
Definition attestation_sev_snp.h:168
uint8_t committed_build
Definition attestation_sev_snp.h:194
uint8_t image_id[16]
Definition attestation_sev_snp.h:169
uint8_t cpuid_fam_id
Definition attestation_sev_snp.h:184
uint8_t report_id[32]
Definition attestation_sev_snp.h:181
uint8_t reserved1[21]
Definition attestation_sev_snp.h:187
uint32_t vmpl
Definition attestation_sev_snp.h:170
SignatureAlgorithm signature_algo
Definition attestation_sev_snp.h:171
struct TcbVersion reported_tcb
Definition attestation_sev_snp.h:183
struct TcbVersion platform_version
Definition attestation_sev_snp.h:172
struct TcbVersion launch_tcb
Definition attestation_sev_snp.h:198
uint8_t report_id_ma[32]
Definition attestation_sev_snp.h:182
uint8_t cpuid_step
Definition attestation_sev_snp.h:186
Flags flags
Definition attestation_sev_snp.h:174
uint8_t cpuid_mod_id
Definition attestation_sev_snp.h:185
uint8_t current_major
Definition attestation_sev_snp.h:192
uint8_t reserved4[168]
Definition attestation_sev_snp.h:199
uint8_t author_key_digest[48]
Definition attestation_sev_snp.h:180
Definition attestation_sev_snp_endorsements.h:72
EndorsementsEndpointType type
Definition attestation_sev_snp_endorsements.h:73
std::optional< std::string > url
Definition attestation_sev_snp_endorsements.h:74
Definition attestation_sev_snp.h:134
uint64_t reserved
Definition attestation_sev_snp.h:138
uint8_t signing_key
Definition attestation_sev_snp.h:137
uint8_t mask_chip_key
Definition attestation_sev_snp.h:136
uint8_t author_key_en
Definition attestation_sev_snp.h:135
Definition attestation_sev_snp.h:115
uint8_t single_socket
Definition attestation_sev_snp.h:122
uint64_t reserved2
Definition attestation_sev_snp.h:123
uint8_t abi_major
Definition attestation_sev_snp.h:117
uint8_t abi_minor
Definition attestation_sev_snp.h:116
uint8_t reserved
Definition attestation_sev_snp.h:119
uint8_t smt
Definition attestation_sev_snp.h:118
uint8_t migrate_ma
Definition attestation_sev_snp.h:120
uint8_t debug
Definition attestation_sev_snp.h:121
Definition attestation_sev_snp_endorsements.h:84
std::string port
Definition attestation_sev_snp_endorsements.h:86
Definition attestation_sev_snp.h:147
uint64_t reserved
Definition attestation_sev_snp.h:150
uint8_t tsme_en
Definition attestation_sev_snp.h:149
uint8_t smt_en
Definition attestation_sev_snp.h:148
Definition attestation_sev_snp.h:98
uint8_t r[72]
Definition attestation_sev_snp.h:99
uint8_t reserved[512 - 144]
Definition attestation_sev_snp.h:101
uint8_t s[72]
Definition attestation_sev_snp.h:100
Definition attestation_sev_snp.h:82
uint8_t reserved[4]
Definition attestation_sev_snp.h:85
uint8_t boot_loader
Definition attestation_sev_snp.h:83
uint8_t microcode
Definition attestation_sev_snp.h:87
bool operator==(const TcbVersion &) const =default
uint8_t tee
Definition attestation_sev_snp.h:84
uint8_t snp
Definition attestation_sev_snp.h:86