Esempio n. 1
0
def foobar(input_file, file_list, option, buffer_size, count):
    """
        Sample method showing some usage examples.
    """

    # First of all, check if the paramters have the correct type
    pv.param_type_list([[input_file, "input file", str],
                        [file_list, "file list",
                         list], [option, "option", str],
                        [buffer_size, "buffer size", int],
                        [count, "count", int]])

    # Ensure that 'input_file' exists
    pv.path(input_file, "input file", True, True)

    # Ensure that 'input_file' is not identical with any from 'file_list'
    pv.compfile(input_file, "input file", file_list)

    # Ensure that the file name of 'input_file' does not contain any wildcards
    # and also that it does not contain brackets or exlamation marks
    pv.string(input_file, "input file", False, ['(', ')', '!'])

    # Ensure 'option' is one of the options from the list
    pv.compstr(option, "option", ["print", "read", "write"])

    # Ensure that 'buffer_size' is a postive integer between 1 and 4096
    pv.intrange(buffer_size, "buffer size", 1, 4096, False)

    # Finally, ensure that 'count' is either zero or a positive integer
    pv.intvalue(count, "count", True, True, False)

    print("Parameter validation successful.")
Esempio n. 2
0
def compare_files(file_input,
                  directory,
                  ignore_read_errors=True,
                  obfuscate_enc=0,
                  obfuscate_key=0):
    """
        Compare files to find out which key fits to an encrypted file
        and vice versa.
    """
    pv.path(file_input, "input", True, True)
    pv.path(directory, "compare", False, True)
    pv.intvalue(obfuscate_enc, "encrypted file obfuscation", True, True, \
                False)
    pv.intvalue(obfuscate_key, "key file obfuscation", True, True, False)

    obfuscate_enc = int(obfuscate_enc)
    obfuscate_key = int(obfuscate_key)

    file_input = os.path.abspath(file_input)
    file_input_size = int(common.get_file_size(file_input))

    directory = os.path.abspath(directory)
    list_files = []

    for item in os.listdir(directory):
        path = os.path.join(directory, item)
        if os.path.isfile(path):
            if path == file_input:
                continue

            file_enc_size1 = int(common.get_file_size(path) + obfuscate_enc)
            file_enc_size2 = int(common.get_file_size(path) - obfuscate_enc)
            file_key_size1 = int(common.get_file_size(path) + obfuscate_key)
            file_key_size2 = int(common.get_file_size(path) - obfuscate_key)

            try:
                if file_input_size == file_enc_size1 or \
                   file_input_size == file_enc_size2 or \
                   file_input_size == file_key_size1 or \
                   file_input_size == file_key_size2:
                    list_files.append(path)
            except Exception as e:
                if not ignore_read_errors:
                    raise Exception(e)
                else:
                    pass

    list_files.sort()

    return list_files
Esempio n. 3
0
def indent(directory,
           file_ext,
           spaces=4,
           padding=12,
           left_justify=False,
           recursive=False,
           overwrite=False,
           verbose=False):
    """
        Method to perform the indentation process.
    """
    pv.path(directory, "input", False, True)
    pv.string(file_ext, "file extension", False, None)
    pv.intvalue(spaces, "spaces", True, False, False)
    pv.intvalue(padding, "padding", True, False, False)

    directory = os.path.abspath(directory)
    spaces = int(spaces)
    padding = int(padding)
    num = 1

    if verbose:
        print "\nGathering files to process. Please wait.\n"

    list_files = common.get_files(directory, file_ext, recursive)

    if len(list_files) == 0:
        if verbose:
            print "No files to process.\n"
            return

    just = len(str(len(list_files)))
    for file_input in list_files:
        if verbose:
            print "Processing file %s of %s: '%s'" % \
                (str(num).rjust(just, " "), str(len(list_files)), file_input)
            num += 1

        if overwrite:
            __indent_file(file_input, spaces, padding, left_justify)
        else:
            __indent_copy(file_input, spaces, padding, left_justify)

    if verbose:
        print "\nFinished.\n"
Esempio n. 4
0
def generate_key_string(key_bytes, dev_random=False, fortuna=False):
    """
        Generate a binary key and convert it into a Base64 string.
    """
    pv.intvalue(key_bytes, "key size", True, False, False)
    key_bytes = int(key_bytes)

    prng = randgen.get_prng(dev_random, fortuna)
    key_string = prng.get_bytes(key_bytes)

    # Run the appropriate code for the Python framework used
    if sys.version_info[0] == 2:
        key_string = base64.b64encode(key_string)
    elif sys.version_info[0] > 2:
        key_bytes = base64.b64encode(key_string)
        key_string = key_bytes.decode(sys.getdefaultencoding())

    return key_string
