The Hardware Side of Cryptography

17 June 2008

Fast AES Implementation on PIC18F4550

Filed under: encryption — Tags: , , , — edipermadi @ 7:14 pm

I have wrote two versions of AES (Rijndael) cipher code for 2 kind of microcontrollers, which are PIC16F84 and PIC16F877. Those microcontroller were able to run AES code well, but something is bothering me. I felt dissatisfied with Galois Field multiplication routine which run a bit slow due to instruction type limitation. PIC16F84 and PIC16F877 were not able to to directly implement “shift without carry”. These microcontrollers keep entering carry bit to bit 0 while doing shift left operation, and some times i feel a bit upset because of this.

To start writing this post, first i spent my time to learn PIC18F4550 instruction set and its architecture. I also spent my time to learn how lookup table was done on PIC18F4550 and also the sense of using PIC18F4550. Hmmm, now lets get ourself dirty🙂 .

Yeah, after sitting for 4 hours. I am finally able to port my Rijndael (AES) code from PIC16F877 to PIC18F4550 with major modifications on lookup table and GF(28) routine. Horray!!!😀 . This new implementation gave me better improvement on decrypting routine and small improvement on encrypting routine. Nice progress, i love my new code🙂 . It works and also fast, that was what i looking for.

My AES (Rijndael) cipher implementation on PIC18F4550 is basically divided into six versions. The characteristic of each version are listed below.

  • Version 1.x is intended for unbuffered AES 128-bit
  • Version 2.x is intended for unbuffered AES 192-bit (not available yet)
  • Version 3.x is intended for unbuffered AES 256-bit
  • Version 4.x is intended for buffered AES 128-bit
  • Version 5.x is intended for buffered AES 192-bit
  • Version 6.x is intended for buffered AES 256-bit

The term buffered means that all subkeys are buffered, so that the program only need to generate subkeys once all use it all the time until the new subkey are generated. By doing this, we can speed up the code by excluding key scheduling routine.

In the other side, the implementation which has no buffered (unbuffered) will perform key scheduling to generate subkey on each iteration. That was the reason why unbuffered implementation is slower than buffered implementation. But note that buffered implementation require more memory to store its subkey. If you have lots of free memory, I suggest you to use the buffered one.

See two Screenshots below, i took those picture from MPLAB v8.0, the tools where i developed this code. Nice software and Its absolutely free!. Checkout microchip website for more updates.

Plain Text

Cipher Text

Check out also materials related to this post below. If you need AES (Rijndael) implementations on PIC16F84 and PIC16F877. Please check out these links: AES (Rijndael) PIC16F84 and AES (Rijndael) PIC16F877.

RELATED STUFF

Download:
Source Code AES 128-bit unbuffered | v1.0 | v1.1 | v1.2
Source Code AES 256-bit unbuffered | v3.0 | v3.1
Source Code AES 128-bit buffered | v4.0 | v4.1 | v4.2 | v4.3 | v4.4
Source Code AES 192-bit buffered | v5.0 | v5.1 | v5.2
Source Code AES 256-bit buffered | v6.0 | v6.1 | v6.2 | v6.3
PIC18F4550 Datasheet
MPLAB v8.0

References:
Advanced Encryption Standard
Joan Daemen
Vincent Rijmen

Simulator:
AES(Rijndael Simulator)

Official Webiste:
http://www.microchip.com

