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 <string.h>
16 #include "hitls_build.h"
17 #ifdef HITLS_TLS_SUITE_CIPHER_AEAD
18 #include "securec.h"
19 #include "tls_binlog_id.h"
20 #include "bsl_log_internal.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_bytes.h"
23 #include "crypt.h"
24 #include "hitls_error.h"
25 #include "record.h"
26 #include "rec_alert.h"
27 #include "rec_conn.h"
28 #include "rec_crypto_aead.h"
29
30 #define AEAD_AAD_TLS12_SIZE 13u /* TLS1.2 AEAD additional_data length */
31 #define AEAD_AAD_MAX_SIZE AEAD_AAD_TLS12_SIZE
32 #define AEAD_NONCE_SIZE 12u /* The length of the AEAD nonce is fixed to 12 */
33 #define AEAD_NONCE_ZEROS_SIZE 4u /* The length of the AEAD nonce First 4 bytes */
34 #ifdef HITLS_TLS_PROTO_TLS13
35 #define AEAD_AAD_TLS13_SIZE 5u /* TLS1.3 AEAD additional_data length */
36 #endif
37
CleanSensitiveData(int32_t ret,uint8_t * nonce,uint8_t * aad,uint32_t outLen,uint32_t cipherLen)38 static int32_t CleanSensitiveData(int32_t ret, uint8_t *nonce, uint8_t *aad, uint32_t outLen, uint32_t cipherLen)
39 {
40 BSL_SAL_CleanseData(nonce, AEAD_NONCE_SIZE);
41 BSL_SAL_CleanseData(aad, AEAD_AAD_MAX_SIZE);
42 if (ret != HITLS_SUCCESS) {
43 BSL_ERR_PUSH_ERROR(ret);
44 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15480, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
45 "Record:encrypt record error.", NULL, NULL, NULL, NULL);
46 return ret;
47 }
48
49 if (outLen != cipherLen) {
50 BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_ENCRYPT);
51 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15481, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
52 "Record:encrypt error. outLen:%u cipherLen:%u", outLen, cipherLen, NULL, NULL);
53 return HITLS_REC_ERR_ENCRYPT;
54 }
55
56 return HITLS_SUCCESS;
57 }
58
AeadGetNonce(const RecConnSuitInfo * suiteInfo,uint8_t * nonce,uint8_t nonceLen,const uint8_t * seq,uint8_t seqLen)59 static int32_t AeadGetNonce(const RecConnSuitInfo *suiteInfo, uint8_t *nonce, uint8_t nonceLen,
60 const uint8_t *seq, uint8_t seqLen)
61 {
62 uint8_t fixedIvLength = suiteInfo->fixedIvLength;
63 uint8_t recordIvLength = suiteInfo->recordIvLength;
64
65 if ((fixedIvLength + recordIvLength) != nonceLen) {
66 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17239, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "nonceLen err", 0, 0, 0, 0);
67 BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_AEAD_NONCE_PARAM);
68 return HITLS_REC_ERR_AEAD_NONCE_PARAM; // The caller should ensure that the input is correct
69 }
70
71 if (recordIvLength == seqLen) {
72 /*
73 * According to the RFC5116 && RFC5288 AEAD_AES_128_GCM/AEAD_AES_256_GCM definition, the nonce length is fixed
74 * to 12. 4 bytes + 8bytes(64 bits record sequence number, big endian) = 12 bytes 4 bytes the implicit part be
75 * derived from iv. The first 4 bytes of the IV are obtained.
76 */
77 (void)memcpy_s(nonce, nonceLen, suiteInfo->iv, fixedIvLength);
78 (void)memcpy_s(&nonce[fixedIvLength], recordIvLength, seq, seqLen);
79 return HITLS_SUCCESS;
80 } else if (recordIvLength == 0) {
81 /*
82 * (same as defined in RFC7905 AEAD_CHACHA20_POLY1305)
83 * The per-record nonce for the AEAD defined in RFC8446 5.3
84 * First 4 bytes (all 0s) + Last 8bytes(64 bits record sequence number, big endian) = 12 bytes
85 * Perform XOR with the 12 bytes IV. The result is nonce.
86 */
87 // First four bytes (all 0s)
88 (void)memset_s(&nonce[0], nonceLen, 0, AEAD_NONCE_ZEROS_SIZE);
89 // First 4 bytes (all 0s) + Last 8 bytes (64-bit record sequence number, big endian)
90 (void)memcpy_s(&nonce[AEAD_NONCE_ZEROS_SIZE], nonceLen - AEAD_NONCE_ZEROS_SIZE, seq, seqLen);
91 for (uint32_t i = 0; i < nonceLen; i++) {
92 nonce[i] = nonce[i] ^ suiteInfo->iv[i];
93 }
94 return HITLS_SUCCESS;
95 }
96
97 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17240, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "get nonce fail", 0, 0, 0, 0);
98 BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_AEAD_NONCE_PARAM);
99 return HITLS_REC_ERR_AEAD_NONCE_PARAM;
100 }
101
AeadGetAad(uint8_t * aad,uint32_t * aadLen,const REC_TextInput * input,uint32_t plainDataLen)102 static void AeadGetAad(uint8_t *aad, uint32_t *aadLen, const REC_TextInput *input, uint32_t plainDataLen)
103 {
104 #ifdef HITLS_TLS_PROTO_TLS13
105 /*
106 TLS1.3 generation
107 additional_data = TLSCiphertext.opaque_type || TLSCiphertext.legacy_record_version || TLSCiphertext.length
108 */
109 if (input->negotiatedVersion == HITLS_VERSION_TLS13) {
110 // The 0th byte is the record type
111 aad[0] = input->type;
112 uint32_t offset = 1;
113 // The first and second bytes of indicate the version number
114 BSL_Uint16ToByte(input->version, &aad[offset]);
115 offset += sizeof(uint16_t);
116 // The third and fourth bytes of indicate the data length
117 BSL_Uint16ToByte((uint16_t)plainDataLen, &aad[offset]);
118 *aadLen = AEAD_AAD_TLS13_SIZE;
119 return;
120 }
121 #endif /* HITLS_TLS_PROTO_TLS13 */
122 /* non-TLS1.3 generation additional_data = seq_num + TLSCompressed.type + TLSCompressed.version +
123 * TLSCompressed.length */
124 (void)memcpy_s(aad, AEAD_AAD_MAX_SIZE, input->seq, REC_CONN_SEQ_SIZE);
125 uint32_t offset = REC_CONN_SEQ_SIZE;
126 aad[offset] = input->type; // The eighth byte indicates the record type
127 offset++;
128 BSL_Uint16ToByte(input->version, &aad[offset]); // The ninth and tenth bytes indicate the version number.
129 offset += sizeof(uint16_t);
130 BSL_Uint16ToByte((uint16_t)plainDataLen, &aad[offset]); // The 11th and 12th bytse indicate the data length.
131 *aadLen = AEAD_AAD_TLS12_SIZE;
132 return;
133 }
134
AeadCalCiphertextLen(const TLS_Ctx * ctx,RecConnSuitInfo * suiteInfo,uint32_t plantextLen,bool isRead)135 static uint32_t AeadCalCiphertextLen(const TLS_Ctx *ctx, RecConnSuitInfo *suiteInfo, uint32_t plantextLen, bool isRead)
136 {
137 (void)ctx;
138 (void)isRead;
139 return plantextLen + suiteInfo->macLen + suiteInfo->recordIvLength;
140 }
AeadCalPlantextBufLen(TLS_Ctx * ctx,RecConnSuitInfo * suiteInfo,uint32_t ciphertextLen,uint32_t * offset,uint32_t * plainLen)141 static int32_t AeadCalPlantextBufLen(TLS_Ctx *ctx, RecConnSuitInfo *suiteInfo,
142 uint32_t ciphertextLen, uint32_t *offset, uint32_t *plainLen)
143 {
144 (void)ctx;
145 *offset = suiteInfo->recordIvLength;
146 uint32_t plantextLen = ciphertextLen - suiteInfo->macLen - suiteInfo->recordIvLength;
147 if (plantextLen > ciphertextLen) {
148 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17241, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
149 "plantextLen err", 0, 0, 0, 0);
150 return HITLS_INVALID_INPUT;
151 }
152 *plainLen = plantextLen;
153 return HITLS_SUCCESS;
154 }
155
AeadDecrypt(TLS_Ctx * ctx,RecConnState * state,const REC_TextInput * cryptMsg,uint8_t * data,uint32_t * dataLen)156 static int32_t AeadDecrypt(TLS_Ctx *ctx, RecConnState *state, const REC_TextInput *cryptMsg,
157 uint8_t *data, uint32_t *dataLen)
158 {
159 RecConnSuitInfo *suiteInfo = state->suiteInfo;
160 /** Initialize the encryption length offset */
161 uint32_t cipherOffset = 0u;
162 HITLS_CipherParameters cipherParam = {0};
163 cipherParam.ctx = &suiteInfo->ctx;
164 cipherParam.type = suiteInfo->cipherType;
165 cipherParam.algo = suiteInfo->cipherAlg;
166 cipherParam.key = (const uint8_t *)suiteInfo->key;
167 cipherParam.keyLen = suiteInfo->encKeyLen;
168
169 /** Read the explicit IV during AEAD decryption */
170 const uint8_t *recordIv;
171 if (suiteInfo->recordIvLength > 0u) {
172 recordIv = &cryptMsg->text[cipherOffset];
173 cipherOffset += REC_CONN_SEQ_SIZE;
174 } else {
175 // If no IV is displayed, use the serial number
176 recordIv = cryptMsg->seq;
177 }
178
179 /** Calculate NONCE */
180 uint8_t nonce[AEAD_NONCE_SIZE] = {0};
181 int32_t ret = AeadGetNonce(suiteInfo, nonce, sizeof(nonce), recordIv, REC_CONN_SEQ_SIZE);
182 if (ret != HITLS_SUCCESS) {
183 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15395, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
184 "Record decrypt:get nonce failed.", 0, 0, 0, 0);
185 return ret;
186 }
187 cipherParam.iv = nonce;
188 cipherParam.ivLen = AEAD_NONCE_SIZE;
189
190 /* Calculate additional_data */
191 uint8_t aad[AEAD_AAD_MAX_SIZE] = {0};
192 uint32_t aadLen = AEAD_AAD_MAX_SIZE;
193 /*
194 Definition of additional_data
195 tls1.2 additional_data = seq_num + TLSCompressed.type +
196 TLSCompressed.version + TLSCompressed.length;
197 tls1.3 additional_data = TLSCiphertext.opaque_type ||
198 TLSCiphertext.legacy_record_version ||
199 TLSCiphertext.length
200 diff: length
201 */
202 uint32_t plainDataLen = cryptMsg->textLen;
203 if (cryptMsg->negotiatedVersion != HITLS_VERSION_TLS13) {
204 plainDataLen = cryptMsg->textLen - suiteInfo->recordIvLength - suiteInfo->macLen;
205 }
206 AeadGetAad(aad, &aadLen, cryptMsg, plainDataLen);
207 cipherParam.aad = aad;
208 cipherParam.aadLen = aadLen;
209
210 /** Calculate the encryption length: GenericAEADCipher.content + aead tag */
211 uint32_t cipherLen = cryptMsg->textLen - cipherOffset;
212 /** Decryption */
213 ret = SAL_CRYPT_Decrypt(LIBCTX_FROM_CTX(ctx), ATTRIBUTE_FROM_CTX(ctx),
214 &cipherParam, &cryptMsg->text[cipherOffset], cipherLen, data, dataLen);
215 /* Clear sensitive information */
216 BSL_SAL_CleanseData(nonce, AEAD_NONCE_SIZE);
217 BSL_SAL_CleanseData(aad, AEAD_AAD_MAX_SIZE);
218 if (ret != HITLS_SUCCESS) {
219 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15396, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
220 "decrypt record error. ret:%d", ret, 0, 0, 0);
221 if (BSL_UIO_GetUioChainTransportType(ctx->uio, BSL_UIO_SCTP)) {
222 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC);
223 return HITLS_REC_BAD_RECORD_MAC;
224 }
225 return RecordSendAlertMsg(ctx, ALERT_LEVEL_FATAL, ALERT_BAD_RECORD_MAC);
226 }
227 return HITLS_SUCCESS;
228 }
229
230 /**
231 * @brief AEAD encryption
232 *
233 * @param state [IN] RecConnState Context
234 * @param input [IN] Input data before encryption
235 * @param cipherText [OUT] Encrypted content
236 * @param cipherTextLen [IN] Length after encryption
237 *
238 * @retval HITLS_SUCCESS succeeded.
239 * @retval HITLS_INTERNAL_EXCEPTION: null pointer
240 * @retval HITLS_MEMCPY_FAIL The copy fails.
241 * @retval For details, see SAL_CRYPT_Encrypt.
242 */
AeadEncrypt(TLS_Ctx * ctx,RecConnState * state,const REC_TextInput * plainMsg,uint8_t * cipherText,uint32_t cipherTextLen)243 static int32_t AeadEncrypt(TLS_Ctx *ctx, RecConnState *state, const REC_TextInput *plainMsg, uint8_t *cipherText,
244 uint32_t cipherTextLen)
245 {
246 /** Initialize the encryption length offset */
247 uint32_t cipherOffset = 0u;
248 HITLS_CipherParameters cipherParam = {0};
249 cipherParam.ctx = &state->suiteInfo->ctx;
250 cipherParam.type = state->suiteInfo->cipherType;
251 cipherParam.algo = state->suiteInfo->cipherAlg;
252 cipherParam.key = (const uint8_t *)state->suiteInfo->key;
253 cipherParam.keyLen = state->suiteInfo->encKeyLen;
254
255 /** During AEAD encryption, the sequence number is used as the explicit IV */
256 if (state->suiteInfo->recordIvLength > 0u) {
257 if (memcpy_s(&cipherText[cipherOffset], cipherTextLen, plainMsg->seq, REC_CONN_SEQ_SIZE) != EOK) {
258 BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL);
259 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15384, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
260 "Record encrypt:memcpy fail.", 0, 0, 0, 0);
261 return HITLS_MEMCPY_FAIL;
262 }
263 cipherOffset += REC_CONN_SEQ_SIZE;
264 }
265
266 /** Calculate NONCE */
267 uint8_t nonce[AEAD_NONCE_SIZE] = {0};
268 int32_t ret = AeadGetNonce(state->suiteInfo, nonce, sizeof(nonce), plainMsg->seq, REC_CONN_SEQ_SIZE);
269 if (ret != HITLS_SUCCESS) {
270 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15385, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
271 "Record encrypt:get nonce failed.", 0, 0, 0, 0);
272 return ret;
273 }
274 cipherParam.iv = nonce;
275 cipherParam.ivLen = AEAD_NONCE_SIZE;
276
277 /* Calculate additional_data */
278 uint8_t aad[AEAD_AAD_MAX_SIZE];
279 uint32_t aadLen = AEAD_AAD_MAX_SIZE;
280 uint32_t textLen =
281 #ifdef HITLS_TLS_PROTO_TLS13
282 (plainMsg->negotiatedVersion == HITLS_VERSION_TLS13) ? cipherTextLen :
283 #endif /* HITLS_TLS_PROTO_TLS13 */
284 plainMsg->textLen;
285 AeadGetAad(aad, &aadLen, plainMsg, textLen);
286 cipherParam.aad = aad;
287 cipherParam.aadLen = aadLen;
288
289 /** Calculate the encryption length */
290 uint32_t cipherLen = cipherTextLen - cipherOffset;
291 uint32_t outLen = cipherLen;
292 /** Encryption */
293 ret = SAL_CRYPT_Encrypt(LIBCTX_FROM_CTX(ctx), ATTRIBUTE_FROM_CTX(ctx),
294 &cipherParam, plainMsg->text, plainMsg->textLen, &cipherText[cipherOffset], &outLen);
295 /* Clear sensitive information */
296 return CleanSensitiveData(ret, nonce, aad, outLen, cipherLen);
297 }
298
RecGetAeadCryptoFuncs(DecryptPostProcess decryptPostProcess,EncryptPreProcess encryptPreProcess)299 const RecCryptoFunc *RecGetAeadCryptoFuncs(DecryptPostProcess decryptPostProcess, EncryptPreProcess encryptPreProcess)
300 {
301 static RecCryptoFunc cryptoFuncAead = {
302 .calCiphertextLen = AeadCalCiphertextLen,
303 .calPlantextBufLen = AeadCalPlantextBufLen,
304 .decrypt = AeadDecrypt,
305 .encryt = AeadEncrypt,
306 };
307 cryptoFuncAead.decryptPostProcess = decryptPostProcess;
308 cryptoFuncAead.encryptPreProcess = encryptPreProcess;
309 return &cryptoFuncAead;
310 }
311 #endif