1 // Copyright (C) 2018-2019, Cloudflare, Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
19 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 use ring::aead;
28 use ring::hkdf;
29
30 use crate::Error;
31 use crate::Result;
32
33 use crate::packet;
34
35 #[repr(C)]
36 #[derive(Clone, Copy, Debug, PartialEq)]
37 pub enum Level {
38 Initial = 0,
39 ZeroRTT = 1,
40 Handshake = 2,
41 OneRTT = 3,
42 }
43
44 impl Level {
from_epoch(e: packet::Epoch) -> Level45 pub fn from_epoch(e: packet::Epoch) -> Level {
46 match e {
47 packet::EPOCH_INITIAL => Level::Initial,
48
49 packet::EPOCH_HANDSHAKE => Level::Handshake,
50
51 packet::EPOCH_APPLICATION => Level::OneRTT,
52
53 _ => unreachable!(),
54 }
55 }
56 }
57
58 #[derive(Clone, Copy, Debug, PartialEq)]
59 pub enum Algorithm {
60 #[allow(non_camel_case_types)]
61 AES128_GCM,
62
63 #[allow(non_camel_case_types)]
64 AES256_GCM,
65
66 #[allow(non_camel_case_types)]
67 ChaCha20_Poly1305,
68 }
69
70 impl Algorithm {
get_ring_aead(self) -> &'static aead::Algorithm71 fn get_ring_aead(self) -> &'static aead::Algorithm {
72 match self {
73 Algorithm::AES128_GCM => &aead::AES_128_GCM,
74 Algorithm::AES256_GCM => &aead::AES_256_GCM,
75 Algorithm::ChaCha20_Poly1305 => &aead::CHACHA20_POLY1305,
76 }
77 }
78
get_ring_hp(self) -> &'static aead::quic::Algorithm79 fn get_ring_hp(self) -> &'static aead::quic::Algorithm {
80 match self {
81 Algorithm::AES128_GCM => &aead::quic::AES_128,
82 Algorithm::AES256_GCM => &aead::quic::AES_256,
83 Algorithm::ChaCha20_Poly1305 => &aead::quic::CHACHA20,
84 }
85 }
86
get_ring_digest(self) -> hkdf::Algorithm87 fn get_ring_digest(self) -> hkdf::Algorithm {
88 match self {
89 Algorithm::AES128_GCM => hkdf::HKDF_SHA256,
90 Algorithm::AES256_GCM => hkdf::HKDF_SHA384,
91 Algorithm::ChaCha20_Poly1305 => hkdf::HKDF_SHA256,
92 }
93 }
94
key_len(self) -> usize95 pub fn key_len(self) -> usize {
96 self.get_ring_aead().key_len()
97 }
98
tag_len(self) -> usize99 pub fn tag_len(self) -> usize {
100 if cfg!(feature = "fuzzing") {
101 return 0;
102 }
103
104 self.get_ring_aead().tag_len()
105 }
106
nonce_len(self) -> usize107 pub fn nonce_len(self) -> usize {
108 self.get_ring_aead().nonce_len()
109 }
110 }
111
112 pub struct Open {
113 alg: Algorithm,
114
115 hp_key: aead::quic::HeaderProtectionKey,
116
117 key: aead::LessSafeKey,
118
119 nonce: Vec<u8>,
120 }
121
122 impl Open {
new( alg: Algorithm, key: &[u8], iv: &[u8], hp_key: &[u8], ) -> Result<Open>123 pub fn new(
124 alg: Algorithm, key: &[u8], iv: &[u8], hp_key: &[u8],
125 ) -> Result<Open> {
126 Ok(Open {
127 hp_key: aead::quic::HeaderProtectionKey::new(
128 alg.get_ring_hp(),
129 hp_key,
130 )
131 .map_err(|_| Error::CryptoFail)?,
132
133 key: aead::LessSafeKey::new(
134 aead::UnboundKey::new(alg.get_ring_aead(), key)
135 .map_err(|_| Error::CryptoFail)?,
136 ),
137
138 nonce: Vec::from(iv),
139
140 alg,
141 })
142 }
143
from_secret(aead: Algorithm, secret: &[u8]) -> Result<Open>144 pub fn from_secret(aead: Algorithm, secret: &[u8]) -> Result<Open> {
145 let key_len = aead.key_len();
146 let nonce_len = aead.nonce_len();
147
148 let mut key = vec![0; key_len];
149 let mut iv = vec![0; nonce_len];
150 let mut pn_key = vec![0; key_len];
151
152 derive_pkt_key(aead, &secret, &mut key)?;
153 derive_pkt_iv(aead, &secret, &mut iv)?;
154 derive_hdr_key(aead, &secret, &mut pn_key)?;
155
156 Open::new(aead, &key, &iv, &pn_key)
157 }
158
open_with_u64_counter( &self, counter: u64, ad: &[u8], buf: &mut [u8], ) -> Result<usize>159 pub fn open_with_u64_counter(
160 &self, counter: u64, ad: &[u8], buf: &mut [u8],
161 ) -> Result<usize> {
162 if cfg!(feature = "fuzzing") {
163 return Ok(buf.len());
164 }
165
166 let nonce = make_nonce(&self.nonce, counter);
167
168 let ad = aead::Aad::from(ad);
169
170 let plain = self
171 .key
172 .open_in_place(nonce, ad, buf)
173 .map_err(|_| Error::CryptoFail)?;
174
175 Ok(plain.len())
176 }
177
new_mask(&self, sample: &[u8]) -> Result<[u8; 5]>178 pub fn new_mask(&self, sample: &[u8]) -> Result<[u8; 5]> {
179 if cfg!(feature = "fuzzing") {
180 return Ok(<[u8; 5]>::default());
181 }
182
183 let mask = self
184 .hp_key
185 .new_mask(sample)
186 .map_err(|_| Error::CryptoFail)?;
187
188 Ok(mask)
189 }
190
alg(&self) -> Algorithm191 pub fn alg(&self) -> Algorithm {
192 self.alg
193 }
194 }
195
196 pub struct Seal {
197 alg: Algorithm,
198
199 hp_key: aead::quic::HeaderProtectionKey,
200
201 key: aead::LessSafeKey,
202
203 nonce: Vec<u8>,
204 }
205
206 impl Seal {
new( alg: Algorithm, key: &[u8], iv: &[u8], hp_key: &[u8], ) -> Result<Seal>207 pub fn new(
208 alg: Algorithm, key: &[u8], iv: &[u8], hp_key: &[u8],
209 ) -> Result<Seal> {
210 Ok(Seal {
211 hp_key: aead::quic::HeaderProtectionKey::new(
212 alg.get_ring_hp(),
213 hp_key,
214 )
215 .map_err(|_| Error::CryptoFail)?,
216
217 key: aead::LessSafeKey::new(
218 aead::UnboundKey::new(alg.get_ring_aead(), key)
219 .map_err(|_| Error::CryptoFail)?,
220 ),
221
222 nonce: Vec::from(iv),
223
224 alg,
225 })
226 }
227
from_secret(aead: Algorithm, secret: &[u8]) -> Result<Seal>228 pub fn from_secret(aead: Algorithm, secret: &[u8]) -> Result<Seal> {
229 let key_len = aead.key_len();
230 let nonce_len = aead.nonce_len();
231
232 let mut key = vec![0; key_len];
233 let mut iv = vec![0; nonce_len];
234 let mut pn_key = vec![0; key_len];
235
236 derive_pkt_key(aead, &secret, &mut key)?;
237 derive_pkt_iv(aead, &secret, &mut iv)?;
238 derive_hdr_key(aead, &secret, &mut pn_key)?;
239
240 Seal::new(aead, &key, &iv, &pn_key)
241 }
242
seal_with_u64_counter( &self, counter: u64, ad: &[u8], buf: &mut [u8], ) -> Result<()>243 pub fn seal_with_u64_counter(
244 &self, counter: u64, ad: &[u8], buf: &mut [u8],
245 ) -> Result<()> {
246 if cfg!(feature = "fuzzing") {
247 return Ok(());
248 }
249
250 let nonce = make_nonce(&self.nonce, counter);
251
252 let ad = aead::Aad::from(ad);
253
254 let tag_len = self.alg().tag_len();
255
256 let in_out_len =
257 buf.len().checked_sub(tag_len).ok_or(Error::CryptoFail)?;
258
259 let (in_out, tag_out) = buf.split_at_mut(in_out_len);
260
261 let tag = self
262 .key
263 .seal_in_place_separate_tag(nonce, ad, in_out)
264 .map_err(|_| Error::CryptoFail)?;
265
266 // Append the AEAD tag to the end of the sealed buffer.
267 tag_out.copy_from_slice(tag.as_ref());
268
269 Ok(())
270 }
271
new_mask(&self, sample: &[u8]) -> Result<[u8; 5]>272 pub fn new_mask(&self, sample: &[u8]) -> Result<[u8; 5]> {
273 if cfg!(feature = "fuzzing") {
274 return Ok(<[u8; 5]>::default());
275 }
276
277 let mask = self
278 .hp_key
279 .new_mask(sample)
280 .map_err(|_| Error::CryptoFail)?;
281
282 Ok(mask)
283 }
284
alg(&self) -> Algorithm285 pub fn alg(&self) -> Algorithm {
286 self.alg
287 }
288 }
289
derive_initial_key_material( cid: &[u8], version: u32, is_server: bool, ) -> Result<(Open, Seal)>290 pub fn derive_initial_key_material(
291 cid: &[u8], version: u32, is_server: bool,
292 ) -> Result<(Open, Seal)> {
293 let mut secret = [0; 32];
294
295 let aead = Algorithm::AES128_GCM;
296
297 let key_len = aead.key_len();
298 let nonce_len = aead.nonce_len();
299
300 let initial_secret = derive_initial_secret(&cid, version);
301
302 // Client.
303 let mut client_key = vec![0; key_len];
304 let mut client_iv = vec![0; nonce_len];
305 let mut client_hp_key = vec![0; key_len];
306
307 derive_client_initial_secret(&initial_secret, &mut secret)?;
308 derive_pkt_key(aead, &secret, &mut client_key)?;
309 derive_pkt_iv(aead, &secret, &mut client_iv)?;
310 derive_hdr_key(aead, &secret, &mut client_hp_key)?;
311
312 // Server.
313 let mut server_key = vec![0; key_len];
314 let mut server_iv = vec![0; nonce_len];
315 let mut server_hp_key = vec![0; key_len];
316
317 derive_server_initial_secret(&initial_secret, &mut secret)?;
318 derive_pkt_key(aead, &secret, &mut server_key)?;
319 derive_pkt_iv(aead, &secret, &mut server_iv)?;
320 derive_hdr_key(aead, &secret, &mut server_hp_key)?;
321
322 let (open, seal) = if is_server {
323 (
324 Open::new(aead, &client_key, &client_iv, &client_hp_key)?,
325 Seal::new(aead, &server_key, &server_iv, &server_hp_key)?,
326 )
327 } else {
328 (
329 Open::new(aead, &server_key, &server_iv, &server_hp_key)?,
330 Seal::new(aead, &client_key, &client_iv, &client_hp_key)?,
331 )
332 };
333
334 Ok((open, seal))
335 }
336
derive_initial_secret(secret: &[u8], version: u32) -> hkdf::Prk337 fn derive_initial_secret(secret: &[u8], version: u32) -> hkdf::Prk {
338 const INITIAL_SALT: [u8; 20] = [
339 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6,
340 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a,
341 ];
342
343 const INITIAL_SALT_DRAFT29: [u8; 20] = [
344 0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1,
345 0x9c, 0x61, 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99,
346 ];
347
348 const INITIAL_SALT_DRAFT27: [u8; 20] = [
349 0xc3, 0xee, 0xf7, 0x12, 0xc7, 0x2e, 0xbb, 0x5a, 0x11, 0xa7, 0xd2, 0x43,
350 0x2b, 0xb4, 0x63, 0x65, 0xbe, 0xf9, 0xf5, 0x02,
351 ];
352
353 let salt = match version {
354 crate::PROTOCOL_VERSION_DRAFT27 | crate::PROTOCOL_VERSION_DRAFT28 =>
355 &INITIAL_SALT_DRAFT27,
356
357 crate::PROTOCOL_VERSION_DRAFT29 => &INITIAL_SALT_DRAFT29,
358
359 _ => &INITIAL_SALT,
360 };
361
362 let salt = hkdf::Salt::new(hkdf::HKDF_SHA256, salt);
363 salt.extract(secret)
364 }
365
derive_client_initial_secret(prk: &hkdf::Prk, out: &mut [u8]) -> Result<()>366 fn derive_client_initial_secret(prk: &hkdf::Prk, out: &mut [u8]) -> Result<()> {
367 const LABEL: &[u8] = b"client in";
368 hkdf_expand_label(prk, LABEL, out)
369 }
370
derive_server_initial_secret(prk: &hkdf::Prk, out: &mut [u8]) -> Result<()>371 fn derive_server_initial_secret(prk: &hkdf::Prk, out: &mut [u8]) -> Result<()> {
372 const LABEL: &[u8] = b"server in";
373 hkdf_expand_label(prk, LABEL, out)
374 }
375
derive_hdr_key( aead: Algorithm, secret: &[u8], out: &mut [u8], ) -> Result<()>376 pub fn derive_hdr_key(
377 aead: Algorithm, secret: &[u8], out: &mut [u8],
378 ) -> Result<()> {
379 const LABEL: &[u8] = b"quic hp";
380
381 let key_len = aead.key_len();
382
383 if key_len > out.len() {
384 return Err(Error::CryptoFail);
385 }
386
387 let secret = hkdf::Prk::new_less_safe(aead.get_ring_digest(), secret);
388 hkdf_expand_label(&secret, LABEL, &mut out[..key_len])
389 }
390
derive_pkt_key( aead: Algorithm, secret: &[u8], out: &mut [u8], ) -> Result<()>391 pub fn derive_pkt_key(
392 aead: Algorithm, secret: &[u8], out: &mut [u8],
393 ) -> Result<()> {
394 const LABEL: &[u8] = b"quic key";
395
396 let key_len = aead.key_len();
397
398 if key_len > out.len() {
399 return Err(Error::CryptoFail);
400 }
401
402 let secret = hkdf::Prk::new_less_safe(aead.get_ring_digest(), secret);
403 hkdf_expand_label(&secret, LABEL, &mut out[..key_len])
404 }
405
derive_pkt_iv( aead: Algorithm, secret: &[u8], out: &mut [u8], ) -> Result<()>406 pub fn derive_pkt_iv(
407 aead: Algorithm, secret: &[u8], out: &mut [u8],
408 ) -> Result<()> {
409 const LABEL: &[u8] = b"quic iv";
410
411 let nonce_len = aead.nonce_len();
412
413 if nonce_len > out.len() {
414 return Err(Error::CryptoFail);
415 }
416
417 let secret = hkdf::Prk::new_less_safe(aead.get_ring_digest(), secret);
418 hkdf_expand_label(&secret, LABEL, &mut out[..nonce_len])
419 }
420
hkdf_expand_label( prk: &hkdf::Prk, label: &[u8], out: &mut [u8], ) -> Result<()>421 fn hkdf_expand_label(
422 prk: &hkdf::Prk, label: &[u8], out: &mut [u8],
423 ) -> Result<()> {
424 const LABEL_PREFIX: &[u8] = b"tls13 ";
425
426 let out_len = (out.len() as u16).to_be_bytes();
427 let label_len = (LABEL_PREFIX.len() + label.len()) as u8;
428
429 let info = [&out_len, &[label_len][..], LABEL_PREFIX, label, &[0][..]];
430
431 prk.expand(&info, ArbitraryOutputLen(out.len()))
432 .map_err(|_| Error::CryptoFail)?
433 .fill(out)
434 .map_err(|_| Error::CryptoFail)?;
435
436 Ok(())
437 }
438
make_nonce(iv: &[u8], counter: u64) -> aead::Nonce439 fn make_nonce(iv: &[u8], counter: u64) -> aead::Nonce {
440 let mut nonce = [0; aead::NONCE_LEN];
441 nonce.copy_from_slice(&iv);
442
443 // XOR the last bytes of the IV with the counter. This is equivalent to
444 // left-padding the counter with zero bytes.
445 for (a, b) in nonce[4..].iter_mut().zip(counter.to_be_bytes().iter()) {
446 *a ^= b;
447 }
448
449 aead::Nonce::assume_unique_for_key(nonce)
450 }
451
452 // The ring HKDF expand() API does not accept an arbitrary output length, so we
453 // need to hide the `usize` length as part of a type that implements the trait
454 // `ring::hkdf::KeyType` in order to trick ring into accepting it.
455 struct ArbitraryOutputLen(usize);
456
457 impl hkdf::KeyType for ArbitraryOutputLen {
len(&self) -> usize458 fn len(&self) -> usize {
459 self.0
460 }
461 }
462
463 #[cfg(test)]
464 mod tests {
465 use super::*;
466
467 #[test]
derive_initial_secrets_v1()468 fn derive_initial_secrets_v1() {
469 let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
470
471 let mut secret = [0; 32];
472 let mut pkt_key = [0; 16];
473 let mut pkt_iv = [0; 12];
474 let mut hdr_key = [0; 16];
475
476 let aead = Algorithm::AES128_GCM;
477
478 let initial_secret =
479 derive_initial_secret(&dcid, crate::PROTOCOL_VERSION_V1);
480
481 // Client.
482 assert!(
483 derive_client_initial_secret(&initial_secret, &mut secret).is_ok()
484 );
485 let expected_client_initial_secret = [
486 0xc0, 0x0c, 0xf1, 0x51, 0xca, 0x5b, 0xe0, 0x75, 0xed, 0x0e, 0xbf,
487 0xb5, 0xc8, 0x03, 0x23, 0xc4, 0x2d, 0x6b, 0x7d, 0xb6, 0x78, 0x81,
488 0x28, 0x9a, 0xf4, 0x00, 0x8f, 0x1f, 0x6c, 0x35, 0x7a, 0xea,
489 ];
490 assert_eq!(&secret, &expected_client_initial_secret);
491
492 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
493 let expected_client_pkt_key = [
494 0x1f, 0x36, 0x96, 0x13, 0xdd, 0x76, 0xd5, 0x46, 0x77, 0x30, 0xef,
495 0xcb, 0xe3, 0xb1, 0xa2, 0x2d,
496 ];
497 assert_eq!(&pkt_key, &expected_client_pkt_key);
498
499 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
500 let expected_client_pkt_iv = [
501 0xfa, 0x04, 0x4b, 0x2f, 0x42, 0xa3, 0xfd, 0x3b, 0x46, 0xfb, 0x25,
502 0x5c,
503 ];
504 assert_eq!(&pkt_iv, &expected_client_pkt_iv);
505
506 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
507 let expected_client_hdr_key = [
508 0x9f, 0x50, 0x44, 0x9e, 0x04, 0xa0, 0xe8, 0x10, 0x28, 0x3a, 0x1e,
509 0x99, 0x33, 0xad, 0xed, 0xd2,
510 ];
511 assert_eq!(&hdr_key, &expected_client_hdr_key);
512
513 // Server.
514 assert!(
515 derive_server_initial_secret(&initial_secret, &mut secret).is_ok()
516 );
517 let expected_server_initial_secret = [
518 0x3c, 0x19, 0x98, 0x28, 0xfd, 0x13, 0x9e, 0xfd, 0x21, 0x6c, 0x15,
519 0x5a, 0xd8, 0x44, 0xcc, 0x81, 0xfb, 0x82, 0xfa, 0x8d, 0x74, 0x46,
520 0xfa, 0x7d, 0x78, 0xbe, 0x80, 0x3a, 0xcd, 0xda, 0x95, 0x1b,
521 ];
522 assert_eq!(&secret, &expected_server_initial_secret);
523
524 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
525 let expected_server_pkt_key = [
526 0xcf, 0x3a, 0x53, 0x31, 0x65, 0x3c, 0x36, 0x4c, 0x88, 0xf0, 0xf3,
527 0x79, 0xb6, 0x06, 0x7e, 0x37,
528 ];
529 assert_eq!(&pkt_key, &expected_server_pkt_key);
530
531 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
532 let expected_server_pkt_iv = [
533 0x0a, 0xc1, 0x49, 0x3c, 0xa1, 0x90, 0x58, 0x53, 0xb0, 0xbb, 0xa0,
534 0x3e,
535 ];
536 assert_eq!(&pkt_iv, &expected_server_pkt_iv);
537
538 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
539 let expected_server_hdr_key = [
540 0xc2, 0x06, 0xb8, 0xd9, 0xb9, 0xf0, 0xf3, 0x76, 0x44, 0x43, 0x0b,
541 0x49, 0x0e, 0xea, 0xa3, 0x14,
542 ];
543 assert_eq!(&hdr_key, &expected_server_hdr_key);
544 }
545
546 #[test]
derive_initial_secrets_draft29()547 fn derive_initial_secrets_draft29() {
548 let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
549
550 let mut secret = [0; 32];
551 let mut pkt_key = [0; 16];
552 let mut pkt_iv = [0; 12];
553 let mut hdr_key = [0; 16];
554
555 let aead = Algorithm::AES128_GCM;
556
557 let initial_secret =
558 derive_initial_secret(&dcid, crate::PROTOCOL_VERSION_DRAFT29);
559
560 // Client.
561 assert!(
562 derive_client_initial_secret(&initial_secret, &mut secret).is_ok()
563 );
564 let expected_client_initial_secret = [
565 0x00, 0x88, 0x11, 0x92, 0x88, 0xf1, 0xd8, 0x66, 0x73, 0x3c, 0xee,
566 0xed, 0x15, 0xff, 0x9d, 0x50, 0x90, 0x2c, 0xf8, 0x29, 0x52, 0xee,
567 0xe2, 0x7e, 0x9d, 0x4d, 0x49, 0x18, 0xea, 0x37, 0x1d, 0x87,
568 ];
569 assert_eq!(&secret, &expected_client_initial_secret);
570
571 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
572 let expected_client_pkt_key = [
573 0x17, 0x52, 0x57, 0xa3, 0x1e, 0xb0, 0x9d, 0xea, 0x93, 0x66, 0xd8,
574 0xbb, 0x79, 0xad, 0x80, 0xba,
575 ];
576 assert_eq!(&pkt_key, &expected_client_pkt_key);
577
578 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
579 let expected_client_pkt_iv = [
580 0x6b, 0x26, 0x11, 0x4b, 0x9c, 0xba, 0x2b, 0x63, 0xa9, 0xe8, 0xdd,
581 0x4f,
582 ];
583 assert_eq!(&pkt_iv, &expected_client_pkt_iv);
584
585 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
586 let expected_client_hdr_key = [
587 0x9d, 0xdd, 0x12, 0xc9, 0x94, 0xc0, 0x69, 0x8b, 0x89, 0x37, 0x4a,
588 0x9c, 0x07, 0x7a, 0x30, 0x77,
589 ];
590 assert_eq!(&hdr_key, &expected_client_hdr_key);
591
592 // Server.
593 assert!(
594 derive_server_initial_secret(&initial_secret, &mut secret).is_ok()
595 );
596 let expected_server_initial_secret = [
597 0x00, 0x6f, 0x88, 0x13, 0x59, 0x24, 0x4d, 0xd9, 0xad, 0x1a, 0xcf,
598 0x85, 0xf5, 0x95, 0xba, 0xd6, 0x7c, 0x13, 0xf9, 0xf5, 0x58, 0x6f,
599 0x5e, 0x64, 0xe1, 0xac, 0xae, 0x1d, 0x9e, 0xa8, 0xf6, 0x16,
600 ];
601 assert_eq!(&secret, &expected_server_initial_secret);
602
603 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
604 let expected_server_pkt_key = [
605 0x14, 0x9d, 0x0b, 0x16, 0x62, 0xab, 0x87, 0x1f, 0xbe, 0x63, 0xc4,
606 0x9b, 0x5e, 0x65, 0x5a, 0x5d,
607 ];
608 assert_eq!(&pkt_key, &expected_server_pkt_key);
609
610 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
611 let expected_server_pkt_iv = [
612 0xba, 0xb2, 0xb1, 0x2a, 0x4c, 0x76, 0x01, 0x6a, 0xce, 0x47, 0x85,
613 0x6d,
614 ];
615 assert_eq!(&pkt_iv, &expected_server_pkt_iv);
616
617 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
618 let expected_server_hdr_key = [
619 0xc0, 0xc4, 0x99, 0xa6, 0x5a, 0x60, 0x02, 0x4a, 0x18, 0xa2, 0x50,
620 0x97, 0x4e, 0xa0, 0x1d, 0xfa,
621 ];
622 assert_eq!(&hdr_key, &expected_server_hdr_key);
623 }
624
625 #[test]
derive_initial_secrets_draft27()626 fn derive_initial_secrets_draft27() {
627 let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
628
629 let mut secret = [0; 32];
630 let mut pkt_key = [0; 16];
631 let mut pkt_iv = [0; 12];
632 let mut hdr_key = [0; 16];
633
634 let aead = Algorithm::AES128_GCM;
635
636 let initial_secret =
637 derive_initial_secret(&dcid, crate::PROTOCOL_VERSION_DRAFT27);
638
639 // Client.
640 assert!(
641 derive_client_initial_secret(&initial_secret, &mut secret).is_ok()
642 );
643 let expected_client_initial_secret = [
644 0xfd, 0xa3, 0x95, 0x3a, 0xec, 0xc0, 0x40, 0xe4, 0x8b, 0x34, 0xe2,
645 0x7e, 0xf8, 0x7d, 0xe3, 0xa6, 0x09, 0x8e, 0xcf, 0x0e, 0x38, 0xb7,
646 0xe0, 0x32, 0xc5, 0xc5, 0x7b, 0xcb, 0xd5, 0x97, 0x5b, 0x84,
647 ];
648 assert_eq!(&secret, &expected_client_initial_secret);
649
650 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
651 let expected_client_pkt_key = [
652 0xaf, 0x7f, 0xd7, 0xef, 0xeb, 0xd2, 0x18, 0x78, 0xff, 0x66, 0x81,
653 0x12, 0x48, 0x98, 0x36, 0x94,
654 ];
655 assert_eq!(&pkt_key, &expected_client_pkt_key);
656
657 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
658 let expected_client_pkt_iv = [
659 0x86, 0x81, 0x35, 0x94, 0x10, 0xa7, 0x0b, 0xb9, 0xc9, 0x2f, 0x04,
660 0x20,
661 ];
662 assert_eq!(&pkt_iv, &expected_client_pkt_iv);
663
664 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
665 let expected_client_hdr_key = [
666 0xa9, 0x80, 0xb8, 0xb4, 0xfb, 0x7d, 0x9f, 0xbc, 0x13, 0xe8, 0x14,
667 0xc2, 0x31, 0x64, 0x25, 0x3d,
668 ];
669 assert_eq!(&hdr_key, &expected_client_hdr_key);
670
671 // Server.
672 assert!(
673 derive_server_initial_secret(&initial_secret, &mut secret).is_ok()
674 );
675 let expected_server_initial_secret = [
676 0x55, 0x43, 0x66, 0xb8, 0x19, 0x12, 0xff, 0x90, 0xbe, 0x41, 0xf1,
677 0x7e, 0x80, 0x22, 0x21, 0x30, 0x90, 0xab, 0x17, 0xd8, 0x14, 0x91,
678 0x79, 0xbc, 0xad, 0xf2, 0x22, 0xf2, 0x9f, 0xf2, 0xdd, 0xd5,
679 ];
680 assert_eq!(&secret, &expected_server_initial_secret);
681
682 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
683 let expected_server_pkt_key = [
684 0x5d, 0x51, 0xda, 0x9e, 0xe8, 0x97, 0xa2, 0x1b, 0x26, 0x59, 0xcc,
685 0xc7, 0xe5, 0xbf, 0xa5, 0x77,
686 ];
687 assert_eq!(&pkt_key, &expected_server_pkt_key);
688
689 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
690 let expected_server_pkt_iv = [
691 0x5e, 0x5a, 0xe6, 0x51, 0xfd, 0x1e, 0x84, 0x95, 0xaf, 0x13, 0x50,
692 0x8b,
693 ];
694 assert_eq!(&pkt_iv, &expected_server_pkt_iv);
695
696 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
697 let expected_server_hdr_key = [
698 0xa8, 0xed, 0x82, 0xe6, 0x66, 0x4f, 0x86, 0x5a, 0xed, 0xf6, 0x10,
699 0x69, 0x43, 0xf9, 0x5f, 0xb8,
700 ];
701 assert_eq!(&hdr_key, &expected_server_hdr_key);
702 }
703
704 #[test]
derive_chacha20_secrets()705 fn derive_chacha20_secrets() {
706 let secret = [
707 0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
708 0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
709 0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
710 ];
711
712 let aead = Algorithm::ChaCha20_Poly1305;
713
714 let mut pkt_key = [0; 32];
715 let mut pkt_iv = [0; 12];
716 let mut hdr_key = [0; 32];
717
718 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
719 let expected_pkt_key = [
720 0xc6, 0xd9, 0x8f, 0xf3, 0x44, 0x1c, 0x3f, 0xe1, 0xb2, 0x18, 0x20,
721 0x94, 0xf6, 0x9c, 0xaa, 0x2e, 0xd4, 0xb7, 0x16, 0xb6, 0x54, 0x88,
722 0x96, 0x0a, 0x7a, 0x98, 0x49, 0x79, 0xfb, 0x23, 0xe1, 0xc8,
723 ];
724 assert_eq!(&pkt_key, &expected_pkt_key);
725
726 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
727 let expected_pkt_iv = [
728 0xe0, 0x45, 0x9b, 0x34, 0x74, 0xbd, 0xd0, 0xe4, 0x4a, 0x41, 0xc1,
729 0x44,
730 ];
731 assert_eq!(&pkt_iv, &expected_pkt_iv);
732
733 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
734 let expected_hdr_key = [
735 0x25, 0xa2, 0x82, 0xb9, 0xe8, 0x2f, 0x06, 0xf2, 0x1f, 0x48, 0x89,
736 0x17, 0xa4, 0xfc, 0x8f, 0x1b, 0x73, 0x57, 0x36, 0x85, 0x60, 0x85,
737 0x97, 0xd0, 0xef, 0xcb, 0x07, 0x6b, 0x0a, 0xb7, 0xa7, 0xa4,
738 ];
739 assert_eq!(&hdr_key, &expected_hdr_key);
740 }
741 }
742