blob: b9e220e5c8b0e2cf7e0f1a5e0dab6dd6bf299f31 [file] [log] [blame]
Mate Toth-Pal51b61982022-03-17 14:19:30 +01001############################
2Initial Attestation Verifier
3############################
4This is a set of utility scripts for working with PSA Initial Attestation
5Token, the structure of which is described here:
6
7 https://tools.ietf.org/html/draft-tschofenig-rats-psa-token-05
8
9The following utilities are provided:
10
11check_iat
12 Verifies the structure, and optionally the signature, of a token.
13
14compile_token
15 Creates a (optionally, signed) token from a YAML descriptions of the claims.
16
17decompile_token
18 Generates a YAML descriptions of the claims contained within a token. (Note:
19 this description can then be compiled back into a token using compile_token.)
20
21
22************
23Installation
24************
25You can install the script using pip:
26
27.. code:: bash
28
29 # Inside the directory containg this README
30 pip3 install .
31
32This should automatically install all the required dependencies. Please
33see ``setup.py`` for the list of said dependencies.
34
35*****
36Usage
37*****
38
39.. note::
40 You can use ``-h`` flag with any of the scripts to see their usage help.
41
42check_iat
43---------
44
45After installing, you should have ``check_iat`` script in your ``PATH``. The
Mate Toth-Pal530106f2022-05-03 15:29:49 +020046script expects two parameters:
Mate Toth-Pal51b61982022-03-17 14:19:30 +010047
Mate Toth-Pal530106f2022-05-03 15:29:49 +020048* a path to the signed IAT in COSE format
49
50* the token type
51
Mate Toth-Palb74e82e2022-10-07 16:06:04 +020052You can find an example in the ``tests/data`` directory.
Mate Toth-Pal51b61982022-03-17 14:19:30 +010053
54The script will extract the COSE payload and make sure that it is a
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010055valid IAT (i.e. all mandatory fields are present, and all known
Mate Toth-Pal51b61982022-03-17 14:19:30 +010056fields have correct size/type):
57
58.. code:: bash
59
Mate Toth-Palb74e82e2022-10-07 16:06:04 +020060 $ check_iat -t PSA-IoT-Profile1-token tests/data/iat.cbor
Mate Toth-Pal51b61982022-03-17 14:19:30 +010061 Token format OK
62
63If you want the script to verify the signature, you need to specify the
64file containing the signing key in PEM format using -k option. The key
Mate Toth-Palb74e82e2022-10-07 16:06:04 +020065used to sign tests/data/iat.cbor is inside tests/data/key.pem.
Mate Toth-Pal51b61982022-03-17 14:19:30 +010066
67::
68
Mate Toth-Palb74e82e2022-10-07 16:06:04 +020069 $ check_iat -t PSA-IoT-Profile1-token -k tests/data/key.pem tests/data/iat.cbor
Mate Toth-Pal51b61982022-03-17 14:19:30 +010070 Signature OK
71 Token format OK
72
73You can add a -p flag to the invocation in order to have the script
74print out the decoded IAT in JSON format. It should look something like
75this:
76
77.. code:: json
78
Mate Toth-Pal530106f2022-05-03 15:29:49 +020079 {
80 "INSTANCE_ID": "b'0107060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
81 "IMPLEMENTATION_ID": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
82 "CHALLENGE": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
83 "CLIENT_ID": 2,
84 "SECURITY_LIFECYCLE": "SL_SECURED",
85 "PROFILE_ID": "http://example.com",
86 "BOOT_SEED": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
87 "SW_COMPONENTS": [
88 {
89 "SW_COMPONENT_TYPE": "BL",
90 "SIGNER_ID": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
91 "SW_COMPONENT_VERSION": "3.4.2",
92 "MEASUREMENT_VALUE": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
93 "MEASUREMENT_DESCRIPTION": "TF-M_SHA256MemPreXIP"
94 },
95 {
96 "SW_COMPONENT_TYPE": "M1",
97 "SIGNER_ID": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
98 "SW_COMPONENT_VERSION": "1.2",
99 "MEASUREMENT_VALUE": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'"
100 },
101 {
102 "SW_COMPONENT_TYPE": "M2",
103 "SIGNER_ID": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
104 "SW_COMPONENT_VERSION": "1.2.3",
105 "MEASUREMENT_VALUE": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'"
106 },
107 {
108 "SW_COMPONENT_TYPE": "M3",
109 "SIGNER_ID": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
110 "SW_COMPONENT_VERSION": "1",
111 "MEASUREMENT_VALUE": "b'07060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'"
112 }
113 ]
114 }
Mate Toth-Pal51b61982022-03-17 14:19:30 +0100115
116compile_token
117-------------
118
119You can use this script to compile a YAML claims description into a COSE-wrapped
120CBOR token:
121
122.. code:: bash
123
Mate Toth-Palb74e82e2022-10-07 16:06:04 +0200124 $ compile_token -t PSA-IoT-Profile1-token -k tests/data/key.pem tests/data/iat.yaml > sample_token.cbor
Mate Toth-Pal51b61982022-03-17 14:19:30 +0100125
126*No validation* is performed as part of this, so there is no guarantee that a
127valid IAT will be produced.
128
129You can omit the ``-k`` option, in which case, the resulting token will not be
130signed, however it will still be wrapped in COSE "envelope". If you would like
131to produce a pure CBOR encoding of the claims without a COSE wrapper, you can
132use ``-r`` flag.
133
134
135decompile_token
136---------------
137
138Decompile an IAT (or any COSE-wrapped CBOR object -- *no validation* is performed
139as part of this) into a YAML description of its claims.
140
141
142.. code:: bash
143
Mate Toth-Palb74e82e2022-10-07 16:06:04 +0200144 $ decompile_token -t PSA-IoT-Profile1-token tests/data/iat.cbor
Mate Toth-Pal530106f2022-05-03 15:29:49 +0200145 boot_seed: !!binary |
146 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
147 challenge: !!binary |
148 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
149 client_id: 2
150 implementation_id: !!binary |
151 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
152 instance_id: !!binary |
153 AQcGBQQDAgEADw4NDAsKCQgXFhUUExIREB8eHRwbGhkY
154 profile_id: http://example.com
155 security_lifecycle: SL_SECURED
156 sw_components:
157 - measurement_description: TF-M_SHA256MemPreXIP
158 measurement_value: !!binary |
159 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
160 signer_id: !!binary |
161 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
162 sw_component_type: BL
163 sw_component_version: 3.4.2
164 - measurement_value: !!binary |
165 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
166 signer_id: !!binary |
167 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
168 sw_component_type: M1
169 sw_component_version: '1.2'
170 - measurement_value: !!binary |
171 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
172 signer_id: !!binary |
173 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
174 sw_component_type: M2
175 sw_component_version: 1.2.3
176 - measurement_value: !!binary |
177 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
178 signer_id: !!binary |
179 BwYFBAMCAQAPDg0MCwoJCBcWFRQTEhEQHx4dHBsaGRg=
180 sw_component_type: M3
181 sw_component_version: '1'
Mate Toth-Pal51b61982022-03-17 14:19:30 +0100182
183This description can then be compiled back into CBOR using ``compile_token``.
184
185
186***********
187Mac0Message
188***********
189
190By default, the expectation is that the message will be wrapped using
191Sign1Message COSE structure, however, the alternative Mac0Message structure
192that uses HMAC with SHA256 algorithm rather than a signature is supported via
193the ``-m mac`` flag:
194
195::
196
Mate Toth-Palb74e82e2022-10-07 16:06:04 +0200197 $ check_iat -t PSA-IoT-Profile1-token -m mac -k tests/data/hmac.key tests/data/iat-hmac.cbor
Mate Toth-Pal51b61982022-03-17 14:19:30 +0100198 Signature OK
199 Token format OK
200
201*******
202Testing
203*******
204Tests can be run using ``nose2``:
205
206.. code:: bash
207
208 pip install nose2
209
210Then run by executing ``nose2`` in the root directory.
211
212
213*******************
214Development Scripts
215*******************
216The following utility scripts are contained within ``dev_scripts``
217subdirectory and were utilized in development of this tool. They are not
218need to use the iat-verifier script, and can generally be ignored.
219
220.. code:: bash
221
222 ./dev_scripts/generate-key.py OUTFILE
223
224Generate an ECDSA (NIST256p curve) signing key and write it in PEM
225format to the specified file.
226
227.. code:: bash
228
229 ./dev_scripts/generate-sample-iat.py KEYFILE OUTFILE
230
231Generate a sample token, signing it with the specified key, and writing
232the output to the specified file.
233
234.. note::
235 This script is deprecated -- use ``compile_token`` (see above) instead.
236
Mate Toth-Pal530106f2022-05-03 15:29:49 +0200237*********************
238Adding new token type
239*********************
240
241#. Create a file with the claims for the new token type in
242 `tf-m-tools/iat-verifier/iatverifier`.
243
244 * For each claim a new class must be created that inherits from
245 ``AttestationClaim`` or from one of its descendants
246
Mate Toth-Palc7404e92022-07-15 11:11:13 +0200247 * ``CompositeAttestClaim`` is descendants of ``AttestationClaim``, for
248 details on how to use it see the documentation in the class definition.
Mate Toth-Pal530106f2022-05-03 15:29:49 +0200249
Mate Toth-Palc7404e92022-07-15 11:11:13 +0200250 * For each claim, the methods ``get_claim_key(self=None)``,
251 ``get_claim_name(self=None)`` must be implemented.
252
Mate Toth-Pal530106f2022-05-03 15:29:49 +0200253 * Other methods of ``AttestationClaim`` are optional to override.
254
Mate Toth-Palc7404e92022-07-15 11:11:13 +0200255 * Any claim that inherits from ``AttestationClaim`` might have a ``verify``
256 method (``def verify(self, token_item):``). This method is called when the
257 ``verify()`` method of a ``TokenItem`` object is called. ``TokenItem``'s
258 ``verify()`` method walks up the inheritance tree of the ``claim_type``
259 object's class in that ``TokenItem``. If a class in the walk path has a
260 ``verify()`` method, calls it. For further details see ``TokenItem``'s
261 ``_call_verify_with_parents()`` method.
262
263 Any verify method needs to call ``AttestationClaim``'s ``error()`` or
264 ``warning()`` in case of a problem. If the actual class inherits from
265 ``AttestationTokenVerifier`` this can be done like
266 ``self.error('Meaningful error message.')``. In other cases
267 ``self.verifier.error('Meaningful error message.')``
268
Mate Toth-Pal530106f2022-05-03 15:29:49 +0200269#. Create a file for the new token in `tf-m-tools/iat-verifier/iatverifier`.
270
271 * Create a new class for the token type. It must inherit from the class
272 ``AttestationTokenVerifier``.
273
274 * Implement ``get_claim_key(self=None)`` and ``get_claim_name(self=None)``
Mate Toth-Pal530106f2022-05-03 15:29:49 +0200275
276 * Implement the ``__init__(self, ...)`` function. This function must create a
277 list with the claims that are accepted by this token. (Note that the
278 ``AttestationTokenVerifier`` class inherits from ``AttestationClaim``. this
279 makes it possible to create nested token). Each item is the list is a
280 tuple:
281
282 * first element is the class of the claim
283
284 * Second is a dictionary containing the ``__init__`` function parameters
285 for the claim
286
287 * the key is the name of the parameter
288
289 * the value is the value of the parameter
290
291 The list of claims must be passed to the init function of the base class.
292
Mate Toth-Palc7404e92022-07-15 11:11:13 +0200293 For example see *iat-verifier/iatverifier/cca_token_verifier.py*.
Mate Toth-Pal530106f2022-05-03 15:29:49 +0200294
295#. Add handling of the new token type to the ``check_iat``, ``decompile_token``,
296 and ``compile_token`` scripts.
297
Mate Toth-Pal51b61982022-03-17 14:19:30 +0100298--------------
299
Mate Toth-Pal530106f2022-05-03 15:29:49 +0200300*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*