// File: lmclaramunt[P]AES-Crypto/Cipher.cpp
// Function: Cipher::CBC_decrypt()
void Cipher::CBC_decrypt(){   
    Sequence tag = CBC_MAC(*inputBlock, false, true);             //Generate MAC Tag from Ciphertext
    Sequence readTag = inputBlock->getSequenceVector().at(0);     //Get the MAC Tag in the Ciphertext
    if(authenticateSequences(&readTag, &tag)){                    //Compare them for authentication purposes
        Sequence prevSq(16), cipherText(16); 
        int size = inputBlock->getSequenceVector().size();
        int i = -1;
        for(Sequence sq: inputBlock->getSequenceVector()){         
            i++;
            if(i <= 1){
                prevSq.updateSequence(sq);  //Skip decryption of first and last Block of ciphertext
                continue;                   //These blocks are the IV and MAC Tag respectively
            }
            cipherText.updateSequence(sq);  //Keep track of ciphertext, we'll need it next round   
            decrypt(&sq, aesKeyExp);
            sq = sq ^ prevSq;               
            prevSq.updateSequence(cipherText);  //Update previous sequence, to ciphertext values
        }
        try{
            removePadding(&inputBlock->getSequenceVector().at(size-1));     //Last block will have padding
        }catch(const char* str){
            throw str;
        }

        //Blocks have been authenticated, decrypted, and padding removed. Ready to write plaintext
        writePlainText();
        /* Sequence cleanup as it can leave traces in memory */
        prevSq.~Sequence();
        cipherText.~Sequence();
    }else
        throw "Ciphertext has been modified, it won't be decrypted!\n";     //Authenticate-then-decrypt
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x108(%rbp)
movq 0x10(%rax), %rsi
leaq -0x30(%rbp), %rdi
movq %rdi, -0x100(%rbp)
callq 0xb960
movq -0x108(%rbp), %rdi
movq -0x100(%rbp), %rsi
xorl %edx, %edx
movl $0x1, %ecx
callq 0x9c90
movl %edx, -0xf4(%rbp)
movq %rax, -0xf0(%rbp)
jmp 0xa737
movl -0xf4(%rbp), %eax
movq -0xf0(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movl %eax, -0x48(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x18(%rbp)
movl -0x48(%rbp), %eax
movl %eax, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x5100
movq -0x108(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x5190
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xb990
movq -0x108(%rbp), %rdi
movq (%rax), %rcx
movq %rcx, -0x60(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x58(%rbp)
leaq -0x60(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x9fe0
testb $0x1, %al
jne 0xa7aa
jmp 0xaa42
leaq -0x70(%rbp), %rdi
movl $0x10, %esi
callq 0x4a10
leaq -0x80(%rbp), %rdi
movl $0x10, %esi
callq 0x4a10
movq -0x108(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x5190
movq %rax, %rdi
callq 0x5c00
movq %rax, %rcx
movq -0x108(%rbp), %rax
movl %ecx, -0x84(%rbp)
movl $0xffffffff, -0x88(%rbp) # imm = 0xFFFFFFFF
movq 0x10(%rax), %rdi
callq 0x5190
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rdi
callq 0x5b00
movq %rax, -0x98(%rbp)
movq -0x90(%rbp), %rdi
callq 0x5980
movq %rax, -0xa0(%rbp)
leaq -0x98(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0xb6a0
testb $0x1, %al
jne 0xa84a
jmp 0xa97c
leaq -0x98(%rbp), %rdi
callq 0x68c0
movq (%rax), %rcx
movq %rcx, -0xb0(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0xa8(%rbp)
movl -0x88(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x88(%rbp)
cmpl $0x1, -0x88(%rbp)
jg 0xa8d4
movq -0xb0(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xc0(%rbp), %rsi
movl -0xb8(%rbp), %edx
leaq -0x70(%rbp), %rdi
callq 0x4b70
jmp 0xa96b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x5100
jmp 0xaa72
movq -0xb0(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0xd0(%rbp), %rsi
movl -0xc8(%rbp), %edx
leaq -0x80(%rbp), %rdi
callq 0x4b70
movq -0x108(%rbp), %rdi
movq (%rdi), %rdx
leaq -0xb0(%rbp), %rsi
callq 0x9a10
leaq -0xb0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x4cc0
movq (%rax), %rcx
movq %rcx, -0xb0(%rbp)
movl 0x8(%rax), %eax
movl %eax, -0xa8(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xe0(%rbp), %rsi
movl -0xd8(%rbp), %edx
leaq -0x70(%rbp), %rdi
callq 0x4b70
leaq -0x98(%rbp), %rdi
callq 0x68e0
jmp 0xa82e
movq -0x108(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x5190
movq %rax, -0x110(%rbp)
jmp 0xa995
movq -0x110(%rbp), %rdi
movl -0x84(%rbp), %eax
decl %eax
movslq %eax, %rsi
callq 0xb990
movq %rax, -0x118(%rbp)
jmp 0xa9b5
movq -0x118(%rbp), %rsi
movq -0x108(%rbp), %rdi
callq 0xa060
jmp 0xa9ca
jmp 0xaa34
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0xaa72
movq -0x38(%rbp), %rdi
callq 0x30b0
movq %rax, -0xe8(%rbp)
movl $0x8, %edi
callq 0x3120
movq %rax, %rdi
movq -0xe8(%rbp), %rax
movq %rax, (%rdi)
movq 0xb5aa(%rip), %rsi      # 0x15fc0
xorl %eax, %eax
movl %eax, %edx
callq 0x3490
jmp 0xaa7b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
callq 0x3450
jmp 0xaa72
movq -0x108(%rbp), %rdi
callq 0xa110
jmp 0xaa69
movl $0x8, %edi
callq 0x3120
movq %rax, %rdi
leaq 0x4d7b(%rip), %rax      # 0xf7d1
movq %rax, (%rdi)
movq 0xb560(%rip), %rsi      # 0x15fc0
xorl %eax, %eax
movl %eax, %edx
callq 0x3490
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
movq -0x38(%rbp), %rdi
callq 0x34d0
nopl (%rax,%rax)