1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_crypto: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker========= 4*61c4878aSAndroid Build Coastguard Workerpw_crypto 5*61c4878aSAndroid Build Coastguard Worker========= 6*61c4878aSAndroid Build Coastguard WorkerA set of safe (read: easy to use, hard to misuse) crypto APIs. 7*61c4878aSAndroid Build Coastguard Worker 8*61c4878aSAndroid Build Coastguard WorkerThe following crypto services are provided by this module. 9*61c4878aSAndroid Build Coastguard Worker 10*61c4878aSAndroid Build Coastguard Worker1. Hashing a message with `SHA256`_. 11*61c4878aSAndroid Build Coastguard Worker2. Verifying a digital signature signed with `ECDSA`_ over the NIST P256 curve. 12*61c4878aSAndroid Build Coastguard Worker3. Many more to come ... 13*61c4878aSAndroid Build Coastguard Worker 14*61c4878aSAndroid Build Coastguard Worker------ 15*61c4878aSAndroid Build Coastguard WorkerSHA256 16*61c4878aSAndroid Build Coastguard Worker------ 17*61c4878aSAndroid Build Coastguard Worker 18*61c4878aSAndroid Build Coastguard Worker1. Obtaining a oneshot digest. 19*61c4878aSAndroid Build Coastguard Worker 20*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 21*61c4878aSAndroid Build Coastguard Worker 22*61c4878aSAndroid Build Coastguard Worker #include "pw_crypto/sha256.h" 23*61c4878aSAndroid Build Coastguard Worker 24*61c4878aSAndroid Build Coastguard Worker std::byte digest[32]; 25*61c4878aSAndroid Build Coastguard Worker if (!pw::crypto::sha256::Hash(message, digest).ok()) { 26*61c4878aSAndroid Build Coastguard Worker // Handle errors. 27*61c4878aSAndroid Build Coastguard Worker } 28*61c4878aSAndroid Build Coastguard Worker 29*61c4878aSAndroid Build Coastguard Worker // The content can also come from a pw::stream::Reader. 30*61c4878aSAndroid Build Coastguard Worker if (!pw::crypto::sha256::Hash(reader, digest).ok()) { 31*61c4878aSAndroid Build Coastguard Worker // Handle errors. 32*61c4878aSAndroid Build Coastguard Worker } 33*61c4878aSAndroid Build Coastguard Worker 34*61c4878aSAndroid Build Coastguard Worker2. Hashing a long, potentially non-contiguous message. 35*61c4878aSAndroid Build Coastguard Worker 36*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 37*61c4878aSAndroid Build Coastguard Worker 38*61c4878aSAndroid Build Coastguard Worker #include "pw_crypto/sha256.h" 39*61c4878aSAndroid Build Coastguard Worker 40*61c4878aSAndroid Build Coastguard Worker std::byte digest[32]; 41*61c4878aSAndroid Build Coastguard Worker 42*61c4878aSAndroid Build Coastguard Worker if (!pw::crypto::sha256::Sha256() 43*61c4878aSAndroid Build Coastguard Worker .Update(chunk1).Update(chunk2).Update(chunk...) 44*61c4878aSAndroid Build Coastguard Worker .Final().ok()) { 45*61c4878aSAndroid Build Coastguard Worker // Handle errors. 46*61c4878aSAndroid Build Coastguard Worker } 47*61c4878aSAndroid Build Coastguard Worker 48*61c4878aSAndroid Build Coastguard Worker----- 49*61c4878aSAndroid Build Coastguard WorkerECDSA 50*61c4878aSAndroid Build Coastguard Worker----- 51*61c4878aSAndroid Build Coastguard Worker 52*61c4878aSAndroid Build Coastguard Worker1. Verifying a digital signature signed with ECDSA over the NIST P256 curve. 53*61c4878aSAndroid Build Coastguard Worker 54*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 55*61c4878aSAndroid Build Coastguard Worker 56*61c4878aSAndroid Build Coastguard Worker #include "pw_crypto/sha256.h" 57*61c4878aSAndroid Build Coastguard Worker 58*61c4878aSAndroid Build Coastguard Worker std::byte digest[32]; 59*61c4878aSAndroid Build Coastguard Worker if (!pw::crypto::sha256::Hash(message, digest).ok()) { 60*61c4878aSAndroid Build Coastguard Worker // handle errors. 61*61c4878aSAndroid Build Coastguard Worker } 62*61c4878aSAndroid Build Coastguard Worker 63*61c4878aSAndroid Build Coastguard Worker if (!pw::crypto::ecdsa::VerifyP256Signature(public_key, digest, 64*61c4878aSAndroid Build Coastguard Worker signature).ok()) { 65*61c4878aSAndroid Build Coastguard Worker // handle errors. 66*61c4878aSAndroid Build Coastguard Worker } 67*61c4878aSAndroid Build Coastguard Worker 68*61c4878aSAndroid Build Coastguard Worker2. Verifying a digital signature signed with ECDSA over the NIST P256 curve, 69*61c4878aSAndroid Build Coastguard Worker with a long and/or non-contiguous message. 70*61c4878aSAndroid Build Coastguard Worker 71*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 72*61c4878aSAndroid Build Coastguard Worker 73*61c4878aSAndroid Build Coastguard Worker #include "pw_crypto/sha256.h" 74*61c4878aSAndroid Build Coastguard Worker 75*61c4878aSAndroid Build Coastguard Worker std::byte digest[32]; 76*61c4878aSAndroid Build Coastguard Worker 77*61c4878aSAndroid Build Coastguard Worker if (!pw::crypto::sha256::Sha256() 78*61c4878aSAndroid Build Coastguard Worker .Update(chunk1).Update(chunk2).Update(chunkN) 79*61c4878aSAndroid Build Coastguard Worker .Final(digest).ok()) { 80*61c4878aSAndroid Build Coastguard Worker // Handle errors. 81*61c4878aSAndroid Build Coastguard Worker } 82*61c4878aSAndroid Build Coastguard Worker 83*61c4878aSAndroid Build Coastguard Worker if (!pw::crypto::ecdsa::VerifyP256Signature(public_key, digest, 84*61c4878aSAndroid Build Coastguard Worker signature).ok()) { 85*61c4878aSAndroid Build Coastguard Worker // Handle errors. 86*61c4878aSAndroid Build Coastguard Worker } 87*61c4878aSAndroid Build Coastguard Worker 88*61c4878aSAndroid Build Coastguard Worker------------- 89*61c4878aSAndroid Build Coastguard WorkerConfiguration 90*61c4878aSAndroid Build Coastguard Worker------------- 91*61c4878aSAndroid Build Coastguard Worker 92*61c4878aSAndroid Build Coastguard WorkerThe crypto services offered by pw_crypto can be backed by different backend 93*61c4878aSAndroid Build Coastguard Workercrypto libraries. 94*61c4878aSAndroid Build Coastguard Worker 95*61c4878aSAndroid Build Coastguard WorkerMbed TLS 96*61c4878aSAndroid Build Coastguard Worker======== 97*61c4878aSAndroid Build Coastguard Worker 98*61c4878aSAndroid Build Coastguard WorkerThe `Mbed TLS project <https://www.trustedfirmware.org/projects/mbed-tls/>`_ 99*61c4878aSAndroid Build Coastguard Workeris a mature and full-featured crypto library that implements cryptographic 100*61c4878aSAndroid Build Coastguard Workerprimitives, X.509 certificate manipulation and the SSL/TLS and DTLS protocols. 101*61c4878aSAndroid Build Coastguard Worker 102*61c4878aSAndroid Build Coastguard WorkerThe project also has good support for interfacing to cryptographic accelerators. 103*61c4878aSAndroid Build Coastguard Worker 104*61c4878aSAndroid Build Coastguard WorkerThe small code footprint makes the project suitable and popular for embedded 105*61c4878aSAndroid Build Coastguard Workersystems. 106*61c4878aSAndroid Build Coastguard Worker 107*61c4878aSAndroid Build Coastguard WorkerTo select the Mbed TLS backend, the MbedTLS library needs to be installed and 108*61c4878aSAndroid Build Coastguard Workerconfigured. If using GN, do, 109*61c4878aSAndroid Build Coastguard Worker 110*61c4878aSAndroid Build Coastguard Worker.. code-block:: sh 111*61c4878aSAndroid Build Coastguard Worker 112*61c4878aSAndroid Build Coastguard Worker # Install and configure MbedTLS 113*61c4878aSAndroid Build Coastguard Worker pw package install mbedtls 114*61c4878aSAndroid Build Coastguard Worker gn gen out --args=' 115*61c4878aSAndroid Build Coastguard Worker dir_pw_third_party_mbedtls=getenv("PW_PACKAGE_ROOT")+"/mbedtls" 116*61c4878aSAndroid Build Coastguard Worker pw_crypto_SHA256_BACKEND="//pw_crypto:sha256_mbedtls_v3" 117*61c4878aSAndroid Build Coastguard Worker pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_mbedtls_v3" 118*61c4878aSAndroid Build Coastguard Worker ' 119*61c4878aSAndroid Build Coastguard Worker 120*61c4878aSAndroid Build Coastguard Worker ninja -C out 121*61c4878aSAndroid Build Coastguard Worker 122*61c4878aSAndroid Build Coastguard WorkerIf using Bazel, add the Mbed TLS repository to your WORKSPACE and select 123*61c4878aSAndroid Build Coastguard Workerappropriate backends by adding them to your project's `platform 124*61c4878aSAndroid Build Coastguard Worker<https://bazel.build/extending/platforms>`_: 125*61c4878aSAndroid Build Coastguard Worker 126*61c4878aSAndroid Build Coastguard Worker.. code-block:: python 127*61c4878aSAndroid Build Coastguard Worker 128*61c4878aSAndroid Build Coastguard Worker platform( 129*61c4878aSAndroid Build Coastguard Worker name = "my_platform", 130*61c4878aSAndroid Build Coastguard Worker constraint_values = [ 131*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_crypto:sha256_mbedtls_backend", 132*61c4878aSAndroid Build Coastguard Worker "@pigweed//pw_crypto:ecdsa_mbedtls_backend", 133*61c4878aSAndroid Build Coastguard Worker # ... other constraint_values 134*61c4878aSAndroid Build Coastguard Worker ], 135*61c4878aSAndroid Build Coastguard Worker ) 136*61c4878aSAndroid Build Coastguard Worker 137*61c4878aSAndroid Build Coastguard WorkerFor optimal code size and/or performance, the Mbed TLS library can be configured 138*61c4878aSAndroid Build Coastguard Workerper product. Mbed TLS configuration is achieved by turning on and off MBEDTLS_* 139*61c4878aSAndroid Build Coastguard Workeroptions in a config.h file. See //third_party/mbedtls for how this is done. 140*61c4878aSAndroid Build Coastguard Worker 141*61c4878aSAndroid Build Coastguard Worker``pw::crypto::sha256`` does not need any special configuration as it uses the 142*61c4878aSAndroid Build Coastguard Workermbedtls_sha256_* APIs directly. However you can optionally turn on 143*61c4878aSAndroid Build Coastguard Worker``MBEDTLS_SHA256_SMALLER`` to further reduce the code size to from 3KiB to 144*61c4878aSAndroid Build Coastguard Worker~1.8KiB at a ~30% slowdown cost (Cortex-M4). 145*61c4878aSAndroid Build Coastguard Worker 146*61c4878aSAndroid Build Coastguard Worker.. code-block:: c 147*61c4878aSAndroid Build Coastguard Worker 148*61c4878aSAndroid Build Coastguard Worker #define MBEDTLS_SHA256_SMALLER 149*61c4878aSAndroid Build Coastguard Worker 150*61c4878aSAndroid Build Coastguard Worker``pw::crypto::ecdsa`` requires the following minimum configurations which yields 151*61c4878aSAndroid Build Coastguard Workera code size of ~12KiB. 152*61c4878aSAndroid Build Coastguard Worker 153*61c4878aSAndroid Build Coastguard Worker.. code-block:: c 154*61c4878aSAndroid Build Coastguard Worker 155*61c4878aSAndroid Build Coastguard Worker #define MBEDTLS_BIGNUM_C 156*61c4878aSAndroid Build Coastguard Worker #define MBEDTLS_ECP_C 157*61c4878aSAndroid Build Coastguard Worker #define MBEDTLS_ECDSA_C 158*61c4878aSAndroid Build Coastguard Worker // The ASN1 options are needed only because mbedtls considers and verifies 159*61c4878aSAndroid Build Coastguard Worker // them (in check_config.h) as dependencies of MBEDTLS_ECDSA_C. 160*61c4878aSAndroid Build Coastguard Worker #define MBEDTLS_ASN1_WRITE_C 161*61c4878aSAndroid Build Coastguard Worker #define MBEDTLS_ASN1_PARSE_C 162*61c4878aSAndroid Build Coastguard Worker #define MBEDTLS_ECP_NO_INTERNAL_RNG 163*61c4878aSAndroid Build Coastguard Worker #define MBEDTLS_ECP_DP_SECP256R1_ENABLED 164*61c4878aSAndroid Build Coastguard Worker 165*61c4878aSAndroid Build Coastguard WorkerMicro ECC 166*61c4878aSAndroid Build Coastguard Worker========= 167*61c4878aSAndroid Build Coastguard Worker 168*61c4878aSAndroid Build Coastguard Worker.. Warning:: 169*61c4878aSAndroid Build Coastguard Worker Micro ECC's upstream hasn't received any updates since April 2023. 170*61c4878aSAndroid Build Coastguard Worker Please investigate to make sure that it meets your product's security 171*61c4878aSAndroid Build Coastguard Worker requirements before use. 172*61c4878aSAndroid Build Coastguard Worker 173*61c4878aSAndroid Build Coastguard WorkerTo select Micro ECC, the library needs to be installed and configured. 174*61c4878aSAndroid Build Coastguard Worker 175*61c4878aSAndroid Build Coastguard Worker.. code-block:: sh 176*61c4878aSAndroid Build Coastguard Worker 177*61c4878aSAndroid Build Coastguard Worker # Install and configure Micro ECC 178*61c4878aSAndroid Build Coastguard Worker pw package install micro-ecc 179*61c4878aSAndroid Build Coastguard Worker gn gen out --args=' 180*61c4878aSAndroid Build Coastguard Worker dir_pw_third_party_micro_ecc=getenv("PW_PACKAGE_ROOT")+"/micro-ecc" 181*61c4878aSAndroid Build Coastguard Worker pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_uecc" 182*61c4878aSAndroid Build Coastguard Worker ' 183*61c4878aSAndroid Build Coastguard Worker 184*61c4878aSAndroid Build Coastguard WorkerThe default micro-ecc backend uses big endian as is standard practice. It also 185*61c4878aSAndroid Build Coastguard Workerhas a little-endian configuration which can be used to slightly reduce call 186*61c4878aSAndroid Build Coastguard Workerstack frame use and/or when non pw_crypto clients use the same micro-ecc 187*61c4878aSAndroid Build Coastguard Workerwith a little-endian configuration. The little-endian version of micro-ecc 188*61c4878aSAndroid Build Coastguard Workercan be selected with ``pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_uecc_little_endian"`` 189*61c4878aSAndroid Build Coastguard Worker 190*61c4878aSAndroid Build Coastguard WorkerNote Micro-ECC does not implement any hashing functions, so you will need to use other backends for SHA256 functionality if needed. 191*61c4878aSAndroid Build Coastguard Worker 192*61c4878aSAndroid Build Coastguard Worker------------ 193*61c4878aSAndroid Build Coastguard WorkerSize Reports 194*61c4878aSAndroid Build Coastguard Worker------------ 195*61c4878aSAndroid Build Coastguard Worker 196*61c4878aSAndroid Build Coastguard WorkerBelow are size reports for each crypto service. These vary across 197*61c4878aSAndroid Build Coastguard Workerconfigurations. 198*61c4878aSAndroid Build Coastguard Worker 199*61c4878aSAndroid Build Coastguard Worker.. include:: size_report 200*61c4878aSAndroid Build Coastguard Worker 201*61c4878aSAndroid Build Coastguard Worker------------- 202*61c4878aSAndroid Build Coastguard WorkerAPI reference 203*61c4878aSAndroid Build Coastguard Worker------------- 204*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: pw::crypto::ecdsa::VerifyP256Signature(ConstByteSpan public_key, ConstByteSpan digest, ConstByteSpan signature) 205*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: pw::crypto::sha256::Hash(ConstByteSpan message, ByteSpan out_digest) 206*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: pw::crypto::sha256::Hash(stream::Reader& reader, ByteSpan out_digest) 207*61c4878aSAndroid Build Coastguard Worker.. doxygenvariable:: pw::crypto::sha256::kDigestSizeBytes 208*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: pw::crypto::sha256::Sha256::Final(ByteSpan out_digest) 209*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: pw::crypto::sha256::Sha256::Update(ConstByteSpan data) 210*61c4878aSAndroid Build Coastguard Worker.. doxygenenum:: pw::crypto::sha256::Sha256State 211