CCF
Loading...
Searching...
No Matches
sev_snp_cpuid.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
5#include "ccf/ds/hex.h"
6#include "ccf/ds/json.h"
7
8#include <cstdint>
9#include <stdexcept>
10#include <string>
11
12namespace ccf::pal::snp
13{
14
15#pragma pack(push, 1)
16 // AMD CPUID specification. Chapter 2 Fn0000_0001_EAX
17 // Milan: 0x00A00F11
18 // Genoa: 0X00A10F11
19 // Note: The CPUID is little-endian so the hex_string is reversed
20 struct CPUID
21 {
22 uint8_t stepping : 4;
23 uint8_t base_model : 4;
24 uint8_t base_family : 4;
25 uint8_t reserved : 4;
26 uint8_t extended_model : 4;
27 uint8_t extended_family : 8;
28 uint8_t reserved2 : 4;
29
30 bool operator==(const CPUID&) const = default;
31 std::string hex_str() const
32 {
33 CPUID buf = *this;
34 auto buf_ptr = reinterpret_cast<uint8_t*>(&buf);
35 const std::span<const uint8_t> tcb_bytes{
36 buf_ptr, buf_ptr + sizeof(CPUID)};
37 return fmt::format(
38 "{:02x}", fmt::join(tcb_bytes.rbegin(), tcb_bytes.rend(), ""));
39 }
40 inline uint8_t get_family_id() const
41 {
42 return this->base_family + this->extended_family;
43 }
44 inline uint8_t get_model_id() const
45 {
46 return (this->extended_model << 4) | this->base_model;
47 }
48 };
49#pragma pack(pop)
52 CPUID, stepping, base_model, base_family, extended_model, extended_family);
53 static_assert(
54 sizeof(CPUID) == sizeof(uint32_t), "Cannot cast CPUID to uint32_t");
55 static CPUID cpuid_from_hex(const std::string& hex_str)
56 {
57 CPUID ret{};
58 auto* buf_ptr = reinterpret_cast<uint8_t*>(&ret);
59 ccf::ds::from_hex(hex_str, buf_ptr, buf_ptr + sizeof(CPUID));
60 std::reverse(
61 buf_ptr, buf_ptr + sizeof(CPUID)); // fix little endianness of AMD
62 return ret;
63 }
64
65 // On SEVSNP cpuid cannot be trusted and must later be validated against an
66 // attestation.
67 static CPUID get_cpuid_untrusted()
68 {
69 uint32_t ieax = 1;
70 uint64_t iebx = 0;
71 uint64_t iecx = 0;
72 uint64_t iedx = 0;
73 uint32_t oeax = 0;
74 uint64_t oebx = 0;
75 uint64_t oecx = 0;
76 uint64_t oedx = 0;
77 // pass in e{b,c,d}x to prevent cpuid from blatting other registers
78 asm volatile("cpuid"
79 : "=a"(oeax), "=b"(oebx), "=c"(oecx), "=d"(oedx)
80 : "a"(ieax), "b"(iebx), "c"(iecx), "d"(iedx));
81 auto cpuid = *reinterpret_cast<CPUID*>(&oeax);
82 return cpuid;
83 }
84
85 enum class ProductName
86 {
87 Milan,
88 Genoa,
89 Turin
90 };
91
92 inline std::string to_string(ProductName product)
93 {
94 switch (product)
95 {
97 return "Milan";
99 return "Genoa";
101 return "Turin";
102 default:
103 throw std::logic_error("Unknown SEV-SNP product");
104 }
105 }
106
109 {
110 {ProductName::Milan, "Milan"},
111 {ProductName::Genoa, "Genoa"},
112 {ProductName::Turin, "Turin"},
113 });
114
115 using AMDFamily = uint8_t;
116 using AMDModel = uint8_t;
117
119 {
120 constexpr uint8_t milan_family = 0x19;
121 constexpr uint8_t milan_model = 0x01;
122 if (family == milan_family && model == milan_model)
123 {
124 return ProductName::Milan;
125 }
126 constexpr uint8_t genoa_family = 0x19;
127 constexpr uint8_t genoa_model = 0x11;
128 if (family == genoa_family && model == genoa_model)
129 {
130 return ProductName::Genoa;
131 }
132 constexpr uint8_t turin_family = 0x1A;
133 constexpr uint8_t turin_model = 0x01;
134 if (family == turin_family && model == turin_model)
135 {
136 return ProductName::Turin;
137 }
138 throw std::logic_error(fmt::format(
139 "SEV-SNP: Unsupported CPUID family {} model {}", family, model));
140 }
141
143 {
144 return get_sev_snp_product(cpuid.get_family_id(), cpuid.get_model_id());
145 }
146
147 inline std::string get_cpuid_of_snp_sev_product(ProductName product)
148 {
149 switch (product)
150 {
152 return "00a00f11";
154 return "00a10f11";
156 return "00b00f11";
157 default:
158 throw std::logic_error(fmt::format(
159 "SEV-SNP: Unsupported product for CPUID: {}", to_string(product)));
160 }
161 }
162}
#define DECLARE_JSON_REQUIRED_FIELDS(TYPE,...)
Definition json.h:714
#define DECLARE_JSON_TYPE(TYPE)
Definition json.h:663
#define DECLARE_JSON_ENUM(TYPE,...)
Definition json.h:837
Definition attestation_sev_snp.h:24
std::string to_string(ProductName product)
Definition sev_snp_cpuid.h:92
ProductName
Definition sev_snp_cpuid.h:86
uint8_t AMDModel
Definition sev_snp_cpuid.h:116
ProductName get_sev_snp_product(AMDFamily family, AMDModel model)
Definition sev_snp_cpuid.h:118
uint8_t AMDFamily
Definition sev_snp_cpuid.h:115
std::string get_cpuid_of_snp_sev_product(ProductName product)
Definition sev_snp_cpuid.h:147
Definition sev_snp_cpuid.h:21
uint8_t get_family_id() const
Definition sev_snp_cpuid.h:40
uint8_t extended_model
Definition sev_snp_cpuid.h:26
uint8_t extended_family
Definition sev_snp_cpuid.h:27
std::string hex_str() const
Definition sev_snp_cpuid.h:31
uint8_t base_family
Definition sev_snp_cpuid.h:24
uint8_t get_model_id() const
Definition sev_snp_cpuid.h:44
uint8_t reserved
Definition sev_snp_cpuid.h:25
bool operator==(const CPUID &) const =default
uint8_t stepping
Definition sev_snp_cpuid.h:22
uint8_t base_model
Definition sev_snp_cpuid.h:23
uint8_t reserved2
Definition sev_snp_cpuid.h:28