def multiblock_encrypt(connection, KeyId, WorkingKeyMode = None, WorkingKey = None, Versus = None, Data = None, IV = None, BlockSize = 16): """ MultiBlock Encryption, MAC Generation: Keyboard and Security (0x40,0x15). :Parameters: -*connection* (PupySPOT): Object managing spot connection. - *KeyId* (integer): Slot ID of Master Key. - *WorkingKeyMode* (Enums.WKMode): Working Key format. - *WorkingKey* (bytes array): Working Key value encrypted with Master Key. - *Versus* (Enums.Versus): Operation required. - *Data* (bytes array): Data block on which the operation is performed. - *IV* (bytes array): Initial vector IV. - *BlockSize* (integer): Length of each block. :Returns: Ack-Code indicating successful of the operation. """ blkcount=0 data = Data cblock = IV resultdata = '' # block split while True: block = data[:BlockSize] data = data[BlockSize:] #send if len(block) > 0 and len(data) > 0: flags = Enums.Flags.START_DATA_BLOCK if blkcount == 0 else Enums.Flags.INTERMEDIATE_DATA_BLOCK else: flags = Enums.Flags.FIRSTANDLAST_DATA_BLOCK if blkcount == 0 else Enums.Flags.END_DATA_BLOCK Protocol.send_multiblock_encrypt(connection, Flags = flags, KeyId = KeyId, WorkingKeyMode = Enums.WKMode[WorkingKeyMode], WorkingKey = WorkingKey, Versus = Enums.Versus[Versus], Data = block, ChainingData = cblock) #receive ack = Protocol.recv_multiblock_encrypt(connection, 120) if ack['ACKcode'] == 0x00: cblock = ack['ChainingData'] resultdata += ack['Data'] if flags == Enums.Flags.FIRSTANDLAST_DATA_BLOCK or flags == Enums.Flags.END_DATA_BLOCK: break else: break blkcount += 1 return ack['ACKcode'], resultdata