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 16 #ifndef REC_H 17 #define REC_H 18 19 #include <stdbool.h> 20 #include <stdint.h> 21 #include "hitls_build.h" 22 #include "hitls_crypt_type.h" 23 #include "tls.h" 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 #define REC_MAX_PLAIN_LENGTH 16384 /* Maximum plain length */ 30 /* TLS13 Maximum MAC address padding */ 31 #define REC_MAX_TLS13_ENCRYPTED_OVERHEAD 256u 32 /* TLS13 Maximum ciphertext length */ 33 #define REC_MAX_TLS13_ENCRYPTED_LEN (REC_MAX_PLAIN_LENGTH + REC_MAX_TLS13_ENCRYPTED_OVERHEAD) 34 /* The length (in bytes) of the following TLSCiphertext.fragment. The length MUST NOT exceed 2^14 + 2048. */ 35 #define REC_MAX_PLAIN_DECRYPTO_MAX_LENGTH (16384 + 2048) 36 37 #define REC_MASTER_SECRET_LEN 48 38 #define REC_RANDOM_LEN 32 39 40 #define RECORD_HEADER 0x100 41 #define RECORD_INNER_CONTENT_TYPE 0x101 42 /** 43 * record type 44 */ 45 typedef enum { 46 REC_TYPE_CHANGE_CIPHER_SPEC = 20, 47 REC_TYPE_ALERT = 21, 48 REC_TYPE_HANDSHAKE = 22, 49 REC_TYPE_APP = 23, 50 REC_TYPE_UNKNOWN = 255 51 } REC_Type; 52 53 /** 54 * SecurityParameters, used to generate keys and initialize the connect state 55 */ 56 typedef struct { 57 bool isClient; /* Connection Endpoint */ 58 bool isClientTrafficSecret; /* TrafficSecret type */ 59 HITLS_HashAlgo prfAlg; /* prf_algorithm */ 60 HITLS_MacAlgo macAlg; /* mac algorithm */ 61 HITLS_CipherAlgo cipherAlg; /* symmetric encryption algorithm */ 62 HITLS_CipherType cipherType; /* encryption algorithm type */ 63 64 /* key length */ 65 uint8_t fixedIvLength; /* iv length. In TLS1.2 AEAD algorithm is the implicit IV length */ 66 uint8_t encKeyLen; /* Length of the symmetric key */ 67 uint8_t macKeyLen; /* MAC key length: If the AEAD algorithm is used, the MAC key length is 0 */ 68 69 uint8_t blockLength; /* If the block length is not zero, the alignment should be handled. */ 70 uint8_t recordIvLength; /* The explicit IV needs to be sent to the peer */ 71 uint8_t macLen; /* MAC length. For AEAD, it is the mark length */ 72 73 uint8_t masterSecret[MAX_DIGEST_SIZE]; /* tls1.2 master key. TLS1.3 carries the TrafficSecret */ 74 uint8_t clientRandom[REC_RANDOM_LEN]; /* Client random number */ 75 uint8_t serverRandom[REC_RANDOM_LEN]; /* service random number */ 76 } REC_SecParameters; 77 78 /** 79 * @ingroup record 80 * @brief Record initialization 81 * 82 * @param ctx [IN] TLS object 83 * 84 * @retval HITLS_SUCCESS 85 * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer 86 * @retval HITLS_MEMALLOC_FAIL Memory allocated failed 87 * 88 */ 89 int32_t REC_Init(TLS_Ctx *ctx); 90 91 /** 92 * @ingroup record 93 * @brief record deinitialize 94 * 95 * @param ctx [IN] TLS object 96 */ 97 void REC_DeInit(TLS_Ctx *ctx); 98 99 /** 100 * @ingroup record 101 * @brief Check whether data exists in the read buffer of the reocrd 102 * 103 * @param ctx [IN] TLS object 104 * @return whether data exists in the read buffer 105 */ 106 bool REC_ReadHasPending(const TLS_Ctx *ctx); 107 108 /** 109 * @ingroup record 110 * @brief Reads a message in the unit of a record. Data is read from the uio of the CTX to the data pointer 111 * 112 * @attention recordType indicates the expected record type (app or handshake) 113 * readLen indicates the length of read data. The maximum length is REC_MAX_PLAIN_LENGTH (16384) 114 * @param ctx [IN] TLS object 115 * @param recordType [IN] Expected record type(app or handshake) 116 * @param data [OUT] Read buffer 117 * @param readLen [OUT] Length of the read data 118 * @param num [IN] The size of read buffer, which must be greater than or equal to the maximum size of the record 119 * 120 * @retval HITLS_SUCCESS 121 * @retval HITLS_INTERNAL_EXCEPTION,Invalid null pointer 122 * @retval HITLS_REC_ERR_BUFFER_NOT_ENOUGH The buffer space is insufficient 123 * @retval HITLS_MEMCPY_FAIL Memory copy failed 124 * @retval HITLS_REC_NORMAL_RECV_BUF_EMPTY indicates that the buffer is empty and needs to be read again 125 * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error 126 * @retval HITLS_REC_NORMAL_RECV_UNEXPECT_MSG An unexpected message is received and needs to be processed 127 * @retval HITLS_REC_ERR_SN_WRAPPING Sequence number wrap 128 */ 129 int32_t REC_Read(TLS_Ctx *ctx, REC_Type recordType, uint8_t *data, uint32_t *readLen, uint32_t num); 130 131 /** 132 * @ingroup record 133 * @brief Write a record in the unit of record 134 * 135 * @attention If the value of num exceeds the maximum length of the record, return error 136 * 137 * @param ctx [IN] TLS object 138 * @param recordType [IN] record type 139 * @param data [IN] Write data 140 * @param num [IN] Attempt to write num bytes of plaintext data 141 * 142 * @retval HITLS_SUCCESS 143 * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer 144 * @retval HITLS_REC_ERR_BUFFER_NOT_ENOUGH The buffer space is insufficient 145 * @retval HITLS_MEMCPY_FAIL Memory copy failed 146 * @retval HITLS_REC_PMTU_TOO_SMALL The PMTU is too small 147 * @retval HITLS_REC_ERR_IO_EXCEPTION I/O error 148 * @retval HITLS_REC_NORMAL_IO_BUSY I/O busy 149 * @retval HITLS_REC_ERR_TOO_BIG_LENGTH The length of the plaintext data written by the upper layer exceeds the 150 * maximum length of the plaintext data that can be written by a single record 151 * @retval HITLS_REC_ERR_NOT_SUPPORT_CIPHER The key algorithm is not supported 152 * @retval HITLS_REC_ERR_SN_WRAPPING Sequence number wrap 153 */ 154 int32_t REC_Write(TLS_Ctx *ctx, REC_Type recordType, const uint8_t *data, uint32_t num); 155 156 /** 157 * @ingroup record 158 * @brief Activate the expired write state. This API is invoked in the retransmission scenario 159 * 160 * @attention Reservation Interface 161 * @param ctx [IN] TLS object 162 * 163 */ 164 void REC_ActiveOutdatedWriteState(TLS_Ctx *ctx); 165 166 /** 167 * @ingroup record 168 * @brief Disable the expired write status. This API is invoked in the retransmission scenario 169 * 170 * @attention Reservation Interface 171 * @param ctx [IN] TLS object 172 * 173 */ 174 void REC_DeActiveOutdatedWriteState(TLS_Ctx *ctx); 175 176 177 /** 178 * @ingroup record 179 * @brief Initialize the pending state 180 * 181 * @param ctx [IN] TLS object 182 * @param param [IN] Security parameter 183 * 184 * @retval HITLS_SUCCESS 185 * @retval HITLS_MEMALLOC_FAIL Memory allocated failed 186 * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer 187 * 188 */ 189 int32_t REC_InitPendingState(const TLS_Ctx *ctx, const REC_SecParameters *param); 190 191 /** 192 * @ingroup record 193 * @brief Activate the pending state, switch the pending state to the current state 194 * 195 * @attention ctx cannot be empty 196 * @param ctx [IN] TLS object 197 * @param isOut [IN] Indicates whether is the output type 198 * 199 * @retval HITLS_SUCCESS 200 * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer 201 * 202 */ 203 int32_t REC_ActivePendingState(TLS_Ctx *ctx, bool isOut); 204 205 /** 206 * @brief Obtain the maximum writable plaintext length of a single record 207 * 208 * @param ctx [IN] TLS_Ctx context 209 * @param len [OUT] Maximum length of the plaintext 210 * 211 * @retval HITLS_SUCCESS 212 * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer 213 * @retval HITLS_REC_PMTU_TOO_SMALL The PMTU is too small 214 */ 215 int32_t REC_GetMaxWriteSize(const TLS_Ctx *ctx, uint32_t *len); 216 217 /** 218 * @ingroup record 219 * @brief TLS13 Initialize the pending state 220 * 221 * @param ctx [IN] TLS object 222 * @param param [IN] Security parameter 223 * @param isOut [IN] Indicates whether is the output type 224 * 225 * @retval HITLS_SUCCESS 226 * @retval HITLS_MEMALLOC_FAIL Memory allocated failed 227 * @retval HITLS_INTERNAL_EXCEPTION Invalid null pointer 228 * 229 */ 230 int32_t REC_TLS13InitPendingState(const TLS_Ctx *ctx, const REC_SecParameters *param, bool isOut); 231 232 /** 233 * @ingroup record 234 * @brief Retransmit a record 235 * 236 * @param recCtx [IN] Record context 237 * @param recordType [IN] record type 238 * @param data [IN] data 239 * @param dataLen [IN] data length 240 */ 241 int32_t REC_RetransmitListAppend(REC_Ctx *recCtx, REC_Type recordType, const uint8_t *data, uint32_t dataLen); 242 243 /** 244 * @ingroup record 245 * @brief Clean the retransmit list 246 * 247 * @param recCtx [IN] Record context 248 */ 249 void REC_RetransmitListClean(REC_Ctx *recCtx); 250 251 252 /** 253 * @ingroup record 254 * @brief Flush the retransmit list 255 * 256 * @param ctx [IN] TLS object 257 */ 258 void REC_RetransmitListFlush(TLS_Ctx *ctx); 259 260 REC_Type REC_GetUnexpectedMsgType(TLS_Ctx *ctx); 261 262 bool REC_HaveReadSuiteInfo(const TLS_Ctx *ctx); 263 264 /** 265 * @ingroup app 266 * @brief Obtain the length of the remaining readable app messages in the current record. 267 * 268 * @param ctx [IN] TLS object 269 * @return Length of the remaining readable app message 270 */ 271 uint32_t APP_GetReadPendingBytes(const TLS_Ctx *ctx); 272 273 int32_t REC_RecBufReSet(TLS_Ctx *ctx); 274 #ifdef __cplusplus 275 } 276 #endif 277 278 #endif /* REC_H */ 279