• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }