user: 请显示与下面列出的汇编代码相匹配的C语言实现:

```asm
<file_encrypt>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x1000,%rsp
  orq    $0x0,(%rsp)
  sub    $0x1000,%rsp
  orq    $0x0,(%rsp)
  sub    $0x70,%rsp
  mov    %rdi,-0x2048(%rbp)
  mov    %rsi,-0x2050(%rbp)
  mov    %rdx,-0x2058(%rbp)
  mov    %rcx,-0x2060(%rbp)
  mov    %r8,-0x2068(%rbp)
  mov    %r9,-0x2070(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  lea    -0x2030(%rbp),%rdx
  mov    -0x2050(%rbp),%rcx
  mov    -0x2058(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <pbkdf2@plt>
  mov    $0x0,%eax
  call   <EVP_CIPHER_CTX_new@plt>
  mov    %rax,-0x2038(%rbp)
  cmpq   $0x0,-0x2038(%rbp)
  jne    L65
  mov    $0xffffffff,%eax
  jmp    L157
L65:
  mov    $0x0,%eax
  call   <EVP_aes_256_gcm@plt>
  mov    %rax,%rsi
  mov    -0x2038(%rbp),%rax
  mov    $0x0,%r8d
  mov    $0x0,%ecx
  mov    $0x0,%edx
  mov    %rax,%rdi
  call   <EVP_EncryptInit_ex@plt>
  cmp    $0x1,%eax
  je     L100
  mov    $0xffffffff,%eax
  jmp    L157
L100:
  mov    D2(%rip),%rax
  mov    (%rax),%esi
  mov    -0x2038(%rbp),%rax
  mov    $0x0,%ecx
  mov    $0x10,%edx
  mov    %rax,%rdi
  call   <EVP_CIPHER_CTX_ctrl@plt>
  cmp    $0x1,%eax
  je     L102
  mov    $0xffffffff,%eax
  jmp    L157
L102:
  mov    -0x2060(%rbp),%rcx
  lea    -0x2030(%rbp),%rdx
  mov    -0x2038(%rbp),%rax
  mov    %rcx,%r8
  mov    %rdx,%rcx
  mov    $0x0,%edx
  mov    $0x0,%esi
  mov    %rax,%rdi
  call   <EVP_EncryptInit_ex@plt>
  cmp    $0x1,%eax
  je     L128
  mov    $0xffffffff,%eax
  jmp    L157
L128:
  mov    -0x2048(%rbp),%rdx
  lea    -0x2010(%rbp),%rax
  mov    %rdx,%rcx
  mov    $0x1000,%edx
  mov    $0x1,%esi
  mov    %rax,%rdi
  call   <fread@plt>
  mov    %eax,-0x203c(%rbp)
  mov    -0x203c(%rbp),%edi
  lea    -0x2010(%rbp),%rcx
  lea    -0x2040(%rbp),%rdx
  lea    -0x1010(%rbp),%rsi
  mov    -0x2038(%rbp),%rax
  mov    %edi,%r8d
  mov    %rax,%rdi
  call   <EVP_EncryptUpdate@plt>
  cmp    $0x1,%eax
  je     L10
  mov    $0xffffffff,%eax
  jmp    L157
L10:
  mov    -0x2040(%rbp),%edx
  mov    -0x2068(%rbp),%rcx
  lea    -0x1010(%rbp),%rax
  mov    $0x1,%esi
  mov    %rax,%rdi
  call   <fwrite@plt>
  cmpl   $0x1000,-0x203c(%rbp)
  je     L128
  lea    -0x2040(%rbp),%rdx
  lea    -0x1010(%rbp),%rcx
  mov    -0x2038(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <EVP_EncryptFinal_ex@plt>
  cmp    $0x1,%eax
  je     L11
  mov    $0xffffffff,%eax
  jmp    L157
L11:
  mov    D5(%rip),%rax
  mov    (%rax),%esi
  mov    -0x2070(%rbp),%rdx
  mov    -0x2038(%rbp),%rax
  mov    %rdx,%rcx
  mov    $0x10,%edx
  mov    %rax,%rdi
  call   <EVP_CIPHER_CTX_ctrl@plt>
  cmp    $0x1,%eax
  je     L9
  mov    $0xffffffff,%eax
  jmp    L157
L9:
  mov    -0x2038(%rbp),%rax
  mov    %rax,%rdi
  call   <EVP_CIPHER_CTX_free@plt>
  mov    $0x0,%eax
L157:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L71
  call   <__stack_chk_fail@plt>
L71:
  leave
  ret
```

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;
}
```