Coverage for sgx/envelope.py: 100%

40 statements  

« 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. 

22 

23from comm.cstruct import CStruct 

24 

25 

26class SgxEnvelope(CStruct): 

27 """ 

28 sgx_envelope_t 

29 

30 sgx_quote_t quote 

31 sgx_quote_tail_t quote_tail 

32 sgx_quote_auth_data_t quote_auth_data 

33 """ 

34 

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() 

38 

39 qead = SgxQeAuthData(envelope_bytes, offset, little) 

40 offset += qead.get_total_bytelength() 

41 self.qe_auth_data = qead 

42 

43 qecd = SgxQeCertData(envelope_bytes, offset, little) 

44 offset += qecd.get_total_bytelength() 

45 self.qe_cert_data = qecd 

46 

47 if envelope_bytes[offset:] != custom_message_bytes: 

48 raise ValueError("Unexpected custom message in envelope tail") 

49 self.custom_message = custom_message_bytes 

50 

51############################################################################## 

52# Types below taken from OpenEnclave's include/openenclave/bits/sgx/sgxtypes.h 

53############################################################################## 

54 

55 

56class SgxAttributes(CStruct): 

57 """ 

58 sgx_attributes_t 

59 

60 uint64_t flags 

61 uint64_t xfrm 

62 """ 

63 

64 

65class SgxReportData(CStruct): 

66 """ 

67 sgx_report_data_t 

68 

69 uint8_t field 64 

70 """ 

71 

72 

73class SgxReportBody(CStruct): 

74 """ 

75 sgx_report_body_t 

76 

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 """ 

94 

95 

96class SgxEcdsa256Signature(CStruct): 

97 """ 

98 sgx_ecdsa256_signature_t 

99 

100 uint8_t r 32 

101 uint8_t s 32 

102 """ 

103 

104 

105class SgxEcdsa256Key(CStruct): 

106 """ 

107 sgx_ecdsa256_key_t 

108 

109 uint8_t x 32 

110 uint8_t y 32 

111 """ 

112 

113 

114class SgxQuote(CStruct): 

115 """ 

116 sgx_quote_t 

117 

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 """ 

127 

128 

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 

135 

136 uint32_t signature_len 

137 """ 

138 

139 

140class SgxQuoteAuthData(CStruct): 

141 """ 

142 sgx_quote_auth_data_t 

143 

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 """ 

149 

150#################################################################### 

151# The following two structs are augmented with content parsing logic 

152#################################################################### 

153 

154 

155class SgxQeAuthData(CStruct): 

156 """ 

157 sgx_qe_auth_data_t 

158 

159 uint16_t size 

160 """ 

161 

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 

169 

170 def get_total_bytelength(self): 

171 return self.get_bytelength() + len(self.data) 

172 

173 

174class SgxQeCertData(SgxQeAuthData): 

175 """ 

176 sgx_qe_cert_data_t 

177 

178 uint16_t type 

179 uint32_t size 

180 """ 

181 SPEC = None 

182 TYPENAME = None 

183 

184 X509_START_MARKER = b"-----BEGIN CERTIFICATE-----\n" 

185 X509_END_MARKER = b"\n-----END CERTIFICATE-----\n" 

186 

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))))