Jump to content
  • entries
  • comments
  • views

AES-128 on the Propeller



One of the knocks against the Propeller is it has no code protection, unlike PICs and other microcontrollers with onboard EEPROMs. And although the protection may be less than perfect, I can understand many companies are not willing to have their IP in an easily accessible state.


IMHO the way to remedy the situation is to include a small amount of onboard OTP storage for an encryption key and integrate a decryption routine into the bootloader. But for that to work someone (i.e. me) needs to code up the crypto routines. So I've been learning all about AES and working out how to code the routines in Propeller Assembly.


I've coded up a first attempt at the encryption routine and it's surprisingly compact - less than 1K. I've done some cycle counting and it's over 14K cycles per 128 bit block! At 80MHz that works out to 88K per second, so that's not too bad as far as load time is concerned, adding less than a half a second for 32K. The biggest time sync is the combined ShiftRows + SubBytes routine which has to do a table lookup for each byte and reorder the bytes in the four 32 bit columns at just under 1K cycles for each round, and there are 10 rounds per block.


And although crypto sounds big and scary, it's actually not that complex. The toughest part is keeping the byte order straight when reading the spec! (Like the 4 bytes which make up the 32 bit column are shown as [a0 a1 a2 a3], where a0 is the LSB!) AES breaks down into four or so main subroutines (SubByte which does a table lookup, ShiftRows which mixes bytes between words, MixColumns which does a matrix multiply on each column, and a routine to do a polynomial multiply by 2). The parts which operate on the 32 bit columns are easy on the Propeller, but the byte operations are painful!


My next step is to wrap the code in something I can use to view the results then start going through the sample data and make sure everything works.


Recommended Comments

Drat. I just figured out that Cipher Feedback mode (aka CFB) fails horribly if the plaintext of the first block is known.


CFB mode works by encrypting an Initialization Vector, then XORing it with the plaintext block to produce the ciphertext block. The resulting ciphertext block is then encrypted and XOR'd with the next plaintext block to produce the second ciphertext block. And so on. The big advantage is decryption re-uses the encryption routine.


But say you have a case where the first plaintext block and the ciphertext block are both known. (Not unrealistic as the first block is often a well defined header.) Then it's possible to determine the encrypted IV and use that to create the first ciphertext block for an arbitrary plaintext. So there's a slight possibility an attacker could create an arbitrary first block which would contain enough code to beep out the encryption key.


Cipher Block Chaining mode (aka CBC) should defeat this because the plaintext of the first block is "behind" the encryption. So even if you have a known plaintext all you can do is generate the same ciphertext. The disadvantage is CBC mode requires the decryption routine.

Share this comment

Link to comment

Using the GEAR emulator I've confirmed the Key Expansion routine generates the correct output (and takes 4K+ cycles). Found two bugs and one optimization. Next I get to start tracing through the cipher routine. Thank gods for the NIST example data which shows the data at each step.


One more bug and SubBytes + ShiftRows done. MixColumns + AddRoundKey is next. I just ran it and it fails. Sigh...


It's working. Two more bugs squashed. Now I need to work out the Inverse Cipher routine. (Similar, but different and slightly more complicated, and may not optimize as nicely.)


Each of the bugs has been fairly simple:

1. SHR instead of SHL to multiply by 2

2. AND #4 instead of AND #3 for MOD 4

3. ADD #3 instead of ADD #5 when I wanted to add 4 then add 1.

4. MOVD instead of MOVS (update destination rather than source)

5. ROL instead of ROR


So, not logic problems per-se. More like typos. Do what I mean, not what I say.

Share this comment

Link to comment

To be sure, using CFB means that someone can create an image with any desired first block. So what? Design the boot loader so that the first block won't be stored anyplace and then the first block could be filled with 128 bits of random garbage.

Share this comment

Link to comment

In actual fact, the first 16 bytes of the Propeller binary image don't appear to contain any code. However, I'd rather avoid any chance that someone could figure out a way to embed code in those 16 bytes.


I'm just surprised that the literature I've read doesn't indicate this weakness. For Output FeedBack (OFB) mode where only the encrypted IV is used as the input to the next Cipher function, the lit indicates if the plaintext for any block is known then the ciphertext for any arbitrary plaintext can be generated for that block. Generating new IVs for each message is supposed to address this issue, but for my environment the IV is either static (stored onchip) or stored with the code (and therefore subject to duplication/reuse). CBC mode does away with the known plaintext risks by putting the plaintext behind the Cipher function.

Share this comment

Link to comment
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...