// File: /workspace/github_c_makefile_star2_O0/blasphemy[P]mmc-utils/mmc_cmds.c
// Function: do_rpmb_read_block
int do_rpmb_read_block(int nargs, char **argv)
{
	int i, ret, dev_fd, data_fd, key_fd = -1;
	uint16_t addr;
	/*
	 * for reading RPMB, number of blocks is set by CMD23 only, the packet
	 * frame field for that is set to 0. So, the type is not u16 but uint!
	 */
	unsigned int blocks_cnt;
	unsigned char key[32];
	struct rpmb_frame frame_in = {
		.req_resp    = htobe16(MMC_RPMB_READ),
	}, *frame_out_p;

	if (nargs != 5 && nargs != 6) {
		fprintf(stderr, "Usage: mmc rpmb read-block </path/to/mmcblkXrpmb> <address> <blocks count> </path/to/output_file> [/path/to/key]\n");
		exit(1);
	}

	dev_fd = open(argv[1], O_RDWR);
	if (dev_fd < 0) {
		perror("device open");
		exit(1);
	}

	/* Get block address */
	errno = 0;
	addr = strtol(argv[2], NULL, 0);
	if (errno) {
		perror("incorrect address");
		exit(1);
	}
	frame_in.addr = htobe16(addr);

	/* Get blocks count */
	errno = 0;
	blocks_cnt = strtol(argv[3], NULL, 0);
	if (errno) {
		perror("incorrect blocks count");
		exit(1);
	}

	if (!blocks_cnt) {
		printf("please, specify valid blocks count number\n");
		exit(1);
	}

	frame_out_p = calloc(sizeof(*frame_out_p), blocks_cnt);
	if (!frame_out_p) {
		printf("can't allocate memory for RPMB outer frames\n");
		exit(1);
	}

	/* Write 256b data */
	if (0 == strcmp(argv[4], "-"))
		data_fd = STDOUT_FILENO;
	else {
		data_fd = open(argv[4], O_WRONLY | O_CREAT | O_APPEND,
					   S_IRUSR | S_IWUSR);
		if (data_fd < 0) {
			perror("can't open output file");
			exit(1);
		}
	}

	/* Key is specified */
	if (nargs == 6) {
		if (0 == strcmp(argv[5], "-"))
			key_fd = STDIN_FILENO;
		else {
			key_fd = open(argv[5], O_RDONLY);
			if (key_fd < 0) {
				perror("can't open input key file");
				exit(1);
			}
		}

		ret = DO_IO(read, key_fd, key, sizeof(key));
		if (ret < 0) {
			perror("read the key data");
			exit(1);
		} else if (ret != sizeof(key)) {
			printf("Data must be %lu bytes length, but we read only %d, exit\n",
				   (unsigned long)sizeof(key),
				   ret);
			exit(1);
		}
	}

	/* Execute RPMB op */
	ret = do_rpmb_op(dev_fd, &frame_in, frame_out_p, blocks_cnt);
	if (ret != 0) {
		perror("RPMB ioctl failed");
		exit(1);
	}

	/* Check RPMB response */
	if (frame_out_p[blocks_cnt - 1].result != 0) {
		printf("RPMB operation failed, retcode 0x%04x\n",
			   be16toh(frame_out_p[blocks_cnt - 1].result));
		exit(1);
	}

	/* Do we have to verify data against key? */
	if (nargs == 6) {
		unsigned char mac[32];
		hmac_sha256_ctx ctx;
		struct rpmb_frame *frame_out = NULL;

		hmac_sha256_init(&ctx, key, sizeof(key));
		for (i = 0; i < blocks_cnt; i++) {
			frame_out = &frame_out_p[i];
			hmac_sha256_update(&ctx, frame_out->data,
							   sizeof(*frame_out) -
								   offsetof(struct rpmb_frame, data));
		}

		hmac_sha256_final(&ctx, mac, sizeof(mac));

		/* Impossible */
		assert(frame_out);

		/* Compare calculated MAC and MAC from last frame */
		if (memcmp(mac, frame_out->key_mac, sizeof(mac))) {
			printf("RPMB MAC missmatch\n");
			exit(1);
		}
	}

	/* Write data */
	for (i = 0; i < blocks_cnt; i++) {
		struct rpmb_frame *frame_out = &frame_out_p[i];
		ret = DO_IO(write, data_fd, frame_out->data, sizeof(frame_out->data));
		if (ret < 0) {
			perror("write the data");
			exit(1);
		} else if (ret != sizeof(frame_out->data)) {
			printf("Data must be %lu bytes length, but we wrote only %d, exit\n",
				   (unsigned long)sizeof(frame_out->data),
				   ret);
			exit(1);
		}
	}

	free(frame_out_p);
	close(dev_fd);
	if (data_fd != STDOUT_FILENO)
		close(data_fd);
	if (key_fd != -1 && key_fd != STDIN_FILENO)
		close(key_fd);

	return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x5e0, %rsp            # imm = 0x5E0
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
movl $0xffffffff, -0x24(%rbp) # imm = 0xFFFFFFFF
leaq -0x250(%rbp), %rdi
xorl %esi, %esi
movl $0x200, %edx            # imm = 0x200
callq 0x30f0
movl $0x4, %edi
callq 0x8670
movw %ax, -0x52(%rbp)
cmpl $0x5, -0x4(%rbp)
je 0x8af8
cmpl $0x6, -0x4(%rbp)
je 0x8af8
movq 0x12513(%rip), %rax     # 0x1aff0
movq (%rax), %rdi
leaq 0xd5e6(%rip), %rsi      # 0x160cd
movb $0x0, %al
callq 0x3180
movl $0x1, %edi
callq 0x3240
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x2, %esi
movb $0x0, %al
callq 0x31e0
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jge 0x8b2b
leaq 0xd4c1(%rip), %rdi      # 0x15fdd
callq 0x3200
movl $0x1, %edi
callq 0x3240
callq 0x3050
movl $0x0, (%rax)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x31a0
movw %ax, -0x26(%rbp)
callq 0x3050
cmpl $0x0, (%rax)
je 0x8b6d
leaq 0xd5e1(%rip), %rdi      # 0x1613f
callq 0x3200
movl $0x1, %edi
callq 0x3240
movzwl -0x26(%rbp), %edi
callq 0x8670
movw %ax, -0x58(%rbp)
callq 0x3050
movl $0x0, (%rax)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x31a0
movl %eax, -0x2c(%rbp)
callq 0x3050
cmpl $0x0, (%rax)
je 0x8bbb
leaq 0xd5a5(%rip), %rdi      # 0x16151
callq 0x3200
movl $0x1, %edi
callq 0x3240
cmpl $0x0, -0x2c(%rbp)
jne 0x8bd9
leaq 0xd5a0(%rip), %rdi      # 0x16168
movb $0x0, %al
callq 0x30c0
movl $0x1, %edi
callq 0x3240
movl -0x2c(%rbp), %eax
movl %eax, %esi
movl $0x200, %edi            # imm = 0x200
callq 0x3160
movq %rax, -0x258(%rbp)
cmpq $0x0, -0x258(%rbp)
jne 0x8c11
leaq 0xd593(%rip), %rdi      # 0x16193
movb $0x0, %al
callq 0x30c0
movl $0x1, %edi
callq 0x3240
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
leaq 0xa6dd(%rip), %rsi      # 0x132fd
callq 0x3170
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x8c36
movl $0x1, -0x20(%rbp)
jmp 0x8c70
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movl $0x441, %esi            # imm = 0x441
movl $0x180, %edx            # imm = 0x180
movb $0x0, %al
callq 0x31e0
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jge 0x8c6e
leaq 0xd561(%rip), %rdi      # 0x161c0
callq 0x3200
movl $0x1, %edi
callq 0x3240
jmp 0x8c70
cmpl $0x6, -0x4(%rbp)
jne 0x8dd9
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
leaq 0xa674(%rip), %rsi      # 0x132fd
callq 0x3170
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x8c9f
movl $0x0, -0x24(%rbp)
jmp 0x8cd1
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
xorl %esi, %esi
movb $0x0, %al
callq 0x31e0
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jge 0x8ccf
leaq 0xd517(%rip), %rdi      # 0x161d7
callq 0x3200
movl $0x1, %edi
callq 0x3240
jmp 0x8cd1
movq $0x0, -0x260(%rbp)
movl -0x24(%rbp), %edi
leaq -0x50(%rbp), %rsi
addq -0x260(%rbp), %rsi
movl $0x20, %edx
subq -0x260(%rbp), %rdx
callq 0x3120
movq %rax, -0x268(%rbp)
cmpq $0x0, -0x268(%rbp)
jge 0x8d23
callq 0x3050
cmpl $0x4, (%rax)
je 0x8d23
movq $-0x1, -0x260(%rbp)
jmp 0x8d77
cmpq $0x0, -0x268(%rbp)
jle 0x8d42
movq -0x268(%rbp), %rax
addq -0x260(%rbp), %rax
movq %rax, -0x260(%rbp)
jmp 0x8d44
jmp 0x8d46
xorl %eax, %eax
cmpq $0x0, -0x268(%rbp)
movb %al, -0x5d9(%rbp)
je 0x8d69
cmpq $0x20, -0x260(%rbp)
setne %al
movb %al, -0x5d9(%rbp)
movb -0x5d9(%rbp), %al
testb $0x1, %al
jne 0x8cdc
movq -0x260(%rbp), %rax
movq %rax, -0x270(%rbp)
movq -0x270(%rbp), %rax
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
jge 0x8dab
leaq 0xd455(%rip), %rdi      # 0x161f1
callq 0x3200
movl $0x1, %edi
callq 0x3240
movslq -0x18(%rbp), %rax
cmpq $0x20, %rax
je 0x8dd5
movl -0x18(%rbp), %edx
leaq 0xd444(%rip), %rdi      # 0x16203
movl $0x20, %esi
movb $0x0, %al
callq 0x30c0
movl $0x1, %edi
callq 0x3240
jmp 0x8dd7
jmp 0x8dd9
movl -0x1c(%rbp), %edi
movq -0x258(%rbp), %rdx
movl -0x2c(%rbp), %ecx
leaq -0x250(%rbp), %rsi
callq 0x86a0
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
je 0x8e11
leaq 0xd246(%rip), %rdi      # 0x16048
callq 0x3200
movl $0x1, %edi
callq 0x3240
movq -0x258(%rbp), %rax
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
shlq $0x9, %rcx
addq %rcx, %rax
movzwl 0x1fc(%rax), %eax
cmpl $0x0, %eax
je 0x8e70
movq -0x258(%rbp), %rax
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
shlq $0x9, %rcx
addq %rcx, %rax
movzwl 0x1fc(%rax), %edi
callq 0x8670
movzwl %ax, %esi
leaq 0xd1fb(%rip), %rdi      # 0x1605a
movb $0x0, %al
callq 0x30c0
movl $0x1, %edi
callq 0x3240
cmpl $0x6, -0x4(%rbp)
jne 0x8f7b
movq $0x0, -0x5b8(%rbp)
leaq -0x50(%rbp), %rsi
leaq -0x5b0(%rbp), %rdi
movl $0x20, %edx
callq 0xfdb0
movl $0x0, -0x14(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jae 0x8efa
movq -0x258(%rbp), %rax
movslq -0x14(%rbp), %rcx
shlq $0x9, %rcx
addq %rcx, %rax
movq %rax, -0x5b8(%rbp)
movq -0x5b8(%rbp), %rsi
addq $0xe4, %rsi
leaq -0x5b0(%rbp), %rdi
movl $0x200, %eax            # imm = 0x200
xorl %ecx, %ecx
addq $0xe4, %rcx
subq %rcx, %rax
movl %eax, %edx
callq 0xffa0
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x8ea1
leaq -0x290(%rbp), %rsi
leaq -0x5b0(%rbp), %rdi
movl $0x20, %edx
callq 0xffd0
cmpq $0x0, -0x5b8(%rbp)
je 0x8f1e
jmp 0x8f3d
leaq 0xd318(%rip), %rdi      # 0x1623d
leaq 0xd31b(%rip), %rsi      # 0x16247
movl $0x8b5, %edx            # imm = 0x8B5
leaq 0xd31a(%rip), %rcx      # 0x16252
callq 0x30e0
leaq -0x290(%rbp), %rdi
movq -0x5b8(%rbp), %rsi
addq $0xc4, %rsi
movl $0x20, %edx
callq 0x3140
cmpl $0x0, %eax
je 0x8f79
leaq 0xd30f(%rip), %rdi      # 0x16277
movb $0x0, %al
callq 0x30c0
movl $0x1, %edi
callq 0x3240
jmp 0x8f7b
movl $0x0, -0x14(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jae 0x90cc
movq -0x258(%rbp), %rax
movslq -0x14(%rbp), %rcx
shlq $0x9, %rcx
addq %rcx, %rax
movq %rax, -0x5c0(%rbp)
movq $0x0, -0x5c8(%rbp)
movl -0x20(%rbp), %edi
movq -0x5c0(%rbp), %rsi
addq $0xe4, %rsi
addq -0x5c8(%rbp), %rsi
movl $0x100, %edx            # imm = 0x100
subq -0x5c8(%rbp), %rdx
callq 0x3080
movq %rax, -0x5d0(%rbp)
cmpq $0x0, -0x5d0(%rbp)
jge 0x9003
callq 0x3050
cmpl $0x4, (%rax)
je 0x9003
movq $-0x1, -0x5c8(%rbp)
jmp 0x905a
cmpq $0x0, -0x5d0(%rbp)
jle 0x9022
movq -0x5d0(%rbp), %rax
addq -0x5c8(%rbp), %rax
movq %rax, -0x5c8(%rbp)
jmp 0x9024
jmp 0x9026
xorl %eax, %eax
cmpq $0x0, -0x5d0(%rbp)
movb %al, -0x5da(%rbp)
je 0x904c
cmpq $0x100, -0x5c8(%rbp) # imm = 0x100
setne %al
movb %al, -0x5da(%rbp)
movb -0x5da(%rbp), %al
testb $0x1, %al
jne 0x8fb2
movq -0x5c8(%rbp), %rax
movq %rax, -0x5d8(%rbp)
movq -0x5d8(%rbp), %rax
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
jge 0x908e
leaq 0xd20c(%rip), %rdi      # 0x1628b
callq 0x3200
movl $0x1, %edi
callq 0x3240
movslq -0x18(%rbp), %rax
cmpq $0x100, %rax            # imm = 0x100
je 0x90ba
movl -0x18(%rbp), %edx
leaq 0xd1f6(%rip), %rdi      # 0x1629a
movl $0x100, %esi            # imm = 0x100
movb $0x0, %al
callq 0x30c0
movl $0x1, %edi
callq 0x3240
jmp 0x90bc
jmp 0x90be
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x8f82
movq -0x258(%rbp), %rdi
callq 0x3030
movl -0x1c(%rbp), %edi
callq 0x3110
cmpl $0x1, -0x20(%rbp)
je 0x90ee
movl -0x20(%rbp), %edi
callq 0x3110
cmpl $-0x1, -0x24(%rbp)
je 0x9102
cmpl $0x0, -0x24(%rbp)
je 0x9102
movl -0x24(%rbp), %edi
callq 0x3110
movl -0x18(%rbp), %eax
addq $0x5e0, %rsp            # imm = 0x5E0
popq %rbp
retq
nop