// File: /workspace/github_c_makefile_star2_O2/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 %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
andq $0x0, -0x48(%rbp)
andw $0x0, -0x30(%rbp)
andq $0x0, -0x40(%rbp)
andw $0x0, -0x2e(%rbp)
movb $0x1, %al
andq $0x0, -0x38(%rbp)
movb %al, -0x2a(%rbp)
movb %al, -0x29(%rbp)
movw $0x10, -0x2c(%rbp)
testq %rsi, %rsi
je 0x3072
movq %rdi, %r14
leaq -0x2c(%rbp), %rax
leaq -0x38(%rbp), %r10
leaq -0x48(%rbp), %rdx
leaq -0x30(%rbp), %rcx
leaq -0x40(%rbp), %r8
leaq -0x2e(%rbp), %r9
pushq %rax
pushq %r10
callq 0x30b6
popq %rcx
popq %rdx
movl %eax, %ebx
testb %al, %al
je 0x3087
callq 0x38cc
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, %r13w
movw %r13w, 0x4(%rdi)
pushq $0x1
popq %r12
leaq -0x2a(%rbp), %rdx
movl %r12d, %esi
callq 0x38e7
incb 0x28(%r14)
callq 0x38cc
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 -0x30(%rbp), %esi
movw %si, 0x4(%rdi)
movq -0x48(%rbp), %r15
movq %r15, %rdx
callq 0x38e7
incb 0x28(%r14)
callq 0x38cc
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 -0x2e(%rbp), %esi
movw %si, 0x4(%rdi)
movq -0x40(%rbp), %rdx
callq 0x38e7
incb 0x28(%r14)
callq 0x38cc
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 %r13w, 0x4(%rdi)
leaq -0x29(%rbp), %rdx
movl %r12d, %esi
callq 0x38e7
incb 0x28(%r14)
callq 0x38cc
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 -0x2c(%rbp), %esi
movw %si, 0x4(%rdi)
movq -0x38(%rbp), %rdx
callq 0x38e7
incb 0x28(%r14)
jmp 0x308b
leaq 0x2417(%rip), %rsi      # 0x5490
xorl %ebx, %ebx
pushq $0x3
popq %rdi
xorl %eax, %eax
callq 0x37ac
jmp 0x3093
movq -0x48(%rbp), %r15
movq %r15, %rdi
callq 0x21d0
movq -0x40(%rbp), %rdi
callq 0x21d0
movq -0x38(%rbp), %rdi
callq 0x21d0
movl %ebx, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq