Crypto hardware acceleration

Introduction

This page is mainly about how to use crypto hardware acceleration in OpenSSL.Many internet applications such as OpenSSH and OpenVPN depends on OpenSSL to do encryption/decryption. So this can accelerate the crypto speed and reduce the CPU usage than software implemention.

Hardware Support

The crypto is supported in AT91SAM9G46, AT91SAM9CN11, AT91SAMA5D3, 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

- Not supported, X Supported

Prerequisites

The hardware acceleration is implemented as a driver in kernel space. In order to use it in user space application, the thirdparty kernel module is needed to convert the request of user space into kernel space. It provides the interface for user space to use. And OpenSSL can use it. There are two candidates, one is ocf-linux, and the other is cryptodev-linux. They can be selected and built in buildroot.

ocf-linux

OCF-Linux is a Linux port of the OpenBSD/FreeBSD Cryptographic Framework (OCF).

cryptodev-linux

Cryptodev-linux is a device that allows access to Linux kernel cryptographic drivers; thus allowing of userspace applications to take advantage of hardware accelerators. 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 userspace API (/dev/crypto).

Building cryptodev

Entering buildroot source directory:
make menuconfig
The cryptodev-linux can be selected in
Target packages
     -->   Libraries
          -->      Crypto
               -->         cryptodev
cryptodev-linux.png

If you want to use ocf-linux, it also can be selected either.

cryptodev-linux.png

If one of them is built and installed in root filesystem, when board startup, enter command

modprobe cryptodev
a device node /dev/crypto will appear. If not, the hardware drivers cannot be used in user space program.

Note, the Linux kernel must be enabed in buildroot.

Configurations in Kernel

Atmel hardware driver must be enabled in kernel configuration. Entering Linux source directory:
make menuconfig

Cryptographic API
     -->   Hardware crypto devices
cryptodev-linux.png

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. Using 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

Applications

OpenSSL

OpenSSL is an open source toolkit implementing the Secure Socket Layer (SSL) and Transport Layer Security 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 can do benches when we give to it "speed" parameter. 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
    • AES: aes-128-cbc, aes-192-cbc and aes-256-cbc
  2. engine: hardware implementation name: "cryptodev" in our case.
  3. elapsed: performances are calculated in taking into account time consumed in user space and kernel space. Without this parameter only user space time is used.
  4. mr: produce machine readable output
Linux "time" command is used to get CPU load.

AES with 128bits key example:

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

OpenSSH

OpenSSH (OpenBSD Secure Shell) is a set of computer programs providing encrypted communication sessions over a computer network using the SSH protocol.
For the benches we are using "scp" program to copy a 20Mbytes file from Atmel board to a PC and then from the PC to Atmel board. Both client and server mode are tested.
RSA public keys are used for encryption.
Files are copied to/from /tmp directory in order to reduce the impact of memory accesses on measurements.
Moreover Atmel board and the PC are directly connected via ethernet cable.
Arguments given to scp are:
  • -c : algorithm name: aes128-cbc, aes192-cbc, aes256-cbc and 3des-cbc
  • source file
  • destination file
  • -v: verbose mode
Example for AES 128bits key:
  • Atmel board is SSH client: commands are executed from it:
    • From Atmel board to the PC (write access):
        scp -v -c aes128-cbc /tmp/test_20M PC_user@PC_IP:/tmp
    • From the PC to Atmel board (read access):
        scp -v -c aes128-cbc PC_user@PC_IP:/tmp/test_20M /tmp/
  • Atmel board is SSH server: commands are executed from the PC:
    • From Atmel board to the PC (read access):
        scp -v -c aes128-cbc board_user@board_IP:/tmp/test_20M /tmp
    • From the PC to Atmel board (write access):
        scp -v -c aes128-cbc /tmp/test_20M board_user@board_IP:/tmp

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 the benches we are using a point-to-point connection between Atmel board and a PC.
Atmel board and the PC are directly connected via ethernet cable. The PC is the server and Atmel board is the client.
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
In order to change the cipher we add this parameter to both the Atmel board and the PC at openVPN startup: --cipher algorithm_name (DES-EDE3-CBC, AES-128-CBC and AES-256-CBC).

Moreover on Atmel board we also give the following parameter to openVPN to tell it to use hardware cryptography drivers: --engine cryptodev.

AES 256 bits key example:

  • Atmel board
    • SW driver:
        openvpn --config atmel-board.conf --cipher AES-2 56-CBC
    • HW driver:
        openvpn --config atmel-board.conf --engine cryptodev --cipher AES-2 56-CBC
  • PC:
      openvpn --config PC.conf --cipher AES-2 56-CBC
Once VPN is up performances are measured with "iperf" tool. Both client and server mode are tested.
  • Command executed on server:
      
      iperf -s
  • Command executed on client:
      iperf -c server_IP

FAQ

Q: What algorithms are supported in hardware acceleration?

A: SHA-1, SHA-224, SHA-256, SHA-384, SHA-512. DES, TDES, AES and all the modes defined in FIPS.

Q: How can I get the performance comparisions between software and hardware?

A: Disable the atmel hardware driver in kernel. The default software implemention will be selected by crypto framework. OpenSSL can be used to get the performance comparisions whether atmel hardware driver enabled or not.

Q: How can I use the cyptodev interface in my own applicaion?

A: There are several examples provided in cryptodev-linux's documents. They can be referred in your applicaions.

Q: How do I know the crypto hardware acceleration is used in kernel?

A: Execute the following commad and check the priority of registered algorithm. The kernel will take the highest priority If there are multiple same algorithms registered. Please ensure that there are no priority of other algorithms are higher than 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

Topic attachments
I Attachment Action Size Date Who Comment
PNGpng cryptodev-linux.png manage 34.0 K 2015-05-20 - 02:42 UnknownUser  
PNGpng cryptodev.png manage 41.9 K 2015-05-20 - 02:41 UnknownUser  
PNGpng cryptodriver.png manage 39.1 K 2015-05-20 - 02:41 UnknownUser  
r11 - 10 Oct 2017 - 12:53:54 - NicolasFerre
 
Linux & Open Source related information for AT91 Smart ARM Microcontrollers

Copyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.

Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries.

Atmel® and others, are registered trademarks or trademarks of Atmel Corporation or its subsidiaries. This site is powered by the TWiki collaboration platform

ARM® and others are registered trademarks or trademarks of ARM Ltd. Other terms and product names may be trademarks of others.

Ideas, requests, contributions ? Connect to LinksToCommunities page.

Syndicate this siteRSS ATOM