// File: /workspace/github_c_makefile_star2_O3/TimeToogo[P]ff-proxy/client/c/crypto.c
// Function: ff_client_encrypt_request
bool ff_client_encrypt_request(struct ff_request *request, struct ff_encryption_config *config)
{
    uint8_t encryption_mode = FF_CRYPTO_MODE_AES_256_GCM;
    uint8_t key_derive_mode = FF_KEY_DERIVE_MODE_PBKDF2;
    bool ret_val;
    uint8_t *iv = NULL;
    uint16_t iv_len = 0;
    uint8_t *tag = NULL;
    uint16_t tag_len = 0;
    uint8_t *salt = NULL;
    uint16_t salt_len = 16;

    if (config == NULL)
    {
        ff_log(FF_WARNING, "Encountered encrypted request and no pre-shared-key was set");
        goto error;
    }

    if (!ff_client_encrypt_request_aes_256_gcm_pbkdf2(request, config, &iv, &iv_len, &tag, &tag_len, &salt, &salt_len))
    {
        goto error;
    }

    request->options[request->options_length] = ff_request_option_node_alloc();
    request->options[request->options_length]->type = FF_REQUEST_OPTION_TYPE_ENCRYPTION_MODE;
    request->options[request->options_length]->length = 1;
    ff_request_option_load_buff(request->options[request->options_length], 1, &encryption_mode);
    request->options_length++;

    request->options[request->options_length] = ff_request_option_node_alloc();
    request->options[request->options_length]->type = FF_REQUEST_OPTION_TYPE_ENCRYPTION_IV;
    request->options[request->options_length]->length = iv_len;
    ff_request_option_load_buff(request->options[request->options_length], iv_len, iv);
    request->options_length++;

    request->options[request->options_length] = ff_request_option_node_alloc();
    request->options[request->options_length]->type = FF_REQUEST_OPTION_TYPE_ENCRYPTION_TAG;
    request->options[request->options_length]->length = tag_len;
    ff_request_option_load_buff(request->options[request->options_length], tag_len, tag);
    request->options_length++;

    request->options[request->options_length] = ff_request_option_node_alloc();
    request->options[request->options_length]->type = FF_REQUEST_OPTION_TYPE_KEY_DERIVE_MODE;
    request->options[request->options_length]->length = 1;
    ff_request_option_load_buff(request->options[request->options_length], 1, &key_derive_mode);
    request->options_length++;

    request->options[request->options_length] = ff_request_option_node_alloc();
    request->options[request->options_length]->type = FF_REQUEST_OPTION_TYPE_KEY_DERIVE_SALT;
    request->options[request->options_length]->length = salt_len;
    ff_request_option_load_buff(request->options[request->options_length], salt_len, salt);
    request->options_length++;

    goto done;

error:
    ret_val = false;
    goto cleanup;

done:
    ret_val = true;
    goto cleanup;

cleanup:
    if (iv != NULL)
    {
        FREE(iv);
    }

    if (tag != NULL)
    {
        FREE(tag);
    }

    if (salt != NULL)
    {
        FREE(salt);
    }

    return ret_val;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x20, %rsp
movb $0x1, %al
movb %al, -0x22(%rbp)
movb %al, -0x21(%rbp)
xorl %eax, %eax
movq %rax, -0x40(%rbp)
movw %ax, -0x28(%rbp)
movq %rax, -0x38(%rbp)
movw %ax, -0x26(%rbp)
movq %rax, -0x30(%rbp)
movw $0x10, -0x24(%rbp)
testq %rsi, %rsi
je 0x328f
movq %rdi, %r14
leaq -0x24(%rbp), %rax
leaq -0x30(%rbp), %r10
leaq -0x40(%rbp), %rdx
leaq -0x28(%rbp), %rcx
leaq -0x38(%rbp), %r8
leaq -0x26(%rbp), %r9
pushq %rax
pushq %r10
callq 0x32e2
addq $0x10, %rsp
movl %eax, %ebx
testb %al, %al
je 0x32a6
callq 0x3b40
movq 0x30(%r14), %rcx
movzbl 0x28(%r14), %edx
shll $0x3, %edx
movq %rax, (%rcx,%rdx)
movq 0x30(%r14), %rax
movq (%rax,%rdx), %rdi
movl $0x1, (%rdi)
movw $0x1, %r12w
movw %r12w, 0x4(%rdi)
leaq -0x22(%rbp), %rdx
movl $0x1, %esi
callq 0x3b64
incb 0x28(%r14)
callq 0x3b40
movq 0x30(%r14), %rcx
movzbl 0x28(%r14), %edx
shll $0x3, %edx
movq %rax, (%rcx,%rdx)
movq 0x30(%r14), %rax
movq (%rax,%rdx), %rdi
movl $0x2, (%rdi)
movzwl -0x28(%rbp), %esi
movw %si, 0x4(%rdi)
movq -0x40(%rbp), %r15
movq %r15, %rdx
callq 0x3b64
incb 0x28(%r14)
callq 0x3b40
movq 0x30(%r14), %rcx
movzbl 0x28(%r14), %edx
shll $0x3, %edx
movq %rax, (%rcx,%rdx)
movq 0x30(%r14), %rax
movq (%rax,%rdx), %rdi
movl $0x3, (%rdi)
movzwl -0x26(%rbp), %esi
movw %si, 0x4(%rdi)
movq -0x38(%rbp), %rdx
callq 0x3b64
incb 0x28(%r14)
callq 0x3b40
movq 0x30(%r14), %rcx
movzbl 0x28(%r14), %edx
shll $0x3, %edx
movq %rax, (%rcx,%rdx)
movq 0x30(%r14), %rax
movq (%rax,%rdx), %rdi
movl $0x5, (%rdi)
movw %r12w, 0x4(%rdi)
leaq -0x21(%rbp), %rdx
movl $0x1, %esi
callq 0x3b64
incb 0x28(%r14)
callq 0x3b40
movq 0x30(%r14), %rcx
movzbl 0x28(%r14), %edx
shll $0x3, %edx
movq %rax, (%rcx,%rdx)
movq 0x30(%r14), %rax
movq (%rax,%rdx), %rdi
movl $0x6, (%rdi)
movzwl -0x24(%rbp), %esi
movw %si, 0x4(%rdi)
movq -0x30(%rbp), %rdx
callq 0x3b64
incb 0x28(%r14)
jmp 0x32aa
leaq 0x21fa(%rip), %rsi      # 0x5490
xorl %ebx, %ebx
movl $0x3, %edi
xorl %eax, %eax
callq 0x3a20
jmp 0x32b7
movq -0x40(%rbp), %r15
testq %r15, %r15
je 0x32b7
movq %r15, %rdi
callq 0x21d0
movq -0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x32c5
callq 0x21d0
movq -0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x32d3
callq 0x21d0
movl %ebx, %eax
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq