pw_crypto#

Pigweed AI summary: The pw_crypto module provides a set of safe crypto APIs that are easy to use and hard to misuse. The module offers various crypto services, including hashing a message with SHA256 and verifying a digital signature signed with ECDSA over the NIST P256 curve. The module also supports hashing long and potentially non-contiguous messages. The crypto services offered by pw_crypto can be backed by different backend crypto libraries, such as Mbed TLS and Micro ECC. The Mbed TLS backend requires installation and configuration of

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#

Pigweed AI summary: This section explains how to obtain a one-shot digest and how to hash a long, potentially non-contiguous message using SHA256 in C++. It provides code examples for both scenarios using the pw_crypto library. The first example shows how to obtain a digest from a message or a stream reader, while the second example demonstrates how to hash a long message by updating it with multiple chunks. Error handling is also mentioned in both examples.

  1. Obtaining a oneshot digest.

#include "pw_crypto/sha256.h"

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

// The content can also come from a pw::stream::Reader.
if (!pw::crypto::sha256::Hash(reader, 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#

Pigweed AI summary: This text describes how to verify a digital signature signed with ECDSA over the NIST P256 curve using C++ code. It includes two examples, one for verifying a signature with a single message and another for verifying a signature with a long and/or non-contiguous message. Both examples use the SHA256 hashing algorithm to generate a digest of the message, which is then used to verify the signature. Error handling is also included in the code.

  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#

Pigweed AI summary: The pw_crypto library offers crypto services that can be supported by different backend crypto libraries. One such backend is Mbed TLS, which is a mature and full-featured crypto library that implements cryptographic primitives, X.509 certificate manipulation, and SSL/TLS and DTLS protocols. It also has good support for interfacing with cryptographic accelerators and is popular for embedded systems. To use the Mbed TLS backend, the MbedTLS library needs to be installed and configured. Another backend option is Micro ECC

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

Mbed TLS#

Pigweed AI summary: The Mbed TLS project is a crypto library that implements cryptographic primitives, X.509 certificate manipulation, and SSL/TLS and DTLS protocols. It also has good support for interfacing with cryptographic accelerators. The project is popular for embedded systems due to its small code footprint. To use the Mbed TLS backend, the library needs to be installed and configured. The configuration can be done using GN or Bazel. For optimal code size and performance, the Mbed TLS library can be configured per

The Mbed TLS project is a mature and full-featured crypto library that implements cryptographic primitives, X.509 certificate manipulation and the SSL/TLS and DTLS protocols.

The project also has good support for interfacing to cryptographic accelerators.

The small code footprint makes the project suitable and popular for embedded systems.

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

# Install and configure MbedTLS
pw package install mbedtls
gn gen out --args='
    dir_pw_third_party_mbedtls=getenv("PW_PACKAGE_ROOT")+"/mbedtls"
    pw_crypto_SHA256_BACKEND="//pw_crypto:sha256_mbedtls_v3"
    pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_mbedtls_v3"
'

ninja -C out

If using Bazel, add the Mbed TLS repository to your WORKSPACE and select appropriate backends by adding them to your project’s platform:

platform(
  name = "my_platform",
   constraint_values = [
     "@pigweed//pw_crypto:sha256_mbedtls_backend",
     "@pigweed//pw_crypto:ecdsa_mbedtls_backend",
     # ... other constraint_values
   ],
)

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

Micro ECC#

Pigweed AI summary: Micro ECC is a library that needs to be installed and configured in order to be used. To install and configure Micro ECC, the command "pw package install micro-ecc" needs to be executed. The default configuration of Micro ECC uses big endian, but there is also a little-endian configuration available which can be used to reduce call stack frame use. To select the little-endian version, the command "pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_uecc_little_endian"" needs

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=getenv("PW_PACKAGE_ROOT")+"/micro-ecc"
    pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_uecc"
'

The default micro-ecc backend uses big endian as is standard practice. It also has a little-endian configuration which can be used to slightly reduce call stack frame use and/or when non pw_crypto clients use the same micro-ecc with a little-endian configuration. The little-endian version of micro-ecc can be selected with pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_uecc_little_endian"

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

Size Reports#

Pigweed AI summary: This section provides size reports for different crypto services, which can vary depending on the configurations. The table shows the label, segment, and delta for a backend that is not selected.

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

Label

Segment

Delta

No backend is selected.

(ALL)

0