65816-crypto/aes.macros

399 lines
6.5 KiB
Plaintext

* Copyright (c) 2017 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* This makes a function wrapper that is callable from C,
* taking a pointer to the context structure as its argument.
macro
CFunction &fn
phb
plx
ply
tdc
pld
plb
plb
phy
phx
plb
pha
jsl &fn
pld
rtl
mend
*The 'core' function applied to some words when computing the AES key schedule
macro
ExpandKeyCore &xorback,&rconoffset
ShortRegs
ldy rk-3,x
lda Sbox,y
eor Rcon-&xorback+&rconoffset,x
eor rk-&xorback,x
sta rk,x
ldy rk-2,x
lda Sbox,y
eor rk+1-&xorback,x
sta rk+1,x
ldy rk-1,x
lda Sbox,y
eor rk+2-&xorback,x
sta rk+2,x
ldy rk-4,x
lda Sbox,y
eor rk+3-&xorback,x
sta rk+3,x
LongRegs
mend
* Secondary substitution step used when expanding AES-256 keys
macro
ExpandKeySubst &xorback,&rconoffset
ShortRegs
ldy rk-4,x
lda Sbox,y
eor rk-&xorback,x
sta rk,x
ldy rk+1-4,x
lda Sbox,y
eor rk+1-&xorback,x
sta rk+1,x
ldy rk+2-4,x
lda Sbox,y
eor rk+2-&xorback,x
sta rk+2,x
ldy rk+3-4,x
lda Sbox,y
eor rk+3-&xorback,x
sta rk+3,x
LongRegs
mend
* Generate consecutive words of key schedule that don't use above functions
macro
ExpandKeyIter &xorback,&nwords
lcla &i
lda rk,x
.loop1
eor rk+&i+4-&xorback,x
sta rk+&i+4,x
&i seta &i+4
aif &i/4<&nwords,.loop1
&i seta 2
lda rk+2,x
.loop2
eor rk+&i+4-&xorback,x
sta rk+&i+4,x
&i seta &i+4
aif &i/4<&nwords,.loop2
mend
* Do an initial AddRoundKey step on the starting state (for encryption)
macro
AddInitialRoundKey
lcla &i
.top
lda state1+&i
eor rk+&i
sta state1+&i
&i seta &i+2
aif &i<16,.top
mend
* Do a full normal round, including (in effect) SubBytes through AddRoundKey
macro
&lbl NormalRound &round
&lbl anop
aif &round/2*2=&round,.evenround
MixColumn 0,0,5,10,15,state1,state2
MixColumn 4,4,9,14,3,state1,state2
MixColumn 8,8,13,2,7,state1,state2
MixColumn 12,12,1,6,11,state1,state2
ago .done
.evenround
MixColumn 0,0,5,10,15,state2,state1
MixColumn 4,4,9,14,3,state2,state1
MixColumn 8,8,13,2,7,state2,state1
MixColumn 12,12,1,6,11,state2,state1
.done
mend
* Do the operations on one column for a normal round.
macro
MixColumn &i,&A,&B,&C,&D,&state,&out
aif (&i=0).AND.(&round<>1),.skip
ldy &state+&D
.skip
lda Sbox,Y
pha
ldx &state+&A
eor Xtime2Sbox,X
ldy &state+&B
eor Xtime3Sbox,Y
ldy &state+&C
eor Sbox,Y
eor rk+&round*16+&i
sta &out+&i
pla
eor Xtime3Sbox,Y
eor Sbox,X
ldy &state+&B
eor Xtime2Sbox,Y
eor rk+&round*16+&i+1
sta &out+&i+1
lda Sbox,Y
pha
ldy &state+&D
eor Xtime3Sbox,Y
eor Sbox,X
ldy &state+&C
eor Xtime2Sbox,Y
eor rk+&round*16+&i+2
sta &out+&i+2
pla
eor Sbox,Y
eor Xtime3Sbox,X
ldy &state+&D
eor Xtime2Sbox,Y
aif (rk+&round*16+&i+3)>255,.bigindex
eor rk+&round*16+&i+3
ago .cont
.bigindex
ldx #&round*16+&i+3
eor rk,X
.cont
sta &out+&i+3
aif &i<>12,.skip2
tay
.skip2
mend
* Do final round, including (in effect) SubBytes, ShiftRows, and AddRoundKey.
macro
FinalRound &round
FinalRoundStep 3,15,1
FinalRoundStep 15,11
FinalRoundStep 11,7
FinalRoundStep 7,3
FinalRoundStep 0,0
FinalRoundStep 4,4
FinalRoundStep 8,8
FinalRoundStep 12,12
FinalRoundStep 13,1
FinalRoundStep 1,5
FinalRoundStep 5,9
FinalRoundStep 9,13
FinalRoundStep 10,2
FinalRoundStep 2,10
FinalRoundStep 14,6
FinalRoundStep 6,14
mend
* Do the final round operations for one byte.
macro
FinalRoundStep &to,&from,&skipldy
aif C:&skipldy,.skip
ldy state2+&from
.skip
lda Sbox,Y
aif (rk+&round*16+&to)>255,.bigindex
eor rk+&round*16+&to
ago .cont
.bigindex
ldx #&round*16+&to
eor rk,X
.cont
sta state1+&to
mend
* Perform an inverse normal round (for decryption)
macro
InvNormalRound &round,&state
lcla &i
lclc &state
lclc &out
aif &round/2*2=&round,.evenround
&state setc state2
&out setc state1
ago .cont
.evenround
&state setc state1
&out setc state2
.cont
InvMixColumn 12,1,6,11,12,1
InvMixColumn 0,5,10,15,0
InvMixColumn 8,13,2,7,8
InvMixColumn 4,9,14,3,4,dotax=1
mend
* Perform the operations for one column in an inverse normal round
macro
InvMixColumn &A,&B,&C,&D,&i,&skipldx,&dotax
aif C:&skipldx,.skip
ldx &state+&i+2
.skip
lda Xtime9,X
ldy &state+&i+0
eor XtimeB,Y
ldy &state+&i+1
eor XtimeD,Y
ldy &state+&i+3
eor XtimeE,Y
tay
lda InvSbox,Y
eor rk+(&round-1)*16+&D
sta &out+&D
ldy &state+&i+0
lda XtimeE,Y
ldy &state+&i+1
eor XtimeB,Y
eor XtimeD,X
ldy &state+&i+3
eor Xtime9,Y
tay
lda InvSbox,Y
eor rk+(&round-1)*16+&A
sta &out+&A
ldy &state+&i+0
lda Xtime9,Y
ldy &state+&i+1
eor XtimeE,Y
eor XtimeB,X
ldy &state+&i+3
eor XtimeD,Y
tay
lda InvSbox,Y
eor rk+(&round-1)*16+&B
sta &out+&B
ldy &state+&i+0
lda XtimeD,Y
ldy &state+&i+1
eor Xtime9,Y
eor XtimeE,X
ldy &state+&i+3
eor XtimeB,Y
tay
lda InvSbox,Y
eor rk+(&round-1)*16+&C
aif (C:&dotax).AND.(&round<>1),.dotax
sta &out+&C
ago .done
.dotax
tax
.done
mend
* Do the inverse final round steps for one byte.
macro
InvFinalRoundStep &to,&from,&dotax
lda state1+&from
aif (rk+&round*16+&from)>255,.bigindex
eor rk+&round*16+&from
ago .cont
.bigindex
ldx #&round*16+&from
eor rk,X
.cont
tay
lda InvSbox,Y
aif (rk+(&round-1)*16+&to)>255,.bigindex2
eor rk+(&round-1)*16+&to
ago .cont2
.bigindex2
ldx #(&round-1)*16+&to
eor rk,X
.cont2
aif C:&dotax,.dotax
sta state2+&to
ago .done
.dotax
tax
.done
mend
* Do the inverse of the final round (which comes first for decryption).
macro
InvFinalRound &round
InvFinalRoundStep 0,0
InvFinalRoundStep 4,4
InvFinalRoundStep 8,8
InvFinalRoundStep 12,12
InvFinalRoundStep 1,13
InvFinalRoundStep 13,9
InvFinalRoundStep 9,5
InvFinalRoundStep 5,1
InvFinalRoundStep 15,3
InvFinalRoundStep 3,7
InvFinalRoundStep 7,11
InvFinalRoundStep 11,15
InvFinalRoundStep 2,10
InvFinalRoundStep 10,2
InvFinalRoundStep 6,14
InvFinalRoundStep 14,6,1
mend
* Set registers to 8 bits
macro
ShortRegs
sep #$30
longa off
longi off
mend
* Set registers to 16 bits
macro
LongRegs
rep #$30
longa on
longi on
mend