Line 1: |
Line 1: |
− | TSEC is a nvidia falcon processor with crypto extensions.
| + | #REDIRECT [[TSEC]] |
− | | |
− | Firmware can be disassembled with [http://envytools.readthedocs.io/en/latest/ envytools'] [https://github.com/envytools/envytools/tree/master/envydis envydis]:
| |
− | | |
− | <code>envydis -i tsec_fw.bin -m falcon -V fuc5 -F crypt</code>
| |
− | | |
− | Note that the instruction set has variable length instructions, and the disassembler is not very good at detecting locations it should start disassembling from. One needs to disassemble multiple sub-regions and join them together.
| |
− | | |
− | == Additional Notes on Crypto Extensions ==
| |
− | | |
− | [https://wiki.0x04.net/wiki/Marcin_Ko%C5%9Bcielnicki mwk] shared additional info learned from RE of falcon processors over the years, which hasn't made it into envytools documentation yet:
| |
− | | |
− | === cxset ===
| |
− | | |
− | cxset instruction provides a way to change behavior of a variable amount of successively executed DMA-related instructions.
| |
− | | |
− | for example: <code>000000de: f4 3c 02 cxset 0x2</code>
| |
− | | |
− | can be read as: <code>dma_override(type=crypto_reg, count=2)</code>
| |
− | | |
− | The argument to cxset specifies the type of behavior change in the top 3 bits, and the number of DMA-related instructions the effect lasts for in the lower 5 bits.
| |
− | | |
− | ==== Override Types ====
| |
− | | |
− | Unlisted values are unknown, but probably do something.
| |
− | | |
− | {| class=wikitable
| |
− | ! Value || Effect
| |
− | |-
| |
− | | 0b000 || falcon data mem <-> falcon $cX register
| |
− | |-
| |
− | | 0b001 || external mem <-> crypto input/output stream
| |
− | |}
| |
− | | |
− | ==== DMA-Related Instructions ====
| |
− | | |
− | At least the following instructions may have changed behavior, and count against the cxset "count" argument: <code>xdwait</code>, <code>xdst</code>, <code>xdld</code>.
| |
− | | |
− | For example, if override type=0b000, then the "length" argument to <code>xdst</code> is instead treated as the index of the target $cX register.
| |
− | | |
− | === Register ACLs ===
| |
− | | |
− | Falcon tracks permission metadata about each crypto reg. Permissions include read/write ability per execution mode, as well as ability to use the reg for encrypt/decrypt, among other permissions. Permissions are propagated when registers are referenced by instructions (e.g. moving a value from read-protected $cX to $cY will result in $cY also being read-protected).
| |
− | | |
− | === Authenticated Mode Entry/Exit ===
| |
− | | |
− | Entry to Authenticated Mode always sets $pc to the address supplied in $cauth (ie the base of the signature-checked region). This takes effect when trying to branch to any address within the range covered by $cauth. Entry to Authenticated Mode (also called "Secure Mode") computes a MAC over the $cauth region and compares it to $c6 in order to perform the signature check.
| |
− | | |
− | Exit from Authenticated Mode must poke a special register (this seems to be I[0x10300] = 0) before leaving authenticated code pages. Failure to do this would result in the Falcon core halting.
| |
− | | |
− | == Annotated Assembly ==
| |
− | | |
− | Keep in mind the architecture is not officially documented, so some things may be incorrect.
| |
− | | |
− | <pre>
| |
− | 00000000: 4d 00 42 mov $r13 0x4200 ; UC_CAPS
| |
− | 00000003: cf dd 00 iord $r13 I[$r13]
| |
− | 00000006: b6 d5 09 shr b32 $r13 0x9
| |
− | 00000009: f1 d4 ff 01 and $r13 0x1ff
| |
− | 0000000d: b6 d4 08 shl b32 $r13 0x8 ; r13 = falcon data segment size
| |
− | 00000010: fe d4 00 mov $sp $r13 ; put stack top all the way at the end
| |
− | 00000013: 7e 19 00 00 lcall 0x19
| |
− | 00000017: f8 02 exit
| |
− | | |
− | 00000019: 0f f0 C mov $r15 -0x10
| |
− | 0000001b: f5 30 e4 fe add $sp -0x11c
| |
− | 0000001f: f9 82 mpush $r8
| |
− | 00000021: fe 49 01 mov $r9 $sp
| |
− | 00000024: 90 99 c4 add b32 $r9 $r9 0xc4
| |
− | 00000027: ff 9f 34 and $r3 $r9 $r15 ; r3 = (sp + 0xc4) & ~0xf
| |
− | 0000002a: 92 99 8b sub b32 $r9 $r9 0x8b
| |
− | 0000002d: 85 00 03 00 mov $r5 0x300
| |
− | 00000031: ff 9f 44 and $r4 $r9 $r15 ; r4 = (sp + 0x39) & ~0xf
| |
− | 00000034: b2 5b mov b32 $r11 $r5
| |
− | 00000036: 0c 7c mov $r12 0x7c
| |
− | 00000038: b2 3a mov b32 $r10 $r3
| |
− | 0000003a: 7e 0b 02 00 lcall 0x20b ; memcpy_i2d(dst=r3{local}, src=0x300, len=0x7c)
| |
− | 0000003e: 98 3c 1d ld b32 $r12 D[$r3+TSecLoaderInfo.secure_loader_len] ; r12 = 0x600
| |
− | 00000041: 95 59 08 shr b32 $r9 $r5 0x8
| |
− | 00000044: 8b 00 04 00 mov $r11 0x400
| |
− | 00000048: b0 91 09 st b32 D[$sp+0x24] $r9
| |
− | 0000004b: bd a4 clear b32 $r10 ; temp copy for next step
| |
− | 0000004d: 7e 0b 02 00 lcall 0x20b ; memcpy_i2d(dst=0, src=0x400, len=0x600)
| |
− | 00000051: 98 3c 1d ld b32 $r12 D[$r3+TSecLoaderInfo.secure_loader_len] ; r12 = 0x600
| |
− | 00000054: b2 5a mov b32 $r10 $r5
| |
− | 00000056: bd b4 clear b32 $r11
| |
− | 00000058: b2 5d mov b32 $r13 $r5
| |
− | 0000005a: 0e 01 mov $r14 0x1 ; copy the code originally @ I:0x400 to I:0x300 and mark secret
| |
− | 0000005c: 7e c2 01 00 lcall 0x1c2 ; memcpy_d2i_ex(dst_page_offset=0x300, src=0, len=0x600, dst=0x300, is_secret=1)
| |
− | 00000060: 89 00 00 06 mov $r9 0x60000 ; will be used as size bits for xdst @ 000000e1
| |
− | 00000064: 90 4f 20 add b32 $r15 $r4 0x20 ; TSecLoaderInfo.field_20
| |
− | 00000067: bd 64 clear b32 $r6
| |
− | 00000069: ff f9 75 or $r7 $r15 $r9
| |
− | 0000006c: bd 24 clear b32 $r2 ; loop_count = 0
| |
− | 0000006e: bd 94 clear b32 $r9
| |
− | 00000070: bd 84 clear b32 $r8 ; ext_offset = 0
| |
− | 00000072: 3e 78 00 00 lbra 0x78
| |
− | loop_set_ignored_cmd:
| |
− | 00000076: b2 19 B mov b32 $r9 $r1 ; i guess this is because SCRATCH0 retains the old cmd
| |
− | loop:
| |
− | 00000078: 90 22 01 B add b32 $r2 $r2 0x1
| |
− | 0000007b: 8f 01 09 3d mov $r15 0x3d0901 ; 4000001
| |
− | 0000007f: a6 2f cmp b32 $r2 $r15
| |
− | 00000081: f4 1b 17 bra ne 0x98 ; for (u32 r2 = 0; r2 < 4000000; r2++) {
| |
− | set_status_c0_loop_expired:
| |
− | 00000084: df c0 c0 c0 c0 mov $r15 0xc0c0c0c0
| |
− | 00000089: 49 00 11 mov $r9 0x1100
| |
− | 0000008c: fa 9f 00 iowr I[$r9] $r15 ; SCRATCH1 = 0xc0c0c0c0
| |
− | 0000008f: d0 c0 c0 c0 c0 mov $r0 0xc0c0c0c0
| |
− | 00000094: 3e 0c 01 00 lbra 0x10c ; -> writeback_key_and_ret
| |
− | read_next_command:
| |
− | 00000098: 4f 00 10 B mov $r15 0x1000
| |
− | 0000009b: ff f8 1f iord $r1 I[$r15+$r8*0x4] ; r1 = SCRATCH0 (cmd)
| |
− | 0000009e: b3 14 64 18 bra b32 $r1 0x64 ne 0xb6 ; -> dispatch_command
| |
− | handle_command_0x64:
| |
− | 000000a2: df b0 b0 b0 b0 mov $r15 0xb0b0b0b0
| |
− | 000000a7: 49 00 11 mov $r9 0x1100
| |
− | 000000aa: fa 9f 00 iowr I[$r9] $r15 ; SCRATCH1 = 0xb0b0b0b0
| |
− | 000000ad: d0 b0 b0 b0 b0 mov $r0 0xb0b0b0b0
| |
− | 000000b2: 3e 0c 01 00 lbra 0x10c ; -> writeback_key_and_ret
| |
− | dispatch_command:
| |
− | 000000b6: a6 19 B cmp b32 $r1 $r9
| |
− | 000000b8: f4 0b c0 bra e 0x78 ; if (cmd == ignored_cmd) continue;
| |
− | 000000bb: b3 10 00 3b bra b32 $r1 0x0 e 0xf6 ; if (cmd == 0) set_status_b0_ok_and_continue;
| |
− | 000000bf: b0 16 03 cmp b32 $r1 0x3
| |
− | 000000c2: f4 0c 56 bra a 0x118 ; if (cmd > 3) return BAD_CMD;
| |
− | 000000c5: b2 4a mov b32 $r10 $r4
| |
− | 000000c7: b2 3b mov b32 $r11 $r3
| |
− | 000000c9: 0c 7c mov $r12 0x7c ; make another copy of the ldr_info (secure_loader will zero it before return)
| |
− | 000000cb: 7e 37 02 00 lcall 0x237 ; memcpy_d2d(dst=r4{local}, src=r3{local}, len=0x7c)
| |
− | 000000cf: 98 49 1d ld b32 $r9 D[$r4+TSecLoaderInfo.secure_loader_len] ; code_size = 0x600
| |
− | 000000d2: b4 f0 09 ld b32 $r15 D[$sp+0x24] ; secure_loader_dst_page = 0x300 >> 8
| |
− | 000000d5: b6 94 10 shl b32 $r9 0x10
| |
− | 000000d8: fd 9f 05 or $r9 $r15
| |
− | 000000db: fe 9a 00 mov $cauth $r9 ; cauth = (code_size << 16) | secure_loader_dst_page
| |
− | 000000de: f4 3c 02 cxset 0x2 ; dma_override(type=crypto_reg, count=2)
| |
− | 000000e1: fa 87 06 xdst $r8 $r7 ; crypto_reg_load(crypto_reg=$c6, local_address=r4+0x20)
| |
− | 000000e4: f8 03 xdwait
| |
− | 000000e6: b2 6c mov b32 $r12 $r6
| |
− | 000000e8: b2 4a mov b32 $r10 $r4
| |
− | 000000ea: b2 1b mov b32 $r11 $r1
| |
− | 000000ec: 06 01 mov $r6 0x1 ; set loader_called=1 for next iterations
| |
− | 000000ee: f9 55 call $r5 ; secure_loader_thunk(ldr_info{r4 local}, cmd, skip_copy_and_decrypt=loader_called)
| |
− | 000000f0: b2 a0 mov b32 $r0 $r10
| |
− | 000000f2: b3 a4 00 09 bra b32 $r10 0x0 ne 0xfb ; if (rv != 0) { SCRATCH1 = rv; return; }
| |
− | set_status_b0_ok_and_continue:
| |
− | 000000f6: d0 b0 b0 b0 b0 B mov $r0 0xb0b0b0b0 ; else { SCRATCH1 = 0xb0b0b0b0; continue; }
| |
− | write_status_and_key: // returns if status != 0xb0b0b0b0
| |
− | 000000fb: 49 00 11 B mov $r9 0x1100
| |
− | 000000fe: fa 90 00 iowr I[$r9] $r0 ; SCRATCH1 = rv
| |
− | 00000101: df b0 b0 b0 b0 mov $r15 0xb0b0b0b0
| |
− | 00000106: a6 0f cmp b32 $r0 $r15
| |
− | 00000108: f5 0b 6e ff bra e 0x76 ; -> loop_set_ignored_cmd (continue)
| |
− | writeback_key_and_ret:
| |
− | 0000010c: b2 3a B mov b32 $r10 $r3 ; somehow secure_payload writes back to this..?
| |
− | 0000010e: 7e 77 01 00 lcall 0x177 ; write128_via_SOR(r3{local})
| |
− | 00000112: b2 0a mov b32 $r10 $r0
| |
− | 00000114: fb 83 1c 01 mpopaddret $r8, 0x11c ; was: mpopunk [unknown: 00 80 1c 01]
| |
− | set_status_d0_bad_cmd:
| |
− | 00000118: d0 d0 d0 d0 d0 B mov $r0 0xd0d0d0d0 ; rv = 0xd0d0d0d0
| |
− | 0000011d: 3e fb 00 00 lbra 0xfb
| |
− | | |
− | // wait_1c000()
| |
− | // 0x1c000 == mmio + 0x700
| |
− | while (((*(u32 *)0x1c000 >> 12) & 7) == 1) {
| |
− | ; // expect it to clear to 0
| |
− | }
| |
− | 00000121: 8f 00 c0 01 C mov $r15 0x1c000
| |
− | 00000125: cf f9 00 B iord $r9 I[$r15]
| |
− | 00000128: c7 9a 4c extr $r10 $r9 0xc:0xe
| |
− | 0000012b: b3 a0 01 fa bra b32 $r10 0x1 e 0x125
| |
− | 0000012f: f8 00 ret
| |
− | | |
− | // write_1c000_indirect(addr=r10, val=r11)
| |
− | 00000131: f9 12 C mpush $r1
| |
− | 00000133: b2 a0 mov b32 $r0 $r10
| |
− | 00000135: b2 b1 mov b32 $r1 $r11
| |
− | 00000137: 7e 21 01 00 lcall 0x121
| |
− | 0000013b: 09 01 mov $r9 0x1
| |
− | 0000013d: b3 a4 00 2d bra b32 $r10 0x0 ne 0x16a ; if (wait_1c000() != STATUS_OK) return 1;
| |
− | 00000141: 89 00 c1 01 mov $r9 0x1c100
| |
− | 00000145: fa 90 00 iowr I[$r9] $r0 ; 0x1c100 = addr
| |
− | 00000148: b8 99 00 01 00 add b32 $r9 $r9 0x100
| |
− | 0000014d: fa 91 00 iowr I[$r9] $r1 ; 0x1c200 = val
| |
− | 00000150: df f2 00 00 80 mov $r15 0x800000f2
| |
− | 00000155: b8 99 00 02 02 sub b32 $r9 $r9 0x200
| |
− | 0000015a: fa 9f 00 iowr I[$r9] $r15 ; 0x1c000 = 0x800000f2
| |
− | 0000015d: 7e 21 01 00 lcall 0x121 ; wait_1c000()
| |
− | 00000161: b0 a6 00 cmp b32 $r10 0x0
| |
− | 00000164: f0 9c 0b xbit $r9 $flags z
| |
− | 00000167: f0 96 01 xor $r9 0x1 ; return (wait_1c000() == STATUS_OK) ? 0 : 1;
| |
− | 0000016a: b2 9a B mov b32 $r10 $r9
| |
− | 0000016c: fb 11 mpopret $r1
| |
− | | |
− | // write_1c300(val=r10)
| |
− | ; unused function?
| |
− | 0000016e: 89 00 c3 01 mov $r9 0x1c300
| |
− | 00000172: fa 9a 00 iowr I[$r9] $r10 ; 0x1c300 = r10
| |
− | 00000175: f8 00 ret
| |
− | | |
− | // throw the key material in "random" HDCP key regs...
| |
− | void write128_via_SOR(u32 *data) {
| |
− | 0x1c300 = 0xfff;
| |
− | if (write_1c000_indirect(0x545801e8, data[0])) {
| |
− | return;
| |
− | }
| |
− | if (write_1c000_indirect(0x5458021c, data[1])) {
| |
− | return;
| |
− | }
| |
− | if (write_1c000_indirect(0x54580208, data[2])) {
| |
− | return;
| |
− | }
| |
− | if (write_1c000_indirect(0x5458020c, data[3])) {
| |
− | return;
| |
− | }
| |
− | }
| |
− | 00000177: f9 02 C mpush $r0
| |
− | 00000179: 4f ff 0f mov $r15 0xfff
| |
− | 0000017c: b2 a0 mov b32 $r0 $r10
| |
− | 0000017e: 89 00 c3 01 mov $r9 0x1c300
| |
− | 00000182: fa 9f 00 iowr I[$r9] $r15
| |
− | 00000185: bf ab ld b32 $r11 D[$r10]
| |
− | 00000187: da e8 01 58 54 mov $r10 0x545801e8
| |
− | 0000018c: 7e 31 01 00 lcall 0x131
| |
− | 00000190: b3 a4 00 30 bra b32 $r10 0x0 ne 0x1c0
| |
− | 00000194: 98 0b 01 ld b32 $r11 D[$r0+0x4]
| |
− | 00000197: da 1c 02 58 54 mov $r10 0x5458021c
| |
− | 0000019c: 7e 31 01 00 lcall 0x131
| |
− | 000001a0: b3 a4 00 20 bra b32 $r10 0x0 ne 0x1c0
| |
− | 000001a4: 98 0b 02 ld b32 $r11 D[$r0+0x8]
| |
− | 000001a7: da 08 02 58 54 mov $r10 0x54580208
| |
− | 000001ac: 7e 31 01 00 lcall 0x131
| |
− | 000001b0: b3 a4 00 10 bra b32 $r10 0x0 ne 0x1c0
| |
− | 000001b4: 98 0b 03 ld b32 $r11 D[$r0+0xc]
| |
− | 000001b7: da 0c 02 58 54 mov $r10 0x5458020c
| |
− | 000001bc: 7e 31 01 00 lcall 0x131
| |
− | 000001c0: fb 01 B mpopret $r0
| |
− | | |
− | // memcpy_d2i_ex(dst_page_offset=r10, src=r11, len=r12, dst=r13, is_secret=r14)
| |
− | 000001c2: f9 02 C mpush $r0
| |
− | 000001c4: b2 b0 mov b32 $r0 $r11 ; src, data
| |
− | 000001c6: b2 cb mov b32 $r11 $r12 ; len, bytes
| |
− | 000001c8: b2 dc mov b32 $r12 $r13 ; dst, insn
| |
− | 000001ca: 33 00 00 0a bra b8 $r0 0x0 e 0x1d4 ; assert((src & 0xff) == 0)
| |
− | 000001ce: f8 02 exit
| |
− | 000001d0: 3e d0 01 00 B lbra 0x1d0
| |
− | 000001d4: 33 b0 00 0a B bra b8 $r11 0x0 e 0x1de ; assert((len & 0xff) == 0)
| |
− | 000001d8: f8 02 exit
| |
− | 000001da: 3e da 01 00 B lbra 0x1da
| |
− | 000001de: 33 c0 00 0a B bra b8 $r12 0x0 e 0x1e8 ; assert((dst & 0xff) == 0)
| |
− | 000001e2: f8 02 exit
| |
− | 000001e4: 3e e4 01 00 B lbra 0x1e4
| |
− | 000001e8: b3 e0 00 0d B bra b32 $r14 0x0 e 0x1f5
| |
− | 000001ec: d9 00 00 00 11 mov $r9 0x11000000
| |
− | 000001f1: 3e fa 01 00 lbra 0x1fa
| |
− | 000001f5: d9 00 00 00 01 B mov $r9 0x1000000
| |
− | 000001fa: ff a9 95 B or $r9 $r10 $r9
| |
− | 000001fd: 4f 00 60 mov $r15 0x6000 ;
| |
− | 00000200: fa f9 00 iowr I[$r15] $r9 ; CODE_INDEX = r10 | AUTO_INC_WRITE | ((r14) ? SECRET : 0)
| |
− | 00000203: b2 0a mov b32 $r10 $r0
| |
− | 00000205: 7e 4f 02 00 lcall 0x24f ; memcpy_d2i(src=r10, len=r11, dst=r12)
| |
− | 00000209: fb 01 mpopret $r0
| |
− | | |
− | // memcpy_i2d(dst=r10, src=r11, len=r12)
| |
− | CODE_INDEX = r11 | 0x2000000; // AUTO_INC_READ
| |
− | for (u32 r14 = 0; r14 < r12; r14 += 4) {
| |
− | r10[r14] = CODE;
| |
− | }
| |
− | 0000020b: d9 00 00 00 02 C mov $r9 0x2000000
| |
− | 00000210: fd b9 05 or $r11 $r9
| |
− | 00000213: 49 00 60 mov $r9 0x6000
| |
− | 00000216: fa 9b 00 iowr I[$r9] $r11 ; CODE_INDEX = r11 | 0x2000000
| |
− | 00000219: bd e4 clear b32 $r14 ; r14 = 0
| |
− | 0000021b: 4b 00 61 mov $r11 0x6100
| |
− | 0000021e: bd d4 clear b32 $r13 ; r13 = 0
| |
− | 00000220: 3e 30 02 00 lbra 0x230
| |
− | 00000224: ff bd ff B iord $r15 I[$r11+$r13*0x4] ; r15 = CODE
| |
− | 00000227: 95 e9 02 shr b32 $r9 $r14 0x2 ; r9 = r14 / 2
| |
− | 0000022a: 90 ee 04 add b32 $r14 $r14 0x4 ; r14 += 4
| |
− | 0000022d: bc af 99 st b32 D[$r10+$r9*0x4] $r15 ; [r10 + r9 * 4] = r15
| |
− | 00000230: a6 ec B cmp b32 $r14 $r12
| |
− | 00000232: f4 08 f2 bra b 0x224
| |
− | 00000235: f8 00 ret
| |
− | | |
− | // memcpy_d2d(dst=r10, src=r11, len=r12)
| |
− | 00000237: 3e 48 02 00 C lbra 0x248
| |
− | 0000023b: bf bf B ld b32 $r15 D[$r11]
| |
− | 0000023d: b6 b0 04 add b32 $r11 0x4
| |
− | 00000240: b6 c2 04 sub b32 $r12 0x4
| |
− | 00000243: a0 af st b32 D[$r10] $r15
| |
− | 00000245: b6 a0 04 add b32 $r10 0x4
| |
− | 00000248: b3 c4 00 f3 B bra b32 $r12 0x0 ne 0x23b
| |
− | 0000024c: f8 00 ret
| |
− | | |
− | ; for some reason there is this extra byte here
| |
− | 0000024e: 01
| |
− | | |
− | // memcpy_d2i(src=r10, len=r11, dst=r12)
| |
− | // caller sets CODE_INDEX to initial page offset
| |
− | 0000024f: f9 32 mpush $r3
| |
− | 00000251: 4d 00 61 mov $r13 0x6100 ; CODE
| |
− | 00000254: 4e 00 62 mov $r14 0x6200 ; CODE_VIRT_ADDR
| |
− | 00000257: 3e 82 02 00 lbra 0x282
| |
− | 0000025b: c4 c0 ff B and $r0 $r12 0xff
| |
− | 0000025e: f4 0b 2a bra e 0x288
| |
− | 00000261: 98 a0 00 B ld b32 $r0 D[$r10]
| |
− | 00000264: 98 a1 01 ld b32 $r1 D[$r10+0x4]
| |
− | 00000267: 98 a2 02 ld b32 $r2 D[$r10+0x8]
| |
− | 0000026a: 98 a3 03 ld b32 $r3 D[$r10+0xc]
| |
− | 0000026d: f6 d0 00 iowr I[$r13] $r0
| |
− | 00000270: f6 d1 00 iowr I[$r13] $r1
| |
− | 00000273: f6 d2 00 iowr I[$r13] $r2
| |
− | 00000276: f6 d3 00 iowr I[$r13] $r3
| |
− | 00000279: b6 a0 10 add b32 $r10 0x10
| |
− | 0000027c: b6 b2 10 sub b32 $r11 0x10
| |
− | 0000027f: b6 c0 10 add b32 $r12 0x10
| |
− | 00000282: b3 b4 00 d9 B bra b32 $r11 0x0 ne 0x25b
| |
− | 00000286: fb 31 mpopret $r3
| |
− | 00000288: 95 c0 08 B shr b32 $r0 $r12 0x8
| |
− | 0000028b: f6 e0 00 iowr I[$r14] $r0 ; write next page base and continue
| |
− | 0000028e: 3e 61 02 00 lbra 0x261
| |
− | | |
− | ; this shit gets copied to 00000019's stack
| |
− | struct TSecLoaderInfo {
| |
− | u8 derived_key[16]; // written by the secure payload and then written back for bpmp to pass to SE
| |
− | u8 field_10[16]; // mac of unauthenticated code (which loads secure_loader). checked by secure_loader
| |
− | u8 field_20[16]; // used for auth of secure_loader code pages
| |
− | u8 field_30[16]; // used for auth of secure_payload code pages
| |
− | u8 field_40[16]; // IV to decrypt secure_payload
| |
− | u8 key_name_0[16]; // arg0 for secure_payload(cmd=1)
| |
− | u8 key_name_1[16]; // arg0 for secure_payload(cmd=2)
| |
− | u32 secure_loader_offset; // points to this info header (consumes 0x100 bytes). secure_loader relocated here
| |
− | u32 secure_loader_len; // size of secure_loader code after this 0x100 byte header
| |
− | u32 secure_payload_len;
| |
− | };
| |
− | 00000300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
| |
− | 00000310 f1 40 c7 6e 6c 0c 6d 59 a8 26 44 ca d0 85 2f f1 |.@.nl.mY.&D.../.|
| |
− | 00000320 9c 8b 75 d3 df 0b f0 6c 95 fc 91 c0 76 1e f0 62 |..u....l....v..b|
| |
− | 00000330 89 2a 36 22 8d 49 e0 48 4d 48 0c b0 ac da 02 34 |.*6".I.HMH.....4|
| |
− | 00000340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
| |
− | 00000350 48 4f 56 49 5f 45 4b 53 5f 30 31 00 00 00 00 00 |HOVI_EKS_01.....|
| |
− | 00000360 48 4f 56 49 5f 43 4f 4d 4d 4f 4e 5f 30 31 00 00 |HOVI_COMMON_01..|
| |
− | 00000370 00 03 00 00 00 06 00 00 00 05 00 00
| |
− | | |
− | // u32 secure_loader_thunk(TSecLoaderInfo *info=r10, cmd=r11, skip_load_and_decrypt=r12)
| |
− | ; this is just a thunk that (tries to) sanitize state before running secure code
| |
− | ; originally @ I:0x400, gets copied twice and winds up executed @ I:0x300
| |
− | 00000300: f4 32 10 bclr $flags ie0 ; some re-init code since this can be called by attackers!
| |
− | 00000303: f4 32 11 bclr $flags ie1
| |
− | 00000306: f4 32 12 bclr $flags ie2
| |
− | 00000309: f4 3c 80 cxset 0x80 ; dma_override(type=0b100, count=0) ; clear overrides?
| |
− | 0000030c: fe ae 01 mov $r14 $cauth
| |
− | 0000030f: f0 ea 13 bclr $r14 0x13
| |
− | 00000312: fe ea 00 mov $cauth $r14 ; cauth &= ~(1 << 19)
| |
− | 00000315: 0e 00 mov $r14 0x0
| |
− | 00000317: fe eb 00 mov $xtargets $r14 ; xtargets = 0
| |
− | 0000031a: f8 03 xdwait
| |
− | 0000031c: f8 07 xcwait
| |
− | 0000031e: f4 3c 02 cxset 0x2 ; dma_override(type=crypto_reg, count=2)
| |
− | 00000321: 0e 00 mov $r14 0x0
| |
− | 00000323: fa ee 06 xdst $r14 $r14 ; $c0 = ?
| |
− | 00000326: f8 03 xdwait
| |
− | 00000328: f5 3c 00 ac cxor $c0 $c0
| |
− | 0000032c: f5 3c 01 84 cmov $c1 $c0
| |
− | 00000330: f5 3c 02 84 cmov $c2 $c0
| |
− | 00000334: f5 3c 03 84 cmov $c3 $c0
| |
− | 00000338: f5 3c 04 84 cmov $c4 $c0
| |
− | 0000033c: f5 3c 05 84 cmov $c5 $c0
| |
− | 00000340: f5 3c 07 84 cmov $c7 $c0
| |
− | 00000344: 8e 00 0e 02 mov $r14 0x20e00
| |
− | 00000348: cf ef 00 iord $r15 I[$r14]
| |
− | 0000034b: f0 fa 10 bclr $r15 0x10
| |
− | 0000034e: fa ef 00 iowr I[$r14] $r15 ; 0x20e00 &= ~0x10
| |
− | 00000351: 8e 00 06 01 mov $r14 0x10600
| |
− | 00000355: cf ef 00 iord $r15 I[$r14]
| |
− | 00000358: f0 f9 00 bset $r15 0x0
| |
− | 0000035b: fa ef 00 iowr I[$r14] $r15 ; 0x10600 |= 1
| |
− | 0000035e: cf ef 00 B iord $r15 I[$r14]
| |
− | 00000361: f0 f4 02 and $r15 0x2
| |
− | 00000364: f4 0b fa bra e 0x35e ; while (0x10600 & 2) == 0
| |
− | 00000367: 4e 00 42 mov $r14 0x4200
| |
− | 0000036a: cf ee 00 iord $r14 I[$r14] ; UC_CAPS
| |
− | 0000036d: b6 e5 09 shr b32 $r14 0x9
| |
− | 00000370: f1 e4 ff 01 and $r14 0x1ff
| |
− | 00000374: b6 e4 08 shl b32 $r14 0x8 ; r14 = falcon data segment size
| |
− | 00000377: fe 4f 01 mov $r15 $sp
| |
− | 0000037a: a4 fe cmpu b32 $r15 $r14
| |
− | 0000037c: f4 18 51 bra ae 0x3cd ; if (sp >= DATA_SEG_SIZE) exit;
| |
− | 0000037f: b1 f4 00 08 cmpu b32 $r15 0x800
| |
− | 00000383: f4 08 4a bra b 0x3cd ; if (sp < 0x800) exit;
| |
− | 00000386: f9 82 mpush $r8
| |
− | 00000388: 7e cf 03 00 lcall 0x3cf ; call the real entrypoint @ secure_loader
| |
− | 0000038c: fb 80 mpop $r8
| |
− | 0000038e: f5 3c 00 e0 ??? [unknown: 00 00 00 e0] [unknown instruction] ; this is some "cocmd" insn -> "mwk: chmod IIRC, it modifies the ACLs"
| |
− | 00000392: f5 3c 00 ac cxor $c0 $c0 ; we're done... clear some state
| |
− | 00000396: f5 3c 11 ac cxor $c1 $c1
| |
− | 0000039a: f5 3c 22 ac cxor $c2 $c2
| |
− | 0000039e: f5 3c 33 ac cxor $c3 $c3
| |
− | 000003a2: f5 3c 44 ac cxor $c4 $c4
| |
− | 000003a6: f5 3c 55 ac cxor $c5 $c5
| |
− | 000003aa: f5 3c 66 ac cxor $c6 $c6
| |
− | 000003ae: f5 3c 77 ac cxor $c7 $c7
| |
− | 000003b2: 09 00 mov $r9 0x0
| |
− | 000003b4: 0b 00 mov $r11 0x0
| |
− | 000003b6: 0c 00 mov $r12 0x0
| |
− | 000003b8: 0d 00 mov $r13 0x0
| |
− | 000003ba: 0e 00 mov $r14 0x0
| |
− | 000003bc: 0f 00 mov $r15 0x0
| |
− | 000003be: fc f0 pop $r15 ; pop THE RETURN ADDRESS!!
| |
− | 000003c0: 4b 00 03 mov $r11 0x300
| |
− | 000003c3: f0 b3 01 sethi $r11 0x10000 ; confusing disassembler! this is |= (1 << 16)
| |
− | 000003c6: 0c 00 mov $r12 0x0
| |
− | 000003c8: fa bc 00 iowr I[$r11] $r12 ; 0x10300 = 0
| |
− | 000003cb: f9 f4 bra $r15 ; -> return..?
| |
− | 000003cd: f8 02 B exit
| |
− | | |
− | // u32 secure_loader(TSecLoaderInfo *info=r10, cmd=r11, skip_load_and_decrypt=r12)
| |
− | 000003cf: f4 30 e0 C add $sp -0x20
| |
− | 000003d2: f9 42 mpush $r4 ; sp -= 0x14
| |
− | 000003d4: b2 c4 mov b32 $r4 $r12
| |
− | 000003d6: 98 ac 1c ld b32 $r12 D[$r10+TSecLoaderInfo.secure_loader_offset]
| |
− | 000003d9: f4 30 fc add $sp -0x4
| |
− | 000003dc: b2 a2 mov b32 $r2 $r10
| |
− | 000003de: b2 b3 mov b32 $r3 $r11
| |
− | 000003e0: bd a4 clear b32 $r10
| |
− | 000003e2: bd b4 clear b32 $r11 ; copy all insn memory before the secure_loader to D:0
| |
− | 000003e4: 7e 3f 05 00 lcall 0x53f ; memcpy_i2d(dst=0, src=0, len=secure_loader_offset)
| |
− | 000003e8: bd a4 clear b32 $r10
| |
− | 000003ea: bd b4 clear b32 $r11
| |
− | 000003ec: 7e 47 06 00 lcall 0x647 ; key_init(hdr_type=CODE_SIG, key_type=ENCRYPT)
| |
− | 000003f0: 98 21 1c ld b32 $r1 D[$r2+TSecLoaderInfo.secure_loader_offset]
| |
− | 000003f3: 09 f0 mov $r9 -0x10
| |
− | 000003f5: fe 40 01 mov $r0 $sp
| |
− | 000003f8: 90 00 28 add b32 $r0 $r0 0x28
| |
− | 000003fb: b2 1b mov b32 $r11 $r1
| |
− | 000003fd: fd 09 04 and $r0 $r9
| |
− | 00000400: b2 0a mov b32 $r10 $r0 ; unauth_code_mac = (sp + 0x28) & ~0xf
| |
− | 00000402: 7e 88 06 00 lcall 0x688 ; crypto_688(unauth_code_mac{local}, secure_loader_offset)
| |
− | 00000406: bd 94 clear b32 $r9
| |
− | 00000408: b2 1b mov b32 $r11 $r1
| |
− | 0000040a: b2 0c mov b32 $r12 $r0
| |
− | 0000040c: bd a4 clear b32 $r10
| |
− | 0000040e: b2 0d mov b32 $r13 $r0
| |
− | 00000410: 0e 02 mov $r14 0x2
| |
− | 00000412: b0 91 00 st b32 D[$sp] $r9 ; arg on the stack
| |
− | ; crypto_6b9(buf_in=0, buf_in_len=secure_loader_offset, iv=unauth_code_mac, buf_out=unauth_code_mac, mode=2, some_bool=0)
| |
− | 00000415: 7e b9 06 00 lcall 0x6b9
| |
− | 00000419: b2 0a mov b32 $r10 $r0
| |
− | 0000041b: 90 2b 10 add b32 $r11 $r2 0x10 ; TSecLoaderInfo.field_10
| |
− | 0000041e: 0c 10 mov $r12 0x10
| |
− | 00000420: 7e 9a 05 00 lcall 0x59a ; r10 = memcmp(p1=unauth_code_mac{local}, p2=&info->field_10, len=0x10)
| |
− | 00000424: b3 a0 00 0d bra b32 $r10 0x0 e 0x431
| |
− | 00000428: da ef be ad de mov $r10 0xdeadbeef
| |
− | 0000042d: 3e f0 04 00 lbra 0x4f0 ; if mac failure, return 0xdeadbeef
| |
− | 00000431: 49 00 42 B mov $r9 0x4200 ; UC_CAPS
| |
− | 00000434: cf 99 00 iord $r9 I[$r9] ; useless code?
| |
− | 00000437: 98 2f 1d ld b32 $r15 D[$r2+TSecLoaderInfo.secure_loader_len]
| |
− | 0000043a: 98 29 1c ld b32 $r9 D[$r2+TSecLoaderInfo.secure_loader_offset]
| |
− | 0000043d: bc f9 10 add b32 $r1 $r15 $r9 ; r1 = 0x600 + 0x300 = 0x900
| |
− | 00000440: b3 44 00 4c bra b32 $r4 0x0 ne 0x48c ; skip load_and_decrypt_payload?
| |
− | 00000444: 98 20 1e ld b32 $r0 D[$r2+TSecLoaderInfo.secure_payload_len] ; 0x500
| |
− | 00000447: fe 49 01 mov $r9 $sp
| |
− | 0000044a: a6 09 cmp b32 $r0 $r9
| |
− | 0000044c: f4 18 40 bra ae 0x48c ; if (secure_payload_len >= sp): skip load_and_decrypt_payload ???
| |
− | load_and_decrypt_payload:
| |
− | ; copy payload to D:0, decrypt it, copy as secret to I:0x900, then clear the copy at D:0
| |
− | 0000044f: b2 0c mov b32 $r12 $r0
| |
− | 00000451: b8 1b 00 01 00 add b32 $r11 $r1 0x100 ; r11 = 0xa00 (payload_addr)
| |
− | 00000456: 7e 3f 05 00 lcall 0x53f ; memcpy_i2d(dst=0, src=0xa00, len=secure_payload_len)
| |
− | 0000045a: 0a 01 mov $r10 0x1
| |
− | 0000045c: b2 ab mov b32 $r11 $r10
| |
− | 0000045e: 7e 47 06 00 lcall 0x647 ; key_init(hdr_type=CODE_ENC, key_type=DECRYPT)
| |
− | 00000462: b2 0b mov b32 $r11 $r0
| |
− | 00000464: 90 2c 40 add b32 $r12 $r2 0x40 ; TSecLoaderInfo.field_40
| |
− | 00000467: bd d4 clear b32 $r13
| |
− | 00000469: bd e4 clear b32 $r14
| |
− | 0000046b: bd a4 clear b32 $r10
| |
− | 0000046d: b0 41 00 st b32 D[$sp] $r4 ; always zero. arg on the stack
| |
− | ; crypto_6b9(buf_in=0, buf_in_len=secure_payload_len, iv=info->field_40, buf_out=0, mode=0, some_bool=0)
| |
− | 00000470: 7e b9 06 00 lcall 0x6b9
| |
− | 00000474: b2 1a mov b32 $r10 $r1
| |
− | 00000476: bd b4 clear b32 $r11
| |
− | 00000478: b2 0c mov b32 $r12 $r0
| |
− | 0000047a: b2 1d mov b32 $r13 $r1
| |
− | 0000047c: 0e 01 mov $r14 0x1
| |
− | 0000047e: 7e f6 04 00 lcall 0x4f6 ; memcpy_d2i_ex(dst_page_offset=0x900, src=0, len=secure_payload_len, dst=0x900, is_secret=1)
| |
− | 00000482: b2 0c mov b32 $r12 $r0
| |
− | 00000484: bd a4 clear b32 $r10
| |
− | 00000486: bd b4 clear b32 $r11
| |
− | 00000488: 7e 6b 05 00 lcall 0x56b ; memset(dst=0, val=0, len=secure_payload_len)
| |
− | auth_and_exec_payload:
| |
− | 0000048c: f4 3c 02 B cxset 0x2 ; dma_override(type=crypto_reg, count=2)
| |
− | 0000048f: 8f 00 00 06 mov $r15 0x60000
| |
− | 00000493: 90 29 30 add b32 $r9 $r2 0x30 ; TSecLoaderInfo.field_30
| |
− | 00000496: fd 9f 05 or $r9 $r15
| |
− | 00000499: bd f4 clear b32 $r15
| |
− | 0000049b: fa f9 06 xdst $r15 $r9 ; crypto_reg_load(crypto_reg=$c6, local_address=&info->field_30)
| |
− | 0000049e: f8 03 xdwait
| |
− | 000004a0: fe a4 01 mov $r4 $cauth ; save cauth
| |
− | 000004a3: 98 29 1e ld b32 $r9 D[$r2+TSecLoaderInfo.secure_payload_len]
| |
− | 000004a6: 95 1f 08 shr b32 $r15 $r1 0x8
| |
− | 000004a9: b6 94 10 shl b32 $r9 0x10
| |
− | 000004ac: fd f9 05 or $r15 $r9
| |
− | 000004af: fe fa 00 mov $cauth $r15 ; cauth = (secure_payload_len << 16) | (secure_payload_dst >> 8)
| |
− | 000004b2: b3 34 01 0d bra b32 $r3 0x1 ne 0x4bf
| |
− | handle_cmd_1:
| |
− | 000004b6: b2 3b mov b32 $r11 $r3
| |
− | 000004b8: 90 2a 50 add b32 $r10 $r2 0x50 ; TSecLoaderInfo.key_name_0
| |
− | 000004bb: 3e dd 04 00 lbra 0x4dd ; status = secure_payload(&info->key_name_0, cmd=1)
| |
− | 000004bf: b3 34 02 0d B bra b32 $r3 0x2 ne 0x4cc
| |
− | handle_cmd_2:
| |
− | 000004c3: b2 3b mov b32 $r11 $r3
| |
− | 000004c5: 90 2a 60 add b32 $r10 $r2 0x60 ; TSecLoaderInfo.key_name_1
| |
− | 000004c8: 3e dd 04 00 lbra 0x4dd ; status = secure_payload(&info->key_name_1, cmd=2)
| |
− | 000004cc: b3 30 03 0d B bra b32 $r3 0x3 e 0x4d9
| |
− | handle_invalid_cmd:
| |
− | 000004d0: d0 d0 d0 d0 d0 mov $r0 0xd0d0d0d0
| |
− | 000004d5: 3e e1 04 00 lbra 0x4e1 ; status = 0xd0d0d0d0;
| |
− | handle_cmd_3:
| |
− | 000004d9: b2 3b B mov b32 $r11 $r3
| |
− | 000004db: b2 2a mov b32 $r10 $r2
| |
− | 000004dd: f9 15 B call $r1 ; status = secure_payload(info, cmd=3)
| |
− | 000004df: b2 a0 mov b32 $r0 $r10
| |
− | 000004e1: b2 2a B mov b32 $r10 $r2
| |
− | 000004e3: bd b4 clear b32 $r11
| |
− | 000004e5: 0c 7c mov $r12 0x7c ; clear our copy of the info header
| |
− | 000004e7: 7e 6b 05 00 lcall 0x56b ; memset(dst=info, val=0, len=0x7c)
| |
− | 000004eb: fe 4a 00 mov $cauth $r4 ; restore cauth
| |
− | 000004ee: b2 0a mov b32 $r10 $r0 ; return status
| |
− | 000004f0: f4 30 04 B add $sp 0x4
| |
− | 000004f3: fb 45 20 mpopaddret $r4 0x20
| |
− | | |
− | // memcpy_d2i_ex(dst_page_offset=r10, src=r11, len=r12, dst=r13, is_secret=r14)
| |
− | 000004f6: f9 02 C mpush $r0
| |
− | 000004f8: b2 b0 mov b32 $r0 $r11
| |
− | 000004fa: b2 cb mov b32 $r11 $r12
| |
− | 000004fc: b2 dc mov b32 $r12 $r13
| |
− | 000004fe: 33 00 00 0a bra b8 $r0 0x0 e 0x508
| |
− | 00000502: f8 02 exit
| |
− | 00000504: 3e 04 05 00 B lbra 0x504
| |
− | 00000508: 33 b0 00 0a B bra b8 $r11 0x0 e 0x512
| |
− | 0000050c: f8 02 exit
| |
− | 0000050e: 3e 0e 05 00 B lbra 0x50e
| |
− | 00000512: 33 c0 00 0a B bra b8 $r12 0x0 e 0x51c
| |
− | 00000516: f8 02 exit
| |
− | 00000518: 3e 18 05 00 B lbra 0x518
| |
− | 0000051c: b3 e0 00 0d B bra b32 $r14 0x0 e 0x529
| |
− | 00000520: d9 00 00 00 11 mov $r9 0x11000000
| |
− | 00000525: 3e 2e 05 00 lbra 0x52e
| |
− | 00000529: d9 00 00 00 01 B mov $r9 0x1000000
| |
− | 0000052e: ff a9 95 B or $r9 $r10 $r9
| |
− | 00000531: 4f 00 60 mov $r15 0x6000 ; CODE_INDEX
| |
− | 00000534: fa f9 00 iowr I[$r15] $r9
| |
− | 00000537: b2 0a mov b32 $r10 $r0
| |
− | 00000539: 7e 88 08 00 lcall 0x888 ; memcpy_d2i(src=r10, len=r11, dst=r12)
| |
− | 0000053d: fb 01 mpopret $r0
| |
− | | |
− | // memcpy_i2d(dst=r10, src=r11, len=r12)
| |
− | 0000053f: d9 00 00 00 02 C mov $r9 0x2000000
| |
− | 00000544: fd b9 05 or $r11 $r9
| |
− | 00000547: 49 00 60 mov $r9 0x6000 ; CODE_INDEX
| |
− | 0000054a: fa 9b 00 iowr I[$r9] $r11
| |
− | 0000054d: bd e4 clear b32 $r14
| |
− | 0000054f: 4b 00 61 mov $r11 0x6100 ; CODE
| |
− | 00000552: bd d4 clear b32 $r13
| |
− | 00000554: 3e 64 05 00 lbra 0x564
| |
− | 00000558: ff bd ff B iord $r15 I[$r11+$r13*0x4]
| |
− | 0000055b: 95 e9 02 shr b32 $r9 $r14 0x2
| |
− | 0000055e: 90 ee 04 add b32 $r14 $r14 0x4
| |
− | 00000561: bc af 99 st b32 D[$r10+$r9*0x4] $r15
| |
− | 00000564: a6 ec B cmp b32 $r14 $r12
| |
− | 00000566: f4 08 f2 bra b 0x558
| |
− | 00000569: f8 00 ret
| |
− | | |
− | // memset(dst=r10, val=r11, len=r12)
| |
− | 0000056b: 3e 81 05 00 C lbra 0x581
| |
− | 0000056f: b5 ab 00 B st b32 D[$r10] $r11
| |
− | 00000572: b5 ab 01 st b32 D[$r10+0x4] $r11
| |
− | 00000575: b5 ab 02 st b32 D[$r10+0x8] $r11
| |
− | 00000578: b5 ab 03 st b32 D[$r10+0xc] $r11
| |
− | 0000057b: b6 a0 10 add b32 $r10 0x10
| |
− | 0000057e: b6 c2 10 sub b32 $r12 0x10
| |
− | 00000581: b0 c6 10 B cmp b32 $r12 0x10
| |
− | 00000584: f4 18 eb bra ae 0x56f
| |
− | 00000587: 3e 93 05 00 lbra 0x593
| |
− | 0000058b: a0 ab B st b32 D[$r10] $r11
| |
− | 0000058d: b6 a0 04 add b32 $r10 0x4
| |
− | 00000590: b6 c2 04 sub b32 $r12 0x4
| |
− | 00000593: b3 c4 00 f8 B bra b32 $r12 0x0 ne 0x58b
| |
− | 00000597: f8 00 ret
| |
− | | |
− | ; another extra 0x01 byte following a ret
| |
− | 00000599: 01
| |
− | | |
− | // int memcmp(p1=r10, p2=r11, len=r12)
| |
− | // NOT TIMING INVARIANT
| |
− | 0000059a: 3e b0 05 00 lbra 0x5b0
| |
− | 0000059e: bf ad B ld b32 $r13 D[$r10]
| |
− | 000005a0: bf be ld b32 $r14 D[$r11]
| |
− | 000005a2: a6 de cmp b32 $r13 $r14
| |
− | 000005a4: f4 1b 14 bra ne 0x5b8
| |
− | 000005a7: b6 a0 04 add b32 $r10 0x4
| |
− | 000005aa: b6 b0 04 add b32 $r11 0x4
| |
− | 000005ad: b6 c2 04 sub b32 $r12 0x4
| |
− | 000005b0: b3 c4 00 ee B bra b32 $r12 0x0 ne 0x59e
| |
− | 000005b4: 0a 00 mov $r10 0x0
| |
− | 000005b6: f8 00 ret
| |
− | 000005b8: 0a 01 B mov $r10 0x1
| |
− | 000005ba: f8 00 ret
| |
− | | |
− | ; again, the floating 0x01 byte...
| |
− | 000005bc: 01
| |
− | | |
− | // these xfers are for crypto stuff. size is in bits!
| |
− | | |
− | // crypto_reg_store(crypto_reg=r10, local_addr=r11)
| |
− | 000005bd: f4 3c 02 C cxset 0x2 ; dma_override(type=crypto_reg, count=2)
| |
− | 000005c0: b6 a4 10 shl b32 $r10 0x10
| |
− | 000005c3: fd ba 05 or $r11 $r10
| |
− | 000005c6: fa bb 05 xdld $r11 $r11
| |
− | 000005c9: f8 03 xdwait
| |
− | 000005cb: f8 00 ret
| |
− | | |
− | // crypto_reg_load(crypto_reg=r10, local_addr=r11)
| |
− | // read from local_addr into $cX
| |
− | 000005cd: f4 3c 02 C cxset 0x2 ; dma_override(type=crypto_reg, count=2)
| |
− | 000005d0: b6 a4 10 shl b32 $r10 0x10
| |
− | 000005d3: fd ba 05 or $r11 $r10
| |
− | 000005d6: fa bb 06 xdst $r11 $r11
| |
− | 000005d9: f8 03 xdwait
| |
− | 000005db: f8 00 ret
| |
− | | |
− | // get_type_string(buf=r10, type=r11)
| |
− | 000005dd: c4 a9 0f C and $r9 $r10 0xf
| |
− | 000005e0: f4 0b 09 bra e 0x5e9
| |
− | 000005e3: f8 02 exit ; assert r10 16byte aligned
| |
− | 000005e5: 3e e5 05 00 B lbra 0x5e5
| |
− | 000005e9: b3 b0 00 0c B bra b32 $r11 0x0 e 0x5f5
| |
− | 000005ed: b3 b4 01 3e bra b32 $r11 0x1 ne 0x62b
| |
− | 000005f1: 3e 10 06 00 lbra 0x610
| |
− | ; if (r11 == 0) { "CODE_SIG_01"
| |
− | 000005f5: d9 43 4f 44 45 B mov $r9 0x45444f43 ; "CODE"
| |
− | 000005fa: a0 a9 st b32 D[$r10] $r9
| |
− | 000005fc: d9 5f 53 49 47 mov $r9 0x4749535f ; "_SIG"
| |
− | 00000601: b5 ab 03 st b32 D[$r10+0xc] $r11
| |
− | 00000604: b5 a9 01 st b32 D[$r10+0x4] $r9
| |
− | 00000607: 89 5f 30 31 mov $r9 0x31305f ; "_01"
| |
− | 0000060b: b5 a9 02 st b32 D[$r10+0x8] $r9
| |
− | 0000060e: f8 00 ret
| |
− | ; } else if (r11 == 1) { "CODE_ENC_01"
| |
− | 00000610: d9 43 4f 44 45 B mov $r9 0x45444f43 ; "CODE"
| |
− | 00000615: a0 a9 st b32 D[$r10] $r9
| |
− | 00000617: d9 5f 45 4e 43 mov $r9 0x434e455f ; "_ENC"
| |
− | 0000061c: b5 a9 01 st b32 D[$r10+0x4] $r9
| |
− | 0000061f: 89 5f 30 31 mov $r9 0x31305f ; "_01"
| |
− | 00000623: b5 a9 02 st b32 D[$r10+0x8] $r9
| |
− | 00000626: bd 94 clear b32 $r9
| |
− | 00000628: b5 a9 03 st b32 D[$r10+0xc] $r9
| |
− | ; }
| |
− | 0000062b: f8 00 B ret
| |
− | | |
− | ; unused function?
| |
− | 0000062d: f9 02 mpush $r0
| |
− | 0000062f: b2 b0 mov b32 $r0 $r11
| |
− | 00000631: b2 ab mov b32 $r11 $r10
| |
− | 00000633: 0a 04 mov $r10 0x4
| |
− | 00000635: 7e cd 05 00 lcall 0x5cd ; crypto_reg_load(crypto_reg=$c4, local_addr=r11)
| |
− | 00000639: b3 00 00 08 bra b32 $r0 0x0 e 0x641
| |
− | 0000063d: b3 04 03 08 bra b32 $r0 0x3 ne 0x645
| |
− | 00000641: f5 3c 44 c8 B ckexp $c4 $c4
| |
− | 00000645: fb 01 B mpopret $r0
| |
− | | |
− | // key_init(hdr_type=r10, key_type=r11)
| |
− | // hdr_type 0: CODE_SIG, 1: CODE_ENC
| |
− | // key_type 0: ENCRYPT, 1: DECRYPT
| |
− | // leaves the key material in c4, then other funcs use that
| |
− | 00000647: 09 f0 mov $r9 -0x10
| |
− | 00000649: f4 30 e0 add $sp -0x20
| |
− | 0000064c: f9 12 mpush $r1
| |
− | 0000064e: b2 b1 mov b32 $r1 $r11
| |
− | 00000650: fe 40 01 mov $r0 $sp
| |
− | 00000653: b2 ab mov b32 $r11 $r10 ; r11 = hdr_type
| |
− | 00000655: 90 00 18 add b32 $r0 $r0 0x18
| |
− | 00000658: fd 09 04 and $r0 $r9 ; r0 = (sp + 0x18) & ~0xf
| |
− | 0000065b: b2 0a mov b32 $r10 $r0
| |
− | 0000065d: 7e dd 05 00 lcall 0x5dd ; get_type_string(buf=r0{local}, type=hdr_type)
| |
− | 00000661: b2 0b mov b32 $r11 $r0
| |
− | 00000663: bd a4 clear b32 $r10
| |
− | 00000665: 7e cd 05 00 lcall 0x5cd ; crypto_reg_load(crypto_reg=$c0, r0{local})
| |
− | 00000669: f5 3c 61 c2 csecret $c1 0x26 ; c1 = hw_secrets[0x26]. whatever that means! kfuse data?
| |
− | 0000066d: f5 3c 01 c4 ckeyreg $c1 ; ACTIVE_KEY_REG = c1
| |
− | 00000671: f5 3c 01 d0 cenc $c1 $c0 ; c1 = Aes128EcbEncrypt(key=c1, data=c0)
| |
− | 00000675: f5 3c 11 dc csigenc $c1 $c1 ; c1 = EncryptSig(key=c1) this the sig supplied when our code page was auth'd (info.field_20)
| |
− | 00000679: f5 3c 14 84 cmov $c4 $c1 ; c4 = c1
| |
− | 0000067d: b3 10 00 08 bra b32 $r1 0x0 e 0x685 ; check key_type
| |
− | 00000681: f5 3c 44 c8 ckexp $c4 $c4 ; do key expansion if DEC, else skip
| |
− | 00000685: fb 15 20 B mpopaddret $r1 0x20
| |
− | | |
− | // crypto_688(buf=r10, in_word=r11)
| |
− | 00000688: f9 02 mpush $r0
| |
− | 0000068a: bd 94 clear b32 $r9
| |
− | 0000068c: b2 a0 mov b32 $r0 $r10
| |
− | 0000068e: a0 a9 st b32 D[$r10] $r9
| |
− | 00000690: b5 a9 02 st b32 D[$r10+0x8] $r9
| |
− | 00000693: b5 a9 01 st b32 D[$r10+0x4] $r9
| |
− | 00000696: 7d b3 hswap b16 $r11
| |
− | 00000698: bd b3 hswap b32 $r11
| |
− | 0000069a: 7d b3 hswap b16 $r11
| |
− | 0000069c: b5 ab 03 st b32 D[$r10+0xc] $r11 ; r10 = 0 || 0 || 0 || bswap32(in_word)
| |
− | 0000069f: 0a 03 mov $r10 0x3 ; input num_bytes = 4
| |
− | 000006a1: b2 0b mov b32 $r11 $r0
| |
− | 000006a3: 7e cd 05 00 lcall 0x5cd ; crypto_reg_load(crypto_reg=$c3, local_addr=buf)
| |
− | 000006a7: f5 3c 04 c4 ckeyreg $c4
| |
− | 000006ab: f5 3c 35 d0 cenc $c5 $c3 ; c5 = Aes128EcbEncrypt(key=c4, data=c3)
| |
− | 000006af: 0a 05 mov $r10 0x5 ; output num_bytes = 16
| |
− | 000006b1: b2 0b mov b32 $r11 $r0
| |
− | 000006b3: 7e bd 05 00 lcall 0x5bd ; crypto_reg_store(crypto_reg=$c5, local_addr=buf)
| |
− | 000006b7: fb 01 mpopret $r0
| |
− | | |
− | // crypto_6b9(buf_in=r10, buf_in_len=r11, iv=r12, buf_out=r13, mode=r14, some_bool=[sp])
| |
− | 000006b9: f9 52 mpush $r5
| |
− | 000006bb: b2 b3 mov b32 $r3 $r11
| |
− | 000006bd: b2 d4 mov b32 $r4 $r13
| |
− | 000006bf: b2 cb mov b32 $r11 $r12
| |
− | 000006c1: b2 e2 mov b32 $r2 $r14
| |
− | 000006c3: b4 50 07 ld b32 $r5 D[$sp+0x1c]
| |
− | 000006c6: b2 a1 mov b32 $r1 $r10
| |
− | 000006c8: b2 d0 mov b32 $r0 $r13
| |
− | 000006ca: b3 34 00 0a bra b32 $r3 0x0 ne 0x6d4 ; assert buf_in_len != 0
| |
− | 000006ce: f8 02 exit
| |
− | 000006d0: 3e d0 06 00 B lbra 0x6d0
| |
− | 000006d4: c4 39 0f B and $r9 $r3 0xf
| |
− | 000006d7: f4 0b 09 bra e 0x6e0 ; assert (buf_in_len & 0xf) == 0
| |
− | 000006da: f8 02 exit
| |
− | 000006dc: 3e dc 06 00 B lbra 0x6dc
| |
− | 000006e0: c4 a9 0f B and $r9 $r10 0xf
| |
− | 000006e3: f4 0b 09 bra e 0x6ec ; assert (buf_in & 0xf) == 0
| |
− | 000006e6: f8 02 exit
| |
− | 000006e8: 3e e8 06 00 B lbra 0x6e8
| |
− | 000006ec: c4 49 0f B and $r9 $r4 0xf
| |
− | 000006ef: f4 0b 09 bra e 0x6f8 ; assert (buf_out & 0xf) == 0
| |
− | 000006f2: f8 02 exit
| |
− | 000006f4: 3e f4 06 00 B lbra 0x6f4
| |
− | 000006f8: b3 b0 00 0e B bra b32 $r11 0x0 e 0x706 ; if present, use 16byte iv
| |
− | set_iv_to_input:
| |
− | 000006fc: 0a 05 mov $r10 0x5
| |
− | 000006fe: 7e cd 05 00 lcall 0x5cd ; crypto_reg_load(crypto_reg=$c5, local_addr=iv)
| |
− | 00000702: 3e 0a 07 00 lbra 0x70a
| |
− | set_iv_zero:
| |
− | 00000706: f5 3c 55 ac B cxor $c5 $c5
| |
− | set_active_key_c4:
| |
− | 0000070a: f5 3c 04 c4 B ckeyreg $c4
| |
− | mode_dispatch:
| |
− | 0000070e: b3 20 02 50 bra b32 $r2 0x2 e 0x75e
| |
− | 00000712: b0 26 02 cmp b32 $r2 0x2
| |
− | 00000715: f4 0c 10 bra a 0x725
| |
− | 00000718: b3 20 00 2a bra b32 $r2 0x0 e 0x742
| |
− | 0000071c: b3 2d 01 6a 01 bra b32 $r2 0x1 ne 0x886
| |
− | 00000721: 3e 32 07 00 lbra 0x732
| |
− | 00000725: b3 20 03 5d B bra b32 $r2 0x3 e 0x782
| |
− | 00000729: b3 2d 04 5d 01 bra b32 $r2 0x4 ne 0x886
| |
− | 0000072e: 3e 72 07 00 lbra 0x772
| |
− | 00000732: f5 3c 40 94 B cs0begin 0x4
| |
− | 00000736: f5 3c 03 88 cxsin $c3
| |
− | 0000073a: f5 3c 53 ac cxor $c3 $c5
| |
− | 0000073e: 3e 7a 07 00 lbra 0x77a
| |
− | 00000742: f5 3c 50 94 B cs0begin 0x5
| |
− | 00000746: f5 3c 03 88 cxsin $c3
| |
− | 0000074a: f5 3c 32 d4 cdec $c2 $c3
| |
− | 0000074e: f5 3c 25 ac cxor $c5 $c2
| |
− | 00000752: f5 3c 05 8c cxsout $c5
| |
− | 00000756: f5 3c 35 84 cmov $c5 $c3
| |
− | 0000075a: 3e 75 08 00 lbra 0x875
| |
− | 0000075e: f5 3c 30 94 B cs0begin 0x3
| |
− | 00000762: f5 3c 03 88 cxsin $c3
| |
− | 00000766: f5 3c 35 ac cxor $c5 $c3
| |
− | 0000076a: f5 3c 55 d0 cenc $c5 $c5
| |
− | 0000076e: 3e 75 08 00 lbra 0x875
| |
− | 00000772: f5 3c 30 94 B cs0begin 0x3
| |
− | 00000776: f5 3c 03 88 cxsin $c3
| |
− | 0000077a: f5 3c 35 d0 B cenc $c5 $c3
| |
− | 0000077e: 3e 8e 07 00 lbra 0x78e
| |
− | 00000782: f5 3c 30 94 B cs0begin 0x3
| |
− | 00000786: f5 3c 03 88 cxsin $c3
| |
− | 0000078a: f5 3c 35 d4 cdec $c5 $c3
| |
− | 0000078e: f5 3c 05 8c B cxsout $c5
| |
− | 00000792: 3e 75 08 00 lbra 0x875
| |
− | 00000796: 95 3f 04 B shr b32 $r15 $r3 0x4
| |
− | 00000799: b0 f6 10 cmp b32 $r15 0x10
| |
− | 0000079c: f4 0d 05 bra be 0x7a1
| |
− | 0000079f: 0f 10 mov $r15 0x10
| |
− | 000007a1: 92 f9 01 B sub b32 $r9 $r15 0x1
| |
− | 000007a4: fd 9f 04 and $r9 $r15
| |
− | 000007a7: f4 0b 05 bra e 0x7ac
| |
− | 000007aa: 0f 01 mov $r15 0x1
| |
− | 000007ac: 94 fe 04 B shl b32 $r14 $r15 0x4
| |
− | 000007af: ff 01 f5 or $r15 $r0 $r1
| |
− | 000007b2: 92 e9 01 sub b32 $r9 $r14 0x1
| |
− | 000007b5: fd 9f 04 and $r9 $r15
| |
− | 000007b8: f4 1b 68 bra ne 0x820
| |
− | 000007bb: b3 e0 40 41 bra b32 $r14 0x40 e 0x7fc
| |
− | 000007bf: b1 e6 40 00 cmp b32 $r14 0x40
| |
− | 000007c3: f4 0c 0b bra a 0x7ce
| |
− | 000007c6: b3 e4 20 5a bra b32 $r14 0x20 ne 0x820
| |
− | 000007ca: 3e 0e 08 00 lbra 0x80e
| |
− | 000007ce: b3 ea 80 00 1c B bra b32 $r14 0x80 e 0x7ea
| |
− | 000007d3: b3 ee 00 01 4d bra b32 $r14 0x100 ne 0x820
| |
− | 000007d8: b2 1f mov b32 $r15 $r1
| |
− | 000007da: f0 f3 06 sethi $r15 0x60000
| |
− | 000007dd: b2 09 mov b32 $r9 $r0
| |
− | 000007df: f0 93 06 sethi $r9 0x60000
| |
− | 000007e2: f5 3c 00 99 cs0exec 0x10
| |
− | 000007e6: 3e 30 08 00 lbra 0x830
| |
− | 000007ea: b2 1f B mov b32 $r15 $r1
| |
− | 000007ec: f0 f3 05 sethi $r15 0x50000
| |
− | 000007ef: b2 09 mov b32 $r9 $r0
| |
− | 000007f1: f0 93 05 sethi $r9 0x50000
| |
− | 000007f4: f5 3c 80 98 cs0exec 0x8
| |
− | 000007f8: 3e 30 08 00 lbra 0x830
| |
− | 000007fc: b2 1f B mov b32 $r15 $r1
| |
− | 000007fe: f0 f3 04 sethi $r15 0x40000
| |
− | 00000801: b2 09 mov b32 $r9 $r0
| |
− | 00000803: f0 93 04 sethi $r9 0x40000
| |
− | 00000806: f5 3c 40 98 cs0exec 0x4
| |
− | 0000080a: 3e 30 08 00 lbra 0x830
| |
− | 0000080e: b2 1f B mov b32 $r15 $r1
| |
− | 00000810: f0 f3 03 sethi $r15 0x30000
| |
− | 00000813: b2 09 mov b32 $r9 $r0
| |
− | 00000815: f0 93 03 sethi $r9 0x30000
| |
− | 00000818: f5 3c 20 98 cs0exec 0x2
| |
− | 0000081c: 3e 30 08 00 lbra 0x830
| |
− | 00000820: b2 1f B mov b32 $r15 $r1
| |
− | 00000822: f0 f3 02 sethi $r15 0x20000
| |
− | 00000825: b2 09 mov b32 $r9 $r0
| |
− | 00000827: f0 93 02 sethi $r9 0x20000
| |
− | 0000082a: f5 3c 10 98 cs0exec 0x1
| |
− | 0000082e: 0e 10 mov $r14 0x10
| |
− | 00000830: b3 54 01 0b B bra b32 $r5 0x1 ne 0x83b
| |
− | 00000834: f4 3c a1 cxset 0xa1 ; dma_override(type=0b101, count=1)
| |
− | 00000837: 3e 3e 08 00 lbra 0x83e
| |
− | 0000083b: f4 3c 21 B cxset 0x21 ; dma_override(type=0b001, count=1)
| |
− | 0000083e: fa ff 06 B xdst $r15 $r15
| |
− | 00000841: b3 20 02 1e bra b32 $r2 0x2 e 0x85f
| |
− | 00000845: b3 54 01 0b bra b32 $r5 0x1 ne 0x850
| |
− | 00000849: f4 3c a2 cxset 0xa2 ; dma_override(type=0b101, count=2)
| |
− | 0000084c: 3e 53 08 00 lbra 0x853
| |
− | 00000850: f4 3c 22 B cxset 0x22 ; dma_override(type=0b001, count=2)
| |
− | 00000853: fa 99 05 B xdld $r9 $r9
| |
− | 00000856: f8 03 xdwait
| |
− | 00000858: bc 0e 00 add b32 $r0 $r0 $r14
| |
− | 0000085b: 3e 6f 08 00 lbra 0x86f
| |
− | 0000085f: b3 54 01 0b B bra b32 $r5 0x1 ne 0x86a
| |
− | 00000863: f4 3c a1 cxset 0xa1 ; dma_override(type=0b101, count=1)
| |
− | 00000866: 3e 6d 08 00 lbra 0x86d
| |
− | 0000086a: f4 3c 21 B cxset 0x21 ; dma_override(type=0b001, count=1)
| |
− | 0000086d: f8 03 B xdwait
| |
− | 0000086f: bc 1e 10 B add b32 $r1 $r1 $r14
| |
− | 00000872: bb 3e 02 sub b32 $r3 $r14
| |
− | 00000875: b3 3d 00 21 ff B bra b32 $r3 0x0 ne 0x796
| |
− | 0000087a: b3 24 02 0c bra b32 $r2 0x2 ne 0x886
| |
− | 0000087e: b2 4b mov b32 $r11 $r4
| |
− | 00000880: 0a 05 mov $r10 0x5
| |
− | 00000882: 7e bd 05 00 lcall 0x5bd ; crypto_reg_store(crypto_reg=$c5, local_addr=r11)
| |
− | 00000886: fb 51 B mpopret $r5
| |
− | | |
− | // memcpy_d2i(src=r10, len=r11, dst=r12)
| |
− | 00000888: f9 32 mpush $r3
| |
− | 0000088a: 4d 00 61 mov $r13 0x6100 ; CODE
| |
− | 0000088d: 4e 00 62 mov $r14 0x6200 ; CODE_VIRT_ADDR
| |
− | 00000890: 3e bb 08 00 lbra 0x8bb
| |
− | 00000894: c4 c0 ff B and $r0 $r12 0xff
| |
− | 00000897: f4 0b 2a bra e 0x8c1
| |
− | 0000089a: 98 a0 00 B ld b32 $r0 D[$r10]
| |
− | 0000089d: 98 a1 01 ld b32 $r1 D[$r10+0x4]
| |
− | 000008a0: 98 a2 02 ld b32 $r2 D[$r10+0x8]
| |
− | 000008a3: 98 a3 03 ld b32 $r3 D[$r10+0xc]
| |
− | 000008a6: f6 d0 00 iowr I[$r13] $r0
| |
− | 000008a9: f6 d1 00 iowr I[$r13] $r1
| |
− | 000008ac: f6 d2 00 iowr I[$r13] $r2
| |
− | 000008af: f6 d3 00 iowr I[$r13] $r3
| |
− | 000008b2: b6 a0 10 add b32 $r10 0x10
| |
− | 000008b5: b6 b2 10 sub b32 $r11 0x10
| |
− | 000008b8: b6 c0 10 add b32 $r12 0x10
| |
− | 000008bb: b3 b4 00 d9 B bra b32 $r11 0x0 ne 0x894
| |
− | 000008bf: fb 31 mpopret $r3
| |
− | 000008c1: 95 c0 08 B shr b32 $r0 $r12 0x8
| |
− | 000008c4: f6 e0 00 iowr I[$r14] $r0
| |
− | 000008c7: 3e 9a 08 00 lbra 0x89a
| |
− | | |
− | | |
− | ; encrypted secure_payload
| |
− | 00000a00 ca e0 f8 6a d9 72 ba 7b eb 25 b3 a8 42 98 75 38 |...j.r.{.%..B.u8|
| |
− | 00000a10 25 ed 0c 3f 80 56 22 01 8a 19 87 8a fe 6d 9e 4f |%..?.V"......m.O|
| |
− | 00000a20 dd 80 11 e9 5a 48 40 c4 1a ed c2 7f ed 7f b3 43 |....ZH@........C|
| |
− | 00000a30 14 bb 58 53 09 2a 45 12 3a b4 b6 44 6a ef 19 1b |..XS.*E.:..Dj...|
| |
− | 00000a40 55 2a 99 69 68 06 5c 1b ab df c2 00 ee a9 e1 b0 |U*.ih.\.........|
| |
− | 00000a50 c6 aa 5c 54 3a 5d 7d 7d 79 30 50 69 b5 61 be 1d |..\T:]}}y0Pi.a..|
| |
− | 00000a60 6f a3 2e ec f1 95 c6 6d 62 22 43 5c 36 a4 0e c4 |o......mb"C\6...|
| |
− | 00000a70 94 e6 37 4e 41 80 d4 6f 27 80 1c 5e 94 cb d6 d4 |..7NA..o'..^....|
| |
− | 00000a80 6d f7 0f 26 68 6c fa d7 b4 63 23 f7 19 2f b5 49 |m..&hl...c#../.I|
| |
− | 00000a90 87 13 59 d0 be 85 00 9e 1e 7e 07 50 1b bc 5c ec |..Y......~.P..\.|
| |
− | 00000aa0 2b 1a 81 62 02 f3 83 58 cd 9a b4 7a 1e 11 94 3e |+..b...X...z...>|
| |
− | 00000ab0 bf c6 69 fa 41 91 76 c3 4d a4 4e 1a d5 bf 29 37 |..i.A.v.M.N...)7|
| |
− | 00000ac0 36 74 8d 1c 54 89 ec 47 45 3e 20 f4 69 96 25 fe |6t..T..GE> .i.%.|
| |
− | 00000ad0 74 83 64 44 7a 4c 83 a9 b3 c2 1a 1c a9 59 e9 99 |t.dDzL.......Y..|
| |
− | 00000ae0 89 ba a3 8f ed 26 b6 f7 a2 f4 b2 a7 f0 ab ea 7f |.....&..........|
| |
− | 00000af0 ea d2 55 0c 64 36 7b 23 c2 a6 69 86 d4 a3 93 33 |..U.d6{#..i....3|
| |
− | 00000b00 a3 7e 39 ad 6e a3 72 76 b4 b0 82 b4 67 30 8a 48 |.~9.n.rv....g0.H|
| |
− | 00000b10 9e dc 94 b3 29 85 22 ca 7b 55 24 33 9c 01 a2 0d |....).".{U$3....|
| |
− | 00000b20 10 06 6f f9 01 7a 23 0f 99 37 9f bb 2b a4 3a fc |..o..z#..7..+.:.|
| |
− | 00000b30 a4 a0 d5 06 b4 e0 61 44 01 48 b0 75 3f ac a1 25 |......aD.H.u?..%|
| |
− | 00000b40 4b 85 bf b7 a4 21 f2 82 09 2e 72 61 c7 69 92 11 |K....!....ra.i..|
| |
− | 00000b50 a6 81 2f e1 c2 e8 aa 41 da 62 a7 a0 6c be 74 a6 |../....A.b..l.t.|
| |
− | 00000b60 cb 9b 20 c4 65 ed fb 3c 3d d0 9a c8 4e b0 91 f5 |.. .e..<=...N...|
| |
− | 00000b70 a9 3f e0 9c 7b 6f 21 78 d2 4f 50 a5 b0 61 05 93 |.?..{o!x.OP..a..|
| |
− | 00000b80 b0 4b 60 98 6d 56 cc 07 a7 d5 61 4c d2 9e 23 0f |.K`.mV....aL..#.|
| |
− | 00000b90 cd d9 bf c8 ef 05 a9 24 72 6d 50 7f f7 be fd bf |.......$rmP.....|
| |
− | 00000ba0 7c a5 df 4d bb 8d f3 05 2a 48 40 88 34 6d e7 d0 ||..M....*H@.4m..|
| |
− | 00000bb0 03 b7 4b b1 db df 09 ff 20 94 c0 3b 10 01 ed c8 |..K..... ..;....|
| |
− | 00000bc0 a9 d2 0f cd 1d 06 92 0f 4c cc 01 c0 e8 d3 d3 5b |........L......[|
| |
− | 00000bd0 34 2e 61 20 dd 2c 09 83 6a e3 3b b4 6d d5 34 99 |4.a .,..j.;.m.4.|
| |
− | 00000be0 7b 22 cd 23 e1 f1 a9 c4 50 07 31 fd 97 18 54 3f |{".#....P.1...T?|
| |
− | 00000bf0 ba 88 70 27 89 b4 74 5a 36 bf 73 37 d3 bc 00 86 |..p'..tZ6.s7....|
| |
− | 00000c00 14 8d 3d e1 30 ac af 6d 72 df 9a 28 b0 98 e7 89 |..=.0..mr..(....|
| |
− | 00000c10 55 88 60 55 48 a1 ef f9 79 15 6b f0 db 48 4b 9f |U.`UH...y.k..HK.|
| |
− | 00000c20 6a ca 6c 29 a2 0c 97 e7 12 05 76 e5 a2 8e ed 15 |j.l)......v.....|
| |
− | 00000c30 83 14 28 39 fc 98 fa 5d 1d 76 9b ab 3f 06 ea 43 |..(9...].v..?..C|
| |
− | 00000c40 f8 09 d5 d6 a2 85 ff 5f 5f d0 41 60 68 9a 76 23 |.......__.A`h.v#|
| |
− | 00000c50 af 18 b8 76 16 3a 8c 83 cd bc 06 5a a7 44 8f 86 |...v.:.....Z.D..|
| |
− | 00000c60 54 73 e4 11 d0 2b 34 85 34 b2 ee 07 83 a1 57 e8 |Ts...+4.4.....W.|
| |
− | 00000c70 0b 83 a6 7d bc 4b 2f ca 5e a0 21 ed 82 6a bd 8d |...}.K/.^.!..j..|
| |
− | 00000c80 91 a6 79 5b 53 d8 09 0d 6a d8 7d f9 2f 0c a2 71 |..y[S...j.}./..q|
| |
− | 00000c90 98 37 c7 93 b9 fc 0c af 24 29 66 cc a9 ed 8a 2b |.7......$)f....+|
| |
− | 00000ca0 cf e2 5a f1 95 ec 27 95 79 2b b3 e5 7b 14 99 a3 |..Z...'.y+..{...|
| |
− | 00000cb0 ca be 0f fe 37 c6 04 a4 61 6f 2a 0f 90 d3 f9 88 |....7...ao*.....|
| |
− | 00000cc0 c3 0c e2 bc 09 20 47 19 53 89 1e e6 18 01 02 51 |..... G.S......Q|
| |
− | 00000cd0 43 ea b3 c0 04 4f a2 53 74 30 41 2b ec c6 54 4f |C....O.St0A+..TO|
| |
− | 00000ce0 65 50 fa 6c f7 d9 bf 45 7c 23 8f 38 3a 89 e0 fd |eP.l...E|#.8:...|
| |
− | 00000cf0 d4 48 71 b8 86 65 87 42 01 00 23 22 b6 e7 08 c3 |.Hq..e.B..#"....|
| |
− | 00000d00 1a c8 c1 4e 69 78 6d 68 c5 9f de 64 85 be 94 52 |...Nixmh...d...R|
| |
− | 00000d10 fb 7c c5 9e 97 4a e3 aa 2c 6c 49 e6 5d af 1e 2c |.|...J..,lI.]..,|
| |
− | 00000d20 a0 29 3c bb f4 94 5f fb 66 49 e7 30 0e 6b e0 9d |.)<..._.fI.0.k..|
| |
− | 00000d30 bf 28 25 e8 97 8f 17 c4 87 f3 95 ce be ad 87 b9 |.(%.............|
| |
− | 00000d40 d1 e4 0c 9e 12 cf f9 9c ac 8c 6f 77 2a 8a b5 b3 |..........ow*...|
| |
− | 00000d50 19 7c ea bf b8 c4 0e e0 0f 73 8a 34 8d a9 73 2d |.|.......s.4..s-|
| |
− | 00000d60 97 cd 72 51 43 82 e9 bc af 4c 34 6c b9 3e ec cc |..rQC....L4l.>..|
| |
− | 00000d70 e3 e5 7d 06 72 a8 8e ee 2c 11 a1 40 eb 20 0f 77 |..}.r...,..@. .w|
| |
− | 00000d80 b1 27 b4 3b 82 b6 ec 85 f6 5b 35 48 e4 46 51 e5 |.'.;.....[5H.FQ.|
| |
− | 00000d90 2a 31 ce e0 e8 04 04 91 d0 db 46 a0 57 19 26 02 |*1........F.W.&.|
| |
− | 00000da0 d6 c6 dd b9 ce c6 cf bf 55 e5 35 96 71 d3 9c d5 |........U.5.q...|
| |
− | 00000db0 e0 a7 ec fe e3 8b 7d 9a 28 32 b5 b0 b7 c8 21 38 |......}.(2....!8|
| |
− | 00000dc0 9e 6e be 08 6f 62 cd ee b0 a1 79 e2 a0 2b 6e 22 |.n..ob....y..+n"|
| |
− | 00000dd0 6b 2b 00 7f 49 57 4a 23 28 99 75 b5 40 01 c7 9f |k+..IWJ#(.u.@...|
| |
− | 00000de0 2d e7 85 1b 5a 4e 55 3c ce d6 c7 7b 85 ec 52 ff |-...ZNU<...{..R.|
| |
− | 00000df0 23 87 38 cf 44 e1 95 bb 9c e5 44 05 3d f6 f1 85 |#.8.D.....D.=...|
| |
− | 00000e00 78 a3 7d 19 44 43 3b d4 fa db 9a bd 81 85 34 fd |x.}.DC;.......4.|
| |
− | 00000e10 ba c7 9b f5 96 1a 73 c1 46 7c 39 ec 37 56 81 ca |......s.F|9.7V..|
| |
− | 00000e20 0e a9 30 7f 82 3c f7 49 85 c7 dc 2e 34 50 78 c1 |..0..<.I....4Px.|
| |
− | 00000e30 da d5 d2 14 b6 d3 05 5c be b8 d9 ca 96 bd 52 8b |.......\......R.|
| |
− | 00000e40 c1 40 41 56 14 0f 16 aa 3e 07 bb 52 d5 1a 94 0f |.@AV....>..R....|
| |
− | 00000e50 5f 53 e5 46 dc 12 b1 74 05 70 6b 16 17 a7 94 ec |_S.F...t.pk.....|
| |
− | 00000e60 c0 5f 5e 0e 88 b1 45 e2 08 19 63 e4 b9 12 0d ca |._^...E...c.....|
| |
− | 00000e70 05 8d 42 64 39 37 3d fb 5c d1 d3 27 e7 c5 67 1b |..Bd97=.\..'..g.|
| |
− | 00000e80 21 61 64 5e a1 5f 6e f6 7b a1 bd 37 35 3a 3a 90 |!ad^._n.{..75::.|
| |
− | 00000e90 8e 65 78 e9 4b 04 87 6f fa be 82 63 12 5d 46 b8 |.ex.K..o...c.]F.|
| |
− | 00000ea0 32 f8 10 67 f9 4b 1f 40 33 f4 b6 50 2d 76 34 bc |2..g.K.@3..P-v4.|
| |
− | 00000eb0 e3 49 ee a7 d5 84 31 4e f3 1e 5b d8 a4 8a f5 12 |.I....1N..[.....|
| |
− | 00000ec0 80 1a 4b c6 ab 16 31 48 23 ea 1b 72 c4 f6 7c 2d |..K...1H#..r..|-|
| |
− | 00000ed0 ef 7a e7 54 65 cc 19 9f f6 7a fe d7 35 de d7 ab |.z.Te....z..5...|
| |
− | 00000ee0 94 7f 7e 5e 47 2a 19 78 95 e2 91 37 bd c9 e9 e9 |..~^G*.x...7....|
| |
− | 00000ef0 9f 55 b8 00 69 c2 b3 50 ea b4 f9 48 f3 d2 78 c6 |.U..i..P...H..x.|
| |
− | </pre>
| |