1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
8
9 #include "cc_pal_types.h"
10 #include "cc_pal_mem.h"
11 #include "cc_pal_abort.h"
12 #include "chacha_driver.h"
13 #include "mbedtls_cc_chacha.h"
14 #include "mbedtls_cc_chacha_error.h"
15 #include "driver_defs.h"
16 #include "cc_sym_error.h"
17
Driver2CCChachaErr(drvError_t drvRc)18 static CCError_t Driver2CCChachaErr(drvError_t drvRc)
19 {
20 switch (drvRc) {
21 case CHACHA_DRV_OK:
22 return CC_OK;
23 case CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR:
24 return CC_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR;
25 case CHACHA_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR:
26 return CC_CHACHA_INVALID_ENCRYPT_MODE_ERROR;
27 case CHACHA_DRV_ILLEGAL_INPUT_ADDR_MEM_ERROR:
28 return CC_CHACHA_DATA_IN_POINTER_INVALID_ERROR;
29 case CHACHA_DRV_ILLEGAL_OUTPUT_ADDR_MEM_ERROR:
30 return CC_CHACHA_DATA_OUT_POINTER_INVALID_ERROR;
31 case CHACHA_DRV_ILLEGAL_NONCE_SIZE_ERROR:
32 return CC_CHACHA_INVALID_NONCE_ERROR;
33 default:
34 return CC_FATAL_ERROR;
35 }
36 }
37
ChachaBlock(mbedtls_chacha_user_context * pContextID,uint8_t * pDataIn,size_t dataInSize,uint8_t * pDataOut)38 static CCError_t ChachaBlock(mbedtls_chacha_user_context *pContextID,
39 uint8_t *pDataIn,
40 size_t dataInSize,
41 uint8_t *pDataOut)
42 {
43 drvError_t drvRc = CHACHA_DRV_OK;
44 ChachaContext_t *chachaCtx = NULL;
45 uintptr_t upDataOut = 0;
46 uintptr_t upDataIn = 0;
47 CCBuffInfo_t inBuffInfo;
48 CCBuffInfo_t outBuffInfo;
49
50 /* if the users context ID pointer is NULL return an error */
51 if (pContextID == NULL) {
52 return CC_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR;
53 }
54
55 /* if the users Data In pointer is illegal return an error */
56 if (pDataIn == NULL) {
57 return CC_CHACHA_DATA_IN_POINTER_INVALID_ERROR;
58 }
59
60 /* Size zero is not a valid block operation */
61 if (dataInSize == 0) {
62 return CC_CHACHA_DATA_IN_SIZE_ILLEGAL;
63 }
64
65 /* if the users Data Out pointer is illegal return an error */
66 if (pDataOut == NULL) {
67 return CC_CHACHA_DATA_OUT_POINTER_INVALID_ERROR;
68 }
69
70 upDataOut = (uintptr_t)pDataOut;
71 upDataIn = (uintptr_t)pDataIn;
72 if ((((upDataOut > upDataIn) && (upDataOut - upDataIn < dataInSize))) ||
73 (((upDataIn > upDataOut) && (upDataIn - upDataOut < dataInSize)))) {
74 return CC_CHACHA_DATA_OUT_POINTER_INVALID_ERROR;
75 }
76
77 chachaCtx = (ChachaContext_t *)pContextID;
78
79 /* set data buffers structures */
80 drvRc = SetDataBuffersInfo(pDataIn, dataInSize, &inBuffInfo,
81 pDataOut, dataInSize, &outBuffInfo);
82 if (drvRc != 0) {
83 CC_PAL_LOG_ERR("illegal data buffers\n");
84 return CC_CHACHA_DATA_IN_POINTER_INVALID_ERROR;
85 }
86
87 drvRc = ProcessChacha(chachaCtx, &inBuffInfo, &outBuffInfo, dataInSize);
88
89 return Driver2CCChachaErr(drvRc);
90 }
91
mbedtls_chacha_init(mbedtls_chacha_user_context * pContextID,mbedtls_chacha_nonce pNonce,mbedtls_chacha_nonce_size_t nonceSize,mbedtls_chacha_key pKey,uint32_t initialCounter,mbedtls_chacha_encrypt_mode_t EncryptDecryptFlag)92 CIMPORT_C CCError_t mbedtls_chacha_init(mbedtls_chacha_user_context *pContextID,
93 mbedtls_chacha_nonce pNonce,
94 mbedtls_chacha_nonce_size_t nonceSize,
95 mbedtls_chacha_key pKey,
96 uint32_t initialCounter,
97 mbedtls_chacha_encrypt_mode_t EncryptDecryptFlag)
98 {
99 ChachaContext_t *chachaCtx = NULL;
100
101 /* Chacha key size bytes */
102 uint32_t keySizeBytes = CC_CHACHA_KEY_MAX_SIZE_IN_BYTES;
103 /* Chacha nonce size bytes */
104 uint32_t nonceSizeBytes = 0;
105
106 /* FUNCTION LOGIC */
107
108 /* ............... local initializations .............................. */
109 /* -------------------------------------------------------------------- */
110
111 /* ............... checking the parameters validity ................... */
112 /* -------------------------------------------------------------------- */
113
114 /* if the users context ID pointer is NULL return an error */
115 if (pContextID == NULL) {
116 return CC_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR;
117 }
118
119 if (sizeof(mbedtls_chacha_user_context) != sizeof(ChachaContext_t)) {
120 return CC_CHACHA_CTX_SIZES_ERROR;
121 }
122
123 /* if the pNonce is NULL return an error */
124 if (pNonce == NULL) {
125 return CC_CHACHA_INVALID_NONCE_PTR_ERROR;
126 }
127
128 /* check the nonce size */
129 if (nonceSize == CC_CHACHA_Nonce64BitSize) {
130 nonceSizeBytes = 8;
131 } else if (nonceSize == CC_CHACHA_Nonce96BitSize) {
132 nonceSizeBytes = CC_CHACHA_NONCE_MAX_SIZE_IN_BYTES;
133 } else {
134 return CC_CHACHA_INVALID_NONCE_ERROR;
135 }
136
137 /* check the Encrypt / Decrypt flag validity */
138 if (EncryptDecryptFlag >= CC_CHACHA_EncryptNumOfOptions) {
139 return CC_CHACHA_INVALID_ENCRYPT_MODE_ERROR;
140 }
141
142 /* check the validity of the key pointer */
143 if (pKey == NULL) {
144 return CC_CHACHA_INVALID_KEY_POINTER_ERROR;
145 }
146
147 chachaCtx = (ChachaContext_t *)pContextID;
148 chachaCtx->dir = (enum cryptoDirection)EncryptDecryptFlag;
149 chachaCtx->nonceSize = (chachaNonceSize_t)nonceSize;
150 chachaCtx->inputDataAddrType = DLLI_ADDR;
151 chachaCtx->outputDataAddrType = DLLI_ADDR;
152
153 /* Copy the key to the context */
154 CC_PalMemCopy(chachaCtx->keyBuf, pKey, keySizeBytes);
155
156 /* Copy the nonce to the context */
157 CC_PalMemCopy(chachaCtx->nonceBuf, pNonce, nonceSizeBytes);
158
159 /* init the block counter */
160 chachaCtx->blockCounterLsb = initialCounter;
161 chachaCtx->blockCounterMsb = 0;
162
163 return CC_OK;
164 }
165
mbedtls_chacha_block(mbedtls_chacha_user_context * pContextID,uint8_t * pDataIn,size_t dataInSize,uint8_t * pDataOut)166 CIMPORT_C CCError_t mbedtls_chacha_block(mbedtls_chacha_user_context *pContextID,
167 uint8_t *pDataIn,
168 size_t dataInSize,
169 uint8_t *pDataOut )
170 {
171 if ((dataInSize % CHACHA_BLOCK_SIZE_BYTES) != 0) {
172 return CC_CHACHA_DATA_IN_SIZE_ILLEGAL;
173 }
174 if (dataInSize == 0) {
175 return CC_OK;
176 }
177
178 return ChachaBlock(pContextID, pDataIn, dataInSize, pDataOut);
179 }
180
mbedtls_chacha_finish(mbedtls_chacha_user_context * pContextID,uint8_t * pDataIn,size_t dataInSize,uint8_t * pDataOut)181 CIMPORT_C CCError_t mbedtls_chacha_finish(mbedtls_chacha_user_context *pContextID,
182 uint8_t *pDataIn,
183 size_t dataInSize,
184 uint8_t *pDataOut)
185 {
186 if (dataInSize == 0) {
187 return CC_OK;
188 }
189
190 return ChachaBlock(pContextID, pDataIn, dataInSize, pDataOut);
191 }
192
mbedtls_chacha_free(mbedtls_chacha_user_context * pContextID)193 CIMPORT_C CCError_t mbedtls_chacha_free(mbedtls_chacha_user_context *pContextID)
194 {
195 ChachaContext_t *chachaCtx = (ChachaContext_t*)pContextID;
196
197 if (pContextID == NULL) {
198 return CC_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR;
199 }
200
201 /* Zero the context */
202 CC_PalMemSetZero(chachaCtx, sizeof(ChachaContext_t));
203
204 return CC_OK;
205 }
206
mbedtls_chacha(mbedtls_chacha_nonce pNonce,mbedtls_chacha_nonce_size_t nonceSize,mbedtls_chacha_key pKey,uint32_t initialCounter,mbedtls_chacha_encrypt_mode_t encryptDecryptFlag,uint8_t * pDataIn,size_t dataInSize,uint8_t * pDataOut)207 CIMPORT_C CCError_t mbedtls_chacha(mbedtls_chacha_nonce pNonce,
208 mbedtls_chacha_nonce_size_t nonceSize,
209 mbedtls_chacha_key pKey,
210 uint32_t initialCounter,
211 mbedtls_chacha_encrypt_mode_t encryptDecryptFlag,
212 uint8_t *pDataIn,
213 size_t dataInSize,
214 uint8_t *pDataOut )
215 {
216 mbedtls_chacha_user_context UserContext;
217 CCError_t Error = CC_OK;
218
219
220 /* if the users Data In pointer is illegal return an error */
221 if ( (pDataIn == NULL) ^ (dataInSize == 0) ) {
222 return CC_CHACHA_DATA_IN_POINTER_INVALID_ERROR;
223 }
224
225 /* limit the input size. in IoT no reason for such a big size */
226 if ( dataInSize > CC_MAX_UINT32_VAL ) {
227 return CC_CHACHA_DATA_IN_SIZE_ILLEGAL;
228 }
229
230 /* Size zero is valid - do nothing and return with CC_OK */
231 if (dataInSize == 0) {
232 return CC_OK;
233 }
234
235 Error = mbedtls_chacha_init(&UserContext, pNonce, nonceSize, pKey, initialCounter, encryptDecryptFlag);
236 if (Error != CC_OK) {
237 goto end;
238 }
239
240 Error = mbedtls_chacha_finish(&UserContext, pDataIn, dataInSize, pDataOut);
241 if (Error != CC_OK) {
242 goto end;
243 }
244
245 Error = mbedtls_chacha_free(&UserContext);
246 if (Error != CC_OK) {
247 goto end;
248 }
249
250 end:
251 return Error;
252 }
253
254
255