Fix dtls_get_max_record_overhead()
[openssl.git] / ssl / record / recordmethod.h
index 5a54dba550eb8a670e1543b5d523a1296dcd6c0d..064f8e5feb56d631790c032d2995fb9bae308337 100644 (file)
@@ -7,7 +7,11 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <openssl/ssl.h>
+#ifndef OSSL_INTERNAL_RECORDMETHOD_H
+# define OSSL_INTERNAL_RECORDMETHOD_H
+# pragma once
+
+# include <openssl/ssl.h>
 
 /*
  * We use the term "record" here to refer to a packet of data. Records are
  * refer to both contexts.
  */
 
-
-/*
- * Types of QUIC record layer;
- *
- * QUIC reuses the TLS handshake for agreeing secrets. An SSL object representing
- * a QUIC connection will have an additional SSL object internally representing
- * the TLS state of the QUIC handshake. This internal TLS is referred to as
- * QUIC-TLS in this file.
- * "Records" output from QUIC-TLS contains standard TLS handshake messages and
- * are *not* encrypted directly but are instead wrapped up in plaintext
- * CRYPTO frames. These CRYPTO frames could be collected together with other
- * QUIC frames into a single QUIC packet. The QUIC record layer will then
- * encrypt the whole packet.
- *
- * So we have:
- * QUIC-TLS record layer: outputs plaintext CRYPTO frames containing TLS
- *                        handshake messages only.
- * QUIC record layer: outputs encrypted packets which may contain CRYPTO frames
- *                    or any other type of QUIC frame.
- */
-
 /*
  * An OSSL_RECORD_METHOD is a protcol specific method which provides the
  * functions for reading and writing records for that protocol. Which
@@ -54,39 +37,36 @@ typedef struct ossl_record_method_st OSSL_RECORD_METHOD;
 typedef struct ossl_record_layer_st OSSL_RECORD_LAYER;
 
 
-#define OSSL_RECORD_ROLE_CLIENT 0
-#define OSSL_RECORD_ROLE_SERVER 1
+# define OSSL_RECORD_ROLE_CLIENT 0
+# define OSSL_RECORD_ROLE_SERVER 1
 
-#define OSSL_RECORD_DIRECTION_READ  0
-#define OSSL_RECORD_DIRECTION_WRITE 1
+# define OSSL_RECORD_DIRECTION_READ  0
+# define OSSL_RECORD_DIRECTION_WRITE 1
 
 /*
  * Protection level. For <= TLSv1.2 only "NONE" and "APPLICATION" are used.
  */
-#define OSSL_RECORD_PROTECTION_LEVEL_NONE        0
-#define OSSL_RECORD_PROTECTION_LEVEL_EARLY       1
-#define OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE   2
-#define OSSL_RECORD_PROTECTION_LEVEL_APPLICATION 3
-
+# define OSSL_RECORD_PROTECTION_LEVEL_NONE        0
+# define OSSL_RECORD_PROTECTION_LEVEL_EARLY       1
+# define OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE   2
+# define OSSL_RECORD_PROTECTION_LEVEL_APPLICATION 3
 
-#define OSSL_RECORD_RETURN_SUCCESS           1
-#define OSSL_RECORD_RETURN_RETRY             0
-#define OSSL_RECORD_RETURN_NON_FATAL_ERR    -1
-#define OSSL_RECORD_RETURN_FATAL            -2
-#define OSSL_RECORD_RETURN_EOF              -3
+# define OSSL_RECORD_RETURN_SUCCESS           1
+# define OSSL_RECORD_RETURN_RETRY             0
+# define OSSL_RECORD_RETURN_NON_FATAL_ERR    -1
+# define OSSL_RECORD_RETURN_FATAL            -2
+# define OSSL_RECORD_RETURN_EOF              -3
 
 /*
  * Template for creating a record. A record consists of the |type| of data it
- * will contain (e.g. alert, handshake, application data, etc) along with an
- * array of buffers in |bufs| of size |numbufs|. There is a corresponding array
- * of buffer lengths in |buflens|. Concatenating all of the buffer data together
- * would give you the complete plaintext payload to be sent in a single record.
+ * will contain (e.g. alert, handshake, application data, etc) along with a
+ * buffer of payload data in |buf| of length |buflen|.
  */
 struct ossl_record_template_st {
     int type;
-    void **bufs;
-    size_t *buflens;
-    size_t numbufs;
+    unsigned int version;
+    const unsigned char *buf;
+    size_t buflen;
 };
 
 typedef struct ossl_record_template_st OSSL_RECORD_TEMPLATE;
