Mate Toth-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 1 | ############################ |
| 2 | Initial Attestation Verifier |
| 3 | ############################ |
| 4 | This is a set of utility scripts for working with PSA Initial Attestation |
| 5 | Token, the structure of which is described here: |
| 6 | |
| 7 | https://tools.ietf.org/html/draft-tschofenig-rats-psa-token-05 |
| 8 | |
| 9 | The following utilities are provided: |
| 10 | |
| 11 | check_iat |
| 12 | Verifies the structure, and optionally the signature, of a token. |
| 13 | |
| 14 | compile_token |
| 15 | Creates a (optionally, signed) token from a YAML descriptions of the claims. |
| 16 | |
| 17 | decompile_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 | ************ |
| 23 | Installation |
| 24 | ************ |
| 25 | You can install the script using pip: |
| 26 | |
| 27 | .. code:: bash |
| 28 | |
| 29 | # Inside the directory containg this README |
| 30 | pip3 install . |
| 31 | |
| 32 | This should automatically install all the required dependencies. Please |
| 33 | see ``setup.py`` for the list of said dependencies. |
| 34 | |
| 35 | ***** |
| 36 | Usage |
| 37 | ***** |
| 38 | |
| 39 | .. note:: |
| 40 | You can use ``-h`` flag with any of the scripts to see their usage help. |
| 41 | |
| 42 | check_iat |
| 43 | --------- |
| 44 | |
| 45 | After installing, you should have ``check_iat`` script in your ``PATH``. The |
Mate Toth-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 46 | script expects two parameters: |
Mate Toth-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 47 | |
Mate Toth-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 48 | * a path to the signed IAT in COSE format |
| 49 | |
| 50 | * the token type |
| 51 | |
Mate Toth-Pal | b74e82e | 2022-10-07 16:06:04 +0200 | [diff] [blame] | 52 | You can find an example in the ``tests/data`` directory. |
Mate Toth-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 53 | |
| 54 | The script will extract the COSE payload and make sure that it is a |
Mate Toth-Pal | 5ebca51 | 2022-03-24 16:45:51 +0100 | [diff] [blame] | 55 | valid IAT (i.e. all mandatory fields are present, and all known |
Mate Toth-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 56 | fields have correct size/type): |
| 57 | |
| 58 | .. code:: bash |
| 59 | |
Mate Toth-Pal | b74e82e | 2022-10-07 16:06:04 +0200 | [diff] [blame] | 60 | $ check_iat -t PSA-IoT-Profile1-token tests/data/iat.cbor |
Mate Toth-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 61 | Token format OK |
| 62 | |
| 63 | If you want the script to verify the signature, you need to specify the |
| 64 | file containing the signing key in PEM format using -k option. The key |
Mate Toth-Pal | b74e82e | 2022-10-07 16:06:04 +0200 | [diff] [blame] | 65 | used to sign tests/data/iat.cbor is inside tests/data/key.pem. |
Mate Toth-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 66 | |
| 67 | :: |
| 68 | |
Mate Toth-Pal | b74e82e | 2022-10-07 16:06:04 +0200 | [diff] [blame] | 69 | $ check_iat -t PSA-IoT-Profile1-token -k tests/data/key.pem tests/data/iat.cbor |
Mate Toth-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 70 | Signature OK |
| 71 | Token format OK |
| 72 | |
| 73 | You can add a -p flag to the invocation in order to have the script |
| 74 | print out the decoded IAT in JSON format. It should look something like |
| 75 | this: |
| 76 | |
| 77 | .. code:: json |
| 78 | |
Mate Toth-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 79 | { |
| 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-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 115 | |
| 116 | compile_token |
| 117 | ------------- |
| 118 | |
| 119 | You can use this script to compile a YAML claims description into a COSE-wrapped |
| 120 | CBOR token: |
| 121 | |
| 122 | .. code:: bash |
| 123 | |
Mate Toth-Pal | b74e82e | 2022-10-07 16:06:04 +0200 | [diff] [blame] | 124 | $ compile_token -t PSA-IoT-Profile1-token -k tests/data/key.pem tests/data/iat.yaml > sample_token.cbor |
Mate Toth-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 125 | |
| 126 | *No validation* is performed as part of this, so there is no guarantee that a |
| 127 | valid IAT will be produced. |
| 128 | |
| 129 | You can omit the ``-k`` option, in which case, the resulting token will not be |
| 130 | signed, however it will still be wrapped in COSE "envelope". If you would like |
| 131 | to produce a pure CBOR encoding of the claims without a COSE wrapper, you can |
| 132 | use ``-r`` flag. |
| 133 | |
| 134 | |
| 135 | decompile_token |
| 136 | --------------- |
| 137 | |
| 138 | Decompile an IAT (or any COSE-wrapped CBOR object -- *no validation* is performed |
| 139 | as part of this) into a YAML description of its claims. |
| 140 | |
| 141 | |
| 142 | .. code:: bash |
| 143 | |
Mate Toth-Pal | b74e82e | 2022-10-07 16:06:04 +0200 | [diff] [blame] | 144 | $ decompile_token -t PSA-IoT-Profile1-token tests/data/iat.cbor |
Mate Toth-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 145 | 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-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 182 | |
| 183 | This description can then be compiled back into CBOR using ``compile_token``. |
| 184 | |
| 185 | |
| 186 | *********** |
| 187 | Mac0Message |
| 188 | *********** |
| 189 | |
| 190 | By default, the expectation is that the message will be wrapped using |
| 191 | Sign1Message COSE structure, however, the alternative Mac0Message structure |
| 192 | that uses HMAC with SHA256 algorithm rather than a signature is supported via |
| 193 | the ``-m mac`` flag: |
| 194 | |
| 195 | :: |
| 196 | |
Mate Toth-Pal | b74e82e | 2022-10-07 16:06:04 +0200 | [diff] [blame] | 197 | $ check_iat -t PSA-IoT-Profile1-token -m mac -k tests/data/hmac.key tests/data/iat-hmac.cbor |
Mate Toth-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 198 | Signature OK |
| 199 | Token format OK |
| 200 | |
| 201 | ******* |
| 202 | Testing |
| 203 | ******* |
| 204 | Tests can be run using ``nose2``: |
| 205 | |
| 206 | .. code:: bash |
| 207 | |
| 208 | pip install nose2 |
| 209 | |
| 210 | Then run by executing ``nose2`` in the root directory. |
| 211 | |
| 212 | |
| 213 | ******************* |
| 214 | Development Scripts |
| 215 | ******************* |
| 216 | The following utility scripts are contained within ``dev_scripts`` |
| 217 | subdirectory and were utilized in development of this tool. They are not |
| 218 | need to use the iat-verifier script, and can generally be ignored. |
| 219 | |
| 220 | .. code:: bash |
| 221 | |
| 222 | ./dev_scripts/generate-key.py OUTFILE |
| 223 | |
| 224 | Generate an ECDSA (NIST256p curve) signing key and write it in PEM |
| 225 | format to the specified file. |
| 226 | |
| 227 | .. code:: bash |
| 228 | |
| 229 | ./dev_scripts/generate-sample-iat.py KEYFILE OUTFILE |
| 230 | |
| 231 | Generate a sample token, signing it with the specified key, and writing |
| 232 | the output to the specified file. |
| 233 | |
| 234 | .. note:: |
| 235 | This script is deprecated -- use ``compile_token`` (see above) instead. |
| 236 | |
Mate Toth-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 237 | ********************* |
| 238 | Adding 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-Pal | c7404e9 | 2022-07-15 11:11:13 +0200 | [diff] [blame] | 247 | * ``CompositeAttestClaim`` is descendants of ``AttestationClaim``, for |
| 248 | details on how to use it see the documentation in the class definition. |
Mate Toth-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 249 | |
Mate Toth-Pal | c7404e9 | 2022-07-15 11:11:13 +0200 | [diff] [blame] | 250 | * For each claim, the methods ``get_claim_key(self=None)``, |
| 251 | ``get_claim_name(self=None)`` must be implemented. |
| 252 | |
Mate Toth-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 253 | * Other methods of ``AttestationClaim`` are optional to override. |
| 254 | |
Mate Toth-Pal | c7404e9 | 2022-07-15 11:11:13 +0200 | [diff] [blame] | 255 | * 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-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 269 | #. 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-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 275 | |
| 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-Pal | c7404e9 | 2022-07-15 11:11:13 +0200 | [diff] [blame] | 293 | For example see *iat-verifier/iatverifier/cca_token_verifier.py*. |
Mate Toth-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 294 | |
| 295 | #. Add handling of the new token type to the ``check_iat``, ``decompile_token``, |
| 296 | and ``compile_token`` scripts. |
| 297 | |
Mate Toth-Pal | 51b6198 | 2022-03-17 14:19:30 +0100 | [diff] [blame] | 298 | -------------- |
| 299 | |
Mate Toth-Pal | 530106f | 2022-05-03 15:29:49 +0200 | [diff] [blame] | 300 | *Copyright (c) 2019-2022, Arm Limited. All rights reserved.* |