示例#1
0
    def DecryptString(self, ciphertext: str) -> str:
        ciphertext_bytes = base64.b64decode(ciphertext)

        salt, header, body = ciphertext_bytes[:48], ciphertext_bytes[
            48:48 + 16], ciphertext_bytes[48 + 16:]
        if len(salt) == 48 and len(header) == 16:
            xts_key = pbkdf2.PBKDF2HMAC(hashes.SHA1(),
                                        128 // 8 * 2, salt[0:40], 1000,
                                        default_backend()).derive(
                                            self._password)
        else:
            raise ValueError('Broken ciphertext: length is too short.')

        xts_cipher = Cipher(
            algorithms.AES(xts_key),
            modes.XTS(
                b'\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00'
            ), default_backend())
        xts_decryptor = xts_cipher.decryptor()
        header = xts_decryptor.update(header) + xts_decryptor.finalize()
        header_tag, header_textlength, header_blocksize = \
            header[0:4], int.from_bytes(header[4:12], 'little'), int.from_bytes(header[12:16], 'little')
        padded_textlength = header_textlength if header_textlength % 16 == 0 else header_textlength + 16 - header_textlength % 16
        if not (header_tag == b'XTS1'):
            raise ValueError('Broken ciphertext: header_tag is corrupted.')
        if not (padded_textlength == len(body)):
            raise ValueError(
                'Broken ciphertext: header_textlength is corrupted.')
        if not (0 < header_blocksize <= 0x100000
                and header_blocksize % 16 == 0):
            raise ValueError(
                'Broken ciphertext: header_blocksize is corrupted.')

        plaintext_bytes = bytearray()
        for i in itertools.count():
            offset_begin = i * header_blocksize
            offset_end = offset_begin + header_blocksize
            if offset_begin < len(body):
                xts_cipher = Cipher(algorithms.AES(xts_key),
                                    modes.XTS(i.to_bytes(16, 'little')),
                                    default_backend())
                xts_decryptor = xts_cipher.decryptor()

                block = xts_decryptor.update(
                    body[offset_begin:offset_end]) + xts_decryptor.finalize()
                if len(
                        block
                ) < header_blocksize and header_textlength != padded_textlength:
                    block = block[0:header_textlength - padded_textlength]

                plaintext_bytes.extend(block)
            else:
                break

        return plaintext_bytes.decode('utf-8')
示例#2
0
    def decrypt_keybag(self, wrapped_keybag, offset, key):
        """
        Decrypts the wrapped binary keybag that will be decrypted using the Container's UUID.
        Uses the setKey function as the cipher
        The UUID is set as both the first and second key in the cipher
        param: wrapped_keybag: The wrapped binary keybag that will be decrypted using the Container's UUID
        """

        cs_factor = self.block_size // 0x200
        uno = offset * cs_factor
        complete_plaintext = b""

        # Cipher is AES-XTS with the container UUID as the first and second key

        try:
            log.debug("Attempting to decrypt the keybag")
            k = 0
            size = len(wrapped_keybag)
            while k < size:
                tweak = struct.pack("<QQ", uno, 0)
                decryptor = Cipher(algorithms.AES(key + key),
                                   modes.XTS(tweak),
                                   backend=default_backend()).decryptor()
                complete_plaintext += decryptor.update(
                    wrapped_keybag[k:k + 0x200]) + decryptor.finalize()
                uno += 1
                k += 0x200

            log.debug("Successfully decrypted the keybag")
            return complete_plaintext
        except InternalError as ex:
            log.exception("Could not decrypt the keybag.")
        return ''
示例#3
0
    def read(self, path, size, offset, fh):
        obfs_path = self.path_obfuscate(path)
        if path == self.proc_wl_path: return str(self.proc_wl).encode()
        start_block = offset // self.block_size
        num_blocks = size // self.block_size
        if (size % self.block_size): num_blocks += 1
        rb_data = self.read_block(path, start_block, num_blocks, fh)

        # decryption here
        #        pt = rb_data
        pt = b""
        rb_data_len = len(rb_data)
        i = 0
        while len(pt) < rb_data_len:
            ct = rb_data[:self.block_size]
            tweak1, tweak2 = start_block + i * self.block_size // 256, start_block + i * self.block_size % 256
            decryptor = Cipher(algorithms.AES(self.key),
                               modes.XTS(struct.pack('>QQ', tweak1, tweak2)),
                               backend=default_backend()).decryptor()
            pt += decryptor.update(ct)
            rb_data = rb_data[self.block_size:]
            i += 1

        start = offset % self.block_size
        return pt[start:(start + size)]
