Home | History | Annotate | Download | only in common
      1 /*
      2  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <arm_def.h>
      8 #include <assert.h>
      9 #include <cassert.h>
     10 #include <platform.h>
     11 #include <stdint.h>
     12 #include <string.h>
     13 #include <tbbr_oid.h>
     14 
     15 /* SHA256 algorithm */
     16 #define SHA256_BYTES			32
     17 
     18 /* ROTPK locations */
     19 #define ARM_ROTPK_REGS_ID		1
     20 #define ARM_ROTPK_DEVEL_RSA_ID		2
     21 #define ARM_ROTPK_DEVEL_ECDSA_ID	3
     22 
     23 static const unsigned char rotpk_hash_hdr[] =		\
     24 		"\x30\x31\x30\x0D\x06\x09\x60\x86\x48"	\
     25 		"\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
     26 static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
     27 static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
     28 
     29 /* Use the cryptocell variants if Cryptocell is present */
     30 #if !ARM_CRYPTOCELL_INTEG
     31 #if !ARM_ROTPK_LOCATION_ID
     32   #error "ARM_ROTPK_LOCATION_ID not defined"
     33 #endif
     34 
     35 /* Weak definition may be overridden in specific platform */
     36 #pragma weak plat_get_nv_ctr
     37 #pragma weak plat_set_nv_ctr
     38 
     39 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
     40 static const unsigned char arm_devel_rotpk_hash[] =	\
     41 		"\xB0\xF3\x82\x09\x12\x97\xD8\x3A"	\
     42 		"\x37\x7A\x72\x47\x1B\xEC\x32\x73"	\
     43 		"\xE9\x92\x32\xE2\x49\x59\xF6\x5E"	\
     44 		"\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
     45 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
     46 static const unsigned char arm_devel_rotpk_hash[] =	\
     47 		"\x2E\x40\xBF\x6E\xF9\x12\xBB\x98"	\
     48 		"\x31\x71\x09\x0E\x1E\x15\x3D\x0B"	\
     49 		"\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B"	\
     50 		"\xA0\xB0\x20\x86\x4E\x6C\x07\x17";
     51 #endif
     52 
     53 /*
     54  * Return the ROTPK hash in the following ASN.1 structure in DER format:
     55  *
     56  * AlgorithmIdentifier  ::=  SEQUENCE  {
     57  *     algorithm         OBJECT IDENTIFIER,
     58  *     parameters        ANY DEFINED BY algorithm OPTIONAL
     59  * }
     60  *
     61  * DigestInfo ::= SEQUENCE {
     62  *     digestAlgorithm   AlgorithmIdentifier,
     63  *     digest            OCTET STRING
     64  * }
     65  */
     66 int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
     67 			unsigned int *flags)
     68 {
     69 	uint8_t *dst;
     70 
     71 	assert(key_ptr != NULL);
     72 	assert(key_len != NULL);
     73 	assert(flags != NULL);
     74 
     75 	/* Copy the DER header */
     76 	memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
     77 	dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
     78 
     79 #if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
     80 	|| (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
     81 	memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
     82 #elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
     83 	uint32_t *src, tmp;
     84 	unsigned int words, i;
     85 
     86 	/*
     87 	 * Append the hash from Trusted Root-Key Storage registers. The hash has
     88 	 * not been written linearly into the registers, so we have to do a bit
     89 	 * of byte swapping:
     90 	 *
     91 	 *     0x00    0x04    0x08    0x0C    0x10    0x14    0x18    0x1C
     92 	 * +---------------------------------------------------------------+
     93 	 * | Reg0  | Reg1  | Reg2  | Reg3  | Reg4  | Reg5  | Reg6  | Reg7  |
     94 	 * +---------------------------------------------------------------+
     95 	 *  | ...                    ... |   | ...                   ...  |
     96 	 *  |       +--------------------+   |                    +-------+
     97 	 *  |       |                        |                    |
     98 	 *  +----------------------------+   +----------------------------+
     99 	 *          |                    |                        |       |
    100 	 *  +-------+                    |   +--------------------+       |
    101 	 *  |                            |   |                            |
    102 	 *  v                            v   v                            v
    103 	 * +---------------------------------------------------------------+
    104 	 * |                               |                               |
    105 	 * +---------------------------------------------------------------+
    106 	 *  0                           15  16                           31
    107 	 *
    108 	 * Additionally, we have to access the registers in 32-bit words
    109 	 */
    110 	words = SHA256_BYTES >> 3;
    111 
    112 	/* Swap bytes 0-15 (first four registers) */
    113 	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
    114 	for (i = 0 ; i < words ; i++) {
    115 		tmp = src[words - 1 - i];
    116 		/* Words are read in little endian */
    117 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
    118 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
    119 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
    120 		*dst++ = (uint8_t)(tmp & 0xFF);
    121 	}
    122 
    123 	/* Swap bytes 16-31 (last four registers) */
    124 	src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
    125 	for (i = 0 ; i < words ; i++) {
    126 		tmp = src[words - 1 - i];
    127 		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
    128 		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
    129 		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
    130 		*dst++ = (uint8_t)(tmp & 0xFF);
    131 	}
    132 #endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
    133 		  || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */
    134 
    135 	*key_ptr = (void *)rotpk_hash_der;
    136 	*key_len = (unsigned int)sizeof(rotpk_hash_der);
    137 	*flags = ROTPK_IS_HASH;
    138 	return 0;
    139 }
    140 
    141 /*
    142  * Return the non-volatile counter value stored in the platform. The cookie
    143  * will contain the OID of the counter in the certificate.
    144  *
    145  * Return: 0 = success, Otherwise = error
    146  */
    147 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
    148 {
    149 	const char *oid;
    150 	uint32_t *nv_ctr_addr;
    151 
    152 	assert(cookie != NULL);
    153 	assert(nv_ctr != NULL);
    154 
    155 	oid = (const char *)cookie;
    156 	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
    157 		nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
    158 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
    159 		nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
    160 	} else {
    161 		return 1;
    162 	}
    163 
    164 	*nv_ctr = (unsigned int)(*nv_ctr_addr);
    165 
    166 	return 0;
    167 }
    168 
    169 /*
    170  * Store a new non-volatile counter value. By default on ARM development
    171  * platforms, the non-volatile counters are RO and cannot be modified. We expect
    172  * the values in the certificates to always match the RO values so that this
    173  * function is never called.
    174  *
    175  * Return: 0 = success, Otherwise = error
    176  */
    177 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
    178 {
    179 	return 1;
    180 }
    181 #else /* ARM_CRYPTOCELL_INTEG */
    182 
    183 #include <nvm.h>
    184 #include <nvm_otp.h>
    185 #include <sbrom_bsv_api.h>
    186 
    187 CASSERT(HASH_RESULT_SIZE_IN_BYTES == SHA256_BYTES,
    188 		assert_mismatch_in_hash_result_size);
    189 
    190 /*
    191  * Return the ROTPK hash in the following ASN.1 structure in DER format:
    192  *
    193  * AlgorithmIdentifier  ::=  SEQUENCE  {
    194  *     algorithm         OBJECT IDENTIFIER,
    195  *     parameters        ANY DEFINED BY algorithm OPTIONAL
    196  * }
    197  *
    198  * DigestInfo ::= SEQUENCE {
    199  *     digestAlgorithm   AlgorithmIdentifier,
    200  *     digest            OCTET STRING
    201  * }
    202  */
    203 int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
    204 			unsigned int *flags)
    205 {
    206 	unsigned char *dst;
    207 	CCError_t error;
    208 	uint32_t lcs;
    209 
    210 	assert(key_ptr != NULL);
    211 	assert(key_len != NULL);
    212 	assert(flags != NULL);
    213 
    214 	error = NVM_GetLCS(PLAT_CRYPTOCELL_BASE, &lcs);
    215 	if (error != CC_OK)
    216 		return 1;
    217 
    218 	/* If the lifecycle state is `SD`, return failure */
    219 	if (lcs == CC_BSV_SECURITY_DISABLED_LCS)
    220 		return 1;
    221 
    222 	/*
    223 	 * If the lifecycle state is `CM` or `DM`, ROTPK shouldn't be verified.
    224 	 * Return success after setting ROTPK_NOT_DEPLOYED flag
    225 	 */
    226 	if ((lcs == CC_BSV_CHIP_MANUFACTURE_LCS) ||
    227 			(lcs == CC_BSV_DEVICE_MANUFACTURE_LCS)) {
    228 		*key_len = 0;
    229 		*flags = ROTPK_NOT_DEPLOYED;
    230 		return 0;
    231 	}
    232 
    233 	/* Copy the DER header */
    234 	memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
    235 	dst = &rotpk_hash_der[rotpk_hash_hdr_len];
    236 	error = NVM_ReadHASHPubKey(PLAT_CRYPTOCELL_BASE,
    237 			CC_SB_HASH_BOOT_KEY_256B,
    238 			(uint32_t *)dst, HASH_RESULT_SIZE_IN_WORDS);
    239 	if (error != CC_OK)
    240 		return 1;
    241 
    242 	*key_ptr = rotpk_hash_der;
    243 	*key_len = sizeof(rotpk_hash_der);
    244 	*flags = ROTPK_IS_HASH;
    245 	return 0;
    246 }
    247 
    248 /*
    249  * Return the non-volatile counter value stored in the platform. The cookie
    250  * specifies the OID of the counter in the certificate.
    251  *
    252  * Return: 0 = success, Otherwise = error
    253  */
    254 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
    255 {
    256 	CCError_t error = CC_FAIL;
    257 
    258 	if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
    259 		error = NVM_GetSwVersion(PLAT_CRYPTOCELL_BASE,
    260 				CC_SW_VERSION_COUNTER1, nv_ctr);
    261 	} else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
    262 		error = NVM_GetSwVersion(PLAT_CRYPTOCELL_BASE,
    263 				CC_SW_VERSION_COUNTER2, nv_ctr);
    264 	}
    265 
    266 	return (error != CC_OK);
    267 }
    268 
    269 /*
    270  * Store a new non-volatile counter value in the counter specified by the OID
    271  * in the cookie. This function is not expected to be called if the Lifecycle
    272  * state is RMA as the values in the certificate are expected to always match
    273  * the nvcounter values. But if called when the LCS is RMA, the underlying
    274  * helper functions will return success but without updating the counter.
    275  *
    276  * Return: 0 = success, Otherwise = error
    277  */
    278 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
    279 {
    280 	CCError_t error = CC_FAIL;
    281 
    282 	if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
    283 		error = NVM_SetSwVersion(PLAT_CRYPTOCELL_BASE,
    284 				CC_SW_VERSION_COUNTER1, nv_ctr);
    285 	} else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
    286 		error = NVM_SetSwVersion(PLAT_CRYPTOCELL_BASE,
    287 				CC_SW_VERSION_COUNTER2, nv_ctr);
    288 	}
    289 
    290 	return (error != CC_OK);
    291 }
    292 
    293 #endif /* ARM_CRYPTOCELL_INTEG */
    294