The Hardware Side of Cryptography

8 July 2008

1200 bps AES-128 Serial Encryptor

Filed under: encryption — Tags: , , , , , , , , — edipermadi @ 2:07 pm

AES-128 is a common block cipher used in cryptography. AES-128 encrypt 128-bit plain text becoming 128-bit cipher text with 128-bit key supplied. AES-128 consists of 10 rounds non-feistel cipher. Each of that rounds are being supplied by subkeys generated from cipherkey.

Here, as my first embedded cryptography experiment, I’m trying to implement simple RS232 serial encryptor using AES-128 block cipher on PIC16F84 microcontroller flatform. The goal is about creating secured serial communication. Here, i’ve got couple things to do. First, is about modifying AES-128 block cipher becoming stream cipher and the second one is about embedding the cryptographic function itself.

This project is originally designed for 1200 bps serial transmission. See, I just tought that 1200 bps is really slow, so i decided to speed it up into 9600 bps.

See this picture below, it describes more than words.

The picture above is the concept of modifying AES-128 block cipher into stream cipher. But wait, why we have to do such this thing? The answer is that RS232 transmit everything byte by byte therefore we need byte stream encryptor, but how can we do this? The answer is easy. Here i just use standard AES-128 encryption routine to generate 128-bit random vector. The random vector is just the cipher text of IV1 and IV2. IV1 acts as a plain text and IV2 as cipher key. So here we have couple IV values to initialize.

Next, the last subkey generated from previous step is propagated to the current random vector generating process as its IV2 and its IV1 was taken from previous random vector. Each generated random vector will encrypt 16 bytes of plain text byte by byte. Here we can conclude that random vector will generated after 16 bytes of data were encrypted.

Since generating random vector takes 3850 cycles (approximately 3850us when we use 4MHz crystal), we need such delay between 16 bytes of data to resynchronize the encryptor.

[16 bytes of data] [delay] [16 bytes of data] [delay]

After i finished modyfying AES, i tried to wrote the code for microcntroller itself. I wrote the code on MPLAB v8.0 and simulate it using Oshon Soft PIC Simulator IDE and it works. See this screenshot below.

The screenshot above simulates this setting:

IV1 = 00000000000000000000000000000000
IV2 = 00000000000000000000000000000000
pt0 = 00000000000000000000000000000000
ct0 = 66e94bd4ef8a2c3b884cfa59ca342b2e
pt1 = 00000000000000000000000000000000
ct1 = 40527d2f2d1fafb4d326b0f8f93a58e1
pt2 = 00000000000000000000000000000000
ct2 = ae08e8d98ee3cb0e595e64f8cfe7f609
pt3 = 00000000000000000000000000000000
ct3 = 8e4ddc08cb5d0ac7a4ac041cc9819610

Mathematically speaking,

IV1[0] = IV1
IV2[0] = IV2
IV1[n] = RV[n-1]
IV2[n] = Last Subkey of IV2[n-1]
RV[n] = AES_128_Encrypt(IV1[n],IV2[n])
CT[n] = PT[n] XOR RV[n]

After code verified, i downloaded the code into PIC16F84 microcontroller using ICProg, PIC ICSP Programmer and PIC16F84 development board from Innovative Electronics bought couple months ago. I operated my PIC16F84 microcontroller at 4MHz and 9600 bps serial transmission. The schematic is basically easy. You jusy use RA0 as RS232 Tranmitting port (TX) and RA1 as receiving port (RX). You may use any TTL to RS232 converter, here i just used the simplest onešŸ™‚ . See Pictures Below

PIC ICSP Programmer


PIC16F84 Development Board (Front)

PIC16F84 Development Board (Back)

RS232 Cable

Cheap Adaptor

After everything plugged properly and RS232 cable connected from microcontroller to PC, i tested the circuit using RS232 Terminal Viewer integrated on Oshon PIC Simulator IDE and it works the same as simulation. To use this encryptor, first you have to send 32 bytes of data to initialize the microcontroller. The first 16 bytes is used to initialize IV1 and second one to initialize IV2. After that, you may dump data as much as you want and dont forget to give somewhat 50 ms delay on each 16 bytes transmission. Nice huh! see the screenshot below.

Encrypted RS232 Result Screenshot (taken form RS232 COM1 terminal)

