Changes

Jump to navigation Jump to search
55,962 bytes removed ,  20:12, 11 August 2017
Redirected page to TSEC
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>
 

Navigation menu