#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int uint8_t;

/* Variables and functions */
int /*<<< orphan*/ AES128_CBC_decrypt_buffer(int *, int *, int, int *, int *);
int /*<<< orphan*/ printf(char *);
scalar_t__ strncmp(char *, char *, int);
void test_decrypt_cbc(void) {
  uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
                   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
  uint8_t iv[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
  uint8_t in[] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9,
                  0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, 0x50, 0x86, 0xcb, 0x9b,
                  0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76,
                  0x78, 0xb2, 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b,
                  0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, 0x3f, 0xf1,
                  0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30,
                  0x75, 0x86, 0xe1, 0xa7};
  uint8_t out[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d,
                   0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57,
                   0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf,
                   0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
                   0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f,
                   0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b,
                   0xe6, 0x6c, 0x37, 0x10};
  uint8_t buffer[64];
  AES128_CBC_decrypt_buffer(buffer + 0, in + 0, 16, key, iv);
  AES128_CBC_decrypt_buffer(buffer + 16, in + 16, 16, 0, 0);
  AES128_CBC_decrypt_buffer(buffer + 32, in + 32, 16, 0, 0);
  AES128_CBC_decrypt_buffer(buffer + 48, in + 48, 16, 0, 0);
  printf("CBC decrypt: ");
  if (0 == strncmp((char *)out, (char *)buffer, 64)) {
    printf("SUCCESS!\n");
  } else {
    printf("FAILURE!\n");
  }
}


