diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 74a0a85..57f2c40 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -690,12 +690,32 @@ This function is mandatory when Trusted Board Boot is enabled. It sets a new counter value in the platform. The cookie in the first argument may be used to -select the counter (as explained in plat_get_nv_ctr()). +select the counter (as explained in plat_get_nv_ctr()). The second argument is +the updated counter value to be written to the NV counter. The function returns 0 on success. Any other value means the counter value could not be updated. +### Function: plat_set_nv_ctr2() + + Argument : void *, const auth_img_desc_t *, unsigned int + Return : int + +This function is optional when Trusted Board Boot is enabled. If this +interface is defined, then `plat_set_nv_ctr()` need not be defined. The +first argument passed is a cookie and is typically used to +differentiate between a Non Trusted NV Counter and a Trusted NV +Counter. The second argument is a pointer to an authentication image +descriptor and may be used to decide if the counter is allowed to be +updated or not. The third argument is the updated counter value to +be written to the NV counter. + +The function returns 0 on success. Any other value means the counter value +either could not be updated or the authentication image descriptor indicates +that it is not allowed to be updated. + + 2.3 Common mandatory function modifications --------------------------------- diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c index 88ef0b0..2c8643f 100644 --- a/drivers/auth/auth_mod.c +++ b/drivers/auth/auth_mod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -50,6 +50,8 @@ } \ } while (0) +#pragma weak plat_set_nv_ctr2 + /* Pointer to CoT */ extern const auth_img_desc_t *const cot_desc_ptr; extern unsigned int auth_img_flags[]; @@ -297,21 +299,20 @@ /* Invalid NV-counter */ return 1; } else if (cert_nv_ctr > plat_nv_ctr) { - if (img_desc->parent == NULL) { - /* This certificate has been signed with the ROT key. - * Update the platform counter value */ - rc = plat_set_nv_ctr(param->plat_nv_ctr->cookie, - cert_nv_ctr); - return_if_error(rc); - } else { - /* Secondary certificates cannot modify the counter */ - return 1; - } + rc = plat_set_nv_ctr2(param->plat_nv_ctr->cookie, + img_desc, cert_nv_ctr); + return_if_error(rc); } return 0; } +int plat_set_nv_ctr2(void *cookie, const auth_img_desc_t *img_desc __unused, + unsigned int nv_ctr) +{ + return plat_set_nv_ctr(cookie, nv_ctr); +} + /* * Return the parent id in the output parameter '*parent_id' * diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 5b4d11d..f904292 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -39,6 +39,7 @@ /******************************************************************************* * Forward declarations ******************************************************************************/ +struct auth_img_desc_s; struct meminfo; struct image_info; struct entry_point_info; @@ -274,6 +275,8 @@ unsigned int *flags); int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr); int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr); +int plat_set_nv_ctr2(void *cookie, const struct auth_img_desc_s *img_desc, + unsigned int nv_ctr); #if LOAD_IMAGE_V2 /******************************************************************************* diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 626b443..9b078ce 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -165,9 +165,11 @@ BL1_SOURCES += ${AUTH_SOURCES} \ bl1/tbbr/tbbr_img_desc.c \ - plat/arm/common/arm_bl1_fwu.c + plat/arm/common/arm_bl1_fwu.c \ + plat/common/tbbr/plat_tbbr.c - BL2_SOURCES += ${AUTH_SOURCES} + BL2_SOURCES += ${AUTH_SOURCES} \ + plat/common/tbbr/plat_tbbr.c $(eval $(call FWU_FIP_ADD_IMG,NS_BL2U,--fwu)) diff --git a/plat/common/tbbr/plat_tbbr.c b/plat/common/tbbr/plat_tbbr.c new file mode 100644 index 0000000..475564a --- /dev/null +++ b/plat/common/tbbr/plat_tbbr.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +/* + * Store a new non-volatile counter value. This implementation + * only allows updating of the platform's Trusted NV counter when a + * certificate protected by the Trusted NV counter is signed with + * the ROT key. This avoids a compromised secondary certificate from + * updating the platform's Trusted NV counter, which could lead to the + * platform becoming unusable. The function is suitable for all TBBR + * compliant platforms. + * + * Return: 0 = success, Otherwise = error + */ +int plat_set_nv_ctr2(void *cookie, const auth_img_desc_t *img_desc, + unsigned int nv_ctr) +{ + int trusted_nv_ctr; + + assert(cookie != NULL); + assert(img_desc != NULL); + + trusted_nv_ctr = strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0; + + /* + * Only update the Trusted NV Counter if the certificate + * has been signed with the ROT key. Non Trusted NV counter + * updates are unconditional. + */ + if (!trusted_nv_ctr || (trusted_nv_ctr && img_desc->parent == NULL)) + return plat_set_nv_ctr(cookie, nv_ctr); + + /* + * Trusted certificates not signed with the ROT key are not + * allowed to update the Trusted NV Counter. + */ + return 1; +}