Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
56 benedikt93 1
#!/usr/bin/env python
2
#
3
#
171 farthen 4
#    Copyright 2010 TheSeven, benedikt93, Farthen
56 benedikt93 5
#
6
#
7
#    This file is part of emBIOS.
8
#
9
#    emBIOS is free software: you can redistribute it and/or
10
#    modify it under the terms of the GNU General Public License as
11
#    published by the Free Software Foundation, either version 2 of the
12
#    License, or (at your option) any later version.
13
#
14
#    emBIOS is distributed in the hope that it will be useful,
15
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
#    See the GNU General Public License for more details.
18
#
19
#    You should have received a copy of the GNU General Public License
20
#    along with emBIOS.  If not, see <http://www.gnu.org/licenses/>.
21
#
22
#
23
 
24
import sys
25
import struct
171 farthen 26
import usb.core
27
import libembiosdata
56 benedikt93 28
 
171 farthen 29
class Error(Exception):
30
    def __init__(self, value=None):
31
        self.value = value
32
    def __str__(self):
33
        if self.value != None:
34
            return repr(self.value)
56 benedikt93 35
 
171 farthen 36
class ArgumentError(Error):
37
    pass
56 benedikt93 38
 
171 farthen 39
class DeviceNotFoundError(Error):
40
    pass
56 benedikt93 41
 
171 farthen 42
class DeviceError(Error):
43
    pass
56 benedikt93 44
 
171 farthen 45
class SendError(Error):
46
    pass
56 benedikt93 47
 
171 farthen 48
class ReceiveError(Error):
49
    pass
56 benedikt93 50
 
51
 
171 farthen 52
class Bunch(dict):
56 benedikt93 53
    """
171 farthen 54
        This is a dict whose items can also be accessed with
55
        bunchinstance.something.
56 benedikt93 56
    """
171 farthen 57
    def __init__(self, **kw):
58
        dict.__init__(self, kw)
59
        self.__dict__ = self
56 benedikt93 60
 
171 farthen 61
    def __getstate__(self):
62
        return self
56 benedikt93 63
 
171 farthen 64
    def __setstate__(self, state):
65
        self.update(state)
66
        self.__dict__ = self
56 benedikt93 67
 
68
 
171 farthen 69
class Embios(object):
70
    def __init__(self):
71
        self.lib = Lib(self)
56 benedikt93 72
 
171 farthen 73
    @staticmethod
74
    def _alignsplit(addr, size, blksize, align):
75
        end = addr + size
76
        if addr & (align - 1):
77
            bodyaddr = (addr + min(size, blksize)) & ~(align - 1)
78
        else: bodyaddr = addr
79
        headsize = bodyaddr - addr
80
        if (size - headsize) & (align - 1):
81
            tailaddr = (end - min(end - bodyaddr, blksize) + align - 1) & ~(align - 1)
82
        else: tailaddr = end
83
        tailsize = end - tailaddr
84
        return (headsize, tailaddr - bodyaddr, tailsize)
56 benedikt93 85
 
171 farthen 86
    def getversioninfo(self):
87
        """ This returns the emBIOS version and device information. """
88
        return self.lib.monitorcommand(struct.pack("IIII", 1, 0, 0, 0), "IBBBBI", ("revision", "majorv", "minorv", "patchv", "swtypeid", "hwtypeid"))
56 benedikt93 89
 
171 farthen 90
    def getpacketsizeinfo(self):
91
        """ This returns the emBIOS max packet size information.
92
            It also sets the properties of the device object accordingly.
93
        """
94
        resp = self.lib.monitorcommand(struct.pack("IIII", 1, 1, 0, 0), "HHII", ("coutmax", "cinmax", "doutmax", "dinmax"))
95
        self.lib.dev.packetsizelimit['cout'] = resp.coutmax
96
        self.lib.dev.packetsizelimit['cin'] = resp.cinmax
97
        self.lib.dev.packetsizelimit['din'] = resp.dinmax
98
        self.lib.dev.packetsizelimit['dout'] = resp.doutmax
99
        return resp
56 benedikt93 100
 
171 farthen 101
    def getusermemrange(self):
102
        """ This returns the memory range the user has access to. """
103
        return self.lib.monitorcommand(struct.pack("IIII", 1, 2, 0, 0), "III", ("lower", "upper", None))
56 benedikt93 104
 
171 farthen 105
    def reset(self, force=False):
106
        """ Reboot the device """
107
        if force:
108
            return self.lib.monitorcommand(struct.pack("IIII", 2, 0, 0, 0))
109
        else:
110
            return self.lib.monitorcommand(struct.pack("IIII", 2, 1, 0, 0), "III", (None, None, None))
56 benedikt93 111
 
171 farthen 112
    def poweroff(self, force=False):
113
        """ Powers the device off. """
114
        if force:
115
            return self.lib.monitorcommand(struct.pack("IIII", 3, 0, 0, 0))
116
        else:
117
            return self.lib.monitorcommand(struct.pack("IIII", 3, 1, 0, 0), "III", (None, None, None))
56 benedikt93 118
 
171 farthen 119
    def read(self, addr, size):
120
        """ Reads the memory from location 'addr' with size 'size'
121
            from the device. This cares about too long packages
122
            and decides whether to use DMA or not.
123
        """
124
        if not self.lib.connected:
125
            self.lib.connect()
126
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - 0x10
127
        din_maxsize = self.lib.dev.packetsizelimit["din"]
128
        data = ""
129
        (headsize, bodysize, tailsize) = self._alignsplit(addr, size, cin_maxsize, 16)
130
        if headsize != 0:
131
            data += self.readmem(addr, headsize)
132
            addr += headsize
133
        while bodysize > 0:
134
            if bodysize >= 2 * cin_maxsize:
135
                readsize = min(bodysize, din_maxsize)
136
                data += self.readdma(addr, readsize)
137
            else:
138
                readsize = min(bodysize, cin_maxsize)
139
                data += self.readmem(addr, readsize)
140
            addr += readsize
141
            bodysize -= readsize
142
        if tailsize != 0:
143
            data += self.readmem(addr, tailsize)
144
        return data
56 benedikt93 145
 
171 farthen 146
    def write(self, addr, data):
147
        """ Writes the data in 'data' to the location 'addr'
148
            in the memory of the device. This cares about too long packages
149
            and decides whether to use DMA or not.
150
        """
151
        if not self.lib.connected:
152
            self.lib.connect()
153
        cout_maxsize = self.lib.dev.packetsizelimit["cout"] - 0x10
154
        dout_maxsize = self.lib.dev.packetsizelimit["dout"]
155
        (headsize, bodysize, tailsize) = self._alignsplit(addr, len(data), cout_maxsize, 16)
156
        offset = 0
157
        if headsize != 0:
158
            self.writemem(addr, headsize)
159
            offset += headsize
160
            addr += headsize
161
        while bodysize > 0:
162
            if bodysize >= 2 * cout_maxsize:
163
                writesize = min(bodysize, dout_maxsize)
164
                self.writedma(addr, data[offset:offset+writesize])
165
            else:
166
                writesize = min(bodysize, cout_maxsize)
167
                self.writemem(addr, data[offset:offset+writesize])
168
            offset += writesize
169
            addr += writesize
170
            bodysize -= writesize
171
        if tailsize != 0:
172
            self.writemem(addr, data[offset:offset+tailsize])
173
        return data
56 benedikt93 174
 
171 farthen 175
    def readmem(self, addr, size):
176
        """ Reads the memory from location 'addr' with size 'size'
177
            from the device.
178
        """
179
        resp = self.lib.monitorcommand(struct.pack("IIII", 4, addr, size, 0), "III%ds" % size, (None, None, None, "data"))
180
        return resp.data
181
 
182
    def writemem(self, addr, data):
183
        """ Writes the data in 'data' to the location 'addr'
184
            in the memory of the device.
185
        """
186
        return self.lib.monitorcommand(struct.pack("IIII%ds" % len(data), 5, addr, len(data), 0, data), "III", (None, None, None))
56 benedikt93 187
 
171 farthen 188
    def readdma(self, addr, size):
189
        """ Reads the memory from location 'addr' with size 'size'
190
            from the device. This uses DMA and the data in endpoint.
191
        """
192
        self.lib.monitorcommand(struct.pack("IIII", 6, addr, size, 0), "III", (None, None, None))
193
        return struct.unpack("%ds" % size, self.lib.dev.din(size))[0]
