summaryrefslogtreecommitdiff
path: root/lib/gnutls_state.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2015-02-20 11:16:44 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2015-02-20 11:16:46 +0100
commit47e828d793807700f20da4c32a9149bf4906f7b2 (patch)
tree555712903a1fc5f9098236eda4306ae0044f9176 /lib/gnutls_state.c
parentb5557f947060167172b43e16889aa206572c70a2 (diff)
downloadgnutls-47e828d793807700f20da4c32a9149bf4906f7b2.tar.gz
Added gnutls_record_get_state() and gnutls_record_set_state()
These functions allow to export the key material and sequence numbers. That allows offloading the sending and receiving of individual records.
Diffstat (limited to 'lib/gnutls_state.c')
-rw-r--r--lib/gnutls_state.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index ac3adbd443..d6aef41a60 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -1522,3 +1522,102 @@ gnutls_handshake_set_hook_function(gnutls_session_t session,
session->internals.h_type = htype;
session->internals.h_post = post;
}
+
+/**
+ * gnutls_record_get_state:
+ * @session: is a #gnutls_session_t structure
+ * @read: if non-zero the read parameters are returned, otherwise the write
+ * @mac_key: the key used for MAC (if a MAC is used)
+ * @IV: the initialization vector or nonce used
+ * @cipher_key: the cipher key
+ * @seq_number: A 64-bit sequence number
+ *
+ * This function will return the parameters of the current record state.
+ * These are only useful to be provided to an external off-loading device
+ * or subsystem.
+ *
+ * In that case, to sync the state you must call gnutls_record_set_state().
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
+ *
+ * Since 3.4.0
+ **/
+int
+gnutls_record_get_state(gnutls_session_t session,
+ unsigned read,
+ gnutls_datum_t *mac_key,
+ gnutls_datum_t *IV,
+ gnutls_datum_t *cipher_key,
+ unsigned char seq_number[8])
+{
+ record_parameters_st *record_params;
+ record_state_st *record_state;
+ int epoch, ret;
+
+ if (read)
+ epoch = EPOCH_READ_CURRENT;
+ else
+ epoch = EPOCH_WRITE_CURRENT;
+
+ ret = _gnutls_epoch_get(session, epoch, &record_params);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ if (!record_params->initialized)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ if (read)
+ record_state = &record_params->read;
+ else
+ record_state = &record_params->write;
+
+ memcpy(&mac_key, &record_state->mac_secret, sizeof(gnutls_datum_t));
+ memcpy(&IV, &record_state->IV, sizeof(gnutls_datum_t));
+ memcpy(&cipher_key, &record_state->key, sizeof(gnutls_datum_t));
+ memcpy(seq_number, UINT64DATA(record_state->sequence_number), 8);
+ return 0;
+}
+
+/**
+ * gnutls_record_set_state:
+ * @session: is a #gnutls_session_t structure
+ * @read: if non-zero the read parameters are returned, otherwise the write
+ * @seq_number: A 64-bit sequence number
+ *
+ * This function will set the sequence number in the current record state.
+ * This function is useful if sending and receiving are offloaded from
+ * gnutls. That is, if gnutls_record_get_state() was used.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
+ *
+ * Since 3.4.0
+ **/
+int
+gnutls_record_set_state(gnutls_session_t session,
+ unsigned read,
+ unsigned char seq_number[8])
+{
+ record_parameters_st *record_params;
+ record_state_st *record_state;
+ int epoch, ret;
+
+ if (read)
+ epoch = EPOCH_READ_CURRENT;
+ else
+ epoch = EPOCH_WRITE_CURRENT;
+
+ ret = _gnutls_epoch_get(session, epoch, &record_params);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ if (!record_params->initialized)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ if (read)
+ record_state = &record_params->read;
+ else
+ record_state = &record_params->write;
+
+ memcpy(UINT64DATA(record_state->sequence_number), seq_number, 8);
+ return 0;
+}