Last, I realized that 50 ms delay requirement on each 16 bytes of data is somewhat annoying and sucks. If you want to eliminate such this delay, please rock the microcontroller up to 20 MHz and down the speed to 1200 bps, so that the required delay is equal to one bit propagation (approximately 1/1200) which is OK. Hopefully that way removes problem from your application and removes headache from yourselfšŸ™‚ .

Codes here are released for free under the term of GNU Public License v3.0. This program comes with no guarantee at all. Take you own Risk and please write some comments or mail me for some feedbacks.


AES-128 Serial Encryptor Source Code | v1.0 | v1.1
PIC16F84 Datasheet
Mid-RangeĀ Reference Manual
AESĀ Publication (fips-197)
MPLAB v8.0

Wikipedia Advanced Encryption Standard
Wikipedia Vincent Rijmen
Wikipedia Joan Daemen
Various TTL to RS232 Connection

Official Website:
Advanced Encryption Standard
Innovative Electronics
Oshon Soft

AES (Rijndael) Simulator


  1. Is this AES in counter mode?

    If the PIC is encrypting and a Java program on a PC is decrypting, then what parameters are needed to setup the decrypt?

    thanks for sharing your pic stuff!

    Comment by robert — 8 August 2008 @ 8:56 am

  2. Yeah, i guess so. This cipher is working in “modified” counter mode.

    I used Counter Mode AES-128 to produce random vector to whiten plain text. In addition whitening using XOR is reciprocal i.e

    C = A XOR B
    A = C XOR B

    If you wish to use Java as decryptor, you only need to emulate how this microcontroller works.

    Prior to paraameters, you initialize both two IVs which are IV1 and IV2. IV1 works as Initial Value and IV2 works as cipher key. Both IV1 and IV2 must be sent at the beginning of transaction till you set another cipher key so that both of side are synchronized. In Addition Random Vector Is Produced as follow

    RV = AES_encrypt(IV1, IV2)
    CT = PT XOR RV
    PT = CT XOR RV

    prior to “last Subkey”, please refer to my Rijndael Simulator. The last subkey is actually the subkey used on the last round.


    Comment by edipermadi — 8 August 2008 @ 10:31 am

  3. I’m not sure I totally understand what you did. I need to use AES to encrypt RS232 data channel from PC to microcontroller (and back). The data stream may be slow at times (bytes per second) and very intermittent (bursts of more data of variable length). There may only be one or two bytes at a time and I cannot wait for 16 bytes. Is there a good way to do it byte-by-byte or at least smaller than 16 bytes?

    Comment by GB — 20 December 2008 @ 2:03 am

    • yeah, i do agree with you. yes, it is possible to remove such that delay, by escaping the wait of 16 bytes incoming data. Thanks a lot for visiting my blog and for your suggestion. i’ll modify my code soon.

      Comment by edipermadi — 22 December 2008 @ 9:16 am

  4. I noticed this interesting solution to the “length” problem.

    Comment by GB — 20 December 2008 @ 2:29 am

    • wow, nice site. but i could not figure out the solution

      Comment by edipermadi — 22 December 2008 @ 9:10 am

  5. Hi.
    I like your work, thanks. I need to implement wireless communication to an electronic lock. I want to send a lock or unlock command encrypted using AES-128. But I want to make sure I won’t be subject to man in the middle or replay attacks. So I know my ciphertext needs to be different for each new lock or unlock request. Can I do this with your AES stream cipher? Ideally, I would not have to resend the keys to the receiver each time. So I want to be able to program the transmitter and receiver initially with a shared secret, and then just vary the initial random vector? Thanks.

    Comment by Jeff B. — 10 March 2009 @ 1:12 am

    • @ Jeff B. :
      thank you jeff. for sure you can use that concept. the most important thing is to synchronize encryptor and decryptor side. gradually you can step to modifying initial vector so that the generated cipher is varying along each transmission. there must be a way to resynchronize both side also. good luck

      Comment by edipermadi — 10 March 2009 @ 9:54 am

  6. Edi,
    Here is what I envision. Please tell me if you think this would be secure. All communications are in 16 byte blocks. For example to lock the lock, First sender PIC_A would wirelessly transmit a plaintext 16 byte block which contains the request to lock command. Secret IV2 is agreed upon in advance by both sender PIC_A and lock receiver PIC_B. Receiver PIC_B recognizes this command, and then generates two random 16 byte vectors. One is used as IV1 and the other is used as the plaintext of the response message. AES-128 is performed using the shared secret IV2, and then the ciphertext is sent back wirelessly in response to the sender PIC_A. Sender PIC_A then decrypts the ciphertext using the agreed upon IV2 key, and extracts the plaintext random vector originally generated at PIC_B. Sender PIC_A then generates its own random 16 byte vector, and that is used as IV1 to re-encrypt the plaintext random vector as a response. Receiver PIC_B then decrypts with its IV2 key and verifies that plaintext sent from PIC_A contains its original random vector that it had sent. If so, then unlock command is issued, and lock opens, and a plaintext response is sent indicating success. If not, plaintext response is sent indicating failure.

    Does this make sense? I want to make sure that there can be no replay attacks. I only a need a one or two byte command/ response for each communication, but I need them to be secure. AES-128 as you have implemented it seems ideal fro my application, but I am still trying to wrap my head around how AES works and make sure that I am not missing something in generating a secure request response protocol using random vectors.

    I have my wireless serial code all working between two PICs, and so all I need is to overlay the AES on top, if my above methodology is correct. Thanks again.

    Comment by Jeff B. — 10 March 2009 @ 3:43 am

    • @ Jeff B. :
      hmm nice.. it make sense. the security is rely on secret IV2. i guess, it is better if you also have another algorithm to exchange IV2 so that secret IV2 can be modified securely.
      good luck

      Comment by edipermadi — 10 March 2009 @ 10:08 am

  7. Edi,

    Would you be willing to do a text chat with me briefly to answer a few questions about AES? I don’t fully understand the randomness of your initial vector, and synchronizing both sides. I have the need I mention above. I’m not too worried about IV2 security in that this is a very short Infrared link where it would generally be pretty easy to make sure the initial secrets were set securely without any middle men.

    I’d be happy to pay you a few $$$ via PayPal for your efforts, I am close to understanding it all, but need a little push to figure out the remainder. Also, if you happen to have any of the AES algorithm’s in C, that would be very nice. I like the ASM for the speed, but now do most of my firmware in C.

    Thanks, Jeff

    Comment by Jeff B. — 24 March 2009 @ 3:19 am

  8. It seems like it might be possible to use your stream algorithm so no initial keys need be exchanged, but not sure if that would work.

    I don’t really care how I implement as long as it is methodologically secure. Since I only need to send a few bytes at a time, I worry that a middle man could do a replay of the 16 bytes in the stream cipher that would give rise to a response. Since I would always be sending roughly the same command, but with some random vector, it would then hinge on the randomization algorithm, which appears to simply be a run through AES with some random initial plaintext.

    Thanks, jeff

    Comment by Jeff B. — 24 March 2009 @ 3:25 am

  9. @Jeff:
    Sorry for replying you so late. I have no daily internet accessšŸ˜€ .

    I have some remarks, hopefully it would help:
    1. IV1 and IV2 were set in the first use of cipher.
    2. IV2 is just the inner state of AES, so it will keep changing while you generate some random vector
    3. For reply attack, it will just disturb the synchronization. since IV2 it modified automatically one a random vecter has produced.
    4. It is also good to make sure that there was no packet loss, since of transmitted packet will be ciphered by IV2 which is changing on every random vector generating process.

    Please mail me for further question. i’ll try my best to help you.

    Comment by edipermadi — 25 March 2009 @ 10:52 am

  10. where can I read about microcontroller in your blog?! I have searched about the word ā€œatmel microcontrollerā€ and you blog appeared to me

    Comment by microcontroller — 30 March 2009 @ 2:56 pm

    • @anonymus :
      Hi. this blog is about programming crypto in microcontroller. so there is no any explicit tutorial about microcontroller

      Comment by edipermadi — 30 March 2009 @ 3:16 pm

  11. One thing I’d prefer to say is the fact that car insurance cancelling is a terrifying experience and if you are doing the correct things being a driver you will not get one. Lots of people do have the notice that they’ve been officially dropped by their particular insurance company and many have to struggle to get supplemental insurance following a cancellation. Inexpensive auto insurance rates usually are hard to get from a cancellation. Understanding the main reasons pertaining to auto insurance cancellation can help people prevent burning off one of the most important privileges available. Thanks for the suggestions shared by your blog.

    Comment by Rudolf Holowell — 30 June 2011 @ 5:40 am

RSS feed for comments on this post. TrackBack URI

Leave a Reply

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

You are commenting using your 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

%d bloggers like this: