1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <stdint.h> 9*91f16700Schasinglulu #include <string.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <lib/mmio.h> 12*91f16700Schasinglulu #include <lib/fconf/fconf.h> 13*91f16700Schasinglulu #include <plat/arm/common/plat_arm.h> 14*91f16700Schasinglulu #include <plat/arm/common/fconf_nv_cntr_getter.h> 15*91f16700Schasinglulu #include <plat/common/platform.h> 16*91f16700Schasinglulu #include <platform_def.h> 17*91f16700Schasinglulu #include <tools_share/cca_oid.h> 18*91f16700Schasinglulu 19*91f16700Schasinglulu /* 20*91f16700Schasinglulu * Return the ROTPK hash in the following ASN.1 structure in DER format: 21*91f16700Schasinglulu * 22*91f16700Schasinglulu * AlgorithmIdentifier ::= SEQUENCE { 23*91f16700Schasinglulu * algorithm OBJECT IDENTIFIER, 24*91f16700Schasinglulu * parameters ANY DEFINED BY algorithm OPTIONAL 25*91f16700Schasinglulu * } 26*91f16700Schasinglulu * 27*91f16700Schasinglulu * DigestInfo ::= SEQUENCE { 28*91f16700Schasinglulu * digestAlgorithm AlgorithmIdentifier, 29*91f16700Schasinglulu * digest OCTET STRING 30*91f16700Schasinglulu * } 31*91f16700Schasinglulu */ 32*91f16700Schasinglulu int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, 33*91f16700Schasinglulu unsigned int *flags) 34*91f16700Schasinglulu { 35*91f16700Schasinglulu return arm_get_rotpk_info(cookie, key_ptr, key_len, flags); 36*91f16700Schasinglulu } 37*91f16700Schasinglulu 38*91f16700Schasinglulu /* 39*91f16700Schasinglulu * Return the non-volatile counter address stored in the platform. The cookie 40*91f16700Schasinglulu * will contain the OID of the counter in the certificate. 41*91f16700Schasinglulu * 42*91f16700Schasinglulu * Return: 0 = success, Otherwise = error 43*91f16700Schasinglulu */ 44*91f16700Schasinglulu static int plat_get_nv_ctr_addr(void *cookie, uintptr_t *nv_ctr_addr) 45*91f16700Schasinglulu { 46*91f16700Schasinglulu const char *oid = (const char *)cookie; 47*91f16700Schasinglulu 48*91f16700Schasinglulu if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { 49*91f16700Schasinglulu *nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, 50*91f16700Schasinglulu TRUSTED_NV_CTR_ID); 51*91f16700Schasinglulu } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { 52*91f16700Schasinglulu *nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, 53*91f16700Schasinglulu NON_TRUSTED_NV_CTR_ID); 54*91f16700Schasinglulu } else if (strcmp(oid, CCA_FW_NVCOUNTER_OID) == 0) { 55*91f16700Schasinglulu /* FVP does not support the CCA NV Counter so use the Trusted NV */ 56*91f16700Schasinglulu *nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, 57*91f16700Schasinglulu TRUSTED_NV_CTR_ID); 58*91f16700Schasinglulu } else { 59*91f16700Schasinglulu return 1; 60*91f16700Schasinglulu } 61*91f16700Schasinglulu 62*91f16700Schasinglulu return 0; 63*91f16700Schasinglulu } 64*91f16700Schasinglulu 65*91f16700Schasinglulu /* 66*91f16700Schasinglulu * Store a new non-volatile counter value. 67*91f16700Schasinglulu * 68*91f16700Schasinglulu * On some FVP versions, the non-volatile counters are read-only so this 69*91f16700Schasinglulu * function will always fail. 70*91f16700Schasinglulu * 71*91f16700Schasinglulu * Return: 0 = success, Otherwise = error 72*91f16700Schasinglulu */ 73*91f16700Schasinglulu int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) 74*91f16700Schasinglulu { 75*91f16700Schasinglulu uintptr_t nv_ctr_addr; 76*91f16700Schasinglulu int rc; 77*91f16700Schasinglulu 78*91f16700Schasinglulu assert(cookie != NULL); 79*91f16700Schasinglulu 80*91f16700Schasinglulu rc = plat_get_nv_ctr_addr(cookie, &nv_ctr_addr); 81*91f16700Schasinglulu if (rc != 0) { 82*91f16700Schasinglulu return rc; 83*91f16700Schasinglulu } 84*91f16700Schasinglulu 85*91f16700Schasinglulu mmio_write_32(nv_ctr_addr, nv_ctr); 86*91f16700Schasinglulu 87*91f16700Schasinglulu /* 88*91f16700Schasinglulu * If the FVP models a locked counter then its value cannot be updated 89*91f16700Schasinglulu * and the above write operation has been silently ignored. 90*91f16700Schasinglulu */ 91*91f16700Schasinglulu return (mmio_read_32(nv_ctr_addr) == nv_ctr) ? 0 : 1; 92*91f16700Schasinglulu } 93*91f16700Schasinglulu 94*91f16700Schasinglulu /* 95*91f16700Schasinglulu * Return the non-volatile counter value stored in the platform. The cookie 96*91f16700Schasinglulu * will contain the OID of the counter in the certificate. 97*91f16700Schasinglulu * 98*91f16700Schasinglulu * Return: 0 = success, Otherwise = error 99*91f16700Schasinglulu */ 100*91f16700Schasinglulu int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) 101*91f16700Schasinglulu { 102*91f16700Schasinglulu uintptr_t nv_ctr_addr; 103*91f16700Schasinglulu int rc; 104*91f16700Schasinglulu 105*91f16700Schasinglulu assert(cookie != NULL); 106*91f16700Schasinglulu assert(nv_ctr != NULL); 107*91f16700Schasinglulu 108*91f16700Schasinglulu rc = plat_get_nv_ctr_addr(cookie, &nv_ctr_addr); 109*91f16700Schasinglulu if (rc != 0) { 110*91f16700Schasinglulu return rc; 111*91f16700Schasinglulu } 112*91f16700Schasinglulu 113*91f16700Schasinglulu *nv_ctr = *((unsigned int *)nv_ctr_addr); 114*91f16700Schasinglulu 115*91f16700Schasinglulu return 0; 116*91f16700Schasinglulu } 117