Changes between Initial Version and Version 1 of linux/encryption


Ignore:
Timestamp:
05/29/2019 11:38:55 PM (5 years ago)
Author:
Tim Harvey
Comment:

initial page

Legend:

Unmodified
Added
Removed
Modified
  • linux/encryption

    v1 v1  
     1[[PageOutline]]
     2
     3[=#crypto]
     4= Linux Crypto API
     5The Crypto API, introduced in Linux 2.5.45, is a generic cryptography library API introduced in the kernel containing support for all popular block ciphers, hash functions, AEAD, HMAC, and compression algorithms. The kernel contains software implementations for major symmetric ciphers as well as allows plugging in implementations which take advantage of hardware components such as the IMX6 CAAM and OcteonTX ZIP/CPT hardware blocks that can accelerate encryption/compression.
     6
     7The Linux Kernel Crypto API backend modules transparently accelerate kernelspace crypto users such as IPsec, 802.11, 802.15.4, Bluetooth, and and dm-crypt (search the
     8kernel for 'crypto_alloc_' to find all users).
     9
     10Software vs Hardware Crypto:
     11* Software:
     12 - Example: OpenSSL SW engine
     13 - pros:
     14  * full control over the algorithm
     15  * no black box
     16 - cons
     17  * consumes CPU cycles
     18  * often slower than dedicated software
     19* Hardware:
     20 - Example: IMX6 CAAM, Octeon-Tx CPT/ZIP
     21 - pros
     22  * minimal CPU cycles
     23  * generally faster than software counterpart
     24 - cons
     25  * limited subset of algorithms
     26  * black box
     27
     28**Note that often modern processors can outperform hardware crypto offload by using software crypto (at the expense of using up CPU cycles). In these cases or the case where the benefit of hardware crypto results in the same performance the difference is the off-loading to conserve CPU cycles. Perform benchmarks before choosing a solution that's right for you.**
     29
     30References:
     31 - [http://events17.linuxfoundation.org/sites/events/files/slides/2017-02%20-%20ELC%20-%20Hudson%20-%20Linux%20Cryptographic%20Acceleration%20on%20an%20MX6.pdf Linux Cryptographic Acceleration on iMX6]
     32
     33[=#crypto-userspace]
     34== Linux userspace crypto support
     35Accessing the Linux kernel Crypto API from userspace in order to take advantage of hardware crypto offload can be done in one of two ways:
     36 * AF_ALG: the in-tree/official solution (since OpenSSL 1.1.0) and supported in older OpenSSL via an out-of-tree plugin
     37 * Cryptodev: out-of-tree kernel module ported from BSD with better performance and natively supported in OpenSSL
     38
     39You can use either of the above kernel API's directly or you can use a crypto library that may support them such as OpenSSL or GnuTLS.
     40
     41
     42[=#af_alg]
     43=== AF_ALG
     44AF_ALG is a netlink-based interface that adds an AF_ALG address family introduced in 2.6.38.
     45
     46Kernel configuration:
     47- CONFIG_CRYPTO_USER_API
     48- CONFIG_CRYPTO_USER_API_HASH
     49- CONFIG_CRYPTO_USER_API_SKCIPHER
     50- CONFIG_CRYPTO_USER_API_RNG
     51- CONFIG_CYRPTO_USER_API_AEAD
     52
     53Comparison to Cryptodev (+ indicates a pro, - indicates a con):
     54* supports CIPHER, HASH
     55* socket based interface
     56* + in kernel since 2.6.38
     57* + inherently asynchronous
     58* - OpenSSL 1.1.0+ supports AF_ALG natively but prior versions require out-of-tree engine plugin to be built
     59* - GnuTLS does not have support for AF_ALG
     60* - not many examples
     61* - higher latency compared to cryptodev
     62
     63
     64Example native code:
     65{{{#!c
     66#include <stdio.h>
     67#include <string.h>
     68#include <unistd.h>
     69#include <sys/socket.h>
     70#include <linux/if_alg.h>
     71#include <linux/socket.h>
     72#define SHA256_DIGEST_SZ 32
     73
     74int main(void)
     75{
     76        struct sockaddr_alg sa = {
     77                .salg_family = AF_ALG,
     78                .salg_type = "hash",
     79                .salg_name = "sha256"
     80        };
     81        unsigned char digest[SHA256_DIGEST_SZ];
     82        char *input = "Hello World!";
     83        int i, sockfd, fd;
     84        sockfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
     85        bind(sockfd, (struct sockaddr *)&sa, sizeof(sa));
     86        fd = accept(sockfd, NULL, 0);
     87        write(fd, input, strlen(input));
     88        read(fd, digest, SHA256_DIGEST_SZ);
     89        close(fd);
     90        close(sockfd);
     91        for (i = 0; i < SHA256_DIGEST_SZ; i++)
     92                printf("%02x", digest[i]);
     93        printf("\n");
     94        return 0;
     95}
     96}}}
     97 * use the splice() call to push data
     98 * page-align the buffers with payloads
     99
     100
     101[=#cryptodev]
     102=== Cryptodev
     103The Cryptodev-linux kernel module has to be compiled as it is not part of the kernel tree. It is API compatible with OpenBSD's Cryptographic Framework (OCF or /dev/crypto) and it is GPLv2 licensed which means one day it could be included directly in the linux kernel. It enables userspace application access to the Crytpo API backend modules already present in the kernel.
     104
     105Comparison to AF_ALG (+ indicates pro, - indicates con):
     106* Supports CIPHER, HASH, AEAD
     107* users character device interface (/dev/crypto)
     108* + compatible with OpenBSP /dev/crytpo (API compatible, not code compatible)
     109* + OpenSSL has engine for cryptodev
     110* + GnuTLS has support for cryptodev
     111* + nice examples (in the examples directory of the linux kernel driver source)
     112* + lower latency than AF_ALG
     113* - out of tree kernel driver (for years now)
     114* - Adds arbitrary IOCTLs
     115* - Synchronous only
     116
     117Even though cryptodev is out-of-tree its quite easy to compile it against your kernel:
     118 * In general:
     119{{{#!bash
     120tar xvf crptodev-linux-*.tar.gz
     121make
     122insmod cryptodev.ko
     123}}}
     124 * Example cross compiling on host for Newport via Newport BSP:
     125{{{#!bash
     126cd newport
     127. ./setup-environment # activate cross-compile shell environment
     128git clone https://github.com/cryptodev-linux/cryptodev-linux.git -b cryptodev-linux-1.10
     129KERNEL_DIR=$PWD/linux DESTDIR=$PWD/linux/install INSTALL_MOD_PATH=$PWD/linux/install make -C cryptodev-linux install
     130tar cvzf cryptodev-linux.tar.gz -C $PWD/linux/install lib/modules/4.20.7-00006-gaf078a3/extra/cryptodev.ko usr/local/include/crypto/cryptodev.h
     131}}}
     132
     133
     134For examples using the cryptodev API via {{{/dev/crypto}}} see the cryptodev-linux/examples:
     135 * https://github.com/nmav/cryptodev-linux/tree/master/examples
     136
     137References:
     138 * http://cryptodev-linux.org/
     139
     140
     141[=#openssl]
     142== OpenSSL library
     143Instead of accessing crypto functions directly via CPU instructions or the kernel APIs, we opted to use the OpenSSL library to wrap that functionality for us. There are a few steps to enable OpenSSL for each kernel API.
     144
     145[[Image(https://image.slidesharecdn.com/slideshare-linuxcrypto-160411115704/95/slideshare-linux-crypto-4-638.jpg?cb=1460375879,400px)]]
     146
     147To see what engine support exists in OpenSSL use the {{{openssl engine}}} command:
     148{{{#!bash
     149root@bionic-armhf:~/openssl-1.1.0g# openssl engine
     150(cryptodev) BSD cryptodev engine
     151(dynamic) Dynamic engine loading support
     152}}}
     153 - the above shows that dynamic engine loading is supported as well as the cryptodev engine
     154
     155To evaluate performance vs CPU load tradeoff use the {{{openssl speed}}} command:
     156 * Example: GW6304 (IMX6Q@1.2GHz)
     157{{{#!bash
     158root@bionic-armhf:~/openssl-1.1.0g# openssl speed -evp aes-128-cbc -elapsed
     159You have chosen to measure elapsed time instead of user CPU time.
     160Doing aes-128-cbc for 3s on 16 size blocks: 27715 aes-128-cbc's in 3.00s
     161Doing aes-128-cbc for 3s on 64 size blocks: 27570 aes-128-cbc's in 3.00s
     162Doing aes-128-cbc for 3s on 256 size blocks: 27010 aes-128-cbc's in 3.00s
     163Doing aes-128-cbc for 3s on 1024 size blocks: 23792 aes-128-cbc's in 3.00s
     164Doing aes-128-cbc for 3s on 8192 size blocks: 9095 aes-128-cbc's in 3.00s
     165Doing aes-128-cbc for 3s on 16384 size blocks: 4963 aes-128-cbc's in 3.00s
     166OpenSSL 1.1.0g  2 Nov 2017
     167built on: reproducible build, date unspecified
     168options:bn(64,32) rc4(char) des(long) aes(partial) blowfish(ptr)
     169compiler: gcc -DDSO_DLFCN -DHAVE_DLFCN_H -DNDEBUG -DOPENSSL_THREADS -DOPENSSL_NO_STATIC_ENGINE -DOPENSSL_PIC -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DBSAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DPOLY1305_ASM -DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGESTS -DOPENSSLDIR="\"/usr/lib/ssl\"" -DENGINESDIR="\"/usr/lib/arm-linux-gnueabihf/engines-1.1\""
     170The 'numbers' are in 1000s of bytes per second processed.
     171type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
     172aes-128-cbc        147.81k      588.16k     2304.85k     8121.00k    24835.41k    27104.60k
     173root@bionic-armhf:~/openssl-1.1.0g# openssl speed -evp aes-128-cbc -engine cryptodev
     174engine "cryptodev" set.
     175Doing aes-128-cbc for 3s on 16 size blocks: 27750 aes-128-cbc's in 0.19s
     176Doing aes-128-cbc for 3s on 64 size blocks: 27562 aes-128-cbc's in 0.04s
     177Doing aes-128-cbc for 3s on 256 size blocks: 26970 aes-128-cbc's in 0.06s
     178Doing aes-128-cbc for 3s on 1024 size blocks: 23868 aes-128-cbc's in 0.08s
     179Doing aes-128-cbc for 3s on 8192 size blocks: 9045 aes-128-cbc's in 0.01s
     180Doing aes-128-cbc for 3s on 16384 size blocks: 4882 aes-128-cbc's in 0.05s
     181OpenSSL 1.1.0g  2 Nov 2017
     182built on: reproducible build, date unspecified
     183options:bn(64,32) rc4(char) des(long) aes(partial) blowfish(ptr)
     184compiler: gcc -DDSO_DLFCN -DHAVE_DLFCN_H -DNDEBUG -DOPENSSL_THREADS -DOPENSSL_NO_STATIC_ENGINE -DOPENSSL_PIC -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DBSAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DPOLY1305_ASM -DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGESTS -DOPENSSLDIR="\"/usr/lib/ssl\"" -DENGINESDIR="\"/usr/lib/arm-linux-gnueabihf/engines-1.1\""
     185The 'numbers' are in 1000s of bytes per second processed.
     186type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
     187aes-128-cbc       2336.84k    44099.20k   115072.00k   305510.40k  7409664.00k  1599733.76k
     188}}}
     189 * Use {{{-elapsed}}} argument when evaluating software crypto to see how many operations within a wall time of 3s can be performed compared to how much CPU time and how many operations can be performed within a wall time of 3s when using a hardware crypto engine: The above test shows for 16 byte blocks of aes-128-cbs's you can get 27715 iterations within 3s with software crypto and 27750 iterations within the same 3s (wall-clock time) but only using 0.19s of CPU time (ever so slight of a performance boost but significantly less CPU use) which results in hardware crypto having a much higher bandwidth if you look at it in terms of what it can do in 3s of CPU time
     190 * Use {{{-engine cryptodev}}} to use the cryptodev engine (if available)
     191 * Use {{{-engine af_alg}}} to use the AF_ALG engine (if available)
     192 * Use {{{-elapsed}}} and no {{{-engine}}} param to use software crypto to show wall-clock time vs CPU time
     193
     194
     195[=#openssl-af_alg]
     196=== OpenSSL with AF_ALG
     197OpenSSL added native AF_ALG support 1.1.0 (Aug 25 2016). If you are using a version prior to that you need to build a plugin for OpenSSL.
     198
     199Note that a Linux v4.1 kernel or newer is required (AF_ALG was added in 2.6.38 but a newer feature of async support on a socket is needed which came with 'net: socket: add support for async operations' in v4.1).
     200
     201Note that Ubuntu's OpenSSL does not enable AF_ALG support by default so you will still need to build/rebuild OpenSSL to enable it.
     202
     203To build the out-of-tree OpenSSL af_alg plugin for OpenSSL versions prior to 1.1.0:
     204{{{#!bash
     205# install deps
     206apt install build-essential pkg-config libssl-dev
     207# build
     208git clone https://github.com/sarnold/af_alg.git
     209cd af_alg/
     210./autogen.sh
     211./configure
     212make
     213# install plugin to engines directory for currently installed libssl
     214DIR=$(dpkg -L libssl1.0.0 | grep engines$)
     215# openssl version -d # shows OPENSSLDIR
     216sudo cp libaf_alg.so $DIR
     217sudo chmod 644 $DIR/libaf_alg.so
     218openssl engine # show engines available
     219}}}
     220 * Note that this plugin is incompatible with OpenSSL 1.1.x and will fail to build for those versions due to API changes
     221
     222Note that prior to OpenSSL 1.1.1 afalg is not enabled by default thus you need to rebuild it and add the 'enable-afalgeng' config option.
     223
     224To ensure you are loading the kernel modules (af_alg, algif_hash, algif_skcipher):
     225 * load them on boot:
     226{{{#!bash
     227# ensure these modules are loaded at bootup
     228echo af_alg >> /etc/modules
     229echo algif_hash >> /etc/modules
     230echo algif_skcipher >> /etc/modules
     231}}}
     232 * load them for current boot:
     233{{{#!bash
     234# load them now
     235modprobe af_alg algif_hash algif_skcipher
     236}}}
     237
     238OpenSSL performance can be tested with:
     239{{{#!bash
     240openssl engine # ensure af_alg is present
     241openssl speed -evp aes-128-cbc -engine af_alg -elapsed
     242}}}
     243
     244
     245[=#openssl-crytodev]
     246=== OpenSSL with cryptodev
     247Because Cryptodev is not available by default on Linux distributions OpenSSL has to be compiled with additional flags to include support for them:
     248{{{#!bash
     249apt install build-essential pkg-config
     250wget https://www.openssl.org/source/openssl-1.1.1c.tar.gz
     251tar xvf openssl-*
     252cd openssl-*
     253./config -DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGESTS
     254make
     255make install
     256}}}
     257 * Additionally the sysroot should have the cryptodev header installed: {{{/usr/include/crypto/cryptodev.h}}}
     258
     259Note that for Ubuntu / Debian Linux distros it is preferred to download source package, modify debian/rules and recompile the package:
     260{{{#!bash
     261apt install build-essential pkg-config ubuntu-dev-tools debhelper
     262apt-get build-dep openssl
     263apt-get source openssl
     264cd openssl-*/
     265sed -i -e "s/CONFARGS  =/CONFARGS = -DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGESTS/" debian/rules
     266dch -i "Enabled cryptodev support"
     267DEB_BUILD_OPTIONS=nocheck debuild # disable checks to avoid issue with api check failing
     268sudo dpkg -i ../openssl*.deb
     269}}}
     270
     271To ensure you are loading the kernel module (cryptodev):
     272 * load them on boot:
     273{{{#!bash
     274# ensure these modules are loaded at bootup
     275echo cryptodev >> /etc/modules
     276}}}
     277 * load them for current boot:
     278{{{#!bash
     279# load them now
     280modprobe cryptodev
     281}}}
     282
     283OpenSSL Testing:
     284{{{#!bash
     285openssl engine # show engines available - look for cryptodev
     286openssl version -f # show compiler flags openssl was built with; look for -DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGESTS
     287}}}
     288
     289OpenSSL performance can be tested with the 'openssl speed' command:
     290{{{#!bash
     291openssl speed -evp aes-128-cbc -engine cryptodev -elapsed
     292}}}
     293 * -elapsed argument is used so throughput measurements are against wall clock time rather than cpu time
     294
     295References:
     296- http://cryptodev-linux.org/
     297
     298
     299== Gateworks BSP Support
     300The embedded linux community tends to prefer cryptodev so that is what we tend to support at Gateworks in our various BSP's:
     301 * Newport:
     302  - Ubuntu - software only (openssl needs to be rebuilt for cryptodev support)
     303  - OpenWrt - cryptodev
     304 * Ventana:
     305  - Ubuntu - software only (openssl needs to be rebuilt for cryptodev support)
     306  - OpenWrt - cryptodev
     307  - Yocto - cryptodev