1 /* 2 * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stdint.h> 9 #include <string.h> 10 11 #include <platform_def.h> 12 13 #include <common/debug.h> 14 #include <common/tbbr/cot_def.h> 15 #include <drivers/auth/auth_common.h> 16 #include <drivers/auth/auth_mod.h> 17 #include <drivers/auth/crypto_mod.h> 18 #include <drivers/auth/img_parser_mod.h> 19 #include <drivers/fwu/fwu.h> 20 #include <lib/fconf/fconf_tbbr_getter.h> 21 #include <plat/common/platform.h> 22 23 /* ASN.1 tags */ 24 #define ASN1_INTEGER 0x02 25 26 #define return_if_error(rc) \ 27 do { \ 28 if (rc != 0) { \ 29 return rc; \ 30 } \ 31 } while (0) 32 33 #pragma weak plat_set_nv_ctr2 34 #pragma weak plat_convert_pk 35 36 static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a, 37 const auth_param_type_desc_t *b) 38 { 39 if ((a->type == b->type) && (a->cookie == b->cookie)) { 40 return 0; 41 } 42 return 1; 43 } 44 45 /* 46 * This function obtains the requested authentication parameter data from the 47 * information extracted from the parent image after its authentication. 48 */ 49 static int auth_get_param(const auth_param_type_desc_t *param_type_desc, 50 const auth_img_desc_t *img_desc, 51 void **param, unsigned int *len) 52 { 53 int i; 54 55 if (img_desc->authenticated_data == NULL) 56 return 1; 57 58 for (i = 0 ; i < COT_MAX_VERIFIED_PARAMS ; i++) { 59 if (0 == cmp_auth_param_type_desc(param_type_desc, 60 img_desc->authenticated_data[i].type_desc)) { 61 *param = img_desc->authenticated_data[i].data.ptr; 62 *len = img_desc->authenticated_data[i].data.len; 63 return 0; 64 } 65 } 66 67 return 1; 68 } 69 70 /* 71 * Authenticate an image by matching the data hash 72 * 73 * This function implements 'AUTH_METHOD_HASH'. To authenticate an image using 74 * this method, the image must contain: 75 * 76 * - The data to calculate the hash from 77 * 78 * The parent image must contain: 79 * 80 * - The hash to be matched with (including hash algorithm) 81 * 82 * For a successful authentication, both hashes must match. The function calls 83 * the crypto-module to check this matching. 84 * 85 * Parameters: 86 * param: parameters to perform the hash authentication 87 * img_desc: pointer to image descriptor so we can know the image type 88 * and parent image 89 * img: pointer to image in memory 90 * img_len: length of image (in bytes) 91 * 92 * Return: 93 * 0 = success, Otherwise = error 94 */ 95 static int auth_hash(const auth_method_param_hash_t *param, 96 const auth_img_desc_t *img_desc, 97 void *img, unsigned int img_len) 98 { 99 void *data_ptr, *hash_der_ptr; 100 unsigned int data_len, hash_der_len; 101 int rc = 0; 102 103 /* Get the hash from the parent image. This hash will be DER encoded 104 * and contain the hash algorithm */ 105 rc = auth_get_param(param->hash, img_desc->parent, 106 &hash_der_ptr, &hash_der_len); 107 return_if_error(rc); 108 109 /* Get the data to be hashed from the current image */ 110 rc = img_parser_get_auth_param(img_desc->img_type, param->data, 111 img, img_len, &data_ptr, &data_len); 112 return_if_error(rc); 113 114 /* Ask the crypto module to verify this hash */ 115 rc = crypto_mod_verify_hash(data_ptr, data_len, 116 hash_der_ptr, hash_der_len); 117 118 return rc; 119 } 120 121 /* 122 * Authenticate by digital signature 123 * 124 * This function implements 'AUTH_METHOD_SIG'. To authenticate an image using 125 * this method, the image must contain: 126 * 127 * - Data to be signed 128 * - Signature 129 * - Signature algorithm 130 * 131 * We rely on the image parser module to extract this data from the image. 132 * The parent image must contain: 133 * 134 * - Public key (or a hash of it) 135 * 136 * If the parent image contains only a hash of the key, we will try to obtain 137 * the public key from the image itself (i.e. self-signed certificates). In that 138 * case, the signature verification is considered just an integrity check and 139 * the authentication is established by calculating the hash of the key and 140 * comparing it with the hash obtained from the parent. 141 * 142 * If the image has no parent (NULL), it means it has to be authenticated using 143 * the ROTPK stored in the platform. Again, this ROTPK could be the key itself 144 * or a hash of it. 145 * 146 * Return: 0 = success, Otherwise = error 147 */ 148 static int auth_signature(const auth_method_param_sig_t *param, 149 const auth_img_desc_t *img_desc, 150 void *img, unsigned int img_len) 151 { 152 void *data_ptr, *pk_ptr, *pk_plat_ptr, *sig_ptr, *sig_alg_ptr; 153 unsigned int data_len, pk_len, pk_plat_len, sig_len, sig_alg_len; 154 unsigned int flags = 0; 155 int rc = 0; 156 157 /* Get the data to be signed from current image */ 158 rc = img_parser_get_auth_param(img_desc->img_type, param->data, 159 img, img_len, &data_ptr, &data_len); 160 return_if_error(rc); 161 162 /* Get the signature from current image */ 163 rc = img_parser_get_auth_param(img_desc->img_type, param->sig, 164 img, img_len, &sig_ptr, &sig_len); 165 return_if_error(rc); 166 167 /* Get the signature algorithm from current image */ 168 rc = img_parser_get_auth_param(img_desc->img_type, param->alg, 169 img, img_len, &sig_alg_ptr, &sig_alg_len); 170 return_if_error(rc); 171 172 /* Get the public key from the parent. If there is no parent (NULL), 173 * the certificate has been signed with the ROTPK, so we have to get 174 * the PK from the platform */ 175 if (img_desc->parent != NULL) { 176 rc = auth_get_param(param->pk, img_desc->parent, 177 &pk_ptr, &pk_len); 178 return_if_error(rc); 179 } else { 180 /* 181 * Root certificates are signed with the ROTPK, so we have to 182 * get it from the platform. 183 */ 184 rc = plat_get_rotpk_info(param->pk->cookie, &pk_plat_ptr, 185 &pk_plat_len, &flags); 186 return_if_error(rc); 187 188 assert(is_rotpk_flags_valid(flags)); 189 190 /* Also retrieve the key from the image. */ 191 rc = img_parser_get_auth_param(img_desc->img_type, 192 param->pk, img, img_len, 193 &pk_ptr, &pk_len); 194 return_if_error(rc); 195 196 /* 197 * Validate the certificate's key against the platform ROTPK. 198 * 199 * Platform may store key in one of the following way - 200 * 1. Hash of ROTPK 201 * 2. Hash if prefixed, suffixed or modified ROTPK 202 * 3. Full ROTPK 203 */ 204 if ((flags & ROTPK_NOT_DEPLOYED) != 0U) { 205 NOTICE("ROTPK is not deployed on platform. " 206 "Skipping ROTPK verification.\n"); 207 } else if ((flags & ROTPK_IS_HASH) != 0U) { 208 /* 209 * platform may store the hash of a prefixed, 210 * suffixed or modified pk 211 */ 212 rc = plat_convert_pk(pk_ptr, pk_len, &pk_ptr, &pk_len); 213 return_if_error(rc); 214 215 /* 216 * The hash of the certificate's public key must match 217 * the hash of the ROTPK. 218 */ 219 rc = crypto_mod_verify_hash(pk_ptr, pk_len, 220 pk_plat_ptr, pk_plat_len); 221 return_if_error(rc); 222 } else { 223 /* Platform supports full ROTPK */ 224 if ((pk_len != pk_plat_len) || 225 (memcmp(pk_plat_ptr, pk_ptr, pk_len) != 0)) { 226 ERROR("plat and cert ROTPK len mismatch\n"); 227 return -1; 228 } 229 } 230 } 231 232 /* Ask the crypto module to verify the signature */ 233 rc = crypto_mod_verify_signature(data_ptr, data_len, 234 sig_ptr, sig_len, 235 sig_alg_ptr, sig_alg_len, 236 pk_ptr, pk_len); 237 238 return rc; 239 } 240 241 /* 242 * Authenticate by Non-Volatile counter 243 * 244 * To protect the system against rollback, the platform includes a non-volatile 245 * counter whose value can only be increased. All certificates include a counter 246 * value that should not be lower than the value stored in the platform. If the 247 * value is larger, the counter in the platform must be updated to the new value 248 * (provided it has been authenticated). 249 * 250 * Return: 0 = success, Otherwise = error 251 * Returns additionally, 252 * cert_nv_ctr -> NV counter value present in the certificate 253 * need_nv_ctr_upgrade = 0 -> platform NV counter upgrade is not needed 254 * need_nv_ctr_upgrade = 1 -> platform NV counter upgrade is needed 255 */ 256 static int auth_nvctr(const auth_method_param_nv_ctr_t *param, 257 const auth_img_desc_t *img_desc, 258 void *img, unsigned int img_len, 259 unsigned int *cert_nv_ctr, 260 bool *need_nv_ctr_upgrade) 261 { 262 unsigned char *p; 263 void *data_ptr = NULL; 264 unsigned int data_len, len, i; 265 unsigned int plat_nv_ctr; 266 int rc = 0; 267 bool is_trial_run = false; 268 269 /* Get the counter value from current image. The AM expects the IPM 270 * to return the counter value as a DER encoded integer */ 271 rc = img_parser_get_auth_param(img_desc->img_type, param->cert_nv_ctr, 272 img, img_len, &data_ptr, &data_len); 273 return_if_error(rc); 274 275 /* Parse the DER encoded integer */ 276 assert(data_ptr); 277 p = (unsigned char *)data_ptr; 278 279 /* 280 * Integers must be at least 3 bytes: 1 for tag, 1 for length, and 1 281 * for value. The first byte (tag) must be ASN1_INTEGER. 282 */ 283 if ((data_len < 3) || (*p != ASN1_INTEGER)) { 284 /* Invalid ASN.1 integer */ 285 return 1; 286 } 287 p++; 288 289 /* 290 * NV-counters are unsigned integers up to 31 bits. Trailing 291 * padding is not allowed. 292 */ 293 len = (unsigned int)*p; 294 if ((len > 4) || (data_len - 2 != len)) { 295 return 1; 296 } 297 p++; 298 299 /* Check the number is not negative */ 300 if (*p & 0x80) { 301 return 1; 302 } 303 304 /* Convert to unsigned int. This code is for a little-endian CPU */ 305 *cert_nv_ctr = 0; 306 for (i = 0; i < len; i++) { 307 *cert_nv_ctr = (*cert_nv_ctr << 8) | *p++; 308 } 309 310 /* Get the counter from the platform */ 311 rc = plat_get_nv_ctr(param->plat_nv_ctr->cookie, &plat_nv_ctr); 312 return_if_error(rc); 313 314 if (*cert_nv_ctr < plat_nv_ctr) { 315 /* Invalid NV-counter */ 316 return 1; 317 } else if (*cert_nv_ctr > plat_nv_ctr) { 318 #if PSA_FWU_SUPPORT && IMAGE_BL2 319 is_trial_run = fwu_is_trial_run_state(); 320 #endif /* PSA_FWU_SUPPORT && IMAGE_BL2 */ 321 *need_nv_ctr_upgrade = !is_trial_run; 322 } 323 324 return 0; 325 } 326 327 int plat_set_nv_ctr2(void *cookie, const auth_img_desc_t *img_desc __unused, 328 unsigned int nv_ctr) 329 { 330 return plat_set_nv_ctr(cookie, nv_ctr); 331 } 332 333 int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len, 334 void **hashed_pk_ptr, unsigned int *hashed_pk_len) 335 { 336 *hashed_pk_ptr = full_pk_ptr; 337 *hashed_pk_len = full_pk_len; 338 339 return 0; 340 } 341 342 /* 343 * Return the parent id in the output parameter '*parent_id' 344 * 345 * Return value: 346 * 0 = Image has parent, 1 = Image has no parent or parent is authenticated 347 */ 348 int auth_mod_get_parent_id(unsigned int img_id, unsigned int *parent_id) 349 { 350 const auth_img_desc_t *img_desc = NULL; 351 352 assert(parent_id != NULL); 353 /* Get the image descriptor */ 354 img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id); 355 356 /* Check if the image has no parent (ROT) */ 357 if (img_desc->parent == NULL) { 358 *parent_id = 0; 359 return 1; 360 } 361 362 /* Check if the parent has already been authenticated */ 363 if (auth_img_flags[img_desc->parent->img_id] & IMG_FLAG_AUTHENTICATED) { 364 *parent_id = 0; 365 return 1; 366 } 367 368 *parent_id = img_desc->parent->img_id; 369 return 0; 370 } 371 372 /* 373 * Initialize the different modules in the authentication framework 374 */ 375 void auth_mod_init(void) 376 { 377 /* Check we have a valid CoT registered */ 378 assert(cot_desc_ptr != NULL); 379 380 /* Image parser module */ 381 img_parser_init(); 382 } 383 384 /* 385 * Authenticate a certificate/image 386 * 387 * Return: 0 = success, Otherwise = error 388 */ 389 int auth_mod_verify_img(unsigned int img_id, 390 void *img_ptr, 391 unsigned int img_len) 392 { 393 const auth_img_desc_t *img_desc = NULL; 394 const auth_method_desc_t *auth_method = NULL; 395 void *param_ptr; 396 unsigned int param_len; 397 int rc, i; 398 unsigned int cert_nv_ctr = 0; 399 bool need_nv_ctr_upgrade = false; 400 bool sig_auth_done = false; 401 const auth_method_param_nv_ctr_t *nv_ctr_param = NULL; 402 403 /* Get the image descriptor from the chain of trust */ 404 img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id); 405 406 /* Ask the parser to check the image integrity */ 407 rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len); 408 return_if_error(rc); 409 410 /* Authenticate the image using the methods indicated in the image 411 * descriptor. */ 412 if (img_desc->img_auth_methods == NULL) 413 return 1; 414 for (i = 0 ; i < AUTH_METHOD_NUM ; i++) { 415 auth_method = &img_desc->img_auth_methods[i]; 416 switch (auth_method->type) { 417 case AUTH_METHOD_NONE: 418 rc = 0; 419 break; 420 case AUTH_METHOD_HASH: 421 rc = auth_hash(&auth_method->param.hash, 422 img_desc, img_ptr, img_len); 423 break; 424 case AUTH_METHOD_SIG: 425 rc = auth_signature(&auth_method->param.sig, 426 img_desc, img_ptr, img_len); 427 sig_auth_done = true; 428 break; 429 case AUTH_METHOD_NV_CTR: 430 nv_ctr_param = &auth_method->param.nv_ctr; 431 rc = auth_nvctr(nv_ctr_param, 432 img_desc, img_ptr, img_len, 433 &cert_nv_ctr, &need_nv_ctr_upgrade); 434 break; 435 default: 436 /* Unknown authentication method */ 437 rc = 1; 438 break; 439 } 440 return_if_error(rc); 441 } 442 443 /* 444 * Do platform NV counter upgrade only if the certificate gets 445 * authenticated, and platform NV-counter upgrade is needed. 446 */ 447 if (need_nv_ctr_upgrade && sig_auth_done) { 448 rc = plat_set_nv_ctr2(nv_ctr_param->plat_nv_ctr->cookie, 449 img_desc, cert_nv_ctr); 450 return_if_error(rc); 451 } 452 453 /* Extract the parameters indicated in the image descriptor to 454 * authenticate the children images. */ 455 if (img_desc->authenticated_data != NULL) { 456 for (i = 0 ; i < COT_MAX_VERIFIED_PARAMS ; i++) { 457 if (img_desc->authenticated_data[i].type_desc == NULL) { 458 continue; 459 } 460 461 /* Get the parameter from the image parser module */ 462 rc = img_parser_get_auth_param(img_desc->img_type, 463 img_desc->authenticated_data[i].type_desc, 464 img_ptr, img_len, ¶m_ptr, ¶m_len); 465 return_if_error(rc); 466 467 /* Check parameter size */ 468 if (param_len > img_desc->authenticated_data[i].data.len) { 469 return 1; 470 } 471 472 /* Copy the parameter for later use */ 473 memcpy((void *)img_desc->authenticated_data[i].data.ptr, 474 (void *)param_ptr, param_len); 475 } 476 } 477 478 /* Mark image as authenticated */ 479 auth_img_flags[img_desc->img_id] |= IMG_FLAG_AUTHENTICATED; 480 481 return 0; 482 } 483