class LibWwqParseCFFI(LibWwqLyParseBase): def __init__(self): super(LibWwqParseCFFI, self).__init__() from cffi import FFI self.ffi = FFI() self.lib = self.ffi.dlopen(self.lib_path) self.ffi.cdef(""" char * get_uuid(); char * get_name(); int parse(char * c,int length,char **result,int *result_length); int free_str(char * c); """) self.lib.__class__.__repr__ = lambda s: "<%s object at 0x%016X>" % (s.__class__.__name__, id(s)) logging.debug("successful load lib %s" % self.lib) weakref.finalize(self, lambda: logging.debug("%s released" % self.lib) if self.ffi.dlclose(self.lib) or 1 else None) def get_uuid(self) -> bytes: return self.ffi.string(self.lib.get_uuid()) def get_name(self) -> bytes: return self.ffi.string(self.lib.get_name()) def lib_parse(self, byte_str: bytes) -> bytes: length = self.ffi.cast("int", len(byte_str)) result_length = self.ffi.new("int *") result_p = self.ffi.new("char **") # p = self.ffi.new("char []", byte_str) p = self.ffi.from_buffer(byte_str) self.lib.parse(p, length, result_p, result_length) result = self.ffi.unpack(result_p[0], result_length[0]) self.lib.free_str(result_p[0]) return result
def test_from_buffer(self): import array ffi = FFI() a = array.array('H', [10000, 20000, 30000]) c = ffi.from_buffer(a) assert ffi.typeof(c) is ffi.typeof("char[]") ffi.cast("unsigned short *", c)[1] += 500 assert list(a) == [10000, 20500, 30000]
def segment(imgname, threshold, doRGBtoLAB): #-------------------------------------------------------------- # read image and change image shape from (h,w,c) to (c,h,w) #-------------------------------------------------------------- img = Image.open(imgname) # img = imread(imgname) img = np.asarray(img) print("input image shape", img.shape) dims = img.shape h, w, c = dims[0], dims[1], 1 if len(dims) > 1: c = dims[2] img = img.transpose(2, 0, 1) #-------------------------------------------------------------- # Reshape image to a single dimensional vector #-------------------------------------------------------------- img = img.reshape(-1).astype(np.double) labels = np.zeros((h, w), dtype=np.int32) numlabels = np.zeros(1, dtype=np.int32) #-------------------------------------------------------------- # Prepare the pointers to pass to the C function #-------------------------------------------------------------- ffibuilder = FFI() pinp = ffibuilder.cast("double*", ffibuilder.from_buffer(img)) plabels = ffibuilder.cast("int*", ffibuilder.from_buffer(labels.reshape(-1))) pnumlabels = ffibuilder.cast("int*", ffibuilder.from_buffer(numlabels)) start = timer() Adaptels_main(pinp, w, h, c, threshold, doRGBtoLAB, plabels, pnumlabels) end = timer() #-------------------------------------------------------------- # Collect labels #-------------------------------------------------------------- print("number of superpixels: ", numlabels[0]) print("time taken in seconds: ", end - start) return labels.reshape(h, w), numlabels[0]
def test_from_buffer(self): import array ffi = FFI() a = array.array('H', [10000, 20000, 30000]) c = ffi.from_buffer(a) assert ffi.typeof(c) is ffi.typeof("char[]") ffi.cast("unsigned short *", c)[1] += 500 assert list(a) == [10000, 20500, 30000] assert c == ffi.from_buffer(a, True) assert c == ffi.from_buffer(a, require_writable=True) # p = ffi.from_buffer(b"abcd") assert p[2] == b"c" # assert p == ffi.from_buffer(b"abcd", False) py.test.raises((TypeError, BufferError), ffi.from_buffer, b"abcd", True) py.test.raises((TypeError, BufferError), ffi.from_buffer, b"abcd", require_writable=True)
class KaldiGmmDecoder(KaldiDecoderBase): """docstring for KaldiGmmDecoder""" def __init__(self, graph_dir=None, words_file=None, graph_file=None, model_conf_file=None): super(KaldiGmmDecoder, self).__init__() self._ffi = FFI() self._ffi.cdef(""" void* init_gmm(float beam, int32_t max_active, int32_t min_active, float lattice_beam, char* word_syms_filename_cp, char* fst_in_str_cp, char* config_cp); bool decode_gmm(void* model_vp, float samp_freq, int32_t num_frames, float* frames, bool finalize); bool get_output_gmm(void* model_vp, char* output, int32_t output_length, double* likelihood_p); """) self._lib = self._ffi.dlopen(self._library_binary) if words_file is None and graph_dir is not None: words_file = graph_dir + r"graph\words.txt" if graph_file is None and graph_dir is not None: graph_file = graph_dir + r"graph\HCLG.fst" self.words_file = os.path.normpath(words_file) self.graph_file = os.path.normpath(graph_file) self.model_conf_file = os.path.normpath(model_conf_file) self._model = self._lib.init_gmm(7.0, 7000, 200, 8.0, words_file, graph_file, model_conf_file) self.sample_rate = 16000 def decode(self, frames, finalize, grammars_activity=None): if not isinstance(frames, np.ndarray): frames = np.frombuffer(frames, np.int16) frames = frames.astype(np.float32) frames_char = self._ffi.from_buffer(frames) frames_float = self._ffi.cast('float *', frames_char) self._start_decode_time(len(frames)) result = self._lib.decode_gmm(self._model, self.sample_rate, len(frames), frames_float, finalize) self._stop_decode_time(finalize) if not result: raise RuntimeError("decoding error") return finalize def get_output(self, output_max_length=4 * 1024): output_p = self._ffi.new('char[]', output_max_length) likelihood_p = self._ffi.new('double *') result = self._lib.get_output_gmm(self._model, output_p, output_max_length, likelihood_p) output_str = self._ffi.string(output_p) likelihood = likelihood_p[0] return output_str, likelihood
def get_sgx_report(public_key_path): with open(public_key_path, 'rb') as f: public_key = f.read() ffi = FFI() ffi.cdef(""" int scone_sgx_report_get( const unsigned char *report_data, const unsigned char *target_info, unsigned char *report); """) C = ffi.dlopen("/libreport.so") sgx_report_data = sha256(public_key).digest() + bytes(32) sgx_report = bytes(432) sgx_report_cdata = ffi.from_buffer("unsigned char[]", sgx_report) print('Calling scone_sgx_report_get()') res = C.scone_sgx_report_get(sgx_report_data, ffi.NULL, sgx_report_cdata) if res != 0: print('Error retrieving SGX report') return { "sgx_quote": base64.b64encode(sgx_report).decode(), "sgx_ehd": base64.b64encode(public_key).decode() }
class RimeConstDefinition(object): """ Holds the cffi object defining the C structure of the RIME constant data which will be passed to GPUs. """ def __init__(self, slvr): self._ffi = FFI() # Parse the structure self._cstr = self._struct(slvr) self._ffi.cdef(self._struct(slvr)) @staticmethod def _struct(slvr): """ Returns a string containing the C definition of the RIME constant data structure """ def _emit_struct_field_str(name): return _SPACE + '{t} {n};'.format(t=_FIELD_TYPE, n=name) # Define our field structure. Looks something like # typedef struct { # unsigned int global_size; # unsigned int local_size; # unsigned int extents[2]; # } _FIELD_TYPE; l = ['typedef struct {'] l.extend([ _SPACE + 'unsigned int {n};'.format(n=n) for n in ('global_size', 'local_size', 'lower_extent', 'upper_extent') ]) l.append('}} {t};'.format(t=_FIELD_TYPE)) # Define our constant data structure. Looks something like # typedef struct { # _FIELD_TYPE ntime; # _FIELD_TYPE na; # .... # } _STRUCT_TYPE; l.append('typedef struct {') l.extend( [_emit_struct_field_str(n) for n in slvr.dimensions().iterkeys()]) l.append('} ' + _STRUCT_TYPE + ';') # Join with newlines and return the string return '\n'.join(l) def struct_size(self): """ Returns the size in bytes of the RIME constant data structure """ return self._ffi.sizeof(_STRUCT_TYPE) def wrap(self, ndary): assert ndary.nbytes == self.struct_size(), \ ('The size of the supplied array {as} does ' 'not match that of the constant data structure {ds}.') \ .format(ws=ndary.nbytes, ds=self.struct_size()) # Create a cdata object by wrapping ndary # and cast to the structure type return self._ffi.cast(_STRUCT_PTR_TYPE, self._ffi.from_buffer(ndary)) def __str__(self): return self._cstr
class RimeConstDefinition(object): """ Holds the cffi object defining the C structure of the RIME constant data which will be passed to GPUs. """ def __init__(self, slvr): self._ffi = FFI() # Parse the structure self._cstr = self._struct(slvr) self._ffi.cdef(self._struct(slvr)) @staticmethod def _struct(slvr): """ Returns a string containing the C definition of the RIME constant data structure """ def _emit_struct_field_str(name): return _SPACE + '{t} {n};'.format(t=_FIELD_TYPE, n=name) # Define our field structure. Looks something like # typedef struct { # unsigned int global_size; # unsigned int local_size; # unsigned int extents[2]; # } _FIELD_TYPE; l = ['typedef struct {'] l.extend([_SPACE + 'unsigned int {n};'.format(n=n) for n in ('global_size', 'local_size', 'lower_extent', 'upper_extent')]) l.append('}} {t};'.format(t=_FIELD_TYPE)) # Define our constant data structure. Looks something like # typedef struct { # _FIELD_TYPE ntime; # _FIELD_TYPE na; # .... # } _STRUCT_TYPE; l.append('typedef struct {') l.extend([_emit_struct_field_str(n) for n in slvr.dimensions().iterkeys()]) l.append('} ' + _STRUCT_TYPE + ';') # Join with newlines and return the string return '\n'.join(l) def struct_size(self): """ Returns the size in bytes of the RIME constant data structure """ return self._ffi.sizeof(_STRUCT_TYPE) def wrap(self, ndary): assert ndary.nbytes == self.struct_size(), \ ('The size of the supplied array {as} does ' 'not match that of the constant data structure {ds}.') \ .format(ws=ndary.nbytes, ds=self.struct_size()) # Create a cdata object by wrapping ndary # and cast to the structure type return self._ffi.cast(_STRUCT_PTR_TYPE, self._ffi.from_buffer(ndary)) def __str__(self): return self._cstr
class Accelerator: """Accelerator for constructing MQTTSN packets. This accelerator is tied to the hardware block built using SDSoC. The following is a table of the memory mapped registers: AXILiteS 0x00 Control signals bit 0 - ap_start (Read/Write/COH) bit 1 - ap_done (Read/COR) bit 2 - ap_idle (Read) bit 3 - ap_ready (Read) bit 7 - auto_restart (Read/Write) others - reserved 0x04 Global Interrupt Enable Register bit 0 - Global Interrupt Enable (Read/Write) others - reserved 0x08 IP Interrupt Enable Register (Read/Write) bit 0 - Channel 0 (ap_done) bit 1 - Channel 1 (ap_ready) others - reserved 0x0c IP Interrupt Status Register (Read/TOW) bit 0 - Channel 0 (ap_done) bit 1 - Channel 1 (ap_ready) others - reserved 0x10 Data signal of b bit 0 - b[0] (Read/Write) others - reserved 0x14 reserved 0x18 Data signal of macAddress_V bit 31~0 - macAddress_V[31:0] (Read/Write) 0x1c Data signal of macAddress_V bit 15~0 - macAddress_V[47:32] (Read/Write) others - reserved 0x20 reserved 0x24 Data signal of ipAddress_V bit 31~0 - ipAddress_V[31:0] (Read/Write) 0x28 reserved 0x2c Data signal of i bit 31~0 - i[31:0] (Read/Write) 0x30 reserved 0x34 Data signal of destIP_V bit 31~0 - destIP_V[31:0] (Read/Write) 0x38 reserved 0x3c Data signal of destPort bit 31~0 - destPort[31:0] (Read/Write) 0x40 reserved 0x44 Data signal of topicID_V bit 15~0 - topicID_V[15:0] (Read/Write) others - reserved 0x48 reserved 0x4c Data signal of qos bit 31~0 - qos[31:0] (Read/Write) 0x50 reserved 0x54 Data signal of message bit 31~0 - message[31:0] (Read/Write) 0x58 reserved 0x5c Data signal of validMessage bit 0 - validMessage[0] (Read/Write) others - reserved 0x60 reserved 0x64 Data signal of network IOP offset bit 31~0 - network IOP offset[31:0] (Read/Write) 0x68 reserved 0x6c Data signal of count bit 31~0 - count[31:0] (Read/Write) 0x70 reserved 0x74 Data signal of size bit 31~0 - size[31:0] (Read/Write) 0x78 reserved 0x7c Data signal of reset bit 0 - reset[0] (Read/Write) others - reserved 0x80 reserved 0x84 Data signal of p_verbose bit 0 - p_verbose[0] (Read/Write) others - reserved 0x88 reserved 0x8c Data signal of events_completed bit 31~0 - events_completed[31:0] (Read) 0x90 Control signal of events_completed bit 0 - events_completed_ap_vld (Read/COR) others - reserved 0x94 Data signal of publishes_sent bit 31~0 - publishes_sent[31:0] (Read) 0x98 Control signal of publishes_sent bit 0 - publishes_sent_ap_vld (Read/COR) others - reserved 0x9c Data signal of packets_received bit 31~0 - packets_received[31:0] (Read) 0xa0 Control signal of packets_received bit 0 - packets_received_ap_vld (Read/COR) others - reserved 0xa4 Data signal of packets_sent bit 31~0 - packets_sent[31:0] (Read) 0xa8 Control signal of packets_sent bit 0 - packets_sent_ap_vld (Read/COR) others - reserved SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake Attributes ---------- interface_string : str The FFI interface description of the overlay (containing c-like prototypes) ffi : FFI The FFI object used by the overlay. dll_name : str This overlay assumes the dll filename is derived from bitfile name. """ def __init__(self): if PL.bitfile_name != BITFILE: raise ValueError("mqttsn_publish.bit must be loaded.") self.interface_string = CFFI_INTERFACE self.ffi = FFI() self.dll_name = SHARED_LIB self.dll = None self.sensor_ptr = None self.ffi.cdef(self.interface_string) with sys_pipes(): self.dll = self.ffi.dlopen(self.dll_name) def read_sensor(self, sensor_iop): """Read the value of a temperature sensor. """ if self.sensor_ptr is None: self.sensor_ptr = self.map(sensor_iop.mmio) return self.dll.read_sensor(self.sensor_ptr) def init_ethernet_raw(self, interface, port=1884): """Initialize the Ethernet raw interface. """ with sys_pipes(): self.dll.init_ethernet_raw(interface.encode('utf-8'), port) def map(self, mmio): """Map the given mmio interface in a way that SDSoC can use.""" virtaddr = self.ffi.from_buffer(mmio.mem) self.dll.sds_mmap(mmio.base_addr + mmio.virt_offset, mmio.length, virtaddr) return virtaddr def publish_cffi(self, size, count, pl_mac_address, pl_ip_address, server_ip_address, server_port_number, topic_id, qos, verbose, net_iop, sensor_iop): """Publish data from the given temperature sensor to an MQTTSN server. This method will use the CFFI to control the accelerator. Parameters ---------- size : int The size of frames to generate. count : int The number of publish events to complete. pl_mac_address : int/str The MAC Address of the PL accelerator (not the host MAC address). pl_ip_address : int/str The IP Address of the PL accelerator (not the host IP address). server_ip_address : int/str The IP Address of the MQTTSN server. server_port_number : int The port number of the MQTTSN server. topic_id : int The topic ID to publish on. qos : int The MQTTSN qos to use (0 means response is not required). verbose : int A non-zero value will get verbose debugging information. net_iop : NetworkIOP The network IOP object. sensor_iop : Pmod_TMP2 The temperature sensor object. """ pl_ip = pl_ip_address if type(pl_ip_address) is int \ else ip_str_to_int(pl_ip_address) pl_mac = pl_mac_address if type(pl_mac_address) is int \ else mac_str_to_int(pl_mac_address) server_ip = server_ip_address if type(server_ip_address) is int \ else ip_str_to_int(server_ip_address) mac_address_arg = self.ffi.cast("unsigned long long", pl_mac) ip_address_arg = self.ffi.cast("unsigned int", pl_ip) server_ip_arg = self.ffi.cast("unsigned int", server_ip) with sys_pipes(): net_iop_ptr = self.map(net_iop.mmio) sensor_iop_ptr = self.map(sensor_iop.mmio) ol.dll.Top(size, count, mac_address_arg, ip_address_arg, server_ip_arg, server_port_number, topic_id, qos, verbose, net_iop_ptr, sensor_iop_ptr) def publish_mmio(self, size, count, pl_mac_address, pl_ip_address, server_ip_address, server_port_number, topic_id, qos, verbose, net_iop, sensor_iop): """Publish data from the given temperature sensor to an MQTTSN server. This method will use the MMIO to control the accelerator. Parameters ---------- size : int The size of frames to generate. count : int The number of publish events to complete. pl_mac_address : int/str The MAC Address of the PL accelerator (not the host MAC address). pl_ip_address : int/str The IP Address of the PL accelerator (not the host IP address). server_ip_address : int/str The IP Address of the MQTTSN server. server_port_number : int The port number of the MQTTSN server. topic_id : int The topic ID to publish on. qos : int The MQTTSN qos to use (0 means response is not required). verbose : int A non-zero value will get verbose debugging information. net_iop : NetworkIOP The network IOP object. sensor_iop : Pmod_TMP2 The temperature sensor object. """ pl_ip = pl_ip_address if type(pl_ip_address) is int \ else ip_str_to_int(pl_ip_address) pl_mac = pl_mac_address if type(pl_mac_address) is int \ else mac_str_to_int(pl_mac_address) server_ip = server_ip_address if type(server_ip_address) is int \ else ip_str_to_int(server_ip_address) _ = self.map(net_iop.mmio) net_iop_phys = net_iop.mmio.base_addr + net_iop.mmio.virt_offset _ = self.map(sensor_iop.mmio) acc_mmio = MMIO(0x83c00000, 0x10000) acc_mmio.write(0x10, 1) acc_mmio.write(0x18, pl_mac & 0xFFFFFFFF) acc_mmio.write(0x1c, pl_mac >> 32) acc_mmio.write(0x24, pl_ip) acc_mmio.write(0x2c, 1) acc_mmio.write(0x34, server_ip) acc_mmio.write(0x3c, server_port_number) acc_mmio.write(0x44, topic_id) acc_mmio.write(0x4c, qos) acc_mmio.write(0x54, 0x0) acc_mmio.write(0x5c, 1) acc_mmio.write(0x64, net_iop_phys) acc_mmio.write(0x6c, count) acc_mmio.write(0x74, size) acc_mmio.write(0x7c, 1) acc_mmio.write(0x84, verbose) # verbose # execute the accelerator once to reset things acc_mmio.write(0x0, 1) status = acc_mmio.read(0x0) while status & 0x2 == 0: status = acc_mmio.read(0x0) # deassert reset acc_mmio.write(0x7c, 0) # reset # wait for the events to complete events_completed = 0 i = 0 while events_completed < count: status = acc_mmio.read(0x0) while status & 0x4 == 0: status = acc_mmio.read(0x0) # set our inputs and start acc_mmio.write(0x2c, i) # valid message acc_mmio.write(0x5c, i % 2) # start acc_mmio.write(0x0, 1) i = i + 1 events_completed = acc_mmio.read(0x8c) if i % 1000 == 0: print("status", status) print("events_completed:", events_completed) print("PublishesSent:", acc_mmio.read(0x94)) print("calls", i) print("events_completed:", events_completed) print("PublishesSent:", acc_mmio.read(0x94)) print("PacketsReceived:", acc_mmio.read(0x9c)) print("PacketsSent:", acc_mmio.read(0xa4))
class KaldiOtfGmmDecoder(KaldiDecoderBase): """docstring for KaldiOtfGmmDecoder""" def __init__(self, graph_dir=None, words_file=None, model_conf_file=None, hcl_fst_file=None, grammar_fst_files=None): super(KaldiOtfGmmDecoder, self).__init__() self._ffi = FFI() self._ffi.cdef(""" void* init_otf_gmm(float beam, int32_t max_active, int32_t min_active, float lattice_beam, char* word_syms_filename_cp, char* config_cp, char* hcl_fst_filename_cp, char** grammar_fst_filenames_cp, int32_t grammar_fst_filenames_len); bool add_grammar_fst_otf_gmm(void* model_vp, char* grammar_fst_filename_cp); bool decode_otf_gmm(void* model_vp, float samp_freq, int32_t num_frames, float* frames, bool finalize, bool* grammars_activity, int32_t grammars_activity_size); bool get_output_otf_gmm(void* model_vp, char* output, int32_t output_length, double* likelihood_p); """) self._lib = self._ffi.dlopen(self._library_binary) if words_file is None and graph_dir is not None: words_file = graph_dir + r"graph\words.txt" if hcl_fst_file is None and graph_dir is not None: hcl_fst_file = graph_dir + r"graph\HCLr.fst" if grammar_fst_files is None and graph_dir is not None: grammar_fst_files = [graph_dir + r"graph\Gr.fst"] self.words_file = os.path.normpath(words_file) self.model_conf_file = os.path.normpath(model_conf_file) self.hcl_fst_file = os.path.normpath(hcl_fst_file) grammar_fst_filenames_cps = [ self._ffi.new('char[]', os.path.normpath(f)) for f in grammar_fst_files ] grammar_fst_filenames_cp = self._ffi.new('char*[]', grammar_fst_filenames_cps) self._model = self._lib.init_otf_gmm( 7.0, 7000, 200, 8.0, words_file, model_conf_file, hcl_fst_file, self._ffi.cast('char**', grammar_fst_filenames_cp), len(grammar_fst_files)) self.sample_rate = 16000 self.num_grammars = len(grammar_fst_files) def add_grammar_fst(self, grammar_fst_file): grammar_fst_file = os.path.normpath(grammar_fst_file) _log.debug("%s: adding grammar_fst_file: %s", self, grammar_fst_file) result = self._lib.add_grammar_fst_otf_gmm(self._model, grammar_fst_file) if not result: raise KaldiError("error adding grammar") self.num_grammars += 1 def decode(self, frames, finalize, grammars_activity=None): # grammars_activity = [True] * self.num_grammars # grammars_activity = np.random.choice([True, False], len(grammars_activity)).tolist(); print grammars_activity; time.sleep(5) if grammars_activity is None: grammars_activity = [] else: _log.debug("decode: grammars_activity = %s", ''.join('1' if a else '0' for a in grammars_activity)) # if len(grammars_activity) != self.num_grammars: # raise KaldiError("wrong len(grammars_activity)") if not isinstance(frames, np.ndarray): frames = np.frombuffer(frames, np.int16) frames = frames.astype(np.float32) frames_char = self._ffi.from_buffer(frames) frames_float = self._ffi.cast('float *', frames_char) self._start_decode_time(len(frames)) result = self._lib.decode_otf_gmm(self._model, self.sample_rate, len(frames), frames_float, finalize, grammars_activity, len(grammars_activity)) self._stop_decode_time(finalize) if not result: raise KaldiError("decoding error") return finalize def get_output(self, output_max_length=4 * 1024): output_p = self._ffi.new('char[]', output_max_length) likelihood_p = self._ffi.new('double *') result = self._lib.get_output_otf_gmm(self._model, output_p, output_max_length, likelihood_p) output_str = self._ffi.string(output_p) likelihood = likelihood_p[0] return output_str, likelihood
def runKernel(opt): ffi = FFI() # create the FFI obj boHandle = xclAllocBO(opt.handle, opt.DATA_SIZE, xclBOKind.XCL_BO_DEVICE_RAM, opt.first_mem) bo1 = xclMapBO(opt.handle, boHandle, True) read_fp = ffi.cast("FILE *", bo1) if xclSyncBO(opt.handle, boHandle, xclBOSyncDirection.XCL_BO_SYNC_BO_TO_DEVICE, opt.DATA_SIZE, 0): return 1 p = xclBOProperties() bodevAddr = p.paddr if not (xclGetBOProperties(opt.handle, boHandle, p)) else -1 if bodevAddr is -1: return 1 # Allocate the exec_bo execHandle = xclAllocBO(opt.handle, opt.DATA_SIZE, xclBOKind.XCL_BO_SHARED_VIRTUAL, (1 << 31)) execData = xclMapBO(opt.handle, execHandle, True) # returns mmap() c_f = ffi.cast("FILE *", execData) if execData is ffi.NULL: print("execData is NULL") print("Construct the exe buf cmd to configure FPGA") ecmd = ert_configure_cmd() ecmd.m_uert.m_cmd_struct.state = 1 # ERT_CMD_STATE_NEW ecmd.m_uert.m_cmd_struct.opcode = 2 # ERT_CONFIGURE ecmd.slot_size = opt.DATA_SIZE ecmd.num_cus = 1 ecmd.cu_shift = 16 ecmd.cu_base_addr = opt.cu_base_addr ecmd.m_features.ert = opt.ert if opt.ert: ecmd.m_features.cu_dma = 1 ecmd.m_features.cu_isr = 1 # CU -> base address mapping ecmd.data[0] = opt.cu_base_addr ecmd.m_uert.m_cmd_struct.count = 5 + ecmd.num_cus sz = sizeof(ert_configure_cmd) ffi.memmove(c_f, ecmd, sz) print("Send the exec command and configure FPGA (ERT)") # Send the command. ret = xclExecBuf(opt.handle, execHandle) if ret: print("Unable to issue xclExecBuf") return 1 print("Wait until the command finish") while xclExecWait(opt.handle, 1000) != 0: print(".") print("Construct the exec command to run the kernel on FPGA") # construct the exec buffer cmd to start the kernel start_cmd = ert_start_kernel_cmd() rsz = (XHELLO_HELLO_CONTROL_ADDR_ACCESS1_DATA / 4 + 1) + 1 # regmap array size new_data = ((start_cmd.data._type_) * rsz)() start_cmd.m_uert.m_start_cmd_struct.state = 1 # ERT_CMD_STATE_NEW start_cmd.m_uert.m_start_cmd_struct.opcode = 0 # ERT_START_CU start_cmd.m_uert.m_start_cmd_struct.count = 1 + rsz start_cmd.cu_mask = 0x1 new_data[XHELLO_HELLO_CONTROL_ADDR_AP_CTRL] = 0x0 new_data[XHELLO_HELLO_CONTROL_ADDR_ACCESS1_DATA / 4] = bodevAddr new_data[XHELLO_HELLO_CONTROL_ADDR_ACCESS1_DATA / 4 + 1] = (bodevAddr >> 32) & 0xFFFFFFFF ffi.memmove(c_f, start_cmd, 2 * sizeof(c_uint32)) tmp_buf = ffi.buffer(c_f, 2 * sizeof(c_uint32) + (len(new_data) * sizeof(c_uint32))) data_ptr = ffi.from_buffer(tmp_buf) ffi.memmove(data_ptr + 2 * sizeof(c_uint32), new_data, len(new_data) * sizeof(c_uint32)) if xclExecBuf(opt.handle, execHandle): print("Unable to issue xclExecBuf") return 1 else: print("Kernel start command issued through xclExecBuf : start_kernel") print("Now wait until the kernel finish") print("Wait until the command finish") while xclExecWait(opt.handle, 1) != 0: print(".") # get the output xclSyncBO print("Get the output data from the device") if xclSyncBO(opt.handle, boHandle, xclBOSyncDirection.XCL_BO_SYNC_BO_FROM_DEVICE, opt.DATA_SIZE, 0): return 1 rd_buf = ffi.buffer(read_fp, len("Hello World")) print("RESULT: ") print(rd_buf[:] + "\n") return 0
# vim:fenc=utf-8 # Copyright © XYM # CreateTime: 2017-01-11 17:33:21 #from array import array import numpy as np from cffi import FFI import sys clf = FFI() try: N = int(eval(sys.argv[1])) except: N = 1000 #a = np.empty((N, N), dtype = 'int32') a = np.memmap('test.npy', mode='w+', shape=(N, N), dtype='int32') b = clf.cast('int [%d][%d]' % (N, N), clf.from_buffer(a)) for i in xrange(N): for j in xrange(N): b[i][j] = 2**31 - 1 for i in xrange(N): for j in xrange(N): if b[i][j] != 2**31 - 1: print 'found' print b[i][j], N * N / 1e8
from cffi import FFI import numpy as np ffi = FFI() lib = ffi.dlopen('./libmyclib.so') ffi.cdef(""" void add(double *, double *, int); void subtract(double *, double *, int); """) a = np.random.random(10) b = np.ones_like(a) # "pointer" objects aptr = ffi.cast("double *", ffi.from_buffer(a)) bptr = ffi.cast("double *", ffi.from_buffer(b)) print("a:", a) print("b:", b) lib.add(aptr, bptr, len(a)) print("a + b", a)
class SGXInterface: def __init__(self): self.ffi = FFI() dir_path = os.path.dirname(os.path.realpath(__file__)) with open(os.path.join(dir_path, "sgx.h")) as stream: self.ffi.cdef(stream.read()) self.ffi.set_source( "_sgx_interface", """ #include "sgx_eid.h" #include "sgx_key_exchange.h" #include "common.h" #include "network_ra.h" #include "barbie_server.h" #include "barbie_client.h" #include "ra_client.h" #include "ra_server.h" #include <stdbool.h> #include "service_provider.h" """, include_dirs=['/usr/include', '/opt/intel/sgxsdk/include'], library_dirs=['/usr/local/lib', '/opt/intel/sgxsdk/lib64/'], libraries=["sample_libcrypto", "BarbiE_Client", "BarbiE_Server"]) self.ffi.compile(tmpdir=dir_path) libuae = self.ffi.dlopen("sgx_uae_service", self.ffi.RTLD_GLOBAL) liburts = self.ffi.dlopen("sgx_urts", self.ffi.RTLD_GLOBAL) libcrypto = self.ffi.dlopen("sample_libcrypto", self.ffi.RTLD_GLOBAL) self.barbie_s = self.ffi.dlopen("BarbiE_Server", self.ffi.RTLD_LAZY) self.barbie_c = self.ffi.dlopen("BarbiE_Client", self.ffi.RTLD_LAZY) self.iv = 12 self.mac = 16 def init_env_variables(self): separator = "=" with open("/opt/BarbiE/env.properties") as f: for line in f: if separator in line: name, value = line.split(separator) os.environ[name.strip()] = value.strip() def init_enclave(self, target_lib): try: p_enclave_id = self.ffi.new("sgx_enclave_id_t *") status = target_lib.initialize_enclave(p_enclave_id) return p_enclave_id[0] except Exception as e: raise Exception("Error in initializing enclave!", e) def generate_key_pair(self, key_dir): pub_key_path = os.path.join(key_dir, "public_key.pem") priv_key_path = os.path.join(key_dir, "private_key.pem") if not os.path.exists(pub_key_path) and not os.path.exists( priv_key_path): priv_key = SigningKey.generate(curve=NIST256p) pub_key = priv_key.get_verifying_key() open(priv_key_path, "w").write(priv_key.to_pem()) open(pub_key_path, "w").write(pub_key.to_pem()) else: priv_key = SigningKey.from_pem(open(priv_key_path).read()) pub_key = VerifyingKey.from_pem(open(pub_key_path).read()) pk64 = pub_key.to_string() pk_x, pk_y = pk64[:len(pk64) / 2], pk64[len(pk64) / 2:] hex_priv_key = priv_key.to_string() hex_sk = hex_priv_key.encode('hex') pk_x = pk_x.encode('hex') pk_y = pk_y.encode('hex') hex_priv_key_out = [hex_sk[i:i + 2] for i in range(0, len(hex_sk), 2)] pk_x_out = [pk_x[i:i + 2] for i in range(0, len(pk_x), 2)] pk_y_out = [pk_y[i:i + 2] for i in range(0, len(pk_y), 2)] pk_x_out.reverse() pk_y_out.reverse() pub_key = "" for i in range(len(pk_x_out)): pub_key = pub_key + pk_x_out[i] for i in range(len(pk_y_out)): pub_key = pub_key + pk_y_out[i] hex_priv_key_out.reverse() priv_key = "" for i in range(len(hex_priv_key_out)): priv_key = priv_key + hex_priv_key_out[i] pub_key = base64.b64encode(pub_key + '\0') priv_key = base64.b64encode(priv_key + '\0') return pub_key, priv_key def get_crt(self, resp_crt=None): pattern = '-----END CERTIFICATE-----\n' crt = resp_crt.split(pattern) return crt[0] + pattern, crt[1] + pattern def verify_certificate(self, crt=None, cacrt=None): try: cert = load_certificate(FILETYPE_PEM, crt) intermediate_cert = load_certificate(FILETYPE_PEM, cacrt) validation_cert = load_certificate(FILETYPE_PEM, cacrt) store = X509Store() store.add_cert(intermediate_cert) store.add_cert(cert) store_ctx = X509StoreContext(store, validation_cert) if (store_ctx.verify_certificate() == None): print "Certificate verification Passed on Client side" return True else: raise Exception( "Certificate Verification Failed on Client side") except Exception as e: raise Exception("Certificate Validation Failed on Client side", e) def verify_signature(self, crt=None, sign=None, resp_body=None): try: x509 = load_certificate(FILETYPE_PEM, crt) pub_key = x509.get_pubkey() ias_public_key = dump_publickey(FILETYPE_PEM, pub_key) public_key = load_publickey(FILETYPE_PEM, ias_public_key) x509 = X509() x509.set_pubkey(public_key) if verify(x509, base64.b64decode(sign), resp_body, 'sha256') == None: print "Signature verification Passed on Client side" return True except Exception as e: raise Exception("Signature verification Failed on Client side", e) def gen_msg0(self, target_lib, spid=None): try: p_ctxt = self.ffi.new("sgx_ra_context_t *") p_req0 = self.ffi.new("ra_samp_msg0_request_header_t **") ret = target_lib.gen_msg0(p_req0, spid) msg0 = base64.b64encode(self.ffi.buffer(p_req0[0])) return ret, msg0 except Exception as e: raise Exception("Error in generating msg0", e) def proc_msg0(self, target_lib, msg0, spid=None, client_verify_ias=False): try: if spid is None: spid = self.ffi.NULL msg0 = self.ffi.from_buffer(base64.b64decode(msg0)) p_net_ctxt = self.ffi.new("void **") ret = target_lib.proc_msg0(msg0, p_net_ctxt, spid, client_verify_ias) return ret, p_net_ctxt except Exception as e: raise Exception("Error in processing msg0", e) def gen_msg1(self, target_lib, enclave_id, pub_key): try: if pub_key != None: pub_key = base64.b64decode(pub_key) key = self.ffi.new("char[]", pub_key) else: key = self.ffi.NULL p_ctxt = self.ffi.new("sgx_ra_context_t *") p_req1 = self.ffi.new("ra_samp_msg1_request_header_t **") target_lib.gen_msg1(enclave_id, p_ctxt, p_req1, key) msg1 = base64.b64encode(self.ffi.buffer(p_req1[0])) return p_ctxt[0], msg1 except Exception as e: raise Exception("Error in generating msg1", e) def proc_msg1_gen_msg2(self, target_lib, msg1, p_net_ctxt, priv_key): try: if priv_key != None: priv_key = base64.b64decode(priv_key) key = self.ffi.new("char[]", priv_key) else: key = self.ffi.NULL msg1 = self.ffi.from_buffer(base64.b64decode(msg1)) pp_resp1 = self.ffi.new("ra_samp_msg1_response_header_t **") target_lib.proc_msg1(msg1, p_net_ctxt, pp_resp1, key) msg2 = base64.b64encode(self.ffi.buffer(pp_resp1[0])) return msg2 except Exception as e: raise Exception("Error in generating msg2", e) def proc_msg2_gen_msg3(self, target_lib, enclave_id, msg2, p_ctxt, ias_crt=None, client_verify_ias=False, server_verify_ias=False): try: if ias_crt is None: ias_crt = self.ffi.NULL msg2 = self.ffi.from_buffer(base64.b64decode(msg2)) pp_req2 = self.ffi.new("ra_samp_msg3_request_header_t **") resp_crt = self.ffi.new("uint8_t[]", 4000) resp_sign = self.ffi.new("uint8_t[]", 500) resp_body = self.ffi.new("uint8_t[]", 1200) if not server_verify_ias and not client_verify_ias: server_verify_ias = True status = target_lib.gen_msg3(enclave_id, p_ctxt, msg2, pp_req2, ias_crt, client_verify_ias, server_verify_ias, resp_crt, resp_sign, resp_body) if status != 3: msg3 = base64.b64encode(self.ffi.buffer(pp_req2[0])) else: raise Exception("IAS verification failed") return (msg3, self.ffi.string(resp_crt), self.ffi.string(resp_sign), self.ffi.string(resp_body)) except Exception as e: raise Exception("Error in generating msg3", e) def proc_msg3_gen_msg4(self, target_lib, enclave_id, s_msg3, p_net_ctxt, sealed_sk, c_msg3, project_id=None, owner_mr_e=None, ias_crt=None, client_verify_ias=False): try: if ias_crt is None: ias_crt = self.ffi.NULL if owner_mr_e is None: owner_mr_e = self.ffi.NULL else: owner_mr_e = self.ffi.from_buffer(base64.b64decode(owner_mr_e)) s_msg3 = self.ffi.from_buffer(base64.b64decode(s_msg3)) c_msg3 = self.ffi.from_buffer(base64.b64decode(c_msg3)) if sealed_sk is None: sealed_len = 0 sealed_sk = self.ffi.NULL else: sealed_len = sealed_sk.length sealed_sk = self.ffi.from_buffer( base64.b64decode(sealed_sk.value)) if project_id is None: project_id_len = 0 project_id = self.ffi.NULL else: project_id_len = len(project_id) pp_resp2 = self.ffi.new("ra_samp_msg3_response_header_t **") target_lib.set_enclave(p_net_ctxt, enclave_id) target_lib.set_secret(p_net_ctxt, sealed_sk, sealed_len, self.ffi.NULL, 0) status = target_lib.proc_msg3(s_msg3, p_net_ctxt, pp_resp2, c_msg3, project_id, owner_mr_e, ias_crt, client_verify_ias) #Initially using 177 length of msg4 but #after adding project id to msg4 using (209 + project id length) for msg4 if status != 3: msg4 = base64.b64encode( self.ffi.buffer(pp_resp2[0], (417 + project_id_len))) else: raise Exception("IAS call failed") return msg4 except Exception as e: raise Exception("Error in generating msg4", e) def legacy_proc_msg3_gen_msg4(self, target_lib, msg3, p_net_ctxt, project_id=None, owner_mr_e=None, ias_crt=None, client_verify_ias=False): try: if ias_crt is None: ias_crt = self.ffi.NULL if owner_mr_e is None: owner_mr_e = self.ffi.NULL else: owner_mr_e = self.ffi.from_buffer(base64.b64decode(owner_mr_e)) if project_id is None: project_id_len = 0 project_id = self.ffi.NULL else: project_id_len = len(project_id) msg3 = self.ffi.from_buffer(base64.b64decode(msg3)) pp_resp2 = self.ffi.new("ra_samp_msg3_response_header_t **") target_lib.set_secret(p_net_ctxt, self.ffi.NULL, 0, self.ffi.NULL, 0) status = target_lib.proc_msg3(msg3, p_net_ctxt, pp_resp2, self.ffi.NULL, project_id, owner_mr_e, ias_crt, client_verify_ias) #Initially using 177 length of msg4 but #after adding project id to msg4 using (209 + project id length) for msg4 if status != 3: msg4 = base64.b64encode( self.ffi.buffer(pp_resp2[0], (417 + project_id_len))) else: raise Exception("IAS call failed") return msg4 except Exception as e: raise Exception("Error in generating msg4", e) def proc_msg4(self, target_lib, enclave_id, msg4, p_ctxt, sealed_nonse): try: plain_sk_len = 16 sealed_len = target_lib.get_sealed_data_len( enclave_id, 0, plain_sk_len) sealed_nonse = self.ffi.from_buffer( base64.b64decode(sealed_nonse.value)) #Length is 0 as this will not be output variable sealed_nonse_len = 0 msg4 = self.ffi.from_buffer(base64.b64decode(msg4)) sealed_secret2 = self.ffi.new("uint8_t[]", sealed_len) status = target_lib.proc_ra(enclave_id, p_ctxt, msg4, sealed_nonse, sealed_nonse_len, sealed_secret2, sealed_len) secret2_buf = base64.b64encode(self.ffi.buffer(sealed_secret2)) target_lib.close_ra(enclave_id, p_ctxt) return status, secret2_buf except Exception as e: raise Exception( "Error in prcessing msg4 and retrieving sealed session key", e) def get_dh_key(self, target_lib, enclave_id, msg4, p_ctxt): try: msg4 = self.ffi.from_buffer(base64.b64decode(msg4)) plain_sk_len = 16 sealed_len = target_lib.get_sealed_data_len( enclave_id, 0, plain_sk_len) sealed_dh = self.ffi.new("uint8_t[]", sealed_len) status = target_lib.get_dh_key( enclave_id, p_ctxt, msg4, sealed_dh, self.ffi.cast("uint32_t", sealed_len)) dh_buf = base64.b64encode(self.ffi.buffer(sealed_dh)) #target_lib.close_ra(enclave_id, p_ctxt) return status, dh_buf except Exception as e: raise Exception("Error in get_dh_key", e) def get_project_id(self, target_lib, enclave_id, msg4, p_ctxt): try: msg4 = self.ffi.from_buffer(base64.b64decode(msg4)) proj_id_len = self.ffi.cast("uint32_t", 0) proj_id_len = target_lib.get_project_id_len( enclave_id, p_ctxt, msg4) proj_id = self.ffi.new("uint8_t[]", proj_id_len) status = target_lib.get_project_id(enclave_id, p_ctxt, msg4, proj_id) return proj_id, proj_id_len except Exception as e: raise Exception("Error in geting project id", e) def get_sk(self, target_lib, p_net_ctx, enc_sk): #todo extract iv and mac, call target_lib.get_sk and return plain sk try: b64_iv = 16 b64_mac = 24 iv = self.ffi.from_buffer(base64.b64decode(enc_sk[:b64_iv])) mac = self.ffi.from_buffer( base64.b64decode(enc_sk[b64_iv:(b64_iv + b64_mac)])) dh_sk = self.ffi.from_buffer( base64.b64decode(enc_sk[(b64_iv + b64_mac):])) plain_sk = self.ffi.new("uint8_t[]", 16) status = target_lib.get_sk(p_net_ctx, plain_sk, 16, dh_sk, iv, mac) return Secret(self.ffi.string(plain_sk, 16), 16) except Exception as e: raise Exception("Error in get_sk", e) def generate_key(self, target_lib, enclave_id, key_len): try: sealed_len = target_lib.get_sealed_data_len(enclave_id, 0, key_len) sealed_key = self.ffi.new("uint8_t[]", sealed_len) target_lib.crypto_generate_key(enclave_id, key_len, sealed_key, sealed_len) #use these api's to determine required plain text buffer given a sealed buffer #add mac always 0 for now #add_mac_len = target_lib.get_add_mac_len(enclave_id, sealed_key, sealed_len) #plain_len = target_lib.get_encrypted_len(enclave_id, sealed_key, sealed_len) return Secret(base64.b64encode(self.ffi.buffer(sealed_key)), sealed_len) except Exception as e: raise Exception("Error in generating key", e) def provision_kek(self, target_lib, enclave_id, sealed_sk, sk_kek, project_id=None): try: if project_id is None: project_id = self.ffi.NULL proj_id_len = 0 else: proj_id_len = len(project_id) b64_iv = 16 b64_mac = 24 sealed_len = sealed_sk.length sealed_sk = self.ffi.from_buffer(base64.b64decode(sealed_sk.value)) iv = self.ffi.from_buffer(base64.b64decode(sk_kek[:b64_iv])) mac = self.ffi.from_buffer( base64.b64decode(sk_kek[b64_iv:(b64_iv + b64_mac)])) sk_kek = self.ffi.from_buffer( base64.b64decode(sk_kek[(b64_iv + b64_mac):])) plain_kek_len = len(sk_kek) sealed_kek_len = target_lib.get_sealed_data_len( enclave_id, 0, plain_kek_len) sealed_kek = self.ffi.new("uint8_t[]", sealed_kek_len) target_lib.crypto_provision_kek(enclave_id, sealed_sk, sealed_len, sk_kek, plain_kek_len, iv, mac, sealed_kek, sealed_kek_len, project_id, proj_id_len) return base64.b64encode(self.ffi.buffer(sealed_kek)) except Exception as e: raise Exception("Error in provisioning of kek", e) def legacy_encrypt(self, target_lib, plain_sk, secret): try: iv = self.ffi.new("uint8_t[]", self.iv) mac = self.ffi.new("uint8_t[]", self.mac) enc_secret = self.ffi.new("uint8_t[]", secret.length) target_lib.crypto_legacy_encrypt(plain_sk.value, plain_sk.length, secret.value, secret.length, enc_secret, iv, mac) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode( self.ffi.buffer(mac)) + base64.b64encode( self.ffi.buffer(enc_secret)) except Exception as e: raise Exception("ERROR: Encryption of the secret failed!", e) def legacy_decrypt(self, plain_sk, enc_secret): try: b64_iv = 16 b64_mac = 24 iv = base64.b64decode(enc_secret[:b64_iv]) mac = base64.b64decode(enc_secret[b64_iv:(b64_iv + b64_mac)]) enc_secret = base64.b64decode(enc_secret[(b64_iv + b64_mac):]) cipher = AES.new(plain_sk, AES.MODE_GCM, iv) dec_secret = cipher.decrypt(enc_secret) #cipher.verify(mac) return base64.b64encode(dec_secret) except Exception as e: raise Exception("ERROR: Legacy Decryption of the secret failed!", e) def encrypt(self, target_lib, enclave_id, sealed_sk, secret): try: iv = self.ffi.new("uint8_t[]", self.iv) mac = self.ffi.new("uint8_t[]", self.mac) sealed_len = sealed_sk.length sealed_sk = self.ffi.from_buffer(base64.b64decode(sealed_sk.value)) enc_secret = self.ffi.new("uint8_t[]", secret.length) target_lib.crypto_encrypt(enclave_id, sealed_sk, sealed_len, secret.value, secret.length, enc_secret, iv, mac) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode( self.ffi.buffer(mac)) + base64.b64encode( self.ffi.buffer(enc_secret)) except Exception as e: raise Exception("ERROR: Encryption of the secret failed!", e) def decrypt(self, target_lib, enclave_id, sealed_sk, enc_secret): try: b64_iv = 16 b64_mac = 24 iv = self.ffi.from_buffer(base64.b64decode(enc_secret[:b64_iv])) mac = self.ffi.from_buffer( base64.b64decode(enc_secret[b64_iv:(b64_iv + b64_mac)])) enc_secret = self.ffi.from_buffer( base64.b64decode(enc_secret[(b64_iv + b64_mac):])) length = len(enc_secret) sealed_len = sealed_sk.length sealed_sk = self.ffi.from_buffer(base64.b64decode(sealed_sk.value)) secret = self.ffi.new("uint8_t[]", length) target_lib.crypto_decrypt(enclave_id, sealed_sk, sealed_len, secret, length, enc_secret, iv, mac, self.ffi.NULL, 0) return base64.b64encode(self.ffi.buffer(secret)) except Exception as e: raise Exception("ERROR: Decryption of the secret failed!", e) def transport(self, target_lib, enclave_id, sealed_kek, sealed_sk, project_id=None): try: if project_id is None: project_id = self.ffi.NULL proj_id_len = 0 else: proj_id_len = len(project_id) iv = self.ffi.new("uint8_t[]", self.iv) mac = self.ffi.new("uint8_t[]", self.mac) sealed_kek_len = sealed_kek.length sealed_kek = self.ffi.from_buffer( base64.b64decode(sealed_kek.value)) sealed_sk_len = sealed_sk.length sealed_sk = self.ffi.from_buffer(base64.b64decode(sealed_sk.value)) sk_len = target_lib.get_encrypted_len(enclave_id, sealed_sk, sealed_sk_len) kek_sk = self.ffi.new("uint8_t[]", sk_len) target_lib.crypto_transport_secret(enclave_id, sealed_kek, sealed_kek_len, sealed_sk, sealed_sk_len, kek_sk, sk_len, iv, mac, project_id, proj_id_len) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode( self.ffi.buffer(mac)) + base64.b64encode( self.ffi.buffer(kek_sk)) except Exception as e: raise Exception("Error in transporting the secret", e) #no need for target lib, server action only def kek_encrypt(self, enclave_id, kek_sk, sealed_kek, sk_secret, project_id=None): try: if project_id is None: project_id = self.ffi.NULL proj_id_len = 0 else: proj_id_len = len(project_id) b64_iv = 16 b64_mac = 24 iv1 = self.ffi.from_buffer(base64.b64decode(kek_sk[:b64_iv])) mac1 = self.ffi.from_buffer( base64.b64decode(kek_sk[b64_iv:(b64_iv + b64_mac)])) kek_sk = self.ffi.from_buffer( base64.b64decode(kek_sk[(b64_iv + b64_mac):])) sealed_kek_len = sealed_kek.length sealed_kek = self.ffi.from_buffer( base64.b64decode(sealed_kek.value)) iv = self.ffi.from_buffer(base64.b64decode(sk_secret[:b64_iv])) mac = self.ffi.from_buffer( base64.b64decode(sk_secret[b64_iv:(b64_iv + b64_mac)])) sk_secret = self.ffi.from_buffer( base64.b64decode(sk_secret[(b64_iv + b64_mac):])) length = len(sk_secret) kek_secret = self.ffi.new("uint8_t[]", length) self.barbie_s.crypto_store_secret(enclave_id, kek_sk, len(kek_sk), iv1, mac1, sealed_kek, sealed_kek_len, sk_secret, length, kek_secret, length, iv, mac, str(project_id), proj_id_len) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode( self.ffi.buffer(mac)) + base64.b64encode( self.ffi.buffer(kek_secret)) except Exception as e: raise Exception("Error in encrypting the secret with kek", e) #no need for target lib, server action only def kek_decrypt(self, enclave_id, kek_sk, sealed_kek, kek_secret, project_id=None): try: if project_id is None: project_id = self.ffi.NULL proj_id_len = 0 else: proj_id_len = len(project_id) b64_iv = 16 b64_mac = 24 iv1 = self.ffi.from_buffer(base64.b64decode(kek_sk[:b64_iv])) mac1 = self.ffi.from_buffer( base64.b64decode(kek_sk[b64_iv:(b64_iv + b64_mac)])) kek_sk = self.ffi.from_buffer( base64.b64decode(kek_sk[(b64_iv + b64_mac):])) sealed_kek_len = sealed_kek.length sealed_kek = self.ffi.from_buffer( base64.b64decode(sealed_kek.value)) iv = self.ffi.from_buffer(base64.b64decode(kek_secret[:b64_iv])) mac = self.ffi.from_buffer( base64.b64decode(kek_secret[b64_iv:(b64_iv + b64_mac)])) kek_secret = self.ffi.from_buffer( base64.b64decode(kek_secret[(b64_iv + b64_mac):])) length = len(kek_secret) sk_secret = self.ffi.new("uint8_t[]", length) self.barbie_s.crypto_get_secret(enclave_id, kek_sk, len(kek_sk), iv1, mac1, sealed_kek, sealed_kek_len, kek_secret, length, sk_secret, length, iv, mac, str(project_id), proj_id_len) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode( self.ffi.buffer(mac)) + base64.b64encode( self.ffi.buffer(sk_secret)) except Exception as e: raise Exception("Error in decrypting the secret with kek", e) def compare_secret(self, target_lib, secret1, secret2, secret_len): try: secret1 = self.ffi.from_buffer(base64.b64decode(secret1)) secret2 = self.ffi.from_buffer(base64.b64decode(secret2)) if target_lib.crypto_cmp(secret1, secret2, secret_len) == 0: return True return False except Exception as e: raise Exception("Error in comparing the secrets", e) def compare_sealed_secret(self, target_lib, encalve_id, secret1, secret2): try: secret1 = self.ffi.from_buffer(base64.b64decode(secret1)) secret2 = self.ffi.from_buffer(base64.b64decode(secret2)) if target_lib.crypto_sealed_cmp(encalve_id, secret1, len(secret1), secret2, len(secret2)) == 0: return True return False except Exception as e: raise Exception("Error in comparing the sealed secrets", e) def compare_sealed_secret(self, target_lib, enclave_id, secret1, secret2): try: secret1 = self.ffi.from_buffer(base64.b64decode(secret1)) secret2 = self.ffi.from_buffer(base64.b64decode(secret2)) if target_lib.crypto_sealed_cmp(enclave_id, secret1, len(secret1), secret2, len(secret2)) == 0: return True return False except Exception as e: raise Exception("Error in comparing the sealed secrets", e) def destroy_enclave(self, target_lib, enclave_id): try: target_lib.destroy_enclave(enclave_id) except Exception as e: raise Exception("Error in destroying enclave!", e) def write_buffer_to_file(self, filename, buff): try: dir_path = os.path.dirname(os.path.realpath(__file__)) write_file = os.path.join(dir_path, filename) with open(write_file, 'w') as f: f.write(buff) except Exception as e: raise Exception("Error writing buffer to file!", e) def read_buffer_from_file(self, filename): try: dir_path = os.path.dirname(os.path.realpath(__file__)) read_file = os.path.join(dir_path, filename) if os.path.exists(os.path.join(dir_path, read_file)): with open(read_file, 'r') as f: read_buffer = f.read() return read_buffer except Exception as e: raise Exception("Error reading buffer from file!", e) def get_mr_enclave(self, msg3): try: msg3 = self.ffi.from_buffer(base64.b64decode(msg3)) mr_e = self.barbie_s.get_mr_e(msg3) #return self.ffi.string(mr_e) #return self.ffi.buffer(mr_e) return base64.b64encode(self.ffi.buffer(mr_e, 32)) except Exception as e: raise Exception("Error in retrieveing mr enclave", e) def get_mr_signer(self, msg3): try: msg3 = self.ffi.from_buffer(base64.b64decode(msg3)) mr_s = self.barbie_s.get_mr_s(msg3) #return self.ffi.string(mr_s) #return self.ffi.buffer(mr_s) return base64.b64encode(self.ffi.buffer(mr_s, 32)) except Exception as e: raise Exception("Error in retrieveing mr signer", e) def get_report_sha256(self, target_lib, msg3): try: msg3 = self.ffi.from_buffer(base64.b64decode(msg3)) sha256 = self.ffi.new("uint8_t []", 32) target_lib.get_report_sha256(msg3, sha256) return base64.b64encode(self.ffi.buffer(sha256)) except Exception as e: raise Exception("Error getting SHA256", e) def test_legacy_client(self): try: #plain_secret = "my-private-secre" secret = "This-Is-My-Private-Secret" plain_secret = Secret(secret, len(secret)) enclave_id = self.init_enclave(self.barbie_s) #To simulate KEK of server side sealed_kek = self.generate_key(self.barbie_s, enclave_id, 16) enc_secret = self.encrypt(self.barbie_s, enclave_id, sealed_kek, plain_secret) r_secret = self.decrypt(self.barbie_s, enclave_id, sealed_kek, enc_secret) r_secret = base64.b64decode(r_secret) if r_secret == secret: print "Legacy Client : Secret Management done!" else: print "Legacy Client : Secret Management failed!" finally: self.destroy_enclave(self.barbie_s, enclave_id) def test_sgx_client_wo_sgx_hw(self, spid=None, crt_path=None, kdir=None): try: pub_key, priv_key = self.generate_key_pair(kdir) s_eid = self.init_enclave(self.barbie_s) plain_sk = Secret("", len("")) #Perform attestation ret, msg0 = self.gen_msg0(self.barbie_s, spid) p_ctxt, msg1 = self.gen_msg1(self.barbie_s, s_eid, pub_key) print "gen_msg1 returned: " + msg1 ret, p_net_ctxt = self.proc_msg0(self.barbie_c, msg0, spid, False) msg2 = self.proc_msg1_gen_msg2(self.barbie_c, msg1, p_net_ctxt, priv_key) print "send_msg1_recv_msg2 returned: " + msg2 msg3, crt, sig, resp_body = self.proc_msg2_gen_msg3( self.barbie_s, s_eid, msg2, p_ctxt, crt_path, False) print "proc_msg2_gen_msg3 returned: " + msg3 msg4 = self.legacy_proc_msg3_gen_msg4(self.barbie_c, msg3, p_net_ctxt, "sgx_wo_hw", None, crt_path, False) print "send_msg3_recv_msg4 returned: " + str(msg4) status, s_dh = self.get_dh_key(self.barbie_s, s_eid, msg4, p_ctxt) print "get_dh_key returned: " + str(status) proj_id, proj_id_size = self.get_project_id( self.barbie_s, s_eid, msg4, p_ctxt) s_sk = self.generate_key(self.barbie_s, s_eid, 16) plain_kek_len = 16 sealed_len = self.barbie_s.get_sealed_data_len( s_eid, 0, plain_kek_len) dh_sk = self.transport(self.barbie_s, s_eid, Secret(s_dh, sealed_len), s_sk, None) plain_sk = self.get_sk(self.barbie_c, p_net_ctxt, dh_sk) #status, plain_sk = self.get_sk(self.barbie_c, p_net_ctxt, 16, dh_sk) #status, sk = self.proc_msg4(self.barbie_s, s_eid, msg4, p_ctxt) #sealed_sk = Secret(sk, sealed_len) #Perform kek provisioning kek = "yek etyb neetxis" plain_kek = Secret(kek, len(kek)) sk_kek = self.legacy_encrypt(self.barbie_c, plain_sk, plain_kek) kek = self.provision_kek(self.barbie_s, s_eid, s_sk, sk_kek, None) plain_kek_len = 16 sealed_len = self.barbie_s.get_sealed_data_len( s_eid, 0, plain_kek_len) sealed_kek = Secret(kek, sealed_len) kek_sk = self.transport(self.barbie_c, s_eid, sealed_kek, s_sk, proj_id) #Perform secret management secret = "my-private-secret" plain_secret = Secret(secret, len(secret)) sk_secret = self.legacy_encrypt(self.barbie_c, plain_sk, plain_secret) kek_secret = self.kek_encrypt(s_eid, kek_sk, sealed_kek, sk_secret, "sgx_wo_hw") rec = self.kek_decrypt(s_eid, kek_sk, sealed_kek, kek_secret, "sgx_wo_hw") if self.compare_secret(self.barbie_c, rec[40:], sk_secret[40:], plain_secret.length): print "SGX Aware Client Without SGX hardware : Secret Management done!" else: print "SGX Aware Cliwnt Without SGX hardware : Secret Management failed!" finally: self.destroy_enclave(self.barbie_s, s_eid)
if status < 0: errno = lib.trb_errno errorstr = ffi.string(lib.trb_errorstr(errno)).decode('ascii') raise NameError('Error initialising ports.', errno, errorstr) # --- Setting up the buffer given to library function calls bufsize = 1024 # 32-bit words # the buffer can be a numpy.array(): #import numpy as np #buf = np.array([0]*bufsize, dtype=np.uint32) # or a Python stdlib array.array(): import array buf = array.array('I', [0]*bufsize) assert buf.itemsize == 4 # otherwise try buf = array.array('L', [0]*bufsize) # --- Casting the buffer to the right type required by the C library buf_ffi = ffi.cast('uint32_t *', ffi.from_buffer(buf)) # --- Call the trb_register_read() function to query the broadcast address for register 0x0 status = lib.trb_register_read(0xffff, 0x0, buf_ffi, bufsize) if status == -1: errno = lib.trb_errno errorstr = ffi.string(lib.trb_errorstr(errno)).decode('ascii') raise NameError('Error reading register', errno, errorstr) # --- Read the response from the buffer response_words = [(buf[i]) for i in range(status)] for i in range(0, status, 2): print('TrbAddress', hex(response_words[i]), 'responded with:', hex(response_words[i+1]))
class KaldiAgfNNet3Decoder(KaldiDecoderBase): """docstring for KaldiAgfNNet3Decoder""" def __init__(self, model_dir, tmp_dir, words_file=None, word_align_lexicon_file=None, mfcc_conf_file=None, ie_conf_file=None, model_file=None, top_fst_file=None, dictation_fst_file=None, save_adaptation_state=True): super(KaldiAgfNNet3Decoder, self).__init__() self._ffi = FFI() self._ffi.cdef(""" void* init_agf_nnet3(float beam, int32_t max_active, int32_t min_active, float lattice_beam, float acoustic_scale, int32_t frame_subsampling_factor, int32_t nonterm_phones_offset, char* word_syms_filename_cp, char* word_align_lexicon_filename_cp, char* mfcc_config_filename_cp, char* ie_config_filename_cp, char* model_filename_cp, char* top_fst_filename_cp, char* dictation_fst_filename_cp); bool add_grammar_fst_agf_nnet3(void* model_vp, char* grammar_fst_filename_cp); bool decode_agf_nnet3(void* model_vp, float samp_freq, int32_t num_frames, float* frames, bool finalize, bool* grammars_activity_cp, int32_t grammars_activity_cp_size, bool save_adaptation_state); bool get_output_agf_nnet3(void* model_vp, char* output, int32_t output_max_length, double* likelihood_p); bool get_word_align_agf_nnet3(void* model_vp, int32_t* times_cp, int32_t* lengths_cp, int32_t num_words); void reset_adaptation_state_agf_nnet3(void* model_vp); """) self._lib = self._ffi.dlopen(self._library_binary) if words_file is None: words_file = find_file(model_dir, 'words.txt') if word_align_lexicon_file is None: word_align_lexicon_file = find_file(model_dir, 'align_lexicon.int') if mfcc_conf_file is None: mfcc_conf_file = find_file(model_dir, 'mfcc_hires.conf') if mfcc_conf_file is None: mfcc_conf_file = find_file(model_dir, 'mfcc.conf') # warning? if ie_conf_file is None: ie_conf_file = self._convert_ie_conf_file( model_dir, find_file(model_dir, 'ivector_extractor.conf'), os.path.join(tmp_dir, 'ivector_extractor.conf')) if model_file is None: model_file = find_file(model_dir, 'final.mdl') nonterm_phones_offset = symbol_table_lookup( find_file(model_dir, 'phones.txt'), '#nonterm_bos') if nonterm_phones_offset is None: raise KaldiError("cannot find #nonterm_bos symbol in phones.txt") self.words_file = os.path.normpath(words_file) self.word_align_lexicon_file = os.path.normpath( word_align_lexicon_file ) if word_align_lexicon_file is not None else None self.mfcc_conf_file = os.path.normpath(mfcc_conf_file) self.ie_conf_file = os.path.normpath(ie_conf_file) self.model_file = os.path.normpath(model_file) self.top_fst_file = os.path.normpath(top_fst_file) self._model = self._lib.init_agf_nnet3( 14.0, 7000, 200, 8.0, 1.0, 3, # chain: 7.0, 7000, 200, 8.0, 1.0, 3, nonterm_phones_offset, words_file, word_align_lexicon_file or "", mfcc_conf_file, ie_conf_file, model_file, top_fst_file, dictation_fst_file or "") self.num_grammars = 0 self._saving_adaptation_state = save_adaptation_state self.sample_rate = 16000 self.num_channels = 1 self.bytes_per_kaldi_frame = self.kaldi_frame_num_to_audio_bytes(1) saving_adaptation_state = property( lambda self: self._saving_adaptation_state, doc= "Whether currently to save updated adaptation state at end of utterance" ) @saving_adaptation_state.setter def saving_adaptation_state(self, value): self._saving_adaptation_state = value def _convert_ie_conf_file(self, model_dir, old_filename, new_filename, search=True): """ Rewrite ivector_extractor.conf file, converting relative paths to absolute paths for current configuration. """ options_with_path = { '--splice-config': 'conf/splice.conf', '--cmvn-config': 'conf/online_cmvn.conf', '--lda-matrix': 'ivector_extractor/final.mat', '--global-cmvn-stats': 'ivector_extractor/global_cmvn.stats', '--diag-ubm': 'ivector_extractor/final.dubm', '--ivector-extractor': 'ivector_extractor/final.ie', } with open(old_filename, 'r') as old_file, open(new_filename, 'wb') as new_file: for line in old_file: key, value = line.strip().split('=', 1) if key in options_with_path: if not search: value = os.path.join(model_dir, options_with_path[key]) else: value = find_file( model_dir, os.path.basename(options_with_path[key])) new_file.write("%s=%s\n" % (key, value)) return new_filename def add_grammar_fst(self, grammar_fst_file): grammar_fst_file = os.path.normpath(grammar_fst_file) _log.debug("%s: adding grammar_fst_file: %s", self, grammar_fst_file) result = self._lib.add_grammar_fst_agf_nnet3(self._model, grammar_fst_file) if not result: raise KaldiError("error adding grammar") self.num_grammars += 1 def decode(self, frames, finalize, grammars_activity=None): """Continue decoding with given new audio data.""" # grammars_activity = [True] * self.num_grammars # grammars_activity = np.random.choice([True, False], len(grammars_activity)).tolist(); print grammars_activity; time.sleep(5) if grammars_activity is None: grammars_activity = [] else: _log.debug("decode: grammars_activity = %s", ''.join('1' if a else '0' for a in grammars_activity)) # if len(grammars_activity) != self.num_grammars: # raise KaldiError("wrong len(grammars_activity)") if not isinstance(frames, np.ndarray): frames = np.frombuffer(frames, np.int16) frames = frames.astype(np.float32) frames_char = self._ffi.from_buffer(frames) frames_float = self._ffi.cast('float *', frames_char) self._start_decode_time(len(frames)) result = self._lib.decode_agf_nnet3(self._model, self.sample_rate, len(frames), frames_float, finalize, grammars_activity, len(grammars_activity), self._saving_adaptation_state) self._stop_decode_time(finalize) if not result: raise KaldiError("decoding error") return finalize def get_output(self, output_max_length=4 * 1024): output_p = self._ffi.new('char[]', output_max_length) likelihood_p = self._ffi.new('double *') result = self._lib.get_output_agf_nnet3(self._model, output_p, output_max_length, likelihood_p) if not result: raise KaldiError("get_output error") output_str = self._ffi.string(output_p) likelihood = likelihood_p[0] # _log.debug("get_output: likelihood %f, %r", likelihood, output_str) return output_str, likelihood def get_word_align(self, output): words = output.split() num_words = len(words) kaldi_frame_times_p = self._ffi.new('int32_t[]', num_words) kaldi_frame_lengths_p = self._ffi.new('int32_t[]', num_words) result = self._lib.get_word_align_agf_nnet3(self._model, kaldi_frame_times_p, kaldi_frame_lengths_p, num_words) if not result: raise KaldiError("get_word_align error") times = [ kaldi_frame_num * self.bytes_per_kaldi_frame for kaldi_frame_num in kaldi_frame_times_p ] lengths = [ kaldi_frame_num * self.bytes_per_kaldi_frame for kaldi_frame_num in kaldi_frame_lengths_p ] return zip(words, times, lengths) def reset_adaptation_state(self): self._lib.reset_adaptation_state_agf_nnet3(self._model) def kaldi_frame_num_to_audio_bytes(self, kaldi_frame_num): kaldi_frame_length_ms = 30 sample_size_bytes = 2 * self.num_channels return kaldi_frame_num * kaldi_frame_length_ms * self.sample_rate / 1000 * sample_size_bytes def audio_bytes_to_s(self, audio_bytes): sample_size_bytes = 2 * self.num_channels return 1.0 * audio_bytes / sample_size_bytes / self.sample_rate
maxSize=max_eye) if len(eyes) != 0: l = max_area_eye(eyes) if l[2] > 0: leftEyeLost = False left_pup_x = l[0] left_pup_y = l[1] ###____________________STARTING MAIN COMPUTATIONAL CHAIN FOR FIRST FRAME____________________ #roi copy of the rigth eye roiRightEye = frame1[int(right_pup_y):int(right_pup_y + W), int(right_pup_x):int(right_pup_x + W)].copy() #pointer to image (roi) pointerToRoiRightEye = ffi.cast("uint8_t *", ffi.from_buffer(roiRightEye)) #transfer image data to buffer ffi.memmove(pointIn + 1, pointerToRoiRightEye, W * W * CH) #DMA tranfer dmaOut.transfer(W * W, 1) dmaIn.transfer(W * W * CH, 0) #roi copy of left eye roiLeftEye = frame1[int(left_pup_y):int(left_pup_y + W), int(left_pup_x):int(left_pup_x + W)].copy() #pointer to image (roi) pointerToRoiLeftEye = ffi.cast("uint8_t *", ffi.from_buffer(roiLeftEye)) #transfer image data to buffer ffi.memmove(pointIn + 1, pointerToRoiLeftEye, W * W * CH)
class LibWwqParseCFFI(LibWwqLyParseBase): def __init__(self): super(LibWwqParseCFFI, self).__init__() from cffi import FFI self.ffi = FFI() self.lib = self.ffi.dlopen(self.lib_path) self.ffi.cdef(""" char * get_uuid(); char * get_name(); int parse(char * c,int length,char **result,int *result_length); int free_str(char * c); void* atomic_int64_init(); int atomic_int64_destroy(void* ptr); int64_t atomic_int64_get(void* ptr); int64_t atomic_int64_set(void* ptr, int64_t val); int64_t atomic_int64_add(void* ptr, int64_t val); int64_t atomic_int64_sub(void* ptr, int64_t val); int64_t atomic_int64_and(void* ptr, int64_t val); int64_t atomic_int64_or(void* ptr, int64_t val); int64_t atomic_int64_xor(void* ptr, int64_t val); typedef union epoll_data { void* ptr; int fd; uint32_t u32; uint64_t u64; uintptr_t sock; /* Windows specific */ void* hnd; /* Windows specific */ } epoll_data_t; typedef struct { uint32_t events; /* Epoll events and flags */ epoll_data_t data; /* User data variable */ } epoll_event ; void* epoll_create(int size); void* epoll_create1(int flags); int epoll_close(void* ephnd); int epoll_ctl(void* ephnd, int op, uintptr_t sock, epoll_event* event); int epoll_wait(void* ephnd, epoll_event* events, int maxevents, int timeout); """) self.lib.__class__.__repr__ = lambda s: "<%s object at 0x%016X>" % (s.__class__.__name__, id(s)) logging.debug("successful load lib %s" % self.lib) weakref.finalize(self, lambda: logging.debug("%s released" % self.lib) if self.ffi.dlclose(self.lib) or 1 else None) def get_uuid(self) -> bytes: return self.ffi.string(self.lib.get_uuid()) def get_name(self) -> bytes: return self.ffi.string(self.lib.get_name()) def lib_parse(self, byte_str: bytes) -> bytes: length = self.ffi.cast("int", len(byte_str)) result_length = self.ffi.new("int *") result_p = self.ffi.new("char **") # p = self.ffi.new("char []", byte_str) p = self.ffi.from_buffer(byte_str) self.lib.parse(p, length, result_p, result_length) result = self.ffi.unpack(result_p[0], result_length[0]) self.lib.free_str(result_p[0]) return result
class cv2pynq(): MAX_WIDTH = 1920 MAX_HEIGHT = 1080 def __init__(self, load_overlay=True): self.bitstream_name = None self.bitstream_name = "cv2pynq03.bit" self.bitstream_path = os.path.join(CV2PYNQ_BIT_DIR, self.bitstream_name) self.ol = Overlay(self.bitstream_path) self.ol.download() self.ol.reset() self.xlnk = Xlnk() self.partitions = 10 #split the cma into partitions for pipelined transfer self.cmaPartitionLen = self.MAX_HEIGHT * self.MAX_WIDTH / self.partitions self.listOfcma = [ self.xlnk.cma_array(shape=(int(self.MAX_HEIGHT / self.partitions), self.MAX_WIDTH), dtype=np.uint8) for i in range(self.partitions) ] self.img_filters = self.ol.image_filters self.dmaOut = self.img_filters.axi_dma_0.sendchannel self.dmaIn = self.img_filters.axi_dma_0.recvchannel self.dmaOut.stop() self.dmaIn.stop() self.dmaIn.start() self.dmaOut.start() self.filter2DType = -1 # filter types: SobelX=0, SobelY=1, ScharrX=2, ScharrY=3, Laplacian1=4, Laplacian3=5 self.filter2D_5Type = -1 # filter types: SobelX=0, SobelY=1, Laplacian5=4 self.filter2DfType = -1 # filter types: blur=0, GaussianBlur=1 self.ffi = FFI() self.f2D = self.img_filters.filter2D_hls_0 self.f2D.reset() self.f2D_5 = self.img_filters.filter2D_hls_5_0 self.f2D_5.reset() self.f2D_f = self.img_filters.filter2D_f_0 self.f2D_f.reset() self.erodeIP = self.img_filters.erode_hls_0 self.erodeIP.reset() self.dilateIP = self.img_filters.dilate_hls_0 self.dilateIP.reset() self.cmaBuffer_0 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT, self.MAX_WIDTH), dtype=np.uint8) self.cmaBuffer0 = self.cmaBuffer_0.view(self.ContiguousArrayCv2pynq) self.cmaBuffer0.init(self.cmaBuffer_0) self.cmaBuffer_1 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT, self.MAX_WIDTH), dtype=np.uint8) self.cmaBuffer1 = self.cmaBuffer_1.view(self.ContiguousArrayCv2pynq) self.cmaBuffer1.init(self.cmaBuffer_1) self.cmaBuffer_2 = self.xlnk.cma_array( shape=(self.MAX_HEIGHT * 4, self.MAX_WIDTH), dtype=np.uint8) # *4 for CornerHarris return self.cmaBuffer2 = self.cmaBuffer_2.view(self.ContiguousArrayCv2pynq) self.cmaBuffer2.init(self.cmaBuffer_2) self.CannyIP = self.img_filters.canny_edge_0 self.CannyIP.reset() #self.cornerHarrisIP = self.img_filters.CornerHarris_hls_0 #self.cornerHarrisIP.reset() def close(self): #self.dmaOut.stop() #self.dmaIn.stop() self.cmaBuffer_0.close() self.cmaBuffer_1.close() self.cmaBuffer_2.close() for cma in self.listOfcma: cma.close() def Sobel(self, src, ddepth, dx, dy, dst, ksize): if (ksize == 3): self.f2D.rows = src.shape[0] self.f2D.columns = src.shape[1] self.f2D.channels = 1 if (dx == 1) and (dy == 0): if self.filter2DType != 0: self.filter2DType = 0 self.f2D.r1 = 0x000100ff #[-1 0 1] self.f2D.r2 = 0x000200fe #[-2 0 2] self.f2D.r3 = 0x000100ff #[-1 0 1] elif (dx == 0) and (dy == 1): if self.filter2DType != 1: self.filter2DType = 1 self.f2D.r1 = 0x00fffeff #[-1 -2 -1] self.f2D.r2 = 0x00000000 #[ 0 0 0] self.f2D.r3 = 0x00010201 #[ 1 2 1] else: raise RuntimeError("Incorrect dx dy configuration") self.img_filters.select_filter(1) self.f2D.start() return self.filter2D(src, dst) else: #ksize == 5 self.f2D_5.rows = src.shape[0] self.f2D_5.columns = src.shape[1] if (dx == 1) and (dy == 0): if self.filter2D_5Type != 0: self.filter2D_5Type = 0 self.f2D_5.par_V = bytes([ \ #-1, -2, 0, 2, 1, 0xff, 0xfe, 0x00, 0x02, 0x01, \ #-4, -8, 0, 8, 4, 0xfc, 0xf8, 0x00, 0x08, 0x04, \ #-6, -12, 0, 12, 6, 0xfa, 0xf4, 0x00, 0x0c, 0x06, \ #-4, -8, 0, 8, 4, 0xfc, 0xf8, 0x00, 0x08, 0x04, \ #-1, -2, 0, 2, 1, 0xff, 0xfe, 0x00, 0x02, 0x01, \ 0,0,0]) #fill up to allign with 4 elif (dx == 0) and (dy == 1): if self.filter2D_5Type != 1: self.filter2D_5Type = 1 self.f2D_5.par_V = bytes([ \ #-1, -4, -6, -4, -1, 0xff, 0xfc, 0xfa, 0xfc, 0xff, \ #-2, -8, -12, -8, -2, 0xfe, 0xf8, 0xf4, 0xf8, 0xfe, \ # 0, 0, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, \ # 2, 8, 12, 8, 2, 0x02, 0x08, 0x0c, 0x08, 0x02, \ # 1, 4, 6, 4, 1, 0x01, 0x04, 0x06, 0x04, 0x01, \ 0,0,0]) #fill up to allign with 4 else: raise RuntimeError("Incorrect dx dy configuration") self.img_filters.select_filter(5) self.f2D_5.start() return self.filter2D(src, dst) def Scharr(self, src, ddepth, dx, dy, dst): self.f2D.rows = src.shape[0] self.f2D.columns = src.shape[1] self.f2D.channels = 1 if (dx == 1) and (dy == 0): if self.filter2DType != 2: self.filter2DType = 2 self.f2D.r1 = 0x000300fd #[-3 0 3] self.f2D.r2 = 0x000a00f6 #[-10 0 10] self.f2D.r3 = 0x000300fd #[-3 0 3] elif (dx == 0) and (dy == 1): if self.filter2DType != 3: self.filter2DType = 3 self.f2D.r1 = 0x00fdf6fd #[-3 -10 -3] self.f2D.r2 = 0x00000000 #[ 0 0 0] self.f2D.r3 = 0x00030a03 #[ 3 10 3] else: raise RuntimeError("Incorrect dx dy configuration") self.img_filters.select_filter(1) self.f2D.start() return self.filter2D(src, dst) def Laplacian(self, src, ddepth, dst, ksize): if ksize == 5: self.f2D_5.rows = src.shape[0] self.f2D_5.columns = src.shape[1] if self.filter2D_5Type != 4: self.filter2D_5Type = 4 # "Laplacian_5" self.f2D_5.par_V = bytes([ \ #2, 4, 4, 4, 2, 0x02, 0x04, 0x04, 0x04, 0x02, \ #4, 0, -8, 0, 4, 0x04, 0x00, 0xf8, 0x00, 0x04, \ #4, -8, -24, -8, 4, 0x04, 0xf8, 0xe8, 0xf8, 0x04, \ #4, 0, -8, 0, 4, 0x04, 0x00, 0xf8, 0x00, 0x04, \ #2, 4, 4, 4, 2, 0x02, 0x04, 0x04, 0x04, 0x02, \ 0,0,0]) #fill up to allign with 4 self.img_filters.select_filter(5) self.f2D_5.start() return self.filter2D(src, dst) else: #ksize 1 or 3 self.f2D.rows = src.shape[0] self.f2D.columns = src.shape[1] self.f2D.channels = 1 if ksize == 1: if (self.filter2DType != 4): self.filter2DType = 4 # "Laplacian_1" self.f2D.r1 = 0x00000100 #[ 0 1 0] self.f2D.r2 = 0x0001fc01 #[ 1 -4 1] self.f2D.r3 = 0x00000100 #[ 0 1 0] elif ksize == 3: if (self.filter2DType != 5): self.filter2DType = 5 # "Laplacian_3" self.f2D.r1 = 0x00020002 #[ 2 0 2] self.f2D.r2 = 0x0000f800 #[ 0 -8 0] self.f2D.r3 = 0x00020002 #[ 2 0 2] self.img_filters.select_filter(1) self.f2D.start() return self.filter2D(src, dst) def blur(self, src, ksize, dst): self.f2D_f.rows = src.shape[0] self.f2D_f.columns = src.shape[1] if (self.filter2DfType != 0): self.filter2DfType = 0 #blur mean = self.floatToFixed(1 / 9, cv2pynqDriverFilter2D_f.K_FP_W, cv2pynqDriverFilter2D_f.K_FP_F) self.f2D_f.r11 = mean self.f2D_f.r12 = mean self.f2D_f.r13 = mean self.f2D_f.r21 = mean self.f2D_f.r22 = mean self.f2D_f.r23 = mean self.f2D_f.r31 = mean self.f2D_f.r32 = mean self.f2D_f.r33 = mean self.img_filters.select_filter(2) self.f2D_f.start() return self.filter2D(src, dst) def GaussianBlur(self, src, ksize, sigmaX, sigmaY, dst): self.f2D_f.rows = src.shape[0] self.f2D_f.columns = src.shape[1] if (self.filter2DfType != 1): self.filter2DfType = 1 #GaussianBlur if (sigmaX <= 0): sigmaX = 0.3 * ((ksize[0] - 1) * 0.5 - 1) + 0.8 if (sigmaY <= 0): sigmaY = sigmaX kX = cv2.getGaussianKernel(3, sigmaX, ktype=cv2.CV_32F) #kernel X kY = cv2.getGaussianKernel(3, sigmaY, ktype=cv2.CV_32F) #kernel Y self.f2D_f.r11 = self.floatToFixed(kY[0] * kX[0], cv2pynqDriverFilter2D_f.K_FP_W, cv2pynqDriverFilter2D_f.K_FP_F) self.f2D_f.r12 = self.floatToFixed(kY[0] * kX[1], cv2pynqDriverFilter2D_f.K_FP_W, cv2pynqDriverFilter2D_f.K_FP_F) self.f2D_f.r13 = self.floatToFixed(kY[0] * kX[2], cv2pynqDriverFilter2D_f.K_FP_W, cv2pynqDriverFilter2D_f.K_FP_F) self.f2D_f.r21 = self.floatToFixed(kY[1] * kX[0], cv2pynqDriverFilter2D_f.K_FP_W, cv2pynqDriverFilter2D_f.K_FP_F) self.f2D_f.r22 = self.floatToFixed(kY[1] * kX[1], cv2pynqDriverFilter2D_f.K_FP_W, cv2pynqDriverFilter2D_f.K_FP_F) self.f2D_f.r23 = self.floatToFixed(kY[1] * kX[2], cv2pynqDriverFilter2D_f.K_FP_W, cv2pynqDriverFilter2D_f.K_FP_F) self.f2D_f.r31 = self.floatToFixed(kY[2] * kX[0], cv2pynqDriverFilter2D_f.K_FP_W, cv2pynqDriverFilter2D_f.K_FP_F) self.f2D_f.r32 = self.floatToFixed(kY[2] * kX[1], cv2pynqDriverFilter2D_f.K_FP_W, cv2pynqDriverFilter2D_f.K_FP_F) self.f2D_f.r33 = self.floatToFixed(kY[2] * kX[2], cv2pynqDriverFilter2D_f.K_FP_W, cv2pynqDriverFilter2D_f.K_FP_F) self.img_filters.select_filter(2) self.f2D_f.start() return self.filter2D(src, dst) def erode(self, src, kernel, dst, iterations, mode): self.img_filters.select_filter(3) return self.erodeDilateKernel(src, kernel, dst, iterations, mode, self.erodeIP) def dilate(self, src, kernel, dst, iterations, mode): self.img_filters.select_filter(4) return self.erodeDilateKernel(src, kernel, dst, iterations, mode, self.dilateIP) def Canny(self, src, threshold1, threshold2, dst): self.img_filters.select_filter(0) self.CannyIP.rows = src.shape[0] self.CannyIP.columns = src.shape[1] self.CannyIP.threshold1 = threshold1 self.CannyIP.threshold2 = threshold2 self.CannyIP.start() if hasattr(src, 'physical_address') and hasattr( dst, 'physical_address'): self.dmaIn.transfer(dst) self.dmaOut.transfer(src) self.dmaIn.wait() return dst self.cmaBuffer1.nbytes = src.nbytes self.dmaIn.transfer(self.cmaBuffer1) if hasattr(src, 'physical_address'): self.dmaOut.transfer(src) else: self.cmaBuffer0.nbytes = src.nbytes self.copyNto(self.cmaBuffer0, src, src.nbytes) self.dmaOut.transfer(self.cmaBuffer0) self.dmaIn.wait() ret = np.ndarray(src.shape, src.dtype) self.copyNto(ret, self.cmaBuffer1, ret.nbytes) return ret def filter2D(self, src, dst): if dst is None: self.cmaBuffer1.nbytes = src.nbytes elif hasattr(src, 'physical_address') and hasattr( dst, 'physical_address'): self.dmaIn.transfer(dst) self.dmaOut.transfer(src) self.dmaIn.wait() return dst if hasattr(src, 'physical_address'): self.dmaIn.transfer(self.cmaBuffer1) self.dmaOut.transfer(src) self.dmaIn.wait() else: #pipeline the copy to contiguous memory and filter calculation in hardware if src.nbytes < 184800: #440x420 self.partitions = 1 elif src.nbytes < 180000: #600x300 self.partitions = 2 elif src.nbytes < 231200: #680x340 self.partitions = 4 else: self.partitions = 8 self.cmaBuffer1.nbytes = src.nbytes self.dmaIn.transfer(self.cmaBuffer1) chunks_len = int(src.nbytes / (self.partitions)) self.cmaBuffer0.nbytes = chunks_len self.cmaBuffer2.nbytes = chunks_len #self.copyNto(src,self.cmaBuffer0,chunks_len) self.copyNto(self.cmaBuffer0, src, chunks_len) for i in range(1, self.partitions): if i % 2 == 1: while not self.dmaOut.idle and not self.dmaOut._first_transfer: pass self.dmaOut.transfer(self.cmaBuffer0) #self.copyNtoOff(src ,self.cmaBuffer2,chunks_len, i*chunks_len, 0) self.copyNtoOff(self.cmaBuffer2, src, chunks_len, 0, i * chunks_len) else: while not self.dmaOut.idle and not self.dmaOut._first_transfer: pass self.dmaOut.transfer(self.cmaBuffer2) #self.copyNtoOff(src ,self.cmaBuffer0,chunks_len, i*chunks_len, 0) self.copyNtoOff(self.cmaBuffer0, src, chunks_len, 0, i * chunks_len) while not self.dmaOut.idle and not self.dmaOut._first_transfer: pass self.dmaOut.transfer(self.cmaBuffer2) rest = src.nbytes % self.partitions if rest > 0: #cleanup any remaining data and send it to HW #self.copyNtoOff(src ,self.cmaBuffer0,chunks_len, self.partitions*chunks_len, 0) self.copyNtoOff(self.cmaBuffer0, src, chunks_len, 0, self.partitions * chunks_len) while not self.dmaOut.idle and not self.dmaOut._first_transfer: pass self.dmaOut.transfer(self.cmaBuffer0) rest -= chunks_len self.dmaIn.wait() ret = np.ndarray(src.shape, src.dtype) self.copyNto(ret, self.cmaBuffer1, ret.nbytes) return ret def floatToFixed(self, f, total_bits, fract_bits): """convert float f to a signed fixed point with #total_bits and #frac_bits after the point""" fix = int((abs(f) * (1 << fract_bits))) if (f < 0): fix += 1 << total_bits - 1 return fix def erodeDilateKernel(self, src, kernel, dst, iterations, mode, filter): filter.mode = mode filter.rows = src.shape[0] filter.columns = src.shape[1] if hasattr(src, 'physical_address') and hasattr( dst, 'physical_address'): filter.start() if iterations > 1: self.dmaIn.transfer(self.cmaBuffer1) else: self.dmaIn.transfer(dst) self.dmaOut.transfer(src) self.dmaIn.wait() self.cmaBuffer2.nbytes = src.nbytes #buffer = self.xlnk.cma_array(src.shape, dtype=np.uint8) for i in range(2, iterations + 1): filter.start() if i % 2 == 0: self.dmaIn.transfer(self.cmaBuffer2) if i != iterations: #avoid copy after last iteration self.dmaOut.transfer(self.cmaBuffer1) else: self.dmaOut.transfer(dst) else: self.dmaIn.transfer(self.cmaBuffer1) if i != iterations: self.dmaOut.transfer(self.cmaBuffer2) else: self.dmaOut.transfer(dst) self.dmaIn.wait() return dst self.cmaBuffer0.nbytes = src.nbytes self.cmaBuffer1.nbytes = src.nbytes filter.start() self.dmaIn.transfer(self.cmaBuffer1) if hasattr(src, 'physical_address'): self.dmaOut.transfer(src) else: self.copyNto(self.cmaBuffer0, src, src.nbytes) #np.copyto(srcBuffer,src) self.dmaOut.transfer(self.cmaBuffer0) self.dmaIn.wait() self.cmaBuffer2.nbytes = src.nbytes #buffer = self.xlnk.cma_array(src.shape, dtype=np.uint8) for i in range(2, iterations + 1): filter.start() if i % 2 == 0: self.dmaIn.transfer(self.cmaBuffer2) self.dmaOut.transfer(self.cmaBuffer1) else: self.dmaIn.transfer(self.cmaBuffer1) self.dmaOut.transfer(self.cmaBuffer2) self.dmaIn.wait() ret = np.ndarray(src.shape, src.dtype) if iterations % 2 == 1: self.copyNto(ret, self.cmaBuffer1, ret.nbytes) else: self.copyNto(ret, self.cmaBuffer2, ret.nbytes) return ret '''def cornerHarris(self, src, k, dst): self.img_filters.select_filter(5) self.cornerHarrisIP.rows = src.shape[0] self.cornerHarrisIP.columns = src.shape[1] self.cornerHarrisIP.start() if hasattr(src, 'physical_address') and hasattr(dst, 'physical_address') and (dst.nbytes == src.nbytes*4): self.dmaIn.transfer(dst) self.dmaOut.transfer(src) self.dmaIn.wait() return dst self.cmaBuffer2.nbytes = src.nbytes*4 self.dmaIn.transfer(self.cmaBuffer2) if hasattr(src, 'physical_address') : self.dmaOut.transfer(src) else: self.cmaBuffer0.nbytes = src.nbytes self.copyNto(self.cmaBuffer0,src,src.nbytes) self.dmaOut.transfer(self.cmaBuffer0) self.dmaIn.wait() ret = np.ndarray(src.shape,np.float32) self.copyNto(ret,self.cmaBuffer2,ret.nbytes) return ret''' def copyNto(self, dst, src, N): dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst)) srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src)) self.ffi.memmove(dstPtr, srcPtr, N) def copyNtoOff(self, dst, src, N, dstOffset, srcOffset): dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst)) srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src)) dstPtr += dstOffset srcPtr += srcOffset self.ffi.memmove(dstPtr, srcPtr, N) class ContiguousArrayCv2pynq(ContiguousArray): def init(self, cmaArray): self._nbytes = cmaArray.nbytes self.physical_address = cmaArray.physical_address self.cacheable = cmaArray.cacheable # overwrite access to nbytes with own function @property def nbytes(self): return self._nbytes @nbytes.setter def nbytes(self, value): self._nbytes = value
def _convert_map(map_data_path, multiplayer_path, bitmaps_pc_path, bitmaps_ce_path, sounds_pc_path, sounds_ce_path, destination, combustion_lib_path): # Initialize the FFI ffi = FFI() # Use the c header ffi.cdef( open(os.path.join(os.path.dirname(__file__), 'combustion.h')).read()) # Import the dynamic library libcombustion_r = ffi.dlopen(combustion_lib_path) map_data = _create_read_only_buffer_tuple(ffi, map_data_path) # @todo multiplayer = (ffi.from_buffer(ctypes.create_string_buffer(0)), 0) bitmaps_pc = _create_read_only_buffer_tuple(ffi, bitmaps_pc_path) sounds_pc = _create_read_only_buffer_tuple(ffi, sounds_pc_path) bitmaps_ce = _create_read_only_buffer_tuple(ffi, bitmaps_ce_path) sounds_ce = _create_read_only_buffer_tuple(ffi, sounds_ce_path) converted_map_len = libcombustion_r.convert_map_cd_len( map_data[0], map_data[1], multiplayer[0], multiplayer[1], bitmaps_pc[0], bitmaps_pc[1], bitmaps_ce[0], bitmaps_ce[1], sounds_pc[0], sounds_pc[1], sounds_ce[0], sounds_ce[1], # This last argument is needed to ensure that cffi passes the rest of the arguments correctly. # I don't know why. 0) if converted_map_len is 0: raise Exception("ERROR!! No data to write to {}!".format(map_name)) map_buffer = _create_writable_buffer_tuple(ffi, converted_map_len) converted_map_len = libcombustion_r.convert_map_cd( map_buffer[1], map_buffer[2], map_data[0], map_data[1], multiplayer[0], multiplayer[1], bitmaps_pc[0], bitmaps_pc[1], bitmaps_ce[0], bitmaps_ce[1], sounds_pc[0], sounds_pc[1], sounds_ce[0], sounds_ce[1], # This last argument is needed to ensure that cffi passes the rest of the arguments correctly. # I don't know why. 0) buffer_file = open(destination, 'wb+') buffer_file.write(ffi.buffer(map_buffer[0])) buffer_file.close()
class SGXInterface: def __init__(self): LOG.info("SGX Interface initialized") self.ffi = FFI() dir_path = os.path.dirname(os.path.realpath(__file__)) with open(os.path.join(dir_path,"sgx.h")) as stream: self.ffi.cdef(stream.read()) self.ffi.set_source("_sgx_interface", """ #include "sgx_eid.h" #include "sgx_key_exchange.h" #include "common.h" #include "network_ra.h" #include "barbie_server.h" #include "barbie_client.h" #include "ra_client.h" #include "ra_server.h" #include <stdbool.h> #include "service_provider.h" """, include_dirs=['/usr/include', '/opt/intel/sgxsdk/include'], library_dirs=['/usr/local/lib', '/opt/intel/sgxsdk/lib64/'], libraries=["sample_libcrypto", "BarbiE_Client", "BarbiE_Server"]) self.ffi.compile(tmpdir=dir_path) libuae = self.ffi.dlopen("sgx_uae_service", self.ffi.RTLD_GLOBAL) liburts = self.ffi.dlopen("sgx_urts", self.ffi.RTLD_GLOBAL) libcrypto = self.ffi.dlopen("sample_libcrypto", self.ffi.RTLD_GLOBAL) self.barbie_s = self.ffi.dlopen("BarbiE_Server", self.ffi.RTLD_LAZY) self.barbie_c = self.ffi.dlopen("BarbiE_Client", self.ffi.RTLD_LAZY) self.iv = 12 self.mac = 16 self.error_dict = {'0':'SP_OK', '1':'SP_UNSUPPORTED_EXTENDED_EPID_GROUP', '2':'SP_INTEGRITY_FAILED', '3':'SP_QUOTE_VERIFICATION_FAILED', '4':'SP_IAS_FAILED', '5':'SP_INTERNAL_ERROR', '6':'SP_PROTOCOL_ERROR', '7':'SP_QUOTE_VERSION_ERROR', '8':'SP_SPID_SET_ERROR'} def init_env_variables(self): separator = "=" with open("/opt/BarbiE/env.properties") as f: for line in f: if separator in line: name, value = line.split(separator) os.environ[name.strip()] = value.strip() def get_spid(self): separator = "=" spid = None with open("/opt/BarbiE/env.properties") as f: for line in f: if separator in line: name, value = line.split(separator) if name.strip() == "IAS_SPID": spid = value.strip() return spid def get_ias_crt(self): separator = "=" ias_crt = None with open("/opt/BarbiE/env.properties") as f: for line in f: if separator in line: name, value = line.split(separator) if name.strip() == "IAS_CRT_PATH": ias_crt = value.strip() return ias_crt def get_ias_enable(self): separator = "=" ias_enabled = None with open("/opt/BarbiE/env.properties") as f: for line in f: if separator in line: name, value = line.split(separator) if name.strip() == "IAS_ENABLED": ias_enabled = value.strip() if ias_enabled == 'True': return True else : return False def init_enclave(self, target_lib): try: p_enclave_id = self.ffi.new("sgx_enclave_id_t *") status = target_lib.initialize_enclave(p_enclave_id) return p_enclave_id[0] except Exception as e: LOG.error("Error in initializing enclave!") return -1 def get_crt(self, resp_crt=None): pattern = '-----END CERTIFICATE-----\n' crt = resp_crt.split(pattern) return crt[0]+pattern, crt[1]+"\n" def verify_certificate(self, crt=None, cacrt=None): try: cert = load_certificate(FILETYPE_PEM, crt) intermediate_cert = load_certificate(FILETYPE_PEM, cacrt) validation_cert = load_certificate(FILETYPE_PEM, cacrt) store = X509Store() store.add_cert(intermediate_cert) store.add_cert(cert) store_ctx = X509StoreContext(store, validation_cert) if(store_ctx.verify_certificate() == None): LOG.info("Certificate verification Passed on Server side") return True else: raise Exception("Certificate Verification Failed on Server side") except Exception as e: LOG.error(str(e)) raise Exception("Certificate Validation Failed on Server side", e) def verify_signature(self, crt=None, sign=None, resp_body=None): try: x509 = load_certificate(FILETYPE_PEM, crt) pub_key = x509.get_pubkey() ias_public_key = dump_publickey(FILETYPE_PEM, pub_key) public_key = load_publickey(FILETYPE_PEM, ias_public_key) x509 = X509() x509.set_pubkey(public_key) if verify(x509, base64.b64decode(sign), resp_body, 'sha256') == None: LOG.info("Signature verification Passed on Server side") return True except Exception as e: LOG.error(str(e)) raise Exception("Signature verification Failed on Server side", e) def generate_key_pair(self): separator = "=" key_dir = None with open("/opt/BarbiE/env.properties") as f: for line in f: if separator in line: name, value = line.split(separator) if name.strip() == "KEY_PAIR_DIR": key_dir = value.strip() pub_key_path = os.path.join(key_dir, "public_key.pem") priv_key_path = os.path.join(key_dir, "private_key.pem") if not os.path.exists(pub_key_path): priv_key = SigningKey.generate(curve=NIST256p) pub_key = priv_key.get_verifying_key() open(priv_key_path,"w").write(priv_key.to_pem()) open(pub_key_path,"w").write(pub_key.to_pem()) else: priv_key = SigningKey.from_pem(open(priv_key_path).read()) pub_key = VerifyingKey.from_pem(open(pub_key_path).read()) pk64 = pub_key.to_string() pk_x, pk_y = pk64[:len(pk64)/2], pk64[len(pk64)/2:] hex_priv_key = priv_key.to_string() hex_sk = hex_priv_key.encode('hex') pk_x = pk_x.encode('hex') pk_y = pk_y.encode('hex') hex_priv_key_out = [hex_sk[i:i + 2]for i in range(0, len(hex_sk), 2)] pk_x_out = [pk_x[i:i + 2] for i in range(0,len(pk_x), 2)] pk_y_out = [pk_y[i:i + 2] for i in range(0,len(pk_y), 2)] pk_x_out.reverse() pk_y_out.reverse() pub_key = "" for i in range(len(pk_x_out)): pub_key = pub_key + pk_x_out[i] for i in range(len(pk_y_out)): pub_key = pub_key + pk_y_out[i] hex_priv_key_out.reverse() priv_key = "" for i in range(len(hex_priv_key_out)): priv_key = priv_key + hex_priv_key_out[i] pub_key = base64.b64encode(pub_key + '\0') priv_key = base64.b64encode(priv_key + '\0') return pub_key , priv_key def gen_msg0(self, target_lib, spid=None): try: if spid is None: spid = self.ffi.NULL p_ctxt = self.ffi.new("sgx_ra_context_t *") p_req0 = self.ffi.new("ra_samp_msg0_request_header_t **") ret = target_lib.gen_msg0(p_req0, spid) msg0 = base64.b64encode(self.ffi.buffer(p_req0[0])) return ret, msg0 except Exception as e: LOG.error("Error in generating msg0") raise e def proc_msg0(self, target_lib, msg0, spid=None, client_verify_ias=False): try: if spid is None: spid = self.ffi.NULL msg0 = self.ffi.from_buffer(base64.b64decode(msg0)) p_net_ctxt = self.ffi.new("void **") status = target_lib.proc_msg0(msg0, p_net_ctxt, spid, client_verify_ias) error = self.error_dict[str(status)] if(error != 'SP_SPID_SET_ERROR'): return status, p_net_ctxt else: raise Exception("SPID not set server side") except Exception as e: LOG.error("Error in processing msg0") raise e def gen_msg1(self, target_lib, enclave_id, pub_key): try: if pub_key != None: pub_key = base64.b64decode(pub_key) key = self.ffi.new("char[]", pub_key) else: key = self.ffi.NULL p_ctxt = self.ffi.new("sgx_ra_context_t *") p_req1 = self.ffi.new("ra_samp_msg1_request_header_t **") target_lib.gen_msg1(enclave_id, p_ctxt, p_req1, key) msg1 = base64.b64encode(self.ffi.buffer(p_req1[0])) return p_ctxt[0], msg1 except Exception as e: LOG.error("Error in generating msg1") raise e def proc_msg1_gen_msg2(self, target_lib, msg1, p_net_ctxt, priv_key): try: if priv_key != None: priv_key = base64.b64decode(priv_key) key = self.ffi.new("char[]", priv_key) else: key = self.ffi.NULL msg1 = self.ffi.from_buffer(base64.b64decode(msg1)) pp_resp1 = self.ffi.new("ra_samp_msg1_response_header_t **") target_lib.proc_msg1(msg1, p_net_ctxt, pp_resp1, key) msg2 = base64.b64encode(self.ffi.buffer(pp_resp1[0])) return msg2 except Exception as e: LOG.error("Error in generating msg2") raise e def proc_msg2_gen_msg3(self, target_lib, enclave_id, msg2, p_ctxt, ias_crt=None, client_verify_ias=False, server_verify_ias=True): try: if ias_crt is None: ias_crt = self.ffi.NULL msg2 = self.ffi.from_buffer(base64.b64decode(msg2)) pp_req2 = self.ffi.new("ra_samp_msg3_request_header_t **") resp_crt = self.ffi.new("uint8_t[]", 4000) resp_sign = self.ffi.new("uint8_t[]", 500) resp_body = self.ffi.new("uint8_t[]", 1200) status = target_lib.gen_msg3(enclave_id, p_ctxt, msg2, pp_req2, ias_crt, client_verify_ias, server_verify_ias, resp_crt, resp_sign, resp_body) error = self.error_dict[str(status)] if(error != 'SP_QUOTE_VERIFICATION_FAILED'): msg3 = base64.b64encode(self.ffi.buffer(pp_req2[0])) else: raise Exception("IAS verification failed") return msg3, self.ffi.string(resp_crt), self.ffi.string(resp_sign), self.ffi.string(resp_body) except Exception as e: LOG.error("Error in generating msg3") raise e def proc_msg3_gen_msg4(self, target_lib, enclave_id, msg3, p_net_ctxt, sealed_sk, project_id=None, owner_mr_e=None, ias_crt=None, client_verify_ias=False, sealed_key2=None): try: if ias_crt is None: ias_crt = self.ffi.NULL owner_mr_e = self.ffi.from_buffer(base64.b64decode(owner_mr_e)) msg3 = self.ffi.from_buffer(base64.b64decode(msg3)) if sealed_sk is None: sealed_len = 0 sealed_sk = self.ffi.NULL else: sealed_len = sealed_sk.length sealed_sk = self.ffi.from_buffer(base64.b64decode(sealed_sk.value)) if project_id is None: project_id_len = 0 project_id = self.ffi.NULL else: project_id_len = len(project_id) sealed_key2_len = sealed_key2.length sealed_key2 = self.ffi.from_buffer(base64.b64decode(sealed_key2.value)) pp_resp2 = self.ffi.new("ra_samp_msg3_response_header_t **") target_lib.set_enclave(p_net_ctxt, enclave_id) target_lib.set_secret(p_net_ctxt, sealed_sk, sealed_len, sealed_key2, sealed_key2_len) status = target_lib.proc_msg3(msg3, p_net_ctxt, pp_resp2, self.ffi.NULL, project_id, owner_mr_e, ias_crt, client_verify_ias) #Initially using 177 length of msg4 but #after adding project id to msg4 using (209 + project id length) for msg4 error = self.error_dict[str(status)] if(error != 'SP_QUOTE_VERIFICATION_FAILED'): msg4 = base64.b64encode(self.ffi.buffer(pp_resp2[0],(417 + project_id_len))) else: raise Exception("IAS verification failed") return msg4 except Exception as e: LOG.error("Error in generating msg4") raise e def ma_proc_msg4(self, target_lib, enclave_id, s_msg4, s_p_ctxt, c_msg3, c_p_net_ctxt, s_mk, mk_sk, policy_dict, ias_crt, client_verify_ias, project_id_len): try: plain_sk_len = 16 b64_iv = 16 b64_mac = 24 if s_mk and mk_sk: LOG.info("Using existing buffers") sealed_len = s_mk.length sealed_mk = self.ffi.from_buffer(base64.b64decode(s_mk.value)) iv = self.ffi.from_buffer(base64.b64decode(mk_sk[:b64_iv])) mac = self.ffi.from_buffer(base64.b64decode(mk_sk[b64_iv:(b64_iv + b64_mac)])) mk_sk = self.ffi.from_buffer(base64.b64decode(mk_sk[(b64_iv + b64_mac):])) mk_sk_len = len(mk_sk) else: LOG.info("Creating new buffers") iv = self.ffi.new("uint8_t[]", self.iv) mac = self.ffi.new("uint8_t[]", self.mac) mk_sk = self.ffi.new("uint8_t[]", plain_sk_len) sealed_len = target_lib.get_sealed_data_len(enclave_id, 0, plain_sk_len) sealed_mk = self.ffi.new("uint8_t[]", sealed_len) #Set sealed len zero to let native side know this is output variable mk_sk_len = plain_sk_len if policy_dict: policy = policy_dict['policy'] attribute = policy_dict['attribute'] iv1 = self.ffi.from_buffer(base64.b64decode(attribute[:b64_iv])) mac1 = self.ffi.from_buffer(base64.b64decode(attribute[b64_iv:(b64_iv + b64_mac)])) attribute = self.ffi.from_buffer(base64.b64decode(attribute[(b64_iv + b64_mac):])) attribute_len = len(attribute) else: policy = 0 attribute = self.ffi.NULL attribute_len = 0 iv1 = self.ffi.NULL mac1 = self.ffi.NULL s_msg4 = self.ffi.from_buffer(base64.b64decode(s_msg4)) c_msg3 = self.ffi.from_buffer(base64.b64decode(c_msg3)) pp_resp2 = self.ffi.new("ra_samp_msg3_response_header_t **") status = target_lib.ma_proc_ra(enclave_id, s_msg4, s_p_ctxt, c_msg3, c_p_net_ctxt, pp_resp2, sealed_mk, sealed_len, mk_sk, mk_sk_len, iv, mac, ias_crt, client_verify_ias, policy, attribute, attribute_len, iv1, mac1) if status == 0: c_msg4 = base64.b64encode(self.ffi.buffer(pp_resp2[0],(417 + project_id_len))) sealed_mk = base64.b64encode(self.ffi.buffer(sealed_mk)) mk_sk = base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode(self.ffi.buffer(mac)) + base64.b64encode(self.ffi.buffer(mk_sk)) sealed_mk_len = target_lib.get_sealed_data_len(enclave_id, 0, plain_sk_len) return Secret(sealed_mk, sealed_mk_len), mk_sk, c_msg4 else: raise Exception("Error getting sealed mk and mk_sk") except Exception as e: LOG.error("Error in ma_proc_msg4") raise e def proc_msg4(self, target_lib, enclave_id, msg4, p_ctxt, sha2_client, sha2_server): try: sha2_client = self.ffi.from_buffer(base64.b64decode(sha2_client)) sha2_server = self.ffi.from_buffer(base64.b64decode(sha2_server)) msg4 = self.ffi.from_buffer(base64.b64decode(msg4)) plain_sk_len = 16 secret1_len = target_lib.get_sealed_data_len(enclave_id, 0, plain_sk_len) sealed_secret1 = self.ffi.new("uint8_t[]", secret1_len) status = target_lib.proc_ra(enclave_id, p_ctxt, msg4, sealed_secret1, secret1_len, self.ffi.NULL, 0) secret1_buf = base64.b64encode(self.ffi.buffer(sealed_secret1)) target_lib.close_ra(enclave_id, p_ctxt) return status, secret1_buf except Exception as e: LOG.error("Error in prcessing msg4 and retrieving sealed session key") raise e def new_proc_ra(self, target_lib, enclave_id, msg4, p_ctxt, s_mk, mk_sk): try: msg4 = self.ffi.from_buffer(base64.b64decode(msg4)) plain_sk_len = 16 b64_iv = 16 b64_mac = 24 if s_mk and mk_sk: LOG.info("Using existing buffers") sealed_len = s_mk.length sealed_mk = self.ffi.from_buffer(base64.b64decode(s_mk.value)) iv = self.ffi.from_buffer(base64.b64decode(mk_sk[:b64_iv])) mac = self.ffi.from_buffer(base64.b64decode(mk_sk[b64_iv:(b64_iv + b64_mac)])) mk_sk = self.ffi.from_buffer(base64.b64decode(mk_sk[(b64_iv + b64_mac):])) mk_sk_len = len(mk_sk) else: LOG.info("Creating new buffers") iv = self.ffi.new("uint8_t[]", self.iv) mac = self.ffi.new("uint8_t[]", self.mac) mk_sk = self.ffi.new("uint8_t[]", plain_sk_len) sealed_len = target_lib.get_sealed_data_len(enclave_id, 0, plain_sk_len) sealed_mk = self.ffi.new("uint8_t[]", sealed_len) #Set sealed len zero to let native side know this is output variable sealed_len = 0 mk_sk_len = 0 iv1 = self.ffi.new("uint8_t[]", self.iv) mac1 = self.ffi.new("uint8_t[]", self.mac) dh_sk = self.ffi.new("uint8_t[]", plain_sk_len) dh_sk_len = plain_sk_len status = target_lib.new_proc_ra(enclave_id, p_ctxt, msg4, sealed_mk, sealed_len, mk_sk, mk_sk_len, iv, mac, dh_sk, dh_sk_len, iv1, mac1) if status == 0: sealed_mk = base64.b64encode(self.ffi.buffer(sealed_mk)) mk_sk = base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode(self.ffi.buffer(mac)) + base64.b64encode(self.ffi.buffer(mk_sk)) dh_sk = base64.b64encode(self.ffi.buffer(iv1)) + base64.b64encode(self.ffi.buffer(mac1)) + base64.b64encode(self.ffi.buffer(dh_sk)) return Secret(sealed_mk, 576), mk_sk, dh_sk else: raise Exception("Error getting sealed mk, mk_sk and dh_sk") except Exception as e: LOG.error("Error in new_proc_ra") raise e def get_dh_key(self, target_lib, enclave_id, msg4, p_ctxt): try: msg4 = self.ffi.from_buffer(base64.b64decode(msg4)) plain_sk_len = 16 sealed_len = target_lib.get_sealed_data_len(enclave_id, 0, plain_sk_len) sealed_dh = self.ffi.new("uint8_t[]", sealed_len) status = target_lib.get_dh_key(enclave_id, p_ctxt, msg4, sealed_dh, self.ffi.cast("uint32_t", sealed_len)) dh_buf = base64.b64encode(self.ffi.buffer(sealed_dh)) #target_lib.close_ra(enclave_id, p_ctxt) return status, dh_buf except Exception as e: LOG.error("Error in get_dh_key") raise e def get_project_id(self, target_lib, enclave_id, msg4, p_ctxt): try: msg4 = self.ffi.from_buffer(base64.b64decode(msg4)) proj_id_len = self.ffi.cast("uint32_t",0) proj_id_len = target_lib.get_project_id_len(enclave_id, p_ctxt, msg4) proj_id = self.ffi.new("uint8_t []", proj_id_len) status = target_lib.get_project_id(enclave_id, p_ctxt, msg4, proj_id) return proj_id, proj_id_len except Exception as e: LOG.error("Error in geting project id") raise e def convert_to_python_data(self,project_id=None): project_id = self.ffi.string(project_id) return project_id def get_sk(self, target_lib, p_net_ctx, enc_sk): #todo extract iv and mac, call target_lib.get_sk and return plain sk try: b64_iv = 16 b64_mac = 24 iv = self.ffi.from_buffer(base64.b64decode(enc_sk[:b64_iv])) mac = self.ffi.from_buffer(base64.b64decode(enc_sk[b64_iv:(b64_iv + b64_mac)])) dh_sk = self.ffi.from_buffer(base64.b64decode(enc_sk[(b64_iv + b64_mac):])) plain_sk = self.ffi.new("uint8_t[]", 16) status = target_lib.get_sk(p_net_ctx, plain_sk, 16, dh_sk, iv, mac) return Secret(self.ffi.string(plain_sk, 16), 16) except Exception as e: LOG.error("Error in get_sk") raise e def generate_key(self, target_lib, enclave_id, key_len): try: sealed_len = target_lib.get_sealed_data_len(enclave_id, 0, key_len) sealed_key = self.ffi.new("uint8_t[]", sealed_len) target_lib.crypto_generate_key(enclave_id, key_len, sealed_key, sealed_len) #use these api's to determine required plain text buffer given a sealed buffer #add mac always 0 for now #add_mac_len = target_lib.get_add_mac_len(enclave_id, sealed_key, sealed_len) #plain_len = target_lib.get_encrypted_len(enclave_id, sealed_key, sealed_len) return Secret(base64.b64encode(self.ffi.buffer(sealed_key)), sealed_len) except Exception as e: LOG.error("Error in generating key") raise e def get_kek(self, target_lib, enclave_id, s_mk, mk_sk, sk_kek, project_id, project_id_len): try: plain_sk_len = 16 b64_iv = 16 b64_mac = 24 sealed_len = s_mk.length sealed_mk = self.ffi.from_buffer(base64.b64decode(s_mk.value)) iv = self.ffi.from_buffer(base64.b64decode(mk_sk[:b64_iv])) mac = self.ffi.from_buffer(base64.b64decode(mk_sk[b64_iv:(b64_iv + b64_mac)])) mk_sk = self.ffi.from_buffer(base64.b64decode(mk_sk[(b64_iv + b64_mac):])) mk_sk_len = plain_sk_len iv1 = self.ffi.from_buffer(base64.b64decode(sk_kek[:b64_iv])) mac1 = self.ffi.from_buffer(base64.b64decode(sk_kek[b64_iv:(b64_iv + b64_mac)])) sk_kek = self.ffi.from_buffer(base64.b64decode(sk_kek[(b64_iv + b64_mac):])) sk_kek_len = plain_sk_len sealed_kek_len = target_lib.get_sealed_data_len(enclave_id, 0, plain_sk_len) sealed_kek = self.ffi.new("uint8_t[]", sealed_kek_len) status = target_lib.get_kek(enclave_id, sealed_mk, sealed_len, mk_sk, mk_sk_len, iv, mac, sk_kek, sk_kek_len, iv1, mac1, sealed_kek, sealed_kek_len, project_id, project_id_len) if status != 0: raise Exception("Error in getting sealed kek") return Secret(base64.b64encode(self.ffi.buffer(sealed_kek)), sealed_len) except Exception as e: LOG.error("Error in getting sealed kek") raise e def secret_encrypt(self, target_lib, enclave_id, s_mk, mk_sk, sk_secret, project_id, project_id_len): try: plain_sk_len = 16 b64_iv = 16 b64_mac = 24 sealed_len = s_mk.length sealed_mk = self.ffi.from_buffer(base64.b64decode(s_mk.value)) iv = self.ffi.from_buffer(base64.b64decode(mk_sk[:b64_iv])) mac = self.ffi.from_buffer(base64.b64decode(mk_sk[b64_iv:(b64_iv + b64_mac)])) mk_sk = self.ffi.from_buffer(base64.b64decode(mk_sk[(b64_iv + b64_mac):])) mk_sk_len = plain_sk_len iv1 = self.ffi.from_buffer(base64.b64decode(sk_secret[:b64_iv])) mac1 = self.ffi.from_buffer(base64.b64decode(sk_secret[b64_iv:(b64_iv + b64_mac)])) sk_secret = self.ffi.from_buffer(base64.b64decode(sk_secret[(b64_iv + b64_mac):])) sk_secret_len = len(sk_secret) mk_secret = self.ffi.new("uint8_t[]", sk_secret_len) iv2 = self.ffi.new("uint8_t[]", self.iv) mac2 = self.ffi.new("uint8_t[]", self.mac) status = target_lib.secret_encrypt(enclave_id, sealed_mk, sealed_len, mk_sk, mk_sk_len, iv, mac, sk_secret, sk_secret_len, iv1, mac1, mk_secret, sk_secret_len, iv2, mac2, project_id, project_id_len) if status != 0: raise Exception("Error in getting mk encrypted secret") return base64.b64encode(self.ffi.buffer(iv2)) + base64.b64encode(self.ffi.buffer(mac2)) + base64.b64encode(self.ffi.buffer(mk_secret)) except Exception as e: LOG.error("Error in getting mk encrypted secret") raise e def secret_decrypt(self, target_lib, enclave_id, s_mk, mk_sk, mk_secret, project_id, project_id_len): try: plain_sk_len = 16 b64_iv = 16 b64_mac = 24 sealed_len = s_mk.length sealed_mk = self.ffi.from_buffer(base64.b64decode(s_mk.value)) iv = self.ffi.from_buffer(base64.b64decode(mk_sk[:b64_iv])) mac = self.ffi.from_buffer(base64.b64decode(mk_sk[b64_iv:(b64_iv + b64_mac)])) mk_sk = self.ffi.from_buffer(base64.b64decode(mk_sk[(b64_iv + b64_mac):])) mk_sk_len = plain_sk_len iv1 = self.ffi.from_buffer(base64.b64decode(mk_secret[:b64_iv])) mac1 = self.ffi.from_buffer(base64.b64decode(mk_secret[b64_iv:(b64_iv + b64_mac)])) mk_secret = self.ffi.from_buffer(base64.b64decode(mk_secret[(b64_iv + b64_mac):])) mk_secret_len = len(mk_secret) sk_secret = self.ffi.new("uint8_t[]", mk_secret_len) iv2 = self.ffi.new("uint8_t[]", self.iv) mac2 = self.ffi.new("uint8_t[]", self.mac) status = target_lib.secret_decrypt(enclave_id, sealed_mk, sealed_len, mk_sk, mk_sk_len, iv, mac, mk_secret, mk_secret_len, iv1, mac1, sk_secret, mk_secret_len, iv2, mac2, project_id, project_id_len) if status != 0: raise Exception("Error in getting sk encrypted secret") return base64.b64encode(self.ffi.buffer(iv2)) + base64.b64encode(self.ffi.buffer(mac2)) + base64.b64encode(self.ffi.buffer(sk_secret)) except Exception as e: LOG.error("Error in getting sk encrypted secret") raise e def provision_kek(self, target_lib, enclave_id, sealed_sk, sk_kek, project_id=None): try: if project_id is None: project_id = self.ffi.NULL proj_id_len = 0 else: proj_id_len = len(project_id) b64_iv = 16 b64_mac = 24 sealed_len = sealed_sk.length sealed_sk = self.ffi.from_buffer(base64.b64decode(sealed_sk.value)) iv = self.ffi.from_buffer(base64.b64decode(sk_kek[:b64_iv])) mac = self.ffi.from_buffer(base64.b64decode(sk_kek[b64_iv:(b64_iv + b64_mac)])) sk_kek = self.ffi.from_buffer(base64.b64decode(sk_kek[(b64_iv + b64_mac):])) plain_kek_len = len(sk_kek) sealed_kek_len = target_lib.get_sealed_data_len(enclave_id, 0, plain_kek_len) sealed_kek = self.ffi.new("uint8_t[]", sealed_kek_len) status = target_lib.crypto_provision_kek(enclave_id, sealed_sk, sealed_len, sk_kek, plain_kek_len, iv, mac, sealed_kek, sealed_kek_len, project_id, proj_id_len) if status != 0: raise Exception("Error in decrypting secret") return base64.b64encode(self.ffi.buffer(sealed_kek)) except Exception as e: LOG.error("Error in provisioning of kek") raise e def legacy_encrypt(self, target_lib, plain_sk, secret): try: iv = self.ffi.new("uint8_t[]", self.iv) mac = self.ffi.new("uint8_t[]", self.mac) enc_secret = self.ffi.new("uint8_t[]", secret.length) target_lib.crypto_legacy_encrypt(plain_sk.value, plain_sk.length, secret.value, secret.length, enc_secret, iv, mac) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode(self.ffi.buffer(mac)) + base64.b64encode(self.ffi.buffer(enc_secret)) except Exception as e: LOG.error("ERROR: Encryption of the secret failed!") raise e def encrypt(self, target_lib, enclave_id, sealed_sk, secret): try: iv = self.ffi.new("uint8_t[]", self.iv) mac = self.ffi.new("uint8_t[]", self.mac) sealed_len = sealed_sk.length sealed_sk = self.ffi.from_buffer(base64.b64decode(sealed_sk.value)) enc_secret = self.ffi.new("uint8_t[]", secret.length) target_lib.crypto_encrypt(enclave_id, sealed_sk, sealed_len, secret.value, secret.length, enc_secret, iv, mac) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode(self.ffi.buffer(mac)) + base64.b64encode(self.ffi.buffer(enc_secret)) except Exception as e: LOG.error("ERROR: Encryption of the secret failed!") raise e def decrypt(self, target_lib, enclave_id, sealed_sk, enc_secret): try: b64_iv = 16 b64_mac = 24 iv = self.ffi.from_buffer(base64.b64decode(enc_secret[:b64_iv])) mac = self.ffi.from_buffer(base64.b64decode(enc_secret[b64_iv:(b64_iv + b64_mac)])) enc_secret = self.ffi.from_buffer(base64.b64decode(enc_secret[(b64_iv + b64_mac):])) length = len(enc_secret) sealed_len = sealed_sk.length sealed_sk = self.ffi.from_buffer(base64.b64decode(sealed_sk.value)) secret = self.ffi.new("uint8_t[]", length) target_lib.crypto_decrypt(enclave_id, sealed_sk, sealed_len, secret, length, enc_secret, iv, mac, self.ffi.NULL, 0) return base64.b64encode(self.ffi.buffer(secret)) except Exception as e: LOG.error("ERROR: Decryption of the secret failed!") raise e def transport(self, target_lib, enclave_id, sealed_kek, sealed_sk, project_id=None): try: if project_id is None: project_id = self.ffi.NULL proj_id_len = 0 else: proj_id_len = len(project_id) iv = self.ffi.new("uint8_t[]", self.iv) mac = self.ffi.new("uint8_t[]", self.mac) sealed_kek_len = sealed_kek.length sealed_kek = self.ffi.from_buffer(base64.b64decode(sealed_kek.value)) sealed_sk_len = sealed_sk.length sealed_sk = self.ffi.from_buffer(base64.b64decode(sealed_sk.value)) sk_len = target_lib.get_encrypted_len(enclave_id, sealed_sk, sealed_sk_len) kek_sk = self.ffi.new("uint8_t[]", sk_len) target_lib.crypto_transport_secret(enclave_id, sealed_kek, sealed_kek_len, sealed_sk, sealed_sk_len, kek_sk, sk_len, iv, mac, project_id, proj_id_len) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode(self.ffi.buffer(mac)) + base64.b64encode(self.ffi.buffer(kek_sk)) except Exception as e: LOG.error("Error in transporting the secret") raise e #no need for target lib, server action only def kek_encrypt(self, enclave_id, kek_sk, sealed_kek, sk_secret, project_id=None): try: if project_id is None: project_id = self.ffi.NULL proj_id_len = 0 else: proj_id_len = len(project_id) b64_iv = 16 b64_mac = 24 iv1 = self.ffi.from_buffer(base64.b64decode(kek_sk[:b64_iv])) mac1 = self.ffi.from_buffer(base64.b64decode(kek_sk[b64_iv:(b64_iv + b64_mac)])) kek_sk = self.ffi.from_buffer(base64.b64decode(kek_sk[(b64_iv + b64_mac):])) sealed_kek_len = sealed_kek.length sealed_kek = self.ffi.from_buffer(base64.b64decode(sealed_kek.value)) iv = self.ffi.from_buffer(base64.b64decode(sk_secret[:b64_iv])) mac = self.ffi.from_buffer(base64.b64decode(sk_secret[b64_iv:(b64_iv + b64_mac)])) sk_secret = self.ffi.from_buffer(base64.b64decode(sk_secret[(b64_iv + b64_mac):])) length = len(sk_secret) kek_secret = self.ffi.new("uint8_t[]", length) self.barbie_s.crypto_store_secret(enclave_id, kek_sk, len(kek_sk), iv1, mac1, sealed_kek, sealed_kek_len, sk_secret, length, kek_secret, length, iv, mac, str(project_id), proj_id_len) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode(self.ffi.buffer(mac)) + base64.b64encode(self.ffi.buffer(kek_secret)) except Exception as e: LOG.error("Error in encrypting the secret with kek") raise e #no need for target lib, server action only def kek_decrypt(self, enclave_id, kek_sk, sealed_kek, kek_secret, project_id=None): try: if project_id is None: project_id = self.ffi.NULL proj_id_len = 0 else: proj_id_len = len(project_id) b64_iv = 16 b64_mac = 24 iv1 = self.ffi.from_buffer(base64.b64decode(kek_sk[:b64_iv])) mac1 = self.ffi.from_buffer(base64.b64decode(kek_sk[b64_iv:(b64_iv + b64_mac)])) kek_sk = self.ffi.from_buffer(base64.b64decode(kek_sk[(b64_iv + b64_mac):])) sealed_kek_len = sealed_kek.length sealed_kek = self.ffi.from_buffer(base64.b64decode(sealed_kek.value)) iv = self.ffi.from_buffer(base64.b64decode(kek_secret[:b64_iv])) mac = self.ffi.from_buffer(base64.b64decode(kek_secret[b64_iv:(b64_iv + b64_mac)])) kek_secret = self.ffi.from_buffer(base64.b64decode(kek_secret[(b64_iv + b64_mac):])) length = len(kek_secret) sk_secret = self.ffi.new("uint8_t[]", length) self.barbie_s.crypto_get_secret(enclave_id, kek_sk, len(kek_sk), iv1, mac1, sealed_kek, sealed_kek_len, kek_secret, length, sk_secret, length, iv, mac, str(project_id), proj_id_len) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode(self.ffi.buffer(mac)) + base64.b64encode(self.ffi.buffer(sk_secret)) except Exception as e: LOG.error("Error in decrypting the secret with kek") raise e def get_mk_mr_list(self, target_lib, enclave_id, mk_sk, sealed_mk, sk_mr_list, project_id, project_id_len, mk_mr_list=None): try: b64_iv = 16 b64_mac = 24 iv1 = self.ffi.from_buffer(base64.b64decode(mk_sk[:b64_iv])) mac1 = self.ffi.from_buffer(base64.b64decode(mk_sk[b64_iv:(b64_iv + b64_mac)])) mk_sk = self.ffi.from_buffer(base64.b64decode(mk_sk[(b64_iv + b64_mac):])) sealed_mk_len = sealed_mk.length sealed_mk = self.ffi.from_buffer(base64.b64decode(sealed_mk.value)) iv2 = self.ffi.from_buffer(base64.b64decode(sk_mr_list[:b64_iv])) mac2 = self.ffi.from_buffer(base64.b64decode(sk_mr_list[b64_iv:(b64_iv + b64_mac)])) sk_mr_list = self.ffi.from_buffer(base64.b64decode(sk_mr_list[(b64_iv + b64_mac):])) iv = self.ffi.new("uint8_t[]", self.iv) mac = self.ffi.new("uint8_t[]", self.mac) if mk_mr_list is None: mk_mr_list = self.ffi.NULL iv3 = self.ffi.NULL mac3 = self.ffi.NULL mk_mr_list_len = 0 else: iv3 = self.ffi.from_buffer(base64.b64decode(mk_mr_list[:b64_iv])) mac3 = self.ffi.from_buffer(base64.b64decode(mk_mr_list[b64_iv:(b64_iv + b64_mac)])) mk_mr_list = self.ffi.from_buffer(base64.b64decode(mk_mr_list[(b64_iv + b64_mac):])) mk_mr_list_len = len(mk_mr_list) new_mk_mr_list = self.ffi.new("uint8_t[]", len(sk_mr_list)) sk_mr_list_len = len(sk_mr_list) target_lib.get_mk_mr_list(enclave_id, sealed_mk, sealed_mk_len, mk_sk, sk_mr_list, sk_mr_list_len, project_id, len(project_id), mk_mr_list, mk_mr_list_len, new_mk_mr_list, iv1, mac1, iv2, mac2, iv3, mac3, iv, mac) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode(self.ffi.buffer(mac)) + base64.b64encode(self.ffi.buffer(new_mk_mr_list)) except Exception as e: LOG.error("Error generating mk_mr_list" + e) raise e def get_sk_data(self, target_lib, enclave_id, mk_sk, sealed_mk, mk_data, project_id, project_id_len): try: b64_iv = 16 b64_mac = 24 iv1 = self.ffi.from_buffer(base64.b64decode(mk_sk[:b64_iv])) mac1 = self.ffi.from_buffer(base64.b64decode(mk_sk[b64_iv:(b64_iv + b64_mac)])) mk_sk = self.ffi.from_buffer(base64.b64decode(mk_sk[(b64_iv + b64_mac):])) sealed_mk_len = sealed_mk.length sealed_mk = self.ffi.from_buffer(base64.b64decode(sealed_mk.value)) iv2 = self.ffi.from_buffer(base64.b64decode(mk_data[:b64_iv])) mac2 = self.ffi.from_buffer(base64.b64decode(mk_data[b64_iv:(b64_iv + b64_mac)])) mk_data = self.ffi.from_buffer(base64.b64decode(mk_data[(b64_iv + b64_mac):])) mk_data_len = len(mk_data) iv = self.ffi.new("uint8_t[]", self.iv) mac = self.ffi.new("uint8_t[]", self.mac) sk_data = self.ffi.new("uint8_t[]", len(mk_data)) target_lib.get_sk_data(enclave_id, sealed_mk, sealed_mk_len, mk_sk, mk_data, mk_data_len, project_id, len(project_id), sk_data, iv1, mac1, iv2, mac2, iv, mac) return base64.b64encode(self.ffi.buffer(iv)) + base64.b64encode(self.ffi.buffer(mac)) + base64.b64encode(self.ffi.buffer(sk_data)) except Exception as e: LOG.error("Error generating sk_data" + e) raise e def compare_secret(self, target_lib, secret1, secret2, secret_len): try: secret1 = self.ffi.from_buffer(base64.b64decode(secret1)) secret2 = self.ffi.from_buffer(base64.b64decode(secret2)) if target_lib.crypto_cmp(secret1, secret2, secret_len) == 0: return True return False except Exception as e: LOG.error("Error in comparing the secrets") raise e def compare_sealed_secret(self, target_lib, encalve_id, secret1, secret2): try: secret1 = self.ffi.from_buffer(base64.b64decode(secret1)) secret2 = self.ffi.from_buffer(base64.b64decode(secret2)) if target_lib.crypto_sealed_cmp(encalve_id, secret1, len(secret1), secret2, len(secret2)) == 0: return True return False except Exception as e: raise Exception("Error in comparing the sealed secrets", e) def destroy_enclave(self, target_lib, enclave_id): try: target_lib.destroy_enclave(enclave_id) except Exception as e: LOG.error("Error in destroying enclave!") #raise e def write_buffer_to_file(self, filename, buff): try: dir_path = os.path.dirname(os.path.realpath(__file__)) write_file = os.path.join(dir_path, filename) with open(write_file, 'w') as f: f.write(buff) except Exception as e: LOG.error("Error writing buffer to file!") raise e def read_buffer_from_file(self, filename): try: dir_path = os.path.dirname(os.path.realpath(__file__)) read_file = os.path.join(dir_path, filename) if os.path.exists(os.path.join(dir_path, read_file)): with open(read_file, 'r') as f: read_buffer = f.read() return read_buffer except Exception as e: LOG.error("Error reading buffer from file!") raise e def get_mr_enclave(self, msg3): try: msg3 = self.ffi.from_buffer(base64.b64decode(msg3)) mr_e = self.barbie_s.get_mr_e(msg3) #return self.ffi.string(mr_e) #return self.ffi.buffer(mr_e) return base64.b64encode(self.ffi.buffer(mr_e, 32)) except Exception as e: LOG.error("Error in retrieveing mr enclave") raise e def get_mr_signer(self, msg3): try: msg3 = self.ffi.from_buffer(base64.b64decode(msg3)) mr_s = self.barbie_s.get_mr_s(msg3) #return self.ffi.string(mr_s) #return self.ffi.buffer(mr_s) return base64.b64encode(self.ffi.buffer(mr_s, 32)) except Exception as e: LOG.error("Error in retrieveing mr signer") raise e def get_report_sha256(self, target_lib, msg3): try: msg3 = self.ffi.from_buffer(base64.b64decode(msg3)) sha256 = self.ffi.new("uint8_t []", 32) target_lib.get_report_sha256(msg3, sha256) return base64.b64encode(self.ffi.buffer(sha256)) except Exception as e: LOG.error("Error in calculating SHA256") raise e def test_legacy_client(self): try: #plain_secret = "my-private-secre" secret = "This-Is-My-Private-Secret" plain_secret = Secret(secret, len(secret)) enclave_id = self.init_enclave(self.barbie_s) #To simulate KEK of server side sealed_kek = self.generate_key(self.barbie_s, enclave_id, 16) enc_secret = self.encrypt(self.barbie_s, enclave_id, sealed_kek, plain_secret) r_secret = self.decrypt(self.barbie_s, enclave_id, sealed_kek, enc_secret) r_secret = base64.b64decode(r_secret) if r_secret == secret: print "Legacy Client : Secret Management done!" else: print "Legacy Client : Secret Management failed!" finally: self.destroy_enclave(self.barbie_s, enclave_id) def test_sgx_client_wo_sgx_hw(self, spid=None, crt_path=None): try: s_eid = self.init_enclave(self.barbie_s) plain_sk = Secret("", len("")) #Perform attestation ret, msg0 = self.gen_msg0(self.barbie_s, spid) p_ctxt, msg1 = self.gen_msg1(self.barbie_s, s_eid) print "gen_msg1 returned: " + msg1 ret, p_net_ctxt = self.proc_msg0(self.barbie_c, msg0, spid, False) msg2 = self.proc_msg1_gen_msg2(self.barbie_c, msg1, p_net_ctxt) print "send_msg1_recv_msg2 returned: " + msg2 msg3, crt, sig, resp_body = self.proc_msg2_gen_msg3(self.barbie_s, s_eid, msg2, p_ctxt, crt_path, False) print "proc_msg2_gen_msg3 returned: " + msg3 msg4 = self.legacy_proc_msg3_gen_msg4(self.barbie_c, msg3, p_net_ctxt, plain_sk , "sgx_wo_hw", crt_path, False) print "send_msg3_recv_msg4 returned: " + str(msg4) status, s_dh = self.get_dh_key(self.barbie_s, s_eid, msg4, p_ctxt) print "get_dh_key returned: " + str(status) proj_id, proj_id_len = self.get_project_id(self.barbie_s, s_eid, msg4, p_ctxt) s_sk = self.generate_key(self.barbie_s, s_eid, 16) plain_kek_len = 16 sealed_len = self.barbie_s.get_sealed_data_len( s_eid, 0, plain_kek_len) dh_sk = self.transport(self.barbie_s, s_eid, Secret(s_dh, sealed_len), s_sk ,None) plain_sk = self.get_sk(self.barbie_c, p_net_ctxt, dh_sk) #status, plain_sk = self.get_sk(self.barbie_c, p_net_ctxt, 16, dh_sk) #status, sk = self.proc_msg4(self.barbie_s, s_eid, msg4, p_ctxt) #sealed_sk = Secret(sk, sealed_len) #Perform kek provisioning kek = "yek etyb neetxis" plain_kek = Secret(kek, len(kek)) sk_kek = self.legacy_encrypt(self.barbie_c, plain_sk, plain_kek) kek = self.provision_kek(self.barbie_s, s_eid, s_sk, sk_kek, None) plain_kek_len = 16 sealed_len = self.barbie_s.get_sealed_data_len(s_eid, 0, plain_kek_len) sealed_kek = Secret(kek, sealed_len) kek_sk = self.transport(self.barbie_c, s_eid, sealed_kek, s_sk, proj_id) #Perform secret management secret = "my-private-secret" plain_secret = Secret(secret, len(secret)) sk_secret = self.legacy_encrypt(self.barbie_c, plain_sk, plain_secret) kek_secret = self.kek_encrypt(s_eid, kek_sk, sealed_kek, sk_secret, "sgx_wo_hw") rec = self.kek_decrypt(s_eid, kek_sk, sealed_kek, kek_secret, "sgx_wo_hw") if self.compare_secret(self.barbie_c, rec[40:], sk_secret[40:], plain_secret.length): print "SGX Aware Client Without SGX hardware : Secret Management done!" else: print "SGX Aware Cliwnt Without SGX hardware : Secret Management failed!" finally: self.destroy_enclave(self.barbie_s, s_eid)
class CVecEnv: """ An environment instance created by an EnvLib, uses the VecEnv interface. https://github.com/openai/baselines/blob/master/baselines/common/vec_env/__init__.py Args: num_envs: number of environments to create lib_dir: a folder containing either lib{name}.so (Linux), lib{name}.dylib (Mac), or {name}.dll (Windows) lib_name: name of the library (minus the lib part) c_func_defs: list of cdefs that are passed to FFI in order to define custom functions that can then be called with env.call_func() options: options to pass to the libenv_make() call for this environment debug: if set to True, check array data to make sure it matches the provided spaces reuse_arrays: reduce allocations by using the same numpy arrays for each reset(), step(), and render() call """ class C_Space: def __init__(self, name: str, is_discrete: bool, shape: tuple, dtype: type, limits: tuple) -> None: self.name = name self.is_discrete = is_discrete self.shape = shape self.dtype = dtype self.limits = limits def to_libenv_space(self, ffi, c_lib): c_space = ffi.new("struct libenv_space *") assert (len(self.name) < c_lib.LIBENV_MAX_NAME_LEN - 1), "length of space name is too long" c_space.name = self.name.encode("utf8") c_space.type = c_lib.LIBENV_SPACE_TYPE_DISCRETE if self.is_discrete else c_lib.LIBENV_SPACE_TYPE_BOX c_space.dtype = CVecEnv._var_to_libenv(ffi, c_lib, self.dtype) for i, dim in enumerate(self.shape): c_space.shape[i] = dim c_space.ndim = len(self.shape) if c_space.dtype == c_lib.LIBENV_DTYPE_UINT8: c_space.low.uint8 = self.limits[0] c_space.high.uint8 = self.limits[1] elif c_space.dtype == c_lib.LIBENV_DTYPE_INT32: c_space.low.int32 = self.limits[0] c_space.high.int32 = self.limits[1] elif c_space.dtype == c_lib.LIBENV_DTYPE_FLOAT32: c_space.low.float32 = self.limits[0] c_space.high.float32 = self.limits[1] else: assert False, "Unknown dtype! This should never happen!" return c_space def __init__( self, num_envs: int, lib_dir: str, lib_name: str = "env", c_func_defs: Optional[List[str]] = None, options: Optional[Dict] = None, debug: bool = False, reuse_arrays: bool = False, additional_info_spaces: list = None, additional_obs_spaces: list = None, ) -> None: self._debug = debug self._reuse_arrays = reuse_arrays if options is None: options = {} options = copy.deepcopy(options) if platform.system() == "Linux": lib_filename = f"lib{lib_name}.so" elif platform.system() == "Darwin": lib_filename = f"lib{lib_name}.dylib" elif platform.system() == "Windows": lib_filename = f"{lib_name}.dll" else: raise Exception(f"unrecognized platform {platform.system()}") if c_func_defs is None: c_func_defs = [] # load cdef for libenv.h libenv_cdef = "" with open(os.path.join(SCRIPT_DIR, "libenv.h")) as f: inside_cdef = False for line in f: if line.startswith("// BEGIN_CDEF"): inside_cdef = True elif line.startswith("// END_CDEF"): inside_cdef = False elif line.startswith("#if") or line.startswith("#endif"): continue if inside_cdef: line = line.replace("LIBENV_API", "") libenv_cdef += line self._ffi = FFI() self._ffi.cdef(libenv_cdef) for cdef in c_func_defs: self._ffi.cdef(cdef) self._lib_path = os.path.join(lib_dir, lib_filename) assert os.path.exists( self._lib_path), f"lib not found at {self._lib_path}" # unclear if this is necessary, but nice to not have symbols conflict if possible dlopen_flags = ( self._ffi.RTLD_NOW | self._ffi.RTLD_LOCAL # pylint: disable=no-member ) if platform.system() == "Linux": dlopen_flags |= self._ffi.RTLD_DEEPBIND # pylint: disable=no-member self._c_lib = self._ffi.dlopen(name=self._lib_path, flags=dlopen_flags) # dlclose will be called automatically when the library goes out of scope # https://cffi.readthedocs.io/en/latest/cdef.html#ffi-dlopen-loading-libraries-in-abi-mode # on mac os x, the library may not always be unloaded when you expect # https://developer.apple.com/videos/play/wwdc2017/413/?time=1776 # loading/unloading the library all the time can be slow # it may be useful to keep a reference to an environment (and thus the c_lib object) # to avoid this happening self._options = options self._state = STATE_NEEDS_RESET c_options, self._options_keepalives = self._convert_options( self._ffi, self._c_lib, options) self._c_env = self._c_lib.libenv_make(num_envs, c_options[0]) if additional_obs_spaces is not None: for space in additional_obs_spaces: print(f"adding obs space: {space}") self._c_lib.libenv_add_space( self._c_env, self._c_lib.LIBENV_SPACES_OBSERVATION, space.to_libenv_space(self._ffi, self._c_lib)) if additional_info_spaces is not None: for space in additional_info_spaces: print(f"adding info space: {space}") self._c_lib.libenv_add_space( self._c_env, self._c_lib.LIBENV_SPACES_INFO, space.to_libenv_space(self._ffi, self._c_lib)) self.reward_range = (float("-inf"), float("inf")) self.spec = None self.num_envs = num_envs self.observation_space = self._get_spaces( self._c_lib.LIBENV_SPACES_OBSERVATION) self._action_space = self._get_spaces(self._c_lib.LIBENV_SPACES_ACTION) self._info_space = self._get_spaces(self._c_lib.LIBENV_SPACES_INFO) self._render_space = self._get_spaces(self._c_lib.LIBENV_SPACES_RENDER) # allocate buffers self._observations, self._observation_buffers = self._allocate_dict_space( self.num_envs, self.observation_space) # we only use dict spaces for consistency, but action is always a single space # the private version is the dict space, while the public version is a single space assert len(self._action_space.spaces ) == 1, "action space can only be 1 element" assert list(self._action_space.spaces.keys())[0] == ACTION_KEY self.action_space = self._action_space.spaces[ACTION_KEY] dict_actions, self._action_buffers = self._allocate_dict_space( self.num_envs, self._action_space) self._actions = dict_actions[ACTION_KEY] self._renders, self._renders_buffers = self._allocate_dict_space( self.num_envs, self._render_space) self.metadata = { "render.modes": list(self._render_space.spaces.keys()) } self._infos, self._infos_buffers = self._allocate_dict_space( self.num_envs, self._info_space) self._rews, self._rews_buffer = self._allocate_array( self.num_envs, np.dtype("float32")) self._dones, self._dones_buffer = self._allocate_array( self.num_envs, np.dtype("bool")) assert np.dtype("bool").itemsize == 1 c_step = self._ffi.new("struct libenv_step *") c_step.obs = self._observation_buffers # cast the pointer to the buffer to avoid a warning from cffi c_step.rews = self._ffi.cast( self._ffi.typeof(c_step.rews).cname, self._rews_buffer) c_step.dones = self._ffi.cast( self._ffi.typeof(c_step.dones).cname, self._dones_buffer) c_step.infos = self._infos_buffers self._c_step = c_step self.closed = False self.viewer = None def __repr__(self): return f"<CVecEnv lib_path={self._lib_path} options={self._options}>" def _numpy_aligned(self, shape, dtype, align=64): """ Allocate an aligned numpy array, based on https://github.com/numpy/numpy/issues/5312#issuecomment-299533915 """ n_bytes = np.prod(shape) * dtype.itemsize arr = np.zeros(n_bytes + (align - 1), dtype=np.uint8) data_align = arr.ctypes.data % align offset = 0 if data_align == 0 else (align - data_align) view = arr[offset:offset + n_bytes].view(dtype) return view.reshape(shape) def _allocate_dict_space( self, num_envs: int, dict_space: gym.spaces.Dict ) -> Tuple[collections.OrderedDict, Any]: """ Allocate arrays for a space, returns an OrderedDict of numpy arrays along with a backing bytearray """ result = collections.OrderedDict() # type: collections.OrderedDict length = len(dict_space.spaces) * num_envs buffers = self._ffi.new(f"void *[{length}]") for space_idx, (name, space) in enumerate(dict_space.spaces.items()): actual_shape = (num_envs, ) + space.shape arr = self._numpy_aligned(shape=actual_shape, dtype=space.dtype) result[name] = arr for env_idx in range(num_envs): buffers[space_idx * num_envs + env_idx] = self._ffi.from_buffer(arr.data[env_idx:]) return result, buffers def _allocate_array(self, num_envs: int, dtype: np.dtype) -> Tuple[np.ndarray, Any]: arr = self._numpy_aligned(shape=(num_envs, ), dtype=dtype) return arr, self._ffi.from_buffer(arr.data) @staticmethod def _convert_options(ffi: Any, c_lib: Any, options: Dict) -> Any: """ Convert a dictionary to libenv_options """ keepalives = ( [] ) # add variables to here to keep them alive after this function returns c_options = ffi.new("struct libenv_options *") c_option_array = ffi.new("struct libenv_option[%d]" % len(options)) for i, (k, v) in enumerate(options.items()): name = str(k).encode("utf8") assert (len(name) < c_lib.LIBENV_MAX_NAME_LEN - 1), "length of options key is too long" if isinstance(v, bytes): c_data = ffi.new("char[]", v) dtype = c_lib.LIBENV_DTYPE_UINT8 count = len(v) elif isinstance(v, str): c_data = ffi.new("char[]", v.encode("utf8")) dtype = c_lib.LIBENV_DTYPE_UINT8 count = len(v) elif isinstance(v, bool): c_data = ffi.new("uint8_t*", v) dtype = c_lib.LIBENV_DTYPE_UINT8 count = 1 elif isinstance(v, int): assert -2**31 < v < 2**31 c_data = ffi.new("int32_t*", v) dtype = c_lib.LIBENV_DTYPE_INT32 count = 1 elif isinstance(v, float): c_data = ffi.new("float*", v) dtype = c_lib.LIBENV_DTYPE_FLOAT32 count = 1 elif isinstance(v, np.ndarray): c_data = ffi.new("char[]", v.tobytes()) if v.dtype == np.dtype("uint8"): dtype = c_lib.LIBENV_DTYPE_UINT8 elif v.dtype == np.dtype("int32"): dtype = c_lib.LIBENV_DTYPE_INT32 elif v.dtype == np.dtype("float32"): dtype = c_lib.LIBENV_DTYPE_FLOAT32 else: assert False, f"unsupported type {v.dtype}" count = v.size else: assert False, f"unsupported value {v} for option {k}" c_option_array[i].name = name c_option_array[i].dtype = dtype c_option_array[i].count = count c_option_array[i].data = c_data keepalives.append(c_data) keepalives.append(c_option_array) c_options.items = c_option_array c_options.count = len(options) return c_options, keepalives @staticmethod def _check_arrays(arrays: Dict[str, np.ndarray], num_envs: int, dict_space: gym.spaces.Dict) -> None: """ Make sure each array in arrays matches the given dict_space """ for name, space in dict_space.spaces.items(): arr = arrays[name] assert isinstance(arr, np.ndarray) expected_shape = (num_envs, ) + space.shape assert ( arr.shape == expected_shape ), f"array is invalid shape expected={expected_shape} received={arr.shape}" assert ( arr.dtype == space.dtype ), f"array has invalid dtype expected={space.dtype} received={arr.dtype}" if isinstance(space, gym.spaces.Box): # we only support single low/high values assert (len(np.unique(space.low)) == 1 and len(np.unique(space.high)) == 1) low = np.min(space.low) high = np.max(space.high) elif isinstance(space, gym.spaces.Discrete): low = 0 high = space.n - 1 else: assert False, "unrecognized space type" assert np.min(arr) >= low, ( '"%s" has values below space lower bound, %f < %f' % (name, np.min(arr), low)) assert np.max(arr) <= high, ( '"%s" has values above space upper bound, %f > %f' % (name, np.max(arr), high)) def _maybe_copy_ndarray(self, obj: np.ndarray) -> np.ndarray: """ Copy a single numpy array if reuse_arrays is False, otherwise just return the object """ if self._reuse_arrays: return obj else: return obj.copy() def _maybe_copy_dict(self, obj: Dict[str, Any]) -> Dict[str, Any]: """ Copy a list of dicts of numpy arrays if reuse_arrays is False, otherwise just return the object """ if self._reuse_arrays: return obj else: result = {} for name, arr in obj.items(): result[name] = arr.copy() return result def _get_spaces(self, c_name: Any) -> gym.spaces.Dict: """ Get a c space and convert to a gym space """ count = self._c_lib.libenv_get_spaces(self._c_env, c_name, self._ffi.NULL) if count == 0: return gym.spaces.Dict([]) c_spaces = self._ffi.new("struct libenv_space[%d]" % count) self._c_lib.libenv_get_spaces(self._c_env, c_name, c_spaces) # convert to gym spaces spaces = [] for i in range(count): c_space = c_spaces[i] name = self._ffi.string(c_space.name).decode("utf8") shape = [] for j in range(c_space.ndim): shape.append(c_space.shape[j]) if c_space.dtype == self._c_lib.LIBENV_DTYPE_UINT8: dtype = np.dtype("uint8") low = c_space.low.uint8 high = c_space.high.uint8 elif c_space.dtype == self._c_lib.LIBENV_DTYPE_INT32: dtype = np.dtype("int32") low = c_space.low.int32 high = c_space.high.int32 elif c_space.dtype == self._c_lib.LIBENV_DTYPE_FLOAT32: dtype = np.dtype("float32") low = c_space.low.float32 high = c_space.high.float32 else: assert False, "unknown dtype" if c_space.type == self._c_lib.LIBENV_SPACE_TYPE_BOX: space = gym.spaces.Box(shape=shape, low=low, high=high, dtype=dtype) elif c_space.type == self._c_lib.LIBENV_SPACE_TYPE_DISCRETE: assert shape == [1], "discrete space must have scalar shape" assert low == 0 and high > 0, "discrete low/high bounds are incorrect" space = gym.spaces.Discrete(n=high + 1) space.dtype = dtype else: assert False, "unknown space type" spaces.append((name, space)) # c spaces are aways a single-layer Dict space return gym.spaces.Dict(spaces) def reset(self) -> Dict[str, np.ndarray]: """ Reset the environment and return the first observation """ self._state = STATE_WAIT_ACT self._c_lib.libenv_reset(self._c_env, self._c_step) return self._maybe_copy_dict(self._observations) def step_async(self, actions: np.ndarray) -> None: """ Asynchronously take an action in the environment, doesn't return anything. """ assert self._state == STATE_WAIT_ACT self._state = STATE_WAIT_WAIT if self._debug: self._check_arrays({"action": actions}, self.num_envs, self._action_space) self._actions[:] = actions self._c_lib.libenv_step_async(self._c_env, self._action_buffers, self._c_step) def step_wait( self ) -> Tuple[Dict[str, np.ndarray], np.ndarray, np.ndarray, List[Dict[str, Any]]]: """ Step the environment, returns (obs, rews, dones, infos) """ assert self._state == STATE_WAIT_WAIT self._state = STATE_WAIT_ACT self._c_lib.libenv_step_wait(self._c_env) if self._debug: self._check_arrays(self._observations, self.num_envs, self.observation_space) infos = [{} for _ in range(self.num_envs)] # type: List[Dict] for key, values in self._infos.items(): for env_idx in range(self.num_envs): v = values[env_idx] if v.shape == (1, ): # extract scalar values v = v[0] infos[env_idx][key] = v return ( self._maybe_copy_dict(self._observations), self._maybe_copy_ndarray(self._rews), self._maybe_copy_ndarray(self._dones), infos, ) def step( self, actions: np.ndarray ) -> Tuple[Dict[str, np.ndarray], np.ndarray, np.ndarray, List[Dict[str, Any]]]: """ Step the environment, combines step_async() and step_wait() and makes this interface mostly compatible with the normal gym interface """ self.step_async(actions) return self.step_wait() def render(self, mode: str = "human") -> Union[bool, np.ndarray]: """ Render the environment. mode='human' tells the environment to render in some human visible way and returns True if the user user visible window created by the environment is still open Other modes are up to the environment, but end up returning a numpy array of some kind that will be tiled as if it were an image by this code. Call get_images() instead if that is not the behavior you want. """ if (mode == "human" and "human" not in self.metadata["render.modes"] and "rgb_array" in self.metadata["render.modes"]): # fallback human mode viewer = self.get_viewer() self._render(mode="rgb_array") images = self._maybe_copy_ndarray(self._renders["rgb_array"]) viewer.imshow(self._tile_images(images)) return viewer.isopen isopen = self._render(mode=mode) if mode == "human": return isopen else: images = self._maybe_copy_ndarray(self._renders[mode]) return self._tile_images(images) def _render(self, mode) -> Union[bool, np.ndarray]: """Internal render method, returns is_open and updates the buffers in self._render""" assert self._state == STATE_WAIT_ACT assert mode in self.metadata["render.modes"], "unsupported render mode" c_mode = self._ffi.new("char[]", mode.encode("utf8")) # only pass the render buffers for the selected mode space_idx = list(self._render_space.spaces.keys()).index(mode) render_buffers = self._renders_buffers[space_idx * self.num_envs:(space_idx + 1) * self.num_envs] return self._c_lib.libenv_render(self._c_env, c_mode, render_buffers) def _tile_images(self, images: np.ndarray) -> np.ndarray: """Tile a set of NHWC images""" num_images, height, width, chans = images.shape width_images = int(np.ceil(np.sqrt(num_images))) height_images = int(np.ceil(float(num_images) / width_images)) result = np.zeros( (height_images * height, width_images * width, chans), dtype=np.uint8) for col in range(width_images): for row in range(height_images): idx = row * width_images + col if idx >= len(images): continue result[row * height:(row + 1) * height, col * width:(col + 1) * width, :, ] = images[idx] return result @staticmethod def _var_to_libenv(ffi, c_lib, var): _t, _v = (var, None) if (type(var) == type) else (type(var), var) print(f"hmm... {_t} {_v}") if issubclass(_t, bytes): dtype = c_lib.LIBENV_DTYPE_UINT8 if _v is None: return dtype return dtype, ffi.new("char[]", _v), len(_v) if issubclass(_t, str): dtype = c_lib.LIBENV_DTYPE_UINT8 if _v is None: return dtype return dtype, ffi.new("char[]", _v.encode("utf8")), len(_v) if issubclass(_t, bool): dtype = c_lib.LIBENV_DTYPE_UINT8 if _v is None: return dtype return dtype, ffi.new("uint8_t*", _v), 1 if issubclass(_t, int): dtype = c_lib.LIBENV_DTYPE_INT32 if _v is None: return dtype assert -2**31 < _v < 2**31 return dtype, ffi.new("int32_t*", _v), 1 if issubclass(_t, float): dtype = c_lib.LIBENV_DTYPE_FLOAT32 if _v is None: return dtype return dtype, ffi.new("float*", _v), 1 if issubclass(_t, np.ndarray): assert _v is not None, f"{_t} can have different dtypes. Use a specific instance." if _v.dtype == np.dtype("uint8"): dtype = c_lib.LIBENV_DTYPE_UINT8 elif _v.dtype == np.dtype("int32"): dtype = c_lib.LIBENV_DTYPE_INT32 elif _v.dtype == np.dtype("float32"): dtype = c_lib.LIBENV_DTYPE_FLOAT32 else: assert False, f"unsupported type {_v.dtype}" return dtype, ffi.new("char[]", _v.tobytes()), _v.size assert False, f"unsupported value {var}" @staticmethod def _var_from_libenv(): pass def get_images(self) -> np.ndarray: """ Get rendered images from the environments, if supported. The returned array's shape will be (num_envs, height, width, num_colors) """ self._render(mode="rgb_array") return self._maybe_copy_ndarray(self._renders["rgb_array"]) def get_viewer(self): """Get the viewer instance being used by render()""" if self.viewer is None: from gym.envs.classic_control import rendering self.viewer = rendering.SimpleImageViewer() return self.viewer def close_extras(self): """ Override this to close environment-specific resources without having to override close()' This method is guaranteed to only be called once, unlike close() """ def close(self) -> None: """Close the environment and free any resources associated with it""" if not hasattr(self, "closed") or self.closed: return self.closed = True self._c_lib.libenv_close(self._c_env) self._c_lib = None self._ffi = None self._options_keepalives = None if self.viewer is not None: self.viewer.close() self.close_extras() def call_func(self, name: str, *args: Any) -> Any: """ Call a function of the libenv declared in c_func_defs """ return getattr(self._c_lib, name)(*args) @property def unwrapped(self): if hasattr(self, "venv"): return self.venv.unwrapped # pylint: disable=no-member else: return self def seed(self, seed=None): """ Seed the environment, this isn't used by VecEnvs but is part of the Gym Env API """ def __del__(self): self.close()
class CTC(object): """ """ def __init__(self, on_device='cpu', blank_label=0): libpath = get_ctc_lib() self.ffi = FFI() self.ffi.cdef(ctc_header()) self.ctclib = self.ffi.dlopen(libpath) supported_devices = ['cpu', 'gpu'] if on_device not in supported_devices: print("the requested device {} is not supported".format(on_device), file=sys.stderr) sys.exit(1) assign_device = 0 if on_device is 'cpu' else 1 self.options = self.ffi.new('ctcOptions*', { "loc": assign_device, "blank_label": blank_label })[0] self.size_in_bytes = self.ffi.new("size_t*") self.nout = None self.bsz = None def get_buf_size(self, ptr_to_buf): return self.ffi.sizeof( self.ffi.getctype(self.ffi.typeof(ptr_to_buf).item)) def buf_ref_from_array(self, arr): return self.ffi.from_buffer( self.ffi.buffer(self.ffi.cast('void*', arr.ptr), arr.nbytes)) def buf_ref_from_ptr(self, ptr, size): return self.ffi.from_buffer(self.ffi.buffer(ptr, size)) def get_gpu_workspace_size(self, lbl_lens, utt_lens, nout, bsz): self.nout = nout self.bsz = bsz _lbl_lens = self.ffi.cast("int*", lbl_lens.ravel().ctypes.data) _utt_lens = self.ffi.cast("int*", utt_lens.ravel().ctypes.data) status = self.ctclib.get_workspace_size(_lbl_lens, _utt_lens, self.nout, self.bsz, self.options, self.size_in_bytes) assert status is 0, "get_workspace_size() in warp-ctc failed" return self.size_in_bytes[0] def bind_to_gpu(self, acts, grads, lbls, lbl_lens, utt_lens, costs, workspace, scratch_size, stream): if stream is None: stream_ptr = self.ffi.cast('void*', 0) stream_buf_size = self.ffi.sizeof(self.ffi.new_handle(stream)) stream_buf = self.buf_ref_from_ptr(stream_ptr, stream_buf_size) else: stream_buf = self.ffi.cast("void*", stream.handle) self.options.stream = stream_buf flat_dims = np.prod(acts.shape) assert np.prod(grads.shape) == flat_dims acts_buf = self.ffi.cast("float*", self.buf_ref_from_array(acts)) grads_buf = self.ffi.cast("float*", self.buf_ref_from_array(grads)) costs_buf = self.ffi.cast("float*", self.buf_ref_from_array(costs)) warp_grads_buf_size = flat_dims * self.get_buf_size(grads_buf) warp_costs_buf_size = self.bsz * self.get_buf_size(costs_buf) warp_labels = self.ffi.cast("int*", lbls.ravel().ctypes.data) warp_label_lens = self.ffi.cast("int*", lbl_lens.ravel().ctypes.data) warp_input_lens = self.ffi.cast("int*", utt_lens.ravel().ctypes.data) workspace_buf = self.buf_ref_from_ptr( self.ffi.cast('void*', workspace), int(scratch_size)) ctc_status = self.ctclib.compute_ctc_loss(acts_buf, grads_buf, warp_labels, warp_label_lens, warp_input_lens, self.nout, self.bsz, costs_buf, workspace_buf, self.options) assert ctc_status is 0, "warp-ctc run failed" def bind_to_cpu(self, acts, lbls, utt_lens, lbl_lens, grads, costs, n_threads=1): self.options.num_threads = n_threads _, self.bsz, self.nout = acts.shape flat_dims = np.prod(acts.shape) assert np.prod(grads.shape) == flat_dims acts_buf = self.ffi.cast("float*", acts.ctypes.data) grads_buf = self.ffi.cast("float*", grads.ctypes.data) costs_buf = self.ffi.cast("float*", costs.ctypes.data) warp_grads_buf_size = flat_dims * self.get_buf_size(grads_buf) warp_costs_buf_size = self.bsz * self.get_buf_size(costs_buf) warp_labels = self.ffi.cast("int*", lbls.ravel().ctypes.data) warp_label_lens = self.ffi.cast("int*", lbl_lens.ravel().ctypes.data) warp_input_lens = self.ffi.cast("int*", utt_lens.ravel().ctypes.data) status = self.ctclib.get_workspace_size(warp_label_lens, warp_input_lens, self.nout, self.bsz, self.options, self.size_in_bytes) assert status is 0, "get_workspace_size() in warp-ctc failed" # TODO: workspace is a variable size buffer whose size is # determined during each call, so we can't initialize ahead # of time. Can we avoid this? workspace = self.ffi.new("char[]", self.size_in_bytes[0]) ctc_status = self.ctclib.compute_ctc_loss(acts_buf, grads_buf, warp_labels, warp_label_lens, warp_input_lens, self.nout, self.bsz, costs_buf, workspace, self.options) # transfer grads and costs back without copying self.ffi.memmove(grads, grads_buf, warp_grads_buf_size) grads = grads.reshape((acts.shape)) self.ffi.memmove(costs, costs_buf, warp_costs_buf_size) assert ctc_status is 0, "warp-ctc run failed"
def runKernel(opt): count = 1024 DATA_SIZE = sizeof(c_int64) * count ffi = FFI() # create the FFI obj boHandle1 = xclAllocBO(opt.handle, DATA_SIZE, xclBOKind.XCL_BO_DEVICE_RAM, opt.first_mem) boHandle2 = xclAllocBO(opt.handle, DATA_SIZE, xclBOKind.XCL_BO_DEVICE_RAM, opt.first_mem) bo1 = xclMapBO(opt.handle, boHandle1, True) bo2 = xclMapBO(opt.handle, boHandle2, True) bo1_fp = ffi.cast("FILE *", bo1) bo2_fp = ffi.cast("FILE *", bo2) # bo1 bo1_arr = np.array([0x586C0C6C for _ in range(count)]) ffi.memmove(bo1_fp, ffi.from_buffer(bo1_arr), count * 5) # bo2 int_arr = np.array([i * i for i in range(count)]) bo2_arr = np.array(map(str, int_arr.astype(int))) ffi.memmove(bo2_fp, ffi.from_buffer(bo2_arr), count * 7) # bufReference int_arr_2 = np.array([i * i + i * 16 for i in range(count)]) str_arr = np.array(map(str, int_arr_2)) buf = ffi.from_buffer(str_arr) bufReference = ''.join(buf) if xclSyncBO(opt.handle, boHandle1, xclBOSyncDirection.XCL_BO_SYNC_BO_TO_DEVICE, DATA_SIZE, 0): return 1 if xclSyncBO(opt.handle, boHandle2, xclBOSyncDirection.XCL_BO_SYNC_BO_TO_DEVICE, DATA_SIZE, 0): return 1 p = xclBOProperties() bo1devAddr = p.paddr if not (xclGetBOProperties(opt.handle, boHandle1, p)) else -1 bo2devAddr = p.paddr if not (xclGetBOProperties(opt.handle, boHandle2, p)) else -1 if bo1devAddr is -1 or bo2devAddr is -1: return 1 # Allocate the exec_bo execHandle = xclAllocBO(opt.handle, DATA_SIZE, xclBOKind.XCL_BO_SHARED_VIRTUAL, (1 << 31)) execData = xclMapBO(opt.handle, execHandle, True) # returns mmap() c_f = ffi.cast("FILE *", execData) if execData is ffi.NULL: print("execData is NULL") print("Construct the exe buf cmd to configure FPGA") ecmd = ert_configure_cmd() ecmd.m_uert.m_cmd_struct.state = 1 # ERT_CMD_STATE_NEW ecmd.m_uert.m_cmd_struct.opcode = 2 # ERT_CONFIGURE ecmd.slot_size = 1024 ecmd.num_cus = 1 ecmd.cu_shift = 16 ecmd.cu_base_addr = opt.cu_base_addr ecmd.m_features.ert = opt.ert if opt.ert: ecmd.m_features.cu_dma = 1 ecmd.m_features.cu_isr = 1 # CU -> base address mapping ecmd.data[0] = opt.cu_base_addr ecmd.m_uert.m_cmd_struct.count = 5 + ecmd.num_cus sz = sizeof(ert_configure_cmd) ffi.memmove(c_f, ecmd, sz) print("Send the exec command and configure FPGA (ERT)") # Send the command. if xclExecBuf(opt.handle, execHandle): print("Unable to issue xclExecBuf") return 1 print("Wait until the command finish") while xclExecWait(opt.handle, 1000) != 0: print(".") print("Construct the exec command to run the kernel on FPGA") print( "Due to the 1D OpenCL group size, the kernel must be launched %d times" ) % count # construct the exec buffer cmd to start the kernel for id in range(count): start_cmd = ert_start_kernel_cmd() rsz = XSIMPLE_CONTROL_ADDR_FOO_DATA / 4 + 2 # regmap array size new_data = ((start_cmd.data._type_) * rsz)() start_cmd.m_uert.m_start_cmd_struct.state = 1 # ERT_CMD_STATE_NEW start_cmd.m_uert.m_start_cmd_struct.opcode = 0 # ERT_START_CU start_cmd.m_uert.m_start_cmd_struct.count = 1 + rsz start_cmd.cu_mask = 0x1 new_data[XSIMPLE_CONTROL_ADDR_AP_CTRL] = 0x0 new_data[XSIMPLE_CONTROL_ADDR_GROUP_ID_X_DATA / 4] = id new_data[XSIMPLE_CONTROL_ADDR_S1_DATA / 4] = bo1devAddr & 0xFFFFFFFF # output new_data[XSIMPLE_CONTROL_ADDR_S2_DATA / 4] = bo2devAddr & 0xFFFFFFFF # input new_data[XSIMPLE_CONTROL_ADDR_FOO_DATA / 4] = 0x10 # foo ffi.memmove(c_f, start_cmd, 2 * sizeof(c_uint32)) tmp_buf = ffi.buffer( c_f, 2 * sizeof(c_uint32) + (len(new_data) * sizeof(c_uint32))) data_ptr = ffi.from_buffer(tmp_buf) ffi.memmove(data_ptr + 2 * sizeof(c_uint32), new_data, len(new_data) * sizeof(c_uint32)) if xclExecBuf(opt.handle, execHandle): print("Unable to issue xclExecBuf") return 1 print("Wait until the command finish") while xclExecWait(opt.handle, 100) != 0: print("reentering wait... \n") # get the output xclSyncBO print("Get the output data from the device") if xclSyncBO(opt.handle, boHandle1, xclBOSyncDirection.XCL_BO_SYNC_BO_FROM_DEVICE, DATA_SIZE, 0): return 1 rd_buf = ffi.buffer(bo1_fp, count * 7) print("RESULT: ") # print(rd_buf[:] + "\n") if bufReference != rd_buf[:]: print("FAILED TEST") print("Value read back does not match value written") sys.exit()
class TestLocationdLib(unittest.TestCase): def setUp(self): header = '''typedef ...* Localizer_t; Localizer_t localizer_init(); void localizer_get_message_bytes(Localizer_t localizer, uint64_t logMonoTime, bool inputsOK, bool sensorsOK, bool gpsOK, char *buff, size_t buff_size); void localizer_handle_msg_bytes(Localizer_t localizer, const char *data, size_t size);''' self.ffi = FFI() self.ffi.cdef(header) self.lib = self.ffi.dlopen(LIBLOCATIOND_PATH) self.localizer = self.lib.localizer_init() self.buff_size = 2048 self.msg_buff = self.ffi.new(f'char[{self.buff_size}]') def localizer_handle_msg(self, msg_builder): bytstr = msg_builder.to_bytes() self.lib.localizer_handle_msg_bytes(self.localizer, self.ffi.from_buffer(bytstr), len(bytstr)) def localizer_get_msg(self, t=0, inputsOK=True, sensorsOK=True, gpsOK=True): self.lib.localizer_get_message_bytes( self.localizer, t, inputsOK, sensorsOK, gpsOK, self.ffi.addressof(self.msg_buff, 0), self.buff_size) return log.Event.from_bytes(self.ffi.buffer(self.msg_buff), nesting_limit=self.buff_size // 8) def test_liblocalizer(self): msg = messaging.new_message('liveCalibration') msg.liveCalibration.validBlocks = random.randint(1, 10) msg.liveCalibration.rpyCalib = [random.random() for _ in range(3)] self.localizer_handle_msg(msg) liveloc = self.localizer_get_msg() self.assertTrue(liveloc is not None) def test_device_fell(self): msg = messaging.new_message('sensorEvents', 1) msg.sensorEvents[0].sensor = 1 msg.sensorEvents[0].type = 1 msg.sensorEvents[0].init('acceleration') msg.sensorEvents[0].acceleration.v = [10.0, 0.0, 0.0] # zero with gravity self.localizer_handle_msg(msg) ret = self.localizer_get_msg() self.assertTrue(ret.liveLocationKalman.deviceStable) msg = messaging.new_message('sensorEvents', 1) msg.sensorEvents[0].sensor = 1 msg.sensorEvents[0].type = 1 msg.sensorEvents[0].init('acceleration') msg.sensorEvents[0].acceleration.v = [50.1, 0.0, 0.0] # more than 40 m/s**2 self.localizer_handle_msg(msg) ret = self.localizer_get_msg() self.assertFalse(ret.liveLocationKalman.deviceStable) def test_posenet_spike(self): for _ in range(SENSOR_DECIMATION): msg = messaging.new_message('carState') msg.carState.vEgo = 6.0 # more than 5 m/s self.localizer_handle_msg(msg) ret = self.localizer_get_msg() self.assertTrue(ret.liveLocationKalman.posenetOK) for _ in range(20 * VISION_DECIMATION): # size of hist_old msg = messaging.new_message('cameraOdometry') msg.cameraOdometry.rot = [0.0, 0.0, 0.0] msg.cameraOdometry.rotStd = [0.0, 0.0, 0.0] msg.cameraOdometry.trans = [0.0, 0.0, 0.0] msg.cameraOdometry.transStd = [2.0, 0.0, 0.0] self.localizer_handle_msg(msg) for _ in range(20 * VISION_DECIMATION): # size of hist_new msg = messaging.new_message('cameraOdometry') msg.cameraOdometry.rot = [0.0, 0.0, 0.0] msg.cameraOdometry.rotStd = [0.0, 0.0, 0.0] msg.cameraOdometry.trans = [0.0, 0.0, 0.0] msg.cameraOdometry.transStd = [8.1, 0.0, 0.0] # more than 4 times larger self.localizer_handle_msg(msg) ret = self.localizer_get_msg() self.assertFalse(ret.liveLocationKalman.posenetOK)
class cv2pynq(): MAX_WIDTH = 800 MAX_HEIGHT = 600 def __init__(self, load_overlay=True): self.bitstream_name = None self.bitstream_name = "imgfilter.bit" self.bitstream_path = os.path.join(self.bitstream_name) self.ol = Overlay(self.bitstream_path) self.ol.download() self.ol.reset() self.xlnk = Xlnk() self.partitions = 10 #split the cma into partitions for pipelined transfer self.cmaPartitionLen = self.MAX_HEIGHT * self.MAX_WIDTH / self.partitions self.listOfcma = [ self.xlnk.cma_array(shape=(int(self.MAX_HEIGHT / self.partitions), self.MAX_WIDTH), dtype=np.uint8) for i in range(self.partitions) ] self.filter2d = self.ol self.dmaOut = self.filter2d.axi_dma_0.sendchannel self.dmaIn = self.filter2d.axi_dma_0.recvchannel self.dmaOut.stop() self.dmaIn.stop() self.dmaIn.start() self.dmaOut.start() self.filter2DType = -1 # filter types: SobelX=0 self.ffi = FFI() self.f2D = self.filter2d.filter2D_hls_0 self.f2D.reset() self.cmaBuffer_0 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT, self.MAX_WIDTH), dtype=np.uint8) self.cmaBuffer0 = self.cmaBuffer_0.view(self.ContiguousArrayCv2pynq) self.cmaBuffer0.init(self.cmaBuffer_0) self.cmaBuffer_1 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT, self.MAX_WIDTH), dtype=np.uint8) self.cmaBuffer1 = self.cmaBuffer_1.view(self.ContiguousArrayCv2pynq) self.cmaBuffer1.init(self.cmaBuffer_1) self.cmaBuffer_2 = self.xlnk.cma_array( shape=(self.MAX_HEIGHT * 4, self.MAX_WIDTH), dtype=np.uint8) # *4 for CornerHarris return self.cmaBuffer2 = self.cmaBuffer_2.view(self.ContiguousArrayCv2pynq) self.cmaBuffer2.init(self.cmaBuffer_2) def close(self): self.cmaBuffer_0.close() self.cmaBuffer_1.close() self.cmaBuffer_2.close() for cma in self.listOfcma: cma.close() def copyNto(self, dst, src, N): dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst)) srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src)) self.ffi.memmove(dstPtr, srcPtr, N) def copyNtoOff(self, dst, src, N, dstOffset, srcOffset): dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst)) srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src)) dstPtr += dstOffset srcPtr += srcOffset self.ffi.memmove(dstPtr, srcPtr, N) def filter2D(self, src, dst): if dst is None: self.cmaBuffer1.nbytes = src.nbytes elif hasattr(src, 'physical_address') and hasattr( dst, 'physical_address'): self.dmaIn.transfer(dst) self.dmaOut.transfer(src) self.dmaIn.wait() return dst if hasattr(src, 'physical_address'): self.dmaIn.transfer(self.cmaBuffer1) self.dmaOut.transfer(src) self.dmaIn.wait() else: #pipeline the copy to contiguous memory and filter calculation in hardware if src.nbytes < 184800: #440x420 self.partitions = 1 elif src.nbytes < 180000: #600x300 self.partitions = 2 elif src.nbytes < 231200: #680x340 self.partitions = 4 else: self.partitions = 8 self.cmaBuffer1.nbytes = src.nbytes self.dmaIn.transfer(self.cmaBuffer1) chunks_len = int(src.nbytes / (self.partitions)) self.cmaBuffer0.nbytes = chunks_len self.cmaBuffer2.nbytes = chunks_len self.copyNto(src, self.cmaBuffer0, chunks_len) for i in range(1, self.partitions): if i % 2 == 1: while not self.dmaOut.idle and not self.dmaOut._first_transfer: pass self.dmaOut.transfer(self.cmaBuffer0) self.copyNtoOff(src, self.cmaBuffer2, chunks_len, i * chunks_len, 0) else: while not self.dmaOut.idle and not self.dmaOut._first_transfer: pass self.dmaOut.transfer(self.cmaBuffer2) self.copyNtoOff(src, self.cmaBuffer0, chunks_len, i * chunks_len, 0) while not self.dmaOut.idle and not self.dmaOut._first_transfer: pass self.dmaOut.transfer(self.cmaBuffer2) rest = src.nbytes % self.partitions if rest != 0: #cleanup any remaining data and send it to HW self.copyNtoOff(src, self.cmaBuffer0, chunks_len, self.partitions * chunks_len, 0) while not self.dmaOut.idle and not self.dmaOut._first_transfer: pass self.dmaOut.transfer(self.cmaBuffer0) self.dmaIn.wait() ret = np.ndarray(src.shape, src.dtype) self.copyNto(ret, self.cmaBuffer1, ret.nbytes) return ret class ContiguousArrayCv2pynq(ContiguousArray): def init(self, cmaArray): self._nbytes = cmaArray.nbytes self.physical_address = cmaArray.physical_address self.cacheable = cmaArray.cacheable # overwrite access to nbytes with own function @property def nbytes(self): return self._nbytes @nbytes.setter def nbytes(self, value): self._nbytes = value def Sobel(self, src, ddepth, dx, dy, dst, ksize): if (ksize == 3): self.filter2DType = 0 self.f2D.rows = src.shape[0] self.f2D.columns = src.shape[1] self.f2D.channels = 1 self.f2D.r1 = 0x000100ff #[-1 0 1] self.f2D.r2 = 0x000200fe #[-2 0 2] self.f2D.r3 = 0x000100ff #[-1 0 1] self.f2D.start() return self.filter2D(src, dst) def Sobel1(self, src, ddepth, dx, dy, dst, ksize): if (ksize == 3): if self.filter2DType != 1: self.filter2DType = 1 self.f2D.rows = src.shape[0] self.f2D.columns = src.shape[1] self.f2D.channels = 1 self.f2D.r1 = 0x00fffeff #[-1 -2 -1] self.f2D.r2 = 0x00000000 #[ 0 0 0] self.f2D.r3 = 0x00010201 #[ 1 2 1] self.f2D.start() return self.filter2D(src, dst)