| nRF5 SDK v12.0.0 |

Choose documentation: | nRF5 SDK | S130 SoftDevice API | S132 SoftDevice API | S212 SoftDevice API | S332 SoftDevice API

All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Cryptography library

The cryptography library provides functions that implement several variants of public key cryptography. These cryptography functions are required for secure DFU. You can also include the library in your application (independently of the bootloader). The implementation utilizes a well-known open source library, micro-ecc.

The library supports the following cryptographic schemes:

- ECDSA (Elliptic Curve Digital Signature Algorithm), an algorithm to create and verify signatures for any kind of data (for example, a firmware image)

- ECDH (Elliptic Curve Diffie-Hellmann), a key agreement protocol that allows to establish a shared secret over an insecure channel

In addition, the library can be used to calculate a hash (or digest) of the input data, based on the SHA-256 hashing algorithm.

# Signing concepts

If you plan to use the cryptography library, you should familiarize yourself with the general concepts of asymmetric cryptography. The following concepts are important to know:

Signature

  A digital signature attests the authenticity of a set of data. Usually, it contains a signed hash or digest of the same data. The recipient of the data can then verify the signature by hashing the data and comparing the hash to the one obtained from the signature.

  The signature is generated using a private key and a hashing algorithm. It can be verified using a public key.

Private key

  A private key (also called signing key in the context of ECDSA) is a key that identifies its owner. You should never share your private key with anybody. When you use it to sign data, you affirm that the data is yours, because no one else knows the private key that is required for signing.

  To be understood by the cryptography library, private keys must be based on one of the curves defined in NRF_CRYPTO_CURVES. Currently, only the secp256r1 (also called NIST P-256) curve is supported. See Recommended elliptic curves for federal government use, SEC 2: Recommended Elliptic Curve Domain Parameters, and other sources for detailed information about this curve.

Public key

  A public key (also called verification key in the context of ECDSA) is openly available and can be used to verify the input data based on the signature and the hash of the input data.

  The public key is calculated based on the private key. This means that if you plan to send signed data, you must create a public key and share it with the recipient so that the recipient can verify the signature.

Shared secret

  A shared secret, or a shared key, is a key that is known only to the involved parties. The shared secret can be negotiated over an insecure channel between parties that each have a public-private key pair. After the shared secret is calculated on both sides, it can be used to encrypt communication between the parties.

  Shared secrets are currently not used in secure DFU, but they can be used in different contexts (for example, they are required for Bluetooth LE Secure Connections).

# Working with keys

The cryptography library requires private and public keys. A public key can be computed from a private key, but the private key must always be provided. The library requires keys to be supplied as little-endian array of bytes along with a length (see nrf_crypto_key_t for more information).

If your keys should be valid for only one device or even only one connection, you can generate them at run time. Simply generate a random number as private key and compute the corresponding public key by calling nrf_crypto_public_key_compute.

If you need static keys for use on multiple devices, you should generate the keys externally. The following example commands use Nordic Semiconductor's nrfutil tool (see the nrfutil documentation) to generate keys based on the secp256r1 curve:

# Generate a private key in c:\vault\priv.pem
nrfutil keys generate c:\vault\priv.pem
# Display the generated private key (in little-endian format)
nrfutil keys display --key sk --format hex c:\vault\priv.pem
# Display the generated private key (in code format to be
# used with nrf_crypto)
nrfutil keys display --key sk --format code c:\vault\priv.pem
# Display the public key that corresponds to the generated private key
# (in little-endian format)
nrfutil keys display --key pk --format hex c:\vault\priv.pem
# Display the public key that corresponds to the generated private key
# (in code format to be used with nrf_crypto)
nrfutil keys display --key pk --format code c:\vault\priv.pem
# Write the public key that corresponds to the generated private key
# to the file public_key.c (in code format)
nrfutil keys display --key pk --format code c:\vault\priv.pem --out_file public_key.c

You can also generate keys using OpenSSL. See the OpenSSL documentation for instructions on how to generate a private key. Issue the following command to display the contents of the .pem key file:

openssl ec -in c:\safe\priv.pem -text -noout

This command will display both the private and the public key in big-endian format. To use these keys with the cryptography library, you must reverse the byte order. Also, the public key will be prefixed by a byte with the value "0x04", which you should ignore.

Make sure to store the private key securely and with limited access. If the private key is lost, you cannot reproduce it and therefore cannot provide signed data anymore.

# Installing micro-ecc

micro-ecc is an open source library that is required to use the cryptography library. When using micro-ecc, you must ensure compliance with the license of the library as stated in the LICENSE.txt file that is included in micro-ecc.

The cryptography library expects to find the compiled micro-ecc library in `InstallFolder\external\micro-ecc\micro-ecc`.

To install micro-ecc, complete the following steps:

1. Install version 4.9-2015-q3-update of the GCC compiler toolchain for ARM. You can use ARM's Launchpad to find the toolchain for your operating system.
2. Clone the micro-ecc GitHub repository into `InstallFolder\external\micro-ecc\micro-ecc`.
3. Enter the subdirectory for the SoC and the toolchain that you are using to build your application:
   - `InstallFolder\external\micro-ecc\nrf51_keil\armgcc`
   - `InstallFolder\external\micro-ecc\nrf52_keil\armgcc`
   - `InstallFolder\external\micro-ecc\nrf51_iar\armgcc`
   - `InstallFolder\external\micro-ecc\nrf52_iar\armgcc`
   - `InstallFolder\external\micro-ecc\nrf51_armgcc\armgcc`
   - `InstallFolder\external\micro-ecc\nrf52_armgcc\armgcc`
4. Run `make` to compile the micro-ecc library.

Note
  If you compile the micro-ecc library without using the provided Makefiles, make sure to use the default compilation options with -Os and optimization level 3. If you change the preprocessor macros (most importantly, `uECC_VLI_NATIVE_LITTLE_ENDIAN=1`), the library might not work properly.

# Library usage

Before you can use the cryptography library, you must initialize it.

To create a public key from a private key, call nrf_crypto_public_key_compute and specify which curve to use. This public key should be shared with other applications to enable them to verify signed data. Remember though that you should not share your private key, so calculating public keys in an application can be a risk.

To sign data, first call nrf_crypto_hash_compute and specify which hashing algorithm to use. This function creates a hash (or digest) of the data. Next, create a signature for the hash by calling nrf_crypto_sign with your private key and the curve that you want to use as input. To verify the signature, the other application must first calculate the hash of the data (using nrf_crypto_hash_compute) and then call nrf_crypto_verify with the computed hash and your public key as input.

To calculate a shared secret between two applications, each application must call nrf_crypto_shared_secret_compute with their own private key and the other application's public key as input.