// File: /workspace/github_cpp_makefile_star2_O2/FFY00[P]uicc/src/program_uicc.c
// Function: authenticate(char*, uicc_vals&)
void authenticate(char *port, struct uicc_vals &values) {
    string key;
    Assert(makeBin(values.key, key) == 16, "can't read a correct key: 16 hexa figures\n");
    string opc;
    Assert(makeBin(values.opc, opc) == 16, "can't read a correct opc: 16 hexa figures\n");
    USIM USIMcard;
    string ATR;
    Assert((ATR=USIMcard.open(port))!="", "Failed to open %s", port);
    //dump_hex("ATR", ATR);
    USIMcard.openUSIM();
    USIMcard.debug=false;
    // We don't make proper values for rand, sqn,
    // we perform first authentication only to get the AUTS from the USIM
    u8 amf[2]= {0};
    u8 sqn[6]= {0};
    u8 rand[16]= {0};
    u8 autn[16]= {0};
    u8 ik[16]= {0};
    u8 ck[16]= {0};
    u8 res[8]= {0};
    Assert(milenage_generate((const uint8_t *)opc.c_str(), amf,
                             (const uint8_t *)key.c_str(), sqn,
                             rand,
                             autn, ik, ck, res),
           "Milenage internal failure\n");
    string srand((char *)rand,sizeof(rand));
    string sautn((char *)autn,sizeof(autn));
    vector<string> returned=USIMcard.authenticate(srand, sautn);

    // We should have one LV value returned, the AUTS
    if (returned.size()!=1) {
        printf("The card didn't accept our challenge: OPc or Ki is wrong\n");
        return;
    }

    u8 SIMsqn[8]= {0};

    if ( ! milenage_auts((const uint8_t *)opc.c_str(),
                         (const uint8_t *)key.c_str(),
                         rand,
                         (const uint8_t *)returned[0].c_str(),
                         SIMsqn+2) ) {
        printf("Can't decode the AUTS returned by the card (wrong Ki or OPc)\n");
        return;
    }

    uint64_t intSqn=be64toh(*(uint64_t *)SIMsqn);
    intSqn+=32; // according to 3GPP TS 33.102 version 11, annex C. 3.2
    uint64_t newSqn=htobe64(intSqn);
    // To make better validation, let's generate a random value in milenage "rand"
    FILE *h=fopen("/dev/random","r");
    fread(rand,sizeof(rand),1,h);
    fclose(h);
    Assert( milenage_generate((const uint8_t *)opc.c_str(), amf,
                              (const uint8_t *)key.c_str(),
                              ((u8 *)&newSqn)+2,
                              rand,
                              autn, ik, ck, res),
            "Milenage internal failure\n");
    // Now, we can test a authentication that should be sucessful
    string new_autn((char *)autn,16);
    string new_rand((char *)rand,16);
    vector<string>  returned_newSQN=USIMcard.authenticate(new_rand, new_autn);

    if ( USIMcard.debug )
        for (size_t i=0; i< returned_newSQN.size(); i++)
            dump_hex("auth answer",returned_newSQN[i]);

    if (returned_newSQN.size() != 4)
        printf("We tried SQN %" PRId64 ", but the card refused!\n",intSqn);
    else {
        string s_ik((char *)ik,sizeof(ik));
        string s_ck((char *)ck,sizeof(ck));
        string s_res((char *)res,sizeof(res));

        if ( s_res != returned_newSQN[0] ||
                s_ck  != returned_newSQN[1] ||
                s_ik  != returned_newSQN[2] )
            printf("The card sent back vectors, but they are not our milenage computation\n");
        else {
            printf("Succeeded to authentify with SQN: %" PRId64 "\n", intSqn);
            printf("set HSS SQN value as: %" PRId64 "\n", intSqn+32 );
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x358, %rsp            # imm = 0x358
leaq -0xf0(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movq %rsi, %r14
movq %rdi, %rbx
movb $0x0, (%rax)
addq $0xe8, %rsi
leaq -0x2c8(%rbp), %rdi
callq 0x2330
leaq -0x2c8(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x714c
movl %eax, %r15d
leaq -0x2c8(%rbp), %rdi
callq 0x2120
cmpl $0x10, %r15d
jne 0x7822
leaq -0xd0(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
addq $0x68, %r14
leaq -0x2a8(%rbp), %rdi
movq %r14, %rsi
callq 0x2330
leaq -0x2a8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x714c
movl %eax, %r14d
leaq -0x2a8(%rbp), %rdi
callq 0x2120
cmpl $0x10, %r14d
jne 0x7858
leaq -0x318(%rbp), %r14
movq %r14, %rdi
callq 0x8b4a
leaq -0x278(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq -0xa0(%rbp), %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x83ae
leaq -0x288(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x2300
leaq 0xc07f(%rip), %rsi      # 0x13392
movq %rax, %rdi
callq 0x83a1
movl %eax, %r14d
leaq -0xa0(%rbp), %rdi
callq 0x2120
testb %r14b, %r14b
je 0x78aa
leaq -0x318(%rbp), %rdi
callq 0x90a2
leaq -0x2a(%rbp), %rsi
andw $0x0, (%rsi)
leaq -0x168(%rbp), %rcx
andw $0x0, 0x4(%rcx)
andl $0x0, (%rcx)
movb $0x0, -0x318(%rbp)
xorps %xmm0, %xmm0
leaq -0x60(%rbp), %rbx
movaps %xmm0, (%rbx)
leaq -0x80(%rbp), %r9
movaps %xmm0, (%r9)
leaq -0x140(%rbp), %r15
movaps %xmm0, (%r15)
leaq -0xc0(%rbp), %r14
andq $0x0, (%r14)
leaq -0x130(%rbp), %r12
movaps %xmm0, (%r12)
movq -0xe0(%rbp), %rdi
movq -0x100(%rbp), %rdx
subq $0x8, %rsp
movq %rbx, %r8
pushq %r14
pushq %r12
pushq %r15
callq 0x2b24
addq $0x20, %rsp
leaq -0x90(%rbp), %rax
movq %rax, -0x10(%rax)
leaq -0x50(%rbp), %rdx
leaq -0xa0(%rbp), %rdi
movq %rbx, %rsi
callq 0xf120
leaq -0x1b8(%rbp), %rax
movq %rax, -0x10(%rax)
leaq -0x70(%rbp), %rdx
leaq -0x1c8(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0xf120
leaq -0x268(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x2330
leaq -0x248(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x2330
leaq -0x118(%rbp), %rdi
leaq -0x318(%rbp), %rsi
leaq -0x268(%rbp), %rdx
leaq -0x248(%rbp), %rcx
callq 0xa170
leaq -0x248(%rbp), %rdi
callq 0x2120
leaq -0x268(%rbp), %rdi
callq 0x2120
movq -0x118(%rbp), %rax
movq -0x110(%rbp), %rcx
subq %rax, %rcx
cmpq $0x20, %rcx
jne 0x7642
leaq -0xb6(%rbp), %r8
andq $0x0, -0x2(%r8)
movq -0xe0(%rbp), %rdi
movq -0x100(%rbp), %rsi
movq (%rax), %rcx
leaq -0x60(%rbp), %rdx
callq 0x2bc1
testb %al, %al
je 0x764b
movq -0xb8(%rbp), %rax
bswapq %rax
movq %rax, -0xa8(%rbp)
addq $0x20, %rax
movq %rax, -0x68(%rbp)
bswapq %rax
leaq -0xae(%rbp), %rcx
movq %rax, -0x2(%rcx)
leaq 0xbb49(%rip), %rdi      # 0x13011
leaq 0xbea8(%rip), %rsi      # 0x13377
callq 0x22d0
movq %rax, %r13
pushq $0x10
popq %rsi
pushq $0x1
popq %rdx
movq %rbx, %rdi
movq %rax, %rcx
callq 0x23a0
movq %r13, %rdi
callq 0x2240
movq -0xe0(%rbp), %rdi
movq -0x100(%rbp), %rdx
subq $0x8, %rsp
leaq -0x2a(%rbp), %rsi
leaq -0x80(%rbp), %r13
leaq -0xae(%rbp), %rcx
movq %rbx, %r8
movq %r13, %r9
pushq %r14
pushq %r12
pushq %r15
callq 0x2b24
addq $0x20, %rsp
leaq -0x198(%rbp), %rax
movq %rax, -0x10(%rax)
leaq -0x1a8(%rbp), %rdi
movq %r13, %rsi
leaq -0x70(%rbp), %rdx
callq 0xf120
leaq -0x178(%rbp), %rax
movq %rax, -0x10(%rax)
leaq -0x188(%rbp), %rdi
leaq -0x60(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0xf120
leaq -0x228(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x2330
leaq -0x208(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x2330
leaq -0x48(%rbp), %rdi
leaq -0x318(%rbp), %rsi
leaq -0x228(%rbp), %rdx
leaq -0x208(%rbp), %rcx
callq 0xa170
leaq -0x208(%rbp), %rdi
callq 0x2120
leaq -0x228(%rbp), %rdi
callq 0x2120
cmpb $0x1, -0x318(%rbp)
jne 0x765c
xorl %ebx, %ebx
leaq -0x358(%rbp), %r12
leaq -0x160(%rbp), %r13
leaq -0x378(%rbp), %r14
xorl %r15d, %r15d
movq -0x48(%rbp), %rax
movq -0x40(%rbp), %rcx
movq %rcx, %rdx
subq %rax, %rdx
sarq $0x5, %rdx
cmpq %rdx, %r15
jae 0x7664
movq %r12, %rdi
leaq 0xba16(%rip), %rsi      # 0x1301d
movq %r13, %rdx
callq 0x20f0
movq -0x48(%rbp), %rsi
addq %rbx, %rsi
movq %r14, %rdi
callq 0x2330
movq %r12, %rdi
movq %r14, %rsi
callq 0x7a66
movq %r14, %rdi
callq 0x2120
movq %r12, %rdi
callq 0x2120
incq %r15
addq $0x20, %rbx
jmp 0x75e6
leaq 0xc888(%rip), %rdi      # 0x13ed1
jmp 0x7652
leaq 0xc7fc(%rip), %rdi      # 0x13e4e
callq 0x23c0
jmp 0x778c
movq -0x48(%rbp), %rax
movq -0x40(%rbp), %rcx
subq %rax, %rcx
cmpq $0x80, %rcx
jne 0x7759
leaq -0x150(%rbp), %rax
movq %rax, -0x10(%rax)
leaq -0x130(%rbp), %rdx
leaq -0x160(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0xf120
leaq -0x1d8(%rbp), %rax
movq %rax, -0x10(%rax)
leaq -0x120(%rbp), %rdx
leaq -0x1e8(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0xf120
leaq -0x328(%rbp), %rax
movq %rax, -0x10(%rax)
movq -0xc0(%rbp), %rcx
movq %rcx, (%rax)
movq $0x8, -0x8(%rax)
movb $0x0, 0x8(%rax)
movq -0x48(%rbp), %rsi
leaq -0x338(%rbp), %rdi
callq 0xa602
testb %al, %al
jne 0x7727
movq -0x48(%rbp), %rsi
addq $0x20, %rsi
leaq -0x1e8(%rbp), %rdi
callq 0xa602
testb %al, %al
jne 0x7727
movq -0x48(%rbp), %rsi
addq $0x40, %rsi
leaq -0x160(%rbp), %rdi
callq 0xa602
testb %al, %al
je 0x77f2
leaq 0xc75d(%rip), %rdi      # 0x13e8b
callq 0x23c0
leaq -0x338(%rbp), %rdi
callq 0x2120
leaq -0x1e8(%rbp), %rdi
callq 0x2120
leaq -0x160(%rbp), %rdi
callq 0x2120
jmp 0x776b
leaq 0xb8c9(%rip), %rdi      # 0x13029
movq -0x68(%rbp), %rsi
xorl %eax, %eax
callq 0x2050
leaq -0x48(%rbp), %rdi
callq 0x8a5a
leaq -0x188(%rbp), %rdi
callq 0x2120
leaq -0x1a8(%rbp), %rdi
callq 0x2120
leaq -0x118(%rbp), %rdi
callq 0x8a5a
leaq -0x1c8(%rbp), %rdi
callq 0x2120
leaq -0xa0(%rbp), %rdi
callq 0x2120
leaq -0x288(%rbp), %rdi
callq 0x2120
leaq -0x318(%rbp), %rdi
callq 0x9366
leaq -0xe0(%rbp), %rdi
callq 0x2120
leaq -0x100(%rbp), %rdi
callq 0x2120
addq $0x358, %rsp            # imm = 0x358
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xb859(%rip), %rdi      # 0x13052
movq -0x68(%rbp), %rsi
xorl %eax, %eax
callq 0x2050
movq -0xa8(%rbp), %rsi
addq $0x40, %rsi
leaq 0xb863(%rip), %rdi      # 0x13079
xorl %eax, %eax
callq 0x2050
jmp 0x7733
movq 0x117a7(%rip), %r14     # 0x18fd0
movq (%r14), %rbx
callq 0x2040
movl (%rax), %edi
callq 0x20c0
leaq 0xb5d1(%rip), %rsi      # 0x12e10
leaq 0xb71b(%rip), %rdx      # 0x12f61
leaq 0x9ad1(%rip), %rcx      # 0x1131e
movq %rbx, %rdi
movl $0x140, %r8d            # imm = 0x140
jmp 0x788c
movq 0x11771(%rip), %r14     # 0x18fd0
movq (%r14), %rbx
callq 0x2040
movl (%rax), %edi
callq 0x20c0
leaq 0xb6f9(%rip), %rsi      # 0x12f6e
leaq 0xb6e5(%rip), %rdx      # 0x12f61
leaq 0x9a9b(%rip), %rcx      # 0x1131e
movq %rbx, %rdi
movl $0x142, %r8d            # imm = 0x142
movq %rax, %r9
xorl %eax, %eax
callq 0x2360
movq 0x1170b(%rip), %rax     # 0x18fa8
movq (%rax), %rdi
callq 0x22c0
movq (%r14), %rdi
jmp 0x7901
movq 0x1171f(%rip), %r15     # 0x18fd0
movq (%r15), %r14
callq 0x2040
movl (%rax), %edi
callq 0x20c0
subq $0x8, %rsp
leaq 0x9a8a(%rip), %rsi      # 0x11355
leaq 0xb68f(%rip), %rdx      # 0x12f61
leaq 0x9a45(%rip), %rcx      # 0x1131e
movq %r14, %rdi
movl $0x145, %r8d            # imm = 0x145
movq %rax, %r9
xorl %eax, %eax
pushq %rbx
callq 0x2360
popq %rcx
popq %rdx
movq 0x116b2(%rip), %rax     # 0x18fa8
movq (%rax), %rdi
callq 0x22c0
movq (%r15), %rdi
callq 0x22c0
pushq $0x1
popq %rdi
callq 0x22e0
movq %rax, %rbx
leaq -0x160(%rbp), %rdi
jmp 0x79df
jmp 0x79e6
movq %rax, %rbx
leaq -0x208(%rbp), %rdi
callq 0x2120
jmp 0x7936
movq %rax, %rbx
leaq -0x228(%rbp), %rdi
callq 0x2120
jmp 0x79f2
movq %rax, %rbx
jmp 0x79f2
movq %rax, %rbx
jmp 0x79fe
movq %rax, %rbx
jmp 0x7a0a
movq %rax, %rbx
leaq -0x248(%rbp), %rdi
callq 0x2120
jmp 0x7973
movq %rax, %rbx
leaq -0x268(%rbp), %rdi
callq 0x2120
jmp 0x7a16
movq %rax, %rbx
jmp 0x7a16
movq %rax, %rbx
jmp 0x7a22
jmp 0x79a0
jmp 0x79a0
movq %rax, %rbx
jmp 0x7a22
movq %rax, %rbx
jmp 0x7a2e
movq %rax, %rbx
leaq -0x2a8(%rbp), %rdi
callq 0x2120
jmp 0x7a46
movq %rax, %rbx
jmp 0x7a46
movq %rax, %rbx
leaq -0x2c8(%rbp), %rdi
jmp 0x7a4d
movq %rax, %rbx
jmp 0x7a52
movq %rax, %rbx
leaq -0x358(%rbp), %rdi
callq 0x2120
jmp 0x79e9
movq %rax, %rbx
leaq -0x48(%rbp), %rdi
callq 0x8a5a
leaq -0x188(%rbp), %rdi
callq 0x2120
leaq -0x1a8(%rbp), %rdi
callq 0x2120
leaq -0x118(%rbp), %rdi
callq 0x8a5a
leaq -0x1c8(%rbp), %rdi
callq 0x2120
leaq -0xa0(%rbp), %rdi
callq 0x2120
leaq -0x288(%rbp), %rdi
callq 0x2120
leaq -0x318(%rbp), %rdi
callq 0x9366
leaq -0xe0(%rbp), %rdi
callq 0x2120
leaq -0x100(%rbp), %rdi
callq 0x2120
movq %rbx, %rdi
callq 0x2400