1 /*
2  * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "crypto_hw.h"
9 
10 #include "cc_lib.h"
11 #include "cc_pal_buff_attr.h"
12 #include "cc_rnd_common.h"
13 #include "mbedtls/platform.h"
14 #include "mbedtls/ctr_drbg.h"
15 #include "mbedtls/entropy.h"
16 #include "mbedtls_cc_mng_int.h"
17 #include "arm_cmse.h"
18 #include "mbedtls_cc_util_key_derivation.h"
19 #include "tfm_attest_hal.h"
20 #include "prod_hw_defs.h"
21 #include "cc_otp_defs.h"
22 #include "dx_crys_kernel.h"
23 
24 #include "region_defs.h"
25 
26 #define CC312_NULL_CONTEXT "NO SALT!"
27 
28 static CCRndContext_t           *CC312_pRndCtx         = NULL;
29 static CCRndWorkBuff_t          *CC312_pRndWorkBuff    = NULL;
30 static mbedtls_ctr_drbg_context *CC312_pRndState       = NULL;
31 static mbedtls_entropy_context  *CC312_pMbedtlsEntropy = NULL;
32 
CC_PalDataBufferAttrGet(const unsigned char * pDataBuffer,size_t buffSize,uint8_t buffType,uint8_t * pBuffNs)33 CCError_t CC_PalDataBufferAttrGet(const unsigned char *pDataBuffer,
34                                   size_t buffSize, uint8_t buffType,
35                                   uint8_t *pBuffNs)
36 {
37     CC_UNUSED_PARAM(buffType);
38 
39     *pBuffNs = DATA_BUFFER_IS_SECURE;
40 #if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
41     if (cmse_check_address_range((void*)pDataBuffer, buffSize, CMSE_NONSECURE)) {
42         *pBuffNs = DATA_BUFFER_IS_NONSECURE;
43     }
44 #else
45     if (pDataBuffer >= (uint8_t *)NS_DATA_START &&
46         (pDataBuffer + buffSize) <= (uint8_t *)NS_DATA_LIMIT) {
47         *pBuffNs = DATA_BUFFER_IS_NONSECURE;
48     }
49 #endif
50 
51     return CC_OK;
52 }
53 
54 /*
55  * \brief Initialize the CC312 crypto accelerator
56  */
57 
crypto_hw_accelerator_init(void)58 int crypto_hw_accelerator_init(void)
59 {
60     int ret = 0;
61 
62     /* Allocate memory on heap */
63     CC312_pRndCtx         = mbedtls_calloc(1, sizeof(CCRndContext_t));
64     CC312_pRndWorkBuff    = mbedtls_calloc(1, sizeof(CCRndWorkBuff_t));
65     CC312_pRndState       = mbedtls_calloc(1, sizeof(mbedtls_ctr_drbg_context));
66     CC312_pMbedtlsEntropy = mbedtls_calloc(1, sizeof(mbedtls_entropy_context));
67 
68     /* Check if memory allocation was successful */
69     if ( !CC312_pRndCtx || !CC312_pRndWorkBuff
70       || !CC312_pRndState || !CC312_pMbedtlsEntropy) {
71         mbedtls_free(CC312_pRndCtx);
72         mbedtls_free(CC312_pRndWorkBuff);
73         mbedtls_free(CC312_pRndState);
74         mbedtls_free(CC312_pMbedtlsEntropy);
75 
76         return -1;
77     }
78 
79     /* Init Rnd context's inner members */
80     CC312_pRndCtx->rndState   = CC312_pRndState;
81     CC312_pRndCtx->entropyCtx = CC312_pMbedtlsEntropy;
82 
83     /* Initialise CryptoCell library */
84     ret = CC_LibInit(CC312_pRndCtx, CC312_pRndWorkBuff);
85     if (ret != CC_LIB_RET_OK) {
86         mbedtls_free(CC312_pRndCtx);
87         mbedtls_free(CC312_pRndWorkBuff);
88         mbedtls_free(CC312_pRndState);
89         mbedtls_free(CC312_pMbedtlsEntropy);
90 
91         return ret;
92     }
93 
94     return 0;
95 }
96 
97 /*
98  * \brief Deallocate the CC312 crypto accelerator
99  */
crypto_hw_accelerator_finish(void)100 int crypto_hw_accelerator_finish(void)
101 {
102     int ret = 0;
103 
104     ret = CC_LibFini(CC312_pRndCtx);
105     if(ret != CC_LIB_RET_OK) {
106         return ret;
107     }
108 
109     mbedtls_free(CC312_pRndCtx);
110     mbedtls_free(CC312_pRndWorkBuff);
111     mbedtls_free(CC312_pRndState);
112     mbedtls_free(CC312_pMbedtlsEntropy);
113 
114     return 0;
115 }
116 
crypto_hw_accelerator_huk_derive_key(const uint8_t * label,size_t label_size,const uint8_t * context,size_t context_size,uint8_t * key,size_t key_size)117 int crypto_hw_accelerator_huk_derive_key(const uint8_t *label,
118                                          size_t label_size,
119                                          const uint8_t *context,
120                                          size_t context_size,
121                                          uint8_t *key,
122                                          size_t key_size)
123 {
124 
125     if (context == NULL || context_size == 0) {
126         /* The CC312 requires the context to not be null, so a default
127          * is given.
128          */
129         context = (const uint8_t *)CC312_NULL_CONTEXT;
130         context_size = sizeof(CC312_NULL_CONTEXT);
131     }
132 
133     return mbedtls_util_key_derivation_cmac(CC_UTIL_ROOT_KEY, NULL,
134                                             label, label_size,
135                                             context, context_size,
136                                             key, key_size);
137 }
138 
crypto_hw_apply_debug_permissions(uint8_t * permissions_mask,uint32_t len)139 int crypto_hw_apply_debug_permissions(uint8_t *permissions_mask, uint32_t len)
140 {
141     int ret_val = -1;
142     int failure = 4;
143     uint32_t before_dcu[4];
144     uint32_t after_dcu;
145     uint32_t host_dcu_en_offsets[] = {
146                         DX_BASE_HOST_RGF + DX_HOST_DCU_EN0_REG_OFFSET,
147                         DX_BASE_HOST_RGF + DX_HOST_DCU_EN1_REG_OFFSET,
148                         DX_BASE_HOST_RGF + DX_HOST_DCU_EN2_REG_OFFSET,
149                         DX_BASE_HOST_RGF + DX_HOST_DCU_EN3_REG_OFFSET};
150 
151     if (len != 16 || permissions_mask == NULL) {
152         return ret_val;
153     }
154 
155     for (int i = 0; i < 4; i++) {
156         before_dcu[i] = *((uint32_t*)(permissions_mask + (i*4)));
157     }
158 
159     for (int i = 0; i < 4; i++) {
160 
161         CC_HAL_WRITE_REGISTER(host_dcu_en_offsets[i], before_dcu[i]);
162         after_dcu = CC_HAL_READ_REGISTER(host_dcu_en_offsets[i]);
163 
164         if (after_dcu == before_dcu[i]) {
165             failure--;
166         }
167 
168         if (!failure) {
169             ret_val = 0;
170         }
171     }
172 
173     return ret_val;
174 }
175