1e71b7053SJung-uk Kim /*
2*b077aed3SPierre Pronchery * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim *
4*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy
6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html
8e71b7053SJung-uk Kim */
9e71b7053SJung-uk Kim
10e71b7053SJung-uk Kim #include <stdio.h>
11e71b7053SJung-uk Kim #include <errno.h>
1217f01e99SJung-uk Kim #include "../ssl_local.h"
13e71b7053SJung-uk Kim #include <openssl/evp.h>
14e71b7053SJung-uk Kim #include <openssl/buffer.h>
1517f01e99SJung-uk Kim #include "record_local.h"
16*b077aed3SPierre Pronchery #include "internal/packet.h"
17e71b7053SJung-uk Kim #include "internal/cryptlib.h"
18e71b7053SJung-uk Kim
DTLS_RECORD_LAYER_new(RECORD_LAYER * rl)19e71b7053SJung-uk Kim int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl)
20e71b7053SJung-uk Kim {
21e71b7053SJung-uk Kim DTLS_RECORD_LAYER *d;
22e71b7053SJung-uk Kim
23e71b7053SJung-uk Kim if ((d = OPENSSL_malloc(sizeof(*d))) == NULL) {
24*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
25e71b7053SJung-uk Kim return 0;
26e71b7053SJung-uk Kim }
27e71b7053SJung-uk Kim
28e71b7053SJung-uk Kim rl->d = d;
29e71b7053SJung-uk Kim
30e71b7053SJung-uk Kim d->unprocessed_rcds.q = pqueue_new();
31e71b7053SJung-uk Kim d->processed_rcds.q = pqueue_new();
32e71b7053SJung-uk Kim d->buffered_app_data.q = pqueue_new();
33e71b7053SJung-uk Kim
34e71b7053SJung-uk Kim if (d->unprocessed_rcds.q == NULL || d->processed_rcds.q == NULL
35e71b7053SJung-uk Kim || d->buffered_app_data.q == NULL) {
36e71b7053SJung-uk Kim pqueue_free(d->unprocessed_rcds.q);
37e71b7053SJung-uk Kim pqueue_free(d->processed_rcds.q);
38e71b7053SJung-uk Kim pqueue_free(d->buffered_app_data.q);
39e71b7053SJung-uk Kim OPENSSL_free(d);
40e71b7053SJung-uk Kim rl->d = NULL;
41e71b7053SJung-uk Kim return 0;
42e71b7053SJung-uk Kim }
43e71b7053SJung-uk Kim
44e71b7053SJung-uk Kim return 1;
45e71b7053SJung-uk Kim }
46e71b7053SJung-uk Kim
DTLS_RECORD_LAYER_free(RECORD_LAYER * rl)47e71b7053SJung-uk Kim void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl)
48e71b7053SJung-uk Kim {
4988e852c0SJung-uk Kim if (rl->d == NULL)
5088e852c0SJung-uk Kim return;
5188e852c0SJung-uk Kim
52e71b7053SJung-uk Kim DTLS_RECORD_LAYER_clear(rl);
53e71b7053SJung-uk Kim pqueue_free(rl->d->unprocessed_rcds.q);
54e71b7053SJung-uk Kim pqueue_free(rl->d->processed_rcds.q);
55e71b7053SJung-uk Kim pqueue_free(rl->d->buffered_app_data.q);
56e71b7053SJung-uk Kim OPENSSL_free(rl->d);
57e71b7053SJung-uk Kim rl->d = NULL;
58e71b7053SJung-uk Kim }
59e71b7053SJung-uk Kim
DTLS_RECORD_LAYER_clear(RECORD_LAYER * rl)60e71b7053SJung-uk Kim void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl)
61e71b7053SJung-uk Kim {
62e71b7053SJung-uk Kim DTLS_RECORD_LAYER *d;
63e71b7053SJung-uk Kim pitem *item = NULL;
64e71b7053SJung-uk Kim DTLS1_RECORD_DATA *rdata;
65e71b7053SJung-uk Kim pqueue *unprocessed_rcds;
66e71b7053SJung-uk Kim pqueue *processed_rcds;
67e71b7053SJung-uk Kim pqueue *buffered_app_data;
68e71b7053SJung-uk Kim
69e71b7053SJung-uk Kim d = rl->d;
70e71b7053SJung-uk Kim
71e71b7053SJung-uk Kim while ((item = pqueue_pop(d->unprocessed_rcds.q)) != NULL) {
72e71b7053SJung-uk Kim rdata = (DTLS1_RECORD_DATA *)item->data;
73e71b7053SJung-uk Kim OPENSSL_free(rdata->rbuf.buf);
74e71b7053SJung-uk Kim OPENSSL_free(item->data);
75e71b7053SJung-uk Kim pitem_free(item);
76e71b7053SJung-uk Kim }
77e71b7053SJung-uk Kim
78e71b7053SJung-uk Kim while ((item = pqueue_pop(d->processed_rcds.q)) != NULL) {
79e71b7053SJung-uk Kim rdata = (DTLS1_RECORD_DATA *)item->data;
80*b077aed3SPierre Pronchery if (rl->s->options & SSL_OP_CLEANSE_PLAINTEXT)
81*b077aed3SPierre Pronchery OPENSSL_cleanse(rdata->rbuf.buf, rdata->rbuf.len);
82e71b7053SJung-uk Kim OPENSSL_free(rdata->rbuf.buf);
83e71b7053SJung-uk Kim OPENSSL_free(item->data);
84e71b7053SJung-uk Kim pitem_free(item);
85e71b7053SJung-uk Kim }
86e71b7053SJung-uk Kim
87e71b7053SJung-uk Kim while ((item = pqueue_pop(d->buffered_app_data.q)) != NULL) {
88e71b7053SJung-uk Kim rdata = (DTLS1_RECORD_DATA *)item->data;
89*b077aed3SPierre Pronchery if (rl->s->options & SSL_OP_CLEANSE_PLAINTEXT)
90*b077aed3SPierre Pronchery OPENSSL_cleanse(rdata->rbuf.buf, rdata->rbuf.len);
91e71b7053SJung-uk Kim OPENSSL_free(rdata->rbuf.buf);
92e71b7053SJung-uk Kim OPENSSL_free(item->data);
93e71b7053SJung-uk Kim pitem_free(item);
94e71b7053SJung-uk Kim }
95e71b7053SJung-uk Kim
96e71b7053SJung-uk Kim unprocessed_rcds = d->unprocessed_rcds.q;
97e71b7053SJung-uk Kim processed_rcds = d->processed_rcds.q;
98e71b7053SJung-uk Kim buffered_app_data = d->buffered_app_data.q;
99e71b7053SJung-uk Kim memset(d, 0, sizeof(*d));
100e71b7053SJung-uk Kim d->unprocessed_rcds.q = unprocessed_rcds;
101e71b7053SJung-uk Kim d->processed_rcds.q = processed_rcds;
102e71b7053SJung-uk Kim d->buffered_app_data.q = buffered_app_data;
103e71b7053SJung-uk Kim }
104e71b7053SJung-uk Kim
DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER * rl,unsigned short e)105e71b7053SJung-uk Kim void DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER *rl, unsigned short e)
106e71b7053SJung-uk Kim {
107e71b7053SJung-uk Kim if (e == rl->d->w_epoch - 1) {
108e71b7053SJung-uk Kim memcpy(rl->d->curr_write_sequence,
109e71b7053SJung-uk Kim rl->write_sequence, sizeof(rl->write_sequence));
110e71b7053SJung-uk Kim memcpy(rl->write_sequence,
111e71b7053SJung-uk Kim rl->d->last_write_sequence, sizeof(rl->write_sequence));
112e71b7053SJung-uk Kim } else if (e == rl->d->w_epoch + 1) {
113e71b7053SJung-uk Kim memcpy(rl->d->last_write_sequence,
114e71b7053SJung-uk Kim rl->write_sequence, sizeof(unsigned char[8]));
115e71b7053SJung-uk Kim memcpy(rl->write_sequence,
116e71b7053SJung-uk Kim rl->d->curr_write_sequence, sizeof(rl->write_sequence));
117e71b7053SJung-uk Kim }
118e71b7053SJung-uk Kim rl->d->w_epoch = e;
119e71b7053SJung-uk Kim }
120e71b7053SJung-uk Kim
DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER * rl,unsigned char * seq)121e71b7053SJung-uk Kim void DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, unsigned char *seq)
122e71b7053SJung-uk Kim {
123e71b7053SJung-uk Kim memcpy(rl->write_sequence, seq, SEQ_NUM_SIZE);
124e71b7053SJung-uk Kim }
125e71b7053SJung-uk Kim
126e71b7053SJung-uk Kim /* copy buffered record into SSL structure */
dtls1_copy_record(SSL * s,pitem * item)127e71b7053SJung-uk Kim static int dtls1_copy_record(SSL *s, pitem *item)
128e71b7053SJung-uk Kim {
129e71b7053SJung-uk Kim DTLS1_RECORD_DATA *rdata;
130e71b7053SJung-uk Kim
131e71b7053SJung-uk Kim rdata = (DTLS1_RECORD_DATA *)item->data;
132e71b7053SJung-uk Kim
133e71b7053SJung-uk Kim SSL3_BUFFER_release(&s->rlayer.rbuf);
134e71b7053SJung-uk Kim
135e71b7053SJung-uk Kim s->rlayer.packet = rdata->packet;
136e71b7053SJung-uk Kim s->rlayer.packet_length = rdata->packet_length;
137e71b7053SJung-uk Kim memcpy(&s->rlayer.rbuf, &(rdata->rbuf), sizeof(SSL3_BUFFER));
138e71b7053SJung-uk Kim memcpy(&s->rlayer.rrec, &(rdata->rrec), sizeof(SSL3_RECORD));
139e71b7053SJung-uk Kim
140e71b7053SJung-uk Kim /* Set proper sequence number for mac calculation */
141e71b7053SJung-uk Kim memcpy(&(s->rlayer.read_sequence[2]), &(rdata->packet[5]), 6);
142e71b7053SJung-uk Kim
143e71b7053SJung-uk Kim return 1;
144e71b7053SJung-uk Kim }
145e71b7053SJung-uk Kim
dtls1_buffer_record(SSL * s,record_pqueue * queue,unsigned char * priority)146e71b7053SJung-uk Kim int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
147e71b7053SJung-uk Kim {
148e71b7053SJung-uk Kim DTLS1_RECORD_DATA *rdata;
149e71b7053SJung-uk Kim pitem *item;
150e71b7053SJung-uk Kim
151e71b7053SJung-uk Kim /* Limit the size of the queue to prevent DOS attacks */
152e71b7053SJung-uk Kim if (pqueue_size(queue->q) >= 100)
153e71b7053SJung-uk Kim return 0;
154e71b7053SJung-uk Kim
155e71b7053SJung-uk Kim rdata = OPENSSL_malloc(sizeof(*rdata));
156e71b7053SJung-uk Kim item = pitem_new(priority, rdata);
157e71b7053SJung-uk Kim if (rdata == NULL || item == NULL) {
158e71b7053SJung-uk Kim OPENSSL_free(rdata);
159e71b7053SJung-uk Kim pitem_free(item);
160*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
161e71b7053SJung-uk Kim return -1;
162e71b7053SJung-uk Kim }
163e71b7053SJung-uk Kim
164e71b7053SJung-uk Kim rdata->packet = s->rlayer.packet;
165e71b7053SJung-uk Kim rdata->packet_length = s->rlayer.packet_length;
166e71b7053SJung-uk Kim memcpy(&(rdata->rbuf), &s->rlayer.rbuf, sizeof(SSL3_BUFFER));
167e71b7053SJung-uk Kim memcpy(&(rdata->rrec), &s->rlayer.rrec, sizeof(SSL3_RECORD));
168e71b7053SJung-uk Kim
169e71b7053SJung-uk Kim item->data = rdata;
170e71b7053SJung-uk Kim
171e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP
172e71b7053SJung-uk Kim /* Store bio_dgram_sctp_rcvinfo struct */
173e71b7053SJung-uk Kim if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
174e71b7053SJung-uk Kim (SSL_get_state(s) == TLS_ST_SR_FINISHED
175e71b7053SJung-uk Kim || SSL_get_state(s) == TLS_ST_CR_FINISHED)) {
176e71b7053SJung-uk Kim BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO,
177e71b7053SJung-uk Kim sizeof(rdata->recordinfo), &rdata->recordinfo);
178e71b7053SJung-uk Kim }
179e71b7053SJung-uk Kim #endif
180e71b7053SJung-uk Kim
181e71b7053SJung-uk Kim s->rlayer.packet = NULL;
182e71b7053SJung-uk Kim s->rlayer.packet_length = 0;
183e71b7053SJung-uk Kim memset(&s->rlayer.rbuf, 0, sizeof(s->rlayer.rbuf));
184e71b7053SJung-uk Kim memset(&s->rlayer.rrec, 0, sizeof(s->rlayer.rrec));
185e71b7053SJung-uk Kim
186e71b7053SJung-uk Kim if (!ssl3_setup_buffers(s)) {
187e71b7053SJung-uk Kim /* SSLfatal() already called */
188e71b7053SJung-uk Kim OPENSSL_free(rdata->rbuf.buf);
189e71b7053SJung-uk Kim OPENSSL_free(rdata);
190e71b7053SJung-uk Kim pitem_free(item);
191e71b7053SJung-uk Kim return -1;
192e71b7053SJung-uk Kim }
193e71b7053SJung-uk Kim
194e71b7053SJung-uk Kim if (pqueue_insert(queue->q, item) == NULL) {
195c9cf7b5cSJung-uk Kim /* Must be a duplicate so ignore it */
196e71b7053SJung-uk Kim OPENSSL_free(rdata->rbuf.buf);
197e71b7053SJung-uk Kim OPENSSL_free(rdata);
198e71b7053SJung-uk Kim pitem_free(item);
199e71b7053SJung-uk Kim }
200e71b7053SJung-uk Kim
201e71b7053SJung-uk Kim return 1;
202e71b7053SJung-uk Kim }
203e71b7053SJung-uk Kim
dtls1_retrieve_buffered_record(SSL * s,record_pqueue * queue)204e71b7053SJung-uk Kim int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
205e71b7053SJung-uk Kim {
206e71b7053SJung-uk Kim pitem *item;
207e71b7053SJung-uk Kim
208e71b7053SJung-uk Kim item = pqueue_pop(queue->q);
209e71b7053SJung-uk Kim if (item) {
210e71b7053SJung-uk Kim dtls1_copy_record(s, item);
211e71b7053SJung-uk Kim
212e71b7053SJung-uk Kim OPENSSL_free(item->data);
213e71b7053SJung-uk Kim pitem_free(item);
214e71b7053SJung-uk Kim
215e71b7053SJung-uk Kim return 1;
216e71b7053SJung-uk Kim }
217e71b7053SJung-uk Kim
218e71b7053SJung-uk Kim return 0;
219e71b7053SJung-uk Kim }
220e71b7053SJung-uk Kim
221e71b7053SJung-uk Kim /*
222e71b7053SJung-uk Kim * retrieve a buffered record that belongs to the new epoch, i.e., not
223e71b7053SJung-uk Kim * processed yet
224e71b7053SJung-uk Kim */
225e71b7053SJung-uk Kim #define dtls1_get_unprocessed_record(s) \
226e71b7053SJung-uk Kim dtls1_retrieve_buffered_record((s), \
227e71b7053SJung-uk Kim &((s)->rlayer.d->unprocessed_rcds))
228e71b7053SJung-uk Kim
dtls1_process_buffered_records(SSL * s)229e71b7053SJung-uk Kim int dtls1_process_buffered_records(SSL *s)
230e71b7053SJung-uk Kim {
231e71b7053SJung-uk Kim pitem *item;
232e71b7053SJung-uk Kim SSL3_BUFFER *rb;
233e71b7053SJung-uk Kim SSL3_RECORD *rr;
234e71b7053SJung-uk Kim DTLS1_BITMAP *bitmap;
235e71b7053SJung-uk Kim unsigned int is_next_epoch;
236e71b7053SJung-uk Kim int replayok = 1;
237e71b7053SJung-uk Kim
238e71b7053SJung-uk Kim item = pqueue_peek(s->rlayer.d->unprocessed_rcds.q);
239e71b7053SJung-uk Kim if (item) {
240e71b7053SJung-uk Kim /* Check if epoch is current. */
241e71b7053SJung-uk Kim if (s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch)
242e71b7053SJung-uk Kim return 1; /* Nothing to do. */
243e71b7053SJung-uk Kim
244e71b7053SJung-uk Kim rr = RECORD_LAYER_get_rrec(&s->rlayer);
245e71b7053SJung-uk Kim
246e71b7053SJung-uk Kim rb = RECORD_LAYER_get_rbuf(&s->rlayer);
247e71b7053SJung-uk Kim
248e71b7053SJung-uk Kim if (SSL3_BUFFER_get_left(rb) > 0) {
249e71b7053SJung-uk Kim /*
250e71b7053SJung-uk Kim * We've still got data from the current packet to read. There could
251e71b7053SJung-uk Kim * be a record from the new epoch in it - so don't overwrite it
252e71b7053SJung-uk Kim * with the unprocessed records yet (we'll do it when we've
253e71b7053SJung-uk Kim * finished reading the current packet).
254e71b7053SJung-uk Kim */
255e71b7053SJung-uk Kim return 1;
256e71b7053SJung-uk Kim }
257e71b7053SJung-uk Kim
258e71b7053SJung-uk Kim /* Process all the records. */
259e71b7053SJung-uk Kim while (pqueue_peek(s->rlayer.d->unprocessed_rcds.q)) {
260e71b7053SJung-uk Kim dtls1_get_unprocessed_record(s);
261e71b7053SJung-uk Kim bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
262e71b7053SJung-uk Kim if (bitmap == NULL) {
263e71b7053SJung-uk Kim /*
264e71b7053SJung-uk Kim * Should not happen. This will only ever be NULL when the
265e71b7053SJung-uk Kim * current record is from a different epoch. But that cannot
266e71b7053SJung-uk Kim * be the case because we already checked the epoch above
267e71b7053SJung-uk Kim */
268*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
269e71b7053SJung-uk Kim return 0;
270e71b7053SJung-uk Kim }
271e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP
272e71b7053SJung-uk Kim /* Only do replay check if no SCTP bio */
273e71b7053SJung-uk Kim if (!BIO_dgram_is_sctp(SSL_get_rbio(s)))
274e71b7053SJung-uk Kim #endif
275e71b7053SJung-uk Kim {
276e71b7053SJung-uk Kim /*
277e71b7053SJung-uk Kim * Check whether this is a repeat, or aged record. We did this
278e71b7053SJung-uk Kim * check once already when we first received the record - but
279e71b7053SJung-uk Kim * we might have updated the window since then due to
280e71b7053SJung-uk Kim * records we subsequently processed.
281e71b7053SJung-uk Kim */
282e71b7053SJung-uk Kim replayok = dtls1_record_replay_check(s, bitmap);
283e71b7053SJung-uk Kim }
284e71b7053SJung-uk Kim
285e71b7053SJung-uk Kim if (!replayok || !dtls1_process_record(s, bitmap)) {
286e71b7053SJung-uk Kim if (ossl_statem_in_error(s)) {
287e71b7053SJung-uk Kim /* dtls1_process_record called SSLfatal() */
288*b077aed3SPierre Pronchery return 0;
289e71b7053SJung-uk Kim }
290e71b7053SJung-uk Kim /* dump this record */
291e71b7053SJung-uk Kim rr->length = 0;
292e71b7053SJung-uk Kim RECORD_LAYER_reset_packet_length(&s->rlayer);
293e71b7053SJung-uk Kim continue;
294e71b7053SJung-uk Kim }
295e71b7053SJung-uk Kim
296e71b7053SJung-uk Kim if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds),
297e71b7053SJung-uk Kim SSL3_RECORD_get_seq_num(s->rlayer.rrec)) < 0) {
298e71b7053SJung-uk Kim /* SSLfatal() already called */
299e71b7053SJung-uk Kim return 0;
300e71b7053SJung-uk Kim }
301e71b7053SJung-uk Kim }
302e71b7053SJung-uk Kim }
303e71b7053SJung-uk Kim
304e71b7053SJung-uk Kim /*
305e71b7053SJung-uk Kim * sync epoch numbers once all the unprocessed records have been
306e71b7053SJung-uk Kim * processed
307e71b7053SJung-uk Kim */
308e71b7053SJung-uk Kim s->rlayer.d->processed_rcds.epoch = s->rlayer.d->r_epoch;
309e71b7053SJung-uk Kim s->rlayer.d->unprocessed_rcds.epoch = s->rlayer.d->r_epoch + 1;
310e71b7053SJung-uk Kim
311e71b7053SJung-uk Kim return 1;
312e71b7053SJung-uk Kim }
313e71b7053SJung-uk Kim
314e71b7053SJung-uk Kim /*-
315e71b7053SJung-uk Kim * Return up to 'len' payload bytes received in 'type' records.
316e71b7053SJung-uk Kim * 'type' is one of the following:
317e71b7053SJung-uk Kim *
318e71b7053SJung-uk Kim * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
319e71b7053SJung-uk Kim * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
320e71b7053SJung-uk Kim * - 0 (during a shutdown, no data has to be returned)
321e71b7053SJung-uk Kim *
322e71b7053SJung-uk Kim * If we don't have stored data to work from, read a SSL/TLS record first
323e71b7053SJung-uk Kim * (possibly multiple records if we still don't have anything to return).
324e71b7053SJung-uk Kim *
325e71b7053SJung-uk Kim * This function must handle any surprises the peer may have for us, such as
326e71b7053SJung-uk Kim * Alert records (e.g. close_notify) or renegotiation requests. ChangeCipherSpec
327e71b7053SJung-uk Kim * messages are treated as if they were handshake messages *if* the |recd_type|
328e71b7053SJung-uk Kim * argument is non NULL.
329e71b7053SJung-uk Kim * Also if record payloads contain fragments too small to process, we store
330e71b7053SJung-uk Kim * them until there is enough for the respective protocol (the record protocol
331e71b7053SJung-uk Kim * may use arbitrary fragmentation and even interleaving):
332e71b7053SJung-uk Kim * Change cipher spec protocol
333e71b7053SJung-uk Kim * just 1 byte needed, no need for keeping anything stored
334e71b7053SJung-uk Kim * Alert protocol
335e71b7053SJung-uk Kim * 2 bytes needed (AlertLevel, AlertDescription)
336e71b7053SJung-uk Kim * Handshake protocol
337e71b7053SJung-uk Kim * 4 bytes needed (HandshakeType, uint24 length) -- we just have
338e71b7053SJung-uk Kim * to detect unexpected Client Hello and Hello Request messages
339e71b7053SJung-uk Kim * here, anything else is handled by higher layers
340e71b7053SJung-uk Kim * Application data protocol
341e71b7053SJung-uk Kim * none of our business
342e71b7053SJung-uk Kim */
dtls1_read_bytes(SSL * s,int type,int * recvd_type,unsigned char * buf,size_t len,int peek,size_t * readbytes)343e71b7053SJung-uk Kim int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
344e71b7053SJung-uk Kim size_t len, int peek, size_t *readbytes)
345e71b7053SJung-uk Kim {
346e71b7053SJung-uk Kim int i, j, iret;
347e71b7053SJung-uk Kim size_t n;
348e71b7053SJung-uk Kim SSL3_RECORD *rr;
349e71b7053SJung-uk Kim void (*cb) (const SSL *ssl, int type2, int val) = NULL;
350e71b7053SJung-uk Kim
351e71b7053SJung-uk Kim if (!SSL3_BUFFER_is_initialised(&s->rlayer.rbuf)) {
352e71b7053SJung-uk Kim /* Not initialized yet */
353e71b7053SJung-uk Kim if (!ssl3_setup_buffers(s)) {
354e71b7053SJung-uk Kim /* SSLfatal() already called */
355e71b7053SJung-uk Kim return -1;
356e71b7053SJung-uk Kim }
357e71b7053SJung-uk Kim }
358e71b7053SJung-uk Kim
359e71b7053SJung-uk Kim if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
360e71b7053SJung-uk Kim (type != SSL3_RT_HANDSHAKE)) ||
361e71b7053SJung-uk Kim (peek && (type != SSL3_RT_APPLICATION_DATA))) {
362*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
363e71b7053SJung-uk Kim return -1;
364e71b7053SJung-uk Kim }
365e71b7053SJung-uk Kim
366e71b7053SJung-uk Kim if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) {
367e71b7053SJung-uk Kim /* type == SSL3_RT_APPLICATION_DATA */
368e71b7053SJung-uk Kim i = s->handshake_func(s);
369e71b7053SJung-uk Kim /* SSLfatal() already called if appropriate */
370e71b7053SJung-uk Kim if (i < 0)
371e71b7053SJung-uk Kim return i;
372e71b7053SJung-uk Kim if (i == 0)
373e71b7053SJung-uk Kim return -1;
374e71b7053SJung-uk Kim }
375e71b7053SJung-uk Kim
376e71b7053SJung-uk Kim start:
377e71b7053SJung-uk Kim s->rwstate = SSL_NOTHING;
378e71b7053SJung-uk Kim
379e71b7053SJung-uk Kim /*-
380*b077aed3SPierre Pronchery * s->s3.rrec.type - is the type of record
381*b077aed3SPierre Pronchery * s->s3.rrec.data, - data
382*b077aed3SPierre Pronchery * s->s3.rrec.off, - offset into 'data' for next read
383*b077aed3SPierre Pronchery * s->s3.rrec.length, - number of bytes.
384e71b7053SJung-uk Kim */
385e71b7053SJung-uk Kim rr = s->rlayer.rrec;
386e71b7053SJung-uk Kim
387e71b7053SJung-uk Kim /*
388e71b7053SJung-uk Kim * We are not handshaking and have no data yet, so process data buffered
389e71b7053SJung-uk Kim * during the last handshake in advance, if any.
390e71b7053SJung-uk Kim */
391e71b7053SJung-uk Kim if (SSL_is_init_finished(s) && SSL3_RECORD_get_length(rr) == 0) {
392e71b7053SJung-uk Kim pitem *item;
393e71b7053SJung-uk Kim item = pqueue_pop(s->rlayer.d->buffered_app_data.q);
394e71b7053SJung-uk Kim if (item) {
395e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP
396e71b7053SJung-uk Kim /* Restore bio_dgram_sctp_rcvinfo struct */
397e71b7053SJung-uk Kim if (BIO_dgram_is_sctp(SSL_get_rbio(s))) {
398e71b7053SJung-uk Kim DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data;
399e71b7053SJung-uk Kim BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO,
400e71b7053SJung-uk Kim sizeof(rdata->recordinfo), &rdata->recordinfo);
401e71b7053SJung-uk Kim }
402e71b7053SJung-uk Kim #endif
403e71b7053SJung-uk Kim
404e71b7053SJung-uk Kim dtls1_copy_record(s, item);
405e71b7053SJung-uk Kim
406e71b7053SJung-uk Kim OPENSSL_free(item->data);
407e71b7053SJung-uk Kim pitem_free(item);
408e71b7053SJung-uk Kim }
409e71b7053SJung-uk Kim }
410e71b7053SJung-uk Kim
411e71b7053SJung-uk Kim /* Check for timeout */
412e71b7053SJung-uk Kim if (dtls1_handle_timeout(s) > 0) {
413e71b7053SJung-uk Kim goto start;
414e71b7053SJung-uk Kim } else if (ossl_statem_in_error(s)) {
415e71b7053SJung-uk Kim /* dtls1_handle_timeout() has failed with a fatal error */
416e71b7053SJung-uk Kim return -1;
417e71b7053SJung-uk Kim }
418e71b7053SJung-uk Kim
419e71b7053SJung-uk Kim /* get new packet if necessary */
420e71b7053SJung-uk Kim if ((SSL3_RECORD_get_length(rr) == 0)
421e71b7053SJung-uk Kim || (s->rlayer.rstate == SSL_ST_READ_BODY)) {
422e71b7053SJung-uk Kim RECORD_LAYER_set_numrpipes(&s->rlayer, 0);
423e71b7053SJung-uk Kim iret = dtls1_get_record(s);
424e71b7053SJung-uk Kim if (iret <= 0) {
425e71b7053SJung-uk Kim iret = dtls1_read_failed(s, iret);
426e71b7053SJung-uk Kim /*
427e71b7053SJung-uk Kim * Anything other than a timeout is an error. SSLfatal() already
428e71b7053SJung-uk Kim * called if appropriate.
429e71b7053SJung-uk Kim */
430e71b7053SJung-uk Kim if (iret <= 0)
431e71b7053SJung-uk Kim return iret;
432e71b7053SJung-uk Kim else
433e71b7053SJung-uk Kim goto start;
434e71b7053SJung-uk Kim }
435e71b7053SJung-uk Kim RECORD_LAYER_set_numrpipes(&s->rlayer, 1);
436e71b7053SJung-uk Kim }
437e71b7053SJung-uk Kim
438e71b7053SJung-uk Kim /*
439e71b7053SJung-uk Kim * Reset the count of consecutive warning alerts if we've got a non-empty
440e71b7053SJung-uk Kim * record that isn't an alert.
441e71b7053SJung-uk Kim */
442e71b7053SJung-uk Kim if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT
443e71b7053SJung-uk Kim && SSL3_RECORD_get_length(rr) != 0)
444e71b7053SJung-uk Kim s->rlayer.alert_count = 0;
445e71b7053SJung-uk Kim
446e71b7053SJung-uk Kim /* we now have a packet which can be read and processed */
447e71b7053SJung-uk Kim
448*b077aed3SPierre Pronchery if (s->s3.change_cipher_spec /* set when we receive ChangeCipherSpec,
449e71b7053SJung-uk Kim * reset by ssl3_get_finished */
450e71b7053SJung-uk Kim && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
451e71b7053SJung-uk Kim /*
452e71b7053SJung-uk Kim * We now have application data between CCS and Finished. Most likely
453e71b7053SJung-uk Kim * the packets were reordered on their way, so buffer the application
454e71b7053SJung-uk Kim * data for later processing rather than dropping the connection.
455e71b7053SJung-uk Kim */
456e71b7053SJung-uk Kim if (dtls1_buffer_record(s, &(s->rlayer.d->buffered_app_data),
457e71b7053SJung-uk Kim SSL3_RECORD_get_seq_num(rr)) < 0) {
458e71b7053SJung-uk Kim /* SSLfatal() already called */
459e71b7053SJung-uk Kim return -1;
460e71b7053SJung-uk Kim }
461e71b7053SJung-uk Kim SSL3_RECORD_set_length(rr, 0);
462e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
463e71b7053SJung-uk Kim goto start;
464e71b7053SJung-uk Kim }
465e71b7053SJung-uk Kim
466e71b7053SJung-uk Kim /*
467e71b7053SJung-uk Kim * If the other end has shut down, throw anything we read away (even in
468e71b7053SJung-uk Kim * 'peek' mode)
469e71b7053SJung-uk Kim */
470e71b7053SJung-uk Kim if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
471e71b7053SJung-uk Kim SSL3_RECORD_set_length(rr, 0);
472e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
473e71b7053SJung-uk Kim s->rwstate = SSL_NOTHING;
474e71b7053SJung-uk Kim return 0;
475e71b7053SJung-uk Kim }
476e71b7053SJung-uk Kim
477e71b7053SJung-uk Kim if (type == SSL3_RECORD_get_type(rr)
478e71b7053SJung-uk Kim || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
479e71b7053SJung-uk Kim && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) {
480e71b7053SJung-uk Kim /*
481e71b7053SJung-uk Kim * SSL3_RT_APPLICATION_DATA or
482e71b7053SJung-uk Kim * SSL3_RT_HANDSHAKE or
483e71b7053SJung-uk Kim * SSL3_RT_CHANGE_CIPHER_SPEC
484e71b7053SJung-uk Kim */
485e71b7053SJung-uk Kim /*
486e71b7053SJung-uk Kim * make sure that we are not getting application data when we are
487e71b7053SJung-uk Kim * doing a handshake for the first time
488e71b7053SJung-uk Kim */
489e71b7053SJung-uk Kim if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
490e71b7053SJung-uk Kim (s->enc_read_ctx == NULL)) {
491*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
492e71b7053SJung-uk Kim SSL_R_APP_DATA_IN_HANDSHAKE);
493e71b7053SJung-uk Kim return -1;
494e71b7053SJung-uk Kim }
495e71b7053SJung-uk Kim
496e71b7053SJung-uk Kim if (recvd_type != NULL)
497e71b7053SJung-uk Kim *recvd_type = SSL3_RECORD_get_type(rr);
498e71b7053SJung-uk Kim
499e71b7053SJung-uk Kim if (len == 0) {
500e71b7053SJung-uk Kim /*
501e71b7053SJung-uk Kim * Mark a zero length record as read. This ensures multiple calls to
502e71b7053SJung-uk Kim * SSL_read() with a zero length buffer will eventually cause
503e71b7053SJung-uk Kim * SSL_pending() to report data as being available.
504e71b7053SJung-uk Kim */
505e71b7053SJung-uk Kim if (SSL3_RECORD_get_length(rr) == 0)
506e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
507e71b7053SJung-uk Kim return 0;
508e71b7053SJung-uk Kim }
509e71b7053SJung-uk Kim
510e71b7053SJung-uk Kim if (len > SSL3_RECORD_get_length(rr))
511e71b7053SJung-uk Kim n = SSL3_RECORD_get_length(rr);
512e71b7053SJung-uk Kim else
513e71b7053SJung-uk Kim n = len;
514e71b7053SJung-uk Kim
515e71b7053SJung-uk Kim memcpy(buf, &(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n);
516e71b7053SJung-uk Kim if (peek) {
517e71b7053SJung-uk Kim if (SSL3_RECORD_get_length(rr) == 0)
518e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
519e71b7053SJung-uk Kim } else {
520*b077aed3SPierre Pronchery if (s->options & SSL_OP_CLEANSE_PLAINTEXT)
521*b077aed3SPierre Pronchery OPENSSL_cleanse(&(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n);
522e71b7053SJung-uk Kim SSL3_RECORD_sub_length(rr, n);
523e71b7053SJung-uk Kim SSL3_RECORD_add_off(rr, n);
524e71b7053SJung-uk Kim if (SSL3_RECORD_get_length(rr) == 0) {
525e71b7053SJung-uk Kim s->rlayer.rstate = SSL_ST_READ_HEADER;
526e71b7053SJung-uk Kim SSL3_RECORD_set_off(rr, 0);
527e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
528e71b7053SJung-uk Kim }
529e71b7053SJung-uk Kim }
530e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP
531e71b7053SJung-uk Kim /*
532e71b7053SJung-uk Kim * We might had to delay a close_notify alert because of reordered
533e71b7053SJung-uk Kim * app data. If there was an alert and there is no message to read
534e71b7053SJung-uk Kim * anymore, finally set shutdown.
535e71b7053SJung-uk Kim */
536e71b7053SJung-uk Kim if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
537e71b7053SJung-uk Kim s->d1->shutdown_received
538*b077aed3SPierre Pronchery && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) <= 0) {
539e71b7053SJung-uk Kim s->shutdown |= SSL_RECEIVED_SHUTDOWN;
540e71b7053SJung-uk Kim return 0;
541e71b7053SJung-uk Kim }
542e71b7053SJung-uk Kim #endif
543e71b7053SJung-uk Kim *readbytes = n;
544e71b7053SJung-uk Kim return 1;
545e71b7053SJung-uk Kim }
546e71b7053SJung-uk Kim
547e71b7053SJung-uk Kim /*
548e71b7053SJung-uk Kim * If we get here, then type != rr->type; if we have a handshake message,
549e71b7053SJung-uk Kim * then it was unexpected (Hello Request or Client Hello).
550e71b7053SJung-uk Kim */
551e71b7053SJung-uk Kim
552e71b7053SJung-uk Kim if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
553e71b7053SJung-uk Kim unsigned int alert_level, alert_descr;
554e71b7053SJung-uk Kim unsigned char *alert_bytes = SSL3_RECORD_get_data(rr)
555e71b7053SJung-uk Kim + SSL3_RECORD_get_off(rr);
556e71b7053SJung-uk Kim PACKET alert;
557e71b7053SJung-uk Kim
558e71b7053SJung-uk Kim if (!PACKET_buf_init(&alert, alert_bytes, SSL3_RECORD_get_length(rr))
559e71b7053SJung-uk Kim || !PACKET_get_1(&alert, &alert_level)
560e71b7053SJung-uk Kim || !PACKET_get_1(&alert, &alert_descr)
561e71b7053SJung-uk Kim || PACKET_remaining(&alert) != 0) {
562*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_INVALID_ALERT);
563e71b7053SJung-uk Kim return -1;
564e71b7053SJung-uk Kim }
565e71b7053SJung-uk Kim
566e71b7053SJung-uk Kim if (s->msg_callback)
567e71b7053SJung-uk Kim s->msg_callback(0, s->version, SSL3_RT_ALERT, alert_bytes, 2, s,
568e71b7053SJung-uk Kim s->msg_callback_arg);
569e71b7053SJung-uk Kim
570e71b7053SJung-uk Kim if (s->info_callback != NULL)
571e71b7053SJung-uk Kim cb = s->info_callback;
572e71b7053SJung-uk Kim else if (s->ctx->info_callback != NULL)
573e71b7053SJung-uk Kim cb = s->ctx->info_callback;
574e71b7053SJung-uk Kim
575e71b7053SJung-uk Kim if (cb != NULL) {
576e71b7053SJung-uk Kim j = (alert_level << 8) | alert_descr;
577e71b7053SJung-uk Kim cb(s, SSL_CB_READ_ALERT, j);
578e71b7053SJung-uk Kim }
579e71b7053SJung-uk Kim
580e71b7053SJung-uk Kim if (alert_level == SSL3_AL_WARNING) {
581*b077aed3SPierre Pronchery s->s3.warn_alert = alert_descr;
582e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
583e71b7053SJung-uk Kim
584e71b7053SJung-uk Kim s->rlayer.alert_count++;
585e71b7053SJung-uk Kim if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) {
586*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
587e71b7053SJung-uk Kim SSL_R_TOO_MANY_WARN_ALERTS);
588e71b7053SJung-uk Kim return -1;
589e71b7053SJung-uk Kim }
590e71b7053SJung-uk Kim
591e71b7053SJung-uk Kim if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
592e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP
593e71b7053SJung-uk Kim /*
594e71b7053SJung-uk Kim * With SCTP and streams the socket may deliver app data
595e71b7053SJung-uk Kim * after a close_notify alert. We have to check this first so
596e71b7053SJung-uk Kim * that nothing gets discarded.
597e71b7053SJung-uk Kim */
598e71b7053SJung-uk Kim if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
599*b077aed3SPierre Pronchery BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) > 0) {
600e71b7053SJung-uk Kim s->d1->shutdown_received = 1;
601e71b7053SJung-uk Kim s->rwstate = SSL_READING;
602e71b7053SJung-uk Kim BIO_clear_retry_flags(SSL_get_rbio(s));
603e71b7053SJung-uk Kim BIO_set_retry_read(SSL_get_rbio(s));
604e71b7053SJung-uk Kim return -1;
605e71b7053SJung-uk Kim }
606e71b7053SJung-uk Kim #endif
607e71b7053SJung-uk Kim s->shutdown |= SSL_RECEIVED_SHUTDOWN;
608e71b7053SJung-uk Kim return 0;
609e71b7053SJung-uk Kim }
610e71b7053SJung-uk Kim } else if (alert_level == SSL3_AL_FATAL) {
611e71b7053SJung-uk Kim s->rwstate = SSL_NOTHING;
612*b077aed3SPierre Pronchery s->s3.fatal_alert = alert_descr;
613*b077aed3SPierre Pronchery SSLfatal_data(s, SSL_AD_NO_ALERT,
614*b077aed3SPierre Pronchery SSL_AD_REASON_OFFSET + alert_descr,
615*b077aed3SPierre Pronchery "SSL alert number %d", alert_descr);
616e71b7053SJung-uk Kim s->shutdown |= SSL_RECEIVED_SHUTDOWN;
617e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
618e71b7053SJung-uk Kim SSL_CTX_remove_session(s->session_ctx, s->session);
619e71b7053SJung-uk Kim return 0;
620e71b7053SJung-uk Kim } else {
621*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_ALERT_TYPE);
622e71b7053SJung-uk Kim return -1;
623e71b7053SJung-uk Kim }
624e71b7053SJung-uk Kim
625e71b7053SJung-uk Kim goto start;
626e71b7053SJung-uk Kim }
627e71b7053SJung-uk Kim
628e71b7053SJung-uk Kim if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
629e71b7053SJung-uk Kim * shutdown */
630e71b7053SJung-uk Kim s->rwstate = SSL_NOTHING;
631e71b7053SJung-uk Kim SSL3_RECORD_set_length(rr, 0);
632e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
633e71b7053SJung-uk Kim return 0;
634e71b7053SJung-uk Kim }
635e71b7053SJung-uk Kim
636e71b7053SJung-uk Kim if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) {
637e71b7053SJung-uk Kim /*
638e71b7053SJung-uk Kim * We can't process a CCS now, because previous handshake messages
639e71b7053SJung-uk Kim * are still missing, so just drop it.
640e71b7053SJung-uk Kim */
641e71b7053SJung-uk Kim SSL3_RECORD_set_length(rr, 0);
642e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
643e71b7053SJung-uk Kim goto start;
644e71b7053SJung-uk Kim }
645e71b7053SJung-uk Kim
646e71b7053SJung-uk Kim /*
647e71b7053SJung-uk Kim * Unexpected handshake message (Client Hello, or protocol violation)
648e71b7053SJung-uk Kim */
649e71b7053SJung-uk Kim if ((SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) &&
650e71b7053SJung-uk Kim !ossl_statem_get_in_handshake(s)) {
651e71b7053SJung-uk Kim struct hm_header_st msg_hdr;
652e71b7053SJung-uk Kim
653e71b7053SJung-uk Kim /*
654e71b7053SJung-uk Kim * This may just be a stale retransmit. Also sanity check that we have
655e71b7053SJung-uk Kim * at least enough record bytes for a message header
656e71b7053SJung-uk Kim */
657e71b7053SJung-uk Kim if (SSL3_RECORD_get_epoch(rr) != s->rlayer.d->r_epoch
658e71b7053SJung-uk Kim || SSL3_RECORD_get_length(rr) < DTLS1_HM_HEADER_LENGTH) {
659e71b7053SJung-uk Kim SSL3_RECORD_set_length(rr, 0);
660e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
661e71b7053SJung-uk Kim goto start;
662e71b7053SJung-uk Kim }
663e71b7053SJung-uk Kim
664e71b7053SJung-uk Kim dtls1_get_message_header(rr->data, &msg_hdr);
665e71b7053SJung-uk Kim
666e71b7053SJung-uk Kim /*
667e71b7053SJung-uk Kim * If we are server, we may have a repeated FINISHED of the client
668e71b7053SJung-uk Kim * here, then retransmit our CCS and FINISHED.
669e71b7053SJung-uk Kim */
670e71b7053SJung-uk Kim if (msg_hdr.type == SSL3_MT_FINISHED) {
671e71b7053SJung-uk Kim if (dtls1_check_timeout_num(s) < 0) {
672e71b7053SJung-uk Kim /* SSLfatal) already called */
673e71b7053SJung-uk Kim return -1;
674e71b7053SJung-uk Kim }
675e71b7053SJung-uk Kim
676e71b7053SJung-uk Kim if (dtls1_retransmit_buffered_messages(s) <= 0) {
677e71b7053SJung-uk Kim /* Fail if we encountered a fatal error */
678e71b7053SJung-uk Kim if (ossl_statem_in_error(s))
679e71b7053SJung-uk Kim return -1;
680e71b7053SJung-uk Kim }
681e71b7053SJung-uk Kim SSL3_RECORD_set_length(rr, 0);
682e71b7053SJung-uk Kim SSL3_RECORD_set_read(rr);
683e71b7053SJung-uk Kim if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
684e71b7053SJung-uk Kim if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
685e71b7053SJung-uk Kim /* no read-ahead left? */
686e71b7053SJung-uk Kim BIO *bio;
687e71b7053SJung-uk Kim
688e71b7053SJung-uk Kim s->rwstate = SSL_READING;
689e71b7053SJung-uk Kim bio = SSL_get_rbio(s);
690e71b7053SJung-uk Kim BIO_clear_retry_flags(bio);
691e71b7053SJung-uk Kim BIO_set_retry_read(bio);
692e71b7053SJung-uk Kim return -1;
693e71b7053SJung-uk Kim }
694e71b7053SJung-uk Kim }
695e71b7053SJung-uk Kim goto start;
696e71b7053SJung-uk Kim }
697e71b7053SJung-uk Kim
698e71b7053SJung-uk Kim /*
699e71b7053SJung-uk Kim * To get here we must be trying to read app data but found handshake
700e71b7053SJung-uk Kim * data. But if we're trying to read app data, and we're not in init
701e71b7053SJung-uk Kim * (which is tested for at the top of this function) then init must be
702e71b7053SJung-uk Kim * finished
703e71b7053SJung-uk Kim */
704e71b7053SJung-uk Kim if (!ossl_assert(SSL_is_init_finished(s))) {
705*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
706e71b7053SJung-uk Kim return -1;
707e71b7053SJung-uk Kim }
708e71b7053SJung-uk Kim
709e71b7053SJung-uk Kim /* We found handshake data, so we're going back into init */
710e71b7053SJung-uk Kim ossl_statem_set_in_init(s, 1);
711e71b7053SJung-uk Kim
712e71b7053SJung-uk Kim i = s->handshake_func(s);
713e71b7053SJung-uk Kim /* SSLfatal() called if appropriate */
714e71b7053SJung-uk Kim if (i < 0)
715e71b7053SJung-uk Kim return i;
716e71b7053SJung-uk Kim if (i == 0)
717e71b7053SJung-uk Kim return -1;
718e71b7053SJung-uk Kim
719e71b7053SJung-uk Kim if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
720e71b7053SJung-uk Kim if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
721e71b7053SJung-uk Kim /* no read-ahead left? */
722e71b7053SJung-uk Kim BIO *bio;
723e71b7053SJung-uk Kim /*
724e71b7053SJung-uk Kim * In the case where we try to read application data, but we
725e71b7053SJung-uk Kim * trigger an SSL handshake, we return -1 with the retry
726e71b7053SJung-uk Kim * option set. Otherwise renegotiation may cause nasty
727e71b7053SJung-uk Kim * problems in the blocking world
728e71b7053SJung-uk Kim */
729e71b7053SJung-uk Kim s->rwstate = SSL_READING;
730e71b7053SJung-uk Kim bio = SSL_get_rbio(s);
731e71b7053SJung-uk Kim BIO_clear_retry_flags(bio);
732e71b7053SJung-uk Kim BIO_set_retry_read(bio);
733e71b7053SJung-uk Kim return -1;
734e71b7053SJung-uk Kim }
735e71b7053SJung-uk Kim }
736e71b7053SJung-uk Kim goto start;
737e71b7053SJung-uk Kim }
738e71b7053SJung-uk Kim
739e71b7053SJung-uk Kim switch (SSL3_RECORD_get_type(rr)) {
740e71b7053SJung-uk Kim default:
741*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD);
742e71b7053SJung-uk Kim return -1;
743e71b7053SJung-uk Kim case SSL3_RT_CHANGE_CIPHER_SPEC:
744e71b7053SJung-uk Kim case SSL3_RT_ALERT:
745e71b7053SJung-uk Kim case SSL3_RT_HANDSHAKE:
746e71b7053SJung-uk Kim /*
747e71b7053SJung-uk Kim * we already handled all of these, with the possible exception of
748e71b7053SJung-uk Kim * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but
749e71b7053SJung-uk Kim * that should not happen when type != rr->type
750e71b7053SJung-uk Kim */
751*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, ERR_R_INTERNAL_ERROR);
752e71b7053SJung-uk Kim return -1;
753e71b7053SJung-uk Kim case SSL3_RT_APPLICATION_DATA:
754e71b7053SJung-uk Kim /*
755e71b7053SJung-uk Kim * At this point, we were expecting handshake data, but have
756e71b7053SJung-uk Kim * application data. If the library was running inside ssl3_read()
757e71b7053SJung-uk Kim * (i.e. in_read_app_data is set) and it makes sense to read
758e71b7053SJung-uk Kim * application data at this point (session renegotiation not yet
759e71b7053SJung-uk Kim * started), we will indulge it.
760e71b7053SJung-uk Kim */
761*b077aed3SPierre Pronchery if (s->s3.in_read_app_data &&
762*b077aed3SPierre Pronchery (s->s3.total_renegotiations != 0) &&
763e71b7053SJung-uk Kim ossl_statem_app_data_allowed(s)) {
764*b077aed3SPierre Pronchery s->s3.in_read_app_data = 2;
765e71b7053SJung-uk Kim return -1;
766e71b7053SJung-uk Kim } else {
767*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD);
768e71b7053SJung-uk Kim return -1;
769e71b7053SJung-uk Kim }
770e71b7053SJung-uk Kim }
771e71b7053SJung-uk Kim /* not reached */
772e71b7053SJung-uk Kim }
773e71b7053SJung-uk Kim
774e71b7053SJung-uk Kim /*
775e71b7053SJung-uk Kim * Call this to write data in records of type 'type' It will return <= 0 if
776e71b7053SJung-uk Kim * not all data has been sent or non-blocking IO.
777e71b7053SJung-uk Kim */
dtls1_write_bytes(SSL * s,int type,const void * buf,size_t len,size_t * written)778e71b7053SJung-uk Kim int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len,
779e71b7053SJung-uk Kim size_t *written)
780e71b7053SJung-uk Kim {
781e71b7053SJung-uk Kim int i;
782e71b7053SJung-uk Kim
783e71b7053SJung-uk Kim if (!ossl_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH)) {
784*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
785e71b7053SJung-uk Kim return -1;
786e71b7053SJung-uk Kim }
787e71b7053SJung-uk Kim s->rwstate = SSL_NOTHING;
788e71b7053SJung-uk Kim i = do_dtls1_write(s, type, buf, len, 0, written);
789e71b7053SJung-uk Kim return i;
790e71b7053SJung-uk Kim }
791e71b7053SJung-uk Kim
do_dtls1_write(SSL * s,int type,const unsigned char * buf,size_t len,int create_empty_fragment,size_t * written)792e71b7053SJung-uk Kim int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
793e71b7053SJung-uk Kim size_t len, int create_empty_fragment, size_t *written)
794e71b7053SJung-uk Kim {
795e71b7053SJung-uk Kim unsigned char *p, *pseq;
796e71b7053SJung-uk Kim int i, mac_size, clear = 0;
797e71b7053SJung-uk Kim size_t prefix_len = 0;
798e71b7053SJung-uk Kim int eivlen;
799e71b7053SJung-uk Kim SSL3_RECORD wr;
800e71b7053SJung-uk Kim SSL3_BUFFER *wb;
801e71b7053SJung-uk Kim SSL_SESSION *sess;
802e71b7053SJung-uk Kim
803e71b7053SJung-uk Kim wb = &s->rlayer.wbuf[0];
804e71b7053SJung-uk Kim
805e71b7053SJung-uk Kim /*
806c3c73b4fSJung-uk Kim * DTLS writes whole datagrams, so there can't be anything left in
807c3c73b4fSJung-uk Kim * the buffer.
808e71b7053SJung-uk Kim */
809e71b7053SJung-uk Kim if (!ossl_assert(SSL3_BUFFER_get_left(wb) == 0)) {
810*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
811e71b7053SJung-uk Kim return 0;
812e71b7053SJung-uk Kim }
813e71b7053SJung-uk Kim
814e71b7053SJung-uk Kim /* If we have an alert to send, lets send it */
815*b077aed3SPierre Pronchery if (s->s3.alert_dispatch) {
816e71b7053SJung-uk Kim i = s->method->ssl_dispatch_alert(s);
817e71b7053SJung-uk Kim if (i <= 0)
818e71b7053SJung-uk Kim return i;
819e71b7053SJung-uk Kim /* if it went, fall through and send more stuff */
820e71b7053SJung-uk Kim }
821e71b7053SJung-uk Kim
822e71b7053SJung-uk Kim if (len == 0 && !create_empty_fragment)
823e71b7053SJung-uk Kim return 0;
824e71b7053SJung-uk Kim
825e71b7053SJung-uk Kim if (len > ssl_get_max_send_fragment(s)) {
826*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE);
827e71b7053SJung-uk Kim return 0;
828e71b7053SJung-uk Kim }
829e71b7053SJung-uk Kim
830e71b7053SJung-uk Kim sess = s->session;
831e71b7053SJung-uk Kim
832*b077aed3SPierre Pronchery if ((sess == NULL)
833*b077aed3SPierre Pronchery || (s->enc_write_ctx == NULL)
834*b077aed3SPierre Pronchery || (EVP_MD_CTX_get0_md(s->write_hash) == NULL))
835e71b7053SJung-uk Kim clear = 1;
836e71b7053SJung-uk Kim
837e71b7053SJung-uk Kim if (clear)
838e71b7053SJung-uk Kim mac_size = 0;
839e71b7053SJung-uk Kim else {
840*b077aed3SPierre Pronchery mac_size = EVP_MD_CTX_get_size(s->write_hash);
841e71b7053SJung-uk Kim if (mac_size < 0) {
842*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR,
843e71b7053SJung-uk Kim SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE);
844e71b7053SJung-uk Kim return -1;
845e71b7053SJung-uk Kim }
846e71b7053SJung-uk Kim }
847e71b7053SJung-uk Kim
848e71b7053SJung-uk Kim p = SSL3_BUFFER_get_buf(wb) + prefix_len;
849e71b7053SJung-uk Kim
850e71b7053SJung-uk Kim /* write the header */
851e71b7053SJung-uk Kim
852e71b7053SJung-uk Kim *(p++) = type & 0xff;
853e71b7053SJung-uk Kim SSL3_RECORD_set_type(&wr, type);
854e71b7053SJung-uk Kim /*
855e71b7053SJung-uk Kim * Special case: for hello verify request, client version 1.0 and we
856e71b7053SJung-uk Kim * haven't decided which version to use yet send back using version 1.0
857e71b7053SJung-uk Kim * header: otherwise some clients will ignore it.
858e71b7053SJung-uk Kim */
859e71b7053SJung-uk Kim if (s->method->version == DTLS_ANY_VERSION &&
860e71b7053SJung-uk Kim s->max_proto_version != DTLS1_BAD_VER) {
861e71b7053SJung-uk Kim *(p++) = DTLS1_VERSION >> 8;
862e71b7053SJung-uk Kim *(p++) = DTLS1_VERSION & 0xff;
863e71b7053SJung-uk Kim } else {
864e71b7053SJung-uk Kim *(p++) = s->version >> 8;
865e71b7053SJung-uk Kim *(p++) = s->version & 0xff;
866e71b7053SJung-uk Kim }
867e71b7053SJung-uk Kim
868e71b7053SJung-uk Kim /* field where we are to write out packet epoch, seq num and len */
869e71b7053SJung-uk Kim pseq = p;
870e71b7053SJung-uk Kim p += 10;
871e71b7053SJung-uk Kim
872e71b7053SJung-uk Kim /* Explicit IV length, block ciphers appropriate version flag */
873e71b7053SJung-uk Kim if (s->enc_write_ctx) {
874*b077aed3SPierre Pronchery int mode = EVP_CIPHER_CTX_get_mode(s->enc_write_ctx);
875e71b7053SJung-uk Kim if (mode == EVP_CIPH_CBC_MODE) {
876*b077aed3SPierre Pronchery eivlen = EVP_CIPHER_CTX_get_iv_length(s->enc_write_ctx);
877*b077aed3SPierre Pronchery if (eivlen < 0) {
878*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG);
879*b077aed3SPierre Pronchery return -1;
880*b077aed3SPierre Pronchery }
881e71b7053SJung-uk Kim if (eivlen <= 1)
882e71b7053SJung-uk Kim eivlen = 0;
883e71b7053SJung-uk Kim }
884e71b7053SJung-uk Kim /* Need explicit part of IV for GCM mode */
885e71b7053SJung-uk Kim else if (mode == EVP_CIPH_GCM_MODE)
886e71b7053SJung-uk Kim eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
887e71b7053SJung-uk Kim else if (mode == EVP_CIPH_CCM_MODE)
888e71b7053SJung-uk Kim eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
889e71b7053SJung-uk Kim else
890e71b7053SJung-uk Kim eivlen = 0;
891e71b7053SJung-uk Kim } else
892e71b7053SJung-uk Kim eivlen = 0;
893e71b7053SJung-uk Kim
894e71b7053SJung-uk Kim /* lets setup the record stuff. */
895e71b7053SJung-uk Kim SSL3_RECORD_set_data(&wr, p + eivlen); /* make room for IV in case of CBC */
896e71b7053SJung-uk Kim SSL3_RECORD_set_length(&wr, len);
897e71b7053SJung-uk Kim SSL3_RECORD_set_input(&wr, (unsigned char *)buf);
898e71b7053SJung-uk Kim
899e71b7053SJung-uk Kim /*
900e71b7053SJung-uk Kim * we now 'read' from wr.input, wr.length bytes into wr.data
901e71b7053SJung-uk Kim */
902e71b7053SJung-uk Kim
903e71b7053SJung-uk Kim /* first we compress */
904e71b7053SJung-uk Kim if (s->compress != NULL) {
905e71b7053SJung-uk Kim if (!ssl3_do_compress(s, &wr)) {
906*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COMPRESSION_FAILURE);
907e71b7053SJung-uk Kim return -1;
908e71b7053SJung-uk Kim }
909e71b7053SJung-uk Kim } else {
910e71b7053SJung-uk Kim memcpy(SSL3_RECORD_get_data(&wr), SSL3_RECORD_get_input(&wr),
911e71b7053SJung-uk Kim SSL3_RECORD_get_length(&wr));
912e71b7053SJung-uk Kim SSL3_RECORD_reset_input(&wr);
913e71b7053SJung-uk Kim }
914e71b7053SJung-uk Kim
915e71b7053SJung-uk Kim /*
916e71b7053SJung-uk Kim * we should still have the output to wr.data and the input from
917e71b7053SJung-uk Kim * wr.input. Length should be wr.length. wr.data still points in the
918e71b7053SJung-uk Kim * wb->buf
919e71b7053SJung-uk Kim */
920e71b7053SJung-uk Kim
921e71b7053SJung-uk Kim if (!SSL_WRITE_ETM(s) && mac_size != 0) {
922e71b7053SJung-uk Kim if (!s->method->ssl3_enc->mac(s, &wr,
923e71b7053SJung-uk Kim &(p[SSL3_RECORD_get_length(&wr) + eivlen]),
924e71b7053SJung-uk Kim 1)) {
925*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
926e71b7053SJung-uk Kim return -1;
927e71b7053SJung-uk Kim }
928e71b7053SJung-uk Kim SSL3_RECORD_add_length(&wr, mac_size);
929e71b7053SJung-uk Kim }
930e71b7053SJung-uk Kim
931e71b7053SJung-uk Kim /* this is true regardless of mac size */
932e71b7053SJung-uk Kim SSL3_RECORD_set_data(&wr, p);
933e71b7053SJung-uk Kim SSL3_RECORD_reset_input(&wr);
934e71b7053SJung-uk Kim
935e71b7053SJung-uk Kim if (eivlen)
936e71b7053SJung-uk Kim SSL3_RECORD_add_length(&wr, eivlen);
937e71b7053SJung-uk Kim
938*b077aed3SPierre Pronchery if (s->method->ssl3_enc->enc(s, &wr, 1, 1, NULL, mac_size) < 1) {
939e71b7053SJung-uk Kim if (!ossl_statem_in_error(s)) {
940*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
941e71b7053SJung-uk Kim }
942e71b7053SJung-uk Kim return -1;
943e71b7053SJung-uk Kim }
944e71b7053SJung-uk Kim
945e71b7053SJung-uk Kim if (SSL_WRITE_ETM(s) && mac_size != 0) {
946e71b7053SJung-uk Kim if (!s->method->ssl3_enc->mac(s, &wr,
947e71b7053SJung-uk Kim &(p[SSL3_RECORD_get_length(&wr)]), 1)) {
948*b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
949e71b7053SJung-uk Kim return -1;
950e71b7053SJung-uk Kim }
951e71b7053SJung-uk Kim SSL3_RECORD_add_length(&wr, mac_size);
952e71b7053SJung-uk Kim }
953e71b7053SJung-uk Kim
954e71b7053SJung-uk Kim /* record length after mac and block padding */
955e71b7053SJung-uk Kim
956e71b7053SJung-uk Kim /* there's only one epoch between handshake and app data */
957e71b7053SJung-uk Kim
958e71b7053SJung-uk Kim s2n(s->rlayer.d->w_epoch, pseq);
959e71b7053SJung-uk Kim
960e71b7053SJung-uk Kim memcpy(pseq, &(s->rlayer.write_sequence[2]), 6);
961e71b7053SJung-uk Kim pseq += 6;
962e71b7053SJung-uk Kim s2n(SSL3_RECORD_get_length(&wr), pseq);
963e71b7053SJung-uk Kim
964e71b7053SJung-uk Kim if (s->msg_callback)
965e71b7053SJung-uk Kim s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH,
966e71b7053SJung-uk Kim DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
967e71b7053SJung-uk Kim
968e71b7053SJung-uk Kim /*
969e71b7053SJung-uk Kim * we should now have wr.data pointing to the encrypted data, which is
970e71b7053SJung-uk Kim * wr->length long
971e71b7053SJung-uk Kim */
972e71b7053SJung-uk Kim SSL3_RECORD_set_type(&wr, type); /* not needed but helps for debugging */
973e71b7053SJung-uk Kim SSL3_RECORD_add_length(&wr, DTLS1_RT_HEADER_LENGTH);
974e71b7053SJung-uk Kim
975e71b7053SJung-uk Kim ssl3_record_sequence_update(&(s->rlayer.write_sequence[0]));
976e71b7053SJung-uk Kim
977e71b7053SJung-uk Kim if (create_empty_fragment) {
978e71b7053SJung-uk Kim /*
979e71b7053SJung-uk Kim * we are in a recursive call; just return the length, don't write
980e71b7053SJung-uk Kim * out anything here
981e71b7053SJung-uk Kim */
982e71b7053SJung-uk Kim *written = wr.length;
983e71b7053SJung-uk Kim return 1;
984e71b7053SJung-uk Kim }
985e71b7053SJung-uk Kim
986e71b7053SJung-uk Kim /* now let's set up wb */
987e71b7053SJung-uk Kim SSL3_BUFFER_set_left(wb, prefix_len + SSL3_RECORD_get_length(&wr));
988e71b7053SJung-uk Kim SSL3_BUFFER_set_offset(wb, 0);
989e71b7053SJung-uk Kim
990e71b7053SJung-uk Kim /*
991e71b7053SJung-uk Kim * memorize arguments so that ssl3_write_pending can detect bad write
992e71b7053SJung-uk Kim * retries later
993e71b7053SJung-uk Kim */
994e71b7053SJung-uk Kim s->rlayer.wpend_tot = len;
995e71b7053SJung-uk Kim s->rlayer.wpend_buf = buf;
996e71b7053SJung-uk Kim s->rlayer.wpend_type = type;
997e71b7053SJung-uk Kim s->rlayer.wpend_ret = len;
998e71b7053SJung-uk Kim
999e71b7053SJung-uk Kim /* we now just need to write the buffer. Calls SSLfatal() as required. */
1000e71b7053SJung-uk Kim return ssl3_write_pending(s, type, buf, len, written);
1001e71b7053SJung-uk Kim }
1002e71b7053SJung-uk Kim
dtls1_get_bitmap(SSL * s,SSL3_RECORD * rr,unsigned int * is_next_epoch)1003e71b7053SJung-uk Kim DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
1004e71b7053SJung-uk Kim unsigned int *is_next_epoch)
1005e71b7053SJung-uk Kim {
1006e71b7053SJung-uk Kim
1007e71b7053SJung-uk Kim *is_next_epoch = 0;
1008e71b7053SJung-uk Kim
1009e71b7053SJung-uk Kim /* In current epoch, accept HM, CCS, DATA, & ALERT */
1010e71b7053SJung-uk Kim if (rr->epoch == s->rlayer.d->r_epoch)
1011e71b7053SJung-uk Kim return &s->rlayer.d->bitmap;
1012e71b7053SJung-uk Kim
1013e71b7053SJung-uk Kim /*
1014*b077aed3SPierre Pronchery * We can only handle messages from the next epoch if we have already
1015*b077aed3SPierre Pronchery * processed all of the unprocessed records from the previous epoch
1016e71b7053SJung-uk Kim */
1017*b077aed3SPierre Pronchery else if (rr->epoch == (unsigned long)(s->rlayer.d->r_epoch + 1)
1018*b077aed3SPierre Pronchery && s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch) {
1019e71b7053SJung-uk Kim *is_next_epoch = 1;
1020e71b7053SJung-uk Kim return &s->rlayer.d->next_bitmap;
1021e71b7053SJung-uk Kim }
1022e71b7053SJung-uk Kim
1023e71b7053SJung-uk Kim return NULL;
1024e71b7053SJung-uk Kim }
1025e71b7053SJung-uk Kim
dtls1_reset_seq_numbers(SSL * s,int rw)1026e71b7053SJung-uk Kim void dtls1_reset_seq_numbers(SSL *s, int rw)
1027e71b7053SJung-uk Kim {
1028e71b7053SJung-uk Kim unsigned char *seq;
1029e71b7053SJung-uk Kim unsigned int seq_bytes = sizeof(s->rlayer.read_sequence);
1030e71b7053SJung-uk Kim
1031e71b7053SJung-uk Kim if (rw & SSL3_CC_READ) {
1032e71b7053SJung-uk Kim seq = s->rlayer.read_sequence;
1033e71b7053SJung-uk Kim s->rlayer.d->r_epoch++;
1034e71b7053SJung-uk Kim memcpy(&s->rlayer.d->bitmap, &s->rlayer.d->next_bitmap,
1035e71b7053SJung-uk Kim sizeof(s->rlayer.d->bitmap));
1036e71b7053SJung-uk Kim memset(&s->rlayer.d->next_bitmap, 0, sizeof(s->rlayer.d->next_bitmap));
1037e71b7053SJung-uk Kim
1038e71b7053SJung-uk Kim /*
1039e71b7053SJung-uk Kim * We must not use any buffered messages received from the previous
1040e71b7053SJung-uk Kim * epoch
1041e71b7053SJung-uk Kim */
1042e71b7053SJung-uk Kim dtls1_clear_received_buffer(s);
1043e71b7053SJung-uk Kim } else {
1044e71b7053SJung-uk Kim seq = s->rlayer.write_sequence;
1045e71b7053SJung-uk Kim memcpy(s->rlayer.d->last_write_sequence, seq,
1046e71b7053SJung-uk Kim sizeof(s->rlayer.write_sequence));
1047e71b7053SJung-uk Kim s->rlayer.d->w_epoch++;
1048e71b7053SJung-uk Kim }
1049e71b7053SJung-uk Kim
1050e71b7053SJung-uk Kim memset(seq, 0, seq_bytes);
1051e71b7053SJung-uk Kim }
1052