Esempio n. 5
0
def obfuscate_file(task_id, file_path, buffer_size=4096, bytes_random=0,
                   dev_random=False, fortuna=False):
    """
        Create a task file first, then add given amount of random bytes
        to the given file.
    """
    pv.path(file_path, "target", True, True)
    pv.intvalue(buffer_size, "buffer size", True, False, False)
    pv.intvalue(bytes_random, "random bytes", True, False, False)

    buffer_size = int(buffer_size)
    bytes_random = int(bytes_random)
    file_path = os.path.abspath(file_path)
    file_size = common.get_file_size(file_path) + int(bytes_random)

    common.build_task_file(task_id, file_path, file_size, None, 0, None, 0,
                          "file obfuscation")

    add_random_bytes(file_path, buffer_size, bytes_random, dev_random,
                     fortuna)
Esempio n. 6
0
def extract_bytes(file_input,
                  file_output,
                  offset=0,
                  length=0,
                  buffer_size=4096,
                  overwrite=False,
                  remove=False):
    """
        Extract a user-defined byte range into a separate file.
    """
    pv.path(file_input, "input", True, True)
    if not overwrite:
        pv.path(file_output, "output", True, False)
    pv.compfile(file_input, "input", [[file_output, "output"]])
    pv.intvalue(offset, "offset", True, True, False)
    pv.intvalue(length, "length", True, False, False)
    pv.intvalue(buffer_size, "buffer size", True, False, False)

    file_input = os.path.abspath(file_input)
    file_output = os.path.abspath(file_output)
    offset = int(offset)
    length = int(length)
    buffer_size = int(buffer_size)
    file_size = get_file_size(file_input)

    if (offset + length) > file_size:
        exception("With this offset the maximal length is %s bytes." % \
                   str(file_size - offset))

    __extract_bytes(file_input, file_output, offset, length, buffer_size,
                    remove)
Esempio n. 7
0
def add_random_bytes(file_path, buffer_size=4096, bytes_random=0,
                     dev_random=False, fortuna=False):
    """
        Add given amount of random bytes to a file.
    """
    delay = common.get_delay()

    pv.path(file_path, "target", True, True)
    pv.intvalue(buffer_size, "buffer size", True, False, False)
    pv.intvalue(bytes_random, "random bytes", True, False, False)

    buffer_size = int(buffer_size)
    bytes_random = int(bytes_random)
    file_path = os.path.abspath(file_path)

    byte_blocks = int(bytes_random / buffer_size)
    byte_remainder = bytes_random % buffer_size
    data_random = bytearray(b"")

    always_use_urandom = \
        bool(int(common.global_config(["Obfuscator"], ["always_use_urandom"],
                                      dev_random)))

    if always_use_urandom:
        dev_random = False

    prng = randgen.get_prng(dev_random, fortuna)
    fh_target = open(file_path, "ab")

    for block in range(byte_blocks):
        data_random = prng.get_bytes(buffer_size)
        fh_target.write(data_random)
        time.sleep(delay)

    if byte_remainder > 0:
        data_random = prng.get_bytes(byte_remainder)
        fh_target.write(data_random)
        time.sleep(delay)

    fh_target.close()
Esempio n. 8
0
def validate_range(range_value_min=0, range_value_max=0, range_value_step=0):
    """
        Validate byte range values.
    """
    pv.intvalue(range_value_max, "maximum byte range", True, False, False)
    range_value_max = int(range_value_max)
    pv.intrange(range_value_min, "minimum byte range", 1,
                (int(range_value_max) - 1), False)
    pv.intvalue(range_value_step, "step byte range", True, False, True)

    range_value_min = int(range_value_min)
    range_value_step = int(range_value_step)
    range_length = range_value_max - range_value_min

    if range_length < 4:
        exception("The range must at least have a length of 4.")

    range_max_step = int(range_length / 2)
    pv.intrange(range_value_step, "step byte range", (range_max_step * -1),
                range_max_step, False)

    return range_value_min, range_value_max, range_value_step
