// File: rellla[P]E3DC-Rscp/AES.cpp
// Function: AES::Decrypt(unsigned char const*, unsigned char*, unsigned long, AES::BlockMode)
void AES::Decrypt(const unsigned char * datain, unsigned char * dataout, unsigned long numBlocks, BlockMode mode)
	{
	if (0 == numBlocks)
		return;
	unsigned int blocksize = Nb*4;
	switch (mode)
		{
		case ECB :
			while (numBlocks)
				{
				DecryptBlock(datain,dataout);
				datain   += blocksize;
				dataout  += blocksize;
				--numBlocks;
				}
			break;
		case CBC :
			{
			int iBuf = 0;
			unsigned char buffer[2][32]; // max blocksize
			memcpy(buffer[iBuf], datain, blocksize);
			DecryptBlock(datain,dataout); // do first block
			for (unsigned int pos = 0; pos < blocksize; ++pos)
				*dataout++ ^= iv[pos];
			datain += blocksize;
			numBlocks--;

			while (numBlocks)
				{
				memcpy(buffer[iBuf^1], datain, blocksize);
				DecryptBlock(datain,dataout); // do first block
				for (unsigned int pos = 0; pos < blocksize; ++pos)
					*dataout++ ^= *(buffer[iBuf]+pos);
				datain  += blocksize;
				iBuf ^= 1;
				--numBlocks;
				}
			}
			break;
		default :
			break;
		}
	}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movq %rsi, 0x88(%rsp)
movq %rdx, 0x80(%rsp)
movq %rcx, 0x78(%rsp)
movl %r8d, 0x74(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x10(%rsp)
xorl %eax, %eax
cmpq 0x78(%rsp), %rax
jne 0x1e334
jmp 0x1e563
movq 0x10(%rsp), %rax
movl (%rax), %eax
shll $0x2, %eax
movl %eax, 0x70(%rsp)
movl 0x74(%rsp), %eax
movl %eax, 0xc(%rsp)
testl %eax, %eax
je 0x1e35e
jmp 0x1e350
movl 0xc(%rsp), %eax
subl $0x1, %eax
je 0x1e3c9
jmp 0x1e561
jmp 0x1e360
cmpq $0x0, 0x78(%rsp)
je 0x1e3c4
movq 0x10(%rsp), %rdi
movq 0x88(%rsp), %rsi
movq 0x80(%rsp), %rdx
callq 0x14ad0
movl 0x70(%rsp), %ecx
movq 0x88(%rsp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, 0x88(%rsp)
movl 0x70(%rsp), %ecx
movq 0x80(%rsp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, 0x80(%rsp)
movq 0x78(%rsp), %rax
addq $-0x1, %rax
movq %rax, 0x78(%rsp)
jmp 0x1e360
jmp 0x1e563
movl $0x0, 0x6c(%rsp)
movslq 0x6c(%rsp), %rax
leaq 0x20(%rsp), %rdi
shlq $0x5, %rax
addq %rax, %rdi
movq 0x88(%rsp), %rsi
movl 0x70(%rsp), %eax
movl %eax, %edx
callq 0x2130
movq 0x10(%rsp), %rdi
movq 0x88(%rsp), %rsi
movq 0x80(%rsp), %rdx
callq 0x14ad0
movl $0x0, 0x1c(%rsp)
movl 0x1c(%rsp), %eax
cmpl 0x70(%rsp), %eax
jae 0x1e45d
movq 0x10(%rsp), %rax
movl 0x1c(%rsp), %ecx
movzbl 0x1ec(%rax,%rcx), %edx
movq 0x80(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x80(%rsp)
movzbl (%rax), %ecx
xorl %edx, %ecx
movb %cl, (%rax)
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x1e417
movl 0x70(%rsp), %ecx
movq 0x88(%rsp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, 0x88(%rsp)
movq 0x78(%rsp), %rax
addq $-0x1, %rax
movq %rax, 0x78(%rsp)
cmpq $0x0, 0x78(%rsp)
je 0x1e55f
movl 0x6c(%rsp), %eax
xorl $0x1, %eax
cltq
leaq 0x20(%rsp), %rdi
shlq $0x5, %rax
addq %rax, %rdi
movq 0x88(%rsp), %rsi
movl 0x70(%rsp), %eax
movl %eax, %edx
callq 0x2130
movq 0x10(%rsp), %rdi
movq 0x88(%rsp), %rsi
movq 0x80(%rsp), %rdx
callq 0x14ad0
movl $0x0, 0x18(%rsp)
movl 0x18(%rsp), %eax
cmpl 0x70(%rsp), %eax
jae 0x1e528
movslq 0x6c(%rsp), %rcx
leaq 0x20(%rsp), %rax
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x18(%rsp), %ecx
movzbl (%rax,%rcx), %edx
movq 0x80(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x80(%rsp)
movzbl (%rax), %ecx
xorl %edx, %ecx
movb %cl, (%rax)
movl 0x18(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18(%rsp)
jmp 0x1e4da
movl 0x70(%rsp), %ecx
movq 0x88(%rsp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, 0x88(%rsp)
movl 0x6c(%rsp), %eax
xorl $0x1, %eax
movl %eax, 0x6c(%rsp)
movq 0x78(%rsp), %rax
addq $-0x1, %rax
movq %rax, 0x78(%rsp)
jmp 0x1e484
jmp 0x1e563
jmp 0x1e563
addq $0x98, %rsp
retq
nopl (%rax,%rax)