1 /*
2  * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <stddef.h>
9 #include <string.h>
10 
11 #include <platform_def.h>
12 
13 #include <plat/common/platform.h>
14 #include <tools_share/tbbr_oid.h>
15 
16 #include <common/debug.h>
17 #include <drivers/arm/cryptocell/712/sbrom_bsv_api.h>
18 #include <drivers/arm/cryptocell/712/nvm.h>
19 #include <drivers/arm/cryptocell/712/nvm_otp.h>
20 
21 /*
22  * Return the ROTPK hash
23  *
24  * dst:   buffer into which the ROTPK hash will be copied into
25  * len:   length of the provided buffer, which must be at least enough for a
26  *        SHA256 hash
27  * flags: a pointer to integer that will be set to indicate the ROTPK status
28  *
29  * Return: 0 = success, Otherwise = error
30  */
cc_get_rotpk_hash(unsigned char * dst,unsigned int len,unsigned int * flags)31 int cc_get_rotpk_hash(unsigned char *dst, unsigned int len, unsigned int *flags)
32 {
33 	CCError_t error;
34 	uint32_t lcs;
35 
36 	assert(dst != NULL);
37 	assert(len >= HASH_RESULT_SIZE_IN_WORDS);
38 	assert(flags != NULL);
39 
40 	error = NVM_GetLCS(PLAT_CRYPTOCELL_BASE, &lcs);
41 	if (error != CC_OK)
42 		return 1;
43 
44 	/* If the lifecycle state is `SD`, return failure */
45 	if (lcs == CC_BSV_SECURITY_DISABLED_LCS)
46 		return 1;
47 
48 	/*
49 	 * If the lifecycle state is `CM` or `DM`, ROTPK shouldn't be verified.
50 	 * Return success after setting ROTPK_NOT_DEPLOYED flag
51 	 */
52 	if ((lcs == CC_BSV_CHIP_MANUFACTURE_LCS) ||
53 			(lcs == CC_BSV_DEVICE_MANUFACTURE_LCS)) {
54 		*flags = ROTPK_NOT_DEPLOYED;
55 		return 0;
56 	}
57 
58 	/* Copy the DER header */
59 	error = NVM_ReadHASHPubKey(PLAT_CRYPTOCELL_BASE,
60 			CC_SB_HASH_BOOT_KEY_256B,
61 			(uint32_t *)dst, HASH_RESULT_SIZE_IN_WORDS);
62 	if (error != CC_OK)
63 		return 1;
64 
65 	*flags = ROTPK_IS_HASH;
66 	return 0;
67 }
68 
69 /*
70  * Return the non-volatile counter value stored in the platform. The cookie
71  * specifies the OID of the counter in the certificate.
72  *
73  * Return: 0 = success, Otherwise = error
74  */
plat_get_nv_ctr(void * cookie,unsigned int * nv_ctr)75 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
76 {
77 	CCError_t error = CC_FAIL;
78 
79 	if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
80 		error = NVM_GetSwVersion(PLAT_CRYPTOCELL_BASE,
81 				CC_SW_VERSION_COUNTER1, nv_ctr);
82 	} else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
83 		error = NVM_GetSwVersion(PLAT_CRYPTOCELL_BASE,
84 				CC_SW_VERSION_COUNTER2, nv_ctr);
85 	}
86 
87 	return (error != CC_OK);
88 }
89 
90 /*
91  * Store a new non-volatile counter value in the counter specified by the OID
92  * in the cookie. This function is not expected to be called if the Lifecycle
93  * state is RMA as the values in the certificate are expected to always match
94  * the nvcounter values. But if called when the LCS is RMA, the underlying
95  * helper functions will return success but without updating the counter.
96  *
97  * Return: 0 = success, Otherwise = error
98  */
plat_set_nv_ctr(void * cookie,unsigned int nv_ctr)99 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
100 {
101 	CCError_t error = CC_FAIL;
102 
103 	if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
104 		error = NVM_SetSwVersion(PLAT_CRYPTOCELL_BASE,
105 				CC_SW_VERSION_COUNTER1, nv_ctr);
106 	} else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
107 		error = NVM_SetSwVersion(PLAT_CRYPTOCELL_BASE,
108 				CC_SW_VERSION_COUNTER2, nv_ctr);
109 	}
110 
111 	return (error != CC_OK);
112 }
113 
114