Esempio n. 9
0
def replace(directory,
            file_ext,
            mode,
            spaces=8,
            recursive=False,
            overwrite=False,
            verbose=True):
    """
        Method to perform the replacement process.
    """
    pv.path(directory, "input", False, True)
    pv.string(file_ext, "file extension", False, None)
    mode = mode.lower()
    pv.compstr(mode, "mode", ["spaces", "tabs"])
    pv.intvalue(spaces, "spaces", True, False, False)

    directory = os.path.abspath(directory)
    spaces = int(spaces)
    num = 1

    if verbose:
        print "\nGathering files to process. Please wait.\n"

    list_files = common.get_files(directory, file_ext, recursive)
    just = len(str(len(list_files)))
    for file_input in list_files:
        if verbose:
            print "Processing file %s of %s: '%s'" % \
                (str(num).rjust(just, " "), str(len(list_files)), file_input)
            num += 1

        if overwrite:
            __replace_file(file_input, mode, spaces)
        else:
            __replace_copy(file_input, mode, spaces)

    if verbose:
        print "\nFinished.\n"
Esempio n. 10
0
    def get_bytes(self, amount):
        """
            Get a certain amount of pseudo-random bytes.
        """
        pv.intvalue(amount, "random bytes", True, False, False)
        amount = int(amount)

        if self.__fortuna_reseed_count == 0 or \
           self.__fortuna_reseed_count >= self.__fortuna_reseed_period:
            try:
                self.__fortuna.reseed(
                    self.__randgen.get_bytes(self.__fortuna_seed_bytes))
            except TypeError:
                common.exception("Version mismatch?")

            if self.__fortuna_reseed_count >= self.__fortuna_reseed_period:
                self.__fortuna_reseed_period = 1
            else:
                self.__fortuna_reseed_period += 1

        bytes_random = \
            bytearray(b"" + self.__fortuna.pseudo_random_data(amount))

        return bytes_random
Esempio n. 11
0
def generate_key_file(task_id,
                      file_path,
                      file_size,
                      buffer_size=4096,
                      bytes_random=0,
                      use_existing_key=False,
                      dev_random=False,
                      fortuna=False,
                      overwrite=False,
                      parts=1):
    """
        Create a task file first, then build the key file.
    """
    if use_existing_key:
        pv.path(file_path, "key", True, True)
    else:
        if not overwrite:
            pv.path(file_path, "key", True, False)

    pv.intvalue(file_size, "key file size", True, False, False)
    pv.intvalue(buffer_size, "buffer size", True, False, False)
    pv.intvalue(bytes_random, "random bytes", True, True, False)
    pv.intvalue(parts, "key file parts", True, False, False)

    file_path = os.path.abspath(file_path)
    file_size = int(file_size)
    buffer_size = int(buffer_size)
    bytes_random = int(bytes_random)

    if parts == 1:
        generation_type = "key generation"
    else:
        generation_type = "multi-part key generation"

    file_size = file_size + bytes_random

    common.build_task_file(task_id, file_path, file_size, None, 0, None, 0,
                           generation_type)

    build_file_key(file_path, file_size, buffer_size, bytes_random, False,
                   dev_random, fortuna, overwrite, parts)
Esempio n. 12
0
def progress_bar(width=0,
                 value=0,
                 description="",
                 padding=0,
                 block_char="=",
                 status_char="",
                 percent=False):
    """
        Draw a character based progress bar.
    """
    pv.intvalue(width, "width", True, False, False)
    pv.intvalue(value, "percent", True, True, False)
    pv.intvalue(padding, "padding", True, True, False)

    if len(description) > 0:
        description = description.ljust(padding, " ")
    if len(block_char) == 0:
        block_char = "="
    if len(status_char) > 0:
        status_char = status_char[0].rjust(2, " ")
        padding += 2
    if percent:
        pstatus = "(%s %%)".rjust(8, " ") % str(value).rjust(3, " ")
        padding += 8
    else:
        pstatus = ""

    blocks_max = width - (padding + 2)
    blocks = int((blocks_max * value) / 100)
    if blocks > blocks_max:
        blocks = blocks_max

    blocks_empty = blocks_max - blocks
    progress_bar = "%s[%s%s]%s%s" % \
        (description, (block_char * blocks), (" " * blocks_empty), pstatus,
         status_char)

    return progress_bar
