Crypto Hardware Acceleration
Introduction
This document primarily addresses the utilization of crypto hardware acceleration in OpenSSL®. Many internet applications, including OpenSSH and OpenVPN®, rely on OpenSSL for encryption and decryption processes. This can accelerate the crypto speed and reduce the CPU usage than software implementation.
Hardware Support
The crypto is supported in AT91SAM9G46, AT91SAM9CN11, AT91SAMA5D3, and AT91SAMA5D4.
| algo\board | AT91SAM9G46 | AT91SAM9CN11 | AT91SAMA5D3 | AT91SAMA5D4 | AT91SAMA5D2 |
|---|---|---|---|---|---|
| SHA1 | X | X | X | X | X |
| SHA256 | X | X | X | X | X |
| SHA224 | - | X | X | X | X |
| SHA384 | - | - | X | X | X |
| SHA512 | - | - | X | X | X |
| HMAC-SHAx | - | - | - | - | X |
| DES | X | - | X | X | X |
| TDES | X | - | X | X | X |
| AES-ECB | X | X | X | X | X |
| AES-CBC | X | X | X | X | X |
| AES-OFB | X | X | X | X | X |
| AES-CFB | X | X | X | X | X |
| AES-CTR | X | X | X | X | X |
| AES-GCM | - | - | - | X | X |
| AES-XTS | - | - | - | - | X |
| AEAD AES+HMAC-SHA | - | - | - | - | X |
| Note: - Not supported, X Supported | |||||
Prerequisites
The hardware acceleration is implemented as a driver in kernel space. To enable its use in user space applications, a third-party kernel module is needed to convert the request of user space into kernel space. This module provides the necessary interface for user space access, allowing applications such as OpenSSL to leverage hardware acceleration. There are two primary kernel modules available for this purpose: ocf-linux and cryptodev-linux. There is a third option, afalg, which supports fewer algorithms. All of these modules can be selected and built using Buildroot.
cryptodev-linux
Cryptodev-linux is a device interface that enables user-space applications to access cryptographic drivers within the Linux kernel, allowing them to leverage hardware accelerators for enhanced performance. Cryptodev-linux is implemented as a standalone module that requires no dependencies other than a stock Linux® kernel. Its API is compatible with OpenBSD's cryptodev user-space Application Programming Interface (API) (/dev/crypto).
ocf-linux
OCF-Linux is a Linux port of the OpenBSD/FreeBSD® Cryptographic Framework (OCF).
af_alg
Starting in OpenSSL 1.1.0, an AF_ALG engine can be used. The AF_ALG interface uses sockets to allow access to the kernel crypto algorithms, so you won't see a /dev/crypto interface associated with it.
Building the openssl Binary and the User Space Interface
openssl Binary
Enter the buildroot source directory.
Make sure the openssl binary and the associated helper scripts will be installed to the target file system.
--> Libraries
--> Crypto
--> cryptodev
--> openssl support (BR2_PACKAGE_OPENSSL [=y])
--> ssl library (<choice> [=y])
--> openssl (BR2_PACKAGE_LIBOPENSSL [=y])

Enter the Buildroot source directory and select cryptodev. cryptodev-linux can be selected in:
--> Libraries
--> Crypto
--> cryptodev

Select ocf-linux, if you would like to use it:

If you want to use additional openssl engines, like af_alg, select openssl additional engines:

If cryptodev is built and included in the root filesystem, you can enable it at board startup by running the following command:
This will create the device node /dev/crypto, which allows user-space programs to access hardware cryptographic drivers. If /dev/crypto does not appear, user-space applications will not be able to utilize the hardware drivers.
Configurations in Kernel
Atmel hardware driver must be enabled in kernel configuration. Enter the Linux source directory:
Cryptographic API
--> Hardware crypto devices

The following configs will be enabled in .config.
CONFIG_CRYPTO_DEV_ATMEL_AES=y
CONFIG_CRYPTO_DEV_ATMEL_TDES=y
CONFIG_CRYPTO_DEV_ATMEL_SHA=y
If you select them as modules, please enter the following commands after board up:
modprobe atmel-aes
modprobe atmel-tdes
After the hardware drivers are loaded, the algorithms will be registered to crypto framework. Use the following command to see them:
driver : atmel-ofb-tdes
driver : atmel-cfb32-tdes
driver : atmel-cfb16-tdes
driver : atmel-cfb8-tdes
driver : atmel-cfb-tdes
driver : atmel-cbc-tdes
driver : atmel-ecb-tdes
driver : atmel-ofb-des
driver : atmel-cfb32-des
driver : atmel-cfb16-des
driver : atmel-cfb8-des
driver : atmel-cfb-des
driver : atmel-cbc-des
driver : atmel-ecb-des
driver : atmel-sha512
driver : atmel-sha384
driver : atmel-sha224
driver : atmel-sha256
driver : atmel-sha1
driver : atmel-cfb64-aes
driver : atmel-ctr-aes
driver : atmel-cfb8-aes
driver : atmel-cfb16-aes
driver : atmel-cfb32-aes
driver : atmel-cfb-aes
driver : atmel-ofb-aes
driver : atmel-cbc-aes
driver : atmel-ecb-aes
Applications
OpenSSL
OpenSSL is an open source toolkit that implements the Secure Socket Layer (SSL) and Transport Layer Security (TLS) protocols as well as a full-strength general-purpose cryptography library.
We are using it with cryptodev-linux, which makes the link between OpenSSL and cryptography hardware drivers.
OpenSSL includes a built-in benchmarking tool, which can be invoked using the speed command. Other parameters given for the benches are:
- evp: Algorithm name
- SHA: sha1, sha256, sha224 sha384 and sha512
- DES/TDES: des-cbc and des-ede3-cbc
- Advanced Encryption Standard (AES): aes-128-cbc, aes-192-cbc and aes-256-cbc
- elapsed: Performances are calculated taking into account time consumed in user space and kernel space. Without this parameter, only user space time is used.
- mr: Produce machine-readable output
The Linux time command is used to get the CPU load.
Before and after running an OpenSSL speed test, check the number of interrupts on the crypto IPs.
CPU0
...
27: 0 atmel-aic5 12 Level atmel-sha
28: 0 atmel-aic5 9 Level atmel-aes
...
49: 0 atmel-aic5 11 Level atmel-tdes
Keep in mind the number of interrupts and then run an openssl speed test. To benchmark the performance of the AES algorithm with a 128-bit key, use the following command:
Verify that the number of interrupts increased on the AES IP:
CPU0
...
27: 0 atmel-aic5 12 Level atmel-sha
28: 247 atmel-aic5 9 Level atmel-aes
...
49: 0 atmel-aic5 11 Level atmel-tdes
If you want to accelerate the algorithm through afalg, execute the following:
Verify that the number of interrupts increased on the AES IP:
...
27: 0 atmel-aic5 12 Level atmel-sha
28: 495 atmel-aic5 9 Level atmel-aes
...
49: 0 atmel-aic5 11 Level atmel-tdes
OpenSSH
OpenSSH (OpenBSD Secure Shell) is a set of computer programs that provide encrypted communication sessions over a computer network using the SSH protocol.
For benchmarking, we are using a algorithm program to copy a 20 Mb file from a Microchip Technology (formerly Atmel) board to a PC and then from the PC to the board. Both client and server modes are tested.
Rivest–Shamir–Adleman (RSA) public keys are used for encryption.
Files are copied to/from the /tmp directory in order to reduce the impact of memory accesses on measurements. Additionally, the board and the PC are directly connected via an Ethernet cable.
The arguments provided to the scp command are as follows:
- -c: algorithm name: aes128-cbc, aes192-cbc, aes256-cbc and 3des-cbc
- Source file
- Destination file
- -v: verbose mode
Example using AES 128-bit key:
- Atmel board as SSH client (commands are executed from the board):
- From the board to the PC (write access):
- From the PC to the board (read access):
- Atmel board as SSH server (commands are executed from the PC):
- From the board to the PC (read access):
- From the PC to the board (write access):
OpenVPN
OpenVPN is an open-source software application that implements Virtual Private Network (VPN) techniques for creating secure connections. OpenVPN uses the OpenSSL library to provide encryption of both the data and control channels.
For benchmarking, we use a point-to-point connection between the Atmel board and a PC. Atmel board and the PC are directly connected via an Ethernet cable, with the PC acting as the server and the board as the client.
The server and client configuration files are based on sample configuration files provided with OpenVPN source code, static-office.conf and static-home.conf.
Atmel board configuration files:
- atmel-board.conf:
#Server
remote 192.168.2.2
ifconfig 10.1.0.2 10.1.0.1
up ./atmel-board.up
secret static.key
script-security 3 system
no-replay
tun-mtu 60000
fragment 0
mssfix 0
- atmel-board.up:
route add -net 10.0.0.0 netmask 255.255.255.0 gw $5
PC configuration files:
- PC.conf:
ifconfig 10.1.0.1 10.1.0.2
up ./PC.up
secret static.key
script-security 3 system
no-replay
tun-mtu 60000
fragment 0
mssfix 0
- PC.up:
route add -net 10.0.1.0 netmask 255.255.255.0 gw $5
To change th cipher, add the following parameter to both the Atmel board and the PC when starting OpenVPN:
--cipher algorithm_name (e.g., DES-EDE3-CBC, AES-128-CBC, or AES-256-CBC).
Additionally, on the Atmel board, use the following parameter to instruct OpenVPN to utilize hardware cryptography drivers:
--engine cryptodev.
Example using AES 256-bit key:
- Atmel board
- Software driver:
- Hardware driver:
- PC:
Once the VPN is established, performance is measured with the "iperf" tool. Both client and server modes are tested.
- Command executed on server:
iperf -s
- Command executed on client:
FAQ
| Question | Answer |
|---|---|
| What algorithms are supported in hardware acceleration? | SHA-1, SHA-224, SHA-256, SHA-384, SHA-512. DES, TDES, AES and all the modes defined in FIPS. |
| How can I get the performance comparison between software and hardware? | Disable the Atmel hardware driver in kernel. The default software implementation will be selected by crypto framework. OpenSSL can be used to get the performance comparisons, whether Atmel hardware driver enabled or not. |
| How can I use the cyptodev interface in my own application? | There are several examples provided in cryptodev-linux's documents. They can be referred in your applications. |
| How do I know the crypto hardware acceleration is used in kernel? | Execute the following command and check the priority of registered algorithm. The kernel will take the highest priority if there are multiple same algorithms registered. Please ensure there are no priority of other algorithms that are higher than the priority of Atmel crypto driver. root@buildroot:~# cat /proc/crypto name : ofb(des3_ede) driver : atmel-ofb-tdes module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 8 min keysize : 16 max keysize : 24 ivsize : 8 geniv : <default> name : cfb32(des3_ede) driver : atmel-cfb32-tdes module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 4 min keysize : 16 max keysize : 16 ivsize : 8 geniv : <default> name : cfb16(des3_ede) driver : atmel-cfb16-tdes module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 2 min keysize : 16 max keysize : 16 ivsize : 8 geniv : <default> name : cfb8(des3_ede) driver : atmel-cfb8-tdes module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 1 min keysize : 16 max keysize : 16 ivsize : 8 geniv : <default> name : cfb(des3_ede) driver : atmel-cfb-tdes module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 8 min keysize : 16 max keysize : 16 ivsize : 8 geniv : <default> name : cbc(des3_ede) driver : atmel-cbc-tdes module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 8 min keysize : 16 max keysize : 24 ivsize : 8 geniv : <default> name : ecb(des3_ede) driver : atmel-ecb-tdes module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 8 min keysize : 16 max keysize : 24 ivsize : 0 geniv : <default> name : ofb(des) driver : atmel-ofb-des module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 8 min keysize : 8 max keysize : 8 ivsize : 8 geniv : <default> name : cfb32(des) driver : atmel-cfb32-des module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 4 min keysize : 8 max keysize : 8 ivsize : 8 geniv : <default> name : cfb16(des) driver : atmel-cfb16-des module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 2 min keysize : 8 max keysize : 8 ivsize : 8 geniv : <default> name : cfb8(des) driver : atmel-cfb8-des module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 1 min keysize : 8 max keysize : 8 ivsize : 8 geniv : <default> name : cfb(des) driver : atmel-cfb-des module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 8 min keysize : 8 max keysize : 8 ivsize : 8 geniv : <default> name : cbc(des) driver : atmel-cbc-des module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 8 min keysize : 8 max keysize : 8 ivsize : 8 geniv : <default> name : ecb(des) driver : atmel-ecb-des module : atmel_tdes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 8 min keysize : 8 max keysize : 8 ivsize : 0 geniv : <default> name : sha512 driver : atmel-sha512 module : atmel_sha priority : 100 refcnt : 1 selftest : passed type : ahash async : yes blocksize : 128 digestsize : 64 name : sha384 driver : atmel-sha384 module : atmel_sha priority : 100 refcnt : 1 selftest : passed type : ahash async : yes blocksize : 128 digestsize : 48 name : sha224 driver : atmel-sha224 module : atmel_sha priority : 100 refcnt : 1 selftest : passed type : ahash async : yes blocksize : 64 digestsize : 28 name : sha256 driver : atmel-sha256 module : atmel_sha priority : 100 refcnt : 1 selftest : passed type : ahash async : yes blocksize : 64 digestsize : 32 name : sha1 driver : atmel-sha1 module : atmel_sha priority : 100 refcnt : 1 selftest : passed type : ahash async : yes blocksize : 64 digestsize : 20 name : cfb64(aes) driver : atmel-cfb64-aes module : atmel_aes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 8 min keysize : 16 max keysize : 32 ivsize : 16 geniv : <default> name : ctr(aes) driver : atmel-ctr-aes module : atmel_aes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 16 min keysize : 16 max keysize : 32 ivsize : 16 geniv : <default> name : cfb8(aes) driver : atmel-cfb8-aes module : atmel_aes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 8 min keysize : 16 max keysize : 32 ivsize : 16 geniv : <default> name : cfb16(aes) driver : atmel-cfb16-aes module : atmel_aes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 2 min keysize : 16 max keysize : 32 ivsize : 16 geniv : <default> name : cfb32(aes) driver : atmel-cfb32-aes module : atmel_aes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 4 min keysize : 16 max keysize : 32 ivsize : 16 geniv : <default> name : cfb(aes) driver : atmel-cfb-aes module : atmel_aes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 16 min keysize : 16 max keysize : 32 ivsize : 16 geniv : <default> name : ofb(aes) driver : atmel-ofb-aes module : atmel_aes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 16 min keysize : 16 max keysize : 32 ivsize : 16 geniv : <default> name : cbc(aes) driver : atmel-cbc-aes module : atmel_aes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 16 min keysize : 16 max keysize : 32 ivsize : 16 geniv : <default> name : ecb(aes) driver : atmel-ecb-aes module : atmel_aes priority : 100 refcnt : 1 selftest : passed type : ablkcipher async : yes blocksize : 16 min keysize : 16 max keysize : 32 ivsize : 0 geniv : <default> name : stdrng driver : krng module : kernel priority : 200 refcnt : 1 selftest : passed type : rng seedsize : 0 name : lzo driver : lzo-generic module : kernel priority : 0 refcnt : 2 selftest : passed type : compression name : crc32c driver : crc32c-generic module : kernel priority : 100 refcnt : 1 selftest : passed type : shash blocksize : 1 digestsize : 4 name : deflate driver : deflate-generic module : kernel priority : 0 refcnt : 2 selftest : passed type : compression name : aes driver : aes-generic module : kernel priority : 100 refcnt : 2 selftest : passed type : cipher blocksize : 16 min keysize : 16 max keysize : 32 name : des3_ede driver : des3_ede-generic module : kernel priority : 0 refcnt : 1 selftest : passed type : cipher blocksize : 8 min keysize : 24 max keysize : 24 name : des driver : des-generic module : kernel priority : 0 refcnt : 1 selftest : passed type : cipher blocksize : 8 min keysize : 8 max keysize : 8 name : sha384 driver : sha384-generic module : kernel priority : 0 refcnt : 1 selftest : passed type : shash blocksize : 128 digestsize : 48 name : sha512 driver : sha512-generic module : kernel priority : 0 refcnt : 1 selftest : passed type : shash blocksize : 128 digestsize : 64 name : sha224 driver : sha224-generic module : kernel priority : 0 refcnt : 1 selftest : passed type : shash blocksize : 64 digestsize : 28 name : sha256 driver : sha256-generic module : kernel priority : 0 refcnt : 1 selftest : passed type : shash blocksize : 64 digestsize : 32 name : sha1 driver : sha1-generic module : kernel priority : 0 refcnt : 1 selftest : passed type : shash blocksize : 64 digestsize : 20 name : md5 driver : md5-generic module : kernel priority : 0 refcnt : 1 selftest : passed type : shash blocksize : 64 digestsize : 16 name : md4 driver : md4-generic module : kernel priority : 0 refcnt : 1 selftest : passed type : shash blocksize : 64 digestsize : 16 |