// File: /workspace/github_cpp_makefile_star2_O1/msotoodeh[P]asymmetric-passwords/client/APKeyDerivation.cpp
// Function: APDigest::hmac(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long)
size_t APDigest::hmac(
    const uint8_t* key, size_t key_size, 
    const uint8_t* msg, size_t msg_size,
    uint8_t* mac, size_t mac_size)
{
    uint32_t i;
    uint8_t i_pad[BLOCK_SIZE], o_pad[BLOCK_SIZE];
    if (key_size > BLOCK_SIZE)
    {
        APDigest h((void*)key, key_size);
        for (i = 0; i < DIGEST_SIZE; i++)
        {
            o_pad[i] = h.m_Digest[i] ^ 0x5c;
            i_pad[i] = h.m_Digest[i] ^ 0x36;
        }
    }
    else
    {
        for (i = 0; i < key_size; i++)
        {
            o_pad[i] = key[i] ^ 0x5c;
            i_pad[i] = key[i] ^ 0x36;
        }
    }

    while (i < BLOCK_SIZE)
    {
        o_pad[i] = 0x5c;
        i_pad[i] = 0x36;
        i++;
    }

    APDigest inner_hash;
    inner_hash.update((void*)&i_pad[0], sizeof(i_pad));
    inner_hash.update((void*)msg, msg_size);
    inner_hash.finish();

    APDigest outer_hash;
    outer_hash.update((void*)&o_pad[0], sizeof(o_pad));
    outer_hash.update((void*)&inner_hash.m_Digest[0], sizeof(inner_hash.m_Digest));
    return outer_hash.finish((void*)mac, mac_size);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x338, %rsp            # imm = 0x338
movq %r9, %r14
movq %r8, %rbx
movq %rcx, %r15
movq %rdx, %r12
movq %rsi, %rdx
movq %rdi, %rsi
cmpq $0x80, %rdx
jbe 0x405ad5
leaq 0x8(%rsp), %rdi
callq 0x4059a8
xorl %eax, %eax
movaps 0x174cb5(%rip), %xmm0   # 0x57a740
movaps 0x174cbe(%rip), %xmm1   # 0x57a750
movups 0xe0(%rsp,%rax), %xmm2
movaps %xmm2, %xmm3
xorps %xmm0, %xmm3
movaps %xmm3, 0x120(%rsp,%rax)
xorps %xmm1, %xmm2
movaps %xmm2, 0x1a0(%rsp,%rax)
addq $0x10, %rax
cmpq $0x40, %rax
jne 0x405a92
leaq 0x8(%rsp), %rdi
movl $0x118, %edx            # imm = 0x118
xorl %esi, %esi
callq 0x401060
movl $0x40, %edx
jmp 0x405b03
testq %rdx, %rdx
je 0x405b01
xorl %eax, %eax
movb (%rsi,%rax), %cl
movl %ecx, %edi
xorb $0x5c, %dil
movb %dil, 0x120(%rsp,%rax)
xorb $0x36, %cl
movb %cl, 0x1a0(%rsp,%rax)
incq %rax
cmpq %rax, %rdx
jne 0x405adc
jmp 0x405b03
xorl %edx, %edx
cmpl $0x7f, %edx
ja 0x405b43
movl %edx, %ebp
leaq (%rsp,%rbp), %rdi
addq $0x120, %rdi            # imm = 0x120
movl $0x80, %r13d
subl %edx, %r13d
movl $0x5c, %esi
movq %r13, %rdx
callq 0x401060
leaq (%rsp,%rbp), %rdi
addq $0x1a0, %rdi            # imm = 0x1A0
movl $0x36, %esi
movq %r13, %rdx
callq 0x401060
leaq 0x8(%rsp), %r13
movq %r13, %rdi
callq 0x408338
leaq 0x1a0(%rsp), %rsi
movl $0x80, %edx
movq %r13, %rdi
callq 0x409b13
leaq 0x8(%rsp), %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x409b13
leaq 0xe0(%rsp), %r15
leaq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x4083c0
leaq 0x220(%rsp), %rdi
callq 0x408338
leaq 0x220(%rsp), %rdi
leaq 0x120(%rsp), %rsi
movl $0x80, %edx
callq 0x409b13
leaq 0x220(%rsp), %rdi
movl $0x40, %edx
movq %r15, %rsi
callq 0x409b13
leaq 0x2f8(%rsp), %r15
leaq 0x220(%rsp), %rsi
movq %r15, %rdi
callq 0x4083c0
cmpq $0x40, %r14
movl $0x40, %r12d
cmovbq %r14, %r12
movq %rbx, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x401110
leaq 0x220(%rsp), %rdi
movl $0x118, %edx            # imm = 0x118
xorl %esi, %esi
callq 0x401060
leaq 0x8(%rsp), %rdi
movl $0x118, %edx            # imm = 0x118
xorl %esi, %esi
callq 0x401060
movq %r12, %rax
addq $0x338, %rsp            # imm = 0x338
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x405c4f
movq %rax, %rbx
leaq 0x220(%rsp), %rdi
movl $0x118, %edx            # imm = 0x118
xorl %esi, %esi
callq 0x401060
jmp 0x405c52
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
movl $0x118, %edx            # imm = 0x118
xorl %esi, %esi
callq 0x401060
movq %rbx, %rdi
callq 0x4a9c80
nop