1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15 #include "securec.h"
16 #include "hitls_build.h"
17 #include "rec_crypto.h"
18 #include "hs_ctx.h"
19 #include "stub_replace.h"
20 #include "rec_wrapper.h"
21 #define MAX_BUF 16384
22 static RecWrapper g_recWrapper;
23 static bool g_enableWrapper;
24 static __thread uint8_t g_locBuffer[MAX_BUF] = { 0 };
25
26 extern int32_t __real_REC_Read(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num);
27
28 extern int32_t __real_REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num);
29
__wrap_REC_Read(TLS_Ctx * ctx,REC_Type recordType,uint8_t * data,uint32_t * readLen,uint32_t num)30 extern int32_t __wrap_REC_Read(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num)
31 {
32 return __real_REC_Read(ctx, recordType, data, readLen, num);
33 }
34
__wrap_REC_Write(TLS_Ctx * ctx,REC_Type recordType,const uint8_t * data,uint32_t num)35 extern int32_t __wrap_REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num)
36 {
37 // Length that can be manipulated in wrapper
38 uint32_t manipulateLen = num;
39 if (!g_enableWrapper || g_recWrapper.isRecRead || g_recWrapper.recordType != recordType) {
40 return __real_REC_Write(ctx, recordType, data, manipulateLen);
41 }
42 if (g_recWrapper.recordType == REC_TYPE_HANDSHAKE && ctx->hsCtx->state != g_recWrapper.ctrlState) {
43 return __real_REC_Write(ctx, recordType, data, manipulateLen);
44 }
45 (void)memcpy_s(g_locBuffer, MAX_BUF, data, num);
46 // The value of manipulateLen can be greater than or smaller than num
47 g_recWrapper.func(ctx, g_locBuffer, &manipulateLen, MAX_BUF, g_recWrapper.userData);
48 if (ctx->hsCtx->bufferLen < manipulateLen) {
49 exit(-1);
50 }
51 if (recordType == REC_TYPE_HANDSHAKE) {
52 (void)memcpy_s(ctx->hsCtx->msgBuf, ctx->hsCtx->bufferLen, g_locBuffer, manipulateLen);
53 ctx->hsCtx->msgLen = manipulateLen;
54 }
55 int32_t ret = __real_REC_Write(ctx, recordType, g_locBuffer, manipulateLen);
56 if (recordType == REC_TYPE_HANDSHAKE && ret == HITLS_SUCCESS) {
57 ctx->hsCtx->msgOffset = manipulateLen - num;
58 }
59 return ret;
60 }
61
62 RecCryptoFunc g_aeadFuncs;
63 RecCryptoFunc g_cbcFuncs;
64 RecCryptoFunc g_plainFuncs;
65
FRAME_InitRecCrypto(void)66 void FRAME_InitRecCrypto(void)
67 {
68 g_plainFuncs = *RecGetCryptoFuncs(NULL);
69 RecConnSuitInfo info = {0};
70 info.cipherType = HITLS_AEAD_CIPHER;
71 g_aeadFuncs = *RecGetCryptoFuncs(&info);
72 info.cipherType = HITLS_CBC_CIPHER;
73 g_cbcFuncs = *RecGetCryptoFuncs(&info);
74 }
75
RecGetOriginCryptFuncs(RecConnSuitInfo * suiteInfo)76 static RecCryptoFunc *RecGetOriginCryptFuncs(RecConnSuitInfo *suiteInfo)
77 {
78 if (suiteInfo == NULL) {
79 return &g_plainFuncs;
80 }
81 switch (suiteInfo->cipherType) {
82 case HITLS_AEAD_CIPHER:
83 return &g_aeadFuncs;
84 case HITLS_CBC_CIPHER:
85 return &g_cbcFuncs;
86 default:
87 return &g_plainFuncs;
88 }
89 return &g_plainFuncs;
90 }
91
WrapperDecryptFunc(TLS_Ctx * ctx,RecConnState * state,const REC_TextInput * cryptMsg,uint8_t * data,uint32_t * dataLen)92 static int32_t WrapperDecryptFunc(TLS_Ctx *ctx, RecConnState *state, const REC_TextInput *cryptMsg,
93 uint8_t *data, uint32_t *dataLen)
94 {
95 int32_t ret = RecGetOriginCryptFuncs(state->suiteInfo)->decrypt(ctx, state, cryptMsg, data, dataLen);
96 if (ret == HITLS_SUCCESS && IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask) && g_recWrapper.isRecRead) {
97 if (g_recWrapper.recordType != cryptMsg->type) {
98 return ret;
99 }
100 if (g_recWrapper.recordType == REC_TYPE_HANDSHAKE) {
101 if (ctx->hsCtx == NULL || ctx->hsCtx->state != g_recWrapper.ctrlState) {
102 return ret;
103 }
104 }
105 g_recWrapper.func(ctx, data, dataLen, *dataLen, g_recWrapper.userData);
106 }
107 return ret;
108 }
109
WrapperDecryptPostProcess(TLS_Ctx * ctx,RecConnSuitInfo * suitInfo,REC_TextInput * cryptMsg,uint8_t * data,uint32_t * dataLen)110 static int32_t WrapperDecryptPostProcess(TLS_Ctx *ctx, RecConnSuitInfo *suitInfo, REC_TextInput *cryptMsg,
111 uint8_t *data, uint32_t *dataLen)
112 {
113 int32_t ret = RecGetOriginCryptFuncs(suitInfo)->decryptPostProcess(ctx, suitInfo, cryptMsg, data, dataLen);
114 if (ret == HITLS_SUCCESS && g_recWrapper.isRecRead) {
115 if (g_recWrapper.recordType != cryptMsg->type) {
116 return ret;
117 }
118 if (g_recWrapper.recordType == REC_TYPE_HANDSHAKE) {
119 if (ctx->hsCtx == NULL || ctx->hsCtx->state != g_recWrapper.ctrlState) {
120 return ret;
121 }
122 }
123 g_recWrapper.func(ctx, data, dataLen, *dataLen, g_recWrapper.userData);
124 }
125 return ret;
126 }
127
WrapperCalPlantextBufLenFunc(TLS_Ctx * ctx,RecConnSuitInfo * suitInfo,uint32_t ciphertextLen,uint32_t * offset,uint32_t * plainLen)128 static int32_t WrapperCalPlantextBufLenFunc(TLS_Ctx *ctx, RecConnSuitInfo *suitInfo,
129 uint32_t ciphertextLen, uint32_t *offset, uint32_t *plainLen)
130 {
131 (void)ctx;
132 (void)suitInfo;
133 (void)ciphertextLen;
134 (void)offset;
135 *plainLen = 16384 + 2048;
136 return HITLS_SUCCESS;
137 }
138
Stub_RecCrypto(RecConnSuitInfo * suiteInfo)139 static RecCryptoFunc *Stub_RecCrypto(RecConnSuitInfo *suiteInfo)
140 {
141 static RecCryptoFunc recCryptoFunc = { 0 };
142 recCryptoFunc = *RecGetOriginCryptFuncs(suiteInfo);
143 recCryptoFunc.calPlantextBufLen = WrapperCalPlantextBufLenFunc;
144 recCryptoFunc.decrypt = WrapperDecryptFunc;
145 recCryptoFunc.decryptPostProcess = WrapperDecryptPostProcess;
146 return &recCryptoFunc;
147 }
148 FuncStubInfo g_stubRecFuncs;
149
RegisterWrapper(RecWrapper wrapper)150 void RegisterWrapper(RecWrapper wrapper)
151 {
152 if (g_enableWrapper) {
153 ClearWrapper();
154 }
155 FRAME_InitRecCrypto();
156 STUB_Init();
157 STUB_Replace(&g_stubRecFuncs, (void *)RecGetCryptoFuncs, (void *)Stub_RecCrypto);
158 g_enableWrapper = true;
159 g_recWrapper = wrapper;
160 }
161
ClearWrapper(void)162 void ClearWrapper(void)
163 {
164 STUB_Reset(&g_stubRecFuncs);
165 g_enableWrapper = false;
166 }