示例#4
0
 def test_xts_too_short(self, backend):
     key = b"thirty_two_byte_keys_are_great!!"
     tweak = b"\x00" * 16
     cipher = base.Cipher(algorithms.AES(key), modes.XTS(tweak))
     enc = cipher.encryptor()
     with pytest.raises(ValueError):
         enc.update(b"0" * 15)
示例#5
0
 def test_xts_vectors(self, backend, subtests):
     # This list comprehension excludes any vector that does not have a
     # data unit length that is divisible by 8. The NIST vectors include
     # tests for implementations that support encryption of data that is
     # not divisible modulo 8, but OpenSSL is not such an implementation.
     vectors = [
         x for x in _load_all_params(
             os.path.join("ciphers", "AES", "XTS", "tweak-128hexstr"),
             ["XTSGenAES128.rsp", "XTSGenAES256.rsp"],
             load_nist_vectors,
         ) if int(x["dataunitlen"]) / 8.0 == int(x["dataunitlen"]) // 8
     ]
     for vector in vectors:
         with subtests.test():
             key = binascii.unhexlify(vector["key"])
             tweak = binascii.unhexlify(vector["i"])
             pt = binascii.unhexlify(vector["pt"])
             ct = binascii.unhexlify(vector["ct"])
             cipher = base.Cipher(algorithms.AES(key), modes.XTS(tweak),
                                  backend)
             enc = cipher.encryptor()
             computed_ct = enc.update(pt) + enc.finalize()
             assert computed_ct == ct
             dec = cipher.decryptor()
             computed_pt = dec.update(ct) + dec.finalize()
             assert computed_pt == pt
示例#6
0
def _e(x, seed):  # not sure seed is the right term here...
    x = x.encode("utf8") + bytes([0] * (16 - len(x)))
    b = hashlib.sha512(seed.encode("utf8") + ENCRYPT_KEY + SALT).digest()[-16:]
    c = Cipher(algorithms.AES(XTS_KEY),
               modes.XTS(b),
               backend=default_backend())
    e = c.encryptor()
    return base64.urlsafe_b64encode(e.update(x) + e.finalize()).decode("utf8")
示例#7
0
def _d(x, seed):  # not sure seed is the right term here...
    x = base64.urlsafe_b64decode(x)
    b = hashlib.sha512(seed.encode("utf8") + ENCRYPT_KEY + SALT).digest()[-16:]
    c = Cipher(algorithms.AES(XTS_KEY),
               modes.XTS(b),
               backend=default_backend())
    d = c.decryptor()
    return (d.update(x) + d.finalize()).rstrip(b"\x00").decode("utf8")
