Hello les Ubunteros,
Sur certaines machines, il existe des modules hardware spécifiques pour chiffrer/déchiffrer les données bien plus rapidement que l'on pourrait le faire en software. C'est le cas par exemple de mon Sheevaplug ou d'autres plug computers (GuruPlug, PogoPlug, ...) ou bien de certaines machines Intel qui introduisent des instructions dans leur instructions set.
Malheureusement, ces modules hardware ne sont accessibles uniquement qu'en Kernel mode, ce qui ne permet pas à l'utilisateur de les utiliser facilement.
Heureusement, il existe depuis environ deux ans, un 'tuyau' qui permet, depuis le user mode, d'accéder au Crypto API du kernel qui lui fera les appels aux modules hardware s'ils existent:
CryptoDev.
Il nous suffit donc de compiler ce driver, de recompiler openssl pour lui indiquer de passer par lui et le tour est joué! 🙂
Voici la marche à suivre. Je pars du principe que j'installe ça sur mon sheevaplug donc je l'ai fait via une connexion ssh, mais cela n'est pas strictement nécessaire.
- On installe screen sur la machine distante, car la recompilation prend un certain temps (adaptez username et host à vos besoins), et on se reconnecte dans un screen.
ssh username@host
sudo apt-get install screen
exit
ssh -t username@host screen -S session_OPENSSL
- On télécharge la dernière version de cryptodev depuis le dépôt Git qu'on extrait dans /opt (adaptez username à votre nom d'utilisateur).
cd /opt
sudo chown -R username:username /opt
wget https://github.com/cryptodev-linux/cryptodev-linux/archive/master.zip
# Unpack downloaded driver
sudo apt-get install unzip
unzip master.zip -d .
cd cryptodev-linux-master/
- On télécharge les linux headers et build-essential pour pouvoir compiler le driver. Ceci signifie qu'il faudra potentiellement recompiler le driver à chaque mise à jour noyau.
sudo apt-get install linux-headers-`uname -r` build-essential
- On compile le driver cryptodev
make
sudo make install
- On ajoute le module à la liste des modules chargés au démarrage
sudo su
echo "cryptodev" >>/etc/modules
exit
sudo depmod -a
- On charge le module dynamiquement (pour ne pas devoir redémarrer et on test si tout s'est bien passé
sudo modprobe cryptodev
make check
En tapant ls /dev/crypto
vous devriez voir le 'tuyau' qui est à présent apparu. Yay! 🙂
- Ok, maintenant il est temps de recompiler openssl pour qu'il tienne compte de cryptodev. On télécharge les sources
cd ..
apt-get source openssl # No sudo, we only fetch the sources
- On édite le fichier debian/rules pour ajouter les flags de compilation qui feront prendre cryptodev en compte. Il y a trois flags à mettre, à la fin de la ligne CONFARGS
cd openssl-1.0.1e/
nano debian/rules
# add -DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGESTS -DHASH_MAX_LEN=64 at end of CONFARGS line
- On copie la définition de l'"engine" cryptodev depuis le répertoire cryptodev, car il est "mieux" que celui écrit par défaut dans les sources OpenSSL (cette info vient du README de Cryptodev).
cp ../cryptodev/cryptodev-linux-master/extras/eng_cryptodev.c crypto/engine/eng_cryptodev.c
- Parfait, il est temps de créer le binaire!
sudo apt-get install debhelper zlib1g-dev
fakeroot debian/rules binary
- Détachez votre session screen et faites quelques chose d'autre en attendant, ça va prendre un moment (plus d'1h sur mon sheevaplug)
# Ctrl + a + d
- Quand tout cela est fini, reconnectez-vous à votre session screen
ssh -t username@host
screen -ls
screen -r session_OPENSSL
- Installons les packages fraichement compilés!
cd ..
sudo dpkg -i openssl_1.0.1e-2+deb7u4_armel.deb
sudo dpkg -i libssl1.0.0_1.0.1e-2+deb7u4_armel.deb
- Mettre les paquets en 'hold' pour éviter qu'ils soient écrasés par une mise à jour
sudo apt-mark hold openssl libssl1.0.0
- Dernière étape, il est temps de tester ça!
openssl speed -evp aes-256-cbc
Doing aes-256-cbc for 3s on 16 size blocks: 81916 aes-256-cbc's in 0.10s
Doing aes-256-cbc for 3s on 64 size blocks: 79295 aes-256-cbc's in 0.13s
Doing aes-256-cbc for 3s on 256 size blocks: 55737 aes-256-cbc's in 0.04s
Doing aes-256-cbc for 3s on 1024 size blocks: 37217 aes-256-cbc's in 0.05s
Doing aes-256-cbc for 3s on 8192 size blocks: 7555 aes-256-cbc's in 0.01s
OpenSSL 1.0.1e 11 Feb 2013
built on: Fri Apr 4 14:23:33 CEST 2014
options:bn(64,32) rc4(ptr,char) des(idx,cisc,16,long) aes(partial) blowfish(ptr)
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGESTS -DHASH_MAX_LEN=64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wa,--noexecstack -Wall -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DGHASH_ASM
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-256-cbc 13106.56k 39037.54k 356716.80k 762204.16k 6189056.00k
On voit bien qu'au plus les paquets sont larges, au plus le hardware produit un gain significatif. Ceci est du au fait qu'il y a très probablement du pipelining dans le module hardware et l'overhead entre chaque séquence de chiffrement devient significatif quand les paquets sont trop petits.
- Enjoy! :cool: