Using Geode's AES engine on ALIX.3D3

The AMD Geode LX800 CPU has an on-chip AES 128-bit crypto accelerations block and a true random number generator. Using this block for encryption and decryption is a lot faster than software implemented algorithms and it unloads the CPU. There are two main purposes where en/decryption is needed:

  • Storing files
  • Communication over network (IPSEC, OpenVPN, WPA2, ...)

I'll focus on the first point in this article using LUKS (Linux Unified Key Setup).

To use LUKS and the crypto block, some kernel adjustments have to be made:

Device Drivers  --->
   [*] Multiple devices driver support (RAID and LVM)  --->
   <*>   Device mapper support
   <*>     Crypt target support

-*- Cryptographic API  --->
   -*- Cryptographic algorithm manager
   -*- CBC support
   {*} ECB support
   {*} AES cipher algorithms
   <*> AES cipher algorithms (i586)
   -*-   MD5 digest algorithm
   <*> SHA224 and SHA256 digest algorithm
   [*] Hardware crypto devices  --->
   <*>   Support for the Geode LX AES engine

If you want to test with and without crypto acceleration, I recommend compiling the last one as a module. After compiling and rebooting we have to install LUKE userspace tools:

emerge -v cryptsetup

That's all. Now we're ready to test. As we want to bandwidth limitation from a slow CF card or USB stick, we create a memory loopback device for testing purposes with a size of 128 MB:

mkdir /tmp/tmpfs
mount -t tmpfs none /tmp/tmpfs -o size=130m
dd if=/dev/zero of=/tmp/tmpfs/test.img count=131072 bs=1024
losetup /dev/loop1 /tmp/tmpfs/test.img

The tmpfs ramdisk is with intent 130MB large, as the maximum default value is 50% of RAM and with that 128 MB wouldn't fit in.

At first, we want to measure software AES performance. For this, we have to assure, that the driver for the crypto block is not loaded. You can get a list of all loaded modules with

lsmod

If there's geode_aes listed, remove it by

rmmod geode_aes

Now we can create a LUKS device by

cryptsetup -y --cipher aes --key-size 128 luksFormat /dev/loop1

Mind the key size of 128 bit as the Geode crypto block is only capable of 128 bit keys. You have to confirm this command with a uppercase YES and entering the passphrase twice:

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase:
Verify passphrase:
Command successful.

Now we can open the container. Run

cryptsetup luksOpen /dev/loop1 test

and enter the previous set passphrase:

Enter LUKS passphrase:
key slot 0 unlocked.
Command successful.

The container is now under /dev/mapper/test and we can do some write test by running dd:

dd if=/dev/zero of=/dev/mapper/test bs=16384

After a few seconds, dd will terminate, complaining no space left:

dd: writing `/dev/mapper/test': No space left on device
8160+0 records in
8159+0 records out
133689344 bytes (134 MB) copied, 18.574 s, 7.2 MB/s

That's OK. We can read here there 7.2 MB/s throughput with crypto block. After closing the container with

cryptsetup luksClose test

we can load the crypto block driver by

modprobe geode_aes

and can run the same commands as above. We'll get a

dd: writing `/dev/mapper/test': No space left on device
8160+0 records in
8159+0 records out
133689344 bytes (134 MB) copied, 4.88397 s, 27.4 MB/s

noticing that we've got a 27.4 MB/s throughput now! This also works with ESSIV as well. It's a bit slower, but more secure. You can to alter the luksFormat to use it:

cryptsetup -y --cipher aes-cbc-essiv:sha256 --key-size 128 luksFormat /dev/loop1

I measured 7.0 MB/s without and 24.0 MB/s with crypto block. After all testing don't forget to remove the loopback device and umount the ramdisk:

losetup  -d /dev/loop1
umount /tmp/tmpfs/
rmdir /tmp/tmpfs

Now you can setup your real crypto disk. You might want to initialize your partition with random data before creating the luksContainter. dd is once again your friend:

dd if=/dev/urandom of=/dev/XXX bs=1M

Concerning the use of the crypto block for network encryption: By chance it noticed that if I use WPA2 with AES the geode_aes has a 2 in the used row of lsmod:

Module                  Size  Used by
lib80211_crypt_ccmp     4808  2
ipw2200               115904  0
libipw                 22792  1 ipw2200
geode_aes               5464  2
lib80211                4568  3 lib80211_crypt_ccmp,ipw2200,libipw

So it seems, like WPA2 is using this as well. If you know a method to confirm this, let me know.

26 thoughts on “Using Geode's AES engine on ALIX.3D3

  1. Hi

    I have a fit-PC with the Geode AES Engine.
    I have tried following your guide, but I see no speed up.

    I have pasted the output from the terminal here:
    http://thomasdamgaard.dk/paste/P1310.html

    As you can see the speed is about 5.5MB/s both with and without geode_aes loaded.

    I also tried to use ESSIV, but as you can see at the bottom of my paste, this failed.

    Output from dmesg while doing the above is pasted here:
    http://thomasdamgaard.dk/paste/P1311.html

    I hope you have some ideas on how to fix this. I have tried various IRC channels and forums without any luck.

    Feel free to contact me by e-mail, if you like. I would appreciate any help very much.

    Thanks.

    PS.
    My kernel is:
    Linux fette 2.6.24-24-generic #1 SMP Wed Apr 15 15:54:25 UTC 2009 i586 GNU/Linux
    I use Ubuntu Hardy.

  2. Try to look at "lsmod" when testing, if there's a number > 0 in the used column.

    Also, try to install a recent kernel (2.6.29.4). If there's no package for Ubuntu Hardy, you'll get in on kernel.org.

  3. I have also tried using essiv.
    I cannot even create a luks device with essiv when the geode_aes module is loaded:
    http://thomasdamgaard.dk/paste/P1354.html

    I get this error when trying:
    Failed to setup dm-crypt key mapping.
    Check kernel for support for the aes-cbc-essiv:sha256 cipher spec and verify that /dev/loop1 contains at least 133 sectors.
    Failed to write to key storage.

  4. I think I might add, that I have these messages in dmesg:
    [76140.582574] device-mapper: table: 254:1: crypt: Failed to set key for ESSIV cipher
    [76140.582834] device-mapper: ioctl: error adding target to table
    [76140.585445] device-mapper: ioctl: device doesn't appear to be in the dev hash table.

  5. I found this:
    http://www.mail-archive.com/linux-crypto@vger.kernel.org/msg01046.html

    Appearently geode_aes does not support key sizes != 128 bit. So when using sha256 the key size does not match. I tried using md5 as hash:
    http://thomasdamgaard.dk/paste/P1355.html

    Then I do not get the error, I dit before. (Check kernel for support for the aes-cbc-essiv:sha256 cipher spec and verify that /dev/loop1 contains at least 133 sectors.)
    However, throughput is still very small: ~4-5 MB/S.

    Any suggestions?

  6. I wrote in my artikel that only key sizes of 128 bit are supported.

    When you run lsmod there should be geode_aes listed. In the next column there is a number of modules using geode_aes. Is this number >0 when you use for dm device?

  7. In my comment: " June 12th, 2009 at 15:00 | #4", I gave link ( http://thomasdamgaard.dk/paste/P1353.html ) to terminal output from trying just that. The paste contains also output from lsmod. It says:
    [root@fette]~ #modprobe geode_aes [/dev/pts/4 # 510 - 0 - 0 # 0 day 21:02:23 # 1.03 - 0.34 - 0.12]
    [root@fette]~ #lsmod |grep aes [/dev/pts/4 # 511 - 0 - 0 # 0 day 21:03:33 # 0.49 - 0.33 - 0.13]
    geode_aes 7176 0
    aes_i586 33536 2
    blkcipher 8324 2 geode_aes,cbc
    [root@fette]~ #cryptsetup luksOpen /dev/loop1 test [/dev/pts/4 # 512 - 0 - 0 # 0 day 21:03:44 # 0.42 - 0.32 - 0.13]
    Enter LUKS passphrase:
    key slot 0 unlocked.
    Command successful.
    [root@fette]~ #lsmod |grep aes [/dev/pts/4 # 513 - 0 - 0 # 0 day 21:04:12 # 0.25 - 0.28 - 0.12]
    geode_aes 7176 1
    aes_i586 33536 2
    blkcipher 8324 2 geode_aes,cbc
    [root@fette]~ #dd if=/dev/zero of=/dev/mapper/test bs=16384 [/dev/pts/4 # 514 - 0 - 0 # 0 day 21:04:14 # 0.25 - 0.28 - 0.12]
    dd: writing `/dev/mapper/test': No space left on device
    8160+0 records in
    8159+0 records out
    133689344 bytes (134 MB) copied, 33,3845 s, 4,0 MB/s
    [root@fette]~ #cryptsetup luksClose test [/dev/pts/4 # 515 - 0 - 1 # 0 day 21:04:53 # 1.44 - 0.59 - 0.23]
    [root@fette]~ #

    So I guess that the number is 1 after modprobing geode_aes and running cryptsetup luksOpen. However, the performance is not noticeably different.

    About the key sizes: yes, you mention that key size must be 128 bit, but in your suggested command for essiv:
    cryptsetup -y --cipher aes-cbc-essiv:sha256 --key-size 128 luksFormat /dev/loop1
    you use sha256 which gives a 256 bit key and does not work with geode_aes (on my system anyway). Does this work with geode_aes on your ALIX?

  8. Hmm... your modprobe looks OK. The 1 is what I was looking for. No clue why it's so slow 🙁

    The SHA256 worked for me with --key-size 128 IIRC.

  9. I rechecked your commands in your linked file, but everything looks OK. I thought that the problem might be that your loopback is not correctly in RAM. Do you have a swap partition which might be used for that?

  10. I have no swap.

    I have just reinstalled the machine today. I went with Debian Lenny instead of Ubuntu Server 8.04 LTS.

    Now I get much better performance of ~20 MB/s.

    ESSIV also works with sha256 now. 😀

  11. Hmmm... 2.6.24 was released on 2008/01/24 and 2.6.26 on 2008/13/07. But the last changes to geode_aes was made on 2008/01/10, so actually both kernel shouldn't differ in geode-aes support. Maybe the cause for this is somewhere else.

  12. I would be great to provide the AES engine to the OpenSSL (and further to the OpenSSH for example). I had found several outdated howtos on this subject. But all require patching the kernel and the OpenSSL. I tried one without success. Have you any positive results with this?

  13. My system is an ALIX alix6f2 board with Voyage Linux:
    Linux voyage 3.8.5-voyage #1 SMP Sun Apr 14 22:02:05 HKT 2013 i586 GNU/Linux
    CPU: 500 MHz AMD Geode LX800
    DRAM: 256 MB DDR DRAM

    I thank you very very much for your guide - its really great and the only one which is such complete out there (it seems so).

    My test results..

    a) without geode_aes (and NOT using essiv):
    ~ 4.8 MB/s
    b) with geode_aes:
    ~ 17.8 MB/s
    c) with geode_aes and with essiv:
    ~ 15.9 MB/s

    What I haven't done was the kernel part at the beginning can that be the reason why my results differ so much from yours?

    Thanks
    Thomas

  14. Hello,

    This is king of offtopic, but maybe you can help me... I am looking for a unique hardware identifier in a ALIX2D13 that i can use for encrypton, licencing etc.
    I read LX800 datasheet and find out that i could read/write keys into LX800 security block eeprom, however I only can access MSR registers, no eeprom registers.

    Can you provide me some hints how to read/wright cpu eeprom, or alternatively help me find an unique hardware ID in alix?

    Thank you in advance.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.