user: 请将这段汇编代码片段转换成等效的C代码：

```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    $0x48,%rsp
  mov    %rdi,%r13
  mov    %rdx,%rdi
  mov    %rcx,%rbx
  mov    %r8,%r14
  mov    %r9,%r15
  mov    %fs:0x28,%rax
  mov    %rax,0x2038(%rsp)
  xor    %eax,%eax
  lea    0x10(%rsp),%rdx
  call   <pbkdf2@plt>
  mov    $0x0,%eax
  call   <EVP_CIPHER_CTX_new@plt>
  test   %rax,%rax
  je     L120
  mov    %rax,%r12
  mov    $0x0,%eax
  call   <EVP_aes_256_gcm@plt>
  mov    %rax,%rsi
  mov    $0x0,%r8d
  mov    $0x0,%ecx
  mov    $0x0,%edx
  mov    %r12,%rdi
  call   <EVP_EncryptInit_ex@plt>
  cmp    $0x1,%eax
  jne    L82
  mov    $0x0,%ecx
  mov    $0x10,%edx
  mov    D0(%rip),%rax
  mov    (%rax),%esi
  mov    %r12,%rdi
  call   <EVP_CIPHER_CTX_ctrl@plt>
  cmp    $0x1,%eax
  jne    L1
  lea    0x10(%rsp),%rcx
  mov    %rbx,%r8
  mov    $0x0,%edx
  mov    $0x0,%esi
  mov    %r12,%rdi
  call   <EVP_EncryptInit_ex@plt>
  cmp    $0x1,%eax
  jne    L144
  lea    0x30(%rsp),%rbp
L18:
  mov    %r13,%rcx
  mov    $0x1000,%edx
  mov    $0x1,%esi
  mov    %rbp,%rdi
  call   <fread@plt>
  mov    %eax,%ebx
  lea    0xc(%rsp),%rdx
  lea    0x1030(%rsp),%rsi
  mov    %eax,%r8d
  mov    %rbp,%rcx
  mov    %r12,%rdi
  call   <EVP_EncryptUpdate@plt>
  cmp    $0x1,%eax
  jne    L63
  lea    0x1030(%rsp),%rdi
  mov    %r14,%rcx
  mov    0xc(%rsp),%edx
  mov    $0x1,%esi
  call   <fwrite@plt>
  cmp    $0x1000,%ebx
  je     L18
  lea    0xc(%rsp),%rdx
  lea    0x1030(%rsp),%rsi
  mov    %r12,%rdi
  call   <EVP_EncryptFinal_ex@plt>
  cmp    $0x1,%eax
  jne    L112
  mov    %r15,%rcx
  mov    $0x10,%edx
  mov    D12(%rip),%rax
  mov    (%rax),%esi
  mov    %r12,%rdi
  call   <EVP_CIPHER_CTX_ctrl@plt>
  cmp    $0x1,%eax
  jne    L146
  mov    %r12,%rdi
  call   <EVP_CIPHER_CTX_free@plt>
  mov    $0x0,%eax
  jmp    L33
L120:
  mov    $0xffffffff,%eax
  jmp    L33
L82:
  mov    $0xffffffff,%eax
  jmp    L33
L1:
  mov    $0xffffffff,%eax
  jmp    L33
L144:
  mov    $0xffffffff,%eax
  jmp    L33
L63:
  mov    $0xffffffff,%eax
L33:
  mov    0x2038(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L48
  add    $0x2048,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L112:
  mov    $0xffffffff,%eax
  jmp    L33
L146:
  mov    $0xffffffff,%eax
  jmp    L33
L48:
  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;
}
```