1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7
8 #include "cc_pal_mutex.h"
9 #include "cc_pal_abort.h"
10 #include "chacha_driver.h"
11 #include "chacha_driver_ext_dma.h"
12 #include "driver_defs.h"
13 #include "cc_hal.h"
14 #include "cc_hal_plat.h"
15 #include "cc_regs.h"
16 #include "dx_crys_kernel.h"
17 #include "cc_util_pm.h"
18
19
20 extern CC_PalMutex CCSymCryptoMutex;
21
22 /* chacha mode, poly1305 disabled, 256 bit key, 20 rounds, 64 bit iv, do not reset the block counter (overwritten by the context) */
23 #define CHACHA_CONTROL_REG_VAL (1 << DX_CHACHA_CONTROL_REG_INIT_FROM_HOST_BIT_SHIFT)
24 #define CHACHA_CONTROL_REG_USE_IV_96 (1 << DX_CHACHA_CONTROL_REG_USE_IV_96BIT_BIT_SHIFT)
25
26 /******************************************************************************
27 * PRIVATE FUNCTIONS
28 ******************************************************************************/
29
LoadChachaExtDmaState(uint32_t * pNonceBuf,chachaNonceSize_t nonceSizeFlag,uint32_t blockCounterLsb)30 static drvError_t LoadChachaExtDmaState(uint32_t *pNonceBuf, chachaNonceSize_t nonceSizeFlag, uint32_t blockCounterLsb)
31 {
32 /* verify user context pointer */
33 if (pNonceBuf == NULL) {
34 return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
35 }
36
37 /* write the initial counter value according to mode */
38 if (nonceSizeFlag == NONCE_SIZE_64) {
39 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_MSB), 0);
40 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_0), pNonceBuf[0]);
41 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_1), pNonceBuf[1]);
42 }
43 else if (nonceSizeFlag == NONCE_SIZE_96) {
44 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_MSB), pNonceBuf[0]);
45 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_0), pNonceBuf[1]);
46 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_1), pNonceBuf[2]);
47 }
48 else {
49 return CHACHA_DRV_ILLEGAL_NONCE_SIZE_ERROR;
50 }
51 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_LSB), blockCounterLsb);
52
53 return CHACHA_DRV_OK;
54 }
55
LoadChachaKeyExtDma(uint32_t * pKey)56 static drvError_t LoadChachaKeyExtDma(uint32_t *pKey)
57 {
58 int enrtyNum = 0;
59
60 /* verify user context pointer */
61 if (pKey == NULL) {
62 return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
63 }
64
65 for (enrtyNum = 0; enrtyNum < CHACHA_256_BIT_KEY_SIZE_WORDS; ++enrtyNum) {
66 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_KEY0) + (sizeof(uint32_t) * enrtyNum), pKey[enrtyNum]);
67 }
68
69 return CHACHA_DRV_OK;
70 }
71
72 /******************************************************************************
73 * PUBLIC FUNCTIONS
74 ******************************************************************************/
InitChachaExtDma(uint32_t * pNonceBuf,chachaNonceSize_t nonceSizeFlag,uint32_t * keyBuf,uint32_t initialCounter,uint32_t dataLen)75 drvError_t InitChachaExtDma(uint32_t *pNonceBuf, chachaNonceSize_t nonceSizeFlag, uint32_t *keyBuf, uint32_t initialCounter, uint32_t dataLen)
76 {
77 uint32_t irrVal = 0;
78 uint32_t chachaCtrl = CHACHA_CONTROL_REG_VAL;
79 drvError_t drvRc = CHACHA_DRV_OK;
80 drvError_t rc = AES_DRV_OK;
81
82 if (pNonceBuf == NULL || keyBuf == NULL) {
83 return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
84 }
85 /* lock mutex for more chacha hw operation */
86 drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
87 if (drvRc != 0) {
88 CC_PalAbort("Fail to acquire mutex\n");
89 }
90
91 /* increase CC counter at the beginning of each operation */
92 drvRc = CC_IS_WAKE;
93 if (drvRc != 0) {
94 CC_PalAbort("Fail to increase PM counter\n");
95 }
96
97 /* enable clock */
98 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
99 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
100
101 /* make sure sym engines are ready to use */
102 CC_HAL_WAIT_ON_CRYPTO_BUSY();
103
104 /* clear all interrupts before starting the engine */
105 CC_HalClearInterruptBit(0xFFFFFFFFUL);
106
107 /* mask dma interrupts which are not required */
108 irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
109 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
110 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
111 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
112 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
113 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 1);
114 CC_HalMaskInterrupt(irrVal);
115
116 /* configure DIN-CHACHA-DOUT */
117 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_DIN_CHACHA_DOUT_VAL);
118
119 /* write the initial counter value */
120 drvRc = LoadChachaExtDmaState(pNonceBuf, nonceSizeFlag, initialCounter);
121 if (drvRc != CHACHA_DRV_OK) {
122 goto InitExit;
123 }
124
125 /* load key */
126 drvRc = LoadChachaKeyExtDma(keyBuf);
127 if (drvRc != CHACHA_DRV_OK) {
128 goto InitExit;
129 }
130
131 /* configure the CHACHA mode */
132 if (nonceSizeFlag == NONCE_SIZE_96) {
133 chachaCtrl |= CHACHA_CONTROL_REG_USE_IV_96;
134 }
135
136 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_CONTROL_REG), chachaCtrl);
137
138 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_CPU_DATA_SIZE) , dataLen);
139
140 return CHACHA_DRV_OK;
141
142 InitExit:
143
144 rc = terminateChachaExtDma();
145 if (rc != 0) {
146 CC_PalAbort("Failed to terminateAesExtDma \n");
147 }
148 return drvRc;
149 }
150
terminateChachaExtDma(void)151 drvError_t terminateChachaExtDma(void)
152 {
153 drvError_t rc = AES_DRV_OK;
154
155 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
156 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
157
158 /* decrease CC counter at the end of each operation */
159 rc = CC_IS_IDLE;
160 if (rc != 0) {
161 CC_PalAbort("Fail to decrease PM counter\n");
162 }
163
164 /* unlock mutex for more aes hw operation */
165 rc = CC_PalMutexUnlock(&CCSymCryptoMutex);
166 if (rc != 0) {
167 CC_PalAbort("Fail to unlock mutex\n");
168 }
169 return rc;
170 }
171