36 Comments »

  1. Hello, Thnaks alot for proving the asm codes for implementation of AES on PIC18f4550. Presently this code runs in MPLAN using C18 compiler under simulation mode. when I am trying to debug, I am not able to put a break point anywhere in the code. I am trying to modify the user key and plain text. Can u please help?

    Comment by Bappaditya Mandal — 3 September 2008 @ 10:09 am

  2. Hello, Thnaks alot for proving the asm codes for implementation of AES on PIC18f4550. Presently this code runs in MPLAB using C18 compiler under simulation mode. when I am trying to debug, I am not able to put a break point anywhere in the code. I am trying to modify the user key and plain text. Can u please help?

    Comment by Bappaditya Mandal — 3 September 2008 @ 10:11 am

  3. if i want to change the key, how to reinitialize the “subkey buffer”?…..which part of the code has that?. Thanks….wud be grateful if anyone answers this.

    Comment by Bappaditya Mandal — 3 September 2008 @ 11:29 am

  4. Hi, nice to hear your voice🙂

    To change key, you just simply initialize registers s0 to s15 or up to s23 or s31 if you use higher version of aes.

    there are two type of implementation, which are buffered and unbuffered. for better result i suggest you to use the buffered one (using PIC18F4550).

    In buffered version, you simply call “ksch” function to reinitialize key buffer. the function that updates key buffer is named “ksch”.

    For simulation. I did not use MPLAB C18, i used MPLABSIM. i dont know how to use MPLAB C18, so i can not answer your quistion about “break point” problem.

    Comment by edipermadi — 3 September 2008 @ 12:34 pm

  5. Thanks a lot for your reply. I am using your Source Code AES 128-bit buffered – v4.3. Lets say my
    key is: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
    data text is: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff.

    In your program where do I reinitialize this key and initialize data. Also, how do I check the cipher text (encrypted text)?, it should be: 69 c4 e0 d8 6a 7b 04 30 d8 cd b7 80 70 b4 c5 5a.
    Please assume that I am not so familiar with assembly language programming.
    If you just explain the working of encryption part, I can figure out the decryption part. Thanks a lot.

    Comment by Bappaditya Mandal — 3 September 2008 @ 1:53 pm

  6. Yes, you were right. encrypting 00112233445566778899aabbccddeeff with 000102030405060708090a0b0c 0d 0e 0f will result 69c4e0d86a7b0430d8cdb78070b4c55a. I tested it on my AES simulator http://jsnerd.googlepages.com/index01a.htm

    you can initialize data and key before invoking encrypting routine. Once you initialize subkey, you can reuse it as many as poosible till you choose new cipher key.

    If that the case, i’ll give you an example. use this piece to replace “Encrypting Routine” below org 0x00 up to decr routine.

    ;===============================================================================
    ; Program Main Entrance
    ;===============================================================================
    org 0x00

    ;===============================================================================
    ; Test Vector
    ;===============================================================================
    test ; key initialization
    movlf k0,0x00
    movlf k1,0x01
    movlf k2,0x02
    movlf k3,0x03
    movlf k4,0x04
    movlf k5,0x05
    movlf k6,0x06
    movlf k7,0x07
    movlf k8,0x08
    movlf k9,0x09
    movlf k10,0x0a
    movlf k11,0x0b
    movlf k12,0x0c
    movlf k13,0x0d
    movlf k14,0x0e
    movlf k15,0x0f

    ; plain text initialization
    ; now s0:s15 contain plain text
    movlf s0,0x00
    movlf s1,0x11
    movlf s2,0x22
    movlf s3,0x33
    movlf s4,0x44
    movlf s5,0x55
    movlf s6,0x66
    movlf s7,0x77
    movlf s8,0x88
    movlf s9,0x99
    movlf s10,0xaa
    movlf s11,0xbb
    movlf s12,0xcc
    movlf s13,0xdd
    movlf s14,0xee
    movlf s15,0xff

    ;initialize subkey buffer
    call ksch

    ; encrypt plain text
    ; after this, s0:s15 contain cipher text
    call encr

    nop

    ; decrypt plain text
    ; after this, s0:s15 contain plain text again
    call decr
    goto $

    ;===============================================================================
    ; Encrypting Routine
    ;===============================================================================
    init call ksch
    nop

    encr clrf fsr0l
    movlf fsr0h,0x01
    clrf tblptru
    movlf tblptrh, HIGH(tsbox)
    movlf lcnt,0x09
    encra call subrow
    call mixcol
    decfsz lcnt,f
    bra encra
    call subrow
    call addrnde
    return ; encryption ends here

    decr movlf lcnt,0x09
    movlf fsr0l,0xaf
    movlf fsr0h,0x01
    call addrndd
    call isubrow
    decra call addrndd
    call imixcol
    call isubrow
    decfsz lcnt,f
    bra decra
    return ; decryption ends here

    Comment by edipermadi — 3 September 2008 @ 4:02 pm

  7. Thanks for your valuable guidance.
    I have created the test vector as you have suggested in the existing code.
    I initialize the key using:

    ;initialize subkey buffer
    call ksch

    then call the encryption function:

    ; encrypt plain text
    ; after this, s0:s15 contain cipher text
    call encr

    nop

    After this statement how do i check in MPLAB SIM, that the values of s0:s15 have reached the encrypted (cipher) text?
    Thanks a lot for this immense help.

    Comment by Bappaditya Mandal — 3 September 2008 @ 4:24 pm

  8. Hi, Today i selected language toolsuit at
    C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe
    without modifying anything of ur code it gave the following errors. It seems the Sbox and Inverse Sbox Lookup Table cannot be loaded even in assembly language. Pls help me why I am getting this error:

    Clean: Deleting intermediary and output files.
    Clean: Deleted file “C:\D\Crypto\aes\aes-pic18F4550.mcs”.
    Clean: Done.
    Executing: “C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe” /q /p18F4550 “aes-18f4550.asm” /l”C:\D\Crypto\aes\aes-18f4550.lst” /e”C:\D\Crypto\aes\aes-18f4550.err” /o”C:\D\Crypto\aes\aes-18f4550.o”
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 940 : Operand contains unresolvable labels or is too complex
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 941 : Operand contains unresolvable labels or is too complex
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 959 : Operand contains unresolvable labels or is too complex
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 977 : Operand contains unresolvable labels or is too complex
    Halting build on first failure as requested.
    BUILD FAILED: Thu Sep 04 11:21:35 2008

    Thanks!

    Comment by Bappaditya Mandal — 4 September 2008 @ 10:09 am

  9. Hmmm..

    I suggest you to remove all files and take the “.asm” one and try to start a new project.

    don’t forget to confogure the processor to PIC18Fxxxx that compatible with PIC18F4550.

    I’m wondering about this problem too. i coded, simulated and tried this code many times without any errors. Just make sure you set up everything properly

    Comment by edipermadi — 4 September 2008 @ 12:54 pm

  10. yes, i have started a new project now just compiling only ur code:
    I think there is soem problem with ur table definition:
    ;===============================================================================
    ; Sbox and Inverse Sbox Lookup Table
    ;===============================================================================
    org ($+0xff)&~0xff ; force page alignment
    tsbox equ $

    here it gives the error:
    Clean: Deleting intermediary and output files.
    Clean: Done.
    Executing: “C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe” /q /p18F4550 “aes-18f4550.asm” /l”C:\D\Crypto\aes\aes-18f4550.lst” /e”C:\D\Crypto\aes\aes-18f4550.err” /o”C:\D\Crypto\aes\aes-18f4550.o”
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 940 : Operand contains unresolvable labels or is too complex
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 941 : Operand contains unresolvable labels or is too complex
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 959 : Operand contains unresolvable labels or is too complex
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 977 : Operand contains unresolvable labels or is too complex
    Halting build on first failure as requested.
    BUILD FAILED: Thu Sep 04 14:21:08 2008

    can u pls check the
    org ($+0xff)&~0xff ; force page alignment
    tsbox equ $

    Thanks for your reply.

    Comment by Bappaditya Mandal — 4 September 2008 @ 1:05 pm

  11. OK, i see the problem

    lets try this:

    1. change “org ($+0xff)&~0xff” with “org $” -> apply to both tsbox and tisbox.

    2. if you find initialization script that use “tsbox” and “tisbox”, please change it to “high(tsbox)” and high(tisbox)”

    hopefully it works,

    Comment by edipermadi — 4 September 2008 @ 1:13 pm

  12. Thanks.
    with “org $” it is giving the same error.
    They are already defined as:
    high(tsbox) and high(tisbox)

    Will there be any problem with memory allocation using:
    “org ($+0xff)&~0xff”

    Comment by Bappaditya Mandal — 4 September 2008 @ 1:20 pm

  13. I am only getting these four errors:
    (a) org $ ; ($+0xff)&~0xff ; force page alignment

    (b) tsbox equ $

    (c) tisbox equ $

    (d) get4 equ $

    as:
    Clean: Deleting intermediary and output files.
    Clean: Done.
    Executing: “C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe” /q /p18F4550 “aes-18f4550.asm” /l”C:\D\Crypto\aes\aes-18f4550.lst” /e”C:\D\Crypto\aes\aes-18f4550.err” /o”C:\D\Crypto\aes\aes-18f4550.o”
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 940 : Operand contains unresolvable labels or is too complex
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 941 : Operand contains unresolvable labels or is too complex
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 959 : Operand contains unresolvable labels or is too complex
    Error[151] C:\D\CRYPTO\AES\AES-18F4550.ASM 977 : Operand contains unresolvable labels or is too complex
    Halting build on first failure as requested.
    BUILD FAILED: Thu Sep 04 14:44:17 2008

    Rest all portions of ur code are fine.

    Comment by Bappaditya Mandal — 4 September 2008 @ 1:27 pm

  14. Now, all the above problems are solved.🙂
    When I reinitialize the key with the code that u have provided it gives an error:

    Warning[206] C:\D\CRYPTO\AES9\AES-18F4550.ASM 293 : Found call to macro in column 1. (movlf)
    Error[113] C:\D\CRYPTO\AES9\AES-18F4550.ASM 264 : Symbol not previously defined (×00)
    Error[112] C:\D\CRYPTO\AES9\AES-18F4550.ASM 264 : Missing operator

    Please refer to ur reply 6. Thanks a lot. I am not able to change the key and data.

    Comment by Bappaditya Mandal — 4 September 2008 @ 4:01 pm

  15. Hmm, let me triple check my code. Probably there is something wrong in my code. I’m using MPLAB v8.0.

    I’ll post the result soon.

    Sorry for the inconvinience,,

    Comment by edipermadi — 4 September 2008 @ 4:05 pm

  16. leave your email address to email:
    “my nickname” on google mail.

    Comment by edipermadi — 4 September 2008 @ 4:08 pm

  17. Thanks a lot for all ur efforts.
    All things are ‘atleast running’ properly as I expected.
    Now there is a fundamental problem in ur code:
    with example that ur have given:
    ; Encryption Benchmark:
    ; Plain Text = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ; Key = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ; Cipher Text = 66 e9 4b d4 ef 8a 2c 3b 88 4c fa 59 ca 34 2b 2e
    ;
    ; Encryption Benchmark:
    ; Cipher Text = 66 e9 4b d4 ef 8a 2c 3b 88 4c fa 59 ca 34 2b 2e
    ; Key = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ; Plain Text = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    This example works fine.

    However, with mine example (comment 5) the encryption works. The decryption gives wrong result:
    the decrypted data text is: 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0.
    and not:
    00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff.
    I will check with other examples too…

    Comment by Bappaditya Mandal — 4 September 2008 @ 4:43 pm

  18. my email id is bappadityamandal inside gmail. I have already send u an invitation and email.

    Comment by Bappaditya Mandal — 4 September 2008 @ 4:49 pm

  19. Hey, I would be really interested in seeing you implement this on a dsPIC30F chip and see how fast you could get it. The chip has a lot of the built in instructions that you do macros for and with the dsp on board you should be able to take advantage of the matrix math instructions.

    BTW I liked the enigma implementation on the pic 16f.

    Comment by Jason — 16 December 2008 @ 6:00 am

    • hmm, nice idea. i’ll consider your suggestion, porting AES implementation to dSPIC platforms. thank you for visiting my blog

      Comment by edipermadi — 16 December 2008 @ 8:51 am

  20. Hi
    I have a problem with this code, because of your mapping. all datas defined for the spesial place on the ROM and RAM.
    I’m using interrupts in my code, but to impliment this code is a problem.
    do you have some ideas or C code?
    thank you

    Comment by nikos — 18 March 2009 @ 6:42 pm

    • @nikos:
      hi nikos, the code was initially written as a stand alone program. That was the reason why i hardcoded everything in a special place. If you want to combine this code to another code, just declare lookup table in a certain position that acceptable for both side, for example at the end of memory program, or you could modify linker setting.

      I have not written any C code for AES Implementation in microcontoller, but you can easily port it from AES x86 code. just follow what your micro C compiler said. here is a link of it:

      http://www.martux.org/qemu_old/qemu-0.8.2-solaris__20061010x11/aes.c

      OK, good luck

      Comment by edipermadi — 19 March 2009 @ 9:40 am

  21. For those with error:
    Operand contains unresolvable labels or is too complex

    Goto Project – Build options – MPASM/C17/C18 Suite Tab

    and select GENERATE ABSOLUTE CODE

    Then the asm will compile

    Regards Edipermadi!!

    Comment by luis — 13 May 2009 @ 2:17 pm

  22. Hi,
    You really did a lot of work on this, thank you so much for making it open source.

    I’m trying to figure out the 256 bit buffered but I’m not sure I understand it.

    When I manually change the text in RAM locations 10 to 1F it encrypts then decrypts. But then what is S0:S15 for? The header of the .asm file says these are “16 bytes of input”. I don’t know what input means? The input text is in RAM locations 10 to 1F, aren’t they? Then the key is in program memory locations K0 to K31? I want to implement this so a C program can de-crypt it. I’m using ccrypt, it’s an open-source command line tool. I want to change the key to all printable characters so I can compare the answers from each.

    Comment by Tom — 9 September 2009 @ 7:06 am

    • @Tom:
      well, in encrypting mode, s0:s15 is actually the input where you put the plaintext and it is also the ciphertext after the process is completed. In decrypting model, s0:s15 is the input of cipher text and it will be the plain text after decrypting process.

      To monitor the process you may add some feature to print data in each steps in hexadecimal.

      Comment by edipermadi — 17 September 2009 @ 10:18 am

      • Thanks again! I was able to simulate the same conditions using openssl in UNIX. I made a file with the test case of 16 bytes of zeros called 0s_input.bin, then ran the following command:

        openssl enc -aes-256-cfb -nosalt -K 00000000000000000000000000000000000000000000000000000000000000 -iv 00000000000000000000000000000000 -in 0s_input.bin -out crypt.txt

        The output of crypt.txt matched the test case you provided in the comments!

        Comment by Tom — 27 September 2009 @ 4:46 am

  23. Hi,

    Thanks for your nice codes.

    I’m trying to implement this code as a relocatable object. I have problems to properly implement the tsbox and tsibox tables. Could you please help me resolve that?

    Best Regards,
    abbas

    Comment by Abbass — 4 November 2010 @ 6:36 pm

    • Hi. thank you for visiting my blog.

      I actually havent try to make it relocatable. I fixed the table position 256 bytes boundary for the sake of simplicity. please consult topics about creating lookup table on arbitrary position as well as its dereferencing issue. you may require additional arithmetic for address calculation if you make it relocatable.

      Comment by edipermadi — 4 November 2010 @ 11:18 pm

  24. Hello Edipermadi,

    Thank you for the encryption programs. I am having a problem with version 6.2 (PIC18F4550): I changed k0 to 0x01 (by writing bsf k0,0 just after org 0x00). Encryption result is the same as with version 3.1 (with data in s0 to s15 all zeros). However, in version 6.2 (buffered), after decryption, s0 now containts 0x01 (as opposed to 3.1, unbuffered). I did some more tests with other keys, and it seems that, after decryption, the first 16 bytes of key are in s0 to s15. After doing encryption and decryption once more (and after every second encryption/decryption cycle), s0 to s15 contain zeros again. I use MBLAB SIM integrated in MBLAB v. 8.10. Can you confirm this behaviour, or am I doing something wrong … ?

    regards,

    Steffem

    Comment by Steffen Hofmann — 3 January 2011 @ 10:26 pm

  25. I see comment 17 is about this, too; After decryption, the original plain text seems to appear xore’d with the first 16 key bytes …

    Comment by Steffen Hofmann — 3 January 2011 @ 10:35 pm

    • @ Steffen :

      I already identified the bug. I can reproduce what you get. Please use v6.3 for the latest update.

      Comment by edipermadi — 5 January 2011 @ 7:32 am

      • Thank you for your efforts ! Sorry for the late answer

        Comment by Steffen — 5 February 2011 @ 6:10 am

  26. Any idea how many cycles / How long to Encrypt and decrypt AES256 packets on the 18F platform?

    Comment by PosterC — 24 February 2011 @ 5:54 pm

    • i did a small bechmark for AES-256 on PIC18F micros. the result is as following:

      Key Setup = 1409 cycles
      Encryption = 3721 cycles
      Decryption = 5271 cycles

      Comment by edipermadi — 1 March 2011 @ 6:59 pm

  27. Nice to see your work. I implemented AES128 for the PIC10F,PIC16F and dsPIC/PIC24F/H series. PIC10 and PIC16 is only 440 bytes (encrypt) and executes in 8270 cycles on a PIC10. dsPIC executes in 2880 cycles and is below 1K for all code. All with key-scheduling, so no lookup tables !.🙂.

    Comment by Paul — 5 March 2011 @ 4:15 pm

  28. Hi everyone,
    I want to send a fixed length data from hyperterminal to PIC18F4550 via usb port of the computer and then I want to encrypt this data in PIC18F4550 and then send back to hyperterminal. I am new in PIC programming and I have a project about this PIC in university.Since now, I just could set the communication between the PIC and computer via USB port.
    Could you help me about this?
    Thanks a lot,

    Comment by aykut yıldırım — 18 March 2011 @ 6:50 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: