; ADDITIONAL DESIGN NOTES:
; - MOVW Befehl zur Rettung von r28-31 FALSCH herum geschrieben!!!
; - MOVW Befehl zum finalen Zurückschieben der Spalten FALSCH herum geschrieben!

;
;	Globale Definitionen
;
.include "m163def.inc"
.equ RAMSTART = $0060

jmp Start ;nur für Funktionstests!
;
;	Tabellen
;

PrimaryKey:
; Vorläufiger Testschlüssel aus den offiziellen Spezifikationen
.db $2b, $7e, $15, $16, $28, $ae, $d2, $a6, $ab, $f7, $15, $88, $09, $cf, $4f, $3c

SBox:
; S-Box für AES-Encryption
;    0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f
.db $63, $7c, $77, $7b, $f2, $6b, $6f, $c5, $30, $01, $67, $2b, $fe, $d7, $ab, $76 ; 0
.db $ca, $82, $c9, $7d, $fa, $59, $47, $f0, $ad, $d4, $a2, $af, $9c, $a4, $72, $c0 ; 1
.db $b7, $fd, $93, $26, $36, $3f, $f7, $cc, $34, $a5, $e5, $f1, $71, $d8, $31, $15 ; 2
.db $04, $c7, $23, $c3, $18, $96, $05, $9a, $07, $12, $80, $e2, $eb, $27, $b2, $75 ; 3
.db $09, $83, $2c, $1a, $1b, $6e, $5a, $a0, $52, $3b, $d6, $b3, $29, $e3, $2f, $84 ; 4
.db $53, $d1, $00, $ed, $20, $fc, $b1, $5b, $6a, $cb, $be, $39, $4a, $4c, $58, $cf ; 5
.db $d0, $ef, $aa, $fb, $43, $4d, $33, $85, $45, $f9, $02, $7f, $50, $3c, $9f, $a8 ; 6
.db $51, $a3, $40, $8f, $92, $9d, $38, $f5, $bc, $b6, $da, $21, $10, $ff, $f3, $d2 ; 7
.db $cd, $0c, $13, $ec, $5f, $97, $44, $17, $c4, $a7, $7e, $3d, $64, $5d, $19, $73 ; 8
.db $60, $81, $4f, $dc, $22, $2a, $90, $88, $46, $ee, $b8, $14, $de, $5e, $0b, $db ; 9
.db $e0, $32, $3a, $0a, $49, $06, $24, $5c, $c2, $d3, $ac, $62, $91, $95, $e4, $79 ; a
.db $e7, $c8, $37, $6d, $8d, $d5, $4e, $a9, $6c, $56, $f4, $ea, $65, $7a, $ae, $08 ; b
.db $ba, $78, $25, $2e, $1c, $a6, $b4, $c6, $e8, $dd, $74, $1f, $4b, $bd, $8b, $8a ; c
.db $70, $3e, $b5, $66, $48, $03, $f6, $0e, $61, $35, $57, $b9, $86, $c1, $1d, $9e ; d
.db $e1, $f8, $98, $11, $69, $d9, $8e, $94, $9b, $1e, $87, $e9, $ce, $55, $28, $df ; e
.db $8c, $a1, $89, $0d, $bf, $e6, $42, $68, $41, $99, $2d, $0f, $b0, $54, $bb, $16 ; f

InvSBox:
; Inverse S-Box für AES-Decryption
;    0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f
.db $52, $09, $6a, $d5, $30, $36, $a5, $38, $bf, $40, $a3, $9e, $81, $f3, $d7, $fb ; 0
.db $7c, $e3, $39, $82, $9b, $2f, $ff, $87, $34, $8e, $43, $44, $c4, $de, $e9, $cb ; 1
.db $54, $7b, $94, $32, $a6, $c2, $23, $3d, $ee, $4c, $95, $0b, $42, $fa, $c3, $4e ; 2
.db $08, $2e, $a1, $66, $28, $d9, $24, $b2, $76, $5b, $a2, $49, $6d, $8b, $d1, $25 ; 3
.db $72, $f8, $f6, $64, $86, $68, $98, $16, $d4, $a4, $5c, $cc, $5d, $65, $b6, $92 ; 4
.db $6c, $70, $48, $50, $fd, $ed, $b9, $da, $5e, $15, $46, $57, $a7, $8d, $9d, $84 ; 5
.db $90, $d8, $ab, $00, $8c, $bc, $d3, $0a, $f7, $e4, $58, $05, $b8, $b3, $45, $06 ; 6
.db $d0, $2c, $1e, $8f, $ca, $3f, $0f, $02, $c1, $af, $bd, $03, $01, $13, $8a, $6b ; 7
.db $3a, $91, $11, $41, $4f, $67, $dc, $ea, $97, $f2, $cf, $ce, $f0, $b4, $e6, $73 ; 8
.db $96, $ac, $74, $22, $e7, $ad, $35, $85, $e2, $f9, $37, $e8, $1c, $75, $df, $6e ; 9
.db $47, $f1, $1a, $71, $1d, $29, $c5, $89, $6f, $b7, $62, $0e, $aa, $18, $be, $1b ; a
.db $fc, $56, $3e, $4b, $c6, $d2, $79, $20, $9a, $db, $c0, $fe, $78, $cd, $5a, $f4 ; b
.db $1f, $dd, $a8, $33, $88, $07, $c7, $31, $b1, $12, $10, $59, $27, $80, $ec, $5f ; c
.db $60, $51, $7f, $a9, $19, $b5, $4a, $0d, $2d, $e5, $7a, $9f, $93, $c9, $9c, $ef ; d
.db $a0, $e0, $3b, $4d, $ae, $2a, $f5, $b0, $c8, $eb, $bb, $3c, $83, $53, $99, $61 ; e
.db $17, $2b, $04, $7e, $ba, $77, $d6, $26, $e1, $69, $14, $63, $55, $21, $0c, $7d ; f


;
;	Letzte Spalte des Statevektors verschieben
;	um die Zeiger y und z verwenden zu können
;	
;	Aufteilung des Statevektors:
;		Spalte 1: r16-r19
;		Spalte 2: r20-r23
;		Spalte 3: r24-r27
;		Spalte 4: r12-r15
;
;	Frei verwendbare Register für Unterfunktionen sind:
;		r0-r10
;		r28-r31
;
Start: ;nur für Funktionstests!
;Testvektor Cleartext
LDI r16, $32
LDI r17, $43
LDI r18, $f6
LDI r19, $a8
LDI r20, $88
LDI r21, $5a
LDI r22, $30
LDI r23, $8d
LDI r24, $31
LDI r25, $31
LDI r26, $98
LDI r27, $a2
LDI r28, $e0
LDI r29, $37
LDI r30, $07
LDI r31, $34

movw r13:r12, r29:r28
movw r15:r14, r31:r30 

;
;	Stack-Pointer initialisieren
;

ldi r30, LOW(RAMEND)
ldi r31, HIGH(RAMEND)
out spl, r30
out sph, r31

rcall ShiftRows ;nur für Funktionstests!
rcall SubBytes ;nur für Funktionstests!
rcall InvSubBytes ;nur für Funktionstests!
rcall InvShiftRows ;nur für Funktionstests!
rjmp End ;nur für Funktionstests!

;==============================================================================
;
;		V E R S C H L Ü S S E L U N G
;
;==============================================================================
Encrypt:

;
;	Initiale Rundenschlüsseladdition
;

rcall XORRoundKey



;
;	Schleife für 9 Runden
;		Verwende r11 für die Schleifenvariable
;

ldi r28, $09
mov r11, r28

EncRounds:
rcall SubBytes
rcall ShiftRows
rcall MixColumns
rcall XORRoundKey
dec r11
brne EncRounds


;
;	Letzte Runde
;

rcall SubBytes
rcall ShiftRows
rcall XORRoundKey


rjmp End

;==============================================================================
;
;		E N T S C H L Ü S S E L U N G
;
;==============================================================================
Decrypt:

;
;	Initiale Rundenschlüsseladdition
;

rcall InvXORRoundKey


;
;	Schleife für 9 Runden
;		Verwende r11 für die Schleifenvariable
;

ldi r28, $09
mov r11, r28

DecRounds:
rcall InvShiftRows
rcall InvSubBytes
rcall InvXORRoundKey
rcall InvMixColumns
dec r11
brne DecRounds


;
;	Letzte Runde
;

rcall InvShiftRows
rcall InvSubBytes
rcall InvXORRoundKey


rjmp End

;==============================================================================
;
;		X O R R O U N D K E Y
;
;==============================================================================
XORRoundKey:
ret



;==============================================================================
;
;		I N V X O R R O U N D K E Y
;
;==============================================================================
InvXORRoundKey:
ret



;==============================================================================
;
;		S U B B Y T E S
;
;==============================================================================
SubBytes:
PUSH r30
PUSH r31

; LDI r16, $42 ; Testbyte

;Sub Row No.1
;Register r16 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r16
CLR r16
ADC ZH, r16
LPM r16, Z
;Register r20 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r20
CLR r20
ADC ZH, r20
LPM r20, Z
;Register r24 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r24
CLR r24
ADC ZH, r24
LPM r24, Z
;Register r12 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r12
CLR r12
ADC ZH, r12
LPM r12, Z

