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