• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
168To select Micro ECC, the library needs to be installed and configured.
169
170.. code-block:: sh
171
172   # Install and configure Micro ECC
173   pw package install micro-ecc
174   gn gen out --args='
175       dir_pw_third_party_micro_ecc=getenv("PW_PACKAGE_ROOT")+"/micro-ecc"
176       pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_uecc"
177   '
178
179The default micro-ecc backend uses big endian as is standard practice. It also
180has a little-endian configuration which can be used to slightly reduce call
181stack frame use and/or when non pw_crypto clients use the same micro-ecc
182with a little-endian configuration. The little-endian version of micro-ecc
183can be selected with ``pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_uecc_little_endian"``
184
185Note Micro-ECC does not implement any hashing functions, so you will need to use other backends for SHA256 functionality if needed.
186
187------------
188Size Reports
189------------
190
191Below are size reports for each crypto service. These vary across
192configurations.
193
194.. include:: size_report
195
196-------------
197API reference
198-------------
199.. doxygenfunction:: pw::crypto::ecdsa::VerifyP256Signature(ConstByteSpan public_key, ConstByteSpan digest, ConstByteSpan signature)
200.. doxygenfunction:: pw::crypto::sha256::Hash(ConstByteSpan message, ByteSpan out_digest)
201.. doxygenfunction:: pw::crypto::sha256::Hash(stream::Reader& reader, ByteSpan out_digest)
202.. doxygenvariable:: pw::crypto::sha256::kDigestSizeBytes
203.. doxygenfunction:: pw::crypto::sha256::Sha256::Final(ByteSpan out_digest)
204.. doxygenfunction:: pw::crypto::sha256::Sha256::Update(ConstByteSpan data)
205.. doxygenenum::     pw::crypto::sha256::Sha256State
206