示例#8
0
    def EncryptString(self, plaintext: str) -> str:
        plaintext_bytes = plaintext.encode('utf-8')

        salt = os.urandom(48)

        header_tag = b'XTS1'
        header_textlength = len(plaintext_bytes)
        header_blocksize = 0x10000

        xts_key = pbkdf2.PBKDF2HMAC(hashes.SHA1(),
                                    128 // 8 * 2, salt[0:40], 1000,
                                    default_backend()).derive(self._password)

        body = bytearray()
        for i in itertools.count():
            offset_begin = i * header_blocksize
            offset_end = offset_begin + header_blocksize
            if offset_begin < len(plaintext_bytes):
                xts_cipher = Cipher(algorithms.AES(xts_key),
                                    modes.XTS(i.to_bytes(16, 'little')),
                                    default_backend())
                xts_encryptor = xts_cipher.encryptor()

                block = plaintext_bytes[offset_begin:offset_end]
                if len(block) % 16 != 0:
                    block += b'\x00' * (16 - len(block) % 16)

                body.extend(
                    xts_encryptor.update(block) + xts_encryptor.finalize())
            else:
                break

        xts_cipher = Cipher(
            algorithms.AES(xts_key),
            modes.XTS(
                b'\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00'
            ), default_backend())
        xts_encryptor = xts_cipher.encryptor()
        header = xts_encryptor.update(
            header_tag + header_textlength.to_bytes(8, 'little') +
            header_blocksize.to_bytes(4, 'little')) + xts_encryptor.finalize()

        ciphertext_bytes = salt + header + body

        return base64.b64encode(ciphertext_bytes).decode('utf-8')
    def encrypt_entry(self, data_arr, tweak_arr, encr_key):
        # Encrypt 32 bytes of data using AES-XTS encryption
        backend = default_backend()
        plain_text = data_arr.decode('hex')
        tweak = tweak_arr.decode('hex')
        cipher = Cipher(algorithms.AES(encr_key), modes.XTS(tweak), backend=backend)
        encryptor = cipher.encryptor()
        encrypted_data = encryptor.update(plain_text)

        return encrypted_data
示例#10
0
 def test_xts_vectors(self, vector, backend):
     key = binascii.unhexlify(vector["key"])
     tweak = binascii.unhexlify(vector["i"])
     pt = binascii.unhexlify(vector["pt"])
     ct = binascii.unhexlify(vector["ct"])
     cipher = base.Cipher(algorithms.AES(key), modes.XTS(tweak), backend)
     enc = cipher.encryptor()
     computed_ct = enc.update(pt) + enc.finalize()
     assert computed_ct == ct
     dec = cipher.decryptor()
     computed_pt = dec.update(ct) + dec.finalize()
     assert computed_pt == pt
示例#11
0
    def write(self, path, data, offset, fh, obfs=True):
        if obfs:
            obfs_path = self.path_obfuscate(path)
        else:
            obfs_path = path
        data_len = len(data)
        if path == self.proc_wl_path:
            wl_str = str(self.proc_wl)
            wl_str = wl_str[:offset] + data.decode() + wl_str[(offset +
                                                               data_len):]
            wl_str = wl_str[wl_str.index("["):wl_str.index("]") + 1]
            self.proc_wl = ast.literal_eval(wl_str)
            return data_len
        if (obfs_path not in self.st_size_dict):
            self.st_size_dict[obfs_path] = 0
        self.st_size_dict[obfs_path] = max(self.st_size_dict[obfs_path],
                                           offset + data_len)
        start_block = offset // self.block_size
        num_blocks = data_len // self.block_size
        if (data_len % self.block_size): num_blocks += 1
        if num_blocks == 0: return 0

        new_fh = os.open(obfs_path, os.O_RDONLY)
        rb_data = self.read_block(path, start_block, num_blocks, new_fh)
        os.close(new_fh)

        # new data
        if len(rb_data) == 0: rb_data = b"\0" * num_blocks * self.block_size
        start = offset % self.block_size
        rb_data = rb_data[:start] + data + rb_data[(start) + data_len:]

        #        ct = rb_data
        # encryption here
        ct = b""
        rb_data_len = len(rb_data)
        i = 0
        while len(ct) < rb_data_len:
            pt = rb_data[:self.block_size]
            tweak1, tweak2 = start_block + i * self.block_size // 256, start_block + i * self.block_size % 256
            # reusing keys with tweaks; consider modifying
            encryptor = Cipher(algorithms.AES(self.key),
                               modes.XTS(struct.pack('>QQ', tweak1, tweak2)),
                               backend=default_backend()).encryptor()
            ct += encryptor.update(pt)
            rb_data = rb_data[self.block_size:]
            i += 1

        bytes_written = self.write_block(path, ct, start_block, fh)
        return data_len
示例#12
0
def crack_keystore(keystore, dict):

    wordlist = open(dict, 'r')
    hash = get_hash_algorithm(keystore)
    count = 0

    print("\n[*] Starting bruteforce...")

    for line in wordlist.readlines():

        kdf1 = PBKDF2HMAC(algorithm=hash,
                          length=keystore['Key_Length'],
                          salt=keystore['Salt1_PBKDF2'],
                          iterations=keystore['Iteration1_PBKDF2'],
                          backend=backend)

        aes_key = kdf1.derive(line.rstrip().encode())

        cipher = Cipher(algorithms.AES(aes_key),
                        modes.XTS(tweak),
                        backend=backend)
        decryptor = cipher.decryptor()

        aes_decrypt = decryptor.update(keystore['Enc_Password'])

        kdf2 = PBKDF2HMAC(algorithm=hash,
                          length=keystore['KL2_PBKDF2'],
                          salt=keystore['Salt2_PBKDF2'],
                          iterations=keystore['Iteration2_PBKDF2'],
                          backend=backend)

        final_hash = kdf2.derive(aes_decrypt)

        if random.randint(1, 20) == 12:
            print("\t%d password tested..." % count)
        count += 1

        if binascii.hexlify(final_hash).decode() == binascii.hexlify(
                keystore['Final_Hash'].rstrip(b'\x00')).decode():
            print("\n[*] Password Found = %s" % line.rstrip())
            exit(0)

    print("\t[-] Password Not Found. You should try another dictionary.")
示例#13
0
def mode_for_type(mode_type, iv_or_tweak=None):
    if mode_type == 'cbc':
        return modes.CBC(initialization_vector=iv_or_tweak)
    elif mode_type == 'xts':
        return modes.XTS(tweak=iv_or_tweak)
    elif mode_type == 'ecb':
        return modes.ECB()
    elif mode_type == 'ofb':
        return modes.OFB(initialization_vector=iv_or_tweak)
    elif mode_type == 'cfb':
        return modes.CFB(initialization_vector=iv_or_tweak)
    elif mode_type == 'cfb8':
        return modes.CFB8(initialization_vector=iv_or_tweak)
    elif mode_type == 'ctr':
        return modes.CTR(nonce=iv_or_tweak)
    elif mode_type == 'gcm':
        return modes.GCM(initialization_vector=iv_or_tweak)
    else:
        return None
示例#14
0
def decrypt_data(data_input, decr_key, page_num, entry_no, entry_size):
    '''
    Decrypt NVS data entry
    '''
    page_max_size = 4096
    first_entry_offset = 64
    init_tweak_val = '0'
    tweak_len_needed = 32  # in hex
    tweak_tmp = ''

    data_input = binascii.hexlify(data_input)
    rel_addr = page_num * page_max_size + first_entry_offset

    # Set tweak value
    offset = entry_no * entry_size
    addr = hex(rel_addr + offset)[2:]
    addr_len = len(addr)
    if addr_len > 2:
        if not addr_len % 2:
            addr_tmp = addr
        else:
            addr_tmp = init_tweak_val + addr
        tweak_tmp = reverse_hexbytes(addr_tmp)
        tweak_val = tweak_tmp + (init_tweak_val * (tweak_len_needed -
                                                   (len(tweak_tmp))))
    else:
        tweak_val = addr + (init_tweak_val * (tweak_len_needed - len(addr)))

    if type(data_input) == bytes:
        data_input = data_input.decode()

    # Decrypt 32 bytes of data using AES-XTS decryption
    backend = default_backend()
    plain_text = codecs.decode(data_input, 'hex')
    tweak = codecs.decode(tweak_val, 'hex')
    cipher = Cipher(algorithms.AES(decr_key),
                    modes.XTS(tweak),
                    backend=backend)
    decryptor = cipher.decryptor()
    decrypted_data = decryptor.update(plain_text)

    return decrypted_data
