def _read_7z_aes256_sha256(self, coder, input, level): if not self._archive.password: raise NoPasswordGivenError() # TODO: this needs some sanity checks firstbyte = coder['properties'][0] if not IS_PYTHON3: firstbyte = ord(firstbyte) numcyclespower = firstbyte & 0x3f if firstbyte & 0xc0 != 0: saltsize = (firstbyte >> 7) & 1 ivsize = (firstbyte >> 6) & 1 secondbyte = coder['properties'][1] if not IS_PYTHON3: secondbyte = ord(secondbyte) saltsize += (secondbyte >> 4) ivsize += (secondbyte & 0x0f) assert len(coder['properties']) == 2+saltsize+ivsize salt = coder['properties'][2:2+saltsize] iv = coder['properties'][2+saltsize:2+saltsize+ivsize] assert len(salt) == saltsize assert len(iv) == ivsize assert numcyclespower <= 24 if ivsize < 16: iv += bytes('\x00'*(16-ivsize), 'ascii') else: salt = iv = bytes('', 'ascii') password = self._archive.password.encode('utf-16-le') key = pylzma.calculate_key(password, numcyclespower, salt=salt) cipher = pylzma.AESDecrypt(key, iv=iv) if not input: self._file.seek(self._src_start) uncompressed_size = self._uncompressed[level] if uncompressed_size & 0x0f: # we need a multiple of 16 bytes uncompressed_size += 16 - (uncompressed_size & 0x0f) input = self._file.read(uncompressed_size) result = cipher.decrypt(input) return result
def _read_7z_aes256_sha256(self, coder, input, level): if not self._archive.password: raise NoPasswordGivenError() # TODO: this needs some sanity checks firstbyte = coder['properties'][0] if not IS_PYTHON3: firstbyte = ord(firstbyte) numcyclespower = firstbyte & 0x3f if firstbyte & 0xc0 != 0: saltsize = (firstbyte >> 7) & 1 ivsize = (firstbyte >> 6) & 1 secondbyte = coder['properties'][1] if not IS_PYTHON3: secondbyte = ord(secondbyte) saltsize += (secondbyte >> 4) ivsize += (secondbyte & 0x0f) assert len(coder['properties']) == 2 + saltsize + ivsize salt = coder['properties'][2:2 + saltsize] iv = coder['properties'][2 + saltsize:2 + saltsize + ivsize] assert len(salt) == saltsize assert len(iv) == ivsize assert numcyclespower <= 24 if ivsize < 16: iv += bytes('\x00' * (16 - ivsize), 'ascii') else: salt = iv = bytes('', 'ascii') password = self._archive.password.encode('utf-16-le') key = pylzma.calculate_key(password, numcyclespower, salt=salt) cipher = pylzma.AESDecrypt(key, iv=iv) if not input: self._file.seek(self._src_start) uncompressed_size = self._uncompressed[level] if uncompressed_size & 0x0f: # we need a multiple of 16 bytes uncompressed_size += 16 - (uncompressed_size & 0x0f) input = self._file.read(uncompressed_size) result = cipher.decrypt(input) return result