56 benedikt93 194
 
171 farthen 195
    def writedma(self, addr, data):
196
        """ Writes the data in 'data' to the location 'addr'
197
            in the memory of the device. This uses DMA and the data out endpoint.
198
        """
199
        self.lib.monitorcommand(struct.pack("IIII", 7, addr, len(data), 0), "III", (None, None, None))
200
        return self.lib.dev.dout(data)
56 benedikt93 201
 
173 farthen 202
    def readstring(self, addr, maxlength = 256):
203
        """ Reads a zero terminated string from memory 
204
            Reads only a maximum of 'maxlength' chars.
205
        """
206
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - 0x10
207
        string = ""
208
        while (len(string) < maxlength or maxlength < 0):
209
            data = self.readmem(addr, min(maxlength - len(string), cin_maxsize))
210
            length = data.find("\0")
211
            if length >= 0:
212
                string += data[:length]
213
                break
214
            else:
215
                string += data
216
            addr += cin_maxsize
217
        return string
218
 
171 farthen 219
    def i2cread(self, index, slaveaddr, startaddr, size):
220
        """ Reads data from an i2c slave """
56 benedikt93 221
 
171 farthen 222
    def i2cwrite(self, index, slaveaddr, startaddr, data):
223
        """ Writes data to an i2c slave """
56 benedikt93 224
 
171 farthen 225
    def usbcread(self, size):
226
        """ Reads data with size 'size' from the USB console """
56 benedikt93 227
 
171 farthen 228
    def usbcwrite(self, data):
229
        """ Writes data to the USB console """
56 benedikt93 230
 
171 farthen 231
    def cread(self, size, bitmask):
232
        """ Reads data with the specified size from the device consoles
233
            identified with the specified bitmask
234
        """
56 benedikt93 235
 
171 farthen 236
    def cwrite(self, data):
237
        """ Writes data to the device consoles 
238
            identified with the specified bitmask.
239
        """
56 benedikt93 240
 
171 farthen 241
    def cflush(self, bitmask):
242
        """ Flushes the consoles specified with 'bitmask' """
243
        return self.lib.monitorcommand(struct.pack("IIII", 14, bitmask, 0, 0), "III", (None, None, None))
56 benedikt93 244
 
173 farthen 245
    def getprocinfo(self):
171 farthen 246
        """ Gets current state of the scheduler """
173 farthen 247
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - 0x10
248
        # Get the size
249
        schedulerstate = self.lockscheduler()
250
        resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "tablesize", None))
251
        tablesize = resp.tablesize
252
        size = tablesize
253
        structver = resp.structver
254
        offset = 0
255
        data = ""
256
        while size > 0:
257
            if size > cin_maxsize:
258
                readsize = cin_maxsize
259
            else:
260
                readsize = size
261
            resp = self.lib.monitorcommand(struct.pack("IIII", 15, offset, readsize, 0), "III%ds" % readsize, ("structver", "tablesize", None, "data"))
262
            data += resp.data
263
            offset += readsize
264
            size -= readsize
265
        self.lockscheduler(schedulerstate)
266
        threadstructsize = 120
267
        registersize = 32
268
        if len(data) % threadstructsize != 0:
269
            raise DeviceError("The thread struct is not a multiple of "+str(threadsturcsize)+"!")
270
        threadcount = len(data) / threadstructsize
271
        threads = []
272
        id = 0
273
        for thread in range(threadcount):
274
            offset = threadstructsize * thread
275
            threaddata = struct.unpack("<16IIIIIQIIIIIIIBBBB", data[offset:offset+threadstructsize])
276
            info = Bunch()
277
            info.id = id
278
            state = threaddata[17]
279
            info.state = libembiosdata.thread_state[state]
280
            if info.state == "THREAD_FREE":
281
                id += 1
282
                continue
283
            info.regs = Bunch()
284
            for register in range(16):
285
                info.regs["r"+str(register)] = threaddata[register]
286
            info.regs.cpsr = threaddata[16]
287
            info.nameptr = threaddata[18]
288
            if info.nameptr == 0:
289
                info.name = "Thread %d" % info.id
290
            else:
291
                info.name = self.readstring(info.nameptr)
292
            info.cputime_current = threaddata[19]