;Sub Row No.2
;Register r17 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r17
CLR r17
ADC ZH, r17
LPM r17, Z
;Register r21 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r21
CLR r21
ADC ZH, r21
LPM r21, Z
;Register r25 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r25
CLR r25
ADC ZH, r25
LPM r25, Z
;Register r13 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r13
CLR r13
ADC ZH, r13
LPM r13, Z

;Sub Row No.3
;Register r18 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r18
CLR r18
ADC ZH, r18
LPM r18, Z
;Register r22 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r22
CLR r22
ADC ZH, r22
LPM r22, Z
;Register r26 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r26
CLR r26
ADC ZH, r26
LPM r26, Z
;Register r14 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r14
CLR r14
ADC ZH, r14
LPM r14, Z

;Sub Row No.4
;Register r19 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r19
CLR r19
ADC ZH, r19
LPM r19, Z
;Register r23 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r23
CLR r23
ADC ZH, r23
LPM r23, Z
;Register r27 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r27
CLR r27
ADC ZH, r27
LPM r27, Z
;Register r15 Sub'en
LDI ZH, high(SBox * 2)
LDI ZL, low(SBox * 2)
ADD ZL, r15
CLR r15
ADC ZH, r15
LPM r15, Z

POP r31
POP r30
ret



;==============================================================================
;
;		I N V S U B B Y T E S
;
;==============================================================================
InvSubBytes:
PUSH r30
PUSH r31

;LDI r16, $2c ;Testbyte

;InvSub Row No.1
;Register r16 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r16
CLR r16
ADC ZH, r16
LPM r16, Z
;Register r20 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r20
CLR r20
ADC ZH, r20
LPM r20, Z
;Register r24 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r24
CLR r24
ADC ZH, r24
LPM r24, Z
;Register r12 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r12
CLR r12
ADC ZH, r12
LPM r12, Z

;InvSub Row No.2
;Register r17 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r17
CLR r17
ADC ZH, r17
LPM r17, Z
;Register r21 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r21
CLR r21
ADC ZH, r21
LPM r21, Z
;Register r25 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r25
CLR r25
ADC ZH, r25
LPM r25, Z
;Register r13 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r13
CLR r13
ADC ZH, r13
LPM r13, Z

;InvSub Row No.3
;Register r18 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r18
CLR r18
ADC ZH, r18
LPM r18, Z
;Register r22 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r22
CLR r22
ADC ZH, r22
LPM r22, Z
;Register r26 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r26
CLR r26
ADC ZH, r26
LPM r26, Z
;Register r14 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r14
CLR r14
ADC ZH, r14
LPM r14, Z

;InvSub Row No.4
;Register r19 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r19
CLR r19
ADC ZH, r19
LPM r19, Z
;Register r23 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r23
CLR r23
ADC ZH, r23
LPM r23, Z
;Register r27 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r27
CLR r27
ADC ZH, r27
LPM r27, Z
;Register r15 InvSub'en
LDI ZH, high(InvSBox * 2)
LDI ZL, low(InvSBox * 2)
ADD ZL, r15
CLR r15
ADC ZH, r15
LPM r15, Z

POP r31
POP r30
ret



;==============================================================================
;
;		S H I F T R O W S
;
;==============================================================================
ShiftRows:
PUSH r10 ;nur, falls nötig!!!

;"<-"
MOV r10, r17
MOV r17, r21
MOV r21, r25
MOV r25, r13
MOV r13, r10

;"<-<-"
MOV r10, r18
MOV r18, r26
MOV r26, r10 ;1. Ringtausch
MOV r10, r22
MOV r22, r14
MOV r14, r10 ;2. Ringtausch

;"<-<-<- =^= ->"
MOV r10, r15
MOV r15, r27
MOV r27, r23
MOV r23, r19
MOV r19, r10

POP r10 ;siehe push r10
ret



;==============================================================================
;
;		I N V S H I F T R O W S
;
;==============================================================================
InvShiftRows:
PUSH r10 ;nur, falls nötig!!!

;"->"
MOV r10, r13
MOV r13, r25
MOV r25, r21
MOV r21, r17
MOV r17, r10

;"->-> =^= <-<-"
MOV r10, r18
MOV r18, r26
MOV r26, r10 ;1. Ringtausch
MOV r10, r22
MOV r22, r14
MOV r14, r10 ;2. Ringtausch

;"->->-> =^= <-"
MOV r10, r19
MOV r19, r23
MOV r23, r27
MOV r27, r15
MOV r15, r10

POP r10 ;siehe push r10
ret



;==============================================================================
;
;		M I X C O L U M N S
;
;==============================================================================
MixColumns:
ret



;==============================================================================
;
;		I N V M I X C O L U M N S
;
;==============================================================================
InvMixColumns:
ret




End:
;
;	Die letzte Spalte zurückschieben
;

movw r29:r28, r13:r12
movw r31:r30, r15:r14