示例#15
0
def crack_keystore(keystore, wordlist):
    # Open wordlist file
    with open(wordlist, "r") as f:

        # Get hash and method from keystore
        hash_ = get_hash_algorithm(keystore)
        method = get_openssl_method(keystore)

        # Read each line of the file, it is the user password
        for user_password in f:
            user_password = user_password.strip()

            # First call to PBKDF2
            EVP_password = hashlib.pbkdf2_hmac(hash_, user_password.encode(),
                                               keystore['pbkdf2_1_salt'],
                                               keystore['pbkdf2_1_iterations'],
                                               keystore['generic_key_length'])
            # Here, the password used for the second call to PBKDF2 is decrypted
            backend = default_backend()
            cipher = Cipher(
                algorithms.AES(EVP_password),
                modes.XTS(
                    b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
                ),
                backend=backend)
            decryptor = cipher.decryptor()
            decrypted_password = decryptor.update(
                keystore['pbkdf2_2_encrypted_password']
                [0:keystore['evp_decrypt_input_length']]) + decryptor.finalize(
                )

            # Final hash is computed
            final_hash = hashlib.pbkdf2_hmac(hash_, decrypted_password,
                                             keystore['pbkdf2_2_salt'],
                                             keystore['pbkdf2_2_iterations'],
                                             keystore['pbkdf2_2_key_length'])

            # If the computed hash is equal to the stored hash, then we have got the right user password
            if final_hash == keystore['final_hash']:
                return user_password

        return False
示例#16
0
def xts_decrypt(iv, key, ciphertext):
    cipher = Cipher(algorithms.AES(key), modes.XTS(iv), backend=default_backend())
    decryptor = cipher.decryptor()
    decodetext = decryptor.update(ciphertext) + decryptor.finalize()
    return decodetext
示例#17
0
import binascii
import os

import pytest

from cryptography.hazmat.backends.interfaces import CipherBackend
from cryptography.hazmat.primitives.ciphers import algorithms, base, modes

from .utils import _load_all_params, generate_encrypt_test
from ...doubles import DummyMode
from ...utils import load_nist_vectors


