xref: /freebsd/crypto/openssl/include/internal/recordmethod.h (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery /*
2*e7be843bSPierre Pronchery  * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery  *
4*e7be843bSPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5*e7be843bSPierre Pronchery  * this file except in compliance with the License.  You can obtain a copy
6*e7be843bSPierre Pronchery  * in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery  * https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery  */
9*e7be843bSPierre Pronchery 
10*e7be843bSPierre Pronchery #ifndef OSSL_INTERNAL_RECORDMETHOD_H
11*e7be843bSPierre Pronchery # define OSSL_INTERNAL_RECORDMETHOD_H
12*e7be843bSPierre Pronchery # pragma once
13*e7be843bSPierre Pronchery 
14*e7be843bSPierre Pronchery # include <openssl/ssl.h>
15*e7be843bSPierre Pronchery 
16*e7be843bSPierre Pronchery /*
17*e7be843bSPierre Pronchery  * We use the term "record" here to refer to a packet of data. Records are
18*e7be843bSPierre Pronchery  * typically protected via a cipher and MAC, or an AEAD cipher (although not
19*e7be843bSPierre Pronchery  * always). This usage of the term record is consistent with the TLS concept.
20*e7be843bSPierre Pronchery  * In QUIC the term "record" is not used but it is analogous to the QUIC term
21*e7be843bSPierre Pronchery  * "packet". The interface in this file applies to all protocols that protect
22*e7be843bSPierre Pronchery  * records/packets of data, i.e. (D)TLS and QUIC. The term record is used to
23*e7be843bSPierre Pronchery  * refer to both contexts.
24*e7be843bSPierre Pronchery  */
25*e7be843bSPierre Pronchery 
26*e7be843bSPierre Pronchery /*
27*e7be843bSPierre Pronchery  * An OSSL_RECORD_METHOD is a protocol specific method which provides the
28*e7be843bSPierre Pronchery  * functions for reading and writing records for that protocol. Which
29*e7be843bSPierre Pronchery  * OSSL_RECORD_METHOD to use for a given protocol is defined by the SSL_METHOD.
30*e7be843bSPierre Pronchery  */
31*e7be843bSPierre Pronchery typedef struct ossl_record_method_st OSSL_RECORD_METHOD;
32*e7be843bSPierre Pronchery 
33*e7be843bSPierre Pronchery /*
34*e7be843bSPierre Pronchery  * An OSSL_RECORD_LAYER is just an externally defined opaque pointer created by
35*e7be843bSPierre Pronchery  * the method
36*e7be843bSPierre Pronchery  */
37*e7be843bSPierre Pronchery typedef struct ossl_record_layer_st OSSL_RECORD_LAYER;
38*e7be843bSPierre Pronchery 
39*e7be843bSPierre Pronchery 
40*e7be843bSPierre Pronchery # define OSSL_RECORD_ROLE_CLIENT 0
41*e7be843bSPierre Pronchery # define OSSL_RECORD_ROLE_SERVER 1
42*e7be843bSPierre Pronchery 
43*e7be843bSPierre Pronchery # define OSSL_RECORD_DIRECTION_READ  0
44*e7be843bSPierre Pronchery # define OSSL_RECORD_DIRECTION_WRITE 1
45*e7be843bSPierre Pronchery 
46*e7be843bSPierre Pronchery # define OSSL_RECORD_RETURN_SUCCESS           1
47*e7be843bSPierre Pronchery # define OSSL_RECORD_RETURN_RETRY             0
48*e7be843bSPierre Pronchery # define OSSL_RECORD_RETURN_NON_FATAL_ERR    -1
49*e7be843bSPierre Pronchery # define OSSL_RECORD_RETURN_FATAL            -2
50*e7be843bSPierre Pronchery # define OSSL_RECORD_RETURN_EOF              -3
51*e7be843bSPierre Pronchery 
52*e7be843bSPierre Pronchery /*
53*e7be843bSPierre Pronchery  * Template for creating a record. A record consists of the |type| of data it
54*e7be843bSPierre Pronchery  * will contain (e.g. alert, handshake, application data, etc) along with a
55*e7be843bSPierre Pronchery  * buffer of payload data in |buf| of length |buflen|.
56*e7be843bSPierre Pronchery  */
57*e7be843bSPierre Pronchery struct ossl_record_template_st {
58*e7be843bSPierre Pronchery     unsigned char type;
59*e7be843bSPierre Pronchery     unsigned int version;
60*e7be843bSPierre Pronchery     const unsigned char *buf;
61*e7be843bSPierre Pronchery     size_t buflen;
62*e7be843bSPierre Pronchery };
63*e7be843bSPierre Pronchery 
64*e7be843bSPierre Pronchery typedef struct ossl_record_template_st OSSL_RECORD_TEMPLATE;
65*e7be843bSPierre Pronchery 
66*e7be843bSPierre Pronchery /*
67*e7be843bSPierre Pronchery  * Rather than a "method" approach, we could make this fetchable - Should we?
68*e7be843bSPierre Pronchery  * There could be some complexity in finding suitable record layer implementations
69*e7be843bSPierre Pronchery  * e.g. we need to find one that matches the negotiated protocol, cipher,
70*e7be843bSPierre Pronchery  * extensions, etc. The selection_cb approach given above doesn't work so well
71*e7be843bSPierre Pronchery  * if unknown third party providers with OSSL_RECORD_METHOD implementations are
72*e7be843bSPierre Pronchery  * loaded.
73*e7be843bSPierre Pronchery  */
74*e7be843bSPierre Pronchery 
75*e7be843bSPierre Pronchery /*
76*e7be843bSPierre Pronchery  * If this becomes public API then we will need functions to create and
77*e7be843bSPierre Pronchery  * free an OSSL_RECORD_METHOD, as well as functions to get/set the various
78*e7be843bSPierre Pronchery  * function pointers....unless we make it fetchable.
79*e7be843bSPierre Pronchery  */
80*e7be843bSPierre Pronchery struct ossl_record_method_st {
81*e7be843bSPierre Pronchery     /*
82*e7be843bSPierre Pronchery      * Create a new OSSL_RECORD_LAYER object for handling the protocol version
83*e7be843bSPierre Pronchery      * set by |vers|. |role| is 0 for client and 1 for server. |direction|
84*e7be843bSPierre Pronchery      * indicates either read or write. |level| is the protection level as
85*e7be843bSPierre Pronchery      * described above. |settings| are mandatory settings that will cause the
86*e7be843bSPierre Pronchery      * new() call to fail if they are not understood (for example to require
87*e7be843bSPierre Pronchery      * Encrypt-Then-Mac support). |options| are optional settings that will not
88*e7be843bSPierre Pronchery      * cause the new() call to fail if they are not understood (for example
89*e7be843bSPierre Pronchery      * whether to use "read ahead" or not).
90*e7be843bSPierre Pronchery      *
91*e7be843bSPierre Pronchery      * The BIO in |transport| is the BIO for the underlying transport layer.
92*e7be843bSPierre Pronchery      * Where the direction is "read", then this BIO will only ever be used for
93*e7be843bSPierre Pronchery      * reading data. Where the direction is "write", then this BIO will only
94*e7be843bSPierre Pronchery      * every be used for writing data.
95*e7be843bSPierre Pronchery      *
96*e7be843bSPierre Pronchery      * An SSL object will always have at least 2 OSSL_RECORD_LAYER objects in
97*e7be843bSPierre Pronchery      * force at any one time (one for reading and one for writing). In some
98*e7be843bSPierre Pronchery      * protocols more than 2 might be used (e.g. in DTLS for retransmitting
99*e7be843bSPierre Pronchery      * messages from an earlier epoch).
100*e7be843bSPierre Pronchery      *
101*e7be843bSPierre Pronchery      * The created OSSL_RECORD_LAYER object is stored in *ret on success (or
102*e7be843bSPierre Pronchery      * NULL otherwise). The return value will be one of
103*e7be843bSPierre Pronchery      * OSSL_RECORD_RETURN_SUCCESS, OSSL_RECORD_RETURN_FATAL or
104*e7be843bSPierre Pronchery      * OSSL_RECORD_RETURN_NON_FATAL. A non-fatal return means that creation of
105*e7be843bSPierre Pronchery      * the record layer has failed because it is unsuitable, but an alternative
106*e7be843bSPierre Pronchery      * record layer can be tried instead.
107*e7be843bSPierre Pronchery      */
108*e7be843bSPierre Pronchery 
109*e7be843bSPierre Pronchery     /*
110*e7be843bSPierre Pronchery      * If we eventually make this fetchable then we will need to use something
111*e7be843bSPierre Pronchery      * other than EVP_CIPHER. Also mactype would not be a NID, but a string. For
112*e7be843bSPierre Pronchery      * now though, this works.
113*e7be843bSPierre Pronchery      */
114*e7be843bSPierre Pronchery     int (*new_record_layer)(OSSL_LIB_CTX *libctx,
115*e7be843bSPierre Pronchery                             const char *propq, int vers,
116*e7be843bSPierre Pronchery                             int role, int direction,
117*e7be843bSPierre Pronchery                             int level,
118*e7be843bSPierre Pronchery                             uint16_t epoch,
119*e7be843bSPierre Pronchery                             unsigned char *secret,
120*e7be843bSPierre Pronchery                             size_t secretlen,
121*e7be843bSPierre Pronchery                             unsigned char *key,
122*e7be843bSPierre Pronchery                             size_t keylen,
123*e7be843bSPierre Pronchery                             unsigned char *iv,
124*e7be843bSPierre Pronchery                             size_t ivlen,
125*e7be843bSPierre Pronchery                             unsigned char *mackey,
126*e7be843bSPierre Pronchery                             size_t mackeylen,
127*e7be843bSPierre Pronchery                             const EVP_CIPHER *ciph,
128*e7be843bSPierre Pronchery                             size_t taglen,
129*e7be843bSPierre Pronchery                             int mactype,
130*e7be843bSPierre Pronchery                             const EVP_MD *md,
131*e7be843bSPierre Pronchery                             COMP_METHOD *comp,
132*e7be843bSPierre Pronchery                             const EVP_MD *kdfdigest,
133*e7be843bSPierre Pronchery                             BIO *prev,
134*e7be843bSPierre Pronchery                             BIO *transport,
135*e7be843bSPierre Pronchery                             BIO *next,
136*e7be843bSPierre Pronchery                             BIO_ADDR *local,
137*e7be843bSPierre Pronchery                             BIO_ADDR *peer,
138*e7be843bSPierre Pronchery                             const OSSL_PARAM *settings,
139*e7be843bSPierre Pronchery                             const OSSL_PARAM *options,
140*e7be843bSPierre Pronchery                             const OSSL_DISPATCH *fns,
141*e7be843bSPierre Pronchery                             void *cbarg,
142*e7be843bSPierre Pronchery                             void *rlarg,
143*e7be843bSPierre Pronchery                             OSSL_RECORD_LAYER **ret);
144*e7be843bSPierre Pronchery     int (*free)(OSSL_RECORD_LAYER *rl);
145*e7be843bSPierre Pronchery 
146*e7be843bSPierre Pronchery     /* Returns 1 if we have unprocessed data buffered or 0 otherwise */
147*e7be843bSPierre Pronchery     int (*unprocessed_read_pending)(OSSL_RECORD_LAYER *rl);
148*e7be843bSPierre Pronchery 
149*e7be843bSPierre Pronchery     /*
150*e7be843bSPierre Pronchery      * Returns 1 if we have processed data buffered that can be read or 0 otherwise
151*e7be843bSPierre Pronchery      * - not necessarily app data
152*e7be843bSPierre Pronchery      */
153*e7be843bSPierre Pronchery     int (*processed_read_pending)(OSSL_RECORD_LAYER *rl);
154*e7be843bSPierre Pronchery 
155*e7be843bSPierre Pronchery     /*
156*e7be843bSPierre Pronchery      * The amount of processed app data that is internally buffered and
157*e7be843bSPierre Pronchery      * available to read
158*e7be843bSPierre Pronchery      */
159*e7be843bSPierre Pronchery     size_t (*app_data_pending)(OSSL_RECORD_LAYER *rl);
160*e7be843bSPierre Pronchery 
161*e7be843bSPierre Pronchery     /*
162*e7be843bSPierre Pronchery      * Find out the maximum number of records that the record layer is prepared
163*e7be843bSPierre Pronchery      * to process in a single call to write_records. It is the caller's
164*e7be843bSPierre Pronchery      * responsibility to ensure that no call to write_records exceeds this
165*e7be843bSPierre Pronchery      * number of records. |type| is the type of the records that the caller
166*e7be843bSPierre Pronchery      * wants to write, and |len| is the total amount of data that it wants
167*e7be843bSPierre Pronchery      * to send. |maxfrag| is the maximum allowed fragment size based on user
168*e7be843bSPierre Pronchery      * configuration, or TLS parameter negotiation. |*preffrag| contains on
169*e7be843bSPierre Pronchery      * entry the default fragment size that will actually be used based on user
170*e7be843bSPierre Pronchery      * configuration. This will always be less than or equal to |maxfrag|. On
171*e7be843bSPierre Pronchery      * exit the record layer may update this to an alternative fragment size to
172*e7be843bSPierre Pronchery      * be used. This must always be less than or equal to |maxfrag|.
173*e7be843bSPierre Pronchery      */
174*e7be843bSPierre Pronchery     size_t (*get_max_records)(OSSL_RECORD_LAYER *rl, uint8_t type, size_t len,
175*e7be843bSPierre Pronchery                               size_t maxfrag, size_t *preffrag);
176*e7be843bSPierre Pronchery 
177*e7be843bSPierre Pronchery     /*
178*e7be843bSPierre Pronchery      * Write |numtempl| records from the array of record templates pointed to
179*e7be843bSPierre Pronchery      * by |templates|. Each record should be no longer than the value returned
180*e7be843bSPierre Pronchery      * by get_max_record_len(), and there should be no more records than the
181*e7be843bSPierre Pronchery      * value returned by get_max_records().
182*e7be843bSPierre Pronchery      * Where possible the caller will attempt to ensure that all records are the
183*e7be843bSPierre Pronchery      * same length, except the last record. This may not always be possible so
184*e7be843bSPierre Pronchery      * the record method implementation should not rely on this being the case.
185*e7be843bSPierre Pronchery      * In the event of a retry the caller should call retry_write_records()
186*e7be843bSPierre Pronchery      * to try again. No more calls to write_records() should be attempted until
187*e7be843bSPierre Pronchery      * retry_write_records() returns success.
188*e7be843bSPierre Pronchery      * Buffers allocated for the record templates can be freed immediately after
189*e7be843bSPierre Pronchery      * write_records() returns - even in the case a retry.
190*e7be843bSPierre Pronchery      * The record templates represent the plaintext payload. The encrypted
191*e7be843bSPierre Pronchery      * output is written to the |transport| BIO.
192*e7be843bSPierre Pronchery      * Returns:
193*e7be843bSPierre Pronchery      *  1 on success
194*e7be843bSPierre Pronchery      *  0 on retry
195*e7be843bSPierre Pronchery      * -1 on failure
196*e7be843bSPierre Pronchery      */
197*e7be843bSPierre Pronchery     int (*write_records)(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates,
198*e7be843bSPierre Pronchery                          size_t numtempl);
199*e7be843bSPierre Pronchery 
200*e7be843bSPierre Pronchery     /*
201*e7be843bSPierre Pronchery      * Retry a previous call to write_records. The caller should continue to
202*e7be843bSPierre Pronchery      * call this until the function returns with success or failure. After
203*e7be843bSPierre Pronchery      * each retry more of the data may have been incrementally sent.
204*e7be843bSPierre Pronchery      * Returns:
205*e7be843bSPierre Pronchery      *  1 on success
206*e7be843bSPierre Pronchery      *  0 on retry
207*e7be843bSPierre Pronchery      * -1 on failure
208*e7be843bSPierre Pronchery      */
209*e7be843bSPierre Pronchery     int (*retry_write_records)(OSSL_RECORD_LAYER *rl);
210*e7be843bSPierre Pronchery 
211*e7be843bSPierre Pronchery     /*
212*e7be843bSPierre Pronchery      * Read a record and return the record layer version and record type in
213*e7be843bSPierre Pronchery      * the |rversion| and |type| parameters. |*data| is set to point to a
214*e7be843bSPierre Pronchery      * record layer buffer containing the record payload data and |*datalen|
215*e7be843bSPierre Pronchery      * is filled in with the length of that data. The |epoch| and |seq_num|
216*e7be843bSPierre Pronchery      * values are only used if DTLS has been negotiated. In that case they are
217*e7be843bSPierre Pronchery      * filled in with the epoch and sequence number from the record.
218*e7be843bSPierre Pronchery      * An opaque record layer handle for the record is returned in |*rechandle|
219*e7be843bSPierre Pronchery      * which is used in a subsequent call to |release_record|. The buffer must
220*e7be843bSPierre Pronchery      * remain available until all the bytes from record are released via one or
221*e7be843bSPierre Pronchery      * more release_record calls.
222*e7be843bSPierre Pronchery      *
223*e7be843bSPierre Pronchery      * Internally the OSSL_RECORD_METHOD implementation may read/process
224*e7be843bSPierre Pronchery      * multiple records in one go and buffer them.
225*e7be843bSPierre Pronchery      */
226*e7be843bSPierre Pronchery     int (*read_record)(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion,
227*e7be843bSPierre Pronchery                       uint8_t *type, const unsigned char **data, size_t *datalen,
228*e7be843bSPierre Pronchery                       uint16_t *epoch, unsigned char *seq_num);
229*e7be843bSPierre Pronchery     /*
230*e7be843bSPierre Pronchery      * Release length bytes from a buffer associated with a record previously
231*e7be843bSPierre Pronchery      * read with read_record. Once all the bytes from a record are released, the
232*e7be843bSPierre Pronchery      * whole record and its associated buffer is released. Records are
233*e7be843bSPierre Pronchery      * guaranteed to be released in the order that they are read.
234*e7be843bSPierre Pronchery      */
235*e7be843bSPierre Pronchery     int (*release_record)(OSSL_RECORD_LAYER *rl, void *rechandle, size_t length);
236*e7be843bSPierre Pronchery 
237*e7be843bSPierre Pronchery     /*
238*e7be843bSPierre Pronchery      * In the event that a fatal error is returned from the functions above then
239*e7be843bSPierre Pronchery      * get_alert_code() can be called to obtain a more details identifier for
240*e7be843bSPierre Pronchery      * the error. In (D)TLS this is the alert description code.
241*e7be843bSPierre Pronchery      */
242*e7be843bSPierre Pronchery     int (*get_alert_code)(OSSL_RECORD_LAYER *rl);
243*e7be843bSPierre Pronchery 
244*e7be843bSPierre Pronchery     /*
245*e7be843bSPierre Pronchery      * Update the transport BIO from the one originally set in the
246*e7be843bSPierre Pronchery      * new_record_layer call
247*e7be843bSPierre Pronchery      */
248*e7be843bSPierre Pronchery     int (*set1_bio)(OSSL_RECORD_LAYER *rl, BIO *bio);
249*e7be843bSPierre Pronchery 
250*e7be843bSPierre Pronchery     /* Called when protocol negotiation selects a protocol version to use */
251*e7be843bSPierre Pronchery     int (*set_protocol_version)(OSSL_RECORD_LAYER *rl, int version);
252*e7be843bSPierre Pronchery 
253*e7be843bSPierre Pronchery     /*
254*e7be843bSPierre Pronchery      * Whether we are allowed to receive unencrypted alerts, even if we might
255*e7be843bSPierre Pronchery      * otherwise expect encrypted records. Ignored by protocol versions where
256*e7be843bSPierre Pronchery      * this isn't relevant
257*e7be843bSPierre Pronchery      */
258*e7be843bSPierre Pronchery     void (*set_plain_alerts)(OSSL_RECORD_LAYER *rl, int allow);
259*e7be843bSPierre Pronchery 
260*e7be843bSPierre Pronchery     /*
261*e7be843bSPierre Pronchery      * Called immediately after creation of the record layer if we are in a
262*e7be843bSPierre Pronchery      * first handshake. Also called at the end of the first handshake
263*e7be843bSPierre Pronchery      */
264*e7be843bSPierre Pronchery     void (*set_first_handshake)(OSSL_RECORD_LAYER *rl, int first);
265*e7be843bSPierre Pronchery 
266*e7be843bSPierre Pronchery     /*
267*e7be843bSPierre Pronchery      * Set the maximum number of pipelines that the record layer should process.
268*e7be843bSPierre Pronchery      * The default is 1.
269*e7be843bSPierre Pronchery      */
270*e7be843bSPierre Pronchery     void (*set_max_pipelines)(OSSL_RECORD_LAYER *rl, size_t max_pipelines);
271*e7be843bSPierre Pronchery 
272*e7be843bSPierre Pronchery     /*
273*e7be843bSPierre Pronchery      * Called to tell the record layer whether we are currently "in init" or
274*e7be843bSPierre Pronchery      * not. Default at creation of the record layer is "yes".
275*e7be843bSPierre Pronchery      */
276*e7be843bSPierre Pronchery     void (*set_in_init)(OSSL_RECORD_LAYER *rl, int in_init);
277*e7be843bSPierre Pronchery 
278*e7be843bSPierre Pronchery     /*
279*e7be843bSPierre Pronchery      * Get a short or long human readable description of the record layer state
280*e7be843bSPierre Pronchery      */
281*e7be843bSPierre Pronchery     void (*get_state)(OSSL_RECORD_LAYER *rl, const char **shortstr,
282*e7be843bSPierre Pronchery                       const char **longstr);
283*e7be843bSPierre Pronchery 
284*e7be843bSPierre Pronchery     /*
285*e7be843bSPierre Pronchery      * Set new options or modify ones that were originally specified in the
286*e7be843bSPierre Pronchery      * new_record_layer call.
287*e7be843bSPierre Pronchery      */
288*e7be843bSPierre Pronchery     int (*set_options)(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options);
289*e7be843bSPierre Pronchery 
290*e7be843bSPierre Pronchery     const COMP_METHOD *(*get_compression)(OSSL_RECORD_LAYER *rl);
291*e7be843bSPierre Pronchery 
292*e7be843bSPierre Pronchery     /*
293*e7be843bSPierre Pronchery      * Set the maximum fragment length to be used for the record layer. This
294*e7be843bSPierre Pronchery      * will override any previous value supplied for the "max_frag_len"
295*e7be843bSPierre Pronchery      * setting during construction of the record layer.
296*e7be843bSPierre Pronchery      */
297*e7be843bSPierre Pronchery     void (*set_max_frag_len)(OSSL_RECORD_LAYER *rl, size_t max_frag_len);
298*e7be843bSPierre Pronchery 
299*e7be843bSPierre Pronchery     /*
300*e7be843bSPierre Pronchery      * The maximum expansion in bytes that the record layer might add while
301*e7be843bSPierre Pronchery      * writing a record
302*e7be843bSPierre Pronchery      */
303*e7be843bSPierre Pronchery     size_t (*get_max_record_overhead)(OSSL_RECORD_LAYER *rl);
304*e7be843bSPierre Pronchery 
305*e7be843bSPierre Pronchery     /*
306*e7be843bSPierre Pronchery      * Increment the record sequence number
307*e7be843bSPierre Pronchery      */
308*e7be843bSPierre Pronchery     int (*increment_sequence_ctr)(OSSL_RECORD_LAYER *rl);
309*e7be843bSPierre Pronchery 
310*e7be843bSPierre Pronchery     /*
311*e7be843bSPierre Pronchery      * Allocate read or write buffers. Does nothing if already allocated.
312*e7be843bSPierre Pronchery      * Assumes default buffer length and 1 pipeline.
313*e7be843bSPierre Pronchery      */
314*e7be843bSPierre Pronchery     int (*alloc_buffers)(OSSL_RECORD_LAYER *rl);
315*e7be843bSPierre Pronchery 
316*e7be843bSPierre Pronchery     /*
317*e7be843bSPierre Pronchery      * Free read or write buffers. Fails if there is pending read or write
318*e7be843bSPierre Pronchery      * data. Buffers are automatically reallocated on next read/write.
319*e7be843bSPierre Pronchery      */
320*e7be843bSPierre Pronchery     int (*free_buffers)(OSSL_RECORD_LAYER *rl);
321*e7be843bSPierre Pronchery };
322*e7be843bSPierre Pronchery 
323*e7be843bSPierre Pronchery 
324*e7be843bSPierre Pronchery /* Standard built-in record methods */
325*e7be843bSPierre Pronchery extern const OSSL_RECORD_METHOD ossl_tls_record_method;
326*e7be843bSPierre Pronchery # ifndef OPENSSL_NO_KTLS
327*e7be843bSPierre Pronchery extern const OSSL_RECORD_METHOD ossl_ktls_record_method;
328*e7be843bSPierre Pronchery # endif
329*e7be843bSPierre Pronchery extern const OSSL_RECORD_METHOD ossl_dtls_record_method;
330*e7be843bSPierre Pronchery 
331*e7be843bSPierre Pronchery #endif /* !defined(OSSL_INTERNAL_RECORDMETHOD_H) */
332