Webserver+3d print
Diff: cyclone_ssl/tls.h
- Revision:
- 0:8918a71cdbe9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cyclone_ssl/tls.h Sat Feb 04 18:15:49 2017 +0000 @@ -0,0 +1,1600 @@ +/** + * @file tls.h + * @brief TLS (Transport Layer Security) + * + * @section License + * + * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. + * + * This file is part of CycloneSSL Open. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * @author Oryx Embedded SARL (www.oryx-embedded.com) + * @version 1.7.6 + **/ + +#ifndef _TLS_H +#define _TLS_H + +//Dependencies +#include "os_port.h" +#include "crypto.h" +#include "tls_config.h" +#include "hmac.h" +#include "rsa.h" +#include "dsa.h" +#include "ecdsa.h" +#include "dh.h" +#include "ecdh.h" +#include "cipher_mode_gcm.h" + +//TLS version numbers +#define SSL_VERSION_3_0 0x0300 +#define TLS_VERSION_1_0 0x0301 +#define TLS_VERSION_1_1 0x0302 +#define TLS_VERSION_1_2 0x0303 + +//Enable SSL/TLS support +#ifndef TLS_SUPPORT + #define TLS_SUPPORT ENABLED +#elif (TLS_SUPPORT != ENABLED && TLS_SUPPORT != DISABLED) + #error TLS_SUPPORT parameter is not valid +#endif + +//Client mode of operation +#ifndef TLS_CLIENT_SUPPORT + #define TLS_CLIENT_SUPPORT ENABLED +#elif (TLS_CLIENT_SUPPORT != ENABLED && TLS_CLIENT_SUPPORT != DISABLED) + #error TLS_CLIENT_SUPPORT parameter is not valid +#endif + +//Server mode of operation +#ifndef TLS_SERVER_SUPPORT + #define TLS_SERVER_SUPPORT ENABLED +#elif (TLS_SERVER_SUPPORT != ENABLED && TLS_SERVER_SUPPORT != DISABLED) + #error TLS_SERVER_SUPPORT parameter is not valid +#endif + +//Minimum version that can be negotiated +#ifndef TLS_MIN_VERSION + #define TLS_MIN_VERSION TLS_VERSION_1_0 +#elif (TLS_MIN_VERSION < SSL_VERSION_3_0) + #error TLS_MIN_VERSION parameter is not valid +#endif + +//Maximum version that can be negotiated +#ifndef TLS_MAX_VERSION + #define TLS_MAX_VERSION TLS_VERSION_1_2 +#elif (TLS_MAX_VERSION > TLS_VERSION_1_2 || TLS_MAX_VERSION < TLS_MIN_VERSION) + #error TLS_MAX_VERSION parameter is not valid +#endif + +//Session resumption mechanism +#ifndef TLS_SESSION_RESUME_SUPPORT + #define TLS_SESSION_RESUME_SUPPORT ENABLED +#elif (TLS_SESSION_RESUME_SUPPORT != ENABLED && TLS_SESSION_RESUME_SUPPORT != DISABLED) + #error TLS_SESSION_RESUME_SUPPORT parameter is not valid +#endif + +//Lifetime of session cache entries +#ifndef TLS_SESSION_CACHE_LIFETIME + #define TLS_SESSION_CACHE_LIFETIME 3600000 +#elif (TLS_SESSION_CACHE_LIFETIME < 1000) + #error TLS_SESSION_CACHE_LIFETIME parameter is not valid +#endif + +//SNI (Server Name Indication) extension +#ifndef TLS_SNI_SUPPORT + #define TLS_SNI_SUPPORT ENABLED +#elif (TLS_SNI_SUPPORT != ENABLED && TLS_SNI_SUPPORT != DISABLED) + #error TLS_SNI_SUPPORT parameter is not valid +#endif + +//ALPN (Application-Layer Protocol Negotiation) extension +#ifndef TLS_ALPN_SUPPORT + #define TLS_ALPN_SUPPORT DISABLED +#elif (TLS_ALPN_SUPPORT != ENABLED && TLS_ALPN_SUPPORT != DISABLED) + #error TLS_ALPN_SUPPORT parameter is not valid +#endif + +//Maximum number of certificates the end entity can load +#ifndef TLS_MAX_CERTIFICATES + #define TLS_MAX_CERTIFICATES 3 +#elif (TLS_MAX_CERTIFICATES < 1) + #error TLS_MAX_CERTIFICATES parameter is not valid +#endif + +//RSA key exchange support +#ifndef TLS_RSA_SUPPORT + #define TLS_RSA_SUPPORT ENABLED +#elif (TLS_RSA_SUPPORT != ENABLED && TLS_RSA_SUPPORT != DISABLED) + #error TLS_RSA_SUPPORT parameter is not valid +#endif + +//DHE_RSA key exchange support +#ifndef TLS_DHE_RSA_SUPPORT + #define TLS_DHE_RSA_SUPPORT ENABLED +#elif (TLS_DHE_RSA_SUPPORT != ENABLED && TLS_DHE_RSA_SUPPORT != DISABLED) + #error TLS_DHE_RSA_SUPPORT parameter is not valid +#endif + +//DHE_DSS key exchange support +#ifndef TLS_DHE_DSS_SUPPORT + #define TLS_DHE_DSS_SUPPORT ENABLED +#elif (TLS_DHE_DSS_SUPPORT != ENABLED && TLS_DHE_DSS_SUPPORT != DISABLED) + #error TLS_DHE_DSS_SUPPORT parameter is not valid +#endif + +//DH_anon key exchange support +#ifndef TLS_DH_ANON_SUPPORT + #define TLS_DH_ANON_SUPPORT DISABLED +#elif (TLS_DH_ANON_SUPPORT != ENABLED && TLS_DH_ANON_SUPPORT != DISABLED) + #error TLS_DH_ANON_SUPPORT parameter is not valid +#endif + +//ECDHE_RSA key exchange support +#ifndef TLS_ECDHE_RSA_SUPPORT + #define TLS_ECDHE_RSA_SUPPORT ENABLED +#elif (TLS_ECDHE_RSA_SUPPORT != ENABLED && TLS_ECDHE_RSA_SUPPORT != DISABLED) + #error TLS_ECDHE_RSA_SUPPORT parameter is not valid +#endif + +//ECDHE_ECDSA key exchange support +#ifndef TLS_ECDHE_ECDSA_SUPPORT + #define TLS_ECDHE_ECDSA_SUPPORT ENABLED +#elif (TLS_ECDHE_ECDSA_SUPPORT != ENABLED && TLS_ECDHE_ECDSA_SUPPORT != DISABLED) + #error TLS_ECDHE_ECDSA_SUPPORT parameter is not valid +#endif + +//ECDH_anon key exchange support +#ifndef TLS_ECDH_ANON_SUPPORT + #define TLS_ECDH_ANON_SUPPORT DISABLED +#elif (TLS_ECDH_ANON_SUPPORT != ENABLED && TLS_ECDH_ANON_SUPPORT != DISABLED) + #error TLS_ECDH_ANON_SUPPORT parameter is not valid +#endif + +//PSK key exchange support +#ifndef TLS_PSK_SUPPORT + #define TLS_PSK_SUPPORT DISABLED +#elif (TLS_PSK_SUPPORT != ENABLED && TLS_PSK_SUPPORT != DISABLED) + #error TLS_PSK_SUPPORT parameter is not valid +#endif + +//RSA_PSK key exchange support +#ifndef TLS_RSA_PSK_SUPPORT + #define TLS_RSA_PSK_SUPPORT DISABLED +#elif (TLS_RSA_PSK_SUPPORT != ENABLED && TLS_RSA_PSK_SUPPORT != DISABLED) + #error TLS_RSA_PSK_SUPPORT parameter is not valid +#endif + +//DHE_PSK key exchange support +#ifndef TLS_DHE_PSK_SUPPORT + #define TLS_DHE_PSK_SUPPORT DISABLED +#elif (TLS_DHE_PSK_SUPPORT != ENABLED && TLS_DHE_PSK_SUPPORT != DISABLED) + #error TLS_DHE_PSK_SUPPORT parameter is not valid +#endif + +//ECDHE_PSK key exchange support +#ifndef TLS_ECDHE_PSK_SUPPORT + #define TLS_ECDHE_PSK_SUPPORT DISABLED +#elif (TLS_ECDHE_PSK_SUPPORT != ENABLED && TLS_ECDHE_PSK_SUPPORT != DISABLED) + #error TLS_ECDHE_PSK_SUPPORT parameter is not valid +#endif + +//RSA signature capability +#ifndef TLS_RSA_SIGN_SUPPORT + #define TLS_RSA_SIGN_SUPPORT ENABLED +#elif (TLS_RSA_SIGN_SUPPORT != ENABLED && TLS_RSA_SIGN_SUPPORT != DISABLED) + #error TLS_RSA_SIGN_SUPPORT parameter is not valid +#endif + +//DSA signature capability +#ifndef TLS_DSA_SIGN_SUPPORT + #define TLS_DSA_SIGN_SUPPORT ENABLED +#elif (TLS_DSA_SIGN_SUPPORT != ENABLED && TLS_DSA_SIGN_SUPPORT != DISABLED) + #error TLS_DSA_SIGN_SUPPORT parameter is not valid +#endif + +//ECDSA signature capability +#ifndef TLS_ECDSA_SIGN_SUPPORT + #define TLS_ECDSA_SIGN_SUPPORT ENABLED +#elif (TLS_ECDSA_SIGN_SUPPORT != ENABLED && TLS_ECDSA_SIGN_SUPPORT != DISABLED) + #error TLS_ECDSA_SIGN_SUPPORT parameter is not valid +#endif + +//Stream cipher support +#ifndef TLS_STREAM_CIPHER_SUPPORT + #define TLS_STREAM_CIPHER_SUPPORT ENABLED +#elif (TLS_STREAM_CIPHER_SUPPORT != ENABLED && TLS_STREAM_CIPHER_SUPPORT != DISABLED) + #error TLS_STREAM_CIPHER_SUPPORT parameter is not valid +#endif + +//CBC block cipher support +#ifndef TLS_CBC_CIPHER_SUPPORT + #define TLS_CBC_CIPHER_SUPPORT ENABLED +#elif (TLS_CBC_CIPHER_SUPPORT != ENABLED && TLS_CBC_CIPHER_SUPPORT != DISABLED) + #error TLS_CBC_CIPHER_SUPPORT parameter is not valid +#endif + +//CCM AEAD support +#ifndef TLS_CCM_CIPHER_SUPPORT + #define TLS_CCM_CIPHER_SUPPORT ENABLED +#elif (TLS_CCM_CIPHER_SUPPORT != ENABLED && TLS_CCM_CIPHER_SUPPORT != DISABLED) + #error TLS_CCM_CIPHER_SUPPORT parameter is not valid +#endif + +//CCM_8 AEAD support +#ifndef TLS_CCM_8_CIPHER_SUPPORT + #define TLS_CCM_8_CIPHER_SUPPORT DISABLED +#elif (TLS_CCM_8_CIPHER_SUPPORT != ENABLED && TLS_CCM_8_CIPHER_SUPPORT != DISABLED) + #error TLS_CCM_8_CIPHER_SUPPORT parameter is not valid +#endif + +//GCM AEAD support +#ifndef TLS_GCM_CIPHER_SUPPORT + #define TLS_GCM_CIPHER_SUPPORT ENABLED +#elif (TLS_GCM_CIPHER_SUPPORT != ENABLED && TLS_GCM_CIPHER_SUPPORT != DISABLED) + #error TLS_GCM_CIPHER_SUPPORT parameter is not valid +#endif + +//ChaCha20Poly1305 AEAD support +#ifndef TLS_CHACHA20_POLY1305_SUPPORT + #define TLS_CHACHA20_POLY1305_SUPPORT DISABLED +#elif (TLS_CHACHA20_POLY1305_SUPPORT != ENABLED && TLS_CHACHA20_POLY1305_SUPPORT != DISABLED) + #error TLS_CHACHA20_POLY1305_SUPPORT parameter is not valid +#endif + +//RC4 cipher support +#ifndef TLS_RC4_SUPPORT + #define TLS_RC4_SUPPORT DISABLED +#elif (TLS_RC4_SUPPORT != ENABLED && TLS_RC4_SUPPORT != DISABLED) + #error TLS_RC4_SUPPORT parameter is not valid +#endif + +//IDEA cipher support +#ifndef TLS_IDEA_SUPPORT + #define TLS_IDEA_SUPPORT DISABLED +#elif (TLS_IDEA_SUPPORT != ENABLED && TLS_IDEA_SUPPORT != DISABLED) + #error TLS_IDEA_SUPPORT parameter is not valid +#endif + +//DES cipher support +#ifndef TLS_DES_SUPPORT + #define TLS_DES_SUPPORT DISABLED +#elif (TLS_DES_SUPPORT != ENABLED && TLS_DES_SUPPORT != DISABLED) + #error TLS_DES_SUPPORT parameter is not valid +#endif + +//Triple DES cipher support +#ifndef TLS_3DES_SUPPORT + #define TLS_3DES_SUPPORT ENABLED +#elif (TLS_3DES_SUPPORT != ENABLED && TLS_3DES_SUPPORT != DISABLED) + #error TLS_3DES_SUPPORT parameter is not valid +#endif + +//AES cipher support +#ifndef TLS_AES_SUPPORT + #define TLS_AES_SUPPORT ENABLED +#elif (TLS_AES_SUPPORT != ENABLED && TLS_AES_SUPPORT != DISABLED) + #error TLS_AES_SUPPORT parameter is not valid +#endif + +//Camellia cipher support +#ifndef TLS_CAMELLIA_SUPPORT + #define TLS_CAMELLIA_SUPPORT ENABLED +#elif (TLS_CAMELLIA_SUPPORT != ENABLED && TLS_CAMELLIA_SUPPORT != DISABLED) + #error TLS_CAMELLIA_SUPPORT parameter is not valid +#endif + +//SEED cipher support +#ifndef TLS_SEED_SUPPORT + #define TLS_SEED_SUPPORT ENABLED +#elif (TLS_SEED_SUPPORT != ENABLED && TLS_SEED_SUPPORT != DISABLED) + #error TLS_SEED_SUPPORT parameter is not valid +#endif + +//ARIA cipher support +#ifndef TLS_ARIA_SUPPORT + #define TLS_ARIA_SUPPORT ENABLED +#elif (TLS_ARIA_SUPPORT != ENABLED && TLS_ARIA_SUPPORT != DISABLED) + #error TLS_ARIA_SUPPORT parameter is not valid +#endif + +//MD5 hash support +#ifndef TLS_MD5_SUPPORT + #define TLS_MD5_SUPPORT DISABLED +#elif (TLS_MD5_SUPPORT != ENABLED && TLS_MD5_SUPPORT != DISABLED) + #error TLS_MD5_SUPPORT parameter is not valid +#endif + +//SHA-1 hash support +#ifndef TLS_SHA1_SUPPORT + #define TLS_SHA1_SUPPORT ENABLED +#elif (TLS_SHA1_SUPPORT != ENABLED && TLS_SHA1_SUPPORT != DISABLED) + #error TLS_SHA1_SUPPORT parameter is not valid +#endif + +//SHA-224 hash support +#ifndef TLS_SHA224_SUPPORT + #define TLS_SHA224_SUPPORT ENABLED +#elif (TLS_SHA224_SUPPORT != ENABLED && TLS_SHA224_SUPPORT != DISABLED) + #error TLS_SHA224_SUPPORT parameter is not valid +#endif + +//SHA-256 hash support +#ifndef TLS_SHA256_SUPPORT + #define TLS_SHA256_SUPPORT ENABLED +#elif (TLS_SHA256_SUPPORT != ENABLED && TLS_SHA256_SUPPORT != DISABLED) + #error TLS_SHA256_SUPPORT parameter is not valid +#endif + +//SHA-384 hash support +#ifndef TLS_SHA384_SUPPORT + #define TLS_SHA384_SUPPORT ENABLED +#elif (TLS_SHA384_SUPPORT != ENABLED && TLS_SHA384_SUPPORT != DISABLED) + #error TLS_SHA384_SUPPORT parameter is not valid +#endif + +//SHA-512 hash support +#ifndef TLS_SHA512_SUPPORT + #define TLS_SHA512_SUPPORT ENABLED +#elif (TLS_SHA512_SUPPORT != ENABLED && TLS_SHA512_SUPPORT != DISABLED) + #error TLS_SHA512_SUPPORT parameter is not valid +#endif + +//secp160k1 elliptic curve support +#ifndef TLS_SECP160K1_SUPPORT + #define TLS_SECP160K1_SUPPORT DISABLED +#elif (TLS_SECP160K1_SUPPORT != ENABLED && TLS_SECP160K1_SUPPORT != DISABLED) + #error TLS_SECP160K1_SUPPORT parameter is not valid +#endif + +//secp160r1 elliptic curve support +#ifndef TLS_SECP160R1_SUPPORT + #define TLS_SECP160R1_SUPPORT DISABLED +#elif (TLS_SECP160R1_SUPPORT != ENABLED && TLS_SECP160R1_SUPPORT != DISABLED) + #error TLS_SECP160R1_SUPPORT parameter is not valid +#endif + +//secp160r2 elliptic curve support +#ifndef TLS_SECP160R2_SUPPORT + #define TLS_SECP160R2_SUPPORT DISABLED +#elif (TLS_SECP160R2_SUPPORT != ENABLED && TLS_SECP160R2_SUPPORT != DISABLED) + #error TLS_SECP160R2_SUPPORT parameter is not valid +#endif + +//secp192k1 elliptic curve support +#ifndef TLS_SECP192K1_SUPPORT + #define TLS_SECP192K1_SUPPORT DISABLED +#elif (TLS_SECP192K1_SUPPORT != ENABLED && TLS_SECP192K1_SUPPORT != DISABLED) + #error TLS_SECP192K1_SUPPORT parameter is not valid +#endif + +//secp192r1 elliptic curve support +#ifndef TLS_SECP192R1_SUPPORT + #define TLS_SECP192R1_SUPPORT ENABLED +#elif (TLS_SECP192R1_SUPPORT != ENABLED && TLS_SECP192R1_SUPPORT != DISABLED) + #error TLS_SECP192R1_SUPPORT parameter is not valid +#endif + +//secp224k1 elliptic curve support +#ifndef TLS_SECP224K1_SUPPORT + #define TLS_SECP224K1_SUPPORT DISABLED +#elif (TLS_SECP224K1_SUPPORT != ENABLED && TLS_SECP224K1_SUPPORT != DISABLED) + #error TLS_SECP224K1_SUPPORT parameter is not valid +#endif + +//secp224r1 elliptic curve support +#ifndef TLS_SECP224R1_SUPPORT + #define TLS_SECP224R1_SUPPORT ENABLED +#elif (TLS_SECP224R1_SUPPORT != ENABLED && TLS_SECP224R1_SUPPORT != DISABLED) + #error TLS_SECP224R1_SUPPORT parameter is not valid +#endif + +//secp256k1 elliptic curve support +#ifndef TLS_SECP256K1_SUPPORT + #define TLS_SECP256K1_SUPPORT DISABLED +#elif (TLS_SECP256K1_SUPPORT != ENABLED && TLS_SECP256K1_SUPPORT != DISABLED) + #error TLS_SECP256K1_SUPPORT parameter is not valid +#endif + +//secp256r1 elliptic curve support +#ifndef TLS_SECP256R1_SUPPORT + #define TLS_SECP256R1_SUPPORT ENABLED +#elif (TLS_SECP256R1_SUPPORT != ENABLED && TLS_SECP256R1_SUPPORT != DISABLED) + #error TLS_SECP256R1_SUPPORT parameter is not valid +#endif + +//secp384r1 elliptic curve support +#ifndef TLS_SECP384R1_SUPPORT + #define TLS_SECP384R1_SUPPORT ENABLED +#elif (TLS_SECP384R1_SUPPORT != ENABLED && TLS_SECP384R1_SUPPORT != DISABLED) + #error TLS_SECP384R1_SUPPORT parameter is not valid +#endif + +//secp521r1 elliptic curve support +#ifndef TLS_SECP521R1_SUPPORT + #define TLS_SECP521R1_SUPPORT ENABLED +#elif (TLS_SECP521R1_SUPPORT != ENABLED && TLS_SECP521R1_SUPPORT != DISABLED) + #error TLS_SECP521R1_SUPPORT parameter is not valid +#endif + +//brainpoolP256r1 elliptic curve support +#ifndef TLS_BRAINPOOLP256R1_SUPPORT + #define TLS_BRAINPOOLP256R1_SUPPORT DISABLED +#elif (TLS_BRAINPOOLP256R1_SUPPORT != ENABLED && TLS_BRAINPOOLP256R1_SUPPORT != DISABLED) + #error TLS_BRAINPOOLP256R1_SUPPORT parameter is not valid +#endif + +//brainpoolP384r1 elliptic curve support +#ifndef TLS_BRAINPOOLP384R1_SUPPORT + #define TLS_BRAINPOOLP384R1_SUPPORT DISABLED +#elif (TLS_BRAINPOOLP384R1_SUPPORT != ENABLED && TLS_BRAINPOOLP384R1_SUPPORT != DISABLED) + #error TLS_BRAINPOOLP384R1_SUPPORT parameter is not valid +#endif + +//brainpoolP512r1 elliptic curve support +#ifndef TLS_BRAINPOOLP512R1_SUPPORT + #define TLS_BRAINPOOLP512R1_SUPPORT DISABLED +#elif (TLS_BRAINPOOLP512R1_SUPPORT != ENABLED && TLS_BRAINPOOLP512R1_SUPPORT != DISABLED) + #error TLS_BRAINPOOLP512R1_SUPPORT parameter is not valid +#endif + +//Minimum acceptable size for Diffie-Hellman prime modulus +#ifndef TLS_MIN_DH_MODULUS_SIZE + #define TLS_MIN_DH_MODULUS_SIZE 1024 +#elif (TLS_MIN_DH_MODULUS_SIZE < 512) + #error TLS_MIN_DH_MODULUS_SIZE parameter is not valid +#endif + +//Maximum acceptable size for Diffie-Hellman prime modulus +#ifndef TLS_MAX_DH_MODULUS_SIZE + #define TLS_MAX_DH_MODULUS_SIZE 4096 +#elif (TLS_MAX_DH_MODULUS_SIZE < TLS_MIN_DH_MODULUS_SIZE) + #error TLS_MAX_DH_MODULUS_SIZE parameter is not valid +#endif + +//Minimum acceptable size for RSA modulus +#ifndef TLS_MIN_RSA_MODULUS_SIZE + #define TLS_MIN_RSA_MODULUS_SIZE 1024 +#elif (TLS_MIN_RSA_MODULUS_SIZE < 512) + #error TLS_MIN_RSA_MODULUS_SIZE parameter is not valid +#endif + +//Maximum acceptable size for RSA modulus +#ifndef TLS_MAX_RSA_MODULUS_SIZE + #define TLS_MAX_RSA_MODULUS_SIZE 4096 +#elif (TLS_MAX_RSA_MODULUS_SIZE < TLS_MIN_RSA_MODULUS_SIZE) + #error TLS_MAX_RSA_MODULUS_SIZE parameter is not valid +#endif + +//Minimum acceptable size for DSA prime modulus +#ifndef TLS_MIN_DSA_MODULUS_SIZE + #define TLS_MIN_DSA_MODULUS_SIZE 1024 +#elif (TLS_MIN_DSA_MODULUS_SIZE < 512) + #error TLS_MIN_DSA_MODULUS_SIZE parameter is not valid +#endif + +//Maximum acceptable size for DSA prime modulus +#ifndef TLS_MAX_DSA_MODULUS_SIZE + #define TLS_MAX_DSA_MODULUS_SIZE 4096 +#elif (TLS_MAX_DSA_MODULUS_SIZE < TLS_MIN_DSA_MODULUS_SIZE) + #error TLS_MAX_DSA_MODULUS_SIZE parameter is not valid +#endif + +//Maximum size for premaster secret +#ifndef TLS_MAX_PREMASTER_SECRET_SIZE + #define TLS_MAX_PREMASTER_SECRET_SIZE 256 +#elif (TLS_MAX_PREMASTER_SECRET_SIZE < 48) + #error TLS_MAX_PREMASTER_SECRET_SIZE parameter is not valid +#endif + +//Memory allocation +#ifndef tlsAllocMem + #define tlsAllocMem(size) osAllocMem(size) +#endif + +//Memory deallocation +#ifndef tlsFreeMem + #define tlsFreeMem(p) osFreeMem(p) +#endif + +//Bind TLS to a particular socket +#define tlsSetSocket(context, socket) tlsSetIoCallbacks(context, (TlsIoHandle) socket, \ + (TlsIoSendCallback) socketSend, (TlsIoReceiveCallback) socketReceive) + +//Maximum plaintext record length +#define TLS_MAX_RECORD_LENGTH 16384 +//Data overhead caused by record encryption +#define TLS_MAX_RECORD_OVERHEAD 512 + +//Forward declaration of TlsContext structure +struct _TlsContext; +#define TlsContext struct _TlsContext + + +/** + * @brief TLS connection end + **/ + +typedef enum +{ + TLS_CONNECTION_END_CLIENT = 0, + TLS_CONNECTION_END_SERVER = 1 +} TlsConnectionEnd; + + +/** + * @brief Client authentication mode + **/ + +typedef enum +{ + TLS_CLIENT_AUTH_NONE = 0, + TLS_CLIENT_AUTH_OPTIONAL = 1, + TLS_CLIENT_AUTH_REQUIRED = 2 +} TlsClientAuthMode; + + +/** + * @brief Flags used by read and write functions + **/ + +typedef enum +{ + TLS_FLAG_WAIT_ALL = 0x0800, + TLS_FLAG_BREAK_CHAR = 0x1000, + TLS_FLAG_BREAK_CRLF = 0x100A, + TLS_FLAG_WAIT_ACK = 0x2000, + TLS_FLAG_BUFFER = 0x4000 +} TlsFlags; + + +//The TLS_FLAG_BREAK macro causes the read function to stop reading +//data whenever the specified break character is encountered +#define TLS_FLAG_BREAK(c) (TLS_FLAG_BREAK_CHAR | LSB(c)) + + +/** + * @brief Content type + **/ + +typedef enum +{ + TLS_TYPE_NONE = 0, + TLS_TYPE_CHANGE_CIPHER_SPEC = 20, + TLS_TYPE_ALERT = 21, + TLS_TYPE_HANDSHAKE = 22, + TLS_TYPE_APPLICATION_DATA = 23, + TLS_TYPE_HEARTBEAT = 24 +} TlsContentType; + + +/** + * @brief Handshake message type + **/ + +typedef enum +{ + TLS_TYPE_HELLO_REQUEST = 0, + TLS_TYPE_CLIENT_HELLO = 1, + TLS_TYPE_SERVER_HELLO = 2, + TLS_TYPE_HELLO_VERIFY_REQUEST = 3, + TLS_TYPE_NEW_SESSION_TICKET = 4, + TLS_TYPE_CERTIFICATE = 11, + TLS_TYPE_SERVER_KEY_EXCHANGE = 12, + TLS_TYPE_CERTIFICATE_REQUEST = 13, + TLS_TYPE_SERVER_HELLO_DONE = 14, + TLS_TYPE_CERTIFICATE_VERIFY = 15, + TLS_TYPE_CLIENT_KEY_EXCHANGE = 16, + TLS_TYPE_FINISHED = 20, + TLS_TYPE_CERTIFICATE_URL = 21, + TLS_TYPE_CERTIFICATE_STATUS = 22, + TLS_TYPE_SUPPLEMENTAL_DATA = 23 +} TlsMessageType; + + +/** + * @brief Alert level + **/ + +typedef enum +{ + TLS_ALERT_LEVEL_WARNING = 1, + TLS_ALERT_LEVEL_FATAL = 2, +} TlsAlertLevel; + + +/** + * @brief Alert description + **/ + +typedef enum +{ + TLS_ALERT_CLOSE_NOTIFY = 0, + TLS_ALERT_UNEXPECTED_MESSAGE = 10, + TLS_ALERT_BAD_RECORD_MAC = 20, + TLS_ALERT_DECRYPTION_FAILED = 21, + TLS_ALERT_RECORD_OVERFLOW = 22, + TLS_ALERT_DECOMPRESSION_FAILURE = 30, + TLS_ALERT_HANDSHAKE_FAILURE = 40, + TLS_ALERT_NO_CERTIFICATE = 41, + TLS_ALERT_BAD_CERTIFICATE = 42, + TLS_ALERT_UNSUPPORTED_CERTIFICATE = 43, + TLS_ALERT_CERTIFICATE_REVOKED = 44, + TLS_ALERT_CERTIFICATE_EXPIRED = 45, + TLS_ALERT_CERTIFICATE_UNKNOWN = 46, + TLS_ALERT_ILLEGAL_PARAMETER = 47, + TLS_ALERT_UNKNOWN_CA = 48, + TLS_ALERT_ACCESS_DENIED = 49, + TLS_ALERT_DECODE_ERROR = 50, + TLS_ALERT_DECRYPT_ERROR = 51, + TLS_ALERT_EXPORT_RESTRICTION = 60, + TLS_ALERT_PROTOCOL_VERSION = 70, + TLS_ALERT_INSUFFICIENT_SECURITY = 71, + TLS_ALERT_INTERNAL_ERROR = 80, + TLS_ALERT_INAPPROPRIATE_FALLBACK = 86, + TLS_ALERT_USER_CANCELED = 90, + TLS_ALERT_NO_RENEGOTIATION = 100, + TLS_ALERT_UNSUPPORTED_EXTENSION = 110, + TLS_ALERT_CERTIFICATE_UNOBTAINABLE = 111, + TLS_ALERT_UNRECOGNIZED_NAME = 112, + TLS_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE = 113, + TLS_ALERT_BAD_CERTIFICATE_HASH_VALUE = 114, + TLS_ALERT_UNKNOWN_PSK_IDENTITY = 115 +} TlsAlertDescription; + + +/** + * @brief Compression methods + **/ + +typedef enum +{ + TLS_COMPRESSION_METHOD_NULL = 0, + TLS_COMPRESSION_METHOD_DEFLATE = 1 +} TlsCompressionMethodList; + + +/** + * @brief Key exchange methods + **/ + +typedef enum +{ + TLS_KEY_EXCH_NONE = 0, + TLS_KEY_EXCH_RSA = 1, + TLS_KEY_EXCH_DH_RSA = 2, + TLS_KEY_EXCH_DHE_RSA = 3, + TLS_KEY_EXCH_DH_DSS = 4, + TLS_KEY_EXCH_DHE_DSS = 5, + TLS_KEY_EXCH_DH_ANON = 6, + TLS_KEY_EXCH_ECDH_RSA = 7, + TLS_KEY_EXCH_ECDHE_RSA = 8, + TLS_KEY_EXCH_ECDH_ECDSA = 9, + TLS_KEY_EXCH_ECDHE_ECDSA = 10, + TLS_KEY_EXCH_ECDH_ANON = 11, + TLS_KEY_EXCH_PSK = 12, + TLS_KEY_EXCH_RSA_PSK = 13, + TLS_KEY_EXCH_DHE_PSK = 14, + TLS_KEY_EXCH_ECDHE_PSK = 15, + TLS_KEY_EXCH_SRP_SHA = 16, + TLS_KEY_EXCH_SRP_SHA_RSA = 17, + TLS_KEY_EXCH_SRP_SHA_DSS = 18 +} TlsKeyExchMethod; + + +/** + * @brief Certificate types + **/ + +typedef enum +{ + TLS_CERT_NONE = 0, + TLS_CERT_RSA_SIGN = 1, + TLS_CERT_DSS_SIGN = 2, + TLS_CERT_RSA_FIXED_DH = 3, + TLS_CERT_DSS_FIXED_DH = 4, + TLS_CERT_RSA_EPHEMERAL_DH = 5, + TLS_CERT_DSS_EPHEMERAL_DH = 6, + TLS_CERT_FORTEZZA_DMS = 20, + TLS_CERT_ECDSA_SIGN = 64, + TLS_CERT_RSA_FIXED_ECDH = 65, + TLS_CERT_ECDSA_FIXED_ECDH = 66 +} TlsCertificateType; + + +/** + * @brief Hash algorithms + **/ + +typedef enum +{ + TLS_HASH_ALGO_NONE = 0, + TLS_HASH_ALGO_MD5 = 1, + TLS_HASH_ALGO_SHA1 = 2, + TLS_HASH_ALGO_SHA224 = 3, + TLS_HASH_ALGO_SHA256 = 4, + TLS_HASH_ALGO_SHA384 = 5, + TLS_HASH_ALGO_SHA512 = 6 +} TlsHashAlgo; + + +/** + * @brief Signature algorithms + **/ + +typedef enum +{ + TLS_SIGN_ALGO_ANONYMOUS = 0, + TLS_SIGN_ALGO_RSA = 1, + TLS_SIGN_ALGO_DSA = 2, + TLS_SIGN_ALGO_ECDSA = 3 +} TlsSignatureAlgo; + + +/** + * @brief TLS extension types + **/ + +typedef enum +{ + TLS_EXT_SERVER_NAME = 0, + TLS_EXT_MAX_FRAGMENT_LENGTH = 1, + TLS_EXT_CLIENT_CERTIFICATE_URL = 2, + TLS_EXT_TRUSTED_CA_KEYS = 3, + TLS_EXT_TRUNCATED_HMAC = 4, + TLS_EXT_STATUS_REQUEST = 5, + TLS_EXT_USER_MAPPING = 6, + TLS_EXT_CLIENT_AUTHZ = 7, + TLS_EXT_SERVER_AUTHZ = 8, + TLS_EXT_CERT_TYPE = 9, + TLS_EXT_ELLIPTIC_CURVES = 10, + TLS_EXT_EC_POINT_FORMATS = 11, + TLS_EXT_SRP = 12, + TLS_EXT_SIGNATURE_ALGORITHMS = 13, + TLS_EXT_USE_SRTP = 14, + TLS_EXT_HEARTBEAT = 15, + TLS_EXT_ALPN = 16, + TLS_EXT_SESSION_TICKET = 35, + TLS_EXT_RENEGOTIATION_INFO = 65281 +} TlsExtensionType; + + +/** + * @brief Name type + **/ + +typedef enum +{ + TLS_NAME_TYPE_HOSTNAME = 0 +} TlsNameType; + + +/** + * @brief EC named curves + **/ + +typedef enum +{ + TLS_EC_CURVE_NONE = 0, + TLS_EC_CURVE_SECT163K1 = 1, //RFC 4492 + TLS_EC_CURVE_SECT163R1 = 2, //RFC 4492 + TLS_EC_CURVE_SECT163R2 = 3, //RFC 4492 + TLS_EC_CURVE_SECT193R1 = 4, //RFC 4492 + TLS_EC_CURVE_SECT193R2 = 5, //RFC 4492 + TLS_EC_CURVE_SECT233K1 = 6, //RFC 4492 + TLS_EC_CURVE_SECT233R1 = 7, //RFC 4492 + TLS_EC_CURVE_SECT239K1 = 8, //RFC 4492 + TLS_EC_CURVE_SECT283K1 = 9, //RFC 4492 + TLS_EC_CURVE_SECT283R1 = 10, //RFC 4492 + TLS_EC_CURVE_SECT409K1 = 11, //RFC 4492 + TLS_EC_CURVE_SECT409R1 = 12, //RFC 4492 + TLS_EC_CURVE_SECT571K1 = 13, //RFC 4492 + TLS_EC_CURVE_SECT571R1 = 14, //RFC 4492 + TLS_EC_CURVE_SECP160K1 = 15, //RFC 4492 + TLS_EC_CURVE_SECP160R1 = 16, //RFC 4492 + TLS_EC_CURVE_SECP160R2 = 17, //RFC 4492 + TLS_EC_CURVE_SECP192K1 = 18, //RFC 4492 + TLS_EC_CURVE_SECP192R1 = 19, //RFC 4492 + TLS_EC_CURVE_SECP224K1 = 20, //RFC 4492 + TLS_EC_CURVE_SECP224R1 = 21, //RFC 4492 + TLS_EC_CURVE_SECP256K1 = 22, //RFC 4492 + TLS_EC_CURVE_SECP256R1 = 23, //RFC 4492 + TLS_EC_CURVE_SECP384R1 = 24, //RFC 4492 + TLS_EC_CURVE_SECP521R1 = 25, //RFC 4492 + TLS_EC_CURVE_BRAINPOOLP256R1 = 26, //RFC 7027 + TLS_EC_CURVE_BRAINPOOLP384R1 = 27, //RFC 7027 + TLS_EC_CURVE_BRAINPOOLP512R1 = 28, //RFC 7027 + TLS_EC_CURVE_ECDH_X25519 = 29, //RFC draft + TLS_EC_CURVE_ECDH_X448 = 30, //RFC draft + TLS_EC_CURVE_FFDHE2048 = 256, //RFC 7919 + TLS_EC_CURVE_FFDHE3072 = 257, //RFC 7919 + TLS_EC_CURVE_FFDHE4096 = 258, //RFC 7919 + TLS_EC_CURVE_FFDHE6144 = 259, //RFC 7919 + TLS_EC_CURVE_FFDHE8192 = 260, //RFC 7919 + TLS_EC_CURVE_ARBITRARY_EXPLICIT_PRIME = 65281, //RFC 4492 + TLS_EC_CURVE_ARBITRARY_EXPLICIT_CHAR2 = 65282 //RFC 4492 +} TlsEcNamedCurve; + + +/** + * @brief EC point formats + **/ + +typedef enum +{ + TLS_EC_POINT_FORMAT_UNCOMPRESSED = 0, + TLS_EC_POINT_FORMAT_ANSIX962_COMPRESSED_PRIME = 1, + TLS_EC_POINT_FORMAT_ANSIX962_COMPRESSED_CHAR2 = 2 +} TlsEcPointFormat; + + +/** + * @brief EC curve types + **/ + +typedef enum +{ + TLS_EC_CURVE_TYPE_EXPLICIT_PRIME = 1, + TLS_EC_CURVE_TYPE_EXPLICIT_CHAR2 = 2, + TLS_EC_CURVE_TYPE_NAMED_CURVE = 3 +} TlsEcCurveType; + + +/** + * @brief TLS FSM states + **/ + +typedef enum +{ + TLS_STATE_INIT = 0, + TLS_STATE_CLIENT_HELLO = 1, + TLS_STATE_SERVER_HELLO = 2, + TLS_STATE_SERVER_CERTIFICATE = 3, + TLS_STATE_SERVER_KEY_EXCHANGE = 4, + TLS_STATE_CERTIFICATE_REQUEST = 5, + TLS_STATE_SERVER_HELLO_DONE = 6, + TLS_STATE_CLIENT_CERTIFICATE = 7, + TLS_STATE_CLIENT_KEY_EXCHANGE = 8, + TLS_STATE_CERTIFICATE_VERIFY = 9, + TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC = 10, + TLS_STATE_CLIENT_FINISHED = 11, + TLS_STATE_SERVER_CHANGE_CIPHER_SPEC = 12, + TLS_STATE_SERVER_FINISHED = 13, + TLS_STATE_APPLICATION_DATA = 14, + TLS_STATE_CLOSING = 15, + TLS_STATE_CLOSED = 16 +} TlsState; + + +//CodeWarrior or Win32 compiler? +#if defined(__CWCC__) || defined(_WIN32) + #pragma pack(push, 1) +#endif + + +/** + * @brief Random structure + **/ + +typedef __start_packed struct +{ + uint32_t gmtUnixTime; //0-3 + uint8_t randomBytes[28]; //4-31 +} __end_packed TlsRandom; + + +/** + * @brief Cipher suite + **/ + +typedef uint16_t TlsCipherSuite; + + +/** + * @brief Cipher suites + **/ + +typedef __start_packed struct +{ + uint16_t length; //0-1 + uint16_t value[]; //2 +} __end_packed TlsCipherSuites; + + +/** + * @brief Compression method + **/ + +typedef uint8_t TlsCompressionMethod; + + +/** + * @brief Compression methods + **/ + +typedef __start_packed struct +{ + uint8_t length; //0 + uint8_t value[]; //1 +} __end_packed TlsCompressionMethods; + + +/** + * @brief Signature algorithm + **/ + +typedef __start_packed struct +{ + uint8_t hash; //0 + uint8_t signature; //1 +} __end_packed TlsSignHashAlgo; + + +/** + * @brief List of signature algorithms + **/ + +typedef __start_packed struct +{ + uint16_t length; //0-1 + TlsSignHashAlgo value[]; //2 +} __end_packed TlsSignHashAlgos; + + +/** + * @brief List of certificate authorities + **/ + +typedef __start_packed struct +{ + uint16_t length; //0-1 + uint8_t value[]; //2 +} __end_packed TlsCertAuthorities; + + +/** + * @brief TLS extension + **/ + +typedef __start_packed struct +{ + uint16_t type; //0-1 + uint16_t length; //2-3 + uint8_t value[]; //4 +} __end_packed TlsExtension; + + +/** + * @brief List of TLS extensions + **/ + +typedef __start_packed struct +{ + uint16_t length; //0-1 + uint8_t value[]; //2 +} __end_packed TlsExtensions; + + +/** + * @brief Server name + **/ + +typedef __start_packed struct +{ + uint8_t type; //0 + uint16_t length; //1-2 + char_t hostname[]; //2 +} __end_packed TlsServerName; + + +/** + * @brief List of server names + **/ + +typedef __start_packed struct +{ + uint16_t length; //0-1 + uint8_t value[]; //2 +} __end_packed TlsServerNameList; + + +/** + * @brief Protocol name + **/ + +typedef __start_packed struct +{ + uint8_t length; //0 + char_t value[]; //1 +} __end_packed TlsProtocolName; + + +/** + * @brief List of protocol names + **/ + +typedef __start_packed struct +{ + uint16_t length; //0-1 + uint8_t value[]; //2 +} __end_packed TlsProtocolNameList; + + +/** + * @brief List of supported elliptic curves + **/ + +typedef __start_packed struct +{ + uint16_t length; //0-1 + uint16_t value[]; //2 +} __end_packed TlsEllipticCurveList; + + +/** + * @brief List of supported EC point formats + **/ + +typedef __start_packed struct +{ + uint8_t length; //0 + uint8_t value[]; //1 +} __end_packed TlsEcPointFormatList; + + +/** + * @brief PSK identity + **/ + +typedef __start_packed struct +{ + uint16_t length; //0-1 + uint8_t value[]; //2 +} __end_packed TlsPskIdentity; + + +/** + * @brief PSK identity hint + **/ + +typedef __start_packed struct +{ + uint16_t length; //0-1 + uint8_t value[]; //2 +} __end_packed TlsPskIdentityHint; + + +/** + * @brief Digitally-signed element (SSL 3.0, TLS 1.0 and TLS 1.1) + **/ + +typedef __start_packed struct +{ + uint16_t length; //0-1 + uint8_t value[]; //2 +} __end_packed TlsDigitalSignature; + + +/** + * @brief Digitally-signed element (TLS 1.2) + **/ + +typedef __start_packed struct +{ + TlsSignHashAlgo algorithm; //0-1 + uint16_t length; //2-3 + uint8_t value[]; //4 +} __end_packed TlsDigitalSignature2; + + +/** + * @brief General format of TLS records + **/ + +typedef __start_packed struct +{ + uint8_t type; //0 + uint16_t version; //1-2 + uint16_t length; //3-4 + uint8_t data[]; //5 +} __end_packed TlsRecord; + + +/** + * @brief Handshake message + **/ + +typedef __start_packed struct +{ + uint8_t msgType; //0 + uint8_t length[3]; //1-3 + uint8_t data[]; //4 +} __end_packed TlsHandshake; + + +/** + * @brief ClientHello message + **/ + +typedef __start_packed struct +{ + uint8_t msgType; //0 + uint8_t length[3]; //1-3 + uint16_t clientVersion; //4-5 + TlsRandom random; //6-37 + uint8_t sessionIdLength; //38 + uint8_t sessionId[]; //39 +} __end_packed TlsClientHello; + + +/** + * @brief ServerHello message + **/ + +typedef __start_packed struct +{ + uint8_t msgType; //0 + uint8_t length[3]; //1-3 + uint16_t serverVersion; //4-5 + TlsRandom random; //6-37 + uint8_t sessionIdLength; //38 + uint8_t sessionId[]; //39 +} __end_packed TlsServerHello; + + +/** + * @brief Certificate message + **/ + +typedef __start_packed struct +{ + uint8_t msgType; //0 + uint8_t length[3]; //1-3 + uint8_t certificateListLength[3]; //4-6 + uint8_t certificateList[]; //7 +} __end_packed TlsCertificate; + + +/** + * @brief ServerKeyExchange message + **/ + +typedef __start_packed struct +{ + uint8_t msgType; //0 + uint8_t length[3]; //1-3 + uint8_t data[]; //4 +} __end_packed TlsServerKeyExchange; + + +/** + * @brief CertificateRequest message + **/ + +typedef __start_packed struct +{ + uint8_t msgType; //0 + uint8_t length[3]; //1-3 + uint8_t certificateTypesLength; //4 + uint8_t certificateTypes[]; //5 +} __end_packed TlsCertificateRequest; + + +/** + * @brief ServerHelloDone message + **/ + +typedef __start_packed struct +{ + uint8_t msgType; //0 + uint8_t length[3]; //1-3 +} __end_packed TlsServerHelloDone; + + +/** + * @brief ClientKeyExchange message + **/ + +typedef __start_packed struct +{ + uint8_t msgType; //0 + uint8_t length[3]; //1-3 + uint8_t data[]; //4 +} __end_packed TlsClientKeyExchange; + + +/** + * @brief CertificateVerify message + **/ + +typedef __start_packed struct +{ + uint8_t msgType; //0 + uint8_t length[3]; //1-3 + uint8_t signature[]; //4 +} __end_packed TlsCertificateVerify; + + +/** + * @brief Finished message + **/ + +typedef __start_packed struct +{ + uint8_t msgType; //0 + uint8_t length[3]; //1-3 + uint8_t verifyData[]; //4 +} __end_packed TlsFinished; + + +/** + * @brief ChangeCipherSpec message + **/ + +typedef __start_packed struct +{ + uint8_t type; //0 +} __end_packed TlsChangeCipherSpec; + + +/** + * @brief Alert message + **/ + +typedef __start_packed struct +{ + uint8_t level; //0 + uint8_t description; //1 +} __end_packed TlsAlert; + + +//CodeWarrior or Win32 compiler? +#if defined(__CWCC__) || defined(_WIN32) + #pragma pack(pop) +#endif + + +/** + * @brief Sequence number + **/ + +typedef uint8_t TlsSequenceNumber[8]; + + +/** + * @brief Handle for I/O operations + **/ + +typedef void *TlsIoHandle; + + +/** + * @brief Send callback function + **/ + +typedef error_t (*TlsIoSendCallback)(TlsIoHandle handle, + const void *data, size_t length, size_t *written, uint_t flags); + + +/** + * @brief Receive callback function + **/ + +typedef error_t (*TlsIoReceiveCallback)(TlsIoHandle handle, + void *data, size_t size, size_t *received, uint_t flags); + + +/** + * @brief Pre-shared key callback function + **/ + +typedef error_t (*TlsPskCallback)(TlsContext *context, + const char_t *pskIdentity); + + +/** + * @brief Structure describing a cipher suite + **/ + +typedef struct +{ + uint16_t identifier; + const char_t *name; + TlsKeyExchMethod keyExchMethod; + const CipherAlgo *cipherAlgo; + CipherMode cipherMode; + const HashAlgo *hashAlgo; + const HashAlgo *prfHashAlgo; + uint8_t macKeyLen; + uint8_t encKeyLen; + uint8_t fixedIvLen; + uint8_t recordIvLen; + uint8_t authTagLen; + uint8_t verifyDataLen; +} TlsCipherSuiteInfo; + + +/** + * @brief TLS session + **/ + +typedef struct +{ + uint8_t id[32]; ///<Session identifier + size_t idLength; ///<Length of the session identifier + systime_t timestamp; ///<Time stamp to manage entry lifetime + uint16_t cipherSuite; ///<Cipher suite identifier + uint8_t compressionMethod; ///<Compression method + uint8_t masterSecret[48]; ///<Master secret +} TlsSession; + + +/** + * @brief Session cache + **/ + +typedef struct +{ + OsMutex mutex; ///<Mutex preventing simultaneous access to the cache + uint_t size; ///<Maximum number of entries + TlsSession sessions[]; ///<Cache entries +} TlsCache; + + +/** + * @brief Certificate descriptor + **/ + +typedef struct +{ + const char_t *certChain; ///<End entity certificate chain (PEM format) + size_t certChainLength; ///<Length of the certificate chain + const char_t *privateKey; ///<Private key (PEM format) + size_t privateKeyLength; ///<Length of the private key + TlsCertificateType type; ///<End entity certificate type + TlsSignatureAlgo signAlgo; ///<Signature algorithm used to sign the end entity certificate + TlsHashAlgo hashAlgo; ///<Hash algorithm used to sign the end entity certificate + TlsEcNamedCurve namedCurve; ///<Named curve used to generate the EC public key +} TlsCertDesc; + + +/** + * @brief TLS context + * + * An opaque data structure that represents a TLS connection + * + **/ + +struct _TlsContext +{ + TlsState state; ///<TLS handshake finite state machine + TlsConnectionEnd entity; ///<Client or server operation + + TlsIoHandle handle; ///<Handle for I/O operations + TlsIoSendCallback sendCallback; ///<Send callback function + TlsIoReceiveCallback receiveCallback; ///<Receive callback function + const PrngAlgo *prngAlgo; ///<Pseudo-random number generator to be used + void *prngContext; ///<Pseudo-random number generator context + + const uint16_t *cipherSuites; ///<List of supported cipher suites + uint_t numCipherSuites; ///<Number of cipher suites in the list + + char_t *serverName; ///<Fully qualified DNS hostname of the server + +#if (TLS_ALPN_SUPPORT == ENABLED) + char_t *protocolList; ///<List of supported ALPN protocols +#endif + +#if (TLS_PSK_SUPPORT == ENABLED || TLS_RSA_PSK_SUPPORT == ENABLED || \ + TLS_DHE_PSK_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED) + char_t *psk; ///<Pre-shared key + size_t pskLen; ///<Length of the pre-shared key, in bytes + char_t *pskIdentity; ///<PSK identity + char_t *pskIdentityHint; ///<PSK identity hint + TlsPskCallback pskCallback; ///<PSK callback function +#endif + +#if (TLS_DH_ANON_SUPPORT == ENABLED || TLS_DHE_RSA_SUPPORT == ENABLED || \ + TLS_DHE_DSS_SUPPORT == ENABLED || TLS_DHE_PSK_SUPPORT == ENABLED) + DhContext dhContext; ///<Diffie-Hellman context +#endif + +#if (TLS_ECDH_ANON_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED || \ + TLS_ECDHE_ECDSA_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED) + EcdhContext ecdhContext; ///<ECDH context +#endif + + TlsCertDesc certs[TLS_MAX_CERTIFICATES]; //End entity certificates + uint_t numCerts; //Number of certificates available + TlsCertDesc *cert; //Pointer to the currently selected certificate + + const char_t *trustedCaList; ///<List of trusted CA (PEM format) + size_t trustedCaListLen; ///<Number of trusted CA in the list + + TlsCertificateType peerCertType; ///<Peer's certificate type + +#if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_SUPPORT == ENABLED || \ + TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED) + RsaPublicKey peerRsaPublicKey; ///<Peer's RSA public key +#endif + +#if (TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_DHE_DSS_SUPPORT == ENABLED) + DsaPublicKey peerDsaPublicKey; ///<Peer's DSA public key +#endif + +#if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED) + EcDomainParameters peerEcParams; ///<Peer's EC domain parameters + EcPoint peerEcPublicKey; ///<Peer's EC public key +#endif + + TlsCache *cache; ///<TLS session cache + + uint8_t sessionId[32]; ///<Session identifier + size_t sessionIdLen; ///<Length of the session identifier + + uint16_t clientVersion; ///<Latest version supported by the client + uint16_t version; ///<Negotiated TLS version + uint16_t cipherSuite; ///<Negotiated cipher suite + uint8_t compressionMethod; ///<Negotiated compression algorithm + uint16_t namedCurve; ///<Named curve + + TlsHashAlgo signHashAlgo; ///<Hash algorithm used for signing + TlsKeyExchMethod keyExchMethod; ///<Key exchange method + const CipherAlgo *cipherAlgo; ///<Bulk cipher algorithm + CipherMode cipherMode; ///<Cipher mode of operation + const HashAlgo *hashAlgo; ///<Hash algorithm for MAC operations + const HashAlgo *prfHashAlgo; ///<Hash algorithm for PRF operations + size_t macKeyLen; ///<Number of bytes that are used for generating MAC keys + size_t encKeyLen; ///<Number of bytes that are used for generating encryption keys + size_t fixedIvLen; ///<Amount of data needed to be generated for the IV + size_t recordIvLen; ///<Length of the IV + size_t authTagLen; ///<Length of the authentication tag + size_t verifyDataLen; ///<Length of the verify data + +//#if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1) + Md5Context *handshakeMd5Context; ///<MD5 context used to compute verify data + Sha1Context *handshakeSha1Context; ///<SHA-1 context used to compute verify data +//#endif + +//#if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_2) + HashContext *handshakeHashContext; ///<Hash context used to compute verify data (TLS 1.2) +//#endif + + uint8_t verifyData[64]; ///<Verify data + + bool_t ecPointFormatExtFound; ///<The EcPointFormats extension has been received + + TlsClientAuthMode clientAuthMode; ///<Client authentication mode + bool_t clientCertRequested; ///<This flag tells whether the client certificate is requested + + bool_t resume; ///<The connection is established by resuming a session + bool_t changeCipherSpecSent; ///<A ChangeCipherSpec message has been sent + bool_t changeCipherSpecReceived; ///<A ChangeCipherSpec message has been received from the peer + bool_t fatalAlertSent; ///<A fatal alert message has been sent + bool_t fatalAlertReceived; ///<A fatal alert message has been received from the peer + bool_t closeNotifySent; ///<A closure alert has been sent + bool_t closeNotifyReceived; ///<A closure alert has been received from the peer + + HmacContext hmacContext; ///<HMAC context + void *writeCipherContext; ///<Bulk cipher context for write operations + void *readCipherContext; ///<Bulk cipher context for read operations +#if (TLS_GCM_CIPHER_SUPPORT == ENABLED) + GcmContext *writeGcmContext; ///<GCM context for write operations + GcmContext *readGcmContext; ///<GCM context for read operations +#endif + + uint8_t *txBuffer; ///<TX buffer + size_t txBufferSize; ///<TX buffer size + TlsContentType txBufferType; ///<Type of data that resides in the TX buffer + size_t txBufferLen; ///<Number of bytes that are pending to be sent + size_t txBufferPos; ///<Current position in TX buffer + size_t txRecordMaxLen; ///<Maximum plaintext fragment length + size_t txRecordLen; ///<Length of the TLS record + size_t txRecordPos; ///<Current position in the TLS record + + uint8_t *rxBuffer; ///<RX buffer + size_t rxBufferSize; ///<RX buffer size + TlsContentType rxBufferType; ///<Type of data that resides in the RX buffer + size_t rxBufferLen; ///<Number of bytes available for reading + size_t rxBufferPos; ///<Current position in RX buffer + size_t rxRecordMaxLen; ///<Maximum plaintext fragment length + size_t rxRecordLen; ///<Length of the TLS record + size_t rxRecordPos; ///<Current position in the TLS record + + union + { + struct + { + TlsRandom clientRandom; ///<Client random value + TlsRandom serverRandom; ///<Server random value + }; + uint8_t random[64]; + }; + + uint8_t premasterSecret[TLS_MAX_PREMASTER_SECRET_SIZE]; ///<Premaster secret + size_t premasterSecretLen; ///<Length of the premaster secret + uint8_t masterSecret[48]; ///<Master secret + uint8_t keyBlock[192]; ///<Key material + uint8_t *writeMacKey; ///<Write MAC key + uint8_t *readMacKey; ///<Read MAC key + uint8_t *writeEncKey; ///<Encryption key that serves for write operations + uint8_t *readEncKey; ///<Encryption key that serves for read operations + uint8_t *writeIv; ///<Write IV + uint8_t *readIv; ///<Read IV + + TlsSequenceNumber writeSeqNum; ///<Write sequence number + TlsSequenceNumber readSeqNum; ///<Read sequence number +}; + + +//TLS application programming interface (API) +TlsContext *tlsInit(void); + +error_t tlsSetIoCallbacks(TlsContext *context, TlsIoHandle handle, + TlsIoSendCallback sendCallback, TlsIoReceiveCallback receiveCallback); + +error_t tlsSetConnectionEnd(TlsContext *context, TlsConnectionEnd entity); +error_t tlsSetPrng(TlsContext *context, const PrngAlgo *prngAlgo, void *prngContext); +error_t tlsSetServerName(TlsContext *context, const char_t *serverName); +error_t tlsSetCache(TlsContext *context, TlsCache *cache); +error_t tlsSetClientAuthMode(TlsContext *context, TlsClientAuthMode mode); + +error_t tlsSetBufferSize(TlsContext *context, + size_t txBufferSize, size_t rxBufferSize); + +error_t tlsSetCipherSuites(TlsContext *context, + const uint16_t *cipherSuites, uint_t length); + +error_t tlsSetDhParameters(TlsContext *context, + const char_t *params, size_t length); + +error_t tlsSetAlpnProtocolList(TlsContext *context, const char_t *protocolList); +const char_t *tlsGetAlpnProtocol(TlsContext *context); + +error_t tlsSetPsk(TlsContext *context, const uint8_t *psk, size_t pskLength); +error_t tlsSetPskIdentity(TlsContext *context, const char_t *pskIdentity); +error_t tlsSetPskIdentityHint(TlsContext *context, const char_t *pskIdentityHint); +error_t tlsSetPskCallback(TlsContext *context, TlsPskCallback pskCallback); + +error_t tlsSetTrustedCaList(TlsContext *context, + const char_t *trustedCaList, size_t length); + +error_t tlsAddCertificate(TlsContext *context, const char_t *certChain, + size_t certChainLength, const char_t *privateKey, size_t privateKeyLength); + +error_t tlsConnect(TlsContext *context); + +error_t tlsWrite(TlsContext *context, const void *data, + size_t length, size_t *written, uint_t flags); + +error_t tlsRead(TlsContext *context, void *data, + size_t size, size_t *received, uint_t flags); + +error_t tlsShutdown(TlsContext *context); +error_t tlsShutdownEx(TlsContext *context, bool_t waitForCloseNotify); + +void tlsFree(TlsContext *context); + +error_t tlsSaveSession(const TlsContext *context, TlsSession *session); +error_t tlsRestoreSession(TlsContext *context, const TlsSession *session); + +TlsCache *tlsInitCache(uint_t size); +void tlsFreeCache(TlsCache *cache); + +#endif +