user: Demonstrate the C code that generates the assembly output below:

```asm
<file_encrypt>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x1000,%rsp
  orq    $0x0,(%rsp)
  sub    $0x1000,%rsp
  orq    $0x0,(%rsp)
  sub    $0x58,%rsp
  mov    %r8,(%rsp)
  lea    0x20(%rsp),%r12
  mov    %rdi,%r14
  mov    %rdx,%rdi
  mov    %r9,0x8(%rsp)
  mov    %r12,%rdx
  mov    %rcx,%rbx
  mov    %fs:0x28,%rax
  mov    %rax,0x2048(%rsp)
  xor    %eax,%eax
  call   <pbkdf2@plt>
  xor    %eax,%eax
  call   <EVP_CIPHER_CTX_new@plt>
  test   %rax,%rax
  je     L52
  mov    %rax,%r13
  xor    %eax,%eax
  call   <EVP_aes_256_gcm@plt>
  xor    %r8d,%r8d
  xor    %ecx,%ecx
  xor    %edx,%edx
  mov    %rax,%rsi
  mov    %r13,%rdi
  call   <EVP_EncryptInit_ex@plt>
  cmp    $0x1,%eax
  jne    L52
  mov    D10(%rip),%rax
  xor    %ecx,%ecx
  mov    $0x10,%edx
  mov    %r13,%rdi
  mov    (%rax),%esi
  call   <EVP_CIPHER_CTX_ctrl@plt>
  cmp    $0x1,%eax
  jne    L52
  xor    %edx,%edx
  xor    %esi,%esi
  mov    %rbx,%r8
  mov    %r12,%rcx
  mov    %r13,%rdi
  call   <EVP_EncryptInit_ex@plt>
  cmp    $0x1,%eax
  jne    L52
  lea    0x40(%rsp),%rbp
  lea    0x1c(%rsp),%r15
  lea    0x1040(%rsp),%r12
  jmp    L3
  nopl   0x0(%rax)
L108:
  mov    (%rsp),%rcx
  mov    0x1c(%rsp),%edx
  mov    $0x1,%esi
  mov    %r12,%rdi
  call   <fwrite@plt>
  cmp    $0x1000,%ebx
  jne    L51
L3:
  mov    %r14,%rcx
  mov    $0x1000,%edx
  mov    $0x1,%esi
  mov    %rbp,%rdi
  call   <fread@plt>
  mov    %rbp,%rcx
  mov    %r15,%rdx
  mov    %r12,%rsi
  mov    %eax,%r8d
  mov    %r13,%rdi
  mov    %eax,%ebx
  call   <EVP_EncryptUpdate@plt>
  cmp    $0x1,%eax
  je     L108
L52:
  mov    $0xffffffff,%eax
L85:
  mov    0x2048(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L56
  add    $0x2058,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopw   0x0(%rax,%rax,1)
L51:
  mov    %r15,%rdx
  mov    %r12,%rsi
  mov    %r13,%rdi
  call   <EVP_EncryptFinal_ex@plt>
  cmp    $0x1,%eax
  jne    L52
  mov    D2(%rip),%rax
  mov    0x8(%rsp),%rcx
  mov    $0x10,%edx
  mov    %r13,%rdi
  mov    (%rax),%esi
  call   <EVP_CIPHER_CTX_ctrl@plt>
  cmp    $0x1,%eax
  jne    L52
  mov    %r13,%rdi
  call   <EVP_CIPHER_CTX_free@plt>
  xor    %eax,%eax
  jmp    L85
L56:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int file_encrypt(FILE *f, unsigned char *salt, char *pwd, unsigned char *iv, FILE *fout, unsigned char *tag) {
  unsigned char key[32];
  unsigned char in_buff[4096];
  unsigned char out_buff[4096];
  int in_len, out_len;
  EVP_CIPHER_CTX *ctx;
  pbkdf2(pwd, salt, key);
  if (!(ctx = EVP_CIPHER_CTX_new()))
    return -1;
  if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
    return -1;
  if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL))
    return -1;
  if (1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
    return -1;
  do {
    in_len = fread(in_buff, 1, 4096, f);
    if (1 != EVP_EncryptUpdate(ctx, out_buff, &out_len, in_buff, in_len))
      return -1;
    fwrite(out_buff, 1, out_len, fout);
  } while (in_len == 4096);
  if (1 != EVP_EncryptFinal_ex(ctx, out_buff, &out_len))
    return -1;
  if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
    return -1;
  EVP_CIPHER_CTX_free(ctx);
  return 0;
}
```