├── LICENSE ├── README.md ├── dtls_misc.c ├── dtls_misc.h ├── dtls_record.c ├── dtls_record.h ├── tls.c ├── tls.h ├── tls13_client.c ├── tls13_client.h ├── tls13_client_extensions.c ├── tls13_client_extensions.h ├── tls13_client_misc.c ├── tls13_client_misc.h ├── tls13_common.c ├── tls13_common.h ├── tls13_key_material.c ├── tls13_key_material.h ├── tls13_misc.c ├── tls13_misc.h ├── tls13_server.c ├── tls13_server.h ├── tls13_server_extensions.c ├── tls13_server_extensions.h ├── tls13_server_misc.c ├── tls13_server_misc.h ├── tls13_sign_generate.c ├── tls13_sign_generate.h ├── tls13_sign_verify.c ├── tls13_sign_verify.h ├── tls13_ticket.c ├── tls13_ticket.h ├── tls_cache.c ├── tls_cache.h ├── tls_certificate.c ├── tls_certificate.h ├── tls_cipher_suites.c ├── tls_cipher_suites.h ├── tls_client.c ├── tls_client.h ├── tls_client_extensions.c ├── tls_client_extensions.h ├── tls_client_fsm.c ├── tls_client_fsm.h ├── tls_client_misc.c ├── tls_client_misc.h ├── tls_common.c ├── tls_common.h ├── tls_extensions.c ├── tls_extensions.h ├── tls_ffdhe.c ├── tls_ffdhe.h ├── tls_handshake.c ├── tls_handshake.h ├── tls_key_material.c ├── tls_key_material.h ├── tls_legacy.h ├── tls_misc.c ├── tls_misc.h ├── tls_quic.c ├── tls_quic.h ├── tls_quic_misc.c ├── tls_quic_misc.h ├── tls_record.c ├── tls_record.h ├── tls_record_decryption.c ├── tls_record_decryption.h ├── tls_record_encryption.c ├── tls_record_encryption.h ├── tls_server.c ├── tls_server.h ├── tls_server_extensions.c ├── tls_server_extensions.h ├── tls_server_fsm.c ├── tls_server_fsm.h ├── tls_server_misc.c ├── tls_server_misc.h ├── tls_sign_generate.c ├── tls_sign_generate.h ├── tls_sign_misc.c ├── tls_sign_misc.h ├── tls_sign_verify.c ├── tls_sign_verify.h ├── tls_ticket.c ├── tls_ticket.h ├── tls_transcript_hash.c └── tls_transcript_hash.h /README.md: -------------------------------------------------------------------------------- 1 | # CycloneSSL 2 | TLS/DTLS Library 3 | -------------------------------------------------------------------------------- /dtls_misc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dtls_misc.h 3 | * @brief DTLS (Datagram Transport Layer Security) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _DTLS_MISC_H 32 | #define _DTLS_MISC_H 33 | 34 | //DTLS version numbers 35 | #define DTLS_VERSION_1_0 0xFEFF 36 | #define DTLS_VERSION_1_2 0xFEFD 37 | #define DTLS_VERSION_1_3 0xFEFC 38 | 39 | //DTLS support 40 | #ifndef DTLS_SUPPORT 41 | #define DTLS_SUPPORT DISABLED 42 | #elif (DTLS_SUPPORT != ENABLED && DTLS_SUPPORT != DISABLED) 43 | #error DTLS_SUPPORT parameter is not valid 44 | #endif 45 | 46 | //Default PMTU value 47 | #ifndef DTLS_DEFAULT_PMTU 48 | #define DTLS_DEFAULT_PMTU 1452 49 | #elif (DTLS_DEFAULT_PMTU < 64) 50 | #error DTLS_DEFAULT_PMTU parameter is not valid 51 | #endif 52 | 53 | //Minimum PMTU value 54 | #ifndef DTLS_MIN_PMTU 55 | #define DTLS_MIN_PMTU 528 56 | #elif (DTLS_MIN_PMTU < 64) 57 | #error DTLS_MIN_PMTU parameter is not valid 58 | #endif 59 | 60 | //Replay protection 61 | #ifndef DTLS_REPLAY_DETECTION_SUPPORT 62 | #define DTLS_REPLAY_DETECTION_SUPPORT ENABLED 63 | #elif (DTLS_REPLAY_DETECTION_SUPPORT != ENABLED && DTLS_REPLAY_DETECTION_SUPPORT != DISABLED) 64 | #error DTLS_REPLAY_DETECTION_SUPPORT parameter is not valid 65 | #endif 66 | 67 | //Size of the sliding window for replay protection 68 | #ifndef DTLS_REPLAY_WINDOW_SIZE 69 | #define DTLS_REPLAY_WINDOW_SIZE 64 70 | #elif (DTLS_REPLAY_WINDOW_SIZE < 1) 71 | #error DTLS_REPLAY_WINDOW_SIZE parameter is not valid 72 | #endif 73 | 74 | //Maximum size for cookies 75 | #ifndef DTLS_MAX_COOKIE_SIZE 76 | #define DTLS_MAX_COOKIE_SIZE 32 77 | #elif (DTLS_MAX_COOKIE_SIZE < 32) 78 | #error DTLS_MAX_COOKIE_SIZE parameter is not valid 79 | #endif 80 | 81 | //Maximum number of retransmissions 82 | #ifndef DTLS_MAX_RETRIES 83 | #define DTLS_MAX_RETRIES 5 84 | #elif (DTLS_MAX_RETRIES < 1) 85 | #error DTLS_MAX_RETRIES parameter is not valid 86 | #endif 87 | 88 | //Initial retransmission timeout 89 | #ifndef DTLS_INIT_TIMEOUT 90 | #define DTLS_INIT_TIMEOUT 1000 91 | #elif (DTLS_INIT_TIMEOUT < 100) 92 | #error DTLS_INIT_TIMEOUT parameter is not valid 93 | #endif 94 | 95 | //Minimum retransmission timeout 96 | #ifndef DTLS_MIN_TIMEOUT 97 | #define DTLS_MIN_TIMEOUT 500 98 | #elif (DTLS_MIN_TIMEOUT < 0) 99 | #error DTLS_MIN_TIMEOUT parameter is not valid 100 | #endif 101 | 102 | //Maximum retransmission timeout 103 | #ifndef DTLS_MAX_TIMEOUT 104 | #define DTLS_MAX_TIMEOUT 60000 105 | #elif (DTLS_MAX_TIMEOUT < 1000) 106 | #error DTLS_MAX_TIMEOUT parameter is not valid 107 | #endif 108 | 109 | //C++ guard 110 | #ifdef __cplusplus 111 | extern "C" { 112 | #endif 113 | 114 | 115 | /** 116 | * @brief DTLS retransmission states 117 | **/ 118 | 119 | typedef enum 120 | { 121 | DTLS_RETRANSMIT_STATE_PREPARING = 0, 122 | DTLS_RETRANSMIT_STATE_SENDING = 1, 123 | DTLS_RETRANSMIT_STATE_WAITING = 2, 124 | DTLS_RETRANSMIT_STATE_FINISHED = 3 125 | } DtlsRetransmitState; 126 | 127 | 128 | //CC-RX, CodeWarrior or Win32 compiler? 129 | #if defined(__CCRX__) 130 | #pragma pack 131 | #elif defined(__CWCC__) || defined(_WIN32) 132 | #pragma pack(push, 1) 133 | #endif 134 | 135 | 136 | /** 137 | * @brief Sequence number 138 | **/ 139 | 140 | typedef __packed_struct 141 | { 142 | uint8_t b[6]; 143 | } DtlsSequenceNumber; 144 | 145 | 146 | /** 147 | * @brief Cookie 148 | **/ 149 | 150 | typedef __packed_struct 151 | { 152 | uint8_t length; //0 153 | uint8_t value[]; //1 154 | } DtlsCookie; 155 | 156 | 157 | /** 158 | * @brief List of supported versions 159 | **/ 160 | 161 | typedef __packed_struct 162 | { 163 | uint8_t length; //0 164 | uint16_t value[]; //1 165 | } DtlsSupportedVersionList; 166 | 167 | 168 | /** 169 | * @brief DTLS record 170 | **/ 171 | 172 | typedef __packed_struct 173 | { 174 | uint8_t type; //0 175 | uint16_t version; //1-2 176 | uint16_t epoch; //3-4 177 | DtlsSequenceNumber seqNum; //5-10 178 | uint16_t length; //11-12 179 | uint8_t data[]; //13 180 | } DtlsRecord; 181 | 182 | 183 | /** 184 | * @brief DTLS handshake message 185 | **/ 186 | 187 | typedef __packed_struct 188 | { 189 | uint8_t msgType; //0 190 | uint8_t length[3]; //1-3 191 | uint16_t msgSeq; //4-5 192 | uint8_t fragOffset[3]; //6-8 193 | uint8_t fragLength[3]; //9-11 194 | uint8_t data[]; //12 195 | } DtlsHandshake; 196 | 197 | 198 | /** 199 | * @brief HelloVerifyRequest message 200 | **/ 201 | 202 | typedef __packed_struct 203 | { 204 | uint16_t serverVersion; //0-1 205 | uint8_t cookieLength; //2 206 | uint8_t cookie[]; //3 207 | } DtlsHelloVerifyRequest; 208 | 209 | 210 | //CC-RX, CodeWarrior or Win32 compiler? 211 | #if defined(__CCRX__) 212 | #pragma unpack 213 | #elif defined(__CWCC__) || defined(_WIN32) 214 | #pragma pack(pop) 215 | #endif 216 | 217 | 218 | /** 219 | * @brief Client parameters 220 | **/ 221 | 222 | typedef struct 223 | { 224 | uint16_t version; 225 | const uint8_t *random; 226 | size_t randomLen; 227 | const uint8_t *sessionId; 228 | size_t sessionIdLen; 229 | const uint8_t *cipherSuites; 230 | size_t cipherSuitesLen; 231 | const uint8_t *compressMethods; 232 | size_t compressMethodsLen; 233 | } DtlsClientParameters; 234 | 235 | 236 | /** 237 | * @brief DTLS cookie generation callback function 238 | **/ 239 | 240 | typedef error_t (*DtlsCookieGenerateCallback)(TlsContext *context, 241 | const DtlsClientParameters *clientParams, uint8_t *cookie, 242 | size_t *length, void *param); 243 | 244 | 245 | /** 246 | * @brief DTLS cookie verification callback function 247 | **/ 248 | 249 | typedef error_t (*DtlsCookieVerifyCallback)(TlsContext *context, 250 | const DtlsClientParameters *clientParams, const uint8_t *cookie, 251 | size_t length, void *param); 252 | 253 | 254 | //DTLS specific functions 255 | error_t dtlsSelectVersion(TlsContext *context, uint16_t version); 256 | uint16_t dtlsTranslateVersion(uint16_t version); 257 | 258 | error_t dtlsFormatCookie(TlsContext *context, uint8_t *p, size_t *written); 259 | 260 | error_t dtlsVerifyCookie(TlsContext *context, const DtlsCookie *cookie, 261 | const DtlsClientParameters *clientParams); 262 | 263 | error_t dtlsSendHelloVerifyRequest(TlsContext *context); 264 | 265 | error_t dtlsFormatHelloVerifyRequest(TlsContext *context, 266 | DtlsHelloVerifyRequest *message, size_t *length); 267 | 268 | error_t dtlsParseHelloVerifyRequest(TlsContext *context, 269 | const DtlsHelloVerifyRequest *message, size_t length); 270 | 271 | error_t dtlsParseClientSupportedVersionsExtension(TlsContext *context, 272 | const DtlsSupportedVersionList *supportedVersionList); 273 | 274 | void dtlsInitReplayWindow(TlsContext *context); 275 | error_t dtlsCheckReplayWindow(TlsContext *context, DtlsSequenceNumber *seqNum); 276 | void dtlsUpdateReplayWindow(TlsContext *context, DtlsSequenceNumber *seqNum); 277 | 278 | //C++ guard 279 | #ifdef __cplusplus 280 | } 281 | #endif 282 | 283 | #endif 284 | -------------------------------------------------------------------------------- /dtls_record.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file dtls_record.h 3 | * @brief DTLS record protocol 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _DTLS_RECORD_H 32 | #define _DTLS_RECORD_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //DTLS related functions 43 | error_t dtlsWriteProtocolData(TlsContext *context, 44 | const uint8_t *data, size_t length, TlsContentType contentType); 45 | 46 | error_t dtlsReadProtocolData(TlsContext *context, 47 | uint8_t **data, size_t *length, TlsContentType *contentType); 48 | 49 | error_t dtlsWriteRecord(TlsContext *context, const uint8_t *data, 50 | size_t length, TlsContentType contentType); 51 | 52 | error_t dtlsReadRecord(TlsContext *context); 53 | error_t dtlsProcessRecord(TlsContext *context); 54 | 55 | error_t dtlsSendFlight(TlsContext *context); 56 | 57 | error_t dtlsFragmentHandshakeMessage(TlsContext *context, uint16_t version, 58 | TlsEncryptionEngine *encryptionEngine, const DtlsHandshake *message); 59 | 60 | error_t dtlsReassembleHandshakeMessage(TlsContext *context, 61 | const DtlsHandshake *message); 62 | 63 | error_t dtlsReadDatagram(TlsContext *context, uint8_t *data, 64 | size_t size, size_t *length); 65 | 66 | error_t dtlsTick(TlsContext *context); 67 | 68 | void dtlsIncSequenceNumber(DtlsSequenceNumber *seqNum); 69 | 70 | //C++ guard 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /tls13_client.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls13_client.h 3 | * @brief Handshake message processing (TLS 1.3 client) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS13_CLIENT_H 32 | #define _TLS13_CLIENT_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS 1.3 client specific functions 43 | error_t tls13SendEndOfEarlyData(TlsContext *context); 44 | 45 | error_t tls13FormatEndOfEarlyData(TlsContext *context, 46 | Tls13EndOfEarlyData *message, size_t *length); 47 | 48 | error_t tls13ParseHelloRetryRequest(TlsContext *context, 49 | const Tls13HelloRetryRequest *message, size_t length); 50 | 51 | error_t tls13ParseEncryptedExtensions(TlsContext *context, 52 | const Tls13EncryptedExtensions *message, size_t length); 53 | 54 | error_t tls13ParseNewSessionTicket(TlsContext *context, 55 | const Tls13NewSessionTicket *message, size_t length); 56 | 57 | //C++ guard 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /tls13_client_extensions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls13_client_extensions.h 3 | * @brief Formatting and parsing of extensions (TLS 1.3 client) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS13_CLIENT_EXTENSIONS_H 32 | #define _TLS13_CLIENT_EXTENSIONS_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS 1.3 client specific functions 43 | error_t tls13FormatCookieExtension(TlsContext *context, uint8_t *p, 44 | size_t *written); 45 | 46 | error_t tls13FormatClientKeyShareExtension(TlsContext *context, 47 | uint8_t *p, size_t *written); 48 | 49 | error_t tls13FormatPskKeModesExtension(TlsContext *context, 50 | uint8_t *p, size_t *written); 51 | 52 | error_t tls13FormatClientPreSharedKeyExtension(TlsContext *context, 53 | uint8_t *p, size_t *written, Tls13PskIdentityList **identityList, 54 | Tls13PskBinderList **binderList); 55 | 56 | error_t tls13FormatClientEarlyDataExtension(TlsContext *context, 57 | uint8_t *p, size_t *written); 58 | 59 | error_t tls13ParseServerSupportedVersionsExtension(TlsContext *context, 60 | const TlsExtension *selectedVersion); 61 | 62 | error_t tls13ParseCookieExtension(TlsContext *context, 63 | const Tls13Cookie *cookie); 64 | 65 | error_t tls13ParseSelectedGroupExtension(TlsContext *context, 66 | const TlsExtension *selectedGroup); 67 | 68 | error_t tls13ParseServerKeyShareExtension(TlsContext *context, 69 | const Tls13KeyShareEntry *serverShare); 70 | 71 | error_t tls13ParseServerPreSharedKeyExtension(TlsContext *context, 72 | const TlsExtension *selectedIdentity); 73 | 74 | error_t tls13ParseServerEarlyDataExtension(TlsContext *context, 75 | TlsMessageType msgType, const TlsExtension *earlyDataIndication); 76 | 77 | //C++ guard 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /tls13_client_misc.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls13_client_misc.c 3 | * @brief Helper functions for TLS 1.3 client 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | //Switch to the appropriate trace level 32 | #define TRACE_LEVEL TLS_TRACE_LEVEL 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | #include "tls_handshake.h" 37 | #include "tls_client.h" 38 | #include "tls_common.h" 39 | #include "tls_transcript_hash.h" 40 | #include "tls_record.h" 41 | #include "tls_misc.h" 42 | #include "tls13_client_misc.h" 43 | #include "tls13_key_material.h" 44 | #include "tls13_ticket.h" 45 | #include "debug.h" 46 | 47 | //Check TLS library configuration 48 | #if (TLS_SUPPORT == ENABLED && TLS_CLIENT_SUPPORT == ENABLED && \ 49 | TLS_MAX_VERSION >= TLS_VERSION_1_3) 50 | 51 | 52 | /** 53 | * @brief Check whether an incoming ServerHello message is a HelloRetryRequest 54 | * @param[in] message Pointer to the ServerHello message 55 | * @param[in] length Length of the ServerHello message 56 | * @return TRUE is the message is a HelloRetryRequest, else FALSE 57 | **/ 58 | 59 | bool_t tls13IsHelloRetryRequest(const TlsServerHello *message, size_t length) 60 | { 61 | bool_t res; 62 | 63 | //Initialize flag 64 | res = FALSE; 65 | 66 | //Check the length of the incoming ServerHello message 67 | if(length >= sizeof(TlsServerHello)) 68 | { 69 | //Upon receiving a message with type ServerHello, implementations must 70 | //first examine the Random field 71 | if(osMemcmp(&message->random, tls13HelloRetryRequestRandom, 72 | sizeof(tls13HelloRetryRequestRandom)) == 0) 73 | { 74 | //The Random field matches the special value 75 | res = TRUE; 76 | } 77 | } 78 | 79 | //Return TRUE is the message is a HelloRetryRequest, else FALSE 80 | return res; 81 | } 82 | 83 | 84 | /** 85 | * @brief Compute PSK binder values 86 | * @param[in] context Pointer to the TLS context 87 | * @param[in] clientHello Pointer to the ClientHello message 88 | * @param[in] clientHelloLen Length of the ClientHello message 89 | * @param[in] identityList List of the identities that the client is willing 90 | * to negotiate with the server 91 | * @param[in,out] binderList List of HMAC values, one for each PSK offered in 92 | * the PreSharedKey extension 93 | * @return Error code 94 | **/ 95 | 96 | error_t tls13ComputePskBinders(TlsContext *context, const void *clientHello, 97 | size_t clientHelloLen, const Tls13PskIdentityList *identityList, 98 | Tls13PskBinderList *binderList) 99 | { 100 | error_t error; 101 | size_t n; 102 | size_t m; 103 | size_t truncatedClientHelloLen; 104 | uint8_t *q; 105 | const uint8_t *p; 106 | Tls13PskBinder *binder; 107 | const Tls13PskIdentity *identity; 108 | 109 | //Initialize status code 110 | error = NO_ERROR; 111 | 112 | #if (TLS13_PSK_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \ 113 | TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED) 114 | //Check whether the ClientHello message contains a PreSharedKey extension 115 | if(identityList != NULL && binderList != NULL) 116 | { 117 | //Point to the list of the identities that the client is willing to 118 | //negotiate with the server 119 | p = identityList->value; 120 | n = ntohs(identityList->length); 121 | 122 | //Point to the list of HMAC values, one for each PSK offered in the 123 | //PreSharedKey extension 124 | q = binderList->value; 125 | m = ntohs(binderList->length); 126 | 127 | //Each entry in the binders list is computed as an HMAC over a transcript 128 | //hash containing a partial ClientHello up to the binders list itself 129 | truncatedClientHelloLen = (uint8_t *) binderList - (uint8_t *) clientHello; 130 | 131 | //Loop through the list of PSK identities 132 | while(n > 0) 133 | { 134 | //Point to the current PskIdentity entry 135 | identity = (Tls13PskIdentity *) p; 136 | 137 | //Malformed PreSharedKey extension? 138 | if(n < sizeof(TlsPskIdentity)) 139 | return ERROR_DECODING_FAILED; 140 | if(n < (sizeof(TlsPskIdentity) + ntohs(identity->length))) 141 | return ERROR_DECODING_FAILED; 142 | 143 | //Point to the obfuscated_ticket_age field 144 | p += sizeof(TlsPskIdentity) + ntohs(identity->length); 145 | n -= sizeof(TlsPskIdentity) + ntohs(identity->length); 146 | 147 | //The obfuscated_ticket_age field is a 32-bit unsigned integer 148 | if(n < sizeof(uint32_t)) 149 | return ERROR_DECODING_FAILED; 150 | 151 | //Point to the next PskIdentity entry 152 | p += sizeof(uint32_t); 153 | n -= sizeof(uint32_t); 154 | 155 | //Point to the PskBinderEntry 156 | binder = (Tls13PskBinder *) q; 157 | 158 | //Malformed PreSharedKey extension? 159 | if(m < sizeof(Tls13PskBinder)) 160 | return ERROR_DECODING_FAILED; 161 | if(m < (sizeof(Tls13PskBinder) + binder->length)) 162 | return ERROR_DECODING_FAILED; 163 | 164 | //Point to the next PskBinderEntry 165 | q += sizeof(Tls13PskBinder) + binder->length; 166 | m -= sizeof(Tls13PskBinder) + binder->length; 167 | 168 | //Fix the value of the PSK binder 169 | error = tls13ComputePskBinder(context, clientHello, clientHelloLen, 170 | truncatedClientHelloLen, identity, binder->value, binder->length); 171 | //Any error to report? 172 | if(error) 173 | break; 174 | } 175 | } 176 | #endif 177 | 178 | //Return status code 179 | return error; 180 | } 181 | 182 | 183 | /** 184 | * @brief Send early data to the remote TLS server 185 | * @param[in] context Pointer to the TLS context 186 | * @param[in] data Pointer to a buffer containing the data to be transmitted 187 | * @param[in] length Number of bytes to be transmitted 188 | * @param[out] written Actual number of bytes written 189 | * @return Error code 190 | **/ 191 | 192 | error_t tls13SendEarlyData(TlsContext *context, const void *data, 193 | size_t length, size_t *written) 194 | { 195 | #if (TLS13_EARLY_DATA_SUPPORT == ENABLED) 196 | error_t error; 197 | size_t n; 198 | 199 | //Actual number of bytes written 200 | *written = 0; 201 | 202 | //Valid PSK? 203 | if(tls13IsPskValid(context)) 204 | { 205 | //Make sure a valid cipher suite has been provisioned 206 | if(context->pskCipherSuite == 0) 207 | return ERROR_END_OF_STREAM; 208 | } 209 | else if(tls13IsTicketValid(context)) 210 | { 211 | //Make sure the cipher suite associated with the ticket is valid 212 | if(context->ticketCipherSuite == 0) 213 | return ERROR_END_OF_STREAM; 214 | } 215 | else 216 | { 217 | //The pre-shared key is not valid 218 | return ERROR_END_OF_STREAM; 219 | } 220 | 221 | //Initialize status code 222 | error = NO_ERROR; 223 | 224 | //TLS 1.3 allows clients to send data on the first flight 225 | while(!error) 226 | { 227 | //TLS protocol? 228 | if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM) 229 | { 230 | //Check current state 231 | if(context->state != TLS_STATE_INIT && 232 | context->state != TLS_STATE_CLOSED) 233 | { 234 | //Flush send buffer 235 | error = tlsWriteProtocolData(context, NULL, 0, TLS_TYPE_NONE); 236 | //Any error to report? 237 | if(error) 238 | break; 239 | } 240 | } 241 | 242 | //The TLS handshake is implemented as a state machine representing the 243 | //current location in the protocol 244 | if(context->state == TLS_STATE_INIT) 245 | { 246 | //TLS handshake initialization 247 | error = tlsInitHandshake(context); 248 | } 249 | else if(context->state == TLS_STATE_CLIENT_HELLO) 250 | { 251 | //If the client opts to send application data in its first flight 252 | //of messages, it must supply both the PreSharedKey and EarlyData 253 | //extensions 254 | context->earlyDataEnabled = TRUE; 255 | 256 | //When a client first connects to a server, it is required to send 257 | //the ClientHello as its first message 258 | error = tlsSendClientHello(context); 259 | } 260 | else if(context->state == TLS_STATE_SERVER_HELLO) 261 | { 262 | //Initialize handshake message hashing 263 | error = tlsInitTranscriptHash(context); 264 | 265 | #if (TLS13_MIDDLEBOX_COMPAT_SUPPORT == ENABLED) 266 | //DTLS implementations do not use the "compatibility mode" and must 267 | //not send ChangeCipherSpec messages (refer to RFC 9147, section 5) 268 | if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM) 269 | { 270 | //In middlebox compatibility mode, the client sends a dummy 271 | //ChangeCipherSpec record immediately before its second flight 272 | tlsChangeState(context, TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC); 273 | } 274 | else 275 | #endif 276 | { 277 | //The client can send its second flight 278 | tlsChangeState(context, TLS_STATE_CLIENT_HELLO_2); 279 | } 280 | } 281 | else if(context->state == TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC) 282 | { 283 | //Send a dummy ChangeCipherSpec record 284 | error = tlsSendChangeCipherSpec(context); 285 | } 286 | else if(context->state == TLS_STATE_CLIENT_HELLO_2) 287 | { 288 | //Compute early traffic keys 289 | error = tls13GenerateEarlyTrafficKeys(context); 290 | } 291 | else if(context->state == TLS_STATE_EARLY_DATA) 292 | { 293 | //Send as much data as possible 294 | if(*written < length && 295 | context->earlyDataLen < context->maxEarlyDataSize) 296 | { 297 | //Calculate the number of bytes to write at a time 298 | n = MIN(context->txBufferMaxLen, length - *written); 299 | n = MIN(n, context->maxEarlyDataSize - context->earlyDataLen); 300 | 301 | //The record length must not exceed 16384 bytes 302 | n = MIN(n, TLS_MAX_RECORD_LENGTH); 303 | 304 | //Debug message 305 | TRACE_INFO("Sending early data (%" PRIuSIZE " bytes)...\r\n", n); 306 | 307 | //Send 0-RTT data 308 | error = tlsWriteProtocolData(context, data, n, 309 | TLS_TYPE_APPLICATION_DATA); 310 | 311 | //Check status code 312 | if(!error) 313 | { 314 | //Advance data pointer 315 | data = (uint8_t *) data + n; 316 | //Update byte counter 317 | *written += n; 318 | 319 | //Total amount of 0-RTT data that have been sent by the client 320 | context->earlyDataLen += n; 321 | } 322 | } 323 | else 324 | { 325 | //Clients must not more than max_early_data_size bytes of 0-RTT data 326 | break; 327 | } 328 | } 329 | else 330 | { 331 | //Report an error 332 | error = ERROR_UNEXPECTED_STATE; 333 | } 334 | } 335 | 336 | //Check status code 337 | if(error == NO_ERROR && length != 0 && *written == 0) 338 | { 339 | error = ERROR_END_OF_STREAM; 340 | } 341 | 342 | //Return status code 343 | return error; 344 | #else 345 | //Not implemented 346 | return ERROR_NOT_IMPLEMENTED; 347 | #endif 348 | } 349 | 350 | #endif 351 | -------------------------------------------------------------------------------- /tls13_client_misc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls13_client_misc.h 3 | * @brief Helper functions for TLS 1.3 client 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS13_CLIENT_MISC_H 32 | #define _TLS13_CLIENT_MISC_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS 1.3 client specific functions 43 | bool_t tls13IsHelloRetryRequest(const TlsServerHello *message, size_t length); 44 | 45 | error_t tls13ComputePskBinders(TlsContext *context, const void *clientHello, 46 | size_t clientHelloLen, const Tls13PskIdentityList *identityList, 47 | Tls13PskBinderList *binderList); 48 | 49 | error_t tls13SendEarlyData(TlsContext *context, const void *data, 50 | size_t length, size_t *written); 51 | 52 | //C++ guard 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /tls13_common.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls13_common.c 3 | * @brief Handshake message processing (TLS 1.3 client and server) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | //Switch to the appropriate trace level 32 | #define TRACE_LEVEL TLS_TRACE_LEVEL 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | #include "tls_handshake.h" 37 | #include "tls_misc.h" 38 | #include "tls13_common.h" 39 | #include "tls13_key_material.h" 40 | #include "debug.h" 41 | 42 | //Check TLS library configuration 43 | #if (TLS_SUPPORT == ENABLED && TLS_MAX_VERSION >= TLS_VERSION_1_3) 44 | 45 | 46 | /** 47 | * @brief Send KeyUpdate message 48 | * 49 | * The KeyUpdate handshake message is used to indicate that the sender is 50 | * updating its sending cryptographic keys. This message can be sent by either 51 | * peer after it has sent a Finished message 52 | * 53 | * @param[in] context Pointer to the TLS context 54 | * @return Error code 55 | **/ 56 | 57 | error_t tls13SendKeyUpdate(TlsContext *context) 58 | { 59 | error_t error; 60 | size_t length; 61 | uint8_t *appTrafficSecret; 62 | Tls13KeyUpdate *message; 63 | const HashAlgo *hash; 64 | 65 | //Initialize pointer 66 | appTrafficSecret = NULL; 67 | 68 | //Point to the buffer where to format the message 69 | message = (Tls13KeyUpdate *) (context->txBuffer + context->txBufferLen); 70 | 71 | //Format KeyUpdate message 72 | error = tls13FormatKeyUpdate(context, message, &length); 73 | 74 | //Check status code 75 | if(!error) 76 | { 77 | //Debug message 78 | TRACE_INFO("Sending KeyUpdate message (%" PRIuSIZE " bytes)...\r\n", length); 79 | TRACE_DEBUG_ARRAY(" ", message, length); 80 | 81 | //Send handshake message 82 | error = tlsSendHandshakeMessage(context, message, length, 83 | TLS_TYPE_KEY_UPDATE); 84 | } 85 | 86 | //Check status code 87 | if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT) 88 | { 89 | //The hash function used by HKDF is the cipher suite hash algorithm 90 | hash = context->cipherSuite.prfHashAlgo; 91 | 92 | //Make sure the hash algorithm is valid 93 | if(hash != NULL) 94 | { 95 | //Check whether TLS operates as a client or a server 96 | if(context->entity == TLS_CONNECTION_END_CLIENT) 97 | { 98 | appTrafficSecret = context->clientAppTrafficSecret; 99 | } 100 | else 101 | { 102 | appTrafficSecret = context->serverAppTrafficSecret; 103 | } 104 | 105 | //Compute the next generation of application traffic secret 106 | error = tls13HkdfExpandLabel(context->transportProtocol, hash, 107 | appTrafficSecret, hash->digestSize, "traffic upd", NULL, 0, 108 | appTrafficSecret, hash->digestSize); 109 | } 110 | else 111 | { 112 | //The hash algorithm is not valid 113 | error = ERROR_FAILURE; 114 | } 115 | } 116 | 117 | //Check status code 118 | if(!error) 119 | { 120 | //Release encryption engine 121 | tlsFreeEncryptionEngine(&context->encryptionEngine); 122 | 123 | //All the traffic keying material is recomputed whenever the underlying 124 | //secret changes 125 | error = tlsInitEncryptionEngine(context, &context->encryptionEngine, 126 | context->entity, TLS_ENCRYPTION_LEVEL_APPLICATION, appTrafficSecret); 127 | } 128 | 129 | //Check status code 130 | if(!error) 131 | { 132 | //After sending a KeyUpdate message, the sender shall send all its 133 | //traffic using the next generation of keys 134 | tlsChangeState(context, TLS_STATE_APPLICATION_DATA); 135 | } 136 | 137 | //Return status code 138 | return error; 139 | } 140 | 141 | 142 | /** 143 | * @brief Format KeyUpdate message 144 | * @param[in] context Pointer to the TLS context 145 | * @param[out] message Buffer where to format the KeyUpdate message 146 | * @param[out] length Length of the resulting KeyUpdate message 147 | * @return Error code 148 | **/ 149 | 150 | error_t tls13FormatKeyUpdate(TlsContext *context, Tls13KeyUpdate *message, 151 | size_t *length) 152 | { 153 | //The request_update field indicates whether the recipient of the KeyUpdate 154 | //should respond with its own KeyUpdate 155 | message->requestUpdate = TLS_KEY_UPDATE_NOT_REQUESTED; 156 | 157 | //The KeyUpdate message consists of a single byte 158 | *length = sizeof(Tls13KeyUpdate); 159 | 160 | //Successful processing 161 | return NO_ERROR; 162 | } 163 | 164 | 165 | /** 166 | * @brief Parse KeyUpdate message 167 | * 168 | * The KeyUpdate handshake message is used to indicate that the sender is 169 | * updating its sending cryptographic keys. This message can be sent by either 170 | * peer after it has sent a Finished message 171 | * 172 | * @param[in] context Pointer to the TLS context 173 | * @param[in] message Incoming EncryptedExtensions message to parse 174 | * @param[in] length Message length 175 | * @return Error code 176 | **/ 177 | 178 | error_t tls13ParseKeyUpdate(TlsContext *context, const Tls13KeyUpdate *message, 179 | size_t length) 180 | { 181 | error_t error; 182 | uint8_t *appTrafficSecret; 183 | TlsConnectionEnd entity; 184 | const HashAlgo *hash; 185 | 186 | //Debug message 187 | TRACE_INFO("KeyUpdate message received (%" PRIuSIZE " bytes)...\r\n", length); 188 | TRACE_DEBUG_ARRAY(" ", message, length); 189 | 190 | //Check TLS version 191 | if(context->version != TLS_VERSION_1_3) 192 | return ERROR_UNEXPECTED_MESSAGE; 193 | 194 | #if (TLS_QUIC_SUPPORT == ENABLED) 195 | //QUIC transport? 196 | if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_QUIC) 197 | { 198 | //Endpoints must treat the receipt of a TLS KeyUpdate message as a 199 | //connection error of type 0x010a, equivalent to a fatal TLS alert of 200 | //unexpected_message (refer to RFC 9001, section 6) 201 | return ERROR_UNEXPECTED_MESSAGE; 202 | } 203 | #endif 204 | 205 | //Check the length of the KeyUpdate message 206 | if(length != sizeof(Tls13KeyUpdate)) 207 | return ERROR_DECODING_FAILED; 208 | 209 | //Ensure the value of the request_update field is valid 210 | if(message->requestUpdate != TLS_KEY_UPDATE_NOT_REQUESTED && 211 | message->requestUpdate != TLS_KEY_UPDATE_REQUESTED) 212 | { 213 | //If an implementation receives any other value, it must terminate the 214 | //connection with an illegal_parameter alert 215 | return ERROR_ILLEGAL_PARAMETER; 216 | } 217 | 218 | //Implementations that receive a KeyUpdate prior to receiving a Finished 219 | //message must terminate the connection with an unexpected_message alert 220 | if(context->state != TLS_STATE_APPLICATION_DATA && 221 | context->state != TLS_STATE_CLOSING) 222 | { 223 | //Report an error 224 | return ERROR_UNEXPECTED_MESSAGE; 225 | } 226 | 227 | #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0) 228 | //Increment the count of consecutive KeyUpdate messages 229 | context->keyUpdateCount++; 230 | 231 | //Do not allow too many consecutive KeyUpdate message 232 | if(context->keyUpdateCount > TLS_MAX_KEY_UPDATE_MESSAGES) 233 | return ERROR_UNEXPECTED_MESSAGE; 234 | #endif 235 | 236 | //The hash function used by HKDF is the cipher suite hash algorithm 237 | hash = context->cipherSuite.prfHashAlgo; 238 | //Make sure the hash algorithm is valid 239 | if(hash == NULL) 240 | return ERROR_FAILURE; 241 | 242 | //Upon receiving a KeyUpdate, the receiver must update its receiving keys 243 | if(context->entity == TLS_CONNECTION_END_CLIENT) 244 | { 245 | entity = TLS_CONNECTION_END_SERVER; 246 | appTrafficSecret = context->serverAppTrafficSecret; 247 | } 248 | else 249 | { 250 | entity = TLS_CONNECTION_END_CLIENT; 251 | appTrafficSecret = context->clientAppTrafficSecret; 252 | } 253 | 254 | //Compute the next generation of application traffic secret 255 | error = tls13HkdfExpandLabel(context->transportProtocol, hash, 256 | appTrafficSecret, hash->digestSize, "traffic upd", NULL, 0, 257 | appTrafficSecret, hash->digestSize); 258 | //Any error to report? 259 | if(error) 260 | return error; 261 | 262 | //The implementation must verify that its receive buffer is empty before 263 | //rekeying 264 | if(context->rxBufferLen != 0) 265 | return ERROR_UNEXPECTED_MESSAGE; 266 | 267 | //Release decryption engine 268 | tlsFreeEncryptionEngine(&context->decryptionEngine); 269 | 270 | //All the traffic keying material is recomputed whenever the underlying 271 | //secret changes 272 | error = tlsInitEncryptionEngine(context, &context->decryptionEngine, 273 | entity, TLS_ENCRYPTION_LEVEL_APPLICATION, appTrafficSecret); 274 | //Any error to report? 275 | if(error) 276 | return error; 277 | 278 | //Check the value of the request_update field 279 | if(message->requestUpdate == TLS_KEY_UPDATE_REQUESTED && 280 | context->state == TLS_STATE_APPLICATION_DATA) 281 | { 282 | #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0) 283 | if(context->keyUpdateCount == 1) 284 | #endif 285 | { 286 | //If the request_update field is set to update_requested then the 287 | //receiver must send a KeyUpdate of its own with request_update set to 288 | //update_not_requested prior to sending its next application data 289 | tlsChangeState(context, TLS_STATE_KEY_UPDATE); 290 | } 291 | } 292 | 293 | //Successful processing 294 | return NO_ERROR; 295 | } 296 | 297 | #endif 298 | -------------------------------------------------------------------------------- /tls13_common.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls13_common.h 3 | * @brief Handshake message processing (TLS 1.3 client and server) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS13_COMMON_H 32 | #define _TLS13_COMMON_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS 1.3 related functions 43 | error_t tls13SendKeyUpdate(TlsContext *context); 44 | 45 | error_t tls13FormatKeyUpdate(TlsContext *context, Tls13KeyUpdate *message, 46 | size_t *length); 47 | 48 | error_t tls13ParseKeyUpdate(TlsContext *context, const Tls13KeyUpdate *message, 49 | size_t length); 50 | 51 | //C++ guard 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /tls13_key_material.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls13_key_material.h 3 | * @brief TLS 1.3 key schedule 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS13_KEY_MATERIAL_H 32 | #define _TLS13_KEY_MATERIAL_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS 1.3 related functions 43 | error_t tls13HkdfExpandLabel(TlsTransportProtocol transportProtocol, 44 | const HashAlgo *hash, const uint8_t *secret, size_t secretLen, 45 | const char_t *label, const uint8_t *context, size_t contextLen, 46 | uint8_t *output, size_t outputLen); 47 | 48 | error_t tls13DeriveSecret(TlsContext *context, const uint8_t *secret, 49 | size_t secretLen, const char_t *label, const char_t *message, 50 | size_t messageLen, uint8_t *output, size_t outputLen); 51 | 52 | error_t tls13GenerateEarlyTrafficKeys(TlsContext *context); 53 | error_t tls13GenerateHandshakeTrafficKeys(TlsContext *context); 54 | error_t tls13GenerateServerAppTrafficKeys(TlsContext *context); 55 | error_t tls13GenerateClientAppTrafficKeys(TlsContext *context); 56 | 57 | //C++ guard 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /tls13_misc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls13_misc.h 3 | * @brief TLS 1.3 helper functions 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS13_MISC_H 32 | #define _TLS13_MISC_H 33 | 34 | //DHE key establishment 35 | #ifndef TLS13_DHE_KE_SUPPORT 36 | #define TLS13_DHE_KE_SUPPORT ENABLED 37 | #elif (TLS13_DHE_KE_SUPPORT != ENABLED && TLS13_DHE_KE_SUPPORT != DISABLED) 38 | #error TLS13_DHE_KE_SUPPORT parameter is not valid 39 | #endif 40 | 41 | //ECDHE key exchange support 42 | #ifndef TLS13_ECDHE_KE_SUPPORT 43 | #define TLS13_ECDHE_KE_SUPPORT ENABLED 44 | #elif (TLS13_ECDHE_KE_SUPPORT != ENABLED && TLS13_ECDHE_KE_SUPPORT != DISABLED) 45 | #error TLS13_ECDHE_KE_SUPPORT parameter is not valid 46 | #endif 47 | 48 | //ML-KEM key exchange support 49 | #ifndef TLS13_MLKEM_KE_SUPPORT 50 | #define TLS13_MLKEM_KE_SUPPORT DISABLED 51 | #elif (TLS13_MLKEM_KE_SUPPORT != ENABLED && TLS13_MLKEM_KE_SUPPORT != DISABLED) 52 | #error TLS13_MLKEM_KE_SUPPORT parameter is not valid 53 | #endif 54 | 55 | //Hybrid key exchange support 56 | #ifndef TLS13_HYBRID_KE_SUPPORT 57 | #define TLS13_HYBRID_KE_SUPPORT DISABLED 58 | #elif (TLS13_HYBRID_KE_SUPPORT != ENABLED && TLS13_HYBRID_KE_SUPPORT != DISABLED) 59 | #error TLS13_HYBRID_KE_SUPPORT parameter is not valid 60 | #endif 61 | 62 | //PSK-only key exchange support 63 | #ifndef TLS13_PSK_KE_SUPPORT 64 | #define TLS13_PSK_KE_SUPPORT DISABLED 65 | #elif (TLS13_PSK_KE_SUPPORT != ENABLED && TLS13_PSK_KE_SUPPORT != DISABLED) 66 | #error TLS13_PSK_KE_SUPPORT parameter is not valid 67 | #endif 68 | 69 | //PSK with DHE key exchange support 70 | #ifndef TLS13_PSK_DHE_KE_SUPPORT 71 | #define TLS13_PSK_DHE_KE_SUPPORT ENABLED 72 | #elif (TLS13_PSK_DHE_KE_SUPPORT != ENABLED && TLS13_PSK_DHE_KE_SUPPORT != DISABLED) 73 | #error TLS13_PSK_DHE_KE_SUPPORT parameter is not valid 74 | #endif 75 | 76 | //PSK with ECDHE key exchange support 77 | #ifndef TLS13_PSK_ECDHE_KE_SUPPORT 78 | #define TLS13_PSK_ECDHE_KE_SUPPORT ENABLED 79 | #elif (TLS13_PSK_ECDHE_KE_SUPPORT != ENABLED && TLS13_PSK_ECDHE_KE_SUPPORT != DISABLED) 80 | #error TLS13_PSK_ECDHE_KE_SUPPORT parameter is not valid 81 | #endif 82 | 83 | //PSK with ML-KEM key exchange support 84 | #ifndef TLS13_PSK_MLKEM_KE_SUPPORT 85 | #define TLS13_PSK_MLKEM_KE_SUPPORT DISABLED 86 | #elif (TLS13_PSK_MLKEM_KE_SUPPORT != ENABLED && TLS13_PSK_MLKEM_KE_SUPPORT != DISABLED) 87 | #error TLS13_PSK_MLKEM_KE_SUPPORT parameter is not valid 88 | #endif 89 | 90 | //PSK with hybrid key exchange support 91 | #ifndef TLS13_PSK_HYBRID_KE_SUPPORT 92 | #define TLS13_PSK_HYBRID_KE_SUPPORT DISABLED 93 | #elif (TLS13_PSK_HYBRID_KE_SUPPORT != ENABLED && TLS13_PSK_HYBRID_KE_SUPPORT != DISABLED) 94 | #error TLS13_PSK_HYBRID_KE_SUPPORT parameter is not valid 95 | #endif 96 | 97 | //Early data support 98 | #ifndef TLS13_EARLY_DATA_SUPPORT 99 | #define TLS13_EARLY_DATA_SUPPORT DISABLED 100 | #elif (TLS13_EARLY_DATA_SUPPORT != ENABLED && TLS13_EARLY_DATA_SUPPORT != DISABLED) 101 | #error TLS13_EARLY_DATA_SUPPORT parameter is not valid 102 | #endif 103 | 104 | //Middlebox compatibility mode 105 | #ifndef TLS13_MIDDLEBOX_COMPAT_SUPPORT 106 | #define TLS13_MIDDLEBOX_COMPAT_SUPPORT ENABLED 107 | #elif (TLS13_MIDDLEBOX_COMPAT_SUPPORT != ENABLED && TLS13_MIDDLEBOX_COMPAT_SUPPORT != DISABLED) 108 | #error TLS13_MIDDLEBOX_COMPAT_SUPPORT parameter is not valid 109 | #endif 110 | 111 | //Maximum size for cookies 112 | #ifndef TLS13_MAX_COOKIE_SIZE 113 | #define TLS13_MAX_COOKIE_SIZE 256 114 | #elif (TLS13_MAX_COOKIE_SIZE < 32) 115 | #error TLS13_MAX_COOKIE_SIZE parameter is not valid 116 | #endif 117 | 118 | //Maximum size for session tickets 119 | #ifndef TLS13_MAX_TICKET_SIZE 120 | #define TLS13_MAX_TICKET_SIZE 1024 121 | #elif (TLS13_MAX_TICKET_SIZE < 32) 122 | #error TLS13_MAX_TICKET_SIZE parameter is not valid 123 | #endif 124 | 125 | //Maximum lifetime of session tickets 126 | #ifndef TLS13_MAX_TICKET_LIFETIME 127 | #define TLS13_MAX_TICKET_LIFETIME 604800 128 | #elif (TLS13_MAX_TICKET_LIFETIME < 0) 129 | #error TLS13_MAX_TICKET_LIFETIME parameter is not valid 130 | #endif 131 | 132 | //Age tolerance for tickets, in milliseconds 133 | #ifndef TLS13_TICKET_AGE_TOLERANCE 134 | #define TLS13_TICKET_AGE_TOLERANCE 5000 135 | #elif (TLS13_TICKET_AGE_TOLERANCE < 0) 136 | #error TLS13_TICKET_AGE_TOLERANCE parameter is not valid 137 | #endif 138 | 139 | //Number of NewSessionTicket message sent by the server 140 | #ifndef TLS13_NEW_SESSION_TICKET_COUNT 141 | #define TLS13_NEW_SESSION_TICKET_COUNT 2 142 | #elif (TLS13_NEW_SESSION_TICKET_COUNT < 0) 143 | #error TLS13_NEW_SESSION_TICKET_COUNT parameter is not valid 144 | #endif 145 | 146 | //Maximum size for HKDF digests 147 | #if (TLS_SHA384_SUPPORT == ENABLED) 148 | #define TLS13_MAX_HKDF_DIGEST_SIZE 48 149 | #else 150 | #define TLS13_MAX_HKDF_DIGEST_SIZE 32 151 | #endif 152 | 153 | //C++ guard 154 | #ifdef __cplusplus 155 | extern "C" { 156 | #endif 157 | 158 | 159 | /** 160 | * @brief PSK key exchange modes 161 | **/ 162 | 163 | typedef enum 164 | { 165 | TLS_PSK_KEY_EXCH_MODE_PSK_KE = 0, 166 | TLS_PSK_KEY_EXCH_MODE_PSK_DHE_KE = 1 167 | } Tls13PskKeyExchMode; 168 | 169 | 170 | /** 171 | * @brief Key update requests 172 | **/ 173 | 174 | typedef enum 175 | { 176 | TLS_KEY_UPDATE_NOT_REQUESTED = 0, 177 | TLS_KEY_UPDATE_REQUESTED = 1 178 | } Tls13KeyUpdateRequest; 179 | 180 | 181 | //CC-RX, CodeWarrior or Win32 compiler? 182 | #if defined(__CCRX__) 183 | #pragma pack 184 | #elif defined(__CWCC__) || defined(_WIN32) 185 | #pragma pack(push, 1) 186 | #endif 187 | 188 | 189 | /** 190 | * @brief Cookie 191 | **/ 192 | 193 | typedef __packed_struct 194 | { 195 | uint16_t length; //0-1 196 | uint8_t value[]; //2 197 | } Tls13Cookie; 198 | 199 | 200 | /** 201 | * @brief Key share entry 202 | **/ 203 | 204 | typedef __packed_struct 205 | { 206 | uint16_t group; //0 207 | uint16_t length; //1 208 | uint8_t keyExchange[]; //2 209 | } Tls13KeyShareEntry; 210 | 211 | 212 | /** 213 | * @brief List of key shares 214 | **/ 215 | 216 | typedef __packed_struct 217 | { 218 | uint16_t length; //0 219 | uint8_t value[]; //1 220 | } Tls13KeyShareList; 221 | 222 | 223 | /** 224 | * @brief List of PSK key exchange modes 225 | **/ 226 | 227 | typedef __packed_struct 228 | { 229 | uint8_t length; //0 230 | uint8_t value[]; //1 231 | } Tls13PskKeModeList; 232 | 233 | 234 | /** 235 | * @brief PSK identity 236 | **/ 237 | 238 | typedef __packed_struct 239 | { 240 | uint16_t length; //0-1 241 | uint8_t value[]; //2 242 | } Tls13PskIdentity; 243 | 244 | 245 | /** 246 | * @brief List of PSK identities 247 | **/ 248 | 249 | typedef __packed_struct 250 | { 251 | uint16_t length; //0-1 252 | uint8_t value[]; //2 253 | } Tls13PskIdentityList; 254 | 255 | 256 | /** 257 | * @brief PSK binder 258 | **/ 259 | 260 | typedef __packed_struct 261 | { 262 | uint8_t length; //0 263 | uint8_t value[]; //1 264 | } Tls13PskBinder; 265 | 266 | 267 | /** 268 | * @brief List of PSK binders 269 | **/ 270 | 271 | typedef __packed_struct 272 | { 273 | uint16_t length; //0-1 274 | uint8_t value[]; //2 275 | } Tls13PskBinderList; 276 | 277 | 278 | /** 279 | * @brief Certificate request context 280 | **/ 281 | 282 | typedef __packed_struct 283 | { 284 | uint8_t length; //0 285 | uint8_t value[]; //1 286 | } Tls13CertRequestContext; 287 | 288 | 289 | /** 290 | * @brief Digitally-signed element (TLS 1.3) 291 | **/ 292 | 293 | typedef __packed_struct 294 | { 295 | uint16_t algorithm; //0-1 296 | uint16_t length; //2-3 297 | uint8_t value[]; //4 298 | } Tls13DigitalSignature; 299 | 300 | 301 | /** 302 | * @brief HelloRetryRequest message 303 | **/ 304 | 305 | typedef __packed_struct 306 | { 307 | uint16_t serverVersion; //0-1 308 | uint8_t random[32]; //2-33 309 | uint8_t sessionIdLen; //34 310 | uint8_t sessionId[]; //35 311 | } Tls13HelloRetryRequest; 312 | 313 | 314 | /** 315 | * @brief EndOfEarlyData message 316 | **/ 317 | 318 | typedef void *Tls13EndOfEarlyData; 319 | 320 | 321 | /** 322 | * @brief EncryptedExtensions message 323 | **/ 324 | 325 | typedef __packed_struct 326 | { 327 | uint16_t extensionsLen; //0-1 328 | uint8_t extensions[]; //2 329 | } Tls13EncryptedExtensions; 330 | 331 | 332 | /** 333 | * @brief NewSessionTicket message (TLS 1.3) 334 | **/ 335 | 336 | typedef __packed_struct 337 | { 338 | uint32_t ticketLifetime; //0-3 339 | uint32_t ticketAgeAdd; //4-7 340 | uint8_t ticketNonceLen; //8 341 | uint8_t ticketNonce[]; //9 342 | } Tls13NewSessionTicket; 343 | 344 | 345 | /** 346 | * @brief KeyUpdate message 347 | **/ 348 | 349 | typedef __packed_struct 350 | { 351 | uint8_t requestUpdate; //0 352 | } Tls13KeyUpdate; 353 | 354 | 355 | /** 356 | * @brief Session ticket 357 | **/ 358 | 359 | typedef __packed_struct 360 | { 361 | uint16_t length; //0-1 362 | uint8_t data[]; //2 363 | } Tls13Ticket; 364 | 365 | 366 | /** 367 | * @brief Session state information 368 | **/ 369 | 370 | typedef __packed_struct 371 | { 372 | uint16_t version; ///mutex)) 73 | { 74 | //Clean up side effects 75 | tlsFreeMem(cache); 76 | //Report an error 77 | return NULL; 78 | } 79 | 80 | //Save the maximum number of cache entries 81 | cache->size = size; 82 | 83 | //Return a pointer to the newly created cache 84 | return cache; 85 | } 86 | 87 | 88 | /** 89 | * @brief Search the session cache for a given session ID 90 | * @param[in] cache Pointer to the session cache 91 | * @param[in] sessionId Expected session ID 92 | * @param[in] sessionIdLen Length of the session ID 93 | * @return A pointer to the matching session is returned. NULL is returned 94 | * if the specified ID could not be found in the session cache 95 | **/ 96 | 97 | TlsSessionState *tlsFindCache(TlsCache *cache, const uint8_t *sessionId, 98 | size_t sessionIdLen) 99 | { 100 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2) 101 | uint_t i; 102 | systime_t time; 103 | TlsSessionState *session; 104 | 105 | //Check parameters 106 | if(cache == NULL || sessionId == NULL || sessionIdLen == 0) 107 | return NULL; 108 | 109 | //Initialize session state 110 | session = NULL; 111 | 112 | //Get current time 113 | time = osGetSystemTime(); 114 | 115 | //Acquire exclusive access to the session cache 116 | osAcquireMutex(&cache->mutex); 117 | 118 | //Flush expired entries 119 | for(i = 0; i < cache->size; i++) 120 | { 121 | //Skip unused entries 122 | if(cache->sessions[i].sessionIdLen != 0) 123 | { 124 | //Outdated entry? 125 | if((time - cache->sessions[i].timestamp) >= TLS_SESSION_CACHE_LIFETIME) 126 | { 127 | //This session is no more valid and should be removed from the cache 128 | tlsFreeSessionState(&cache->sessions[i]); 129 | } 130 | } 131 | } 132 | 133 | //Search the cache for the specified session ID 134 | for(i = 0; i < cache->size; i++) 135 | { 136 | //Check whether the current identifier matches the specified session ID 137 | if(cache->sessions[i].sessionIdLen == sessionIdLen && 138 | osMemcmp(cache->sessions[i].sessionId, sessionId, sessionIdLen) == 0) 139 | { 140 | //A matching session has been found 141 | session = &cache->sessions[i]; 142 | break; 143 | } 144 | } 145 | 146 | //Release exclusive access to the session cache 147 | osReleaseMutex(&cache->mutex); 148 | 149 | //Return a pointer to the matching session, if any 150 | return session; 151 | #else 152 | //Not implemented 153 | return NULL; 154 | #endif 155 | } 156 | 157 | 158 | /** 159 | * @brief Save current session in cache 160 | * @param[in] context TLS context 161 | * @return Error code 162 | **/ 163 | 164 | error_t tlsSaveToCache(TlsContext *context) 165 | { 166 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2) 167 | error_t error; 168 | uint_t i; 169 | systime_t time; 170 | TlsSessionState *session; 171 | TlsSessionState *firstFreeEntry; 172 | TlsSessionState *oldestEntry; 173 | 174 | //Check parameters 175 | if(context == NULL) 176 | return ERROR_INVALID_PARAMETER; 177 | 178 | //Check whether session caching is supported 179 | if(context->cache == NULL) 180 | return ERROR_FAILURE; 181 | 182 | //Ensure the session ID is valid 183 | if(context->sessionIdLen == 0) 184 | return NO_ERROR; 185 | 186 | //Acquire exclusive access to the session cache 187 | osAcquireMutex(&context->cache->mutex); 188 | 189 | //Get current time 190 | time = osGetSystemTime(); 191 | 192 | //Keep track of the first free entry 193 | firstFreeEntry = NULL; 194 | //Keep track of the oldest entry 195 | oldestEntry = NULL; 196 | 197 | //Search the cache for the specified session ID 198 | for(i = 0; i < context->cache->size; i++) 199 | { 200 | //Point to the current entry 201 | session = &context->cache->sessions[i]; 202 | 203 | //If the session ID already exists, we are done 204 | if(session->sessionIdLen == context->sessionIdLen && 205 | osMemcmp(session->sessionId, context->sessionId, session->sessionIdLen) == 0) 206 | { 207 | //Do not write to session cache 208 | firstFreeEntry = NULL; 209 | oldestEntry = NULL; 210 | //Exit immediately 211 | break; 212 | } 213 | 214 | //Check whether current entry is free 215 | if(session->sessionIdLen == 0) 216 | { 217 | //Keep track of the first free entry 218 | if(!firstFreeEntry) 219 | { 220 | firstFreeEntry = session; 221 | } 222 | } 223 | else 224 | { 225 | //Keep track of the oldest entry in the table 226 | if(oldestEntry == NULL) 227 | { 228 | oldestEntry = session; 229 | } 230 | else if((time - session->timestamp) > (time - oldestEntry->timestamp)) 231 | { 232 | oldestEntry = session; 233 | } 234 | } 235 | } 236 | 237 | //Add current session to cache if necessary 238 | if(firstFreeEntry != NULL) 239 | { 240 | error = tlsSaveSessionId(context, firstFreeEntry); 241 | } 242 | else if(oldestEntry != NULL) 243 | { 244 | error = tlsSaveSessionId(context, oldestEntry); 245 | } 246 | else 247 | { 248 | error = NO_ERROR; 249 | } 250 | 251 | //Release exclusive access to the session cache 252 | osReleaseMutex(&context->cache->mutex); 253 | 254 | //Return status code 255 | return error; 256 | #else 257 | //Not implemented 258 | return ERROR_NOT_IMPLEMENTED; 259 | #endif 260 | } 261 | 262 | 263 | /** 264 | * @brief Remove current session from cache 265 | * @param[in] context TLS context 266 | * @return Error code 267 | **/ 268 | 269 | error_t tlsRemoveFromCache(TlsContext *context) 270 | { 271 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2) 272 | uint_t i; 273 | TlsSessionState *session; 274 | 275 | //Check parameters 276 | if(context == NULL) 277 | return ERROR_INVALID_PARAMETER; 278 | 279 | //Check whether session caching is supported 280 | if(context->cache == NULL) 281 | return ERROR_FAILURE; 282 | 283 | //Ensure the session ID is valid 284 | if(context->sessionIdLen == 0) 285 | return NO_ERROR; 286 | 287 | //Acquire exclusive access to the session cache 288 | osAcquireMutex(&context->cache->mutex); 289 | 290 | //Search the cache for the specified session ID 291 | for(i = 0; i < context->cache->size; i++) 292 | { 293 | //Point to the current entry 294 | session = &context->cache->sessions[i]; 295 | 296 | //Check whether the current identifier matches the specified session ID 297 | if(session->sessionIdLen == context->sessionIdLen && 298 | osMemcmp(session->sessionId, context->sessionId, session->sessionIdLen) == 0) 299 | { 300 | //Drop current entry 301 | tlsFreeSessionState(session); 302 | } 303 | } 304 | 305 | //Release exclusive access to the session cache 306 | osReleaseMutex(&context->cache->mutex); 307 | #endif 308 | 309 | //Successful processing 310 | return NO_ERROR; 311 | } 312 | 313 | 314 | /** 315 | * @brief Properly dispose a session cache 316 | * @param[in] cache Pointer to the session cache to be released 317 | **/ 318 | 319 | void tlsFreeCache(TlsCache *cache) 320 | { 321 | uint_t i; 322 | 323 | //Valid session cache? 324 | if(cache != NULL) 325 | { 326 | //Loop through the session cache 327 | for(i = 0; i < cache->size; i++) 328 | { 329 | //Release current entry 330 | tlsFreeSessionState(&cache->sessions[i]); 331 | } 332 | 333 | //Release mutex object 334 | osDeleteMutex(&cache->mutex); 335 | 336 | //Properly dispose the session cache 337 | tlsFreeMem(cache); 338 | } 339 | } 340 | 341 | #endif 342 | -------------------------------------------------------------------------------- /tls_cache.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_cache.h 3 | * @brief Session cache management 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_CACHE_H 32 | #define _TLS_CACHE_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //Session cache management 43 | TlsCache *tlsInitCache(uint_t size); 44 | 45 | TlsSessionState *tlsFindCache(TlsCache *cache, const uint8_t *sessionId, 46 | size_t sessionIdLen); 47 | 48 | error_t tlsSaveToCache(TlsContext *context); 49 | error_t tlsRemoveFromCache(TlsContext *context); 50 | void tlsFreeCache(TlsCache *cache); 51 | 52 | //C++ guard 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /tls_certificate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_certificate.h 3 | * @brief X.509 certificate handling 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_CERTIFICATE_H 32 | #define _TLS_CERTIFICATE_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | #include "pkix/x509_common.h" 37 | 38 | //C++ guard 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | //TLS related functions 44 | error_t tlsFormatCertificateList(TlsContext *context, uint8_t *p, 45 | size_t *written); 46 | 47 | error_t tlsFormatRawPublicKey(TlsContext *context, uint8_t *p, 48 | size_t *written); 49 | 50 | error_t tlsParseCertificateList(TlsContext *context, const uint8_t *p, 51 | size_t length); 52 | 53 | error_t tlsParseRawPublicKey(TlsContext *context, const uint8_t *p, 54 | size_t length); 55 | 56 | bool_t tlsIsCertificateAcceptable(TlsContext *context, 57 | const TlsCertDesc *cert, const uint8_t *certTypes, size_t numCertTypes, 58 | const TlsSupportedGroupList *curveList, 59 | const TlsSignSchemeList *certSignAlgoList, 60 | const TlsCertAuthorities *certAuthorities); 61 | 62 | error_t tlsValidateCertificate(TlsContext *context, 63 | const X509CertInfo *certInfo, uint_t pathLen, const char_t *subjectName); 64 | 65 | error_t tlsGetCertificateType(const X509CertInfo *certInfo, 66 | TlsCertificateType *certType, TlsNamedGroup *namedCurve); 67 | 68 | error_t tlsGetCertificateSignAlgo(const X509CertInfo *certInfo, 69 | TlsSignatureScheme *signScheme); 70 | 71 | error_t tlsReadSubjectPublicKey(TlsContext *context, 72 | const X509SubjectPublicKeyInfo *subjectPublicKeyInfo); 73 | 74 | error_t tlsCheckKeyUsage(const X509CertInfo *certInfo, 75 | TlsConnectionEnd entity, TlsKeyExchMethod keyExchMethod); 76 | 77 | //C++ guard 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /tls_client.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_client.h 3 | * @brief Handshake message processing (TLS client) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_CLIENT_H 32 | #define _TLS_CLIENT_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS client specific functions 43 | error_t tlsSendClientHello(TlsContext *context); 44 | error_t tlsSendClientKeyExchange(TlsContext *context); 45 | 46 | error_t tlsFormatClientHello(TlsContext *context, 47 | TlsClientHello *message, size_t *length); 48 | 49 | error_t tlsFormatClientKeyExchange(TlsContext *context, 50 | TlsClientKeyExchange *message, size_t *length); 51 | 52 | error_t tlsParseHelloRequest(TlsContext *context, 53 | const TlsHelloRequest *message, size_t length); 54 | 55 | error_t tlsParseServerHello(TlsContext *context, 56 | const TlsServerHello *message, size_t length); 57 | 58 | error_t tlsParseServerKeyExchange(TlsContext *context, 59 | const TlsServerKeyExchange *message, size_t length); 60 | 61 | error_t tlsParseCertificateRequest(TlsContext *context, 62 | const TlsCertificateRequest *message, size_t length); 63 | 64 | error_t tlsParseServerHelloDone(TlsContext *context, 65 | const TlsServerHelloDone *message, size_t length); 66 | 67 | error_t tlsParseNewSessionTicket(TlsContext *context, 68 | const TlsNewSessionTicket *message, size_t length); 69 | 70 | //C++ guard 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /tls_client_extensions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_client_extensions.h 3 | * @brief Formatting and parsing of extensions (TLS client) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_CLIENT_EXTENSIONS_H 32 | #define _TLS_CLIENT_EXTENSIONS_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS client specific functions 43 | error_t tlsFormatClientSupportedVersionsExtension(TlsContext *context, 44 | uint8_t *p, size_t *written); 45 | 46 | error_t tlsFormatClientSniExtension(TlsContext *context, 47 | uint8_t *p, size_t *written); 48 | 49 | error_t tlsFormatClientMaxFragLenExtension(TlsContext *context, 50 | uint8_t *p, size_t *written); 51 | 52 | error_t tlsFormatClientRecordSizeLimitExtension(TlsContext *context, 53 | uint8_t *p, size_t *written); 54 | 55 | error_t tlsFormatTrustedCaKeysExtension(TlsContext *context, uint8_t *p, 56 | size_t *written); 57 | 58 | error_t tlsFormatSupportedGroupsExtension(TlsContext *context, uint8_t *p, 59 | size_t *written); 60 | 61 | error_t tlsFormatClientEcPointFormatsExtension(TlsContext *context, 62 | uint8_t *p, size_t *written); 63 | 64 | error_t tlsFormatClientAlpnExtension(TlsContext *context, 65 | uint8_t *p, size_t *written); 66 | 67 | error_t tlsFormatClientCertTypeListExtension(TlsContext *context, 68 | uint8_t *p, size_t *written); 69 | 70 | error_t tlsFormatServerCertTypeListExtension(TlsContext *context, 71 | uint8_t *p, size_t *written); 72 | 73 | error_t tlsFormatClientEtmExtension(TlsContext *context, 74 | uint8_t *p, size_t *written); 75 | 76 | error_t tlsFormatClientEmsExtension(TlsContext *context, 77 | uint8_t *p, size_t *written); 78 | 79 | error_t tlsFormatClientSessionTicketExtension(TlsContext *context, 80 | uint8_t *p, size_t *written); 81 | 82 | error_t tlsFormatClientRenegoInfoExtension(TlsContext *context, 83 | uint8_t *p, size_t *written); 84 | 85 | error_t tlsFormatClientHelloPaddingExtension(TlsContext *context, 86 | size_t clientHelloLen, uint8_t *p, size_t *written); 87 | 88 | error_t tlsParseServerSniExtension(TlsContext *context, 89 | const TlsServerNameList *serverNameList); 90 | 91 | error_t tlsParseServerMaxFragLenExtension(TlsContext *context, 92 | const TlsExtension *maxFragLen); 93 | 94 | error_t tlsParseServerRecordSizeLimitExtension(TlsContext *context, 95 | const TlsExtension *recordSizeLimit); 96 | 97 | error_t tlsParseServerEcPointFormatsExtension(TlsContext *context, 98 | const TlsEcPointFormatList *ecPointFormatList); 99 | 100 | error_t tlsParseServerAlpnExtension(TlsContext *context, 101 | const TlsProtocolNameList *protocolNameList); 102 | 103 | error_t tlsParseClientCertTypeExtension(TlsContext *context, 104 | const TlsExtension *clientCertType); 105 | 106 | error_t tlsParseServerCertTypeExtension(TlsContext *context, 107 | const TlsExtension *serverCertType); 108 | 109 | error_t tlsParseServerEtmExtension(TlsContext *context, 110 | const TlsExtension *encryptThenMac); 111 | 112 | error_t tlsParseServerEmsExtension(TlsContext *context, 113 | const TlsExtension *extendedMasterSecret); 114 | 115 | error_t tlsParseServerSessionTicketExtension(TlsContext *context, 116 | const TlsExtension *sessionTicket); 117 | 118 | error_t tlsParseServerRenegoInfoExtension(TlsContext *context, 119 | const TlsHelloExtensions *extensions); 120 | 121 | //C++ guard 122 | #ifdef __cplusplus 123 | } 124 | #endif 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /tls_client_fsm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_client_fsm.h 3 | * @brief TLS state machine (TLS client) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_CLIENT_FSM_H 32 | #define _TLS_CLIENT_FSM_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsPerformClientHandshake(TlsContext *context); 44 | 45 | error_t tlsParseServerHandshakeMessage(TlsContext *context, uint8_t msgType, 46 | const void *message, size_t length); 47 | 48 | //C++ guard 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /tls_client_misc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_client_misc.h 3 | * @brief Helper functions for TLS client 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_CLIENT_MISC_H 32 | #define _TLS_CLIENT_MISC_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS client specific functions 43 | error_t tlsFormatInitialClientHello(TlsContext *context); 44 | 45 | error_t tlsFormatSessionId(TlsContext *context, uint8_t *p, 46 | size_t *written); 47 | 48 | error_t tlsFormatCipherSuites(TlsContext *context, uint8_t *p, 49 | size_t *written); 50 | 51 | error_t tlsFormatCompressMethods(TlsContext *context, uint8_t *p, 52 | size_t *written); 53 | 54 | error_t tlsFormatTrustedAuthorities(TlsContext *context, uint8_t *p, 55 | size_t *written); 56 | 57 | error_t tlsFormatPskIdentity(TlsContext *context, uint8_t *p, 58 | size_t *written); 59 | 60 | error_t tlsFormatClientKeyParams(TlsContext *context, uint8_t *p, 61 | size_t *written); 62 | 63 | error_t tlsParsePskIdentityHint(TlsContext *context, const uint8_t *p, 64 | size_t length, size_t *consumed); 65 | 66 | error_t tlsParseServerKeyParams(TlsContext *context, const uint8_t *p, 67 | size_t length, size_t *consumed); 68 | 69 | error_t tlsVerifyServerKeySignature(TlsContext *context, 70 | const TlsDigitalSignature *signature, size_t length, 71 | const uint8_t *params, size_t paramsLen, size_t *consumed); 72 | 73 | error_t tls12VerifyServerKeySignature(TlsContext *context, 74 | const Tls12DigitalSignature *signature, size_t length, 75 | const uint8_t *params, size_t paramsLen, size_t *consumed); 76 | 77 | error_t tlsSelectClientVersion(TlsContext *context, 78 | const TlsServerHello *message, const TlsHelloExtensions *extensions); 79 | 80 | error_t tlsResumeSession(TlsContext *context, const uint8_t *sessionId, 81 | size_t sessionIdLen, uint16_t cipherSuite); 82 | 83 | bool_t tlsIsTicketValid(TlsContext *context); 84 | 85 | //C++ guard 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /tls_common.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_common.h 3 | * @brief Handshake message processing (TLS client and server) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_COMMON_H 32 | #define _TLS_COMMON_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsSendCertificate(TlsContext *context); 44 | error_t tlsSendCertificateVerify(TlsContext *context); 45 | error_t tlsSendChangeCipherSpec(TlsContext *context); 46 | error_t tlsSendFinished(TlsContext *context); 47 | error_t tlsSendAlert(TlsContext *context, uint8_t level, uint8_t description); 48 | 49 | error_t tlsFormatCertificate(TlsContext *context, TlsCertificate *message, 50 | size_t *length); 51 | 52 | error_t tlsFormatCertificateVerify(TlsContext *context, 53 | TlsCertificateVerify *message, size_t *length); 54 | 55 | error_t tlsFormatChangeCipherSpec(TlsContext *context, 56 | TlsChangeCipherSpec *message, size_t *length); 57 | 58 | error_t tlsFormatFinished(TlsContext *context, TlsFinished *message, 59 | size_t *length); 60 | 61 | error_t tlsFormatAlert(TlsContext *context, uint8_t level, uint8_t description, 62 | TlsAlert *message, size_t *length); 63 | 64 | error_t tlsFormatCertAuthoritiesExtension(TlsContext *context, uint8_t *p, 65 | size_t *written); 66 | 67 | error_t tlsFormatCertAuthorities(TlsContext *context, uint8_t *p, 68 | size_t *written); 69 | 70 | error_t tlsParseCertificate(TlsContext *context, const TlsCertificate *message, 71 | size_t length); 72 | 73 | error_t tlsParseCertificateVerify(TlsContext *context, 74 | const TlsCertificateVerify *message, size_t length); 75 | 76 | error_t tlsParseChangeCipherSpec(TlsContext *context, 77 | const TlsChangeCipherSpec *message, size_t length); 78 | 79 | error_t tlsParseFinished(TlsContext *context, const TlsFinished *message, 80 | size_t length); 81 | 82 | error_t tlsParseAlert(TlsContext *context, const TlsAlert *message, 83 | size_t length); 84 | 85 | //C++ guard 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /tls_extensions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_extensions.h 3 | * @brief Parsing and checking of TLS extensions 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_EXTENSIONS_H 32 | #define _TLS_EXTENSIONS_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsParseHelloExtensions(TlsMessageType msgType, const uint8_t *p, 44 | size_t length, TlsHelloExtensions *extensions); 45 | 46 | error_t tlsCheckHelloExtensions(TlsMessageType msgType, uint16_t version, 47 | TlsHelloExtensions *extensions); 48 | 49 | error_t tlsCheckDuplicateExtension(uint16_t type, const uint8_t *p, 50 | size_t length); 51 | 52 | bool_t tlsIsAlpnProtocolSupported(TlsContext *context, 53 | const char_t *protocol, size_t length); 54 | 55 | //C++ guard 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /tls_ffdhe.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_ffdhe.h 3 | * @brief FFDHE key exchange 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_FFDHE_H 32 | #define _TLS_FFDHE_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | #include "pkc/dh.h" 37 | 38 | //Maximum size of FFDHE prime modulus 39 | #if (TLS_FFDHE4096_SUPPORT == ENABLED) 40 | #define TLS_MAX_FFDHE_MODULUS_SIZE 512 41 | #elif (TLS_FFDHE3072_SUPPORT == ENABLED) 42 | #define TLS_MAX_FFDHE_MODULUS_SIZE 384 43 | #else 44 | #define TLS_MAX_FFDHE_MODULUS_SIZE 256 45 | #endif 46 | 47 | //C++ guard 48 | #ifdef __cplusplus 49 | extern "C" { 50 | #endif 51 | 52 | 53 | /** 54 | * @brief FFDHE parameters 55 | **/ 56 | 57 | typedef struct 58 | { 59 | const char_t *name; ///txBuffer == NULL) 62 | { 63 | //Allocate TX buffer 64 | context->txBuffer = tlsAllocMem(context->txBufferSize); 65 | 66 | //Failed to allocate memory? 67 | if(context->txBuffer == NULL) 68 | return ERROR_OUT_OF_MEMORY; 69 | 70 | //Clear TX buffer 71 | osMemset(context->txBuffer, 0, context->txBufferSize); 72 | } 73 | 74 | //Allocate receive buffer if necessary 75 | if(context->rxBuffer == NULL) 76 | { 77 | //Allocate RX buffer 78 | context->rxBuffer = tlsAllocMem(context->rxBufferSize); 79 | 80 | //Failed to allocate memory? 81 | if(context->rxBuffer == NULL) 82 | return ERROR_OUT_OF_MEMORY; 83 | 84 | //Clear RX buffer 85 | osMemset(context->rxBuffer, 0, context->rxBufferSize); 86 | } 87 | 88 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3) 89 | //Server mode? 90 | if(context->entity == TLS_CONNECTION_END_SERVER) 91 | { 92 | //A server implementation may choose to reject the early data 93 | context->earlyDataRejected = TRUE; 94 | } 95 | #endif 96 | 97 | //The client initiates the TLS handshake by sending a ClientHello message 98 | //to the server 99 | tlsChangeState(context, TLS_STATE_CLIENT_HELLO); 100 | 101 | //Successful processing 102 | return NO_ERROR; 103 | } 104 | 105 | 106 | /** 107 | * @brief Perform TLS handshake 108 | * 109 | * TLS handshake protocol is responsible for the authentication and key 110 | * exchange necessary to establish a secure session 111 | * 112 | * @param[in] context Pointer to the TLS context 113 | * @return Error code 114 | **/ 115 | 116 | error_t tlsPerformHandshake(TlsContext *context) 117 | { 118 | error_t error; 119 | 120 | #if (TLS_CLIENT_SUPPORT == ENABLED) 121 | //Client mode? 122 | if(context->entity == TLS_CONNECTION_END_CLIENT) 123 | { 124 | //Perform TLS handshake with the remote server 125 | error = tlsPerformClientHandshake(context); 126 | } 127 | else 128 | #endif 129 | #if (TLS_SERVER_SUPPORT == ENABLED) 130 | //Server mode? 131 | if(context->entity == TLS_CONNECTION_END_SERVER) 132 | { 133 | //Perform TLS handshake with the remote client 134 | error = tlsPerformServerHandshake(context); 135 | } 136 | else 137 | #endif 138 | //Unsupported mode of operation? 139 | { 140 | //Report an error 141 | error = ERROR_INVALID_PARAMETER; 142 | } 143 | 144 | //Return status code 145 | return error; 146 | } 147 | 148 | 149 | /** 150 | * @brief Send handshake message 151 | * @param[in] context Pointer to the TLS context 152 | * @param[in] data Pointer to the handshake message 153 | * @param[in] length Length of the handshake message 154 | * @param[in] type Handshake message type 155 | * @return Error code 156 | **/ 157 | 158 | error_t tlsSendHandshakeMessage(TlsContext *context, const void *data, 159 | size_t length, TlsMessageType type) 160 | { 161 | error_t error; 162 | 163 | #if (DTLS_SUPPORT == ENABLED) 164 | //DTLS protocol? 165 | if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM) 166 | { 167 | DtlsHandshake *message; 168 | 169 | //Point to the handshake message header 170 | message = (DtlsHandshake *) data; 171 | 172 | //Make room for the handshake message header 173 | osMemmove(message->data, data, length); 174 | 175 | //Handshake message type 176 | message->msgType = type; 177 | //Number of bytes in the message 178 | STORE24BE(length, message->length); 179 | //Message sequence number 180 | message->msgSeq = htons(context->txMsgSeq); 181 | //Fragment offset 182 | STORE24BE(0, message->fragOffset); 183 | //Fragment length 184 | STORE24BE(length, message->fragLength); 185 | 186 | //Whenever a new message is generated, the message sequence number is 187 | //incremented by one 188 | context->txMsgSeq++; 189 | 190 | //Total length of the handshake message 191 | length += sizeof(DtlsHandshake); 192 | } 193 | else 194 | #endif 195 | //TLS protocol? 196 | { 197 | TlsHandshake *message; 198 | 199 | //Point to the handshake message header 200 | message = (TlsHandshake *) data; 201 | 202 | //Make room for the handshake message header 203 | osMemmove(message->data, data, length); 204 | 205 | //Handshake message type 206 | message->msgType = type; 207 | //Number of bytes in the message 208 | STORE24BE(length, message->length); 209 | 210 | //Total length of the handshake message 211 | length += sizeof(TlsHandshake); 212 | } 213 | 214 | //The HelloRequest message must not be included in the message hashes 215 | //that are maintained throughout the handshake and used in the Finished 216 | //messages and the CertificateVerify message 217 | if(type != TLS_TYPE_HELLO_REQUEST) 218 | { 219 | tlsUpdateTranscriptHash(context, data, length); 220 | } 221 | 222 | //TLS protocol? 223 | if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM || 224 | context->transportProtocol == TLS_TRANSPORT_PROTOCOL_EAP) 225 | { 226 | //Send handshake message 227 | error = tlsWriteProtocolData(context, data, length, TLS_TYPE_HANDSHAKE); 228 | } 229 | #if (DTLS_SUPPORT == ENABLED) 230 | //DTLS protocol? 231 | else if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM) 232 | { 233 | //Send handshake message 234 | error = dtlsWriteProtocolData(context, data, length, TLS_TYPE_HANDSHAKE); 235 | } 236 | #endif 237 | #if (TLS_QUIC_SUPPORT == ENABLED) 238 | //QUIC protocol? 239 | else if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_QUIC) 240 | { 241 | //TLS handshake messages are carried directly over the QUIC transport 242 | //(refer to RFC 9001, section 3) 243 | error = tlsSendQuicHandshakeMessage(context, data, length); 244 | } 245 | #endif 246 | //Unknown protocol? 247 | else 248 | { 249 | //Report an error 250 | error = ERROR_INVALID_PROTOCOL; 251 | } 252 | 253 | //Return status code 254 | return error; 255 | } 256 | 257 | 258 | /** 259 | * @brief Receive peer's message 260 | * @param[in] context Pointer to the TLS context 261 | * @return Error code 262 | **/ 263 | 264 | error_t tlsReceiveHandshakeMessage(TlsContext *context) 265 | { 266 | error_t error; 267 | size_t length; 268 | uint8_t *data; 269 | TlsContentType contentType; 270 | 271 | #if (DTLS_SUPPORT == ENABLED) 272 | //DTLS protocol? 273 | if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM) 274 | { 275 | //A message can be fragmented across several DTLS records 276 | error = dtlsReadProtocolData(context, &data, &length, &contentType); 277 | } 278 | else 279 | #endif 280 | //TLS protocol? 281 | { 282 | //A message can be fragmented across several TLS records 283 | error = tlsReadProtocolData(context, &data, &length, &contentType); 284 | } 285 | 286 | //Check status code 287 | if(!error) 288 | { 289 | //Advance data pointer 290 | context->rxBufferPos += length; 291 | //Number of bytes still pending in the receive buffer 292 | context->rxBufferLen -= length; 293 | 294 | //Handshake message received? 295 | if(contentType == TLS_TYPE_HANDSHAKE) 296 | { 297 | //Parse handshake message 298 | error = tlsParseHandshakeMessage(context, data, length); 299 | } 300 | //ChangeCipherSpec message received? 301 | else if(contentType == TLS_TYPE_CHANGE_CIPHER_SPEC) 302 | { 303 | //The ChangeCipherSpec message is sent by an endpoint to notify the 304 | //peer that subsequent records will be protected under the newly 305 | //negotiated CipherSpec and keys 306 | error = tlsParseChangeCipherSpec(context, (TlsChangeCipherSpec *) data, 307 | length); 308 | } 309 | //Alert message received? 310 | else if(contentType == TLS_TYPE_ALERT) 311 | { 312 | //Parse Alert message 313 | error = tlsParseAlert(context, (TlsAlert *) data, length); 314 | } 315 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3) 316 | //Application data received? 317 | else if(contentType == TLS_TYPE_APPLICATION_DATA) 318 | { 319 | #if (TLS_SERVER_SUPPORT == ENABLED) 320 | //Server mode? 321 | if(context->entity == TLS_CONNECTION_END_SERVER) 322 | { 323 | //Process early data 324 | error = tls13ProcessEarlyData(context, data, length); 325 | } 326 | else 327 | #endif 328 | { 329 | //The server cannot transmit application data before the handshake 330 | //is completed 331 | error = ERROR_UNEXPECTED_MESSAGE; 332 | } 333 | } 334 | #endif 335 | //Unexpected message received? 336 | else 337 | { 338 | //Abort the handshake with an unexpected_message alert 339 | error = ERROR_UNEXPECTED_MESSAGE; 340 | } 341 | } 342 | 343 | //Return status code 344 | return error; 345 | } 346 | 347 | 348 | /** 349 | * @brief Parse handshake message 350 | * @param[in] context Pointer to the TLS context 351 | * @param[in] message Pointer to the handshake message to parse 352 | * @param[in] length Length of the handshake messaged 353 | * @return Error code 354 | **/ 355 | 356 | error_t tlsParseHandshakeMessage(TlsContext *context, const uint8_t *message, 357 | size_t length) 358 | { 359 | error_t error; 360 | uint8_t msgType; 361 | size_t n; 362 | const void *p; 363 | 364 | #if (DTLS_SUPPORT == ENABLED) 365 | //DTLS protocol? 366 | if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM) 367 | { 368 | //Retrieve handshake message type 369 | msgType = ((DtlsHandshake *) message)->msgType; 370 | //Point to the handshake message 371 | p = message + sizeof(DtlsHandshake); 372 | //Calculate the length of the handshake message 373 | n = length - sizeof(DtlsHandshake); 374 | } 375 | else 376 | #endif 377 | //TLS protocol? 378 | { 379 | //Retrieve handshake message type 380 | msgType = ((TlsHandshake *) message)->msgType; 381 | //Point to the handshake message 382 | p = message + sizeof(TlsHandshake); 383 | //Calculate the length of the handshake message 384 | n = length - sizeof(TlsHandshake); 385 | } 386 | 387 | #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0) 388 | //Reset the count of consecutive KeyUpdate messages 389 | if(msgType != TLS_TYPE_KEY_UPDATE) 390 | { 391 | context->keyUpdateCount = 0; 392 | } 393 | #endif 394 | 395 | #if (TLS_CLIENT_SUPPORT == ENABLED) 396 | //Client mode? 397 | if(context->entity == TLS_CONNECTION_END_CLIENT) 398 | { 399 | //Parse server's handshake message 400 | error = tlsParseServerHandshakeMessage(context, msgType, p, n); 401 | 402 | //Update the hash value with the incoming handshake message 403 | tlsUpdateTranscriptHash(context, message, length); 404 | } 405 | else 406 | #endif 407 | #if (TLS_SERVER_SUPPORT == ENABLED) 408 | //Server mode? 409 | if(context->entity == TLS_CONNECTION_END_SERVER) 410 | { 411 | //Update the hash value with the incoming handshake message 412 | if(msgType == TLS_TYPE_CLIENT_KEY_EXCHANGE) 413 | { 414 | tlsUpdateTranscriptHash(context, message, length); 415 | } 416 | 417 | //Parse client's handshake message 418 | error = tlsParseClientHandshakeMessage(context, msgType, p, n); 419 | 420 | //Update the hash value with the incoming handshake message 421 | if(msgType != TLS_TYPE_CLIENT_KEY_EXCHANGE) 422 | { 423 | tlsUpdateTranscriptHash(context, message, length); 424 | } 425 | } 426 | else 427 | #endif 428 | //Unsupported mode of operation? 429 | { 430 | //Report an error 431 | error = ERROR_FAILURE; 432 | } 433 | 434 | //Return status code 435 | return error; 436 | } 437 | 438 | #endif 439 | -------------------------------------------------------------------------------- /tls_handshake.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_handshake.h 3 | * @brief TLS handshake 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_HANDSHAKE_H 32 | #define _TLS_HANDSHAKE_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsInitHandshake(TlsContext *context); 44 | 45 | error_t tlsPerformHandshake(TlsContext *context); 46 | 47 | error_t tlsSendHandshakeMessage(TlsContext *context, const void *data, 48 | size_t length, TlsMessageType type); 49 | 50 | error_t tlsReceiveHandshakeMessage(TlsContext *context); 51 | 52 | error_t tlsParseHandshakeMessage(TlsContext *context, const uint8_t *message, 53 | size_t length); 54 | 55 | //C++ guard 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /tls_key_material.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_key_material.h 3 | * @brief Key material generation 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_KEY_MATERIAL_H 32 | #define _TLS_KEY_MATERIAL_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsGenerateSessionKeys(TlsContext *context); 44 | error_t tlsGenerateMasterSecret(TlsContext *context); 45 | error_t tlsGenerateExtendedMasterSecret(TlsContext *context); 46 | error_t tlsGeneratePskPremasterSecret(TlsContext *context); 47 | error_t tlsGenerateKeyBlock(TlsContext *context, size_t keyBlockLen); 48 | 49 | error_t tlsPrf(const uint8_t *secret, size_t secretLen, const char_t *label, 50 | const uint8_t *seed, size_t seedLen, uint8_t *output, size_t outputLen); 51 | 52 | error_t tls12Prf(const HashAlgo *hash, const uint8_t *secret, size_t secretLen, 53 | const char_t *label, const uint8_t *seed, size_t seedLen, uint8_t *output, 54 | size_t outputLen); 55 | 56 | void tlsDumpSecret(TlsContext *context, const char_t *label, 57 | const uint8_t *secret, size_t secretLen); 58 | 59 | //C++ guard 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /tls_legacy.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_legacy.h 3 | * @brief Legacy definitions 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_LEGACY_H 32 | #define _TLS_LEGACY_H 33 | 34 | //Deprecated definitions 35 | #define TlsIoHandle TlsSocketHandle 36 | 37 | //Deprecated functions 38 | #define tlsSetIoCallbacks(context, handle, sendCallback, receiveCallback) \ 39 | tlsSetSocketCallbacks(context, sendCallback, receiveCallback, handle); 40 | 41 | #ifdef TLS_RSA_SUPPORT 42 | #if (TLS_RSA_SUPPORT == ENABLED) 43 | #define TLS_RSA_KE_SUPPORT ENABLED 44 | #else 45 | #define TLS_RSA_KE_SUPPORT DISABLED 46 | #endif 47 | #undef TLS_RSA_SUPPORT 48 | #endif 49 | 50 | #ifdef TLS_DHE_RSA_SUPPORT 51 | #define TLS_DHE_RSA_KE_SUPPORT TLS_DHE_RSA_SUPPORT 52 | #endif 53 | 54 | #ifdef TLS_DHE_DSS_SUPPORT 55 | #define TLS_DHE_DSS_KE_SUPPORT TLS_DHE_DSS_SUPPORT 56 | #endif 57 | 58 | #ifdef TLS_DH_ANON_SUPPORT 59 | #define TLS_DH_ANON_KE_SUPPORT TLS_DH_ANON_SUPPORT 60 | #endif 61 | 62 | #ifdef TLS_ECDHE_RSA_SUPPORT 63 | #define TLS_ECDHE_RSA_KE_SUPPORT TLS_ECDHE_RSA_SUPPORT 64 | #endif 65 | 66 | #ifdef TLS_ECDHE_ECDSA_SUPPORT 67 | #define TLS_ECDHE_ECDSA_KE_SUPPORT TLS_ECDHE_ECDSA_SUPPORT 68 | #endif 69 | 70 | #ifdef TLS_ECDH_ANON_SUPPORT 71 | #define TLS_ECDH_ANON_KE_SUPPORT TLS_ECDH_ANON_SUPPORT 72 | #endif 73 | 74 | #ifdef TLS_PSK_SUPPORT 75 | #if (TLS_PSK_SUPPORT == ENABLED) 76 | #define TLS_PSK_KE_SUPPORT ENABLED 77 | #else 78 | #define TLS_PSK_KE_SUPPORT DISABLED 79 | #endif 80 | #undef TLS_PSK_SUPPORT 81 | #endif 82 | 83 | #ifdef TLS_RSA_PSK_SUPPORT 84 | #define TLS_RSA_PSK_KE_SUPPORT TLS_RSA_PSK_SUPPORT 85 | #endif 86 | 87 | #ifdef TLS_DHE_PSK_SUPPORT 88 | #define TLS_DHE_PSK_KE_SUPPORT TLS_DHE_PSK_SUPPORT 89 | #endif 90 | 91 | #ifdef TLS_ECDHE_PSK_SUPPORT 92 | #define TLS_ECDHE_PSK_KE_SUPPORT TLS_ECDHE_PSK_SUPPORT 93 | #endif 94 | 95 | #ifdef TLS_CURVE25519_SUPPORT 96 | #define TLS_X25519_SUPPORT TLS_CURVE25519_SUPPORT 97 | #endif 98 | 99 | #ifdef TLS_CURVE448_SUPPORT 100 | #define TLS_X448_SUPPORT TLS_CURVE448_SUPPORT 101 | #endif 102 | 103 | #define TlsSession TlsSessionState 104 | #define tlsSaveSession tlsSaveSessionState 105 | #define tlsRestoreSession tlsRestoreSessionState 106 | 107 | #ifdef TLS_AES_SUPPORT 108 | #define TLS_AES_128_SUPPORT TLS_AES_SUPPORT 109 | #define TLS_AES_256_SUPPORT TLS_AES_SUPPORT 110 | #endif 111 | 112 | #ifdef TLS_CAMELLIA_SUPPORT 113 | #define TLS_CAMELLIA_128_SUPPORT TLS_CAMELLIA_SUPPORT 114 | #define TLS_CAMELLIA_256_SUPPORT TLS_CAMELLIA_SUPPORT 115 | #endif 116 | 117 | #ifdef TLS_ARIA_SUPPORT 118 | #define TLS_ARIA_128_SUPPORT TLS_ARIA_SUPPORT 119 | #define TLS_ARIA_256_SUPPORT TLS_ARIA_SUPPORT 120 | #endif 121 | 122 | #if defined(TLS_EDDSA_SIGN_SUPPORT) && defined(TLS_ED25519_SUPPORT) 123 | #if (TLS_EDDSA_SIGN_SUPPORT == ENABLED && TLS_ED25519_SUPPORT == ENABLED) 124 | #define TLS_ED25519_SIGN_SUPPORT ENABLED 125 | #else 126 | #define TLS_ED25519_SIGN SUPPORT DISABLED 127 | #endif 128 | #endif 129 | 130 | #if defined(TLS_EDDSA_SIGN_SUPPORT) && defined(TLS_ED448_SUPPORT) 131 | #if (TLS_EDDSA_SIGN_SUPPORT == ENABLED && TLS_ED448_SUPPORT == ENABLED) 132 | #define TLS_ED448_SIGN_SUPPORT ENABLED 133 | #else 134 | #define TLS_ED448_SIGN SUPPORT DISABLED 135 | #endif 136 | #endif 137 | 138 | #define TLS_GROUP_ECDH_X25519 TLS_GROUP_X25519 139 | #define TLS_GROUP_ECDH_X448 TLS_GROUP_X448 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /tls_misc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_misc.h 3 | * @brief TLS helper functions 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_MISC_H 32 | #define _TLS_MISC_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | void tlsChangeState(TlsContext *context, TlsState newState); 44 | void tlsProcessError(TlsContext *context, error_t errorCode); 45 | 46 | error_t tlsGenerateRandomValue(TlsContext *context, uint8_t *random); 47 | error_t tlsGenerateSessionId(TlsContext *context, size_t length); 48 | 49 | error_t tlsSelectVersion(TlsContext *context, uint16_t version); 50 | error_t tlsSelectCipherSuite(TlsContext *context, uint16_t identifier); 51 | 52 | error_t tlsSaveSessionId(const TlsContext *context, 53 | TlsSessionState *session); 54 | 55 | error_t tlsSaveSessionTicket(const TlsContext *context, 56 | TlsSessionState *session); 57 | 58 | error_t tlsRestoreSessionId(TlsContext *context, 59 | const TlsSessionState *session); 60 | 61 | error_t tlsRestoreSessionTicket(TlsContext *context, 62 | const TlsSessionState *session); 63 | 64 | error_t tlsInitEncryptionEngine(TlsContext *context, 65 | TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, 66 | TlsEncryptionLevel level, const uint8_t *secret); 67 | 68 | void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine); 69 | 70 | error_t tlsWriteMpi(const Mpi *a, uint8_t *data, size_t *length); 71 | error_t tlsReadMpi(Mpi *a, const uint8_t *data, size_t size, size_t *length); 72 | 73 | error_t tlsWriteEcPoint(const EcPublicKey *publicKey, uint8_t *data, 74 | size_t *length); 75 | 76 | error_t tlsReadEcPoint(EcPublicKey *publicKey, const EcCurve *curve, 77 | const uint8_t *data, size_t size, size_t *length); 78 | 79 | const char_t *tlsGetVersionName(uint16_t version); 80 | const HashAlgo *tlsGetHashAlgo(TlsHashAlgo hashAlgoId); 81 | const EcCurve *tlsGetCurve(TlsContext *context, uint16_t namedCurve); 82 | TlsNamedGroup tlsGetNamedCurve(const uint8_t *oid, size_t length); 83 | 84 | size_t tlsComputeEncryptionOverhead(TlsEncryptionEngine *encryptionEngine, 85 | size_t payloadLen); 86 | 87 | bool_t tlsCheckDnsHostname(const char_t *name, size_t length); 88 | 89 | //C++ guard 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /tls_quic.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_quic.c 3 | * @brief QUIC TLS related API 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @section Description 28 | * 29 | * The TLS protocol provides communications security over the Internet. The 30 | * protocol allows client/server applications to communicate in a way that 31 | * is designed to prevent eavesdropping, tampering, or message forgery 32 | * 33 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 34 | * @version 2.5.4 35 | **/ 36 | 37 | //Switch to the appropriate trace level 38 | #define TRACE_LEVEL TLS_TRACE_LEVEL 39 | 40 | //Dependencies 41 | #include "tls.h" 42 | #include "tls_quic.h" 43 | #include "debug.h" 44 | 45 | //Check TLS library configuration 46 | #if (TLS_SUPPORT == ENABLED && TLS_QUIC_SUPPORT == ENABLED) 47 | 48 | 49 | /** 50 | * @brief Register QUIC-specific callback functions 51 | * @param[in] context Pointer to the TLS context 52 | * @param[in] quicCallbacks QUIC callback functions 53 | * @param[in] handle An opaque pointer passed to the callback functions 54 | * @return Error code 55 | **/ 56 | 57 | error_t tlsRegisterQuicCallbacks(TlsContext *context, 58 | const TlsQuicCallbacks *quicCallbacks, void *handle) 59 | { 60 | //Invalid TLS context? 61 | if(context == NULL) 62 | return ERROR_INVALID_PARAMETER; 63 | 64 | //Save QUIC-specific callback functions 65 | context->quicCallbacks = *quicCallbacks; 66 | //This opaque pointer will be directly passed to the callback functions 67 | context->quicHandle = handle; 68 | 69 | //Successful processing 70 | return NO_ERROR; 71 | } 72 | 73 | 74 | /** 75 | * @brief Set QUIC-specific handle 76 | * @param[in] context Pointer to the TLS context 77 | * @param[in] handle An opaque pointer passed to the callback functions 78 | * @return Error code 79 | **/ 80 | 81 | error_t tlsSetQuicHandle(TlsContext *context, void *handle) 82 | { 83 | //Invalid TLS context? 84 | if(context == NULL) 85 | return ERROR_INVALID_PARAMETER; 86 | 87 | //This opaque pointer will be directly passed to the callback functions 88 | context->quicHandle = handle; 89 | 90 | //Successful processing 91 | return NO_ERROR; 92 | } 93 | 94 | 95 | /** 96 | * @brief Set local QUIC transport parameters 97 | * @param[in] context Pointer to the TLS context 98 | * @param[in] params Pointer to the QUIC transport parameters 99 | * @param[in] length Length of the QUIC transport parameters, in bytes 100 | * @return Error code 101 | **/ 102 | 103 | error_t tlsSetLocalQuicTransportParams(TlsContext *context, 104 | const uint8_t *params, size_t length) 105 | { 106 | //Check parameters 107 | if(context == NULL || params == NULL) 108 | return ERROR_INVALID_PARAMETER; 109 | 110 | //Check whether the QUIC transport parameters have already been configured 111 | if(context->localQuicTransportParams != NULL) 112 | { 113 | //Release memory 114 | tlsFreeMem(context->localQuicTransportParams); 115 | context->localQuicTransportParams = NULL; 116 | context->localQuicTransportParamsLen = 0; 117 | } 118 | 119 | //Valid QUIC transport parameters? 120 | if(length > 0) 121 | { 122 | //Allocate a memory block to hold the QUIC transport parameters 123 | context->localQuicTransportParams = tlsAllocMem(length); 124 | //Failed to allocate memory? 125 | if(context->localQuicTransportParams == NULL) 126 | return ERROR_OUT_OF_MEMORY; 127 | 128 | //Save the QUIC transport parameters 129 | osMemcpy(context->localQuicTransportParams, params, length); 130 | context->localQuicTransportParamsLen = length; 131 | } 132 | 133 | //Successful processing 134 | return NO_ERROR; 135 | } 136 | 137 | 138 | /** 139 | * @brief Get remote QUIC transport parameters 140 | * @param[in] context Pointer to the TLS context 141 | * @param[out] params Pointer to the QUIC transport parameters 142 | * @param[out] length Length of the QUIC transport parameters, in bytes 143 | * @return Error code 144 | **/ 145 | 146 | error_t tlsGetRemoteQuicTransportParams(TlsContext *context, 147 | const uint8_t **params, size_t *length) 148 | { 149 | //Check parameters 150 | if(context == NULL || params == NULL || length == NULL) 151 | return ERROR_INVALID_PARAMETER; 152 | 153 | //Return the QUIC transport parameters 154 | *params = context->remoteQuicTransportParams; 155 | *length = context->remoteQuicTransportParamsLen; 156 | 157 | //Successful processing 158 | return NO_ERROR; 159 | } 160 | 161 | 162 | /** 163 | * @brief Process incoming handshake data 164 | * @param[in] context Pointer to the TLS context 165 | * @param[in] level Encryption level 166 | * @param[in] data Pointer to the handshake data 167 | * @param[in] length Length of the handshake data, in bytes 168 | * @return Error code 169 | **/ 170 | 171 | error_t tlsProcessQuicHandshakeMessage(TlsContext *context, 172 | TlsEncryptionLevel level, const uint8_t *data, size_t length) 173 | { 174 | error_t error; 175 | 176 | //Initialize status code 177 | error = NO_ERROR; 178 | 179 | //Empty receive buffer? 180 | if(context->rxBufferLen == 0) 181 | { 182 | //Rewind to the beginning of the buffer 183 | context->rxBufferPos = 0; 184 | } 185 | 186 | //Check current TLS receiving encryption level 187 | if(level == context->decryptionEngine.level) 188 | { 189 | //Check the length of the handshake data 190 | if((context->rxBufferLen + length) <= context->rxBufferSize) 191 | { 192 | //QUIC CRYPTO frames only carry TLS handshake messages (refer to 193 | //RFC 9001, section 4.1.3) 194 | context->rxBufferType = TLS_TYPE_HANDSHAKE; 195 | 196 | //The content of CRYPTO frames might either be processed incrementally by 197 | //TLS or buffered until complete messages or flights are available. TLS 198 | //is responsible for buffering handshake bytes that have arrived in order 199 | osMemcpy(context->rxBuffer + context->rxBufferLen, data, length); 200 | 201 | //Number of bytes available for reading 202 | context->rxBufferLen += length; 203 | } 204 | else 205 | { 206 | //Report an error 207 | error = ERROR_BUFFER_OVERFLOW; 208 | } 209 | } 210 | else 211 | { 212 | //Report an error 213 | error = ERROR_INVALID_LEVEL; 214 | } 215 | 216 | //Return status code 217 | return error; 218 | } 219 | 220 | #endif 221 | -------------------------------------------------------------------------------- /tls_quic.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_quic.h 3 | * @brief QUIC TLS related API 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @section Description 28 | * 29 | * The TLS protocol provides communications security over the Internet. The 30 | * protocol allows client/server applications to communicate in a way that 31 | * is designed to prevent eavesdropping, tampering, or message forgery 32 | * 33 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 34 | * @version 2.5.4 35 | **/ 36 | 37 | #ifndef _TLS_QUIC_H 38 | #define _TLS_QUIC_H 39 | 40 | //Dependencies 41 | #include "tls.h" 42 | 43 | //C++ guard 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | //QUIC TLS related functions 49 | error_t tlsRegisterQuicCallbacks(TlsContext *context, 50 | const TlsQuicCallbacks *quicCallbacks, void *handle); 51 | 52 | error_t tlsSetQuicHandle(TlsContext *context, void *handle); 53 | 54 | error_t tlsSetLocalQuicTransportParams(TlsContext *context, 55 | const uint8_t *params, size_t length); 56 | 57 | error_t tlsGetRemoteQuicTransportParams(TlsContext *context, 58 | const uint8_t **params, size_t *length); 59 | 60 | error_t tlsProcessQuicHandshakeMessage(TlsContext *context, 61 | TlsEncryptionLevel level, const uint8_t *data, size_t length); 62 | 63 | //C++ guard 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /tls_quic_misc.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_quic_misc.c 3 | * @brief QUIC helper functions 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @section Description 28 | * 29 | * The TLS protocol provides communications security over the Internet. The 30 | * protocol allows client/server applications to communicate in a way that 31 | * is designed to prevent eavesdropping, tampering, or message forgery 32 | * 33 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 34 | * @version 2.5.4 35 | **/ 36 | 37 | //Switch to the appropriate trace level 38 | #define TRACE_LEVEL TLS_TRACE_LEVEL 39 | 40 | //Dependencies 41 | #include "tls.h" 42 | #include "tls_quic_misc.h" 43 | #include "debug.h" 44 | 45 | //Check TLS library configuration 46 | #if (TLS_SUPPORT == ENABLED && TLS_QUIC_SUPPORT == ENABLED) 47 | 48 | 49 | /** 50 | * @brief Format QuicTransportParameters extension 51 | * @param[in] context Pointer to the TLS context 52 | * @param[in] p Output stream where to write the QuicTransportParameters extension 53 | * @param[out] written Total number of bytes that have been written 54 | * @return Error code 55 | **/ 56 | 57 | error_t tlsFormatQuicTransportParamsExtension(TlsContext *context, 58 | uint8_t *p, size_t *written) 59 | { 60 | size_t n; 61 | TlsExtension *extension; 62 | 63 | //Initialize length field 64 | n = 0; 65 | 66 | //The QuicTransportParameters extension is carried in the ClientHello and the 67 | //EncryptedExtensions messages during the handshake. Endpoints must send the 68 | //QuicTransportParameters extension (refer to RFC 9001, section 8.2) 69 | if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_QUIC) 70 | { 71 | //Add the QuicTransportParameters extension 72 | extension = (TlsExtension *) p; 73 | //Type of the extension 74 | extension->type = HTONS(TLS_EXT_QUIC_TRANSPORT_PARAMETERS); 75 | 76 | //Get the length of the local QUIC transport parameters 77 | n = context->localQuicTransportParamsLen; 78 | 79 | //The extension_data field of the QuicTransportParameters extension 80 | //contains a value that is defined by the version of QUIC that is in use 81 | osMemcpy(extension->value, context->localQuicTransportParams, n); 82 | 83 | //Fix the length of the extension 84 | extension->length = htons(n); 85 | 86 | //Compute the length, in bytes, of the Cookie extension 87 | n += sizeof(TlsExtension); 88 | } 89 | 90 | //Total number of bytes that have been written 91 | *written = n; 92 | 93 | //Successful processing 94 | return NO_ERROR; 95 | } 96 | 97 | 98 | /** 99 | * @brief Parse QuicTransportParameters extension 100 | * @param[in] context Pointer to the TLS context 101 | * @param[in] selectedIdentity Pointer to the QuicTransportParameters extension 102 | * @return Error code 103 | **/ 104 | 105 | error_t tlsParseQuicTransportParamsExtension(TlsContext *context, 106 | const TlsExtension *quicTransportParams) 107 | { 108 | size_t length; 109 | 110 | //QUIC transport? 111 | if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_QUIC) 112 | { 113 | //Endpoints must send the QuicTransportParameters extension (refer to 114 | //RFC 9001, section 8.2) 115 | if(quicTransportParams == NULL) 116 | return ERROR_MISSING_EXTENSION; 117 | 118 | //Check whether the QUIC transport parameters have already been received 119 | if(context->remoteQuicTransportParams != NULL) 120 | { 121 | //Release memory 122 | tlsFreeMem(context->remoteQuicTransportParams); 123 | context->remoteQuicTransportParams = NULL; 124 | context->remoteQuicTransportParamsLen = 0; 125 | } 126 | 127 | //Retrieve the length of the extension_data field 128 | length = ntohs(quicTransportParams->length); 129 | 130 | //Allocate a memory block to hold the QUIC transport parameters 131 | context->remoteQuicTransportParams = tlsAllocMem(length); 132 | //Failed to allocate memory? 133 | if(context->remoteQuicTransportParams == NULL) 134 | return ERROR_OUT_OF_MEMORY; 135 | 136 | //The extension_data field of the QuicTransportParameters extension 137 | //contains a value that is defined by the version of QUIC that is in use 138 | osMemcpy(context->remoteQuicTransportParams, quicTransportParams->value, length); 139 | context->remoteQuicTransportParamsLen = length; 140 | } 141 | else 142 | { 143 | //A fatal unsupported_extension alert must be sent by an implementation 144 | //that supports this extension if the extension is received when the 145 | //transport is not QUIC (refer to RFC 9001, section 8.2) 146 | if(quicTransportParams != NULL) 147 | return ERROR_UNSUPPORTED_EXTENSION; 148 | } 149 | 150 | //Successful processing 151 | return NO_ERROR; 152 | } 153 | 154 | 155 | /** 156 | * @brief Set encryption keys 157 | * @param[in] context Pointer to the TLS context 158 | * @param[in] level Encryption level 159 | * @param[in] clientKey Client's secret key 160 | * @param[in] serverKey Server's secret key 161 | * @param[in] keyLen Length of the secret keys, in bytes 162 | * @return Error code 163 | **/ 164 | 165 | error_t tlsSetQuicEncryptionKeys(TlsContext *context, TlsEncryptionLevel level, 166 | const uint8_t *clientKey, const uint8_t *serverKey, size_t keyLen) 167 | { 168 | error_t error; 169 | const uint8_t *txKey; 170 | const uint8_t *rxKey; 171 | 172 | //Check whether TLS operates as a client or a server 173 | if(context->entity == TLS_CONNECTION_END_CLIENT) 174 | { 175 | txKey = clientKey; 176 | rxKey = serverKey; 177 | } 178 | else 179 | { 180 | txKey = serverKey; 181 | rxKey = clientKey; 182 | } 183 | 184 | //Any registered callback? 185 | if(context->quicCallbacks.setEncryptionKeys != NULL) 186 | { 187 | //As keys at a given encryption level become available to TLS, TLS 188 | //indicates to QUIC that reading or writing keys at that encryption level 189 | //are available (refer to RFC 9001, section 4.1.4) 190 | error = context->quicCallbacks.setEncryptionKeys(context, level, txKey, 191 | rxKey, keyLen, context->quicHandle); 192 | } 193 | else 194 | { 195 | //Report an error 196 | error = ERROR_FAILURE; 197 | } 198 | 199 | //Return status code 200 | return error; 201 | } 202 | 203 | 204 | /** 205 | * @brief Send handshake message 206 | * @param[in] context Pointer to the TLS context 207 | * @param[in] message Pointer to the handshake message 208 | * @param[in] length Length of the handshake message, in bytes 209 | * @return Error code 210 | **/ 211 | 212 | error_t tlsSendQuicHandshakeMessage(TlsContext *context, const uint8_t *message, 213 | size_t length) 214 | { 215 | error_t error; 216 | TlsEncryptionLevel level; 217 | 218 | //At any time, the TLS stack at an endpoint will have a current sending 219 | //encryption level. TLS encryption level determines the QUIC packet type 220 | //and keys that are used for protecting data (refer to RFC 9001, 221 | //section 4.1.3) 222 | level = context->encryptionEngine.level; 223 | 224 | //Any registered callback? 225 | if(context->quicCallbacks.sendHandshakeMessage != NULL) 226 | { 227 | //When TLS provides handshake bytes to be sent, they are appended to the 228 | //handshake bytes for the current encryption level 229 | error = context->quicCallbacks.sendHandshakeMessage(context, level, message, 230 | length, context->quicHandle); 231 | } 232 | else 233 | { 234 | //Report an error 235 | error = ERROR_FAILURE; 236 | } 237 | 238 | //Return status code 239 | return error; 240 | } 241 | 242 | 243 | /** 244 | * @brief Send alert message 245 | * @param[in] context Pointer to the TLS context 246 | * @param[in] message Pointer to the alert message 247 | * @param[in] length Length of the alert message, in bytes 248 | * @return Error code 249 | **/ 250 | 251 | error_t tlsSendQuicAlertMessage(TlsContext *context, const TlsAlert *message, 252 | size_t length) 253 | { 254 | error_t error; 255 | 256 | //Initialize status code 257 | error = NO_ERROR; 258 | 259 | //QUIC is only able to convey an alert level of "fatal" (refer to RFC 9001, 260 | //section 4.8) 261 | if(length == sizeof(TlsAlert) && message->level == TLS_ALERT_LEVEL_FATAL) 262 | { 263 | //Any registered callback? 264 | if(context->quicCallbacks.sendAlertMessage != NULL) 265 | { 266 | //A TLS alert is converted into a QUIC connection error 267 | error = context->quicCallbacks.sendAlertMessage(context, 268 | message->description, context->quicHandle); 269 | } 270 | else 271 | { 272 | //Report an error 273 | error = ERROR_FAILURE; 274 | } 275 | } 276 | 277 | //Return status code 278 | return error; 279 | } 280 | 281 | #endif 282 | -------------------------------------------------------------------------------- /tls_quic_misc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_quic_misc.h 3 | * @brief QUIC helper functions 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @section Description 28 | * 29 | * The TLS protocol provides communications security over the Internet. The 30 | * protocol allows client/server applications to communicate in a way that 31 | * is designed to prevent eavesdropping, tampering, or message forgery 32 | * 33 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 34 | * @version 2.5.4 35 | **/ 36 | 37 | #ifndef _TLS_QUIC_MISC_H 38 | #define _TLS_QUIC_MISC_H 39 | 40 | //Dependencies 41 | #include "tls.h" 42 | 43 | //C++ guard 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | //QUIC TLS related functions 49 | error_t tlsFormatQuicTransportParamsExtension(TlsContext *context, 50 | uint8_t *p, size_t *written); 51 | 52 | error_t tlsParseQuicTransportParamsExtension(TlsContext *context, 53 | const TlsExtension *quicTransportParams); 54 | 55 | error_t tlsSetQuicEncryptionKeys(TlsContext *context, TlsEncryptionLevel level, 56 | const uint8_t *clientKey, const uint8_t *serverKey, size_t keyLen); 57 | 58 | error_t tlsSendQuicHandshakeMessage(TlsContext *context, const uint8_t *message, 59 | size_t length); 60 | 61 | error_t tlsSendQuicAlertMessage(TlsContext *context, const TlsAlert *message, 62 | size_t length); 63 | 64 | //C++ guard 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /tls_record.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_record.h 3 | * @brief TLS record protocol 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_RECORD_H 32 | #define _TLS_RECORD_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsWriteProtocolData(TlsContext *context, 44 | const uint8_t *data, size_t length, TlsContentType contentType); 45 | 46 | error_t tlsReadProtocolData(TlsContext *context, 47 | uint8_t **data, size_t *length, TlsContentType *contentType); 48 | 49 | error_t tlsWriteRecord(TlsContext *context, const uint8_t *data, 50 | size_t length, TlsContentType contentType); 51 | 52 | error_t tlsReadRecord(TlsContext *context, uint8_t *data, 53 | size_t size, size_t *length, TlsContentType *contentType); 54 | 55 | error_t tlsProcessRecord(TlsContext *context, TlsRecord *record); 56 | 57 | void tlsSetRecordType(TlsContext *context, void *record, uint8_t type); 58 | uint8_t tlsGetRecordType(TlsContext *context, void *record); 59 | void tlsSetRecordLength(TlsContext *context, void *record, size_t length); 60 | size_t tlsGetRecordLength(TlsContext *context, void *record); 61 | uint8_t *tlsGetRecordData(TlsContext *context, void *record); 62 | 63 | void tlsFormatAad(TlsContext *context, TlsEncryptionEngine *encryptionEngine, 64 | const void *record, uint8_t *aad, size_t *aadLen); 65 | 66 | void tlsFormatNonce(TlsContext *context, TlsEncryptionEngine *encryptionEngine, 67 | const void *record, const uint8_t *recordIv, uint8_t *nonce, size_t *nonceLen); 68 | 69 | void tlsIncSequenceNumber(TlsSequenceNumber *seqNum); 70 | 71 | //C++ guard 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /tls_record_decryption.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_record_decryption.h 3 | * @brief TLS record decryption 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_RECORD_DECRYPTION_H 32 | #define _TLS_RECORD_DECRYPTION_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsDecryptRecord(TlsContext *context, 44 | TlsEncryptionEngine *decryptionEngine, void *record); 45 | 46 | error_t tlsDecryptAeadRecord(TlsContext *context, 47 | TlsEncryptionEngine *decryptionEngine, void *record); 48 | 49 | error_t tlsDecryptCbcRecord(TlsContext *context, 50 | TlsEncryptionEngine *decryptionEngine, void *record); 51 | 52 | error_t tlsDecryptStreamRecord(TlsContext *context, 53 | TlsEncryptionEngine *decryptionEngine, void *record); 54 | 55 | error_t tlsVerifyMessageAuthCode(TlsContext *context, 56 | TlsEncryptionEngine *decryptionEngine, void *record); 57 | 58 | uint32_t tlsVerifyPadding(const uint8_t *data, size_t dataLen, 59 | size_t *paddingLen); 60 | 61 | uint32_t tlsVerifyMac(TlsContext *context, 62 | TlsEncryptionEngine *decryptionEngine, const void *record, 63 | const uint8_t *data, size_t dataLen, size_t maxDataLen, const uint8_t *mac); 64 | 65 | uint32_t tlsExtractMac(TlsEncryptionEngine *decryptionEngine, 66 | const uint8_t *data, size_t dataLen, size_t maxDataLen, uint8_t *mac); 67 | 68 | //C++ guard 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /tls_record_encryption.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_record_encryption.h 3 | * @brief TLS record encryption 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_RECORD_ENCRYPTION_H 32 | #define _TLS_RECORD_ENCRYPTION_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsEncryptRecord(TlsContext *context, 44 | TlsEncryptionEngine *encryptionEngine, void *record); 45 | 46 | error_t tlsEncryptAeadRecord(TlsContext *context, 47 | TlsEncryptionEngine *encryptionEngine, void *record); 48 | 49 | error_t tlsEncryptCbcRecord(TlsContext *context, 50 | TlsEncryptionEngine *encryptionEngine, void *record); 51 | 52 | error_t tlsEncryptStreamRecord(TlsContext *context, 53 | TlsEncryptionEngine *encryptionEngine, void *record); 54 | 55 | error_t tlsAppendMessageAuthCode(TlsContext *context, 56 | TlsEncryptionEngine *decryptionEngine, void *record); 57 | 58 | error_t tlsComputeMac(TlsContext *context, TlsEncryptionEngine *encryptionEngine, 59 | const void *record, const uint8_t *data, size_t dataLen, uint8_t *mac); 60 | 61 | //C++ guard 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /tls_server.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_server.h 3 | * @brief Handshake message processing (TLS server) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_SERVER_H 32 | #define _TLS_SERVER_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS server specific functions 43 | error_t tlsSendServerHello(TlsContext *context); 44 | error_t tlsSendServerKeyExchange(TlsContext *context); 45 | error_t tlsSendCertificateRequest(TlsContext *context); 46 | error_t tlsSendServerHelloDone(TlsContext *context); 47 | error_t tlsSendNewSessionTicket(TlsContext *context); 48 | 49 | error_t tlsFormatServerHello(TlsContext *context, 50 | TlsServerHello *message, size_t *length); 51 | 52 | error_t tlsFormatServerKeyExchange(TlsContext *context, 53 | TlsServerKeyExchange *message, size_t *length); 54 | 55 | error_t tlsFormatCertificateRequest(TlsContext *context, 56 | TlsCertificateRequest *message, size_t *length); 57 | 58 | error_t tlsFormatServerHelloDone(TlsContext *context, 59 | TlsServerHelloDone *message, size_t *length); 60 | 61 | error_t tlsFormatNewSessionTicket(TlsContext *context, 62 | TlsNewSessionTicket *message, size_t *length); 63 | 64 | error_t tlsParseClientHello(TlsContext *context, 65 | const TlsClientHello *message, size_t length); 66 | 67 | error_t tlsParseClientKeyExchange(TlsContext *context, 68 | const TlsClientKeyExchange *message, size_t length); 69 | 70 | //C++ guard 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /tls_server_extensions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_server_extensions.h 3 | * @brief Formatting and parsing of extensions (TLS server) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_SERVER_EXTENSIONS_H 32 | #define _TLS_SERVER_EXTENSIONS_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS server specific functions 43 | error_t tlsFormatServerSniExtension(TlsContext *context, 44 | uint8_t *p, size_t *written); 45 | 46 | error_t tlsFormatServerMaxFragLenExtension(TlsContext *context, 47 | uint8_t *p, size_t *written); 48 | 49 | error_t tlsFormatServerRecordSizeLimitExtension(TlsContext *context, 50 | uint8_t *p, size_t *written); 51 | 52 | error_t tlsFormatServerEcPointFormatsExtension(TlsContext *context, 53 | uint8_t *p, size_t *written); 54 | 55 | error_t tlsFormatServerAlpnExtension(TlsContext *context, 56 | uint8_t *p, size_t *written); 57 | 58 | error_t tlsFormatClientCertTypeExtension(TlsContext *context, 59 | uint8_t *p, size_t *written); 60 | 61 | error_t tlsFormatServerCertTypeExtension(TlsContext *context, 62 | uint8_t *p, size_t *written); 63 | 64 | error_t tlsFormatServerEtmExtension(TlsContext *context, 65 | uint8_t *p, size_t *written); 66 | 67 | error_t tlsFormatServerEmsExtension(TlsContext *context, 68 | uint8_t *p, size_t *written); 69 | 70 | error_t tlsFormatServerSessionTicketExtension(TlsContext *context, 71 | uint8_t *p, size_t *written); 72 | 73 | error_t tlsFormatServerRenegoInfoExtension(TlsContext *context, 74 | uint8_t *p, size_t *written); 75 | 76 | error_t tlsParseClientSupportedVersionsExtension(TlsContext *context, 77 | const TlsSupportedVersionList *supportedVersionList); 78 | 79 | error_t tlsParseClientSniExtension(TlsContext *context, 80 | const TlsServerNameList *serverNameList); 81 | 82 | error_t tlsParseClientMaxFragLenExtension(TlsContext *context, 83 | const TlsExtension *maxFragLen); 84 | 85 | error_t tlsParseClientRecordSizeLimitExtension(TlsContext *context, 86 | const TlsExtension *recordSizeLimit); 87 | 88 | error_t tlsParseClientEcPointFormatsExtension(TlsContext *context, 89 | const TlsEcPointFormatList *ecPointFormatList); 90 | 91 | error_t tlsParseClientAlpnExtension(TlsContext *context, 92 | const TlsProtocolNameList *protocolNameList); 93 | 94 | error_t tlsParseClientCertTypeListExtension(TlsContext *context, 95 | const TlsCertTypeList *clientCertTypeList); 96 | 97 | error_t tlsParseServerCertTypeListExtension(TlsContext *context, 98 | const TlsCertTypeList *serverCertTypeList); 99 | 100 | error_t tlsParseClientEtmExtension(TlsContext *context, 101 | const TlsExtension *encryptThenMac); 102 | 103 | error_t tlsParseClientEmsExtension(TlsContext *context, 104 | const TlsExtension *extendedMasterSecret); 105 | 106 | error_t tlsParseClientSessionTicketExtension(TlsContext *context, 107 | const TlsExtension *sessionTicket); 108 | 109 | error_t tlsParseClientRenegoInfoExtension(TlsContext *context, 110 | const TlsHelloExtensions *extensions); 111 | 112 | //C++ guard 113 | #ifdef __cplusplus 114 | } 115 | #endif 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /tls_server_fsm.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_server_fsm.c 3 | * @brief TLS state machine (TLS server) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | //Switch to the appropriate trace level 32 | #define TRACE_LEVEL TLS_TRACE_LEVEL 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | #include "tls_handshake.h" 37 | #include "tls_server.h" 38 | #include "tls_server_fsm.h" 39 | #include "tls_common.h" 40 | #include "tls_cache.h" 41 | #include "tls_record.h" 42 | #include "tls_misc.h" 43 | #include "tls13_server.h" 44 | #include "tls13_common.h" 45 | #include "tls13_key_material.h" 46 | #include "debug.h" 47 | 48 | //Check TLS library configuration 49 | #if (TLS_SUPPORT == ENABLED && TLS_SERVER_SUPPORT == ENABLED) 50 | 51 | 52 | /** 53 | * @brief TLS server handshake 54 | * @param[in] context Pointer to the TLS context 55 | * @return Error code 56 | **/ 57 | 58 | error_t tlsPerformServerHandshake(TlsContext *context) 59 | { 60 | error_t error; 61 | 62 | //Initialize status code 63 | error = NO_ERROR; 64 | 65 | //Wait for the handshake to complete 66 | while(!error) 67 | { 68 | //TLS protocol? 69 | if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM) 70 | { 71 | //Check current state 72 | if(context->state != TLS_STATE_INIT && 73 | context->state != TLS_STATE_CLOSED) 74 | { 75 | //Flush send buffer 76 | error = tlsWriteProtocolData(context, NULL, 0, TLS_TYPE_NONE); 77 | //Any error to report? 78 | if(error) 79 | break; 80 | } 81 | } 82 | 83 | //Check whether the handshake is complete 84 | if(context->state == TLS_STATE_APPLICATION_DATA) 85 | { 86 | //At this is point, the handshake is complete and the server starts 87 | //to exchange application-layer data 88 | break; 89 | } 90 | 91 | //The TLS handshake is implemented as a state machine representing the 92 | //current location in the protocol 93 | switch(context->state) 94 | { 95 | //Initial state? 96 | case TLS_STATE_INIT: 97 | //TLS handshake initialization 98 | error = tlsInitHandshake(context); 99 | break; 100 | 101 | //Sending ServerHello message? 102 | case TLS_STATE_SERVER_HELLO: 103 | case TLS_STATE_SERVER_HELLO_2: 104 | //The server will send this message in response to a ClientHello 105 | //message when it was able to find an acceptable set of algorithms 106 | error = tlsSendServerHello(context); 107 | break; 108 | 109 | //Sending Certificate message? 110 | case TLS_STATE_SERVER_CERTIFICATE: 111 | //The server must send a Certificate message whenever the agreed- 112 | //upon key exchange method uses certificates for authentication. This 113 | //message will always immediately follow the ServerHello message 114 | error = tlsSendCertificate(context); 115 | break; 116 | 117 | //Sending Certificate message? 118 | case TLS_STATE_CERTIFICATE_REQUEST: 119 | //A non-anonymous server can optionally request a certificate from the 120 | //client, if appropriate for the selected cipher suite. This message, 121 | //if sent, will immediately follow the ServerKeyExchange message 122 | error = tlsSendCertificateRequest(context); 123 | break; 124 | 125 | //Sending NewSessionTicket message? 126 | case TLS_STATE_NEW_SESSION_TICKET: 127 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3) 128 | //TLS 1.3 currently selected? 129 | if(context->version == TLS_VERSION_1_3) 130 | { 131 | //At any time after the server has received the client Finished 132 | //message, it may send a NewSessionTicket message 133 | error = tls13SendNewSessionTicket(context); 134 | } 135 | else 136 | #endif 137 | { 138 | //The NewSessionTicket message is sent by the server during the TLS 139 | //handshake before the ChangeCipherSpec message 140 | error = tlsSendNewSessionTicket(context); 141 | } 142 | 143 | break; 144 | 145 | //Sending ChangeCipherSpec message? 146 | case TLS_STATE_SERVER_CHANGE_CIPHER_SPEC: 147 | case TLS_STATE_SERVER_CHANGE_CIPHER_SPEC_2: 148 | //The ChangeCipherSpec message is sent by the server and to notify the 149 | //client that subsequent records will be protected under the newly 150 | //negotiated CipherSpec and keys 151 | error = tlsSendChangeCipherSpec(context); 152 | break; 153 | 154 | //Sending Finished message? 155 | case TLS_STATE_SERVER_FINISHED: 156 | //A Finished message is always sent immediately after a ChangeCipherSpec 157 | //message to verify that the key exchange and authentication processes 158 | //were successful 159 | error = tlsSendFinished(context); 160 | break; 161 | 162 | #if (DTLS_SUPPORT == ENABLED) 163 | //Sending HelloVerifyRequest message? 164 | case TLS_STATE_HELLO_VERIFY_REQUEST: 165 | //When the client sends its ClientHello message to the server, the 166 | //server may respond with a HelloVerifyRequest message 167 | error = dtlsSendHelloVerifyRequest(context); 168 | break; 169 | #endif 170 | 171 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2) 172 | //Sending ServerKeyExchange message? 173 | case TLS_STATE_SERVER_KEY_EXCHANGE: 174 | //The ServerKeyExchange message is sent by the server only when the 175 | //server Certificate message (if sent) does not contain enough data 176 | //to allow the client to exchange a premaster secret 177 | error = tlsSendServerKeyExchange(context); 178 | break; 179 | 180 | //Sending ServerHelloDone message? 181 | case TLS_STATE_SERVER_HELLO_DONE: 182 | //The ServerHelloDone message is sent by the server to indicate the 183 | //end of the ServerHello and associated messages 184 | error = tlsSendServerHelloDone(context); 185 | break; 186 | #endif 187 | 188 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3) 189 | //Sending HelloRetryRequest message? 190 | case TLS_STATE_HELLO_RETRY_REQUEST: 191 | //The server sends a HelloRetryRequest message if the ClientHello 192 | //message does not contain sufficient information to proceed with 193 | //the handshake 194 | error = tls13SendHelloRetryRequest(context); 195 | break; 196 | 197 | //Handshake traffic key generation? 198 | case TLS_STATE_HANDSHAKE_TRAFFIC_KEYS: 199 | //Compute handshake traffic keys 200 | error = tls13GenerateHandshakeTrafficKeys(context); 201 | break; 202 | 203 | //Sending EncryptedExtensions message? 204 | case TLS_STATE_ENCRYPTED_EXTENSIONS: 205 | //The server sends the EncryptedExtensions message immediately after 206 | //the ServerHello message. The EncryptedExtensions message contains 207 | //extensions that can be protected 208 | error = tls13SendEncryptedExtensions(context); 209 | break; 210 | 211 | //Sending CertificateVerify message? 212 | case TLS_STATE_SERVER_CERTIFICATE_VERIFY: 213 | //Servers must send this message when authenticating via a 214 | //certificate. When sent, this message must appear immediately 215 | //after the Certificate message 216 | error = tlsSendCertificateVerify(context); 217 | break; 218 | 219 | //Server application traffic key generation? 220 | case TLS_STATE_SERVER_APP_TRAFFIC_KEYS: 221 | //Compute server application traffic keys 222 | error = tls13GenerateServerAppTrafficKeys(context); 223 | break; 224 | 225 | //Client application traffic key generation? 226 | case TLS_STATE_CLIENT_APP_TRAFFIC_KEYS: 227 | //Compute client application traffic keys 228 | error = tls13GenerateClientAppTrafficKeys(context); 229 | break; 230 | 231 | //Sending KeyUpdate message? 232 | case TLS_STATE_KEY_UPDATE: 233 | //The KeyUpdate handshake message is used to indicate that the sender 234 | //is updating its sending cryptographic keys 235 | error = tls13SendKeyUpdate(context); 236 | break; 237 | #endif 238 | 239 | //Waiting for a message from the client? 240 | case TLS_STATE_CLIENT_HELLO: 241 | case TLS_STATE_CLIENT_HELLO_2: 242 | case TLS_STATE_CLIENT_CERTIFICATE: 243 | case TLS_STATE_CLIENT_KEY_EXCHANGE: 244 | case TLS_STATE_CLIENT_CERTIFICATE_VERIFY: 245 | case TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC: 246 | case TLS_STATE_CLIENT_FINISHED: 247 | //Receive client's message 248 | error = tlsReceiveHandshakeMessage(context); 249 | break; 250 | 251 | //Sending Alert message? 252 | case TLS_STATE_CLOSING: 253 | //Mark the TLS connection as closed 254 | tlsChangeState(context, TLS_STATE_CLOSED); 255 | break; 256 | 257 | //TLS connection closed? 258 | case TLS_STATE_CLOSED: 259 | //Debug message 260 | TRACE_WARNING("TLS handshake failure!\r\n"); 261 | //Report an error 262 | error = ERROR_HANDSHAKE_FAILED; 263 | break; 264 | 265 | //Invalid state? 266 | default: 267 | //Report an error 268 | error = ERROR_UNEXPECTED_STATE; 269 | break; 270 | } 271 | 272 | #if (TLS_RTOS_SUPPORT == DISABLED) 273 | //Force TLS to operate in non-blocking mode 274 | if(error == NO_ERROR && context->state < TLS_STATE_APPLICATION_DATA) 275 | { 276 | error = ERROR_WOULD_BLOCK; 277 | break; 278 | } 279 | #endif 280 | } 281 | 282 | //Successful TLS handshake? 283 | if(!error) 284 | { 285 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2) 286 | //Version of TLS prior to TLS 1.3? 287 | if(context->version <= TLS_VERSION_1_2) 288 | { 289 | #if (TLS_TICKET_SUPPORT == ENABLED) 290 | //Any ticket presented by the client? 291 | if(context->sessionTicketExtReceived) 292 | { 293 | //If a ticket is presented by the client, the server must not 294 | //attempt to use the Session ID in the ClientHello for stateful 295 | //session resumption 296 | } 297 | else 298 | #endif 299 | { 300 | //Save current session in the session cache for further reuse 301 | tlsSaveToCache(context); 302 | } 303 | } 304 | #endif 305 | } 306 | else 307 | { 308 | //Send an alert message to the client, if applicable 309 | tlsProcessError(context, error); 310 | } 311 | 312 | //Return status code 313 | return error; 314 | } 315 | 316 | 317 | /** 318 | * @brief Parse client's handshake message 319 | * @param[in] context Pointer to the TLS context 320 | * @param[in] msgType Handshake message type 321 | * @param[in] message Pointer to the handshake message to parse 322 | * @param[in] length Length of the handshake messaged 323 | * @return Error code 324 | **/ 325 | 326 | error_t tlsParseClientHandshakeMessage(TlsContext *context, uint8_t msgType, 327 | const void *message, size_t length) 328 | { 329 | error_t error; 330 | 331 | //Check handshake message type 332 | switch(msgType) 333 | { 334 | //ClientHello message received? 335 | case TLS_TYPE_CLIENT_HELLO: 336 | //When a client first connects to a server, it is required to send the 337 | //ClientHello as its first message 338 | error = tlsParseClientHello(context, message, length); 339 | break; 340 | 341 | //Certificate message received? 342 | case TLS_TYPE_CERTIFICATE: 343 | //This is the first message the client can send after receiving a 344 | //ServerHelloDone message. This message is only sent if the server 345 | //requests a certificate 346 | error = tlsParseCertificate(context, message, length); 347 | break; 348 | 349 | //CertificateVerify message received? 350 | case TLS_TYPE_CERTIFICATE_VERIFY: 351 | //This message is used to provide explicit verification of a client 352 | //certificate. This message is only sent following a client certificate 353 | //that has signing capability. When sent, it must immediately follow 354 | //the clientKeyExchange message 355 | error = tlsParseCertificateVerify(context, message, length); 356 | break; 357 | 358 | //Finished message received? 359 | case TLS_TYPE_FINISHED: 360 | //A Finished message is always sent immediately after a ChangeCipherSpec 361 | //message to verify that the key exchange and authentication processes 362 | //were successful 363 | error = tlsParseFinished(context, message, length); 364 | break; 365 | 366 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2) 367 | //ClientKeyExchange message received? 368 | case TLS_TYPE_CLIENT_KEY_EXCHANGE: 369 | //This message must immediately follow the client certificate message, if 370 | //it is sent. Otherwise, it must be the first message sent by the client 371 | //after it receives the ServerHelloDone message 372 | error = tlsParseClientKeyExchange(context, message, length); 373 | break; 374 | #endif 375 | 376 | #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3) 377 | //KeyUpdate message received? 378 | case TLS_TYPE_KEY_UPDATE: 379 | //The KeyUpdate handshake message is used to indicate that the client is 380 | //updating its sending cryptographic keys. This message can be sent by 381 | //the client after it has sent a Finished message 382 | error = tls13ParseKeyUpdate(context, message, length); 383 | break; 384 | #endif 385 | 386 | //Invalid handshake message received? 387 | default: 388 | //Report an error 389 | error = ERROR_UNEXPECTED_MESSAGE; 390 | break; 391 | } 392 | 393 | //Return status code 394 | return error; 395 | } 396 | 397 | #endif 398 | -------------------------------------------------------------------------------- /tls_server_fsm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_server_fsm.h 3 | * @brief TLS state machine (TLS server) 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_SERVER_FSM_H 32 | #define _TLS_SERVER_FSM_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsPerformServerHandshake(TlsContext *context); 44 | 45 | error_t tlsParseClientHandshakeMessage(TlsContext *context, uint8_t msgType, 46 | const void *message, size_t length); 47 | 48 | //C++ guard 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /tls_server_misc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_server_misc.h 3 | * @brief Helper functions for TLS server 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_SERVER_MISC_H 32 | #define _TLS_SERVER_MISC_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS server specific functions 43 | error_t tlsFormatPskIdentityHint(TlsContext *context, 44 | uint8_t *p, size_t *written); 45 | 46 | error_t tlsFormatServerKeyParams(TlsContext *context, 47 | uint8_t *p, size_t *written); 48 | 49 | error_t tlsGenerateServerKeySignature(TlsContext *context, 50 | TlsDigitalSignature *signature, const uint8_t *params, 51 | size_t paramsLen, size_t *written); 52 | 53 | error_t tls12GenerateServerKeySignature(TlsContext *context, 54 | Tls12DigitalSignature *signature, const uint8_t *params, 55 | size_t paramsLen, size_t *written); 56 | 57 | error_t tlsCheckSignalingCipherSuiteValues(TlsContext *context, 58 | const TlsCipherSuites *cipherSuites); 59 | 60 | error_t tlsResumeStatefulSession(TlsContext *context, const uint8_t *sessionId, 61 | size_t sessionIdLen, const TlsCipherSuites *cipherSuites, 62 | const TlsHelloExtensions *extensions); 63 | 64 | error_t tlsResumeStatelessSession(TlsContext *context, const uint8_t *sessionId, 65 | size_t sessionIdLen, const TlsCipherSuites *cipherSuites, 66 | const TlsHelloExtensions *extensions); 67 | 68 | error_t tlsNegotiateVersion(TlsContext *context, uint16_t clientVersion, 69 | const TlsSupportedVersionList *supportedVersionList); 70 | 71 | error_t tlsNegotiateCipherSuite(TlsContext *context, const HashAlgo *hashAlgo, 72 | const TlsCipherSuites *cipherSuites, TlsHelloExtensions *extensions); 73 | 74 | error_t tlsSelectGroup(TlsContext *context, 75 | const TlsSupportedGroupList *groupList); 76 | 77 | error_t tlsSelectEcdheGroup(TlsContext *context, 78 | const TlsSupportedGroupList *groupList); 79 | 80 | error_t tlsSelectCertificate(TlsContext *context, 81 | const TlsHelloExtensions *extensions); 82 | 83 | error_t tlsParseCompressMethods(TlsContext *context, 84 | const TlsCompressMethods *compressMethods); 85 | 86 | error_t tlsParsePskIdentity(TlsContext *context, 87 | const uint8_t *p, size_t length, size_t *consumed); 88 | 89 | error_t tlsParseClientKeyParams(TlsContext *context, 90 | const uint8_t *p, size_t length, size_t *consumed); 91 | 92 | //C++ guard 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /tls_sign_generate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_sign_generate.h 3 | * @brief RSA/DSA/ECDSA/EdDSA signature generation 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_SIGN_GENERATE_H 32 | #define _TLS_SIGN_GENERATE_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsGenerateSignature(TlsContext *context, uint8_t *p, 44 | size_t *length); 45 | 46 | error_t tls12GenerateSignature(TlsContext *context, uint8_t *p, 47 | size_t *length); 48 | 49 | error_t tlsGenerateRsaSignature(const RsaPrivateKey *key, 50 | const uint8_t *digest, uint8_t *signature, size_t *signatureLen); 51 | 52 | error_t tlsGenerateRsaPkcs1Signature(TlsContext *context, 53 | const HashAlgo *hashAlgo, const uint8_t *digest, uint8_t *signature, 54 | size_t *signatureLen); 55 | 56 | error_t tlsGenerateRsaPssSignature(TlsContext *context, 57 | const HashAlgo *hashAlgo, const uint8_t *digest, uint8_t *signature, 58 | size_t *signatureLen); 59 | 60 | error_t tlsGenerateDsaSignature(TlsContext *context, const uint8_t *digest, 61 | size_t digestLen, uint8_t *signature, size_t *signatureLen); 62 | 63 | error_t tlsGenerateEcdsaSignature(TlsContext *context, const uint8_t *digest, 64 | size_t digestLen, uint8_t *signature, size_t *signatureLen); 65 | 66 | error_t tlsGenerateEd25519Signature(TlsContext *context, 67 | const DataChunk *message, uint_t messageLen, uint8_t *signature, 68 | size_t *signatureLen); 69 | 70 | error_t tlsGenerateEd448Signature(TlsContext *context, 71 | const DataChunk *message, uint_t messageLen, uint8_t *signature, 72 | size_t *signatureLen); 73 | 74 | //C++ guard 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /tls_sign_misc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_sign_misc.h 3 | * @brief Helper functions for signature generation and verification 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2022-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneIPSEC Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_SIGN_MISC_H 32 | #define _TLS_SIGN_MISC_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //Extract signature algorithm from legacy signature scheme 38 | #define TLS_SIGN_ALGO(signScheme) ((TlsSignatureAlgo) LSB(signScheme)) 39 | 40 | //Extract hash algorithm from legacy signature scheme 41 | #define TLS_HASH_ALGO(signScheme) ((TlsHashAlgo) MSB(signScheme)) 42 | 43 | //C++ guard 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | //TLS related functions 49 | error_t tlsSelectSignAlgo(TlsContext *context, const TlsCertDesc *cert, 50 | const TlsSignSchemeList *signAlgoList); 51 | 52 | error_t tlsFormatSignAlgosExtension(TlsContext *context, uint8_t *p, 53 | size_t *written); 54 | 55 | error_t tlsFormatSignAlgosCertExtension(TlsContext *context, 56 | uint8_t *p, size_t *written); 57 | 58 | error_t tlsFormatSupportedSignAlgos(TlsContext *context, uint8_t *p, 59 | size_t *written); 60 | 61 | bool_t tlsIsSignAlgoOffered(uint16_t signScheme, 62 | const TlsSignSchemeList *signSchemeList); 63 | 64 | bool_t tlsIsSignAlgoAcceptable(TlsContext *context, uint16_t signScheme, 65 | const TlsCertDesc *cert); 66 | 67 | bool_t tlsIsSignAlgoSupported(TlsContext *context, uint16_t signScheme); 68 | bool_t tlsIsCertSignAlgoSupported(uint16_t signScheme); 69 | 70 | //C++ guard 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /tls_sign_verify.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_sign_verify.h 3 | * @brief RSA/DSA/ECDSA/EdDSA signature verification 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_SIGN_VERIFY_H 32 | #define _TLS_SIGN_VERIFY_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | 37 | //C++ guard 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | //TLS related functions 43 | error_t tlsVerifySignature(TlsContext *context, const uint8_t *p, 44 | size_t length); 45 | 46 | error_t tls12VerifySignature(TlsContext *context, const uint8_t *p, 47 | size_t length); 48 | 49 | error_t tlsVerifyRsaSignature(const RsaPublicKey *key, 50 | const uint8_t *digest, const uint8_t *signature, size_t signatureLen); 51 | 52 | error_t tlsVerifyRsaEm(const uint8_t *digest, const uint8_t *em, size_t emLen); 53 | 54 | error_t tlsVerifyDsaSignature(TlsContext *context, const uint8_t *digest, 55 | size_t digestLen, const uint8_t *signature, size_t signatureLen); 56 | 57 | error_t tlsVerifyEcdsaSignature(TlsContext *context, const uint8_t *digest, 58 | size_t digestLen, const uint8_t *signature, size_t signatureLen); 59 | 60 | error_t tlsVerifyEd25519Signature(TlsContext *context, 61 | const DataChunk *message, uint_t messageLen, const uint8_t *signature, 62 | size_t signatureLen); 63 | 64 | error_t tlsVerifyEd448Signature(TlsContext *context, 65 | const DataChunk *message, uint_t messageLen, const uint8_t *signature, 66 | size_t signatureLen); 67 | 68 | //C++ guard 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /tls_ticket.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_ticket.c 3 | * @brief TLS session tickets 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | //Switch to the appropriate trace level 32 | #define TRACE_LEVEL TLS_TRACE_LEVEL 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | #include "tls_ticket.h" 37 | #include "debug.h" 38 | 39 | //Check TLS library configuration 40 | #if (TLS_SUPPORT == ENABLED && TLS_TICKET_SUPPORT == ENABLED) 41 | 42 | 43 | /** 44 | * @brief Initialize ticket encryption context 45 | * @param[in] ticketContext Pointer to ticket encryption context 46 | * @return Error code 47 | **/ 48 | 49 | error_t tlsInitTicketContext(TlsTicketContext *ticketContext) 50 | { 51 | //Make sure the ticket encryption context is valid 52 | if(ticketContext == NULL) 53 | return ERROR_INVALID_PARAMETER; 54 | 55 | //Erase ticket encryption context 56 | osMemset(ticketContext, 0, sizeof(TlsTicketContext)); 57 | 58 | //Create a mutex to prevent simultaneous access to the context 59 | if(!osCreateMutex(&ticketContext->mutex)) 60 | { 61 | //Report an error 62 | return ERROR_OUT_OF_RESOURCES; 63 | } 64 | 65 | //Successful initialization 66 | return NO_ERROR; 67 | } 68 | 69 | 70 | /** 71 | * @brief Session ticket encryption 72 | * @param[in] context Pointer to the TLS context 73 | * @param[in] plaintext Plaintext session state 74 | * @param[in] plaintextLen Length of the plaintext session state, in bytes 75 | * @param[out] ciphertext Encrypted ticket 76 | * @param[out] ciphertextLen Length of the encrypted ticket, in bytes 77 | * @param[in] param Pointer to the ticket encryption context 78 | * @return Error code 79 | **/ 80 | 81 | error_t tlsEncryptTicket(TlsContext *context, const uint8_t *plaintext, 82 | size_t plaintextLen, uint8_t *ciphertext, size_t *ciphertextLen, void *param) 83 | { 84 | error_t error; 85 | uint8_t *iv; 86 | uint8_t *data; 87 | uint8_t *tag; 88 | systime_t time; 89 | TlsTicketContext *ticketContext; 90 | TlsTicketEncryptionState *state; 91 | 92 | //Check parameters 93 | if(context == NULL || param == NULL) 94 | return ERROR_INVALID_PARAMETER; 95 | if(plaintext == NULL || ciphertext == NULL || ciphertextLen == NULL) 96 | return ERROR_INVALID_PARAMETER; 97 | 98 | //Initialize status code 99 | error = NO_ERROR; 100 | 101 | //Initialize variables 102 | iv = NULL; 103 | data = NULL; 104 | tag = NULL; 105 | 106 | //Point to the ticket encryption context 107 | ticketContext = (TlsTicketContext *) param; 108 | 109 | //Acquire exclusive access to the ticket encryption context 110 | osAcquireMutex(&ticketContext->mutex); 111 | 112 | //The keys should be changed regularly (refer to RFC 5077, section 5.5) 113 | tlsCheckTicketKeyLifetime(&ticketContext->encryptionState); 114 | tlsCheckTicketKeyLifetime(&ticketContext->prevEncryptionState); 115 | 116 | //Point to the current ticket encryption state 117 | state = &ticketContext->encryptionState; 118 | 119 | //Check whether the ticket encryption state is valid 120 | if(state->valid) 121 | { 122 | //Get current time 123 | time = osGetSystemTime(); 124 | 125 | //Check the validity of the encryption keys 126 | if((time - state->timestamp) >= TLS_TICKET_LIFETIME) 127 | { 128 | //Rotate keys 129 | ticketContext->prevEncryptionState = ticketContext->encryptionState; 130 | ticketContext->encryptionState.valid = FALSE; 131 | } 132 | } 133 | 134 | //Invalid set of keys? 135 | if(!state->valid) 136 | { 137 | //Generate a new set of keys 138 | error = tlsGenerateTicketKeys(ticketContext, context->prngAlgo, 139 | context->prngContext); 140 | } 141 | 142 | //Check status code 143 | if(!error) 144 | { 145 | //Point to the IV 146 | iv = ciphertext + TLS_TICKET_KEY_NAME_SIZE; 147 | //Point to the data 148 | data = iv + TLS_TICKET_IV_SIZE; 149 | //Point to the buffer where to store the authentication tag 150 | tag = data + plaintextLen; 151 | 152 | //Copy plaintext state 153 | osMemmove(data, plaintext, plaintextLen); 154 | //Copy key name 155 | osMemcpy(ciphertext, state->keyName, TLS_TICKET_KEY_NAME_SIZE); 156 | 157 | //Generate a random IV 158 | error = context->prngAlgo->generate(context->prngContext, iv, 159 | TLS_TICKET_IV_SIZE); 160 | } 161 | 162 | //Check status code 163 | if(!error) 164 | { 165 | //Initialize AES context 166 | error = aesInit(&ticketContext->aesContext, state->key, 167 | TLS_TICKET_KEY_SIZE); 168 | } 169 | 170 | //Check status code 171 | if(!error) 172 | { 173 | //Initialize GCM context 174 | error = gcmInit(&ticketContext->gcmContext, AES_CIPHER_ALGO, 175 | &ticketContext->aesContext); 176 | } 177 | else 178 | { 179 | //Failed to initialize AES context 180 | state = NULL; 181 | } 182 | 183 | //Check status code 184 | if(!error) 185 | { 186 | //Calculate the length of the encrypted ticket 187 | *ciphertextLen = plaintextLen + TLS_TICKET_KEY_NAME_SIZE + 188 | TLS_TICKET_IV_SIZE + TLS_TICKET_TAG_SIZE; 189 | 190 | //The actual state information in encrypted using AES-GCM 191 | error = gcmEncrypt(&ticketContext->gcmContext, iv, TLS_TICKET_IV_SIZE, 192 | state->keyName, TLS_TICKET_KEY_NAME_SIZE, data, data, plaintextLen, 193 | tag, TLS_TICKET_TAG_SIZE); 194 | } 195 | 196 | //Erase AES context 197 | if(state != NULL) 198 | { 199 | aesDeinit(&ticketContext->aesContext); 200 | } 201 | 202 | //Release exclusive access to the ticket encryption context 203 | osReleaseMutex(&ticketContext->mutex); 204 | 205 | //Return status code 206 | return error; 207 | } 208 | 209 | 210 | /** 211 | * @brief Session ticket decryption 212 | * @param[in] context Pointer to the TLS context 213 | * @param[in] ciphertext Encrypted ticket 214 | * @param[in] ciphertextLen Length of the encrypted ticket, in bytes 215 | * @param[out] plaintext Plaintext session state 216 | * @param[out] plaintextLen Length of the plaintext session state, in bytes 217 | * @param[in] param Pointer to the ticket encryption context 218 | * @return Error code 219 | **/ 220 | 221 | error_t tlsDecryptTicket(TlsContext *context, const uint8_t *ciphertext, 222 | size_t ciphertextLen, uint8_t *plaintext, size_t *plaintextLen, void *param) 223 | { 224 | error_t error; 225 | const uint8_t *iv; 226 | const uint8_t *data; 227 | const uint8_t *tag; 228 | TlsTicketContext *ticketContext; 229 | TlsTicketEncryptionState *state; 230 | 231 | //Check parameters 232 | if(context == NULL || param == NULL) 233 | return ERROR_INVALID_PARAMETER; 234 | if(ciphertext == NULL || plaintext == NULL || plaintextLen == NULL) 235 | return ERROR_INVALID_PARAMETER; 236 | 237 | //Check the length of the encrypted ticket 238 | if(ciphertextLen < (TLS_TICKET_KEY_NAME_SIZE + TLS_TICKET_IV_SIZE + 239 | TLS_TICKET_TAG_SIZE)) 240 | { 241 | //Report an error 242 | return ERROR_DECRYPTION_FAILED; 243 | } 244 | 245 | //Initialize status code 246 | error = NO_ERROR; 247 | 248 | //Initialize variables 249 | iv = NULL; 250 | data = NULL; 251 | tag = NULL; 252 | state = NULL; 253 | 254 | //Point to the ticket encryption context 255 | ticketContext = (TlsTicketContext *) param; 256 | 257 | //Acquire exclusive access to the ticket encryption context 258 | osAcquireMutex(&ticketContext->mutex); 259 | 260 | //The keys should be changed regularly (refer to RFC 5077, section 5.5) 261 | tlsCheckTicketKeyLifetime(&ticketContext->encryptionState); 262 | tlsCheckTicketKeyLifetime(&ticketContext->prevEncryptionState); 263 | 264 | //Compare key names 265 | if(tlsCompareTicketKeyName(ciphertext, ciphertextLen, 266 | &ticketContext->encryptionState)) 267 | { 268 | //Point to the current set of keys 269 | state = &ticketContext->encryptionState; 270 | } 271 | else if(tlsCompareTicketKeyName(ciphertext, ciphertextLen, 272 | &ticketContext->prevEncryptionState)) 273 | { 274 | //Point to the previous set of keys 275 | state = &ticketContext->prevEncryptionState; 276 | } 277 | else 278 | { 279 | //Unknown key name 280 | error = ERROR_DECRYPTION_FAILED; 281 | } 282 | 283 | //Check status code 284 | if(!error) 285 | { 286 | //Point to the IV 287 | iv = ciphertext + TLS_TICKET_KEY_NAME_SIZE; 288 | //Point to the data 289 | data = iv + TLS_TICKET_IV_SIZE; 290 | //Point to the authentication tag 291 | tag = ciphertext + ciphertextLen - TLS_TICKET_TAG_SIZE; 292 | 293 | //Retrieve the length of the data 294 | *plaintextLen = ciphertextLen - TLS_TICKET_KEY_NAME_SIZE - 295 | TLS_TICKET_IV_SIZE - TLS_TICKET_TAG_SIZE; 296 | 297 | //Initialize AES context 298 | error = aesInit(&ticketContext->aesContext, state->key, 299 | TLS_TICKET_KEY_SIZE); 300 | } 301 | 302 | //Check status code 303 | if(!error) 304 | { 305 | //Initialize GCM context 306 | error = gcmInit(&ticketContext->gcmContext, AES_CIPHER_ALGO, 307 | &ticketContext->aesContext); 308 | } 309 | else 310 | { 311 | //Failed to initialize AES context 312 | state = NULL; 313 | } 314 | 315 | //Check status code 316 | if(!error) 317 | { 318 | //The actual state information in encrypted using AES-GCM 319 | error = gcmDecrypt(&ticketContext->gcmContext, iv, TLS_TICKET_IV_SIZE, 320 | state->keyName, TLS_TICKET_KEY_NAME_SIZE, data, plaintext, 321 | *plaintextLen, tag, TLS_TICKET_TAG_SIZE); 322 | } 323 | 324 | //Erase AES context 325 | if(state != NULL) 326 | { 327 | aesDeinit(&ticketContext->aesContext); 328 | } 329 | 330 | //Release exclusive access to the ticket encryption context 331 | osReleaseMutex(&ticketContext->mutex); 332 | 333 | //Return status code 334 | return error; 335 | } 336 | 337 | 338 | /** 339 | * @brief Generate a new set of keys 340 | * @param[in] ticketContext Pointer to ticket encryption context 341 | * @param[in] prngAlgo PRNG algorithm 342 | * @param[in] prngContext Pointer to the PRNG context 343 | * @return Error code 344 | **/ 345 | 346 | error_t tlsGenerateTicketKeys(TlsTicketContext *ticketContext, 347 | const PrngAlgo *prngAlgo, void *prngContext) 348 | { 349 | error_t error; 350 | TlsTicketEncryptionState *state; 351 | 352 | //Point to the current ticket encryption state 353 | state = &ticketContext->encryptionState; 354 | 355 | //The set of keys is not valid anymore 356 | state->valid = FALSE; 357 | 358 | //The key name should be randomly generated to avoid collisions between 359 | //servers (refer to RFC 5077, section 4) 360 | error = prngAlgo->generate(prngContext, state->keyName, 361 | TLS_TICKET_KEY_NAME_SIZE); 362 | //Any error to report? 363 | if(error) 364 | return error; 365 | 366 | //Generate a random encryption key 367 | error = prngAlgo->generate(prngContext, state->key, TLS_TICKET_KEY_SIZE); 368 | //Any error to report? 369 | if(error) 370 | return error; 371 | 372 | //Save current time 373 | state->timestamp = osGetSystemTime(); 374 | //The set of keys is valid 375 | state->valid = TRUE; 376 | 377 | //Successful processing 378 | return NO_ERROR; 379 | } 380 | 381 | 382 | /** 383 | * @brief Check the validity of a given set of keys 384 | * @param[in] state Pointer to ticket encryption state 385 | **/ 386 | 387 | void tlsCheckTicketKeyLifetime(TlsTicketEncryptionState *state) 388 | { 389 | systime_t time; 390 | 391 | //Get current time 392 | time = osGetSystemTime(); 393 | 394 | //Valid set of keys? 395 | if(state->valid) 396 | { 397 | //Check lifetime 398 | if((time - state->timestamp) >= (2 * TLS_TICKET_LIFETIME)) 399 | { 400 | //Clear ticket keys 401 | osMemset(state, 0, sizeof(TlsTicketEncryptionState)); 402 | } 403 | } 404 | } 405 | 406 | 407 | /** 408 | * @brief Key name comparison 409 | * @param[in] ticket Encrypted ticket 410 | * @param[in] ticketLen Length of the encrypted ticket, in bytes 411 | * @param[in] state Pointer to ticket encryption state 412 | **/ 413 | 414 | bool_t tlsCompareTicketKeyName(const uint8_t *ticket, size_t ticketLen, 415 | const TlsTicketEncryptionState *state) 416 | { 417 | bool_t res; 418 | 419 | //Initialize flag 420 | res = FALSE; 421 | 422 | //Valid set of keys? 423 | if(state->valid) 424 | { 425 | //The key name serves to identify a particular set of keys used to 426 | //protect the ticket (refer to RFC 5077, section 4) 427 | if(ticketLen >= TLS_TICKET_KEY_NAME_SIZE) 428 | { 429 | //Compare key names 430 | if(osMemcmp(ticket, state->keyName, TLS_TICKET_KEY_NAME_SIZE) == 0) 431 | { 432 | //The key name is valid 433 | res = TRUE; 434 | } 435 | } 436 | } 437 | 438 | //Return comparison result 439 | return res; 440 | } 441 | 442 | 443 | /** 444 | * @brief Properly dispose ticket encryption context 445 | * @param[in] ticketContext Pointer to ticket encryption context to be released 446 | **/ 447 | 448 | void tlsFreeTicketContext(TlsTicketContext *ticketContext) 449 | { 450 | //Make sure the ticket encryption context is valid 451 | if(ticketContext != NULL) 452 | { 453 | //Release previously allocated resources 454 | osDeleteMutex(&ticketContext->mutex); 455 | 456 | //Erase ticket encryption context 457 | osMemset(ticketContext, 0, sizeof(TlsTicketContext)); 458 | } 459 | } 460 | 461 | #endif 462 | -------------------------------------------------------------------------------- /tls_ticket.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tls_ticket.h 3 | * @brief TLS session tickets 4 | * 5 | * @section License 6 | * 7 | * SPDX-License-Identifier: GPL-2.0-or-later 8 | * 9 | * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved. 10 | * 11 | * This file is part of CycloneSSL Open. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software Foundation, 25 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | * 27 | * @author Oryx Embedded SARL (www.oryx-embedded.com) 28 | * @version 2.5.4 29 | **/ 30 | 31 | #ifndef _TLS_TICKET_H 32 | #define _TLS_TICKET_H 33 | 34 | //Dependencies 35 | #include "tls.h" 36 | #include "cipher/aes.h" 37 | #include "aead/gcm.h" 38 | 39 | //Size of ticket key names 40 | #ifndef TLS_TICKET_KEY_NAME_SIZE 41 | #define TLS_TICKET_KEY_NAME_SIZE 16 42 | #elif (TLS_TICKET_KEY_NAME_SIZE < 1) 43 | #error TLS_TICKET_KEY_NAME_SIZE parameter is not valid 44 | #endif 45 | 46 | //Size of ticket keys 47 | #ifndef TLS_TICKET_KEY_SIZE 48 | #define TLS_TICKET_KEY_SIZE 32 49 | #elif (TLS_TICKET_KEY_SIZE < 1) 50 | #error TLS_TICKET_KEY_SIZE parameter is not valid 51 | #endif 52 | 53 | //Size of ticket IVs 54 | #ifndef TLS_TICKET_IV_SIZE 55 | #define TLS_TICKET_IV_SIZE 12 56 | #elif (TLS_TICKET_IV_SIZE < 1) 57 | #error TLS_TICKET_IV_SIZE parameter is not valid 58 | #endif 59 | 60 | //Size of ticket authentication tags 61 | #ifndef TLS_TICKET_TAG_SIZE 62 | #define TLS_TICKET_TAG_SIZE 16 63 | #elif (TLS_TICKET_TAG_SIZE < 1) 64 | #error TLS_TICKET_TAG_SIZE parameter is not valid 65 | #endif 66 | 67 | //C++ guard 68 | #ifdef __cplusplus 69 | extern "C" { 70 | #endif 71 | 72 | 73 | /** 74 | * @brief Session ticket encryption state 75 | **/ 76 | 77 | typedef struct 78 | { 79 | bool_t valid; ///