x86 assembly (clang, -O0):
<test_decrypt_cbc>:
push   %rbp
mov    %rsp,%rbp
sub    $0x380,%rsp
lea    -0x40(%rbp),%rdi
lea    0xeaa(%rip),%rsi
mov    $0x40,%edx
call   1060 <memcpy@plt>
lea    -0x80(%rbp),%rdi
lea    0xed5(%rip),%rsi
mov    $0x40,%edx
call   1060 <memcpy@plt>
lea    -0x180(%rbp),%rdi
lea    0xefd(%rip),%rsi
mov    $0x100,%edx
call   1060 <memcpy@plt>
lea    -0x280(%rbp),%rdi
lea    0xfe5(%rip),%rsi
mov    $0x100,%edx
call   1060 <memcpy@plt>
lea    -0x380(%rbp),%rdi
lea    -0x180(%rbp),%rsi
lea    -0x40(%rbp),%rcx
lea    -0x80(%rbp),%r8
mov    $0x10,%edx
call   1050 <AES128_CBC_decrypt_buffer@plt>
lea    -0x380(%rbp),%rdi
add    $0x40,%rdi
lea    -0x180(%rbp),%rsi
add    $0x40,%rsi
mov    $0x10,%edx
xor    %eax,%eax
mov    %eax,%r8d
mov    %r8,%rcx
call   1050 <AES128_CBC_decrypt_buffer@plt>
lea    -0x380(%rbp),%rdi
add    $0x80,%rdi
lea    -0x180(%rbp),%rsi
add    $0x80,%rsi
mov    $0x10,%edx
xor    %eax,%eax
mov    %eax,%r8d
mov    %r8,%rcx
call   1050 <AES128_CBC_decrypt_buffer@plt>
lea    -0x380(%rbp),%rdi
add    $0xc0,%rdi
lea    -0x180(%rbp),%rsi
add    $0xc0,%rsi
mov    $0x10,%edx
xor    %eax,%eax
mov    %eax,%r8d
mov    %r8,%rcx
call   1050 <AES128_CBC_decrypt_buffer@plt>
lea    0x1030(%rip),%rdi
call   1040 <printf@plt>
lea    -0x280(%rbp),%rdi
lea    -0x380(%rbp),%rsi
mov    $0x40,%edx
call   1030 <strncmp@plt>
mov    %rax,%rcx
xor    %eax,%eax
cmp    %rcx,%rax
jne    128c <test_decrypt_cbc+0x14c>
lea    0x100c(%rip),%rdi
call   1040 <printf@plt>
jmp    1298 <test_decrypt_cbc+0x158>
lea    0x1005(%rip),%rdi
call   1040 <printf@plt>
add    $0x380,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<test_decrypt_cbc>:
push   %r15
push   %r14
push   %rbx
sub    $0x380,%rsp
movaps 0xecd(%rip),%xmm0
movaps %xmm0,0x70(%rsp)
movaps 0xeb1(%rip),%xmm0
movaps %xmm0,0x60(%rsp)
movaps 0xe95(%rip),%xmm0
movaps %xmm0,0x50(%rsp)
movaps 0xe79(%rip),%xmm0
movaps %xmm0,0x40(%rsp)
movaps 0xedd(%rip),%xmm0
movaps %xmm0,0x30(%rsp)
movaps 0xec1(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
movaps 0xea5(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movaps 0xe89(%rip),%xmm0
movaps %xmm0,(%rsp)
lea    0xebe(%rip),%rsi
lea    0x180(%rsp),%rbx
mov    $0x100,%edx
mov    %rbx,%rdi
call   1070 <memcpy@plt>
lea    0xfa2(%rip),%rsi
lea    0x280(%rsp),%r14
mov    $0x100,%edx
mov    %r14,%rdi
call   1070 <memcpy@plt>
lea    0x80(%rsp),%r15
lea    0x40(%rsp),%rcx
mov    %rsp,%r8
mov    %r15,%rdi
mov    %rbx,%rsi
mov    $0x10,%edx
call   1060 <AES128_CBC_decrypt_buffer@plt>
lea    0xc0(%rsp),%rdi
lea    0x1c0(%rsp),%rsi
mov    $0x10,%edx
xor    %ecx,%ecx
xor    %r8d,%r8d
call   1060 <AES128_CBC_decrypt_buffer@plt>
lea    0x100(%rsp),%rdi
lea    0x200(%rsp),%rsi
mov    $0x10,%edx
xor    %ecx,%ecx
xor    %r8d,%r8d
call   1060 <AES128_CBC_decrypt_buffer@plt>
lea    0x140(%rsp),%rdi
lea    0x240(%rsp),%rsi
mov    $0x10,%edx
xor    %ecx,%ecx
xor    %r8d,%r8d
call   1060 <AES128_CBC_decrypt_buffer@plt>
lea    0x1009(%rip),%rdi
call   1050 <printf@plt>
mov    %r14,%rdi
mov    %r15,%rsi
mov    $0x40,%edx
call   1030 <strncmp@plt>
test   %rax,%rax
lea    0x1001(%rip),%rax
lea    0xff1(%rip),%rdi
cmove  %rax,%rdi
call   1040 <puts@plt>
add    $0x380,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@__const.test_decrypt_cbc.key = [16 x i32] [i32 43, i32 126, i32 21, i32 22, i32 40, i32 174, i32 210, i32 166, i32 171, i32 247, i32 21, i32 136, i32 9, i32 207, i32 79, i32 60]
@__const.test_decrypt_cbc.iv = [16 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15]
@__const.test_decrypt_cbc.in = [64 x i32] [i32 118, i32 73, i32 171, i32 172, i32 129, i32 25, i32 178, i32 70, i32 206, i32 233, i32 142, i32 155, i32 18, i32 233, i32 25, i32 125, i32 80, i32 134, i32 203, i32 155, i32 80, i32 114, i32 25, i32 238, i32 149, i32 219, i32 17, i32 58, i32 145, i32 118, i32 120, i32 178, i32 115, i32 190, i32 214, i32 184, i32 227, i32 193, i32 116, i32 59, i32 113, i32 22, i32 230, i32 158, i32 34, i32 34, i32 149, i32 22, i32 63, i32 241, i32 202, i32 161, i32 104, i32 31, i32 172, i32 9, i32 18, i32 14, i32 202, i32 48, i32 117, i32 134, i32 225, i32 167]
@__const.test_decrypt_cbc.out = [64 x i32] [i32 107, i32 193, i32 190, i32 226, i32 46, i32 64, i32 159, i32 150, i32 233, i32 61, i32 126, i32 17, i32 115, i32 147, i32 23, i32 42, i32 174, i32 45, i32 138, i32 87, i32 30, i32 3, i32 172, i32 156, i32 158, i32 183, i32 111, i32 172, i32 69, i32 175, i32 142, i32 81, i32 48, i32 200, i32 28, i32 70, i32 163, i32 92, i32 228, i32 17, i32 229, i32 251, i32 193, i32 25, i32 26, i32 10, i32 82, i32 239, i32 246, i32 159, i32 36, i32 69, i32 223, i32 79, i32 155, i32 23, i32 173, i32 43, i32 65, i32 123, i32 230, i32 108, i32 55, i32 16]
@.str = [14 x i8] c"CBC decrypt: \00"
@.str.1 = [10 x i8] c"SUCCESS!\0A\00"
@.str.2 = [10 x i8] c"FAILURE!\0A\00"
define void @test_decrypt_cbc() {
%1 = alloca [16 x i32]
%2 = alloca [16 x i32]
%3 = alloca [64 x i32]
%4 = alloca [64 x i32]
%5 = alloca [64 x i32]
%6 = bitcast [16 x i32]* %1 to i8*
%7 = bitcast [16 x i32]* %2 to i8*
%8 = bitcast [64 x i32]* %3 to i8*
%9 = bitcast [64 x i32]* %4 to i8*
%10 = getelementptr inbounds [64 x i32], [64 x i32]* %5, i64 0, i64 0
%11 = getelementptr inbounds i32, i32* %10, i64 0
%12 = getelementptr inbounds [64 x i32], [64 x i32]* %3, i64 0, i64 0
%13 = getelementptr inbounds i32, i32* %12, i64 0
%14 = getelementptr inbounds [16 x i32], [16 x i32]* %1, i64 0, i64 0
%15 = getelementptr inbounds [16 x i32], [16 x i32]* %2, i64 0, i64 0
%16 = call i32 @AES128_CBC_decrypt_buffer(i32* %11, i32* %13, i32 16, i32* %14, i32* %15)
%17 = getelementptr inbounds [64 x i32], [64 x i32]* %5, i64 0, i64 0
%18 = getelementptr inbounds i32, i32* %17, i64 16
%19 = getelementptr inbounds [64 x i32], [64 x i32]* %3, i64 0, i64 0
%20 = getelementptr inbounds i32, i32* %19, i64 16
%21 = call i32 @AES128_CBC_decrypt_buffer(i32* %18, i32* %20, i32 16, i32* null, i32* null)
%22 = getelementptr inbounds [64 x i32], [64 x i32]* %5, i64 0, i64 0
%23 = getelementptr inbounds i32, i32* %22, i64 32
%24 = getelementptr inbounds [64 x i32], [64 x i32]* %3, i64 0, i64 0
%25 = getelementptr inbounds i32, i32* %24, i64 32
%26 = call i32 @AES128_CBC_decrypt_buffer(i32* %23, i32* %25, i32 16, i32* null, i32* null)
%27 = getelementptr inbounds [64 x i32], [64 x i32]* %5, i64 0, i64 0
%28 = getelementptr inbounds i32, i32* %27, i64 48
%29 = getelementptr inbounds [64 x i32], [64 x i32]* %3, i64 0, i64 0
%30 = getelementptr inbounds i32, i32* %29, i64 48
%31 = call i32 @AES128_CBC_decrypt_buffer(i32* %28, i32* %30, i32 16, i32* null, i32* null)
%32 = call i32 @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0))
%33 = getelementptr inbounds [64 x i32], [64 x i32]* %4, i64 0, i64 0
%34 = bitcast i32* %33 to i8*
%35 = getelementptr inbounds [64 x i32], [64 x i32]* %5, i64 0, i64 0
%36 = bitcast i32* %35 to i8*
%37 = call i64 @strncmp(i8* %34, i8* %36, i32 64)
%38 = icmp eq i64 0, %37
br i1 %38, label %39, label %41
39: ; preds = %0
%40 = call i32 @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.1, i64 0, i64 0))
br label %43
41: ; preds = %0
%42 = call i32 @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0))
br label %43
43: ; preds = %41, %39
ret void
}