Esempio n. 13
0
def get_status(task_id, delay=0):
    """
        Get the status of the Erfr process with the given task ID.
    """
    task_file = common.get_task_file(task_id)
    pv.intrange(task_id, "task ID", 1, common.get_max_tasks(), False)
    pv.intvalue(delay, "delay", True, True, False)

    delay = int(delay)
    task_id = int(task_id)
    progress_key = True
    process_type = ""
    process_type_list = ["encryption", "decryption", "key generation"]
    file_input_path = ""
    file_input_size = 0
    file_key_path = ""
    file_key_size = 0
    file_output_path = ""
    file_output_size = 0
    valid_type = False

    if not common.file_exists(task_file):
        common.exception("No process is running with the given task ID.")

    dict_contents = __read_content(task_file)
    process_type = dict_contents["process_type"]
    if process_type == "":
        common.exception("The process type cannot be empty.")

    for item in process_type_list:
        if process_type == item:
            valid_type = True

    if not valid_type:
        common.exception("The process type '%s' is not supported." \
                         % process_type)

    file_input_path = dict_contents["file_input_path"]
    file_input_size = dict_contents["file_input_size"]

    if "crypt" in process_type:
        file_key_path = dict_contents["file_key_path"]
        file_key_size = dict_contents["file_key_size"]
        file_output_path = dict_contents["file_output_path"]
        file_output_size = dict_contents["file_output_size"]
        if process_type == "decryption":
            progress_key = False

    print
    print "Monitoring Erfr %s process with task ID %s." % \
              (process_type, task_id)
    if delay > 0:
        if delay == 1:
            print "Refreshing the process status every second."
        else:
            print "Refreshing the process status every %s seconds." % \
                  str(delay)

    print
    print "-" * 78
    if file_key_path == "" and file_output_path == "":
        __monitor_file(task_file, file_input_path, file_input_size,
                       "File name", delay, True)
    else:
        __monitor_file(task_file, file_input_path, file_input_size,
                       "Input file", delay, False)
        print
        __monitor_file(task_file, file_key_path, file_key_size, "Key file",
                       delay, progress_key)
        print
        __monitor_file(task_file, file_output_path, file_output_size,
                       "Output file", delay, True)
    print "-" * 78
    print

    if delay > 0:
        print "Process finished."
Esempio n. 14
0
def rename_files(directory, rename_mode, separator=" ", recursive=False,
                 padding=0, exclude=None, pattern=None, ignore_case=True,
                 regex_syntax=False, report_file=None, ignore_symlinks=False,
                 ignore_file_ext=False, custom_name=None, step=1,
                 order_by=None):
    """
        Rename the base name of files based on the name of the directory where
        they are stored in and add a numeric ID.
    """
    pv.path(directory, "given", False, True)
    pv.compstr(rename_mode, "rename mode",
               ["fill-gaps", "increase", "keep-order", "rename-new"])
    pv.intrange(padding, "padding", 0, 12, True)
    pv.string(separator, "seperator", False, common.get_invalid_chars())
    pv.intvalue(step, "step", True, False, False)

    if not order_by == None:
        pv.compstr(order_by, "order by", ["accessed", "created", "modified"])
        if not rename_mode == "keep-order":
            raise Exception("The order-by argument can only be used in " \
                            "combination with keep-order mode.")

    step = int(step)
    rename_mode = rename_mode.lower()
    directory = os.path.abspath(directory)
    if not directory.endswith(os.path.sep):
        directory += os.path.sep

    if report_file == None:
        simulate = False
    else:
        pv.path(report_file, "report", True, False)
        report_file = os.path.abspath(report_file)
        simulate = True

    if not custom_name == None:
        pv.string(custom_name, "custom file name", False,
                  common.get_invalid_chars())

    time_start = dt.now()

    list_content = []
    list_excluded = []
    list_renamed = []
    list_skipped = []
    regex = None
    if not pattern == None:
        regex = common.compile_regex(pattern, ignore_case, regex_syntax)

    list_content, list_excluded = \
        common.get_files(directory, recursive, ignore_case, regex, exclude,
                         ignore_symlinks, order_by)

    for item in list_content:
        list_files = item[1]
        if rename_mode == "fill-gaps":
            list_renamed, list_skipped = \
                __rename_files_fill(list_files, list_renamed, list_skipped,
                                    separator, padding, True, ignore_file_ext,
                                    custom_name, step)
        elif rename_mode == "rename-new":
            list_renamed, list_skipped = \
                __rename_files_fill(list_files, list_renamed, list_skipped,
                                    separator, padding, False,
                                    ignore_file_ext, custom_name, step)
        elif rename_mode == "keep-order":
            list_renamed, list_skipped = \
                __rename_files_keep_order(list_files, list_renamed,
                                          list_skipped, separator, padding,
                                          ignore_file_ext, custom_name, step,
                                          order_by)
        else:
            raise Exception("An invalid rename mode was given.")

    if simulate:
        if padding == 0:
            padding = "Set automatically"
        else:
            padding = str(padding)

        explicit = None
        if exclude == None:
            exclude = False
            explicit = False
        elif exclude:
            explicit = False
        else:
            explicit = True

        if order_by == "accessed":
            order_by = "Access time"
        elif order_by == "created":
            order_by = "Creation time"
        elif order_by == "modified":
            order_by = "Modification time"
        else:
            order_by = "False"

        list_header = []
        list_header.append("Nomen File Renamer simulation report")
        list_header.append(["Report file name:", report_file])
        list_header.append(["Directory:", directory])
        list_header.append(["Recursive:", recursive])
        list_header.append(["Ignore symlinks:", ignore_symlinks])
        list_header.append(["Rename mode:", rename_mode.capitalize()])
        list_header.append(["Order by time:", order_by])
        list_header.append(["Separator:", "\"" + separator + "\" " \
                            "(without double quotes)"])
        list_header.append(["Numeric padding:", padding])
        list_header.append(["Step size:", step])
        list_header.append(["Exclude files:", exclude])
        list_header.append(["Explicit files:", explicit])
        list_header.append(["Pattern:", pattern])
        list_header.append(["Ignore case:", ignore_case])
        list_header.append(["Regex syntax:", regex_syntax])

        common.report(report_file, list_header, list_renamed, list_excluded,
                      list_skipped, time_start)
    else:
        common.rename(list_renamed)
