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 "mbedtls_cc_chacha.h"
12 #include "mbedtls_cc_poly.h"
13 #include "poly.h"
14 #include "mbedtls_cc_chacha_poly_error.h"
15
16
mbedtls_chacha_poly(mbedtls_chacha_nonce pNonce,mbedtls_chacha_key pKey,mbedtls_chacha_encrypt_mode_t encryptDecryptFlag,uint8_t * pAddData,size_t addDataSize,uint8_t * pDataIn,size_t dataInSize,uint8_t * pDataOut,mbedtls_poly_mac macRes)17 CIMPORT_C CCError_t mbedtls_chacha_poly(
18 mbedtls_chacha_nonce pNonce,
19 mbedtls_chacha_key pKey,
20 mbedtls_chacha_encrypt_mode_t encryptDecryptFlag,
21 uint8_t *pAddData,
22 size_t addDataSize,
23 uint8_t *pDataIn,
24 size_t dataInSize,
25 uint8_t *pDataOut,
26 mbedtls_poly_mac macRes)
27
28 {
29 CCError_t rc;
30 uint8_t chachaInState[CC_CHACHA_BLOCK_SIZE_IN_BYTES] = {0};
31 uint8_t chachaOutState[CC_CHACHA_BLOCK_SIZE_IN_BYTES] = {0};
32 mbedtls_poly_key polyKey = {0};
33 mbedtls_poly_mac polyMac = {0};
34 uint8_t *pCipherData = NULL;
35
36
37 // Verify inputs
38 if ((pAddData == NULL) ^ (addDataSize == 0)) {
39 return CC_CHACHA_POLY_ADATA_INVALID_ERROR;
40 }
41 if ((pDataIn == NULL) ^ (dataInSize == 0)) {
42 return CC_CHACHA_POLY_DATA_INVALID_ERROR;
43 }
44 if (((pDataOut == NULL) ^ (pDataIn == NULL))||
45 (macRes == NULL) ||
46 (pNonce == NULL) ||
47 (pKey == NULL) ||
48 (dataInSize > CC_MAX_UINT32_VAL) ||
49 (addDataSize > CC_MAX_UINT32_VAL))
50 return CC_CHACHA_POLY_DATA_INVALID_ERROR;
51
52
53 if (encryptDecryptFlag == CC_CHACHA_Encrypt) {
54 pCipherData = pDataOut;
55 } else if (encryptDecryptFlag == CC_CHACHA_Decrypt) {
56 pCipherData = pDataIn;
57 } else {
58 return CC_CHACHA_POLY_ENC_MODE_INVALID_ERROR;
59 }
60
61 // 1. Generate poly key
62 // Calling mbedtls_chacha with data=0 is like performing the chacha block function without the encryption
63 rc = mbedtls_chacha(pNonce, CC_CHACHA_Nonce96BitSize, pKey, 0, CC_CHACHA_Encrypt, chachaInState, sizeof(chachaInState), chachaOutState);
64 if (rc != CC_OK) {
65 rc = CC_CHACHA_POLY_GEN_KEY_ERROR;
66 goto end_with_error;
67 }
68 // poly key defined as the first 32 bytes of chacha output.
69 CC_PalMemCopy(polyKey, chachaOutState, sizeof(polyKey));
70
71 // 2. Encryption pDataIn
72 if (encryptDecryptFlag == CC_CHACHA_Encrypt) {
73 rc = mbedtls_chacha(pNonce, CC_CHACHA_Nonce96BitSize, pKey, 1, encryptDecryptFlag, (uint8_t *)pDataIn, dataInSize, (uint8_t *)pDataOut);
74 if (rc != CC_OK) {
75 rc = CC_CHACHA_POLY_ENCRYPTION_ERROR;
76 goto end_with_error;
77 }
78 }
79
80 // 3. Authentication
81 rc = PolyMacCalc(polyKey, pAddData, addDataSize, pCipherData, dataInSize, polyMac, true);
82 if (rc != CC_OK) {
83 rc = CC_CHACHA_POLY_AUTH_ERROR;
84 goto end_with_error;
85 }
86 // 3.1. If encrypt, Calculate mac
87 if (encryptDecryptFlag == CC_CHACHA_Encrypt) {
88 CC_PalMemCopy(macRes, polyMac, sizeof(polyMac));
89 return CC_OK;
90 }
91
92 // 3.2. If decrypt, first Verify the expected macRes with polyMac, than decrypt the msg
93 if (CC_PalMemCmp(macRes, polyMac, sizeof(polyMac)) != 0) {
94 rc = CC_CHACHA_POLY_MAC_ERROR;
95 goto end_with_error;
96 }
97 rc = mbedtls_chacha(pNonce, CC_CHACHA_Nonce96BitSize, pKey, 1, encryptDecryptFlag, (uint8_t *)pDataIn, dataInSize, (uint8_t *)pDataOut);
98 if (rc != CC_OK) {
99 rc = CC_CHACHA_POLY_ENCRYPTION_ERROR;
100 goto end_with_error;
101 }
102 return CC_OK;
103
104 end_with_error:
105 if (pDataOut != NULL) {
106 CC_PalMemSetZero(pDataOut, dataInSize);
107 }
108 return rc;
109
110 }
111
112