/src/nss/lib/ssl/dtls13con.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | /* |
7 | | * DTLS 1.3 Protocol |
8 | | */ |
9 | | |
10 | | #include "ssl.h" |
11 | | #include "sslimpl.h" |
12 | | #include "sslproto.h" |
13 | | #include "keyhi.h" |
14 | | #include "pk11func.h" |
15 | | |
16 | | /*Figure 3: DTLS 1.3 Unified Header */ |
17 | | |
18 | | /* |
19 | | * 0 1 2 3 4 5 6 7 |
20 | | * +-+-+-+-+-+-+-+-+ |
21 | | * |0|0|1|C|S|L|E E| |
22 | | * +-+-+-+-+-+-+-+-+ |
23 | | * | Connection ID | Legend: |
24 | | * | (if any, | |
25 | | * / length as / C - CID present |
26 | | * | negotiated) | S - Sequence number length |
27 | | * +-+-+-+-+-+-+-+-+ L - Length present |
28 | | * | 8 or 16 bit | E - Epoch |
29 | | * |Sequence Number| |
30 | | * +-+-+-+-+-+-+-+-+ |
31 | | * | 16 bit Length | |
32 | | * | (if present) | |
33 | | * +-+-+-+-+-+-+-+-+ |
34 | | */ |
35 | | |
36 | | // E: The two low bits (0x03) include the low order two bits of the epoch. |
37 | 0 | #define MASK_TWO_LOW_BITS 0x3 |
38 | | // Fixed Bits: The three high bits of the first byte of the unified header are set to 001. |
39 | | // The C bit is set if the Connection ID is present. |
40 | | // The S bit (0x08) indicates the size of the sequence number, here 1 stands for 16 bits |
41 | | // The L bit (0x04) is set if the length is present. |
42 | | // The EE bits - mask of the epoch |
43 | | |
44 | | // 0x2c = 0b001-0-1-1-00 |
45 | | // 001-C-S-L-EE |
46 | 0 | #define UNIFIED_HEADER_LONG 0x2c |
47 | | // 0x20 = 0b001-0-0-1-00 |
48 | | // 001-C-S-L-EE |
49 | | // The difference between the long and short header is in the S bit (1 for long, 0 for short). |
50 | | // The S bit (0x08) indicates the size of the sequence number, here 0 stands for 8 bits |
51 | 0 | #define UNIFIED_HEADER_SHORT 0x20 |
52 | | |
53 | | // The masks to get the 8 (MASK_SEQUENCE_NUMBER_SHORT) or 16 bits (MASK_SEQUENCE_NUMBER_LONG) of the record sequence number. |
54 | 0 | #define MASK_SEQUENCE_NUMBER_SHORT 0xff |
55 | 0 | #define MASK_SEQUENCE_NUMBER_LONG 0xffff |
56 | | |
57 | | /*The DTLS Record Layer - Figure 3 and further*/ |
58 | | SECStatus |
59 | | dtls13_InsertCipherTextHeader(const sslSocket *ss, const ssl3CipherSpec *cwSpec, |
60 | | sslBuffer *wrBuf, PRBool *needsLength) |
61 | 0 | { |
62 | | /* Avoid using short records for the handshake. We pack multiple records |
63 | | * into the one datagram for the handshake. */ |
64 | | |
65 | | /* The short header here means that the S bit is set to 0 (8-bit sequence number) */ |
66 | 0 | if (ss->opt.enableDtlsShortHeader && |
67 | 0 | cwSpec->epoch > TrafficKeyHandshake) { |
68 | 0 | *needsLength = PR_FALSE; |
69 | | /* The short header is comprised of two octets in the form |
70 | | * 0b001000eessssssss where 'e' is the low two bits of the |
71 | | * epoch and 's' is the low 8 bits of the sequence number. */ |
72 | 0 | PRUint8 ct = UNIFIED_HEADER_SHORT | ((uint64_t)cwSpec->epoch & MASK_TWO_LOW_BITS); |
73 | 0 | if (sslBuffer_AppendNumber(wrBuf, ct, sizeof(ct)) != SECSuccess) { |
74 | 0 | return SECFailure; |
75 | 0 | } |
76 | 0 | PRUint8 seq = cwSpec->nextSeqNum & MASK_SEQUENCE_NUMBER_SHORT; |
77 | 0 | return sslBuffer_AppendNumber(wrBuf, seq, sizeof(seq)); |
78 | 0 | } |
79 | | |
80 | 0 | PRUint8 ct = UNIFIED_HEADER_LONG | ((PRUint8)cwSpec->epoch & MASK_TWO_LOW_BITS); |
81 | 0 | if (sslBuffer_AppendNumber(wrBuf, ct, sizeof(ct)) != SECSuccess) { |
82 | 0 | return SECFailure; |
83 | 0 | } |
84 | 0 | PRUint16 seq = cwSpec->nextSeqNum & MASK_SEQUENCE_NUMBER_LONG; |
85 | 0 | if (sslBuffer_AppendNumber(wrBuf, seq, sizeof(seq)) != SECSuccess) { |
86 | 0 | return SECFailure; |
87 | 0 | } |
88 | 0 | *needsLength = PR_TRUE; |
89 | 0 | return SECSuccess; |
90 | 0 | } |
91 | | |
92 | | /* DTLS 1.3 Record map for ACK processing. |
93 | | * This represents a single fragment, so a record which includes |
94 | | * multiple fragments will have one entry for each fragment on the |
95 | | * sender. We use the same structure on the receiver for convenience |
96 | | * but the only value we actually use is |record|. |
97 | | */ |
98 | | typedef struct DTLSHandshakeRecordEntryStr { |
99 | | PRCList link; |
100 | | PRUint16 messageSeq; /* The handshake message sequence number. */ |
101 | | PRUint32 offset; /* The offset into the handshake message. */ |
102 | | PRUint32 length; /* The length of the fragment. */ |
103 | | /* DTLS adds an epoch and sequence number to the TLS record header. */ |
104 | | sslSequenceNumber record; /* The record (includes epoch). */ |
105 | | PRBool acked; /* Has this packet been acked. */ |
106 | | } DTLSHandshakeRecordEntry; |
107 | | |
108 | | /*The sequence number is set to be the low order 48 |
109 | | bits of the 64 bit sequence number.*/ |
110 | 0 | #define LENGTH_SEQ_NUMBER 48 |
111 | | |
112 | | /* Combine the epoch and sequence number into a single value. */ |
113 | | static inline sslSequenceNumber |
114 | | dtls_CombineSequenceNumber(DTLSEpoch epoch, sslSequenceNumber seqNum) |
115 | 0 | { |
116 | 0 | PORT_Assert(seqNum <= RECORD_SEQ_MAX); |
117 | 0 | return ((sslSequenceNumber)epoch << LENGTH_SEQ_NUMBER) | seqNum; |
118 | 0 | } |
119 | | |
120 | | SECStatus |
121 | | dtls13_RememberFragment(sslSocket *ss, |
122 | | PRCList *list, |
123 | | PRUint32 sequence, |
124 | | PRUint32 offset, |
125 | | PRUint32 length, |
126 | | DTLSEpoch epoch, |
127 | | sslSequenceNumber record) |
128 | 0 | { |
129 | 0 | DTLSHandshakeRecordEntry *entry; |
130 | |
|
131 | 0 | PORT_Assert(IS_DTLS(ss)); |
132 | | /* We should never send an empty fragment with offset > 0. */ |
133 | 0 | PORT_Assert(length || !offset); |
134 | |
|
135 | 0 | if (!tls13_MaybeTls13(ss)) { |
136 | 0 | return SECSuccess; |
137 | 0 | } |
138 | | |
139 | 0 | SSL_TRC(20, ("%d: SSL3[%d]: %s remembering %s record=%llx msg=%d offset=%d", |
140 | 0 | SSL_GETPID(), ss->fd, |
141 | 0 | SSL_ROLE(ss), |
142 | 0 | list == &ss->ssl3.hs.dtlsSentHandshake ? "sent" : "received", |
143 | 0 | dtls_CombineSequenceNumber(epoch, record), sequence, offset)); |
144 | |
|
145 | 0 | entry = PORT_ZAlloc(sizeof(DTLSHandshakeRecordEntry)); |
146 | 0 | if (!entry) { |
147 | 0 | return SECFailure; |
148 | 0 | } |
149 | | |
150 | 0 | entry->messageSeq = sequence; |
151 | 0 | entry->offset = offset; |
152 | 0 | entry->length = length; |
153 | 0 | entry->record = dtls_CombineSequenceNumber(epoch, record); |
154 | 0 | entry->acked = PR_FALSE; |
155 | |
|
156 | 0 | PR_APPEND_LINK(&entry->link, list); |
157 | |
|
158 | 0 | return SECSuccess; |
159 | 0 | } |
160 | | |
161 | | /* RFC9147; section 7.1 */ |
162 | | SECStatus |
163 | | dtls13_SendAck(sslSocket *ss) |
164 | 0 | { |
165 | 0 | sslBuffer buf = SSL_BUFFER_EMPTY; |
166 | 0 | SECStatus rv = SECSuccess; |
167 | 0 | PRCList *cursor; |
168 | 0 | PRInt32 sent; |
169 | 0 | unsigned int offset = 0; |
170 | |
|
171 | 0 | SSL_TRC(10, ("%d: SSL3[%d]: Sending ACK", |
172 | 0 | SSL_GETPID(), ss->fd)); |
173 | | |
174 | | /* RecordNumber record_numbers<0..2^16-1>; |
175 | | 2 length bytes for the list of ACKs*/ |
176 | 0 | PRUint32 sizeOfListACK = 2; |
177 | 0 | rv = sslBuffer_Skip(&buf, sizeOfListACK, &offset); |
178 | 0 | if (rv != SECSuccess) { |
179 | 0 | goto loser; |
180 | 0 | } |
181 | 0 | for (cursor = PR_LIST_HEAD(&ss->ssl3.hs.dtlsRcvdHandshake); |
182 | 0 | cursor != &ss->ssl3.hs.dtlsRcvdHandshake; |
183 | 0 | cursor = PR_NEXT_LINK(cursor)) { |
184 | 0 | DTLSHandshakeRecordEntry *entry = (DTLSHandshakeRecordEntry *)cursor; |
185 | |
|
186 | 0 | SSL_TRC(10, ("%d: SSL3[%d]: ACK for record=%llx", |
187 | 0 | SSL_GETPID(), ss->fd, entry->record)); |
188 | | |
189 | | /*See dtls_CombineSequenceNumber function */ |
190 | 0 | PRUint64 epoch = entry->record >> 48; |
191 | 0 | PRUint64 seqNum = entry->record & 0xffffffffffff; |
192 | |
|
193 | 0 | rv = sslBuffer_AppendNumber(&buf, epoch, 8); |
194 | 0 | if (rv != SECSuccess) { |
195 | 0 | goto loser; |
196 | 0 | } |
197 | | |
198 | 0 | rv = sslBuffer_AppendNumber(&buf, seqNum, 8); |
199 | 0 | if (rv != SECSuccess) { |
200 | 0 | goto loser; |
201 | 0 | } |
202 | 0 | } |
203 | | |
204 | 0 | rv = sslBuffer_InsertLength(&buf, offset, sizeOfListACK); |
205 | 0 | if (rv != SECSuccess) { |
206 | 0 | goto loser; |
207 | 0 | } |
208 | | |
209 | 0 | ssl_GetXmitBufLock(ss); |
210 | 0 | sent = ssl3_SendRecord(ss, NULL, ssl_ct_ack, |
211 | 0 | buf.buf, buf.len, 0); |
212 | 0 | ssl_ReleaseXmitBufLock(ss); |
213 | 0 | if (sent != buf.len) { |
214 | 0 | rv = SECFailure; |
215 | 0 | if (sent != -1) { |
216 | 0 | PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
217 | 0 | } |
218 | 0 | } |
219 | |
|
220 | 0 | loser: |
221 | 0 | sslBuffer_Clear(&buf); |
222 | 0 | return rv; |
223 | 0 | } |
224 | | |
225 | | void |
226 | | dtls13_SendAckCb(sslSocket *ss) |
227 | 0 | { |
228 | 0 | if (!IS_DTLS(ss)) { |
229 | 0 | return; |
230 | 0 | } |
231 | 0 | (void)dtls13_SendAck(ss); |
232 | 0 | } |
233 | | |
234 | | /* Limits from RFC9147; section 4.5.3. */ |
235 | | PRBool |
236 | | dtls13_AeadLimitReached(ssl3CipherSpec *spec) |
237 | 0 | { |
238 | 0 | if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_3) { |
239 | 0 | switch (spec->cipherDef->calg) { |
240 | 0 | case ssl_calg_chacha20: |
241 | 0 | case ssl_calg_aes_gcm: |
242 | 0 | return spec->deprotectionFailures >= (1ULL << 36); |
243 | 0 | #ifdef UNSAFE_FUZZER_MODE |
244 | 0 | case ssl_calg_null: |
245 | 0 | return PR_FALSE; |
246 | 0 | #endif |
247 | 0 | default: |
248 | 0 | PORT_Assert(0); |
249 | 0 | break; |
250 | 0 | } |
251 | 0 | } |
252 | 0 | return PR_FALSE; |
253 | 0 | } |
254 | | |
255 | | /* Zero length messages are very simple to check. */ |
256 | | static PRBool |
257 | | dtls_IsEmptyMessageAcknowledged(sslSocket *ss, PRUint16 msgSeq, PRUint32 offset) |
258 | 0 | { |
259 | 0 | PRCList *cursor; |
260 | |
|
261 | 0 | for (cursor = PR_LIST_HEAD(&ss->ssl3.hs.dtlsSentHandshake); |
262 | 0 | cursor != &ss->ssl3.hs.dtlsSentHandshake; |
263 | 0 | cursor = PR_NEXT_LINK(cursor)) { |
264 | 0 | DTLSHandshakeRecordEntry *entry = (DTLSHandshakeRecordEntry *)cursor; |
265 | 0 | if (!entry->acked || msgSeq != entry->messageSeq) { |
266 | 0 | continue; |
267 | 0 | } |
268 | | /* Empty fragments are always offset 0. */ |
269 | 0 | if (entry->length == 0) { |
270 | 0 | PORT_Assert(!entry->offset); |
271 | 0 | return PR_TRUE; |
272 | 0 | } |
273 | 0 | } |
274 | 0 | return PR_FALSE; |
275 | 0 | } |
276 | | |
277 | | /* Take a range starting at |*start| and that start forwards based on the |
278 | | * contents of the acknowedgement in |entry|. Only move if the acknowledged |
279 | | * range overlaps |*start|. Return PR_TRUE if it moves. */ |
280 | | static PRBool |
281 | | dtls_MoveUnackedStartForward(DTLSHandshakeRecordEntry *entry, PRUint32 *start) |
282 | 0 | { |
283 | | /* This entry starts too late. */ |
284 | 0 | if (*start < entry->offset) { |
285 | 0 | return PR_FALSE; |
286 | 0 | } |
287 | | /* This entry ends too early. */ |
288 | 0 | if (*start >= entry->offset + entry->length) { |
289 | 0 | return PR_FALSE; |
290 | 0 | } |
291 | 0 | *start = entry->offset + entry->length; |
292 | 0 | return PR_TRUE; |
293 | 0 | } |
294 | | |
295 | | /* Take a range ending at |*end| and move that end backwards based on the |
296 | | * contents of the acknowedgement in |entry|. Only move if the acknowledged |
297 | | * range overlaps |*end|. Return PR_TRUE if it moves. */ |
298 | | static PRBool |
299 | | dtls_MoveUnackedEndBackward(DTLSHandshakeRecordEntry *entry, PRUint32 *end) |
300 | 0 | { |
301 | | /* This entry ends too early. */ |
302 | 0 | if (*end > entry->offset + entry->length) { |
303 | 0 | return PR_FALSE; |
304 | 0 | } |
305 | | /* This entry starts too late. */ |
306 | 0 | if (*end <= entry->offset) { |
307 | 0 | return PR_FALSE; |
308 | 0 | } |
309 | 0 | *end = entry->offset; |
310 | 0 | return PR_TRUE; |
311 | 0 | } |
312 | | |
313 | | /* Get the next contiguous range of unacknowledged bytes from the handshake |
314 | | * message identified by |msgSeq|. The search starts at the offset in |offset|. |
315 | | * |len| contains the full length of the message. |
316 | | * |
317 | | * Returns PR_TRUE if there is an unacknowledged range. In this case, values at |
318 | | * |start| and |end| are modified to contain the range. |
319 | | * |
320 | | * Returns PR_FALSE if the message is entirely acknowledged from |offset| |
321 | | * onwards. |
322 | | */ |
323 | | PRBool |
324 | | dtls_NextUnackedRange(sslSocket *ss, PRUint16 msgSeq, PRUint32 offset, |
325 | | PRUint32 len, PRUint32 *startOut, PRUint32 *endOut) |
326 | 0 | { |
327 | 0 | PRCList *cur_p; |
328 | 0 | PRBool done = PR_FALSE; |
329 | 0 | DTLSHandshakeRecordEntry *entry; |
330 | 0 | PRUint32 start; |
331 | 0 | PRUint32 end; |
332 | |
|
333 | 0 | PORT_Assert(IS_DTLS(ss)); |
334 | |
|
335 | 0 | *startOut = offset; |
336 | 0 | *endOut = len; |
337 | 0 | if (!tls13_MaybeTls13(ss)) { |
338 | 0 | return PR_TRUE; |
339 | 0 | } |
340 | | |
341 | | /* The message is empty. Use a simple search. */ |
342 | 0 | if (!len) { |
343 | 0 | PORT_Assert(!offset); |
344 | 0 | return !dtls_IsEmptyMessageAcknowledged(ss, msgSeq, offset); |
345 | 0 | } |
346 | | |
347 | | /* This iterates multiple times over the acknowledgments and only terminates |
348 | | * when an entire iteration happens without start or end moving. If that |
349 | | * happens without start and end crossing each other, then there is a range |
350 | | * of unacknowledged data. If they meet, then the message is fully |
351 | | * acknowledged. */ |
352 | 0 | start = offset; |
353 | 0 | end = len; |
354 | 0 | while (!done) { |
355 | 0 | done = PR_TRUE; |
356 | 0 | for (cur_p = PR_LIST_HEAD(&ss->ssl3.hs.dtlsSentHandshake); |
357 | 0 | cur_p != &ss->ssl3.hs.dtlsSentHandshake; |
358 | 0 | cur_p = PR_NEXT_LINK(cur_p)) { |
359 | 0 | entry = (DTLSHandshakeRecordEntry *)cur_p; |
360 | 0 | if (!entry->acked || msgSeq != entry->messageSeq) { |
361 | 0 | continue; |
362 | 0 | } |
363 | | |
364 | 0 | if (dtls_MoveUnackedStartForward(entry, &start) || |
365 | 0 | dtls_MoveUnackedEndBackward(entry, &end)) { |
366 | 0 | if (start >= end) { |
367 | | /* The message is all acknowledged. */ |
368 | 0 | return PR_FALSE; |
369 | 0 | } |
370 | | /* Start over again and keep going until we don't move either |
371 | | * start or end. */ |
372 | 0 | done = PR_FALSE; |
373 | 0 | break; |
374 | 0 | } |
375 | 0 | } |
376 | 0 | } |
377 | 0 | PORT_Assert(start < end); |
378 | |
|
379 | 0 | *startOut = start; |
380 | 0 | *endOut = end; |
381 | 0 | return PR_TRUE; |
382 | 0 | } |
383 | | |
384 | | SECStatus |
385 | | dtls13_SetupAcks(sslSocket *ss) |
386 | 0 | { |
387 | 0 | if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { |
388 | 0 | return SECSuccess; |
389 | 0 | } |
390 | | |
391 | 0 | if (ss->ssl3.hs.endOfFlight) { |
392 | 0 | dtls_CancelTimer(ss, ss->ssl3.hs.ackTimer); |
393 | |
|
394 | 0 | if (ss->ssl3.hs.ws == idle_handshake && ss->sec.isServer) { |
395 | 0 | SSL_TRC(10, ("%d: SSL3[%d]: dtls_HandleHandshake, sending ACK", |
396 | 0 | SSL_GETPID(), ss->fd)); |
397 | 0 | return dtls13_SendAck(ss); |
398 | 0 | } |
399 | 0 | return SECSuccess; |
400 | 0 | } |
401 | | |
402 | | /* We need to send an ACK. */ |
403 | 0 | if (!ss->ssl3.hs.ackTimer->cb) { |
404 | | /* We're not armed, so arm. */ |
405 | 0 | SSL_TRC(10, ("%d: SSL3[%d]: dtls_HandleHandshake, arming ack timer", |
406 | 0 | SSL_GETPID(), ss->fd)); |
407 | 0 | return dtls_StartTimer(ss, ss->ssl3.hs.ackTimer, |
408 | 0 | DTLS_RETRANSMIT_INITIAL_MS / 4, |
409 | 0 | dtls13_SendAckCb); |
410 | 0 | } |
411 | | /* The ack timer is already armed, so just return. */ |
412 | 0 | return SECSuccess; |
413 | 0 | } |
414 | | |
415 | | /* |
416 | | * Special case processing for out-of-epoch records. |
417 | | * This can only handle ACKs for now and everything else generates |
418 | | * an error. In future, may also handle KeyUpdate. |
419 | | * |
420 | | * The error checking here is as follows: |
421 | | * |
422 | | * - If it's not encrypted, out of epoch stuff is just discarded. |
423 | | * - If it's encrypted and the message is a piece of an application data, it's discarded. |
424 | | * - Else out of epoch stuff causes an error. |
425 | | * |
426 | | */ |
427 | | SECStatus |
428 | | dtls13_HandleOutOfEpochRecord(sslSocket *ss, const ssl3CipherSpec *spec, |
429 | | SSLContentType rType, |
430 | | sslBuffer *databuf) |
431 | 0 | { |
432 | 0 | SECStatus rv; |
433 | 0 | sslBuffer buf = *databuf; |
434 | |
|
435 | 0 | databuf->len = 0; /* Discard data whatever happens. */ |
436 | 0 | PORT_Assert(IS_DTLS(ss)); |
437 | 0 | PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); |
438 | | /* Can't happen, but double check. */ |
439 | 0 | if (!IS_DTLS(ss) || (ss->version < SSL_LIBRARY_VERSION_TLS_1_3)) { |
440 | 0 | tls13_FatalError(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); |
441 | 0 | return SECFailure; |
442 | 0 | } |
443 | 0 | SSL_TRC(30, ("%d: DTLS13[%d]: %s handles out of epoch record: type=%d", SSL_GETPID(), |
444 | 0 | ss->fd, SSL_ROLE(ss), rType)); |
445 | |
|
446 | 0 | if (rType == ssl_ct_ack) { |
447 | 0 | ssl_GetSSL3HandshakeLock(ss); |
448 | 0 | rv = dtls13_HandleAck(ss, &buf); |
449 | 0 | ssl_ReleaseSSL3HandshakeLock(ss); |
450 | 0 | PORT_Assert(databuf->len == 0); |
451 | 0 | return rv; |
452 | 0 | } |
453 | | |
454 | 0 | switch (spec->epoch) { |
455 | | |
456 | 0 | case TrafficKeyClearText: |
457 | | /* Drop. */ |
458 | 0 | return SECSuccess; |
459 | | |
460 | 0 | case TrafficKeyHandshake: |
461 | | /* Drop out of order handshake messages, but if we are the |
462 | | * server, we might have processed the client's Finished and |
463 | | * moved on to application data keys, but the client has |
464 | | * retransmitted Finished (e.g., because our ACK got lost.) |
465 | | * We just retransmit the ACK to let the client complete. */ |
466 | 0 | if (rType == ssl_ct_handshake) { |
467 | 0 | if ((ss->sec.isServer) && |
468 | 0 | (ss->ssl3.hs.ws == idle_handshake)) { |
469 | 0 | PORT_Assert(dtls_TimerActive(ss, ss->ssl3.hs.hdTimer)); |
470 | 0 | return dtls13_SendAck(ss); |
471 | 0 | } |
472 | 0 | return SECSuccess; |
473 | 0 | } |
474 | | |
475 | | /* This isn't a handshake record, so shouldn't be encrypted |
476 | | * under the handshake key. */ |
477 | 0 | break; |
478 | | |
479 | 0 | default: |
480 | 0 | if (rType == ssl_ct_application_data) { |
481 | 0 | return SECSuccess; |
482 | 0 | } |
483 | 0 | break; |
484 | 0 | } |
485 | | |
486 | 0 | SSL_TRC(10, ("%d: SSL3[%d]: unexpected out of epoch record type %d", SSL_GETPID(), |
487 | 0 | ss->fd, rType)); |
488 | |
|
489 | 0 | (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); |
490 | 0 | PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE); |
491 | 0 | return SECFailure; |
492 | 0 | } |
493 | | |
494 | | /* KeyUpdate in DTLS1.3 is required to be ACKed. |
495 | | The dtls13_maybeProcessKeyUpdateAck function is called when we receive a message acknowledging KeyUpdate. |
496 | | The function will then update the writing keys of the party started KeyUpdate. |
497 | | */ |
498 | | SECStatus |
499 | | dtls13_maybeProcessKeyUpdateAck(sslSocket *ss, PRUint16 entrySeq) |
500 | 0 | { |
501 | | /* RFC 9147. Section 8. |
502 | | Due to the possibility of an ACK message for a KeyUpdate being lost |
503 | | and thereby preventing the sender of KeyUpdate from updating its |
504 | | keying material, receivers MUST retain the pre-update keying material |
505 | | until receipt and successful decryption of a message using the new |
506 | | keys.*/ |
507 | |
|
508 | 0 | if (ss->ssl3.hs.isKeyUpdateInProgress && entrySeq == ss->ssl3.hs.dtlsHandhakeKeyUpdateMessage) { |
509 | 0 | SSL_TRC(30, ("%d: DTLS13[%d]: %s key update is completed", SSL_GETPID(), ss->fd, SSL_ROLE(ss))); |
510 | 0 | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
511 | |
|
512 | 0 | SECStatus rv = SECSuccess; |
513 | 0 | rv = tls13_UpdateTrafficKeys(ss, ssl_secret_write); |
514 | 0 | if (rv != SECSuccess) { |
515 | 0 | return SECFailure; |
516 | 0 | } |
517 | 0 | PORT_Assert(ss->ssl3.hs.isKeyUpdateInProgress); |
518 | 0 | ss->ssl3.hs.isKeyUpdateInProgress = PR_FALSE; |
519 | |
|
520 | 0 | return rv; |
521 | 0 | } |
522 | | |
523 | 0 | else |
524 | 0 | return SECSuccess; |
525 | 0 | } |
526 | | |
527 | | SECStatus |
528 | | dtls13_HandleAck(sslSocket *ss, sslBuffer *databuf) |
529 | 0 | { |
530 | 0 | PRUint8 *b = databuf->buf; |
531 | 0 | PRUint32 l = databuf->len; |
532 | 0 | unsigned int length; |
533 | 0 | SECStatus rv; |
534 | |
|
535 | 0 | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
536 | | |
537 | | /* Ensure we don't loop. */ |
538 | 0 | databuf->len = 0; |
539 | |
|
540 | 0 | PORT_Assert(IS_DTLS(ss)); |
541 | 0 | if (!tls13_MaybeTls13(ss)) { |
542 | 0 | tls13_FatalError(ss, SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, illegal_parameter); |
543 | 0 | return SECFailure; |
544 | 0 | } |
545 | | |
546 | 0 | SSL_TRC(10, ("%d: SSL3[%d]: Handling ACK", SSL_GETPID(), ss->fd)); |
547 | 0 | rv = ssl3_ConsumeHandshakeNumber(ss, &length, 2, &b, &l); |
548 | 0 | if (rv != SECSuccess) { |
549 | 0 | goto loser; |
550 | 0 | } |
551 | 0 | if (length != l) { |
552 | 0 | goto loser; |
553 | 0 | } |
554 | | |
555 | 0 | while (l > 0) { |
556 | 0 | PRUint64 seq; |
557 | 0 | PRUint64 epoch; |
558 | 0 | PRCList *cursor; |
559 | |
|
560 | 0 | rv = ssl3_ConsumeHandshakeNumber64(ss, &epoch, 8, &b, &l); |
561 | 0 | if (rv != SECSuccess) { |
562 | 0 | goto loser; |
563 | 0 | } |
564 | | |
565 | 0 | rv = ssl3_ConsumeHandshakeNumber64(ss, &seq, 8, &b, &l); |
566 | 0 | if (rv != SECSuccess) { |
567 | 0 | goto loser; |
568 | 0 | } |
569 | | |
570 | 0 | if (epoch > RECORD_EPOCH_MAX) { |
571 | 0 | SSL_TRC(50, ("%d: SSL3[%d]: ACK message was rejected: the epoch exceeds the limit", SSL_GETPID(), ss->fd)); |
572 | 0 | continue; |
573 | 0 | } |
574 | 0 | if (seq > RECORD_SEQ_MAX) { |
575 | 0 | SSL_TRC(50, ("%d: SSL3[%d]: ACK message was rejected: the sequence number exceeds the limit", SSL_GETPID(), ss->fd)); |
576 | 0 | continue; |
577 | 0 | } |
578 | | |
579 | 0 | seq = dtls_CombineSequenceNumber(epoch, seq); |
580 | |
|
581 | 0 | for (cursor = PR_LIST_HEAD(&ss->ssl3.hs.dtlsSentHandshake); |
582 | 0 | cursor != &ss->ssl3.hs.dtlsSentHandshake; |
583 | 0 | cursor = PR_NEXT_LINK(cursor)) { |
584 | 0 | DTLSHandshakeRecordEntry *entry = (DTLSHandshakeRecordEntry *)cursor; |
585 | |
|
586 | 0 | if (entry->record == seq) { |
587 | 0 | SSL_TRC(30, ( |
588 | 0 | "%d: DTLS13[%d]: Marking record=%llx message %d offset %d length=%d as ACKed", |
589 | 0 | SSL_GETPID(), ss->fd, |
590 | 0 | entry->record, entry->messageSeq, entry->offset, entry->length)); |
591 | 0 | entry->acked = PR_TRUE; |
592 | | |
593 | | /* When we sent a KeyUpdate message, we have recorded the identifier of the message. |
594 | | During the HandleACK we check if we received an ack for the KeyUpdate message we sent.*/ |
595 | 0 | rv = dtls13_maybeProcessKeyUpdateAck(ss, entry->messageSeq); |
596 | 0 | if (rv != SECSuccess) { |
597 | 0 | return SECFailure; |
598 | 0 | } |
599 | 0 | } |
600 | 0 | } |
601 | 0 | } |
602 | | /* Try to flush. */ |
603 | 0 | rv = dtls_TransmitMessageFlight(ss); |
604 | 0 | if (rv != SECSuccess) { |
605 | 0 | return SECFailure; |
606 | 0 | } |
607 | | |
608 | | /* Reset the retransmit timer. */ |
609 | 0 | if (ss->ssl3.hs.rtTimer->cb) { |
610 | 0 | (void)dtls_RestartTimer(ss, ss->ssl3.hs.rtTimer); |
611 | 0 | } |
612 | | |
613 | | /* If there are no more messages to send, cleanup. */ |
614 | 0 | if (PR_CLIST_IS_EMPTY(&ss->ssl3.hs.lastMessageFlight)) { |
615 | 0 | SSL_TRC(10, ("%d: SSL3[%d]: No more unacked handshake messages", |
616 | 0 | SSL_GETPID(), ss->fd)); |
617 | |
|
618 | 0 | dtls_CancelTimer(ss, ss->ssl3.hs.rtTimer); |
619 | 0 | ssl_ClearPRCList(&ss->ssl3.hs.dtlsSentHandshake, NULL); |
620 | | /* If the handshake is finished, and we're the client then |
621 | | * also clean up the handshake read cipher spec. Any ACKs |
622 | | * we receive will be with the application data cipher spec. |
623 | | * The server needs to keep the handshake cipher spec around |
624 | | * for the holddown period to process retransmitted Finisheds. |
625 | | */ |
626 | 0 | if (!ss->sec.isServer && (ss->ssl3.hs.ws == idle_handshake)) { |
627 | 0 | ssl_CipherSpecReleaseByEpoch(ss, ssl_secret_read, |
628 | 0 | TrafficKeyHandshake); |
629 | 0 | } |
630 | 0 | } |
631 | 0 | return SECSuccess; |
632 | | |
633 | 0 | loser: |
634 | | /* Due to bug 1829391 we may incorrectly send an alert rather than |
635 | | * ignore an invalid record here. */ |
636 | 0 | SSL_TRC(11, ("%d: SSL3[%d]: Error processing DTLS1.3 ACK.", |
637 | 0 | SSL_GETPID(), ss->fd)); |
638 | 0 | PORT_SetError(SSL_ERROR_RX_MALFORMED_DTLS_ACK); |
639 | 0 | return SECFailure; |
640 | 0 | } |
641 | | |
642 | | /* Clean up the read timer for the handshake cipher suites on the |
643 | | * server. |
644 | | * |
645 | | * In DTLS 1.3, the client speaks last (Finished), and will retransmit |
646 | | * until the server ACKs that message (using application data cipher |
647 | | * suites). I.e., |
648 | | * |
649 | | * - The client uses the retransmit timer and retransmits using the |
650 | | * saved write handshake cipher suite. |
651 | | * - The server keeps the saved read handshake cipher suite around |
652 | | * for the holddown period in case it needs to read the Finished. |
653 | | * |
654 | | * After the holddown period, the server assumes the client is happy |
655 | | * and discards the handshake read cipher suite. |
656 | | */ |
657 | | |
658 | | void |
659 | | dtls13_HolddownTimerCb(sslSocket *ss) |
660 | 0 | { |
661 | 0 | SSL_TRC(10, ("%d: SSL3[%d]: holddown timer fired", |
662 | 0 | SSL_GETPID(), ss->fd)); |
663 | 0 | ssl_CipherSpecReleaseByEpoch(ss, ssl_secret_read, TrafficKeyHandshake); |
664 | 0 | ssl_ClearPRCList(&ss->ssl3.hs.dtlsRcvdHandshake, NULL); |
665 | 0 | } |
666 | | |
667 | | /*RFC 9147. 4.2.3. Record Number Encryption*/ |
668 | | SECStatus |
669 | | dtls13_MaskSequenceNumber(sslSocket *ss, ssl3CipherSpec *spec, |
670 | | PRUint8 *hdr, PRUint8 *cipherText, PRUint32 cipherTextLen) |
671 | 0 | { |
672 | 0 | PORT_Assert(IS_DTLS(ss)); |
673 | 0 | if (spec->version < SSL_LIBRARY_VERSION_TLS_1_3) { |
674 | 0 | return SECSuccess; |
675 | 0 | } |
676 | | |
677 | 0 | if (spec->maskContext) { |
678 | 0 | #ifdef UNSAFE_FUZZER_MODE |
679 | | /* Use a null mask. */ |
680 | 0 | PRUint8 mask[2] = { 0 }; |
681 | | #else |
682 | | /* "This procedure requires the ciphertext length be at least 16 bytes. |
683 | | * Receivers MUST reject shorter records as if they had failed |
684 | | * deprotection, as described in Section 4.5.2." */ |
685 | | if (cipherTextLen < 16) { |
686 | | PORT_SetError(SSL_ERROR_BAD_MAC_READ); |
687 | | return SECFailure; |
688 | | } |
689 | | |
690 | | PRUint8 mask[2]; |
691 | | SECStatus rv = ssl_CreateMaskInner(spec->maskContext, cipherText, cipherTextLen, mask, sizeof(mask)); |
692 | | |
693 | | if (rv != SECSuccess) { |
694 | | PORT_SetError(SSL_ERROR_BAD_MAC_READ); |
695 | | return SECFailure; |
696 | | } |
697 | | #endif |
698 | | |
699 | | /* |
700 | | The encrypted sequence number is computed by XORing the leading bytes |
701 | | of the mask with the on-the-wire representation of the sequence |
702 | | number. Decryption is accomplished by the same process. |
703 | | */ |
704 | |
|
705 | 0 | PRUint32 maskSBitIsSet = 0x08; |
706 | 0 | hdr[1] ^= mask[0]; |
707 | 0 | if (hdr[0] & maskSBitIsSet) { |
708 | 0 | hdr[2] ^= mask[1]; |
709 | 0 | } |
710 | 0 | } |
711 | 0 | return SECSuccess; |
712 | 0 | } |
713 | | |
714 | | CK_MECHANISM_TYPE |
715 | | tls13_SequenceNumberEncryptionMechanism(SSLCipherAlgorithm bulkAlgorithm) |
716 | 0 | { |
717 | | /* |
718 | | When the AEAD is based on AES, then the mask is generated by |
719 | | computing AES-ECB on the first 16 bytes of the ciphertext: |
720 | | |
721 | | When the AEAD is based on ChaCha20, then the mask is generated by |
722 | | treating the first 4 bytes of the ciphertext as the block counter and |
723 | | the next 12 bytes as the nonce, passing them to the ChaCha20 block |
724 | | function. |
725 | | */ |
726 | |
|
727 | 0 | switch (bulkAlgorithm) { |
728 | 0 | case ssl_calg_aes_gcm: |
729 | 0 | return CKM_AES_ECB; |
730 | 0 | case ssl_calg_chacha20: |
731 | 0 | return CKM_NSS_CHACHA20_CTR; |
732 | 0 | default: |
733 | 0 | PORT_Assert(PR_FALSE); |
734 | 0 | } |
735 | 0 | return CKM_INVALID_MECHANISM; |
736 | 0 | } |
737 | | |
738 | | /* The function constucts the KeyUpdate Message. |
739 | | The structure is presented in RFC 9147 Section 5.2. */ |
740 | | |
741 | | SECStatus |
742 | | dtls13_EnqueueKeyUpdateMessage(sslSocket *ss, tls13KeyUpdateRequest request) |
743 | 0 | { |
744 | 0 | SECStatus rv = SECFailure; |
745 | | /* |
746 | | The epoch number is initially zero and is incremented each time |
747 | | keying material changes and a sender aims to rekey. |
748 | | More details are provided in RFC 9147 Section 6.1.*/ |
749 | 0 | rv = ssl3_AppendHandshakeHeaderAndStashSeqNum(ss, ssl_hs_key_update, 1, &ss->ssl3.hs.dtlsHandhakeKeyUpdateMessage); |
750 | 0 | if (rv != SECSuccess) { |
751 | 0 | return rv; /* error code set by ssl3_AppendHandshakeHeader, if applicable. */ |
752 | 0 | } |
753 | 0 | rv = ssl3_AppendHandshakeNumber(ss, request, 1); |
754 | 0 | if (rv != SECSuccess) { |
755 | 0 | return rv; /* error code set by ssl3_AppendHandshakeNumber, if applicable. */ |
756 | 0 | } |
757 | | |
758 | 0 | return SECSuccess; |
759 | 0 | } |
760 | | |
761 | | /* The ssl3CipherSpecStr (sslspec.h) structure describes a spec for r/w records. |
762 | | For the specification, the epoch is defined as uint16 value, |
763 | | So the maximum epoch is 2 ^ 16 - 1*/ |
764 | 0 | #define DTLS13_MAX_EPOCH_TYPE PR_UINT16_MAX |
765 | | /*RFC 9147. Section 8. |
766 | | In order to provide an extra margin of security, |
767 | | sending implementations MUST NOT allow the epoch to exceed 2^48-1.*/ |
768 | | #define DTLS13_MAX_EPOCH ((0x1ULL << 48) - 1) |
769 | | |
770 | | SECStatus |
771 | | dtls13_MaybeSendKeyUpdate(sslSocket *ss, tls13KeyUpdateRequest request, PRBool buffer) |
772 | 0 | { |
773 | |
|
774 | 0 | SSL_TRC(30, ("%d: DTLS13[%d]: %s sends key update, response %s", |
775 | 0 | SSL_GETPID(), ss->fd, SSL_ROLE(ss), |
776 | 0 | (request == update_requested) ? "requested" |
777 | 0 | : "not requested")); |
778 | |
|
779 | 0 | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
780 | |
|
781 | 0 | SECStatus rv = SECFailure; |
782 | | /* |
783 | | For the specification, the epoch is defined as uint16 value (see bug 1809872) |
784 | | and the sendKeyUpdate will update the writing keys |
785 | | so, if the epoch is already maximum, KeyUpdate will be cancelled.*/ |
786 | |
|
787 | 0 | ssl_GetSpecWriteLock(ss); |
788 | | /* This check is done as well in the updateTrafficKey function */ |
789 | 0 | if (ss->ssl3.cwSpec->epoch >= DTLS13_MAX_EPOCH_TYPE) { |
790 | 0 | ssl_ReleaseSpecWriteLock(ss); |
791 | 0 | SSL_TRC(30, ("%d: DTLS13[%d]: %s keyUpdate request was cancelled, as the writing epoch arrived to the maximum possible", |
792 | 0 | SSL_GETPID(), ss->fd, SSL_ROLE(ss))); |
793 | 0 | PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); |
794 | 0 | return SECFailure; |
795 | 0 | } else { |
796 | 0 | ssl_ReleaseSpecWriteLock(ss); |
797 | 0 | } |
798 | | |
799 | 0 | PORT_Assert(DTLS13_MAX_EPOCH_TYPE <= DTLS13_MAX_EPOCH); |
800 | |
|
801 | 0 | ssl_GetSpecReadLock(ss); |
802 | | /* TODO(AW) - See bug 1809872. */ |
803 | 0 | if (request == update_requested && ss->ssl3.crSpec->epoch >= DTLS13_MAX_EPOCH_TYPE) { |
804 | 0 | SSL_TRC(30, ("%d: DTLS13[%d]: %s keyUpdate request update_requested was cancelled, as the reading epoch arrived to the maximum possible", |
805 | 0 | SSL_GETPID(), ss->fd, SSL_ROLE(ss))); |
806 | 0 | request = update_not_requested; |
807 | 0 | } |
808 | 0 | ssl_ReleaseSpecReadLock(ss); |
809 | | |
810 | | /* RFC 9147. Section 5.8.4. |
811 | | In contrast, implementations MUST NOT send KeyUpdate, NewConnectionId, or |
812 | | RequestConnectionId messages if an earlier message of the same type |
813 | | has not yet been acknowledged.*/ |
814 | 0 | if (ss->ssl3.hs.isKeyUpdateInProgress) { |
815 | 0 | SSL_TRC(30, ("%d: DTLS13[%d]: the previous %s KeyUpdate message was not yet ack-ed, dropping", |
816 | 0 | SSL_GETPID(), ss->fd, SSL_ROLE(ss), ss->ssl3.hs.sendMessageSeq)); |
817 | 0 | return SECSuccess; |
818 | 0 | } |
819 | | |
820 | 0 | ssl_GetXmitBufLock(ss); |
821 | 0 | rv = dtls13_EnqueueKeyUpdateMessage(ss, request); |
822 | 0 | if (rv != SECSuccess) { |
823 | 0 | return rv; /* error code already set */ |
824 | 0 | } |
825 | | |
826 | | /* Trying to send the message - without buffering. */ |
827 | | /* TODO[AW]: As I just emulated the API, I am not sure that it's necessary to buffer. */ |
828 | 0 | rv = ssl3_FlushHandshake(ss, 0); |
829 | 0 | if (rv != SECSuccess) { |
830 | 0 | return SECFailure; /* error code set by ssl3_FlushHandshake */ |
831 | 0 | } |
832 | 0 | ssl_ReleaseXmitBufLock(ss); |
833 | | |
834 | | /* The keyUpdate is started. */ |
835 | 0 | PORT_Assert(ss->ssl3.hs.isKeyUpdateInProgress == PR_FALSE); |
836 | 0 | ss->ssl3.hs.isKeyUpdateInProgress = PR_TRUE; |
837 | |
|
838 | 0 | SSL_TRC(30, ("%d: DTLS13[%d]: %s has just sent keyUpdate request #%d and is waiting for ack", |
839 | 0 | SSL_GETPID(), ss->fd, SSL_ROLE(ss), ss->ssl3.hs.dtlsHandhakeKeyUpdateMessage)); |
840 | 0 | return SECSuccess; |
841 | 0 | } |
842 | | |
843 | | SECStatus |
844 | | dtls13_HandleKeyUpdate(sslSocket *ss, PRUint8 *b, unsigned int length, PRBool update) |
845 | 0 | { |
846 | 0 | SSL_TRC(10, ("%d: DTLS13[%d]: %s handles Key Update", |
847 | 0 | SSL_GETPID(), ss->fd, SSL_ROLE(ss))); |
848 | |
|
849 | 0 | PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
850 | 0 | SECStatus rv = SECSuccess; |
851 | 0 | if (update == update_requested) { |
852 | | /* Respond immediately (don't buffer). */ |
853 | 0 | rv = tls13_SendKeyUpdate(ss, update_not_requested, PR_FALSE); |
854 | 0 | if (rv != SECSuccess) { |
855 | 0 | return SECFailure; /* Error already set. */ |
856 | 0 | } |
857 | 0 | } |
858 | | |
859 | 0 | SSL_TRC(30, ("%d: DTLS13[%d]: now %s is allowing the messages from the previous epoch", |
860 | 0 | SSL_GETPID(), ss->fd, SSL_ROLE(ss))); |
861 | 0 | ss->ssl3.hs.allowPreviousEpoch = PR_TRUE; |
862 | | /* Updating the reading key. */ |
863 | 0 | rv = tls13_UpdateTrafficKeys(ss, ssl_secret_read); |
864 | 0 | if (rv != SECSuccess) { |
865 | 0 | return SECFailure; /* Error code set by tls13_UpdateTrafficKeys. */ |
866 | 0 | } |
867 | 0 | return SECSuccess; |
868 | 0 | } |