{
if (unlikely(e == NULL))
return 0;
- return e->iv;
+ return e->implicit_iv;
+}
+
+inline static int
+_gnutls_cipher_get_iv_size(const cipher_entry_st * e)
+{
+ if (unlikely(e == NULL))
+ return 0;
+ return e->cipher_iv;
+}
+
+inline static int
+_gnutls_cipher_get_explicit_iv_size(const cipher_entry_st * e)
+{
+ if (unlikely(e == NULL))
+ return 0;
+ return e->explicit_iv;
}
inline static int _gnutls_cipher_get_key_size(const cipher_entry_st * e)
*/
static const cipher_entry_st algorithms[] = {
{"AES-256-CBC", GNUTLS_CIPHER_AES_256_CBC, 16, 32, CIPHER_BLOCK,
- 16, 16, 0},
+ 0, 16, 16, 0},
{"AES-192-CBC", GNUTLS_CIPHER_AES_192_CBC, 16, 24, CIPHER_BLOCK,
- 16, 16, 0},
+ 0, 16, 16, 0},
{"AES-128-CBC", GNUTLS_CIPHER_AES_128_CBC, 16, 16, CIPHER_BLOCK,
- 16, 16, 0},
+ 0, 16, 16, 0},
{"AES-128-GCM", GNUTLS_CIPHER_AES_128_GCM, 16, 16, CIPHER_STREAM,
- AEAD_IMPLICIT_DATA_SIZE, 12, 1},
+ 4, 8, 12, 1},
{"AES-256-GCM", GNUTLS_CIPHER_AES_256_GCM, 16, 32, CIPHER_STREAM,
- AEAD_IMPLICIT_DATA_SIZE, 12, 1},
- {"ARCFOUR-128", GNUTLS_CIPHER_ARCFOUR_128, 1, 16, CIPHER_STREAM, 0,
- 0, 0},
+ 4, 8, 12, 1},
+ {"ARCFOUR-128", GNUTLS_CIPHER_ARCFOUR_128, 1, 16, CIPHER_STREAM,
+ 0, 0, 0, 0},
{"ESTREAM-SALSA20-256", GNUTLS_CIPHER_ESTREAM_SALSA20_256, 64, 32,
- CIPHER_STREAM, 8, 8, 0},
+ CIPHER_STREAM, 0, 0, 8, 0},
{"SALSA20-256", GNUTLS_CIPHER_SALSA20_256, 64, 32, CIPHER_STREAM,
- 8, 8, 0},
+ 0, 0, 8, 0},
{"CAMELLIA-256-CBC", GNUTLS_CIPHER_CAMELLIA_256_CBC, 16, 32,
- CIPHER_BLOCK,
- 16, 16, 0},
+ CIPHER_BLOCK, 0, 16, 16, 0},
{"CAMELLIA-192-CBC", GNUTLS_CIPHER_CAMELLIA_192_CBC, 16, 24,
- CIPHER_BLOCK,
- 16, 16, 0},
+ CIPHER_BLOCK, 0, 16, 16, 0},
{"CAMELLIA-128-CBC", GNUTLS_CIPHER_CAMELLIA_128_CBC, 16, 16,
- CIPHER_BLOCK,
- 16, 16, 0},
+ CIPHER_BLOCK, 0, 16, 16, 0},
{"CAMELLIA-128-GCM", GNUTLS_CIPHER_CAMELLIA_128_GCM, 16, 16,
- CIPHER_STREAM, AEAD_IMPLICIT_DATA_SIZE, 12, 1},
+ CIPHER_STREAM, 4, 8, 12, 1},
{"CAMELLIA-256-GCM", GNUTLS_CIPHER_CAMELLIA_256_GCM, 16, 32,
- CIPHER_STREAM, AEAD_IMPLICIT_DATA_SIZE, 12, 1},
- {"3DES-CBC", GNUTLS_CIPHER_3DES_CBC, 8, 24, CIPHER_BLOCK, 8, 8, 0},
- {"DES-CBC", GNUTLS_CIPHER_DES_CBC, 8, 8, CIPHER_BLOCK, 8, 8, 0},
- {"ARCFOUR-40", GNUTLS_CIPHER_ARCFOUR_40, 1, 5, CIPHER_STREAM, 0, 0,
- 0},
- {"RC2-40", GNUTLS_CIPHER_RC2_40_CBC, 8, 5, CIPHER_BLOCK, 8, 8, 0},
+ CIPHER_STREAM, 4, 8, 12, 1},
+ {"3DES-CBC", GNUTLS_CIPHER_3DES_CBC, 8, 24, CIPHER_BLOCK, 0, 8, 8, 0},
+ {"DES-CBC", GNUTLS_CIPHER_DES_CBC, 8, 8, CIPHER_BLOCK, 0, 8, 8, 0},
+ {"ARCFOUR-40", GNUTLS_CIPHER_ARCFOUR_40, 1, 5, CIPHER_STREAM, 0, 0, 0, 0},
+ {"RC2-40", GNUTLS_CIPHER_RC2_40_CBC, 8, 5, CIPHER_BLOCK, 0, 8, 8, 0},
#ifdef ENABLE_OPENPGP
{"IDEA-PGP-CFB", GNUTLS_CIPHER_IDEA_PGP_CFB, 8, 16, CIPHER_BLOCK,
- 8, 8, 0},
+ 0, 8, 8, 0},
{"3DES-PGP-CFB", GNUTLS_CIPHER_3DES_PGP_CFB, 8, 24, CIPHER_BLOCK,
- 8, 8, 0},
+ 0, 8, 8, 0},
{"CAST5-PGP-CFB", GNUTLS_CIPHER_CAST5_PGP_CFB, 8, 16, CIPHER_BLOCK,
- 8, 8, 0},
+ 0, 8, 8, 0},
{"BLOWFISH-PGP-CFB", GNUTLS_CIPHER_BLOWFISH_PGP_CFB, 8,
- 16 /*actually unlimited */ , CIPHER_BLOCK, 8, 8, 0},
+ 16 /*actually unlimited */ , CIPHER_BLOCK, 0, 8, 8, 0},
{"SAFER-SK128-PGP-CFB", GNUTLS_CIPHER_SAFER_SK128_PGP_CFB, 8, 16,
- CIPHER_BLOCK, 8, 8, 0},
+ CIPHER_BLOCK, 0, 8, 8, 0},
{"AES-128-PGP-CFB", GNUTLS_CIPHER_AES128_PGP_CFB, 16, 16,
- CIPHER_BLOCK, 16,
- 16, 0},
+ CIPHER_BLOCK, 0, 16, 16, 0},
{"AES-192-PGP-CFB", GNUTLS_CIPHER_AES192_PGP_CFB, 16, 24,
- CIPHER_BLOCK, 16,
- 16, 0},
+ CIPHER_BLOCK, 0, 16, 16, 0},
{"AES-256-PGP-CFB", GNUTLS_CIPHER_AES256_PGP_CFB, 16, 32,
- CIPHER_BLOCK, 16,
- 16, 0},
+ CIPHER_BLOCK, 0, 16, 16, 0},
{"TWOFISH-PGP-CFB", GNUTLS_CIPHER_TWOFISH_PGP_CFB, 16, 16,
- CIPHER_BLOCK, 16,
- 16, 0},
+ CIPHER_BLOCK, 0, 16, 16, 0},
#endif
#ifndef ENABLE_FIPS140
gettime(&t1);
}
- *bufel = _mbuffer_alloc(max_size);
+ *bufel = _mbuffer_alloc_align16(max_size, get_total_headers(session));
if (*bufel == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
session->internals.direction = 0;
- *bufel = _mbuffer_alloc(MAX(max_size, size));
+ *bufel = _mbuffer_alloc_align16(MAX(max_size, size), get_total_headers(session));
if (!*bufel) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
inline static int
calc_enc_length_stream(gnutls_session_t session, int data_size,
- int hash_size, unsigned auth_cipher)
+ int hash_size, unsigned auth_cipher,
+ unsigned exp_iv_size)
{
unsigned int length;
length = data_size + hash_size;
if (auth_cipher)
- length += AEAD_EXPLICIT_DATA_SIZE;
+ length += exp_iv_size;
return length;
}
int auth_cipher =
_gnutls_auth_cipher_is_aead(¶ms->write.cipher_state);
uint8_t nonce[MAX_CIPHER_BLOCK_SIZE];
- unsigned iv_size;
+ unsigned iv_size, imp_iv_size, exp_iv_size;
if (unlikely(ver == NULL))
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
- iv_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+ iv_size = _gnutls_cipher_get_iv_size(params->cipher);
+ imp_iv_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+ exp_iv_size = _gnutls_cipher_get_explicit_iv_size(params->cipher);
_gnutls_hard_log("ENC[%p]: cipher: %s, MAC: %s, Epoch: %u\n",
session, _gnutls_cipher_get_name(params->cipher),
pad = 0;
length =
calc_enc_length_stream(session, compressed->size,
- tag_size, auth_cipher);
+ tag_size, auth_cipher, exp_iv_size);
}
if (length < 0)
/* copy the encrypted data to cipher_data.
*/
if (cipher_size < length)
- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
data_ptr = cipher_data;
if (explicit_iv) { /* TLS 1.1 or later */
+
if (block_algo == CIPHER_BLOCK) {
/* copy the random IV.
*/
*/
if (params->write.IV.data == NULL
|| params->write.IV.size !=
- AEAD_IMPLICIT_DATA_SIZE)
+ imp_iv_size)
return
gnutls_assert_val
(GNUTLS_E_INTERNAL_ERROR);
*/
memcpy(nonce, params->write.IV.data,
params->write.IV.size);
- memcpy(&nonce[AEAD_IMPLICIT_DATA_SIZE],
+ memcpy(&nonce[imp_iv_size],
UINT64DATA(params->write.sequence_number),
8);
_gnutls_auth_cipher_setiv(¶ms->write.
cipher_state, nonce,
- AEAD_IMPLICIT_DATA_SIZE +
- AEAD_EXPLICIT_DATA_SIZE);
+ imp_iv_size +
+ exp_iv_size);
/* copy the explicit part */
- memcpy(data_ptr, &nonce[AEAD_IMPLICIT_DATA_SIZE],
- AEAD_EXPLICIT_DATA_SIZE);
+ memcpy(data_ptr, &nonce[imp_iv_size],
+ exp_iv_size);
- data_ptr += AEAD_EXPLICIT_DATA_SIZE;
- cipher_data += AEAD_EXPLICIT_DATA_SIZE;
+ data_ptr += exp_iv_size;
+ cipher_data += exp_iv_size;
} else if (iv_size > 0)
_gnutls_auth_cipher_setiv(¶ms->write.
cipher_state,
int auth_cipher =
_gnutls_auth_cipher_is_aead(¶ms->write.cipher_state);
uint8_t nonce[MAX_CIPHER_BLOCK_SIZE];
- unsigned iv_size, final_cipher_size;
+ unsigned imp_iv_size, final_cipher_size, iv_size, exp_iv_size;
if (unlikely(ver == NULL))
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
- iv_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+ imp_iv_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+ exp_iv_size = _gnutls_cipher_get_explicit_iv_size(params->cipher);
+ iv_size = _gnutls_cipher_get_iv_size(params->cipher);
_gnutls_hard_log("ENC[%p]: cipher: %s, MAC: %s, Epoch: %u\n",
session, _gnutls_cipher_get_name(params->cipher),
*/
if (params->write.IV.data == NULL
|| params->write.IV.size !=
- AEAD_IMPLICIT_DATA_SIZE)
+ imp_iv_size)
return
gnutls_assert_val
(GNUTLS_E_INTERNAL_ERROR);
*/
memcpy(nonce, params->write.IV.data,
params->write.IV.size);
- memcpy(&nonce[AEAD_IMPLICIT_DATA_SIZE],
+ memcpy(&nonce[imp_iv_size],
UINT64DATA(params->write.sequence_number),
8);
_gnutls_auth_cipher_setiv(¶ms->write.
cipher_state, nonce,
- AEAD_IMPLICIT_DATA_SIZE +
- AEAD_EXPLICIT_DATA_SIZE);
+ imp_iv_size +
+ exp_iv_size);
/* copy the explicit part */
- DECR_LEN(cipher_size, AEAD_EXPLICIT_DATA_SIZE);
- memcpy(data_ptr, &nonce[AEAD_IMPLICIT_DATA_SIZE],
- AEAD_EXPLICIT_DATA_SIZE);
+ DECR_LEN(cipher_size, exp_iv_size);
+ memcpy(data_ptr, &nonce[imp_iv_size],
+ exp_iv_size);
- data_ptr += AEAD_EXPLICIT_DATA_SIZE;
- cipher_data += AEAD_EXPLICIT_DATA_SIZE;
- length += AEAD_EXPLICIT_DATA_SIZE;
+ data_ptr += exp_iv_size;
+ cipher_data += exp_iv_size;
+ length += exp_iv_size;
} else if (iv_size > 0)
_gnutls_auth_cipher_setiv(¶ms->write.
cipher_state,
unsigned int tag_size =
_gnutls_auth_cipher_tag_len(¶ms->read.cipher_state);
unsigned int explicit_iv = _gnutls_version_has_explicit_iv(ver);
- unsigned iv_size;
+ unsigned imp_iv_size, iv_size, exp_iv_size;
if (unlikely(ver == NULL))
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
- iv_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+ imp_iv_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+ exp_iv_size = _gnutls_cipher_get_explicit_iv_size(params->cipher);
+ iv_size = _gnutls_cipher_get_iv_size(params->cipher);
blocksize = _gnutls_cipher_get_block_size(params->cipher);
/* actual decryption (inplace)
if (unlikely
(ciphertext->size <
- tag_size + AEAD_EXPLICIT_DATA_SIZE))
+ tag_size + exp_iv_size))
return
gnutls_assert_val
(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
memcpy(nonce, params->read.IV.data,
- AEAD_IMPLICIT_DATA_SIZE);
- memcpy(&nonce[AEAD_IMPLICIT_DATA_SIZE],
- ciphertext->data, AEAD_EXPLICIT_DATA_SIZE);
+ imp_iv_size);
+ memcpy(&nonce[imp_iv_size],
+ ciphertext->data, exp_iv_size);
_gnutls_auth_cipher_setiv(¶ms->read.
cipher_state, nonce,
- AEAD_EXPLICIT_DATA_SIZE +
- AEAD_IMPLICIT_DATA_SIZE);
+ exp_iv_size +
+ imp_iv_size);
- ciphertext->data += AEAD_EXPLICIT_DATA_SIZE;
- ciphertext->size -= AEAD_EXPLICIT_DATA_SIZE;
+ ciphertext->data += exp_iv_size;
+ ciphertext->size -= exp_iv_size;
length = length_to_decrypt =
ciphertext->size - tag_size;
unsigned int tag_size =
_gnutls_auth_cipher_tag_len(¶ms->read.cipher_state);
unsigned int explicit_iv = _gnutls_version_has_explicit_iv(ver);
- unsigned iv_size;
+ unsigned imp_iv_size, iv_size, exp_iv_size;
if (unlikely(ver == NULL))
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
- iv_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+ imp_iv_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+ exp_iv_size = _gnutls_cipher_get_explicit_iv_size(params->cipher);
+ iv_size = _gnutls_cipher_get_iv_size(params->cipher);
blocksize = _gnutls_cipher_get_block_size(params->cipher);
/* actual decryption (inplace)
(GNUTLS_E_INTERNAL_ERROR);
if (ciphertext->size <
- tag_size + AEAD_EXPLICIT_DATA_SIZE + 2)
+ tag_size + exp_iv_size + 2)
return
gnutls_assert_val
(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
memcpy(nonce, params->read.IV.data,
- AEAD_IMPLICIT_DATA_SIZE);
- memcpy(&nonce[AEAD_IMPLICIT_DATA_SIZE],
- ciphertext->data, AEAD_EXPLICIT_DATA_SIZE);
+ imp_iv_size);
+ memcpy(&nonce[imp_iv_size],
+ ciphertext->data, exp_iv_size);
_gnutls_auth_cipher_setiv(¶ms->read.
cipher_state, nonce,
- AEAD_EXPLICIT_DATA_SIZE +
- AEAD_IMPLICIT_DATA_SIZE);
+ exp_iv_size +
+ imp_iv_size);
- ciphertext->data += AEAD_EXPLICIT_DATA_SIZE;
- ciphertext->size -= AEAD_EXPLICIT_DATA_SIZE;
+ ciphertext->data += exp_iv_size;
+ ciphertext->size -= exp_iv_size;
length_to_decrypt = ciphertext->size - tag_size;
- } else if (iv_size > 0) { /* a stream cipher with explicit IV */
+ } else if (iv_size > 0) { /* a stream cipher with implicit IV */
_gnutls_auth_cipher_setiv(¶ms->read.
cipher_state,
UINT64DATA(*sequence),
gnutls_assert_val
(GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM);
- IV_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+ if (!_gnutls_version_has_explicit_iv(ver)) {
+ if (_gnutls_cipher_is_block(params->cipher) != CIPHER_STREAM) {
+ IV_size = _gnutls_cipher_get_iv_size(params->cipher);
+ } else
+ IV_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+ } else
+ IV_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
+
key_size = _gnutls_cipher_get_key_size(params->cipher);
hash_size = _gnutls_mac_get_key_size(params->mac);
int t, ret;
if (_gnutls_cipher_is_block(cipher) == CIPHER_BLOCK) {
- t = _gnutls_cipher_get_implicit_iv_size(cipher);
+ t = _gnutls_cipher_get_explicit_iv_size(cipher);
total += t;
/* padding */
uint16_t blocksize;
uint16_t keysize;
bool block;
- uint16_t iv; /* the size of implicit IV - TLS related */
+ uint16_t implicit_iv; /* the size of implicit IV - the IV generated but not sent */
+ uint16_t explicit_iv; /* the size of explicit IV - the IV stored in record */
uint16_t cipher_iv; /* the size of IV needed by the cipher */
bool aead; /* Whether it is authenc cipher */
} cipher_entry_st;
/* Holds the signature algorithm used in this session - If any */
gnutls_sign_algorithm_t server_sign_algo;
gnutls_sign_algorithm_t client_sign_algo;
-
+
/* FIXME: The following are not saved in the session storage
* for session resumption.
*/
return st;
}
+
/* Copy data into a segment. The segment must not be part of a buffer
* head when using this function.
*
return 0;
}
+#ifdef ENABLE_CRYPTODEV
+# define ALIGN_SIZE 16
+
+/* Allocate a 16-byte alligned buffer segment. The segment is not initially "owned" by
+ * any buffer.
+ *
+ * maximum_size: Amount of data that this segment can contain.
+ * align_pos: identifies the position of the buffer that will be aligned at 16-bytes
+ *
+ * This function should be used to ensure that encrypted data or data to
+ * be encrypted are properly aligned.
+ *
+ * Returns the segment or NULL on error.
+ *
+ * Cost: O(1)
+ */
+mbuffer_st *_mbuffer_alloc_align16(size_t maximum_size, unsigned align_pos)
+{
+ mbuffer_st *st;
+ size_t cur_alignment;
+
+ st = gnutls_malloc(maximum_size + sizeof(mbuffer_st) + ALIGN_SIZE);
+ if (st == NULL) {
+ gnutls_assert();
+ return NULL;
+ }
+
+ /* set the structure to zero */
+ memset(st, 0, sizeof(*st));
+
+ /* payload points after the mbuffer_st structure */
+ st->msg.data = (uint8_t *) st + sizeof(mbuffer_st);
+
+ cur_alignment = ((size_t)(st->msg.data+align_pos)) % ALIGN_SIZE;
+ if (cur_alignment > 0)
+ st->msg.data += ALIGN_SIZE - cur_alignment;
+
+ st->msg.size = 0;
+ st->maximum_size = maximum_size;
+
+ return st;
+}
+
+static unsigned is_aligned16(mbuffer_st * bufel, unsigned align_pos)
+{
+uint8_t * ptr = _mbuffer_get_udata_ptr(bufel);
+
+ if (((size_t)(ptr+align_pos)) % ALIGN_SIZE == 0)
+ return 1;
+ else
+ return 0;
+}
+
/* Takes a buffer in multiple chunks and puts all the data in a single
- * contiguous segment.
+ * contiguous segment, ensuring that the @align_pos is 16-byte aligned.
*
* Returns 0 on success or an error code otherwise.
*
* Cost: O(n)
* n: number of segments initially in the buffer
*/
-int _mbuffer_linearize(mbuffer_head_st * buf)
+int _mbuffer_linearize_align16(mbuffer_head_st * buf, unsigned align_pos)
{
mbuffer_st *bufel, *cur;
gnutls_datum_t msg;
size_t pos = 0;
- if (buf->length <= 1)
+ if (buf->length == 0) {
/* Nothing to do */
return 0;
+ }
+
+ bufel = _mbuffer_head_get_first(buf, NULL);
+ if (buf->length == 1 && is_aligned16(bufel, align_pos))
+ return 0;
+ bufel = _mbuffer_alloc_align16(buf->byte_length, align_pos);
+ if (!bufel) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ for (cur = _mbuffer_head_get_first(buf, &msg);
+ msg.data != NULL; cur = _mbuffer_head_get_next(cur, &msg)) {
+ memcpy(&bufel->msg.data[pos], msg.data, msg.size);
+ bufel->msg.size += msg.size;
+ pos += msg.size;
+ }
+
+ _mbuffer_head_clear(buf);
+ _mbuffer_enqueue(buf, bufel);
+
+ return 0;
+}
+#else
+int _mbuffer_linearize(mbuffer_head_st * buf)
+{
+ mbuffer_st *bufel, *cur;
+ gnutls_datum_t msg;
+ size_t pos = 0;
+
+ if (buf->length <= 1) {
+ /* Nothing to do */
+ return 0;
+ }
+
bufel = _mbuffer_alloc(buf->byte_length);
if (!bufel) {
gnutls_assert();
return 0;
}
+#endif
mbuffer_st *_mbuffer_dequeue(mbuffer_head_st * buf, mbuffer_st * bufel);
int _mbuffer_head_remove_bytes(mbuffer_head_st * buf, size_t bytes);
mbuffer_st *_mbuffer_alloc(size_t maximum_size);
+int _mbuffer_linearize(mbuffer_head_st * buf);
mbuffer_st *_mbuffer_head_get_first(mbuffer_head_st * buf,
gnutls_datum_t * msg);
*/
int _mbuffer_append_data(mbuffer_st * bufel, void *newdata,
size_t newdata_size);
-int _mbuffer_linearize(mbuffer_head_st * buf);
/* For "user" use. One can have buffer data and header.
*bufel = NULL;
}
+#ifdef ENABLE_CRYPTODEV
+mbuffer_st *_mbuffer_alloc_align16(size_t maximum_size, unsigned align_pos);
+int _mbuffer_linearize_align16(mbuffer_head_st * buf, unsigned align_pos);
+#else
+# define _mbuffer_alloc_align16(x,y) _mbuffer_alloc(x)
+# define _mbuffer_linearize_align16(x,y) _mbuffer_linearize(x)
+#endif
+
#endif
/* now proceed to packet encryption
*/
cipher_size = MAX_RECORD_SEND_SIZE(session);
- bufel = _mbuffer_alloc(cipher_size + CIPHER_SLACK_SIZE);
+
+ bufel = _mbuffer_alloc_align16(cipher_size + CIPHER_SLACK_SIZE,
+ get_total_headers2(session, record_params));
if (bufel == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
/* Use the default record version, if it is
* set. */
copy_record_version(session, htype, &headers[1]);
- header_size = RECORD_HEADER_SIZE(session);
/* Adjust header length and add sequence for DTLS */
if (IS_DTLS(session))
memcpy(&headers[3],
session, _gnutls_packet2str(type), type,
(int) data_size, (int) min_pad);
+ header_size = RECORD_HEADER_SIZE(session);
_mbuffer_set_udata_size(bufel, cipher_size);
_mbuffer_set_uhead_size(bufel, header_size);
}
-static int recv_headers(gnutls_session_t session, content_type_t type,
+static int recv_headers(gnutls_session_t session,
+ record_parameters_st *record_params,
+ content_type_t type,
gnutls_handshake_description_t htype,
struct tls_record_st *record, unsigned int *ms)
{
return gnutls_assert_val(ret);
}
- ret = _mbuffer_linearize(&session->internals.record_recv_buffer);
+ ret = _mbuffer_linearize_align16(&session->internals.record_recv_buffer,
+ get_total_headers2(session, record_params));
if (ret < 0)
return gnutls_assert_val(ret);
record_state = &record_params->read;
/* receive headers */
- ret = recv_headers(session, type, htype, &record, &ms);
+ ret = recv_headers(session, record_params, type, htype, &record, &ms);
if (ret < 0) {
ret = gnutls_assert_val_fatal(ret);
goto recv_error;
/* ok now we are sure that we have read all the data - so
* move on !
*/
- ret = _mbuffer_linearize(&session->internals.record_recv_buffer);
+ ret = _mbuffer_linearize_align16(&session->internals.record_recv_buffer,
+ get_total_headers2(session, record_params));
if (ret < 0)
return gnutls_assert_val(ret);
* they are encrypted).
*/
ret = max_decrypted_size(session) + MAX_PAD_SIZE + MAX_HASH_SIZE;
- decrypted = _mbuffer_alloc(ret);
+ decrypted = _mbuffer_alloc_align16(ret, 0);
if (decrypted == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
#include <gnutls/gnutls.h>
#include <gnutls_buffers.h>
+#include <gnutls_constate.h>
ssize_t _gnutls_send_tlen_int(gnutls_session_t session,
content_type_t type,
return size;
}
+/* Returns the headers + any IV that the ciphersuite
+ * requires */
+inline static
+unsigned int get_total_headers(gnutls_session_t session)
+{
+ int ret;
+ record_parameters_st *params;
+ unsigned total = RECORD_HEADER_SIZE(session);
+
+ if (session->security_parameters.new_record_padding)
+ total += 2;
+
+ ret = _gnutls_epoch_get(session, EPOCH_WRITE_CURRENT, ¶ms);
+ if (ret < 0) {
+ return total;
+ }
+
+ return total + _gnutls_cipher_get_explicit_iv_size(params->cipher);
+}
+
+inline static
+unsigned int get_total_headers2(gnutls_session_t session, record_parameters_st *params)
+{
+ unsigned total = RECORD_HEADER_SIZE(session);
+
+ if (session->security_parameters.new_record_padding)
+ total += 2;
+
+ return total + _gnutls_cipher_get_explicit_iv_size(params->cipher);
+}
+
#endif