tls_get_compression,
tls_set_max_frag_len,
dtls_get_max_record_overhead,
- tls_increment_sequence_ctr
+ tls_increment_sequence_ctr,
+ tls_alloc_buffers,
+ tls_free_buffers
};
return OSSL_RECORD_RETURN_SUCCESS;
}
+static int ktls_alloc_buffers(OSSL_RECORD_LAYER *rl)
+{
+ /* We use the application buffer directly for writing */
+ if (rl->direction == OSSL_RECORD_DIRECTION_WRITE)
+ return 1;
+
+ return tls_alloc_buffers(rl);
+}
+
+static int ktls_free_buffers(OSSL_RECORD_LAYER *rl)
+{
+ /* We use the application buffer directly for writing */
+ if (rl->direction == OSSL_RECORD_DIRECTION_WRITE)
+ return 1;
+
+ return tls_free_buffers(rl);
+}
+
static struct record_functions_st ossl_ktls_funcs = {
ktls_set_crypto_state,
ktls_cipher,
tls_get_compression,
tls_set_max_frag_len,
NULL,
- tls_increment_sequence_ctr
+ tls_increment_sequence_ctr,
+ ktls_alloc_buffers,
+ ktls_free_buffers
};
size_t mac_secret_length, char is_sslv3);
int tls_increment_sequence_ctr(OSSL_RECORD_LAYER *rl);
+int tls_alloc_buffers(OSSL_RECORD_LAYER *rl);
+int tls_free_buffers(OSSL_RECORD_LAYER *rl);
int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes);
return 1;
}
+int tls_alloc_buffers(OSSL_RECORD_LAYER *rl)
+{
+ if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) {
+ /* If we have a pending write then buffers are already allocated */
+ if (rl->nextwbuf < rl->numwpipes)
+ return 1;
+ /*
+ * We assume 1 pipe with default sized buffer. If what we need ends up
+ * being a different size to that then it will be reallocated on demand.
+ * If we need more than 1 pipe then that will also be allocated on
+ * demand
+ */
+ if (!tls_setup_write_buffer(rl, 1, 0, 0))
+ return 0;
+
+ /*
+ * Normally when we allocate write buffers we immediately write
+ * something into it. In this case we're not doing that so mark the
+ * buffer as empty.
+ */
+ SSL3_BUFFER_set_left(&rl->wbuf[0], 0);
+ return 1;
+ }
+
+ /* Read direction */
+
+ /* If we have pending data to be read then buffers are already allocated */
+ if (rl->curr_rec < rl->num_recs || SSL3_BUFFER_get_left(&rl->rbuf) != 0)
+ return 1;
+ return tls_setup_read_buffer(rl);
+}
+
+int tls_free_buffers(OSSL_RECORD_LAYER *rl)
+{
+ if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) {
+ if (rl->nextwbuf < rl->numwpipes) {
+ /*
+ * We may have pending data. If we've just got one empty buffer
+ * allocated then it has probably just been alloc'd via
+ * tls_alloc_buffers, and it is fine to free it. Otherwise this
+ * looks like real pending data and it is an error.
+ */
+ if (rl->nextwbuf != 0
+ || rl->numwpipes != 1
+ || SSL3_BUFFER_get_left(&rl->wbuf[0]) != 0)
+ return 0;
+ }
+ tls_release_write_buffer(rl);
+ return 1;
+ }
+
+ /* Read direction */
+
+ /* If we have pending data to be read then fail */
+ if (rl->curr_rec < rl->num_recs || SSL3_BUFFER_get_left(&rl->rbuf) != 0)
+ return 0;
+
+ return tls_release_read_buffer(rl);
+}
+
const OSSL_RECORD_METHOD ossl_tls_record_method = {
tls_new_record_layer,
tls_free,
tls_get_compression,
tls_set_max_frag_len,
NULL,
- tls_increment_sequence_ctr
+ tls_increment_sequence_ctr,
+ tls_alloc_buffers,
+ tls_free_buffers
};
DTLS_RECORD_LAYER_clear(rl);
}
-void RECORD_LAYER_release(RECORD_LAYER *rl)
-{
- /*
- * TODO(RECLAYER): Need a way to release the write buffers in the record
- * layer on demand
- */
-}
-
/* Checks if we have unprocessed read ahead data pending */
int RECORD_LAYER_read_pending(const RECORD_LAYER *rl)
{
void RECORD_LAYER_init(RECORD_LAYER *rl, SSL_CONNECTION *s);
void RECORD_LAYER_clear(RECORD_LAYER *rl);
-void RECORD_LAYER_release(RECORD_LAYER *rl);
int RECORD_LAYER_read_pending(const RECORD_LAYER *rl);
int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl);
int RECORD_LAYER_write_pending(const RECORD_LAYER *rl);
* Increment the record sequence number
*/
int (*increment_sequence_ctr)(OSSL_RECORD_LAYER *rl);
+
+ /*
+ * Allocate read or write buffers. Does nothing if already allocated.
+ * Assumes default buffer length and 1 pipeline.
+ */
+ int (*alloc_buffers)(OSSL_RECORD_LAYER *rl);
+
+ /*
+ * Free read or write buffers. Fails if there is pending read or write
+ * data. Buffers are automatically reallocated on next read/write.
+ */
+ int (*free_buffers)(OSSL_RECORD_LAYER *rl);
};
rl = &sc->rlayer;
- if (RECORD_LAYER_read_pending(rl) || RECORD_LAYER_write_pending(rl))
- return 0;
-
- RECORD_LAYER_release(rl);
- return 1;
+ return rl->rrlmethod->free_buffers(rl->rrl)
+ && rl->wrlmethod->free_buffers(rl->wrl);
}
int SSL_alloc_buffers(SSL *ssl)
{
+ RECORD_LAYER *rl;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
if (sc == NULL)
return 0;
- /* TODO(RECLAYER): Need a way to make this happen in the record layer */
- return 1;
+ rl = &sc->rlayer;
+
+ return rl->rrlmethod->alloc_buffers(rl->rrl)
+ && rl->wrlmethod->alloc_buffers(rl->wrl);
}
void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb)