Crypto Hardware Acceleration

Last modified by Microchip on 2025/11/11 16:19

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\boardAT91SAM9G46AT91SAM9CN11AT91SAMA5D3AT91SAMA5D4AT91SAMA5D2
SHA1XXXXX
SHA256XXXXX
SHA224-XXXX
SHA384--XXX
SHA512--XXX
HMAC-SHAx----X
DESX-XXX
TDESX-XXX
AES-ECBXXXXX
AES-CBCXXXXX
AES-OFBXXXXX
AES-CFBXXXXX
AES-CTRXXXXX
AES-GCM---XX
AES-XTS----X
AEAD AES+HMAC-SHA----X
Note: - Not supported, X Supported

Back to Top

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.

Back to Top

Building the openssl Binary and the User Space Interface

openssl Binary

Enter the buildroot source directory.

make menuconfig

Make sure the openssl binary and the associated helper scripts will be installed to the target file system.

Target packages
     -->   Libraries
          -->     Crypto
               -->      cryptodev
                    -->      openssl support (BR2_PACKAGE_OPENSSL [=y])
                         -->      ssl library (<choice> [=y])
                              -->      openssl (BR2_PACKAGE_LIBOPENSSL [=y])

openssl-binary


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

Target packages
     -->   Libraries
          -->      Crypto
               -->         cryptodev

cryptodev-linux


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

cryptodev-linux


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

af_alg


If cryptodev is built and included in the root filesystem, you can enable it at board startup by running the following command:

modprobe cryptodev

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.

Information

Note: The Linux kernel must be enabled in Buildroot.

Back to Top

Configurations in Kernel

Atmel hardware driver must be enabled in kernel configuration. Enter the Linux source directory:

make menuconfig

Cryptographic API
     -->   Hardware crypto devices

Linux source directory

The following configs will be enabled in .config.

CONFIG_CRYPTO_HW=y
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-sha
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:

root@sama5d4ek:~# cat /proc/crypto | grep atmel
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

Back to Top

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:

  1. 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
  2. elapsed: Performances are calculated taking into account time consumed in user space and kernel space. Without this parameter, only user space time is used.
  3. 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.

cat /proc/interrupts
           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:

time -v openssl speed -evp aes-128-cbc -elapsed -mr

Verify that the number of interrupts increased on the AES IP:

cat /proc/interrupts
           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:

time -v openssl speed -evp aes-128-cbc -engine afalg -elapsed -mr

Verify that the number of interrupts increased on the AES IP:

           CPU0       
 ...
 27:          0  atmel-aic5  12 Level     atmel-sha
 28:        495  atmel-aic5   9 Level     atmel-aes
 ...
 49:          0  atmel-aic5  11 Level     atmel-tdes

Back to Top

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):
        scp -v -c aes128-cbc /tmp/test_20M PC_user@PC_IP:/tmp
  • From the PC to the board (read access):
        scp -v -c aes128-cbc PC_user@PC_IP:/tmp/test_20M /tmp/
  • Atmel board as SSH server (commands are executed from the PC):
    • From the board to the PC (read access):
        scp -v -c aes128-cbc board_user@board_IP:/tmp/test_20M /tmp
  • From the PC to the board (write access):
        scp -v -c aes128-cbc /tmp/test_20M board_user@board_IP:/tmp

Back to Top

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:
      dev tun
      #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:
      #!/bin/sh
      route add -net 10.0.0.0 netmask 255.255.255.0 gw $5

PC configuration files:

  • PC.conf:
      dev tun
      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:
      #!/bin/sh
      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:
        openvpn --config atmel-board.conf --cipher AES-2 56-CBC
  • Hardware driver:
        openvpn --config atmel-board.conf --engine cryptodev --cipher AES-2 56-CBC
  • PC:
      openvpn --config PC.conf --cipher AES-2 56-CBC

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:
      iperf -c server_IP

Back to Top

FAQ

QuestionAnswer
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

Back to Top