/* Cipher SUITES */
#define ENTRY( name, block_algorithm, kx_algorithm, mac_algorithm, min_version, dtls_version ) \
- { #name, name, block_algorithm, kx_algorithm, mac_algorithm, min_version, dtls_version, GNUTLS_MAC_SHA256}
+ { #name, name, block_algorithm, kx_algorithm, mac_algorithm, min_version, dtls_version, GNUTLS_MAC_SHA256, NONCE_IS_SENT}
#define ENTRY_PRF( name, block_algorithm, kx_algorithm, mac_algorithm, min_version, dtls_version, prf ) \
- { #name, name, block_algorithm, kx_algorithm, mac_algorithm, min_version, dtls_version, prf}
-
-typedef struct {
- const char *name;
- const uint8_t id[2];
- gnutls_cipher_algorithm_t block_algorithm;
- gnutls_kx_algorithm_t kx_algorithm;
- gnutls_mac_algorithm_t mac_algorithm;
- gnutls_protocol_t min_version; /* this cipher suite is supported
- * from 'version' and above;
- */
- gnutls_protocol_t min_dtls_version; /* DTLS min version */
- gnutls_mac_algorithm_t prf;
-} gnutls_cipher_suite_entry;
+ { #name, name, block_algorithm, kx_algorithm, mac_algorithm, min_version, dtls_version, prf, NONCE_IS_SENT}
+#define ENTRY_CNONCE( name, block_algorithm, kx_algorithm, mac_algorithm, min_version, dtls_version ) \
+ { #name, name, block_algorithm, kx_algorithm, mac_algorithm, min_version, dtls_version, GNUTLS_MAC_SHA256, NONCE_IS_COUNTER}
/* RSA with NULL cipher and MD5 MAC
* for test purposes.
#define GNUTLS_DH_ANON_AES_128_CBC_SHA256 { 0x00, 0x6C }
#define GNUTLS_DH_ANON_AES_256_CBC_SHA256 { 0x00, 0x6D }
+/* draft-mavrogiannopoulos-chacha-tls-04 */
+#define GNUTLS_RSA_CHACHA20_POLY1305 { 0xFF, 0x30 }
+#define GNUTLS_ECDHE_RSA_CHACHA20_POLY1305 { 0xFF, 0x31 }
+#define GNUTLS_ECDHE_ECDSA_CHACHA20_POLY1305 { 0xFF, 0x32 }
+#define GNUTLS_DHE_RSA_CHACHA20_POLY1305 { 0xFF, 0x33 }
+#define GNUTLS_DHE_PSK_CHACHA20_POLY1305 { 0xFF, 0x34 }
+#define GNUTLS_PSK_CHACHA20_POLY1305 { 0xFF, 0x35 }
+#define GNUTLS_ECDHE_PSK_CHACHA20_POLY1305 { 0xFF, 0x36 }
+#define GNUTLS_RSA_PSK_CHACHA20_POLY1305 { 0xFF, 0x37 }
+
/* PSK (not in TLS 1.0)
* draft-ietf-tls-psk:
*/
#define GNUTLS_ECDHE_PSK_NULL_SHA256 { 0xC0, 0x3A }
#define GNUTLS_ECDHE_PSK_NULL_SHA384 { 0xC0, 0x3B }
-#define CIPHER_SUITES_COUNT (sizeof(cs_algorithms)/sizeof(gnutls_cipher_suite_entry)-1)
+#define CIPHER_SUITES_COUNT (sizeof(cs_algorithms)/sizeof(gnutls_cipher_suite_entry_st)-1)
/* The following is a potential list of ciphersuites. For the options to be
* available, the ciphers and MACs must be available to gnutls as well.
*/
-static const gnutls_cipher_suite_entry cs_algorithms[] = {
+static const gnutls_cipher_suite_entry_st cs_algorithms[] = {
/* RSA-NULL */
ENTRY(GNUTLS_RSA_NULL_MD5,
GNUTLS_CIPHER_NULL,
GNUTLS_CIPHER_CAMELLIA_256_GCM, GNUTLS_KX_RSA,
GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
GNUTLS_DTLS1_2, GNUTLS_MAC_SHA384),
+ ENTRY_CNONCE(GNUTLS_RSA_CHACHA20_POLY1305,
+ GNUTLS_CIPHER_CHACHA20_POLY1305, GNUTLS_KX_RSA,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
+ GNUTLS_DTLS1_2),
/* CCM */
ENTRY(GNUTLS_RSA_AES_128_CCM,
GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
GNUTLS_DTLS1_2),
- ENTRY(GNUTLS_PSK_AES_128_CCM,
- GNUTLS_CIPHER_AES_128_CCM, GNUTLS_KX_PSK,
- GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
- GNUTLS_DTLS1_2),
- ENTRY(GNUTLS_PSK_AES_256_CCM,
- GNUTLS_CIPHER_AES_256_CCM, GNUTLS_KX_PSK,
- GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
- GNUTLS_DTLS1_2),
- ENTRY(GNUTLS_DHE_PSK_AES_128_CCM,
- GNUTLS_CIPHER_AES_128_CCM, GNUTLS_KX_DHE_PSK,
- GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
- GNUTLS_DTLS1_2),
- ENTRY(GNUTLS_DHE_PSK_AES_256_CCM,
- GNUTLS_CIPHER_AES_256_CCM, GNUTLS_KX_DHE_PSK,
- GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
- GNUTLS_DTLS1_2),
/* DHE_DSS */
#ifdef ENABLE_DHE
GNUTLS_CIPHER_CAMELLIA_256_GCM, GNUTLS_KX_DHE_RSA,
GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
GNUTLS_DTLS1_2, GNUTLS_MAC_SHA384),
+
+ ENTRY_CNONCE(GNUTLS_DHE_RSA_CHACHA20_POLY1305,
+ GNUTLS_CIPHER_CHACHA20_POLY1305, GNUTLS_KX_DHE_RSA,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2, GNUTLS_DTLS1_2),
+
#endif /* DHE */
#ifdef ENABLE_ECDHE
/* ECC-RSA */
GNUTLS_CIPHER_CAMELLIA_256_GCM, GNUTLS_KX_ECDHE_RSA,
GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
GNUTLS_DTLS1_2, GNUTLS_MAC_SHA384),
+
+ ENTRY_CNONCE(GNUTLS_ECDHE_RSA_CHACHA20_POLY1305,
+ GNUTLS_CIPHER_CHACHA20_POLY1305, GNUTLS_KX_ECDHE_RSA,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
+ GNUTLS_DTLS1_2),
+
+ ENTRY_CNONCE(GNUTLS_ECDHE_ECDSA_CHACHA20_POLY1305,
+ GNUTLS_CIPHER_CHACHA20_POLY1305, GNUTLS_KX_ECDHE_RSA,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
+ GNUTLS_DTLS1_2),
#endif
#ifdef ENABLE_PSK
/* ECC - PSK */
GNUTLS_CIPHER_CAMELLIA_256_GCM, GNUTLS_KX_DHE_PSK,
GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
GNUTLS_DTLS1_2, GNUTLS_MAC_SHA384),
+
+ ENTRY(GNUTLS_PSK_AES_128_CCM,
+ GNUTLS_CIPHER_AES_128_CCM, GNUTLS_KX_PSK,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
+ GNUTLS_DTLS1_2),
+ ENTRY(GNUTLS_PSK_AES_256_CCM,
+ GNUTLS_CIPHER_AES_256_CCM, GNUTLS_KX_PSK,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
+ GNUTLS_DTLS1_2),
+ ENTRY(GNUTLS_DHE_PSK_AES_128_CCM,
+ GNUTLS_CIPHER_AES_128_CCM, GNUTLS_KX_DHE_PSK,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
+ GNUTLS_DTLS1_2),
+ ENTRY(GNUTLS_DHE_PSK_AES_256_CCM,
+ GNUTLS_CIPHER_AES_256_CCM, GNUTLS_KX_DHE_PSK,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
+ GNUTLS_DTLS1_2),
+ ENTRY_CNONCE(GNUTLS_DHE_PSK_CHACHA20_POLY1305,
+ GNUTLS_CIPHER_CHACHA20_POLY1305, GNUTLS_KX_DHE_PSK,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2, GNUTLS_DTLS1_2),
+ ENTRY_CNONCE(GNUTLS_ECDHE_PSK_CHACHA20_POLY1305,
+ GNUTLS_CIPHER_CHACHA20_POLY1305, GNUTLS_KX_ECDHE_PSK,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2, GNUTLS_DTLS1_2),
+
+ ENTRY_CNONCE(GNUTLS_RSA_PSK_CHACHA20_POLY1305,
+ GNUTLS_CIPHER_CHACHA20_POLY1305, GNUTLS_KX_RSA_PSK,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2, GNUTLS_DTLS1_2),
+
+ ENTRY_CNONCE(GNUTLS_PSK_CHACHA20_POLY1305,
+ GNUTLS_CIPHER_CHACHA20_POLY1305, GNUTLS_KX_PSK,
+ GNUTLS_MAC_AEAD, GNUTLS_TLS1_2, GNUTLS_DTLS1_2),
+
#endif
#ifdef ENABLE_ANON
/* DH_ANON */
GNUTLS_MAC_SHA1, GNUTLS_SSL3,
GNUTLS_DTLS_VERSION_MIN),
#endif
+
+
{0, {0, 0}, 0, 0, 0, 0, 0, 0}
};
#define CIPHER_SUITE_LOOP(b) { \
- const gnutls_cipher_suite_entry *p; \
+ const gnutls_cipher_suite_entry_st *p; \
for(p = cs_algorithms; p->name != NULL; p++) { b ; } }
#define CIPHER_SUITE_ALG_LOOP(a, suite) \
/* Cipher Suite's functions */
+const gnutls_cipher_suite_entry_st *ciphersuite_to_entry(const uint8_t suite[2])
+{
+ CIPHER_SUITE_ALG_LOOP(return p, suite);
+ return NULL;
+}
+
const cipher_entry_st *_gnutls_cipher_suite_get_cipher_algo(const uint8_t
suite[2])
{
}
-static const gnutls_cipher_suite_entry
+static const gnutls_cipher_suite_entry_st
*cipher_suite_get(gnutls_kx_algorithm_t kx_algorithm,
gnutls_cipher_algorithm_t cipher_algorithm,
gnutls_mac_algorithm_t mac_algorithm)
{
- const gnutls_cipher_suite_entry *ret = NULL;
+ const gnutls_cipher_suite_entry_st *ret = NULL;
CIPHER_SUITE_LOOP(
if (kx_algorithm == p->kx_algorithm &&
int alg_size = MAX_ALGOS;
uint8_t new_list[cipher_suites_size]; /* it's safe to use that size because it's provided by _gnutls_supported_ciphersuites() */
int i, new_list_size = 0;
- const gnutls_cipher_suite_entry *entry;
+ const gnutls_cipher_suite_entry_st *entry;
const uint8_t *cp;
/* if we should use a specific certificate,
gnutls_mac_algorithm_t
mac_algorithm)
{
- const gnutls_cipher_suite_entry *ce;
+ const gnutls_cipher_suite_entry_st *ce;
ce = cipher_suite_get(kx_algorithm, cipher_algorithm,
mac_algorithm);
gnutls_mac_algorithm_t mac_algorithm,
uint8_t suite[2])
{
- const gnutls_cipher_suite_entry *ce;
+ const gnutls_cipher_suite_entry_st *ce;
ce = cipher_suite_get(kx_algorithm, cipher_algorithm,
mac_algorithm);
{
unsigned int i, ret_count, j, z, k = 0;
- const gnutls_cipher_suite_entry *ce;
+ const gnutls_cipher_suite_entry_st *ce;
const version_entry_st *version = get_version(session);
unsigned int is_dtls = IS_DTLS(session);
inline static int
calc_enc_length_stream(gnutls_session_t session, int data_size,
int hash_size, unsigned auth_cipher,
- unsigned exp_iv_size)
+ unsigned exp_iv_size, unsigned send_nonce)
{
unsigned int length;
length = data_size + hash_size;
- if (auth_cipher)
+ if (auth_cipher && send_nonce)
length += exp_iv_size;
return length;
int explicit_iv = _gnutls_version_has_explicit_iv(ver);
int auth_cipher =
_gnutls_auth_cipher_is_aead(¶ms->write.cipher_state);
+ unsigned send_nonce = params->send_nonce;
uint8_t nonce[MAX_CIPHER_BLOCK_SIZE];
unsigned imp_iv_size = 0, exp_iv_size = 0;
bool etm = 0;
pad = 0;
length =
calc_enc_length_stream(session, compressed->size,
- tag_size, auth_cipher, exp_iv_size);
+ tag_size, auth_cipher, exp_iv_size, send_nonce);
}
if (length < 0)
UINT64DATA(params->write.sequence_number),
8);
- /* copy the explicit part */
- memcpy(data_ptr, &nonce[imp_iv_size],
- exp_iv_size);
+ if (send_nonce != 0) {
+ /* copy the explicit part */
+ memcpy(data_ptr, &nonce[imp_iv_size],
+ exp_iv_size);
- data_ptr += exp_iv_size;
- cipher_data += exp_iv_size;
+ data_ptr += exp_iv_size;
+ cipher_data += exp_iv_size;
+ }
}
if (etm)
const version_entry_st *ver = get_version(session);
unsigned int tag_size =
_gnutls_auth_cipher_tag_len(¶ms->read.cipher_state);
+ unsigned send_nonce = params->send_nonce;
unsigned int explicit_iv = _gnutls_version_has_explicit_iv(ver);
unsigned imp_iv_size, exp_iv_size;
unsigned cipher_type = _gnutls_cipher_type(params->cipher);
return
gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
- if (unlikely(ciphertext->size < tag_size + exp_iv_size))
+ if (unlikely(ciphertext->size < tag_size + (send_nonce!=0)?exp_iv_size:0))
return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
memcpy(nonce, params->read.IV.data,
imp_iv_size);
- memcpy(&nonce[imp_iv_size],
- ciphertext->data, exp_iv_size);
+ if (send_nonce != 0) {
+ memcpy(&nonce[imp_iv_size],
+ ciphertext->data, exp_iv_size);
- ciphertext->data += exp_iv_size;
- ciphertext->size -= exp_iv_size;
+ ciphertext->data += exp_iv_size;
+ ciphertext->size -= exp_iv_size;
+ } else {
+ memcpy(&nonce[imp_iv_size],
+ UINT64DATA(params->read.sequence_number), 8);
+ }
length =
ciphertext->size - tag_size;