@pytest.mark.supported(
    only_if=lambda backend: backend.cipher_supported(
        algorithms.AES(b"\x00" * 32), modes.XTS(b"\x00" * 16)
    ),
    skip_message="Does not support AES XTS",
)
@pytest.mark.requires_backend_interface(interface=CipherBackend)
class TestAESModeXTS(object):
    @pytest.mark.parametrize(
        "vector",
        # This list comprehension excludes any vector that does not have a
        # data unit length that is divisible by 8. The NIST vectors include
        # tests for implementations that support encryption of data that is
        # not divisible modulo 8, but OpenSSL is not such an implementation.
        [
            x
            for x in _load_all_params(
                os.path.join("ciphers", "AES", "XTS", "tweak-128hexstr"),
 def test_xts_tweak_not_bytes(self):
     with pytest.raises(TypeError):
         modes.XTS(32)  # type: ignore[arg-type]
示例#19
0
import binascii
import os

import pytest

from cryptography.hazmat.backends.interfaces import CipherBackend
from cryptography.hazmat.primitives.ciphers import algorithms, base, modes

from .utils import _load_all_params, generate_aead_test, generate_encrypt_test
from ...utils import load_nist_vectors


@pytest.mark.supported(
    only_if=lambda backend: backend.cipher_supported(
        algorithms.AES(b"\x00" * 32), modes.XTS(b"\x00" * 16)),
    skip_message="Does not support AES XTS",
)
@pytest.mark.requires_backend_interface(interface=CipherBackend)
class TestAESModeXTS(object):
    @pytest.mark.parametrize(
        "vector",
        # This list comprehension excludes any vector that does not have a
        # data unit length that is divisible by 8. The NIST vectors include
        # tests for implementations that support encryption of data that is
        # not divisible modulo 8, but OpenSSL is not such an implementation.
        [
            x for x in _load_all_params(
                os.path.join("ciphers", "AES", "XTS", "tweak-128hexstr"),
                ["XTSGenAES128.rsp", "XTSGenAES256.rsp"], load_nist_vectors)
            if int(x["dataunitlen"]) / 8.0 == int(x["dataunitlen"]) // 8
示例#20
0
def _flash_encryption_operation_aes_xts(output_file, input_file, flash_address,
                                        keyfile, do_decrypt):
    """
    Apply the AES-XTS algorithm with the hardware addressing scheme used by Espressif

    key = AES-XTS key (32 or 64 bytes)
    flash_address = address in flash to encrypt at. Must be multiple of 16 bytes.
    indata = Data to encrypt/decrypt. Must be multiple of 16 bytes.
    encrypt = True to Encrypt indata, False to decrypt indata.

    Returns a bitstring of the ciphertext or plaintext result.
    """

    backend = default_backend()
    key = _load_hardware_key(keyfile)
    indata = input_file.read()

    if flash_address % 16 != 0:
        raise esptool.FatalError(
            "Starting flash address 0x%x must be a multiple of 16" %
            flash_address)

    if len(indata) % 16 != 0:
        raise esptool.FatalError(
            "Input data length (%d) must be a multiple of 16" % len(indata))

    if len(indata) == 0:
        raise esptool.FatalError("Input data must be longer than 0")

    # left pad for a 1024-bit aligned address
    pad_left = flash_address % 0x80
    indata = (b"\x00" * pad_left) + indata

    # right pad for full 1024-bit blocks
    pad_right = len(indata) % 0x80
    if pad_right > 0:
        pad_right = 0x80 - pad_right
    indata = indata + (b"\x00" * pad_right)

    inblocks = _split_blocks(indata, 0x80)  # split into 1024 bit blocks

    output = b""
    for inblock in inblocks:  # for each block
        tweak = struct.pack("<I", (flash_address & ~0x7F)) + (b"\x00" * 12)
        flash_address += 0x80  # for next block

        if len(tweak) != 16:
            raise esptool.FatalError(
                "Length of tweak must be 16, was {}".format(len(tweak)))

        cipher = Cipher(algorithms.AES(key), modes.XTS(tweak), backend=backend)
        encryptor = cipher.decryptor() if do_decrypt else cipher.encryptor()

        inblock = inblock[::-1]  # reverse input
        outblock = encryptor.update(inblock)  # standard algo
        output += outblock[::-1]  # reverse output

    # undo any padding we applied to the input
    if pad_right != 0:
        output = output[:-pad_right]
    if pad_left != 0:
        output = output[pad_left:]

    # output length matches original input
    if len(output) != len(indata) - pad_left - pad_right:
        raise esptool.FatalError(
            "Length of input data ({}) should match the output data ({})".
            format(len(indata) - pad_left - pad_right, len(output)))

    output_file.write(output)
示例#21
0
 def test_xts_wrong_key_size(self, backend):
     with pytest.raises(ValueError):
         ciphers.Cipher(AES(b"0" * 16), modes.XTS(b"0" * 16), backend)
示例#22
0
 def test_xts_tweak_too_small(self):
     with pytest.raises(ValueError):
         modes.XTS(b"0")
示例#23
0
 def test_xts_tweak_not_bytes(self):
     with pytest.raises(TypeError):
         modes.XTS(32)
示例#24
0
def aes_256_xts_encrypt_block(key, iv, blk):
    cipher = Cipher(algorithms.AES(key), modes.XTS(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    ct = encryptor.update(blk) + encryptor.finalize()
    return ct
示例#25
0
 def test_xts_no_duplicate_keys_encryption(self, backend):
     key = bytes(range(16)) * 2
     tweak = b"\x00" * 16
     cipher = base.Cipher(algorithms.AES(key), modes.XTS(tweak))
     with pytest.raises(ValueError, match="duplicated keys"):
         cipher.encryptor()
示例#26
0
def xts_encrypt(iv, key, plaintext):
    cipher = Cipher(algorithms.AES(key), modes.XTS(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()
    return ciphertext
示例#27
0
        _logfd.flush()
else:

    def debugOutputToLog(*args):
        pass


if not hasattr(fuse, '__version__'):
    raise RuntimeError(
        "your fuse-py doesn't know of fuse.__version__, probably it's too old."
    )

fuse.fuse_python_api = (0, 2)

cipher = Cipher(algorithms.AES(AES_KEY),
                modes.XTS(XTS_TWEAK),
                backend=default_backend())


def filterLocals(fArgs):
    return dict(filter(lambda el: el[0] != 'self', fArgs.items()))


class SB3Stat(Stat):
    def __init__(self):
        self.st_mode = 0
        self.st_ino = 0
        self.st_dev = 0
        self.st_nlink = 0
        self.st_uid = 0
        self.st_gid = 0