; ============================================================ ; aes128_ks.S - AES-128 routines (with key schedule precomputation) ; ; Copyright (C) 2010-2013, Tomas Pecina ; ; This file is part of PICCE, an open source PICC emulator. ; ; PICCE is free software: you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, either version 3 of the License, or ; (at your option) any later version. ; ; PICCE is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program. If not, see . ; #include "picce.inc" ; ============================================================ ; aes128ks - prepare AES key schedule ; input: X - pointer to key ; Z - pointer to key schedule buffer (44/52/60 bytes) ; output: key schedule ; uses: r0-r4, AL, CL, DL, DH, X, Y, Z ; .global aes128ks aes128ks: ; initialize variables ldi DH, 1 ldi ZH, hi8(sdir) ldi CL, 10 ; copy key to first fragment and load it in registers .irp iter, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ld \iter, X+ st Z+, \iter .endr ; g function 2: .irp iter, 0, 1, 2, 3 mov ZL, 12 + \iter lpm AL, Z eor \iter, AL .endr mov ZL, DH lpm DH, Z eor r0, DH ; process words .irp iter, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 eor \iter, \iter - 4 .endr ; store fragment in SRAM .irp iter, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 st Z+, \iter .endr ; end of loop dec CL breq 1f rjmp 2b 1: ret ; ============================================================ ; aes128 - encrypt/decrypt block with AES-128 ; input: X - pointer to data ; Z - pointer to key schedule ; AL - mode (0=encrypt, >0=decrypt) ; output: encrypted/decrypted data ; X - incremented ; uses: r0-r15, AL, AH, CL, DL, EL, EH, Y ; .global aes128 aes128: ; initialize variables ldi CL, 10 ; load data to registers .irp iter, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ld \iter, X+ .endr ; test mode tst AL breq 1f rjmp 4f ; Key Addition Layer 1: movw YX, ZX .irp iter, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ld AL, Y+ eor \iter, AL .endr ; combined Byte Substitution Layer + ShiftRows Sublayer 2: ldi ZH, hi8(sdir) mov ZL, r0 lpm r0, Z mov ZL, r4 lpm r4, Z mov ZL, r8 lpm r8, Z mov ZL, r12 lpm r12, Z mov ZL, r1 lpm AL, Z mov ZL, r5 lpm r1, Z mov ZL, r9 lpm r5, Z mov ZL, r13 lpm r9, Z mov r13, AL mov ZL, r2 lpm AL, Z mov ZL, r10 lpm r2, Z mov r10, AL mov ZL, r6 lpm AL, Z mov ZL, r14 lpm r6, Z mov r14, AL mov ZL, r3 lpm AL, Z mov ZL, r15 lpm r3, Z mov ZL, r11 lpm r15, Z mov ZL, r7 lpm r11, Z mov r7, AL ; MixColumn Sublayer cpi CL, 1 brne 1f rjmp 3f 1: ldi ZH, hi8(gfmul) .irp iter, 0, 1, 2, 3 mov ZL, (\iter * 4) + 0 eor ZL, (\iter * 4) + 1 mov DL, ZL lpm AL, Z mov ZL, (\iter * 4) + 1 eor ZL, (\iter * 4) + 2 lpm AH, Z mov ZL, (\iter * 4) + 2 eor ZL, (\iter * 4) + 3 eor DL, ZL lpm EL, Z mov ZL, (\iter * 4) + 3 eor ZL, (\iter * 4) + 0 lpm EH, Z eor AL, DL eor AH, DL eor EL, DL eor EH, DL eor (\iter * 4) + 0, AL eor (\iter * 4) + 1, AH eor (\iter * 4) + 2, EL eor (\iter * 4) + 3, EH .endr ; Key Addition Layer 3: .irp iter, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ld AL, Y+ eor \iter, AL .endr ; end of round 1: dec CL breq 5f rjmp 2b ; write data back to buffer and return 5: .irp iter, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 st -X, 15 - \iter .endr ret ; Key Addition Layer 4: mov YL, CL inc YL swap YL clr YH addw YX, ZX .irp iter, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ld AL, -Y eor 15 - \iter, AL .endr ; Inverse MixColumn Sublayer rjmp 3f ; skip in first round 2: ldi ZH, hi8(gfmul) .irp iter, 0, 1, 2, 3 mov ZL, (\iter * 4) + 0 eor ZL, (\iter * 4) + 2 lpm ZL, Z lpm DL, Z eor (\iter * 4) + 0, DL eor (\iter * 4) + 2, DL mov ZL, (\iter * 4) + 1 eor ZL, (\iter * 4) + 3 lpm ZL, Z lpm DL, Z eor (\iter * 4) + 1, DL eor (\iter * 4) + 3, DL mov ZL, (\iter * 4) + 0 eor ZL, (\iter * 4) + 1 mov DL, ZL lpm AL, Z mov ZL, (\iter * 4) + 1 eor ZL, (\iter * 4) + 2 lpm AH, Z mov ZL, (\iter * 4) + 2 eor ZL, (\iter * 4) + 3 eor DL, ZL lpm EL, Z mov ZL, (\iter * 4) + 3 eor ZL, (\iter * 4) + 0 lpm EH, Z eor AL, DL eor AH, DL eor EL, DL eor EH, DL eor (\iter * 4) + 0, AL eor (\iter * 4) + 1, AH eor (\iter * 4) + 2, EL eor (\iter * 4) + 3, EH .endr ; combined Inverse ShiftRows Sublayer + Inverse Byte Substitution Layer 3: ldi ZH, hi8(sinv) mov ZL, r0 lpm r0, Z mov ZL, r4 lpm r4, Z mov ZL, r8 lpm r8, Z mov ZL, r12 lpm r12, Z mov ZL, r1 lpm AL, Z mov ZL, r13 lpm r1, Z mov ZL, r9 lpm r13, Z mov ZL, r5 lpm r9, Z mov r5, AL mov ZL, r2 lpm AL, Z mov ZL, r10 lpm r2, Z mov r10, AL mov ZL, r6 lpm AL, Z mov ZL, r14 lpm r6, Z mov r14, AL mov ZL, r3 lpm AL, Z mov ZL, r7 lpm r3, Z mov ZL, r11 lpm r7, Z mov ZL, r15 lpm r11, Z mov r15, AL ; Key Addition Layer .irp iter, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ld AL, -Y eor 15 - \iter, AL .endr ; end of round dec CL breq 1f rjmp 2b 1: rjmp 5b ; data tables .aconst 256 sdir: .byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 .byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 .byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 .byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 .byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 .byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf .byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 .byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 .byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 .byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb .byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 .byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 .byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a .byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e .byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf .byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 sinv: .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d gfmul: .byte 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e .byte 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e .byte 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e .byte 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e .byte 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e .byte 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe .byte 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde .byte 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe .byte 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05 .byte 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25 .byte 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45 .byte 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65 .byte 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85 .byte 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5 .byte 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5 .byte 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 .previous .end