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
Exemple #2
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]
Exemple #3
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]
Exemple #4
0
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]
Exemple #5
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()
    }
Exemple #8
0
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
Exemple #9
0
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
Exemple #10
0
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
Exemple #12
0
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
Exemple #13
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
Exemple #14
0
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)
Exemple #15
0
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)
Exemple #16
0
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
Exemple #18
0
                                               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)
Exemple #19
0
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
Exemple #20
0
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()
Exemple #22
0
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)
Exemple #23
0
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()
Exemple #24
0
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"
Exemple #25
0
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()
Exemple #26
0
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)