Coverage for sgx/envelope.py: 100%
40 statements
« prev ^ index » next coverage.py v7.5.3, created at 2025-07-10 13:43 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2025-07-10 13:43 +0000
1# The MIT License (MIT)
2#
3# Copyright (c) 2021 RSK Labs Ltd
4#
5# Permission is hereby granted, free of charge, to any person obtaining a copy of
6# this software and associated documentation files (the "Software"), to deal in
7# the Software without restriction, including without limitation the rights to
8# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9# of the Software, and to permit persons to whom the Software is furnished to do
10# so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be included in all
13# copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21# SOFTWARE.
23from comm.cstruct import CStruct
26class SgxEnvelope(CStruct):
27 """
28 sgx_envelope_t
30 sgx_quote_t quote
31 sgx_quote_tail_t quote_tail
32 sgx_quote_auth_data_t quote_auth_data
33 """
35 def __init__(self, envelope_bytes, custom_message_bytes, offset=0, little=True):
36 super().__init__(envelope_bytes, offset, little)
37 offset += self.get_bytelength()
39 qead = SgxQeAuthData(envelope_bytes, offset, little)
40 offset += qead.get_total_bytelength()
41 self.qe_auth_data = qead
43 qecd = SgxQeCertData(envelope_bytes, offset, little)
44 offset += qecd.get_total_bytelength()
45 self.qe_cert_data = qecd
47 if envelope_bytes[offset:] != custom_message_bytes:
48 raise ValueError("Unexpected custom message in envelope tail")
49 self.custom_message = custom_message_bytes
51##############################################################################
52# Types below taken from OpenEnclave's include/openenclave/bits/sgx/sgxtypes.h
53##############################################################################
56class SgxAttributes(CStruct):
57 """
58 sgx_attributes_t
60 uint64_t flags
61 uint64_t xfrm
62 """
65class SgxReportData(CStruct):
66 """
67 sgx_report_data_t
69 uint8_t field 64
70 """
73class SgxReportBody(CStruct):
74 """
75 sgx_report_body_t
77 uint8_t cpusvn 16
78 uint32_t miscselect
79 uint8_t reserved1 12
80 uint8_t isvextprodid 16
81 sgx_attributes_t attributes
82 uint8_t mrenclave 32
83 uint8_t reserved2 32
84 uint8_t mrsigner 32
85 uint8_t reserved3 32
86 uint8_t configid 64
87 uint16_t isvprodid
88 uint16_t isvsvn
89 uint16_t configsvn
90 uint8_t reserved4 42
91 uint8_t isvfamilyid 16
92 sgx_report_data_t report_data
93 """
96class SgxEcdsa256Signature(CStruct):
97 """
98 sgx_ecdsa256_signature_t
100 uint8_t r 32
101 uint8_t s 32
102 """
105class SgxEcdsa256Key(CStruct):
106 """
107 sgx_ecdsa256_key_t
109 uint8_t x 32
110 uint8_t y 32
111 """
114class SgxQuote(CStruct):
115 """
116 sgx_quote_t
118 uint16_t version
119 uint16_t sign_type
120 uint32_t tee_type
121 uint16_t qe_svn
122 uint16_t pce_svn
123 uint8_t uuid 16
124 uint8_t user_data 20
125 sgx_report_body_t report_body
126 """
129# This is actually part of sgx_quote_t, separated
130# for pratical reasons since the signature doesn't include
131# this field
132class SgxQuoteTail(CStruct):
133 """
134 sgx_quote_tail_t
136 uint32_t signature_len
137 """
140class SgxQuoteAuthData(CStruct):
141 """
142 sgx_quote_auth_data_t
144 sgx_ecdsa256_signature_t signature
145 sgx_ecdsa256_key_t attestation_key
146 sgx_report_body_t qe_report_body
147 sgx_ecdsa256_signature_t qe_report_body_signature
148 """
150####################################################################
151# The following two structs are augmented with content parsing logic
152####################################################################
155class SgxQeAuthData(CStruct):
156 """
157 sgx_qe_auth_data_t
159 uint16_t size
160 """
162 def __init__(self, value, offset=0, little=True):
163 super().__init__(value, offset, little)
164 os = offset + self.get_bytelength()
165 data = value[os:os+self.size]
166 if len(data) != self.size:
167 raise ValueError(f"Expected {self.size} data bytes but only got {len(data)}")
168 self.data = data
170 def get_total_bytelength(self):
171 return self.get_bytelength() + len(self.data)
174class SgxQeCertData(SgxQeAuthData):
175 """
176 sgx_qe_cert_data_t
178 uint16_t type
179 uint32_t size
180 """
181 SPEC = None
182 TYPENAME = None
184 X509_START_MARKER = b"-----BEGIN CERTIFICATE-----\n"
185 X509_END_MARKER = b"\n-----END CERTIFICATE-----\n"
187 def __init__(self, value, offset=0, little=True):
188 super().__init__(value, offset, little)
189 self.certs = list(map(lambda c: c.replace(self.X509_START_MARKER, b""),
190 filter(lambda c:
191 c.strip().startswith(self.X509_START_MARKER),
192 self.data.split(self.X509_END_MARKER))))