LLVM IR (-O2):
@__const.test_decrypt_cbc.key = [16 x i32] [i32 43, i32 126, i32 21, i32 22, i32 40, i32 174, i32 210, i32 166, i32 171, i32 247, i32 21, i32 136, i32 9, i32 207, i32 79, i32 60]
@__const.test_decrypt_cbc.iv = [16 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15]
@__const.test_decrypt_cbc.in = [64 x i32] [i32 118, i32 73, i32 171, i32 172, i32 129, i32 25, i32 178, i32 70, i32 206, i32 233, i32 142, i32 155, i32 18, i32 233, i32 25, i32 125, i32 80, i32 134, i32 203, i32 155, i32 80, i32 114, i32 25, i32 238, i32 149, i32 219, i32 17, i32 58, i32 145, i32 118, i32 120, i32 178, i32 115, i32 190, i32 214, i32 184, i32 227, i32 193, i32 116, i32 59, i32 113, i32 22, i32 230, i32 158, i32 34, i32 34, i32 149, i32 22, i32 63, i32 241, i32 202, i32 161, i32 104, i32 31, i32 172, i32 9, i32 18, i32 14, i32 202, i32 48, i32 117, i32 134, i32 225, i32 167]
@__const.test_decrypt_cbc.out = [64 x i32] [i32 107, i32 193, i32 190, i32 226, i32 46, i32 64, i32 159, i32 150, i32 233, i32 61, i32 126, i32 17, i32 115, i32 147, i32 23, i32 42, i32 174, i32 45, i32 138, i32 87, i32 30, i32 3, i32 172, i32 156, i32 158, i32 183, i32 111, i32 172, i32 69, i32 175, i32 142, i32 81, i32 48, i32 200, i32 28, i32 70, i32 163, i32 92, i32 228, i32 17, i32 229, i32 251, i32 193, i32 25, i32 26, i32 10, i32 82, i32 239, i32 246, i32 159, i32 36, i32 69, i32 223, i32 79, i32 155, i32 23, i32 173, i32 43, i32 65, i32 123, i32 230, i32 108, i32 55, i32 16]
@.str = [14 x i8] c"CBC decrypt: \00"
@str = [9 x i8] c"FAILURE!\00"
@str.3 = [9 x i8] c"SUCCESS!\00"
define void @test_decrypt_cbc() {
%1 = alloca [16 x i32]
%2 = alloca [16 x i32]
%3 = alloca [64 x i32]
%4 = alloca [64 x i32]
%5 = alloca [64 x i32]
%6 = bitcast [16 x i32]* %1 to i8*
%7 = bitcast [16 x i32]* %2 to i8*
%8 = bitcast [64 x i32]* %3 to i8*
%9 = bitcast [64 x i32]* %4 to i8*
%10 = bitcast [64 x i32]* %5 to i8*
%11 = getelementptr inbounds [64 x i32], [64 x i32]* %5, i64 0, i64 0
%12 = getelementptr inbounds [64 x i32], [64 x i32]* %3, i64 0, i64 0
%13 = getelementptr inbounds [16 x i32], [16 x i32]* %1, i64 0, i64 0
%14 = getelementptr inbounds [16 x i32], [16 x i32]* %2, i64 0, i64 0
%15 = call i32 @AES128_CBC_decrypt_buffer(i32* %11, i32* %12, i32 16, i32* %13, i32* %14)
%16 = getelementptr inbounds [64 x i32], [64 x i32]* %5, i64 0, i64 16
%17 = getelementptr inbounds [64 x i32], [64 x i32]* %3, i64 0, i64 16
%18 = call i32 @AES128_CBC_decrypt_buffer(i32* %16, i32* %17, i32 16, i32* null, i32* null)
%19 = getelementptr inbounds [64 x i32], [64 x i32]* %5, i64 0, i64 32
%20 = getelementptr inbounds [64 x i32], [64 x i32]* %3, i64 0, i64 32
%21 = call i32 @AES128_CBC_decrypt_buffer(i32* %19, i32* %20, i32 16, i32* null, i32* null)
%22 = getelementptr inbounds [64 x i32], [64 x i32]* %5, i64 0, i64 48
%23 = getelementptr inbounds [64 x i32], [64 x i32]* %3, i64 0, i64 48
%24 = call i32 @AES128_CBC_decrypt_buffer(i32* %22, i32* %23, i32 16, i32* null, i32* null)
%25 = call i32 @printf(i8* dereferenceable(1) getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0))
%26 = call i64 @strncmp(i8* %9, i8* %10, i32 64)
%27 = icmp eq i64 %26, 0
%28 = select i1 %27, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @str.3, i64 0, i64 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @str, i64 0, i64 0)
%29 = call i32 @puts(i8* dereferenceable(1) %28)
ret void
}