293
            info.cputime_total = threaddata[20]
294
            info.startusec = threaddata[21]
295
            info.queue_next_ptr = threaddata[22]
296
            info.timeout = threaddata[23]
297
            info.blocked_since = threaddata[24]
298
            info.blocked_by_ptr = threaddata[25]
299
            info.stackaddr = threaddata[26]
300
            info.err_no = threaddata[27]
301
            info.block_type = libembiosdata.thread_block[threaddata[28]]
302
            info.type = libembiosdata.thread_type[threaddata[29]]
303
            info.priority = threaddata[30]
304
            info.cpuload = threaddata[31]
305
            threads.append(info)
306
            id += 1
307
        return threads
308
 
309
 
310
        return self.lib.monitorcommand(struct.pack("IIII", 15, offset, size, 0), "III%ds" % size, ("structver", "tablesize", None, "data"))
56 benedikt93 311
 
173 farthen 312
    def lockscheduler(self, freeze=True):
171 farthen 313
        """ Freezes/Unfreezes the scheduler """
173 farthen 314
        resp = self.lib.monitorcommand(struct.pack("IIII", 16, 1 if freeze else 0, 0, 0), "III", ("before", None, None))
315
        return True if resp.before == 1 else False
67 benedikt93 316
 
173 farthen 317
    def unlockscheduler(self):
171 farthen 318
        """ Unfreezes the scheduler """
319
        return self.lib.monitorcommand(struct.pack("IIII", 16, 0, 0, 0), "III", ("before", None, None))
56 benedikt93 320
 
171 farthen 321
    def suspendthread(self, id, suspend=True):
322
        """ Suspends the thread with the specified id """
173 farthen 323
        resp = self.lib.monitorcommand(struct.pack("IIII", 17, 1 if suspend else 0, id, 0), "III", ("before", None, None))
324
        return True if resp.before == 1 else False
56 benedikt93 325
 
173 farthen 326
    def resumethread(self, id):
327
        """ Resumes the thread with the specified id """
171 farthen 328
        return self.lib.monitorcommand(struct.pack("IIII", 17, 0, id, 0), "III", ("before", None, None))
56 benedikt93 329
 
171 farthen 330
    def killthread(self, id):
331
        """ Kills the thread with the specified id """
332
        return self.lib.monitorcommand(struct.pack("IIII", 18, id, 0, 0), "III", ("before", None, None))
56 benedikt93 333
 
171 farthen 334
    def createthread(self, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state):
335
        """ Creates a thread with the specified attributes """
336
        if threadtype == "user":
337
            threadtype = 0
338
        elif threadtype == "system":
339
            threadtype = 1
340
        else:
341
            raise SyntaxError("Threadtype must be either 'system' or 'user'")
342
        if priority > 256 or priority < 0:
343
            raise SyntaxError("Priority must be a number between 0 and 256")
344
        if state == "ready":
345
            state = 0
346
        elif state == "suspended":
347
            state = 1
348
        else:
349
            raise SyntaxError("State must be either 'ready' or 'suspended'")
350
        resp = self.lib.monitorcommand(struct.pack("IIIIIIII", 19, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state), "III", (id, None, None))
351
        if resp.id < 0:
352
            raise DeviceError("The device returned the error code "+str(resp.id))
353
        return resp
56 benedikt93 354
 
172 farthen 355
    def flushcaches(self):
171 farthen 356
        """ Flushes the CPU instruction and data cache """
357
        return self.lib.monitorcommand(struct.pack("IIII", 20, 0, 0, 0), "III", (None, None, None))
56 benedikt93 358
 
172 farthen 359
    def execimage(self, addr):
171 farthen 360
        """ Runs the emBIOS app at 'addr' """
361
        return self.lib.monitorcommand(struct.pack("IIII", 21, addr, 0, 0), "III", ("excecimage", None, None))
56 benedikt93 362
 
171 farthen 363
    def bootflashread(self, memaddr, flashaddr, size):
364
        """ Copies the data in the bootflash at 'flashaddr' of the specified size
365
            to the memory at addr 'memaddr'
366
        """
82 benedikt93 367
 
171 farthen 368
    def bootflashwrite(self, memaddr, flashaddr, size):
369
        """ Copies the data in the memory at 'memaddr' of the specified size
370
            to the boot flash at addr 'flashaddr'
371
        """
