• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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