Esempio n. 15
0
    def __prepare_process(self, task_id, file_input, file_key, file_output,
                          buffer_size, existing_key, overwrite, obfuscate_enc,
                          obfuscate_key, fortuna, dev_random, rotate_min,
                          rotate_max, rotate_step, rotate_mod, reverse_bytes,
                          sbox, skip_checks):
        """
            Prepare the requested process by checking the given parameters
            and execute the appropriate method.
        """
        if not skip_checks:
            pv.path(file_input, "input", True, True)
            if not overwrite:
                if self.__encrypt:
                    pv.path(file_key, "key", True, existing_key)
                pv.path(file_output, "output", True, False)
            pv.compfile(file_input, "input",
                        [[file_key, "key"], [file_output, "output"]])

        pv.intvalue(buffer_size, "buffer size", True, False, False)
        pv.intvalue(obfuscate_enc, "encrypted file obfuscation byte", True,
                    True, False)
        pv.intvalue(obfuscate_key, "key file obfuscation byte", True, True,
                    False)

        if rotate_min == None and rotate_max == None and rotate_step == None:
            self.__rotate = False
        else:
            pv.intvalue(rotate_min, "minimum rotation", True, True, False)
            pv.intvalue(rotate_max, "maximum rotation", True, True, False)
            pv.intvalue(rotate_min, "rotation step", True, False, True)
            range_value_min, range_value_max, range_value_step = \
                common.validate_range(rotate_min, rotate_max, rotate_step)
            self.__rotate = True

        if reverse_bytes == None:
            self.__reverse = False
        else:
            pv.intrange(reverse_bytes, "reverse byte", 2, None, False)
            self.__reverse = True

        self.__task_id = task_id
        self.__fortuna = fortuna
        self.__dev_random = dev_random
        self.__file_input = os.path.abspath(file_input)
        self.__file_key = os.path.abspath(file_key)
        self.__file_output = os.path.abspath(file_output)
        self.__buffer_size = int(buffer_size)
        self.__existing_key = existing_key
        self.__overwrite = overwrite
        self.__obfuscate_enc = int(obfuscate_enc)
        self.__obfuscate_key = int(obfuscate_key)
        self.__sbox = sbox

        if self.__rotate:
            self.__rotate_min = int(rotate_min)
            self.__rotate_max = int(rotate_max)
            self.__rotate_step = int(rotate_step)
            self.__rotate_mod = rotate_mod
            self.__rotate_obj = rt.Rotate(self.__rotate_min, self.__rotate_max,
                                          self.__rotate_step,
                                          self.__rotate_mod)
        if self.__reverse:
            self.__reverse_bytes = int(reverse_bytes)