56 benedikt93 372
 
171 farthen 373
    def execfirmware(self, addr):
374
        """ Executes the firmware at 'addr' and passes all control to it. """
375
        return self.lib.monitorcommand(struct.pack("IIII", 24, addr, 0, 0), "III", (None, None, None))
56 benedikt93 376
 
171 farthen 377
    def aesencrypt(self, addr, size, keyindex):
378
        """ Encrypts the buffer at 'addr' with the specified size
379
            with the hardware AES key index 'keyindex'
380
        """
381
        return self.lib.monitorcommand(struct.pack("IBBHII", 25, 1, 0, keyindex, addr, size), "III", (None, None, None))
82 benedikt93 382
 
171 farthen 383
    def aesdecrypt(self, addr, size, keyindex):
384
        """ Decrypts the buffer at 'addr' with the specified size
385
            with the hardware AES key index 'keyindex'
386
        """
387
        return self.lib.monitorcommand(struct.pack("IBBHII", 25, 0, 0, keyindex, addr, size), "III", (None, None, None))
82 benedikt93 388
 
171 farthen 389
    def hmac_sha1(self, addr, size, destination):
390
        """ Generates a HMAC-SHA1 hash of the buffer and saves it to 'destination' """
391
        return self.lib.monitorcommand(struct.pack("IIII", 26, addr, size, destination), "III", (None, None, None))
56 benedikt93 392
 
393
 
171 farthen 394
class Lib(object):
395
    def __init__(self, embios):
396
        self.idVendor = 0xFFFF
397
        self.idProduct = 0xE000
398
 
399
        self.embios = embios
400
        self.connected = False
56 benedikt93 401
 
171 farthen 402
    def connect(self):
403
        self.dev = Dev(self.idVendor, self.idProduct)
404
        self.connected = True
405
        self.embios.getpacketsizeinfo()
56 benedikt93 406
 
171 farthen 407
    def monitorcommand(self, cmd, rcvdatatypes=None, rcvstruct=None):
408
        if not self.connected:
409
            self.connect()
410
        self.dev.cout(cmd)
411
        if rcvdatatypes:
412
            rcvdatatypes = "I" + rcvdatatypes # add the response
413
            data = self.dev.cin(struct.calcsize(rcvdatatypes))
414
            data = struct.unpack(rcvdatatypes, data)
415
            response = data[0]
416
            if libembiosdata.responsecodes[response] == "ok":
417
                if rcvstruct:
418
                    datadict = Bunch()
419
                    counter = 1 # start with 1, 0 is the id
420
                    for item in rcvstruct:
421
                        if item != None: # else the data is undefined
422
                            datadict[item] = data[counter]
423
                        counter += 1
424
                    return datadict
425
                else:
426
                    return data
427
            elif libembiosdata.responsecodes[response] == "unsupported":
428
                raise DeviceError("The device does not support this command.")
429
            elif libembiosdata.responsecodes[response] == "invalid":
430
                raise DeviceError("Invalid command! This should NOT happen!")
431
            elif libembiosdata.responsecodes[response] == "busy":
432
                raise DeviceError("Device busy")
56 benedikt93 433
 
434
 
171 farthen 435
class Dev(object):
436
    def __init__(self, idVendor, idProduct):
437
        self.idVendor = idVendor
438
        self.idProduct = idProduct
67 benedikt93 439
 
171 farthen 440
        self.interface = 0
441
        self.timeout = 100
119 benedikt93 442
 
171 farthen 443
        self.connect()
444
        self.findEndpoints()
445
 
446
        self.packetsizelimit = {}
447
        self.packetsizelimit['cout'] = None
448
        self.packetsizelimit['cin'] = None
449
        self.packetsizelimit['dout'] = None
450
        self.packetsizelimit['din'] = None
56 benedikt93 451
 
171 farthen 452
    def __del__(self):
453
        self.disconnect()
56 benedikt93 454
 
171 farthen 455
    def findEndpoints(self):
456
        epcounter = 0
457
        self.endpoint = {}
458
        for cfg in self.dev:
459
            for intf in cfg:
460
                for ep in intf:
461
                    if epcounter == 0:
462
                        self.endpoint['cout'] = ep.bEndpointAddress
