Test Run Starlet AES Engine [Bushing / Sven Peter]
#1
Test Run Starlet AES Engine [Bushing / Sven Peter]

What is this?
It is a snippet of PPC code (formed as a C0 gecko code) I wrote using the information about Starlet's AES engine on Wiibrew.org and information from Team Twiizers crypto.c MINI source (https://github.com/fail0verflow/mini/blo...r/crypto.c). I had to adjust some things to get their code to work on Broadway.

This code will take the provided 16 byte data, encrypt it, and then decrypt it (using the provided key and IV)

Licensed under GPLv2.

It APPEARS to be working. Btw, you NEED full Hardware Rights to run this code (https://mkwii.com/showthread.php?tid=1596)

My Test Results:
I used my Mem Viewer Code while running this, and saw the 16-byte data at 0x80001500 and at 0x80001520 is a match, bit for bit. Data was encrypted (16 bytes written at 0x80001510), and decrypted at 0x80001520. Pre-encncrypted data matched post-decrypted data.

Z = 16-byte block of data that will be used in the encryption-decryption
K = Your Key
V = Your IV
S = Source Address for the AES engine

NOTE: The address for S MUST be 16-byte aligned. Simply make sure the address value ends in a 0. (ex: 0x80001500)

S + 0x10 will be where the encrypted data is stored to
S + 0x20 will be where the decrypted data is stored to (will match the pre-encrypted data at S)

Big thank you to Chip for the motivational support.

Region-Free (works on any Wii game)
C0000000 0000002A
7D8802A6 9421FF80
BC610008 7C0000A6
5403045E 7C600124
541B8FFE 48000039
ZZZZZZZZ ZZZZZZZZ
ZZZZZZZZ ZZZZZZZZ
KKKKKKKK KKKKKKKK
KKKKKKKK KKKKKKKK
VVVVVVVV VVVVVVVV
VVVVVVVV VVVVVVVV
SSSSSSSS 7F4802A6
BB9A0000 833A0030
5720073F 40820074
BF990000 3AA00004
7EA903A6 7F23CB78
7C00186C 7C0004AC
38630004 4200FFF4
3F00CD82 38000000
48000081 48000091
5723007E 90780004
3AE30010 92F80008
3C009000 48000065
38000000 4800005D
4800006D 92F80004
3AD70010 92D80008
66D68000 3C009800
48000041 48000041
2C1B0000 7C6000A6
4182000C 60608000
48000008 5460045E
7C000124 3C004E80
60000020 900F0000
B8610008 38210080
7D8803A6 4E800020
90180000 80180000
2C000000 41A0FFF8
4E800020 387A000C
7EA903A6 84030004
9018000C 4200FFF8
7EA903A6 84030004
90180010 4200FFF8
4E800020 00000000



Code creators: Bushing, Sven Peter



/*
mini - a Free Software replacement for the Nintendo/BroadOn IOS.
crypto hardware support
Copyright © 2008, 2009 Haxx Enterprises <bushing@gmail.com>
Copyright © 2008, 2009 Sven Peter <svenpeter@gmail.com>
# This code is licensed to you under the terms of the GNU GPL, version 2;
# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/

https://github.com/fail0verflow/mini/blo...r/crypto.c

#START ASSEMBLY
#r28 thru r31 #For lmw/stmw instructions of Data transfer
#r27 = Machine State Register backup
#r26 = LUT Table Pointer
#r25 = Pointer to Source Address
#r24 = Starlet AES Address Upper 16 bits
#r23 = Pointer to Destinaton Address; stays physical the whole time
#r22 = Pointer to Final Address; starts physical then goes virtual
#r21 = CTR (4)

.set key1, 0xABCDABCD #Edit in whatever Key you are using
.set key2, 0xFFEEFFEE
.set key3, 0x12121212
.set key4, 0x55559999

.set iv1, 0x2EF70033 #Edit in whatever IV you are using
.set iv2, 0xAABD7EC1
.set iv3, 0x00000005
.set iv4, 0x1C00791C

.set source, 0x80001500 #Your source address, edit this to your liking

#Destination address is 0x10 beyond source address
#Final address (where decrypted data goes to) is 0x10 beyond destination address

#Backup LR, create stack frame
mflr r12
stwu sp, -0x80 (sp) #We don't need this much stack space, but whatever
stmw r3, 0x8 (sp)

#Disable Interrupts, what we're doing is important Tongue
mfmsr r0 #Grab MSR
rlwinm r3, r0, 0, 17, 15 #Flip off 'Allow interrupts' bit
mtmsr r3 #Update new MSR
rlwinm r27, r0, 17, 31, 31 #Backup original MSR

#Lookup Table (Data, then Key, then IV)
bl lut_table

.llong 0x2ACD12341234FF00 #First 8 bytes of Data that will be encrypted, edit this to your liking
.llong 0x44445555ABAB0001 #Second 8 bytes

.long key1
.long key2
.long key3
.long key4
.long iv1
.long iv2
.long iv3
.long iv4
.long source

lut_table:
mflr r26

#Load Data and Source Address
lmw r28, 0 (r26)
lwz r25, 0x30 (r26)

#Check if Source Address is 16-byte aligned
clrlwi. r0, r25, 28
bne- restore_interrupts

#Write Data to Source Address
stmw r28, 0 (r25)

#Do a data cache block store on every word of the Data, this is needed!
li r21, 4
mtctr r21

mr r3, r25 #Keep r25 intact

cache_loop:
dcbst 0, r3
sync #Wait for data cache updates to be completed
addi r3, r3, 4
bdnz+ cache_loop

#Set Starlet AES Address Upper 16 bits
lis r24, 0xCD82

#Reset Engine, send Command
li r0, 0
bl command_then_check

#Send Key & IV
bl send_keyiv

#Send Source DMA
clrlwi r3, r25, 1 #Change Address to Physical
stw r3, 0x4 (r24)

#Send Destination DMA
addi r23, r3, 0x10 #Make dest point to spot where encrypted data will be dumped to
stw r23, 0x8 (r24)

#Set Block Size
#Block size is 1 block so its 0 on AES engine

#Prepare AES Command
lis r0, 0x9000 #encrypt, IV bit low (use IV) so no need to write anything to lower 16 bits

#Run the engine!
bl command_then_check

##Encrypted Data written to contents table, now let's decrypt it

#Reset Engine again, send Command
li r0, 0
bl command_then_check

#Send Key and IV
bl send_keyiv

#Send in new Source DMA and new Dest DMA
stw r23, 0x4 (r24) #Old Dest is now New Source DMA
addi r22, r23, 0x10 #Make dest point to new new spot
stw r22, 0x8 (r24)

#Switch r22 back to virtual for later non-engine use
oris r22, r22, 0x8000

#Set Block Size
#Block size is 1 block so its 0 on AES engine

#Prepare AES Command
lis r0, 0x9800 #decrypt

#Run the Engine
bl command_then_check

#Check Busy
bl final_busy_check

#Restore Interrupts
restore_interrupts:
cmpwi r27, 0
mfmsr r3
beq- clear_bit
ori r0, r3, 0x8000
b skip_clear_bit
clear_bit:
rlwinm r0, r3, 0, 17, 15
skip_clear_bit:
mtmsr r0

#Done, rewrite C0, we only need this code to execute once
lis r0, 0x4E80
ori r0, r0, 0x0020
stw r0, 0 (r15)

#Pop Stack, RestoreLR
lmw r3, 0x8 (sp)
addi sp, sp, 0x80
mtlr r12
blr #End C0

#Send Command then Check Busy subroutine
command_then_check:
stw r0, 0 (r24)
final_busy_check:
check_busy:
lwz r0, 0 (r24)
cmpwi r0, 0
blt- check_busy
blr

send_keyiv:
#Send Key
addi r3, r26, 0xC #Point to -0x4 in reference to where key is in LUT
mtctr r21
fifo_loop:
lwzu r0, 0x4 (r3)
stw r0, 0xC (r24)
bdnz+ fifo_loop

#Send IV #r3 address already set
mtctr r21
fifo_loop2:
lwzu r0, 0x4 (r3)
stw r0, 0x10 (r24)
bdnz+ fifo_loop2
blr
Reply
#2
Amazing work as always!
This is amazing that this code accesses and uses the AES Engine from the PowerPC side of the Wii.
Reply
#3
Thank you for the kind words. I updated the source btw, much cleaner.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)