%s: ", desc); 112 | else 113 | printf("
%s: ", desc);
114 | else
115 | printf(" %s: ", desc);
116 | int padding = 20 - strlen(desc);
117 | if (padding < 0)
118 | padding = 0;
119 | for (int count = 0; count < padding; count++)
120 | putchar(' ');
121 |
122 | for (size_t pos = 0; pos < len; pos++) {
123 | printf("%02x", data[swap ? len - pos - 1 : pos]);
124 | if (pos % 32 == 31) {
125 | if (formatAsHtml)
126 | printf("
");
127 | printf("\n ");
128 | } else if (pos % 16 == 15)
129 | putchar(' ');
130 | }
131 | if (formatAsHtml)
132 | printf("
AMD SEV-SNP Attestation Report:
\n"); 141 | else 142 | printf("AMD SEV-SNP Attestation Report:\n"); 143 | PRINT_VAL(r, version); // print the version as an actual number 144 | PRINT_VAL(r, guest_svn); 145 | PRINT_VAL(r, policy); 146 | PRINT_VAL(r, family_id); 147 | PRINT_VAL(r, image_id); 148 | PRINT_VAL(r, vmpl); 149 | PRINT_VAL(r, signature_algo); 150 | PRINT_BYTES(r, platform_version); // dump the platform version as hex bytes 151 | PRINT_BYTES(r, platform_info); 152 | PRINT_VAL(r, author_key_en); 153 | PRINT_VAL(r, reserved1); 154 | BOLD_BYTES(r, report_data); 155 | BOLD_BYTES(r, measurement); 156 | BOLD_BYTES(r, host_data); 157 | PRINT_BYTES(r, id_key_digest); 158 | PRINT_BYTES(r, author_key_digest); 159 | PRINT_BYTES(r, report_id); 160 | PRINT_BYTES(r, report_id_ma); 161 | PRINT_VAL(r, reported_tcb); 162 | PRINT_BYTES(r, reserved2); 163 | BOLD_BYTES(r, chip_id); 164 | PRINT_BYTES(r, committed_svn); 165 | PRINT_BYTES(r, committed_version); 166 | PRINT_BYTES(r, launch_svn); 167 | PRINT_BYTES(r, reserved3); 168 | BOLD_BYTES(r, signature); 169 | } 170 | 171 | uint8_t* decodeHexString(char *hexstring) 172 | { 173 | size_t len = strlen(hexstring); 174 | uint8_t *byte_array = (uint8_t*) malloc(strlen(hexstring)*sizeof(uint8_t)); 175 | 176 | for (size_t i = 0; i < len; i+=2) { 177 | sscanf(hexstring, "%2hhx", &byte_array[i/2]); 178 | hexstring += 2; 179 | } 180 | 181 | return byte_array; 182 | } 183 | 184 | 185 | int main(int argc, char** argv) 186 | { 187 | msg_report_req msg_report_in; 188 | msg_response_resp msg_report_out; 189 | 190 | int fd; 191 | int i; 192 | int rc; 193 | bool hexBlob = false; 194 | 195 | struct sev_snp_guest_request payload = { 196 | .req_msg_type = SNP_MSG_REPORT_REQ, 197 | .rsp_msg_type = SNP_MSG_REPORT_RSP, 198 | .msg_version = 1, 199 | .request_len = sizeof(msg_report_in), 200 | .request_uaddr = (uint64_t) (void*) &msg_report_in, 201 | .response_len = sizeof(msg_report_out), 202 | .response_uaddr = (uint64_t) (void*) &msg_report_out, 203 | .error = 0 204 | }; 205 | 206 | if (argc > 1 && !strcmp(argv[1], "--help")) { 207 | printf("%s: [--help|--html|--raw|--example]\n", argv[0]); 208 | exit(0); 209 | } 210 | 211 | if (argc > 1 && !strcmp(argv[1], "--html")) { 212 | formatAsHtml = true; 213 | argc--; 214 | argv++; 215 | } 216 | 217 | if (argc > 1 && !strcmp(argv[1], "--raw")) { 218 | hexBlob = true; 219 | argc--; 220 | argv++; 221 | } 222 | 223 | // use --example to get a canned report, used to help debug exposing reports via HTTP etc 224 | if (argc == 2 && !strcmp(argv[1], "--example")) { 225 | uint8_t *default_report = decodeHexString("01000000010000001f00030000000000010000000000000000000000000000000200000000000000000000000000000000000000010000000000000000000028010000000000000000000000000000007ab000a323b3c873f5b81bbe584e7c1a26bcf40dc27e00f8e0d144b1ed2d14f10000000000000000000000000000000000000000000000000000000000000000e29af700e85b39996fa38226d2804b78cad746ffef4477360a61b47874bdecd640f9d32f5ff64a55baad3c545484d9ed28603a3ea835a83bd688b0ec1dcb36b6b8c22412e5b63115b75db8628b989bc598c475ca5f7683e8d351e7e789a1baff19041750567161ad52bf0d152bd76d7c6f313d0a0fd72d0089692c18f521155800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040aea62690b08eb6d680392c9a9b3db56a9b3cc44083b9da31fb88bcfc493407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000028000000000000000000000000000000000000000000000000e6c86796cd44b0bc6b7c0d4fdab33e2807e14b5fc4538b3750921169d97bcf4447c7d3ab2a7c25f74c1641e2885c1011d025cc536f5c9a2504713136c7877f480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003131c0f3e7be5c6e400f22404596e1874381e99d03de45ef8b97eee0a0fa93a4911550330343f14dddbbd6c0db83744f000000000000000000000000000000000000000000000000db07c83c5e6162c2387f3b76cd547672657f6a5df99df98efee7c15349320d83e086c5003ec43050a9b18d1c39dedc340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); 226 | if (hexBlob) { 227 | printBytes("Raw example report", (const uint8_t *)default_report, sizeof(snp_attestation_report), false, false); 228 | } else { 229 | printReport((snp_attestation_report *)default_report); 230 | } 231 | exit(0); 232 | } 233 | 234 | memset((void*) &msg_report_in, 0, sizeof(msg_report_in)); 235 | memset((void*) &msg_report_out, 0, sizeof(msg_report_out)); 236 | // default to zeros 237 | memset(msg_report_in.report_data, 0x00, sizeof(msg_report_in.report_data)); 238 | // sha-512 key configuration structure to be used as report_data 239 | if (argc >1) { 240 | char *hexstring = argv[1]; 241 | size_t to_copy = (strlen(hexstring)+1)/2; 242 | if (to_copy > sizeof(msg_report_in.report_data)) 243 | to_copy = sizeof(msg_report_in.report_data); 244 | 245 | for (size_t i = 0; i < to_copy; i++) { 246 | sscanf(hexstring, "%2hhx", &msg_report_in.report_data[i]); 247 | hexstring += 2; 248 | } 249 | } 250 | 251 | fd = open("/dev/sev", O_RDWR | O_CLOEXEC); 252 | 253 | if (fd < 0) { 254 | printf("Failed to open /dev/sev\n"); 255 | exit(-1); 256 | } 257 | 258 | rc = ioctl(fd, SEV_SNP_GUEST_MSG_REPORT, &payload); 259 | 260 | if (rc < 0) { 261 | printf("Failed to issue ioctl SEV_SNP_GUEST_MSG_REPORT\n"); 262 | exit(-1); 263 | } 264 | 265 | if (!formatAsHtml && !hexBlob) { 266 | printf("Response header:\n"); 267 | 268 | uint8_t *hdr = (uint8_t*) &msg_report_out; 269 | 270 | for (i = 0; i < 32; i++) { 271 | printf("%02x", hdr[i]); 272 | if (i % 16 == 15) 273 | printf("\n"); 274 | else 275 | printf(" "); 276 | } 277 | } 278 | 279 | if (hexBlob) { 280 | printBytes("Raw report", (const uint8_t *)&msg_report_out.report, sizeof(msg_report_out.report), false, false); 281 | } else { 282 | printReport(&msg_report_out.report); 283 | } 284 | exit(0); 285 | } 286 | --------------------------------------------------------------------------------