user: Translate the below assembly code into C programming language:

```asm
<is_fido_security_token_desc>:
  endbr64
  test   %rsi,%rsi
  je     L153
  push   %rbx
  mov    %rdi,%rcx
  xor    %eax,%eax
  xor    %r10d,%r10d
L159:
  mov    (%rcx,%rax,4),%edx
  lea    0x0(,%rax,4),%rdi
  lea    0x1(%rax),%r8
  cmp    $0xfe,%edx
  jne    L69
  cmp    %r8,%rsi
  ja     L155
L218:
  mov    D0(%rip),%rax
  pop    %rbx
  mov    (%rax),%eax
  neg    %eax
  ret
  nop
L69:
  mov    %edx,%r9d
  mov    %edx,%r11d
  and    $0x3,%edx
  sar    $0x2,%r9d
  sar    $0x4,%r11d
  and    $0x3,%r9d
  cmp    $0x3,%edx
  je     L41
  movslq %edx,%rbx
  lea    (%rbx,%r8,1),%rax
  cmp    %rsi,%rax
  ja     L218
  test   %edx,%edx
  je     L70
  mov    0x4(%rcx,%rdi,1),%edx
  cmp    $0x2,%rbx
  jne    L30
  mov    0x8(%rcx,%rdi,1),%edi
  shl    $0x8,%edi
  or     %edi,%edx
L30:
  test   %r11d,%r11d
  sete   %dil
  cmp    $0x1,%r9d
  jne    L141
  test   %dil,%dil
  je     L141
  shl    $0x10,%edx
  mov    %edx,%r10d
  jmp    L259
  nopl   0x0(%rax,%rax,1)
L155:
  mov    0x4(%rcx,%rdi,1),%edx
  add    $0x3,%edx
  movslq %edx,%rdx
  add    %rdx,%rax
L259:
  cmp    %rsi,%rax
  jb     L159
  xor    %eax,%eax
  pop    %rbx
  ret
  nopw   0x0(%rax,%rax,1)
L41:
  add    $0x5,%rax
  cmp    %rsi,%rax
  ja     L218
  mov    0x8(%rcx,%rdi,1),%r8d
  mov    0xc(%rcx,%rdi,1),%edx
  shl    $0x8,%r8d
  or     0x4(%rcx,%rdi,1),%r8d
  mov    0x10(%rcx,%rdi,1),%edi
  shl    $0x10,%edx
  or     %r8d,%edx
  shl    $0x18,%edi
  or     %edx,%edi
  test   %r11d,%r11d
  sete   %dl
  cmp    $0x1,%r9d
  jne    L160
  test   %dl,%dl
  jne    L218
L160:
  cmp    $0x2,%r9d
  jne    L259
  test   %dl,%dl
  je     L259
  mov    %edi,%r10d
L164:
  cmp    $0xf1d00001,%r10d
  jne    L259
  mov    $0x1,%eax
  pop    %rbx
  ret
  nopw   0x0(%rax,%rax,1)
L70:
  test   %r11d,%r11d
  sete   %al
  cmp    $0x1,%r9d
  jne    L79
  test   %al,%al
  je     L79
  xor    %r10d,%r10d
  mov    %r8,%rax
  jmp    L259
L79:
  cmp    $0x2,%r9d
  jne    L102
  test   %al,%al
  je     L102
  mov    %r8,%rax
L263:
  mov    %dx,%r10w
  jmp    L164
L153:
  xor    %eax,%eax
  ret
L102:
  mov    %r8,%rax
  jmp    L259
L141:
  cmp    $0x2,%r9d
  jne    L259
  test   %dil,%dil
  jne    L263
  jmp    L259
```

assistant: ```c
int is_fido_security_token_desc(const uint8_t *desc, size_t desc_len) {
  uint32_t usage = 0;
  for (size_t pos = 0; pos < desc_len;) {
    uint8_t tag, type, size_code;
    size_t size;
    uint32_t value;
    if (desc[pos] == 0xfeu) {
      if (pos + 1 >= desc_len)
        return -EINVAL;
      pos += desc[pos + 1] + 3;
      continue;
    }
    tag = desc[pos] >> 4;
    type = (desc[pos] >> 2) & 0x3;
    size_code = desc[pos] & 0x3;
    size = size_code < 3 ? size_code : 4;
    pos++;
    if (pos + size > desc_len)
      return -EINVAL;
    value = 0;
    for (size_t i = 0; i < size; i++)
      value |= (uint32_t)desc[pos + i] << (8 * i);
    pos += size;
    if (type == 0x1u && tag == 0x0u) {
      if (size > 2)
        return -EINVAL;
      usage = (value & 0x0000ffffu) << 16;
    }
    if (type == 0x2u && tag == 0x0u) {
      if (size == 4)
        usage = value;
      else
        usage = (usage & 0xffff0000u) | (value & 0x0000ffffu);
      if (usage == 0xf1d00001u)
        return 1;
    }
  }
  return 0;
}
```