xref: /aosp_15_r20/external/pigweed/pw_crypto/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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