Esempio n. 16
0
def build_task_file(task_id, file_input_path, file_input_size, file_key_path,
                    file_key_size, file_output_path, file_output_size,
                    process_type):
    """
        Build a temporary task file using the Erfr task ID containing the
        relevant information of the corresponding encryption or decryption
        ("crypt_process"), key generation or obfuscation process.
    """

    if task_id == None:
        return

    pv.intrange(task_id, "task ID", 1, get_max_tasks(), False)
    pv.intvalue(file_input_size, "input file size", True, False, False)

    if file_input_path == None:
        exception("The input file path is missing.")

    if "crypt" in process_type:
        pv.intvalue(file_key_size, "key file size", True, True, False)
        if file_key_path == None:
            exception("The key file path is missing.")

        pv.intvalue(file_output_size, "output file size", True, True, False)
        if file_output_path == None:
            exception("The output file path is missing.")

    task = __validate_files(file_input_path, file_key_path, file_output_path)
    if not task == 0:
        exception("At least one of the given files already is in use by " \
                  "another Erfr process with ID %s." % task)

    task_file = get_task_file(task_id)
    if file_exists(task_file):
        exception("The task file for the given ID already exists.")

    string = __build_content_string(file_input_path, file_input_size,
                                    file_key_path, file_key_size,
                                    file_output_path, file_output_size,
                                    process_type)

    encode_file = bool(int(global_config(["TaskID"], ["encode_base64"], 1)))

    # Check if the file shall be encoded and then run the appropriate code for
    # the Python framework used
    if encode_file:
        if sys.version_info[0] == 2:
            content = base64.encodestring(string)
        elif sys.version_info[0] > 2:
            temp = string.encode(sys.getdefaultencoding())
            content = base64.encodestring(temp)
    else:
        if sys.version_info[0] == 2:
            content = string
        elif sys.version_info[0] > 2:
            content = bytes(string, sys.getdefaultencoding())

    try:
        fh_task = open(task_file, "wb")
        fh_task.write(content)
        fh_task.close()
    except:
        print "Failed to create task file. Due to this, the monitor " + \
              "component will not work on this process."
Esempio n. 17
0
def build_file_key(file_path,
                   file_size,
                   buffer_size=4096,
                   bytes_random=0,
                   use_existing_key=False,
                   dev_random=False,
                   fortuna=False,
                   overwrite=False,
                   parts=1):
    """
        Build a key file which contains the random values which are required
        to encrypt the input file.
    """
    delay = common.get_delay()

    if use_existing_key:
        pv.path(file_path, "key", True, True)
    else:
        if not overwrite:
            pv.path(file_path, "key", True, False)
            pv.path(file_path + ".001", "key part", True, False)
    file_path = os.path.abspath(file_path)

    pv.intvalue(file_size, "key file size", True, False, False)
    pv.intvalue(buffer_size, "buffer size", True, False, False)
    pv.intvalue(bytes_random, "random bytes", True, True, False)
    pv.intvalue(parts, "key file parts", True, False, False)

    file_size = int(file_size)
    buffer_size = int(buffer_size)
    bytes_random = int(bytes_random)
    parts = int(parts)

    if parts > (file_size + bytes_random):
        common.exception("The file is too small for given number of key " \
                         "parts.")
    elif parts > 999:
        common.exception("The number of key parts must be less than 1000.")

    if not use_existing_key:
        key_path = file_path
        part_id = 0
        part_temp = int(file_size + bytes_random)
        part_size = part_temp / parts
        part_last = part_temp - (part_size * (parts - 1))
        for part in range(parts):
            if parts > 1:
                part_id += 1
                key_path = file_path + "." + str(part_id).rjust(3, "0")
                if part_id < parts:
                    file_size = part_size
                else:
                    file_size = part_last

            data_key = bytearray(b"")
            fh_key = open(key_path, "wb")
            byte_blocks = int(file_size / buffer_size)
            byte_remainder = file_size % buffer_size

            prng = randgen.get_prng(dev_random, fortuna)
            for block in range(byte_blocks):
                data_key = prng.get_bytes(buffer_size)
                fh_key.write(data_key)
                time.sleep(delay)

            if byte_remainder > 0:
                data_key = prng.get_bytes(byte_remainder)
                fh_key.write(data_key)
                time.sleep(delay)

            fh_key.close()

    if parts == 1:
        if bytes_random > 0:
            obfuscator.add_random_bytes(file_path, buffer_size, bytes_random,
                                        dev_random)