1fe7de035SAntonio Nino Diaz /* 202552d45Slaurenw-arm * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved. 3fe7de035SAntonio Nino Diaz * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5fe7de035SAntonio Nino Diaz */ 6fe7de035SAntonio Nino Diaz 7fe7de035SAntonio Nino Diaz #include <assert.h> 8fe7de035SAntonio Nino Diaz #include <stdint.h> 9fe7de035SAntonio Nino Diaz #include <string.h> 1009d40e0eSAntonio Nino Diaz 11bd363d35SSandrine Bailleux #include <lib/mmio.h> 1214d095c3SManish V Badarkhe #include <lib/fconf/fconf.h> 13a6ffddecSMax Shvetsov #include <plat/arm/common/plat_arm.h> 1414d095c3SManish V Badarkhe #include <plat/arm/common/fconf_nv_cntr_getter.h> 1509d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 16234bc7f8SAntonio Nino Diaz #include <platform_def.h> 1702552d45Slaurenw-arm #include <tools_share/cca_oid.h> 18232c6b34SMasahiro Yamada 19fe7de035SAntonio Nino Diaz /* 20a6ffddecSMax Shvetsov * Return the ROTPK hash in the following ASN.1 structure in DER format: 21a6ffddecSMax Shvetsov * 22a6ffddecSMax Shvetsov * AlgorithmIdentifier ::= SEQUENCE { 23a6ffddecSMax Shvetsov * algorithm OBJECT IDENTIFIER, 24a6ffddecSMax Shvetsov * parameters ANY DEFINED BY algorithm OPTIONAL 25a6ffddecSMax Shvetsov * } 26a6ffddecSMax Shvetsov * 27a6ffddecSMax Shvetsov * DigestInfo ::= SEQUENCE { 28a6ffddecSMax Shvetsov * digestAlgorithm AlgorithmIdentifier, 29a6ffddecSMax Shvetsov * digest OCTET STRING 30a6ffddecSMax Shvetsov * } 31a6ffddecSMax Shvetsov */ 32a6ffddecSMax Shvetsov int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, 33a6ffddecSMax Shvetsov unsigned int *flags) 34a6ffddecSMax Shvetsov { 3588005701SSandrine Bailleux return arm_get_rotpk_info(cookie, key_ptr, key_len, flags); 36a6ffddecSMax Shvetsov } 37a6ffddecSMax Shvetsov 38a6ffddecSMax Shvetsov /* 39*b695b2f1Slaurenw-arm * Return the non-volatile counter address stored in the platform. The cookie 40*b695b2f1Slaurenw-arm * will contain the OID of the counter in the certificate. 41*b695b2f1Slaurenw-arm * 42*b695b2f1Slaurenw-arm * Return: 0 = success, Otherwise = error 43*b695b2f1Slaurenw-arm */ 44*b695b2f1Slaurenw-arm static int plat_get_nv_ctr_addr(void *cookie, uintptr_t *nv_ctr_addr) 45*b695b2f1Slaurenw-arm { 46*b695b2f1Slaurenw-arm const char *oid = (const char *)cookie; 47*b695b2f1Slaurenw-arm 48*b695b2f1Slaurenw-arm if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { 49*b695b2f1Slaurenw-arm *nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, 50*b695b2f1Slaurenw-arm TRUSTED_NV_CTR_ID); 51*b695b2f1Slaurenw-arm } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { 52*b695b2f1Slaurenw-arm *nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, 53*b695b2f1Slaurenw-arm NON_TRUSTED_NV_CTR_ID); 54*b695b2f1Slaurenw-arm } else if (strcmp(oid, CCA_FW_NVCOUNTER_OID) == 0) { 55*b695b2f1Slaurenw-arm /* FVP does not support the CCA NV Counter so use the Trusted NV */ 56*b695b2f1Slaurenw-arm *nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, 57*b695b2f1Slaurenw-arm TRUSTED_NV_CTR_ID); 58*b695b2f1Slaurenw-arm } else { 59*b695b2f1Slaurenw-arm return 1; 60*b695b2f1Slaurenw-arm } 61*b695b2f1Slaurenw-arm 62*b695b2f1Slaurenw-arm return 0; 63*b695b2f1Slaurenw-arm } 64*b695b2f1Slaurenw-arm 65*b695b2f1Slaurenw-arm /* 66bd363d35SSandrine Bailleux * Store a new non-volatile counter value. 67bd363d35SSandrine Bailleux * 68bd363d35SSandrine Bailleux * On some FVP versions, the non-volatile counters are read-only so this 69bd363d35SSandrine Bailleux * function will always fail. 70fe7de035SAntonio Nino Diaz * 71fe7de035SAntonio Nino Diaz * Return: 0 = success, Otherwise = error 72fe7de035SAntonio Nino Diaz */ 73fe7de035SAntonio Nino Diaz int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) 74fe7de035SAntonio Nino Diaz { 75bd363d35SSandrine Bailleux uintptr_t nv_ctr_addr; 76*b695b2f1Slaurenw-arm int rc; 77fe7de035SAntonio Nino Diaz 78fe7de035SAntonio Nino Diaz assert(cookie != NULL); 79fe7de035SAntonio Nino Diaz 80*b695b2f1Slaurenw-arm rc = plat_get_nv_ctr_addr(cookie, &nv_ctr_addr); 81*b695b2f1Slaurenw-arm if (rc != 0) { 82*b695b2f1Slaurenw-arm return rc; 83fe7de035SAntonio Nino Diaz } 84fe7de035SAntonio Nino Diaz 85bd363d35SSandrine Bailleux mmio_write_32(nv_ctr_addr, nv_ctr); 86fe7de035SAntonio Nino Diaz 87bd363d35SSandrine Bailleux /* 88bd363d35SSandrine Bailleux * If the FVP models a locked counter then its value cannot be updated 89bd363d35SSandrine Bailleux * and the above write operation has been silently ignored. 90bd363d35SSandrine Bailleux */ 91bd363d35SSandrine Bailleux return (mmio_read_32(nv_ctr_addr) == nv_ctr) ? 0 : 1; 92fe7de035SAntonio Nino Diaz } 9302552d45Slaurenw-arm 9402552d45Slaurenw-arm /* 9502552d45Slaurenw-arm * Return the non-volatile counter value stored in the platform. The cookie 9602552d45Slaurenw-arm * will contain the OID of the counter in the certificate. 9702552d45Slaurenw-arm * 9802552d45Slaurenw-arm * Return: 0 = success, Otherwise = error 9902552d45Slaurenw-arm */ 10002552d45Slaurenw-arm int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) 10102552d45Slaurenw-arm { 102*b695b2f1Slaurenw-arm uintptr_t nv_ctr_addr; 103*b695b2f1Slaurenw-arm int rc; 10402552d45Slaurenw-arm 10502552d45Slaurenw-arm assert(cookie != NULL); 10602552d45Slaurenw-arm assert(nv_ctr != NULL); 10702552d45Slaurenw-arm 108*b695b2f1Slaurenw-arm rc = plat_get_nv_ctr_addr(cookie, &nv_ctr_addr); 109*b695b2f1Slaurenw-arm if (rc != 0) { 110*b695b2f1Slaurenw-arm return rc; 11102552d45Slaurenw-arm } 11202552d45Slaurenw-arm 113*b695b2f1Slaurenw-arm *nv_ctr = *((unsigned int *)nv_ctr_addr); 11402552d45Slaurenw-arm 11502552d45Slaurenw-arm return 0; 11602552d45Slaurenw-arm } 117