pw_crypto

A set of safe (read: easy to use, hard to misuse) crypto APIs.

The following crypto services are provided by this module.

  1. Hashing a message with SHA256.

  2. Verifying a digital signature signed with ECDSA over the NIST P256 curve.

  3. Many more to come …

SHA256

  1. Obtaining a oneshot digest.

#include "pw_crypto/sha256.h"

std::byte digest[32];
if (!pw::crypto::sha256::Hash(message, digest).ok()) {
  // Handle errors.
}
  1. Hashing a long, potentially non-contiguous message.

#include "pw_crypto/sha256.h"

std::byte digest[32];

if (!pw::crypto::sha256::Sha256()
    .Update(chunk1).Update(chunk2).Update(chunk...)
    .Final().ok()) {
  // Handle errors.
}

ECDSA

  1. Verifying a digital signature signed with ECDSA over the NIST P256 curve.

#include "pw_crypto/sha256.h"

std::byte digest[32];
if (!pw::crypto::sha256::Hash(message, digest).ok()) {
  // handle errors.
}

if (!pw::crypto::ecdsa::VerifyP256Signature(public_key, digest,
                                            signature).ok()) {
  // handle errors.
}
  1. Verifying a digital signature signed with ECDSA over the NIST P256 curve, with a long and/or non-contiguous message.

#include "pw_crypto/sha256.h"

std::byte digest[32];

if (!pw::crypto::sha256::Sha256()
    .Update(chunk1).Update(chunk2).Update(chunkN)
    .Final(digest).ok()) {
    // Handle errors.
}

if (!pw::crypto::ecdsa::VerifyP256Signature(public_key, digest,
                                            signature).ok()) {
    // Handle errors.
}

Configuration

The crypto services offered by pw_crypto can be backed by different backend crypto libraries.

Mbed TLS

To select the Mbed TLS backend, the MbedTLS library needs to be installed and configured.

# Install and configure MbedTLS
pw package install mbedtls
gn gen out \
    --args='dir_pw_third_party_mbedtls="//.environment/packages/mbedtls" \
    pw_crypto_SHA256_BACKEND="//pw_crypto:sha256_mbedtls" \
    pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_mbedtls"'

ninja -C out

For optimal code size and/or performance, the Mbed TLS library can be configured per product. Mbed TLS configuration is achieved by turning on and off MBEDTLS_* options in a config.h file. See //third_party/mbedtls for how this is done.

pw::crypto::sha256 does not need any special configuration as it uses the mbedtls_sha256_* APIs directly. However you can optionally turn on MBEDTLS_SHA256_SMALLER to further reduce the code size to from 3KiB to ~1.8KiB at a ~30% slowdown cost (Cortex-M4).

#define MBEDTLS_SHA256_SMALLER

pw::crypto::ecdsa requires the following minimum configurations which yields a code size of ~12KiB.

#define MBEDTLS_BIGNUM_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ECDSA_C
// The ASN1 options are needed only because mbedtls considers and verifies
// them (in check_config.h) as dependencies of MBEDTLS_ECDSA_C.
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ECP_NO_INTERNAL_RNG
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED

BoringSSL

To select the BoringSSL backend, the BoringSSL library needs to be installed and configured.

# Install and configure BoringSSL
pw package install boringssl
gn gen out \
    --args='dir_pw_third_party_boringssl="//.environment/packages/boringssl" \
    pw_crypto_SHA256_BACKEND="//pw_crypto:sha256_boringssl" \
    pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_boringssl"'

ninja -C out

BoringSSL does not provide a public configuration interface to reduce the code size.

Micro ECC

To select Micro ECC, the library needs to be installed and configured.

# Install and configure Micro ECC
pw package install micro-ecc
gn gen out --args='dir_pw_third_party_micro_ecc="//.environment/packages/micro-ecc" pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_uecc"'

Note Micro-ECC does not implement any hashing functions, so you will need to use other backends for SHA256 functionality if needed.

Size Reports

Below are size reports for each crypto service. These vary across configurations.

Label

Segment

Before

Delta

After

No backend is selected.

(all)
(same)
0
(same)