github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/gosec/signature.go (about)

     1  package gosec
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/sha256"
     6  	"encoding/binary"
     7  	"encoding/gob"
     8  	"io/ioutil"
     9  	"os"
    10  	"os/exec"
    11  	"time"
    12  	"unsafe"
    13  )
    14  
    15  const (
    16  	target           = "/tmp/gobdump.dat"
    17  	_enclaveCssSize  = uintptr(1808)
    18  	_miscselectSize  = uintptr(4)
    19  	_attribSize      = uintptr(16)
    20  	_measurementSize = uintptr(SGX_HASH_SIZE)
    21  	_tcs_t_size      = uintptr(0x1000)
    22  )
    23  
    24  var data2hash []byte = nil
    25  var meta *metadata_t
    26  
    27  func checkStructSize() {
    28  	if unsafe.Sizeof(enclave_css_t{}) != _enclaveCssSize {
    29  		panic("Wrong size for the enclave css.")
    30  	}
    31  
    32  	if unsafe.Sizeof(miscselect_t{}) != _miscselectSize {
    33  		panic("Wrong size for the miscseclect")
    34  	}
    35  
    36  	if unsafe.Sizeof(sgx_attributes_t{}) != _attribSize {
    37  		panic("Wrong size for the sgx_attributes.")
    38  	}
    39  
    40  	if unsafe.Sizeof(sgx_measurement_t{}) != _measurementSize {
    41  		panic("Wrong size for the sgx_measurement")
    42  	}
    43  
    44  	if unsafe.Sizeof(tcs_t{}) != _tcs_t_size {
    45  		panic("Wrong size for the tcs_t")
    46  	}
    47  }
    48  
    49  func sgxHashInit() {
    50  	checkStructSize()
    51  	data2hash = make([]byte, 0)
    52  	meta = &metadata_t{}
    53  	setHeader(&meta.Enclave_css)
    54  	setBody(&meta.Enclave_css)
    55  	meta.Magic_num = METADATA_MAGIC
    56  	meta.Version = METADATA_VERSION
    57  	meta.Tcs_policy = 1
    58  	meta.Max_save_buffer_size = 2632
    59  	meta.Desired_misc_select = 0
    60  	meta.Tcs_min_pool = 1
    61  
    62  }
    63  
    64  func setHeader(e *enclave_css_t) {
    65  	e.Header = [12]uint8{6, 0, 0, 0, 0xE1, 0, 0, 0, 0, 0, 1, 0}
    66  	e.Header2 = [16]uint8{1, 1, 0, 0, 0x60, 0, 0, 0, 0x60, 0, 0, 0, 1, 0, 0, 0}
    67  	//TODO trying to see if dbg works.
    68  	e.Tpe = 0 //uint32(TPE_DBG)
    69  	e.Module_vendor = 0
    70  	year, month, day := time.Now().Date()
    71  	e.Date = uint32(day + (int(month) << 8) + (year % 100 << 16) + (year / 100 << 24))
    72  	e.Hw_version = 0
    73  	for i := range e.Reserved {
    74  		e.Reserved[i] = 0
    75  	}
    76  }
    77  
    78  func setBody(e *enclave_css_t) {
    79  	e.Misc_mask.Value = 0xff
    80  	for i := range e.Misc_mask.Reversed2 {
    81  		e.Misc_mask.Reversed2[i] = 0xff
    82  	}
    83  	e.Isv_prod_id = 0
    84  	e.Isv_svn = 42
    85  }
    86  
    87  func sgxHashEcreate(secs *secs_t) {
    88  	meta.Enclave_size = secs.size
    89  	meta.Attributes.Flags = secs.attributes
    90  	meta.Attributes.Xfrm = secs.xfrm
    91  
    92  	tmp := make([]byte, 64)
    93  	offset := 0
    94  
    95  	eheader := []byte("ECREATE\000")
    96  	if len(eheader) != 8 {
    97  		panic("header has incorrect size.")
    98  	}
    99  	memcpy_s(tmp, eheader, offset, 8)
   100  	offset += 8
   101  
   102  	//ssaFS := make([]byte, 8)
   103  	//binary.LittleEndian.PutUint64(ssaFS, uint64(secs.ssaFrameSize))
   104  	//memcpy_s(tmp, ssaFS, offset, 8)
   105  	//offset += 8
   106  	ssaFS := make([]byte, 4)
   107  	binary.LittleEndian.PutUint32(ssaFS, secs.ssaFrameSize)
   108  	memcpy_s(tmp, ssaFS, offset, 4)
   109  	offset += 4
   110  
   111  	secSize := make([]byte, 8)
   112  	binary.LittleEndian.PutUint64(secSize, secs.size)
   113  	memcpy_s(tmp, secSize, offset, 8)
   114  	offset += 8
   115  	for i := offset; i < len(tmp); i++ {
   116  		tmp[i] = byte(0)
   117  	}
   118  
   119  	// Append it to the hash.
   120  	data2hash = append(data2hash, tmp...)
   121  }
   122  
   123  func sgxHashEadd(secs *secs_t, secinfo *isgx_secinfo, daddr uintptr) {
   124  	if daddr < uintptr(secs.baseAddr) {
   125  		panic("gosec: invalid daddr out of range.")
   126  	}
   127  	tmp := make([]byte, 64)
   128  	offset := 0
   129  
   130  	eheader := []byte("EADD\000\000\000\000")
   131  	if len(eheader) != 8 {
   132  		panic("EADD hash has not the correct size.")
   133  	}
   134  	memcpy_s(tmp, eheader, offset, 8)
   135  	offset += 8
   136  
   137  	off := uint64(daddr) - secs.baseAddr
   138  	encloff := make([]byte, 8)
   139  	binary.LittleEndian.PutUint64(encloff, off)
   140  	memcpy_s(tmp, encloff, offset, 8)
   141  	offset += 8
   142  
   143  	flags := make([]byte, 8)
   144  	binary.LittleEndian.PutUint64(flags, secinfo.flags)
   145  	memcpy_s(tmp, flags, offset, 8)
   146  	offset += 8
   147  
   148  	base := unsafe.Pointer(&secinfo.reserved)
   149  	for i := offset; i < len(tmp); i++ {
   150  		val := (*byte)(unsafe.Pointer(uintptr(base) + uintptr(i-offset)))
   151  		tmp[i] = *val
   152  	}
   153  	// Add it to the signature.
   154  	data2hash = append(data2hash, tmp...)
   155  
   156  	if secinfo.flags&SGX_SECINFO_W == 0 || secinfo.flags&SGX_SECINFO_TCS != 0 {
   157  		sgxHashEExtendRegion(secs, daddr)
   158  	}
   159  
   160  }
   161  
   162  func sgxHashEExtend(secs *secs_t, daddr uintptr) {
   163  	if daddr < uintptr(secs.baseAddr) || daddr > uintptr(secs.baseAddr)+uintptr(secs.size) {
   164  		panic("gosec: invalid daddr out of range.")
   165  	}
   166  	tmp := make([]byte, 320)
   167  	offset := 0
   168  
   169  	eheader := []byte("EEXTEND\000")
   170  	if len(eheader) != 8 {
   171  		panic("EEXTEND has not the correct size.")
   172  	}
   173  	memcpy_s(tmp, eheader, offset, 8)
   174  	offset += 8
   175  
   176  	off := uint64(uint64(daddr) - secs.baseAddr)
   177  	encloff := make([]byte, 8)
   178  	binary.LittleEndian.PutUint64(encloff, off)
   179  	memcpy_s(tmp, encloff, offset, 8)
   180  	offset += 8
   181  
   182  	// TODO 48 0 bytes.
   183  	offset += 48
   184  	base := transposeOut(daddr)
   185  	for i := uintptr(0); i < uintptr(256); i++ {
   186  		val := (*byte)(unsafe.Pointer(base + i))
   187  		tmp[int(i)+offset] = *val
   188  	}
   189  	data2hash = append(data2hash, tmp...)
   190  }
   191  
   192  // Adds a full page to the eextend
   193  func sgxHashEExtendRegion(secs *secs_t, daddr uintptr) {
   194  	for i := uintptr(0); i < PSIZE; i += uintptr(256) {
   195  		sgxHashEExtend(secs, daddr+i)
   196  	}
   197  }
   198  
   199  func sgxHashFinalize() {
   200  	sig := sha256.Sum256(data2hash)
   201  	for i := 0; i < SGX_HASH_SIZE; i++ {
   202  		meta.Enclave_css.Enclave_hash.M[i] = sig[i]
   203  	}
   204  
   205  	//Do a dump of the measurement here.
   206  	err := ioutil.WriteFile("/tmp/gosec_measurement.dat", data2hash, 0644)
   207  	check(err)
   208  }
   209  
   210  func sgxTokenGetRequest(secs *secs_t) *LaunchTokenRequest {
   211  	tokenreq := &LaunchTokenRequest{}
   212  	tokenreq.MrSigner = []byte("trying") // key modulus.
   213  	tokenreq.MrEnclave = meta.Enclave_css.Enclave_hash.M[:]
   214  
   215  	seattrib := make([]byte, 0)
   216  
   217  	attrib := make([]byte, 8)
   218  	binary.LittleEndian.PutUint64(attrib, secs.attributes)
   219  	seattrib = append(seattrib, attrib...)
   220  
   221  	xflags := make([]byte, 8)
   222  	binary.LittleEndian.PutUint64(xflags, secs.xfrm)
   223  	seattrib = append(seattrib, xflags...)
   224  
   225  	tokenreq.SeAttributes = seattrib
   226  	return tokenreq
   227  }
   228  
   229  func sgxTokenGetAesm(secs *secs_t) TokenGob {
   230  	request := sgxTokenGetRequest(secs)
   231  
   232  	f, err := os.Create("/tmp/gobdump_meta.dat")
   233  	check(err)
   234  
   235  	enc := gob.NewEncoder(f)
   236  	err = enc.Encode(meta)
   237  	check(err)
   238  
   239  	f2, err := os.Create("/tmp/gobdump_req.dat")
   240  	check(err)
   241  	enc = gob.NewEncoder(f2)
   242  	err = enc.Encode(request)
   243  	check(err)
   244  
   245  	cmd := exec.Command("serializer", "")
   246  	err = cmd.Run()
   247  	check(err)
   248  
   249  	// Read the token.
   250  	b, err := ioutil.ReadFile("/tmp/go_enclave.token")
   251  	check(err)
   252  
   253  	dec := gob.NewDecoder(bytes.NewReader(b))
   254  	var token TokenGob
   255  	err = dec.Decode(&token)
   256  	check(err)
   257  	return token
   258  }
   259  
   260  func memcpy_s(dst, src []byte, off, s int) {
   261  	for i := 0; i < s; i++ {
   262  		dst[off+i] = src[i]
   263  	}
   264  }