463
                    elif epcounter == 1:
464
                        self.endpoint['cin'] = ep.bEndpointAddress
465
                    elif epcounter == 2:
466
                        self.endpoint['dout'] = ep.bEndpointAddress
467
                    elif epcounter == 3:
468
                        self.endpoint['din'] = ep.bEndpointAddress
469
                    epcounter += 1
470
        if epcounter <= 3:
471
            raise DeviceError("Not all endpoints found in the descriptor. Only "+str(epcounter)+" found, we need 4")
56 benedikt93 472
 
171 farthen 473
    def connect(self):
474
        self.dev = usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct)
475
        if self.dev is None:
476
            raise DeviceNotFoundError()
477
        self.dev.set_configuration()
56 benedikt93 478
 
171 farthen 479
    def disconnect(self):
480
        pass
102 benedikt93 481
 
171 farthen 482
    def send(self, endpoint, data):
483
        size = self.dev.write(endpoint, data, self.interface, self.timeout)
484
        if size != len(data):
485
            raise SendError
486
        return len
102 benedikt93 487
 
171 farthen 488
    def receive(self, endpoint, size):
489
        read = self.dev.read(endpoint, size, self.interface, self.timeout)
490
        if len(read) != size:
491
            raise ReceiveError
492
        return read
56 benedikt93 493
 
171 farthen 494
    def cout(self, data):
495
        if self.packetsizelimit['cout'] and len(data) > self.packetsizelimit['cout']:
496
            raise SendError("Packet too big")
497
        return self.send(self.endpoint['cout'], data)
94 benedikt93 498
 
171 farthen 499
    def cin(self, size):
500
        if self.packetsizelimit['cin'] and size > self.packetsizelimit['cin']:
501
            raise ReceiveError("Packet too big")
502
        return self.receive(self.endpoint['cin'], size)
94 benedikt93 503
 
171 farthen 504
    def dout(self, data):
505
        if self.packetsizelimit['dout'] and len(data) > self.packetsizelimit['dout']:
506
            raise SendError("Packet too big")
507
        return self.send(self.endpoint['dout'], data)
94 benedikt93 508
 
171 farthen 509
    def din(self, size):
510
        if self.packetsizelimit['din'] and size > self.packetsizelimit['din']:
511
            raise ReceiveError("Packet too big")
512
        return self.receive(self.endpoint['din'], size)
56 benedikt93 513
 
96 benedikt93 514
 
171 farthen 515
if __name__ == "__main__":
516
    # Some tests
517
    import sys
518
    embios = Embios()
519
    resp = embios.getversioninfo()
520
    sys.stdout.write("Embios device version information: " + libembiosdata.swtypes[resp.swtypeid] + " v" + str(resp.majorv) + "." + str(resp.minorv) + 
521
                     "." + str(resp.patchv) + " r" + str(resp.revision) + " running on " + libembiosdata.hwtypes[resp.hwtypeid] + "\n")
522
    resp = embios.getusermemrange()
523
    sys.stdout.write("Usermemrange: "+hex(resp.lower)+" - "+hex(resp.upper)+"\n")
524
    memaddr = resp.lower
525
    maxlen = resp.upper - resp.lower
526
    f = open("./embios.py", "rb")
527
    sys.stdout.write("Loading test file (embios.py) to send over USB...\n")
528
    datastr = f.read()[:maxlen]
529
    sys.stdout.write("Sending data...\n")
530
    embios.write(memaddr, datastr)
531
    sys.stdout.write("Encrypting data with the hardware key...\n")
532
    embios.aesencrypt(memaddr, len(datastr), 0)
533
    sys.stdout.write("Reading data back and saving it to 'libembios-test-encrypted.bin'...\n")
534
    f = open("./libembios-test-encrypted.bin", "wb")
535
    f.write(embios.read(memaddr, len(datastr)))
536
    sys.stdout.write("Decrypting the data again...\n")
537
    embios.aesdecrypt(memaddr, len(datastr), 0)
538
    sys.stdout.write("Reading data back from device...\n")
539
    readdata = embios.read(memaddr, len(datastr))
540
    if readdata == datastr:
541
        sys.stdout.write("Data matches!")
542
    else:
543
        sys.stdout.write("Data does NOT match. Something got wrong")