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