@@ -125,25 +105,53 @@ struct ossl_record_method_st {
      * force at any one time (one for reading and one for writing). In some
      * protocols more than 2 might be used (e.g. in DTLS for retransmitting
      * messages from an earlier epoch).
+     *
+     * The created OSSL_RECORD_LAYER object is stored in *ret on success (or
+     * NULL otherwise). The return value will be one of
+     * OSSL_RECORD_RETURN_SUCCESS, OSSL_RECORD_RETURN_FATAL or
+     * OSSL_RECORD_RETURN_NON_FATAL. A non-fatal return means that creation of
+     * the record layer has failed because it is unsuitable, but an alternative
+     * record layer can be tried instead.
      */
 
     /*
-     * TODO: Will have to be something other than SSL_CIPHER if we make this
-     * fetchable
+     * If we eventually make this fetchable then we will need to use something
+     * other than EVP_CIPHER. Also mactype would not be a NID, but a string. For
+     * now though, this works.
      */
-    OSSL_RECORD_LAYER *(*new_record_layer)(int vers, int role, int direction,
-                                          int level, unsigned char *secret,
-                                          size_t secretlen, SSL_CIPHER *c,
-                                          BIO *transport, BIO_ADDR *local,
-                                          BIO_ADDR *peer,
-                                          const OSSL_PARAM *settings,
-                                          const OSSL_PARAM *options);
-    void (*free)(OSSL_RECORD_LAYER *rl);
+    int (*new_record_layer)(OSSL_LIB_CTX *libctx,
+                            const char *propq, int vers,
+                            int role, int direction,
+                            int level,
+                            uint16_t epoch,
+                            unsigned char *key,
+                            size_t keylen,
+                            unsigned char *iv,
+                            size_t ivlen,
+                            unsigned char *mackey,
+                            size_t mackeylen,
+                            const EVP_CIPHER *ciph,
+                            size_t taglen,
+                            int mactype,
+                            const EVP_MD *md,
+                            COMP_METHOD *comp,
+                            BIO *prev,
+                            BIO *transport,
+                            BIO *next,
+                            BIO_ADDR *local,
+                            BIO_ADDR *peer,
+                            const OSSL_PARAM *settings,
+                            const OSSL_PARAM *options,
+                            const OSSL_DISPATCH *fns,
+                            void *cbarg,
+                            OSSL_RECORD_LAYER **ret);
+    int (*free)(OSSL_RECORD_LAYER *rl);
 
     int (*reset)(OSSL_RECORD_LAYER *rl); /* Is this needed? */
 
     /* Returns 1 if we have unprocessed data buffered or 0 otherwise */
     int (*unprocessed_read_pending)(OSSL_RECORD_LAYER *rl);
+
     /*
      * Returns 1 if we have processed data buffered that can be read or 0 otherwise
      * - not necessarily app data
@@ -156,35 +164,27 @@ struct ossl_record_method_st {
      */
     size_t (*app_data_pending)(OSSL_RECORD_LAYER *rl);
 
-    int (*write_pending)(OSSL_RECORD_LAYER *rl);
-
-
-    /*
-     * Find out the maximum amount of plaintext data that the record layer is
-     * prepared to write in a single record. When calling write_records it is
-     * the caller's responsibility to ensure that no record template exceeds
-     * this maximum when calling write_records.
-     */
-    size_t (*get_max_record_len)(OSSL_RECORD_LAYER *rl);
-
     /*
      * Find out the maximum number of records that the record layer is prepared
      * to process in a single call to write_records. It is the caller's
      * responsibility to ensure that no call to write_records exceeds this
-     * number of records.
+     * number of records. |type| is the type of the records that the caller
+     * wants to write, and |len| is the total amount of data that it wants
+     * to send. |maxfrag| is the maximum allowed fragment size based on user
+     * configuration, or TLS parameter negotiation. |*preffrag| contains on
+     * entry the default fragment size that will actually be used based on user
+     * configuration. This will always be less than or equal to |maxfrag|. On
+     * exit the record layer may update this to an alternative fragment size to
+     * be used. This must always be less than or equal to |maxfrag|.
      */
-    size_t (*get_max_records)(OSSL_RECORD_LAYER *rl);
+    size_t (*get_max_records)(OSSL_RECORD_LAYER *rl, int type, size_t len,
+                              size_t maxfrag, size_t *preffrag);
 
     /*
      * Write |numtempl| records from the array of record templates pointed to
      * by |templates|. Each record should be no longer than the value returned
      * by get_max_record_len(), and there should be no more records than the
      * value returned by get_max_records().
-     * |allowance| is the maximum amount of "on-the-wire" data that is allowed
-     * to be sent at the moment (including all QUIC headers, but excluding any
-     * UDP/IP headers). After a successful or retry return |*sent| will
-     * be updated with the amount of data that has been sent so far. In the case
-     * of a retry this could be 0.
      * Where possible the caller will attempt to ensure that all records are the
      * same length, except the last record. This may not always be possible so
      * the record method implementation should not rely on this being the case.
@@ -200,24 +200,19 @@ struct ossl_record_method_st {
      *  0 on retry
      * -1 on failure
      */
-    int (*write_records)(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE **templates,
-                         size_t numtempl, size_t allowance, size_t *sent);
+    int (*write_records)(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates,
+                         size_t numtempl);
 
     /*
      * Retry a previous call to write_records. The caller should continue to
      * call this until the function returns with success or failure. After
-     * each retry more of the data may have been incrementally sent. |allowance|
-     * is the amount of "on-the-wire" data that is allowed to be sent at the
-     * moment. After a successful or retry return |*sent| will
-     * be updated with the amount of data that has been sent by this call to
-     * retry_write_records().
+     * each retry more of the data may have been incrementally sent.
      * Returns:
      *  1 on success
      *  0 on retry
      * -1 on failure
      */
-    int (*retry_write_records)(OSSL_RECORD_LAYER *rl, size_t allowance,
-                               size_t *sent);
+    int (*retry_write_records)(OSSL_RECORD_LAYER *rl);
 
     /*
      * Read a record and return the record layer version and record type in
@@ -235,8 +230,7 @@ struct ossl_record_method_st {
      */
     int (*read_record)(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion,
                       int *type, unsigned char **data, size_t *datalen,
-                      uint16_t *epoch, unsigned char *seq_num,
-                      /* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s);
+                      uint16_t *epoch, unsigned char *seq_num);
     /*
      * Release a buffer associated with a record previously read with
      * read_record. Records are guaranteed to be released in the order that they
@@ -257,22 +251,85 @@ struct ossl_record_method_st {
      */
     int (*set1_bio)(OSSL_RECORD_LAYER *rl, BIO *bio);
 
+    /* Called when protocol negotiation selects a protocol version to use */
+    int (*set_protocol_version)(OSSL_RECORD_LAYER *rl, int version);
+
+    /*
+     * Whether we are allowed to receive unencrypted alerts, even if we might
+     * otherwise expect encrypted records. Ignored by protocol versions where
+     * this isn't relevant
+     */
+    void (*set_plain_alerts)(OSSL_RECORD_LAYER *rl, int allow);
+
+    /*
+     * Called immediately after creation of the record layer if we are in a
+     * first handshake. Also called at the end of the first handshake
+     */
+    void (*set_first_handshake)(OSSL_RECORD_LAYER *rl, int first);
+
+    /*
+     * Set the maximum number of pipelines that the record layer should process.
+     * The default is 1.
+     */
+    void (*set_max_pipelines)(OSSL_RECORD_LAYER *rl, size_t max_pipelines);
+
+    /*
+     * Called to tell the record layer whether we are currently "in init" or
+     * not. Default at creation of the record layer is "yes".
+     */
+    void (*set_in_init)(OSSL_RECORD_LAYER *rl, int in_init);
+
+    /*
+     * Get a short or long human readable description of the record layer state
+     */
+    void (*get_state)(OSSL_RECORD_LAYER *rl, const char **shortstr,
+                      const char **longstr);
+
+    /*
+     * Set new options or modify ones that were originaly specified in the
+     * new_record_layer call.
+     */
+    int (*set_options)(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options);
+
+    const COMP_METHOD *(*get_compression)(OSSL_RECORD_LAYER *rl);
+
+    /*
+     * Set the maximum fragment length to be used for the record layer. This
+     * will override any previous value supplied for the "max_frag_len"
+     * setting during construction of the record layer.
+     */
+    void (*set_max_frag_len)(OSSL_RECORD_LAYER *rl, size_t max_frag_len);
+
+    /*
+     * The maximum expansion in bytes that the record layer might add while
+     * writing a record
+     */
+    size_t (*get_max_record_overhead)(OSSL_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);
+
     /*
-     * TODO(RECLAYER): Remove these. These function pointers are temporary hacks
-     * during the record layer refactoring. They need to be removed before the
-     * refactor is complete.
+     * Free read or write buffers. Fails if there is pending read or write
+     * data. Buffers are automatically reallocated on next read/write.
      */
-    int (*read_n)(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
-                  int clearold, size_t *readbytes);
-    SSL3_BUFFER *(*get0_rbuf)(OSSL_RECORD_LAYER *rl);
-    unsigned char *(*get0_packet)(OSSL_RECORD_LAYER *rl);
-    void (*set0_packet)(OSSL_RECORD_LAYER *rl, unsigned char *packet,
-                        size_t packetlen);
-    size_t (*get_packet_length)(OSSL_RECORD_LAYER *rl);
-    void (*reset_packet_length)(OSSL_RECORD_LAYER *rl);
+    int (*free_buffers)(OSSL_RECORD_LAYER *rl);
 };
 
 
 /* Standard built-in record methods */
 extern const OSSL_RECORD_METHOD ossl_tls_record_method;
-extern const OSSL_RECORD_METHOD ossl_dtls_record_method;
\ No newline at end of file
+# ifndef OPENSSL_NO_KTLS
+extern const OSSL_RECORD_METHOD ossl_ktls_record_method;
+# endif
+extern const OSSL_RECORD_METHOD ossl_dtls_record_method;
+
+#endif /* !defined(OSSL_INTERNAL_RECORDMETHOD_H) */