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.
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.
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.
I have tried following your instructions.
Terminal output is here:
http://thomasdamgaard.dk/paste/P1353.html
I get throughput of only ~4-5mb/s. Something must be wrong.
I have not tried with a new kernel, yet. I hope I don't have to.
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.
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.
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?
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?
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?
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.
Ok.
Do you have any ideas on how I can debug why I get so bad performance?
Should I report it as a bug? If so, where would be the appropriate place to report it?
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?
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. 😀
Although ESSIV is not as fast. About 15 MB/s.
Congrats! What kernel version are you running now? If I remember correctly, your previous system was only 2.6.24.
Linux syrah 2.6.26-2-486 #1 Thu May 28 15:10:18 UTC 2009 i586 GNU/Linux
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.
Maybe. I don't know. I have reinstalled the box and I have not saved the old system, so I cannot investigate it.
I think there is missing an 's' at the end of this command: rmdir /tmp/tmpf
Thanks. I've fixed it.
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?
I hadn't any success with this, because I didn't want to patch so much packages.
Hi,
I found an easy & working solution to use geode aes on amd processors with openssl in userspace here:
http://carnivore.it/2011/04/23/openssl_-_af_alg
No kernel patches, openssl patches, openssh patches required.
Installation is simple, works like a charm
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
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.
I'm sorry. I don't own the ALIX anymore.
No problem, thank you anyway.
BTW you have a nice and helpful blog;)