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) -> Result<hkdf::Prk>337 fn derive_initial_secret(secret: &[u8], version: u32) -> Result<hkdf::Prk> {
338 const INITIAL_SALT: [u8; 20] = [
339 0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1,
340 0x9c, 0x61, 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99,
341 ];
342
343 const INITIAL_SALT_OLD: [u8; 20] = [
344 0xc3, 0xee, 0xf7, 0x12, 0xc7, 0x2e, 0xbb, 0x5a, 0x11, 0xa7, 0xd2, 0x43,
345 0x2b, 0xb4, 0x63, 0x65, 0xbe, 0xf9, 0xf5, 0x02,
346 ];
347
348 let salt = match version {
349 crate::PROTOCOL_VERSION_DRAFT27 | crate::PROTOCOL_VERSION_DRAFT28 =>
350 &INITIAL_SALT_OLD,
351
352 _ => &INITIAL_SALT,
353 };
354
355 let salt = hkdf::Salt::new(hkdf::HKDF_SHA256, salt);
356 Ok(salt.extract(secret))
357 }
358
derive_client_initial_secret(prk: &hkdf::Prk, out: &mut [u8]) -> Result<()>359 fn derive_client_initial_secret(prk: &hkdf::Prk, out: &mut [u8]) -> Result<()> {
360 const LABEL: &[u8] = b"client in";
361 hkdf_expand_label(prk, LABEL, out)
362 }
363
derive_server_initial_secret(prk: &hkdf::Prk, out: &mut [u8]) -> Result<()>364 fn derive_server_initial_secret(prk: &hkdf::Prk, out: &mut [u8]) -> Result<()> {
365 const LABEL: &[u8] = b"server in";
366 hkdf_expand_label(prk, LABEL, out)
367 }
368
derive_hdr_key( aead: Algorithm, secret: &[u8], out: &mut [u8], ) -> Result<()>369 pub fn derive_hdr_key(
370 aead: Algorithm, secret: &[u8], out: &mut [u8],
371 ) -> Result<()> {
372 const LABEL: &[u8] = b"quic hp";
373
374 let key_len = aead.key_len();
375
376 if key_len > out.len() {
377 return Err(Error::CryptoFail);
378 }
379
380 let secret = hkdf::Prk::new_less_safe(aead.get_ring_digest(), secret);
381 hkdf_expand_label(&secret, LABEL, &mut out[..key_len])
382 }
383
derive_pkt_key( aead: Algorithm, secret: &[u8], out: &mut [u8], ) -> Result<()>384 pub fn derive_pkt_key(
385 aead: Algorithm, secret: &[u8], out: &mut [u8],
386 ) -> Result<()> {
387 const LABEL: &[u8] = b"quic key";
388
389 let key_len = aead.key_len();
390
391 if key_len > out.len() {
392 return Err(Error::CryptoFail);
393 }
394
395 let secret = hkdf::Prk::new_less_safe(aead.get_ring_digest(), secret);
396 hkdf_expand_label(&secret, LABEL, &mut out[..key_len])
397 }
398
derive_pkt_iv( aead: Algorithm, secret: &[u8], out: &mut [u8], ) -> Result<()>399 pub fn derive_pkt_iv(
400 aead: Algorithm, secret: &[u8], out: &mut [u8],
401 ) -> Result<()> {
402 const LABEL: &[u8] = b"quic iv";
403
404 let nonce_len = aead.nonce_len();
405
406 if nonce_len > out.len() {
407 return Err(Error::CryptoFail);
408 }
409
410 let secret = hkdf::Prk::new_less_safe(aead.get_ring_digest(), secret);
411 hkdf_expand_label(&secret, LABEL, &mut out[..nonce_len])
412 }
413
hkdf_expand_label( prk: &hkdf::Prk, label: &[u8], out: &mut [u8], ) -> Result<()>414 fn hkdf_expand_label(
415 prk: &hkdf::Prk, label: &[u8], out: &mut [u8],
416 ) -> Result<()> {
417 const LABEL_PREFIX: &[u8] = b"tls13 ";
418
419 let out_len = (out.len() as u16).to_be_bytes();
420 let label_len = (LABEL_PREFIX.len() + label.len()) as u8;
421
422 let info = [&out_len, &[label_len][..], LABEL_PREFIX, label, &[0][..]];
423
424 prk.expand(&info, ArbitraryOutputLen(out.len()))
425 .map_err(|_| Error::CryptoFail)?
426 .fill(out)
427 .map_err(|_| Error::CryptoFail)?;
428
429 Ok(())
430 }
431
make_nonce(iv: &[u8], counter: u64) -> aead::Nonce432 fn make_nonce(iv: &[u8], counter: u64) -> aead::Nonce {
433 let mut nonce = [0; aead::NONCE_LEN];
434 nonce.copy_from_slice(&iv);
435
436 // XOR the last bytes of the IV with the counter. This is equivalent to
437 // left-padding the counter with zero bytes.
438 for (a, b) in nonce[4..].iter_mut().zip(counter.to_be_bytes().iter()) {
439 *a ^= b;
440 }
441
442 aead::Nonce::assume_unique_for_key(nonce)
443 }
444
445 // The ring HKDF expand() API does not accept an arbitrary output length, so we
446 // need to hide the `usize` length as part of a type that implements the trait
447 // `ring::hkdf::KeyType` in order to trick ring into accepting it.
448 struct ArbitraryOutputLen(usize);
449
450 impl hkdf::KeyType for ArbitraryOutputLen {
len(&self) -> usize451 fn len(&self) -> usize {
452 self.0
453 }
454 }
455
456 #[cfg(test)]
457 mod tests {
458 use super::*;
459
460 #[test]
derive_initial_secrets()461 fn derive_initial_secrets() {
462 let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
463
464 let mut secret = [0; 32];
465 let mut pkt_key = [0; 16];
466 let mut pkt_iv = [0; 12];
467 let mut hdr_key = [0; 16];
468
469 let aead = Algorithm::AES128_GCM;
470
471 let initial_secret =
472 derive_initial_secret(&dcid, crate::PROTOCOL_VERSION).unwrap();
473
474 // Client.
475 assert!(
476 derive_client_initial_secret(&initial_secret, &mut secret).is_ok()
477 );
478 let expected_client_initial_secret = [
479 0x00, 0x88, 0x11, 0x92, 0x88, 0xf1, 0xd8, 0x66, 0x73, 0x3c, 0xee,
480 0xed, 0x15, 0xff, 0x9d, 0x50, 0x90, 0x2c, 0xf8, 0x29, 0x52, 0xee,
481 0xe2, 0x7e, 0x9d, 0x4d, 0x49, 0x18, 0xea, 0x37, 0x1d, 0x87,
482 ];
483 assert_eq!(&secret, &expected_client_initial_secret);
484
485 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
486 let expected_client_pkt_key = [
487 0x17, 0x52, 0x57, 0xa3, 0x1e, 0xb0, 0x9d, 0xea, 0x93, 0x66, 0xd8,
488 0xbb, 0x79, 0xad, 0x80, 0xba,
489 ];
490 assert_eq!(&pkt_key, &expected_client_pkt_key);
491
492 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
493 let expected_client_pkt_iv = [
494 0x6b, 0x26, 0x11, 0x4b, 0x9c, 0xba, 0x2b, 0x63, 0xa9, 0xe8, 0xdd,
495 0x4f,
496 ];
497 assert_eq!(&pkt_iv, &expected_client_pkt_iv);
498
499 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
500 let expected_client_hdr_key = [
501 0x9d, 0xdd, 0x12, 0xc9, 0x94, 0xc0, 0x69, 0x8b, 0x89, 0x37, 0x4a,
502 0x9c, 0x07, 0x7a, 0x30, 0x77,
503 ];
504 assert_eq!(&hdr_key, &expected_client_hdr_key);
505
506 // Server.
507 assert!(
508 derive_server_initial_secret(&initial_secret, &mut secret).is_ok()
509 );
510 let expected_server_initial_secret = [
511 0x00, 0x6f, 0x88, 0x13, 0x59, 0x24, 0x4d, 0xd9, 0xad, 0x1a, 0xcf,
512 0x85, 0xf5, 0x95, 0xba, 0xd6, 0x7c, 0x13, 0xf9, 0xf5, 0x58, 0x6f,
513 0x5e, 0x64, 0xe1, 0xac, 0xae, 0x1d, 0x9e, 0xa8, 0xf6, 0x16,
514 ];
515 assert_eq!(&secret, &expected_server_initial_secret);
516
517 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
518 let expected_server_pkt_key = [
519 0x14, 0x9d, 0x0b, 0x16, 0x62, 0xab, 0x87, 0x1f, 0xbe, 0x63, 0xc4,
520 0x9b, 0x5e, 0x65, 0x5a, 0x5d,
521 ];
522 assert_eq!(&pkt_key, &expected_server_pkt_key);
523
524 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
525 let expected_server_pkt_iv = [
526 0xba, 0xb2, 0xb1, 0x2a, 0x4c, 0x76, 0x01, 0x6a, 0xce, 0x47, 0x85,
527 0x6d,
528 ];
529 assert_eq!(&pkt_iv, &expected_server_pkt_iv);
530
531 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
532 let expected_server_hdr_key = [
533 0xc0, 0xc4, 0x99, 0xa6, 0x5a, 0x60, 0x02, 0x4a, 0x18, 0xa2, 0x50,
534 0x97, 0x4e, 0xa0, 0x1d, 0xfa,
535 ];
536 assert_eq!(&hdr_key, &expected_server_hdr_key);
537 }
538
539 #[test]
derive_initial_secrets_old()540 fn derive_initial_secrets_old() {
541 let dcid = [0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08];
542
543 let mut secret = [0; 32];
544 let mut pkt_key = [0; 16];
545 let mut pkt_iv = [0; 12];
546 let mut hdr_key = [0; 16];
547
548 let aead = Algorithm::AES128_GCM;
549
550 let initial_secret =
551 derive_initial_secret(&dcid, crate::PROTOCOL_VERSION_DRAFT28)
552 .unwrap();
553
554 // Client.
555 assert!(
556 derive_client_initial_secret(&initial_secret, &mut secret).is_ok()
557 );
558 let expected_client_initial_secret = [
559 0xfd, 0xa3, 0x95, 0x3a, 0xec, 0xc0, 0x40, 0xe4, 0x8b, 0x34, 0xe2,
560 0x7e, 0xf8, 0x7d, 0xe3, 0xa6, 0x09, 0x8e, 0xcf, 0x0e, 0x38, 0xb7,
561 0xe0, 0x32, 0xc5, 0xc5, 0x7b, 0xcb, 0xd5, 0x97, 0x5b, 0x84,
562 ];
563 assert_eq!(&secret, &expected_client_initial_secret);
564
565 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
566 let expected_client_pkt_key = [
567 0xaf, 0x7f, 0xd7, 0xef, 0xeb, 0xd2, 0x18, 0x78, 0xff, 0x66, 0x81,
568 0x12, 0x48, 0x98, 0x36, 0x94,
569 ];
570 assert_eq!(&pkt_key, &expected_client_pkt_key);
571
572 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
573 let expected_client_pkt_iv = [
574 0x86, 0x81, 0x35, 0x94, 0x10, 0xa7, 0x0b, 0xb9, 0xc9, 0x2f, 0x04,
575 0x20,
576 ];
577 assert_eq!(&pkt_iv, &expected_client_pkt_iv);
578
579 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
580 let expected_client_hdr_key = [
581 0xa9, 0x80, 0xb8, 0xb4, 0xfb, 0x7d, 0x9f, 0xbc, 0x13, 0xe8, 0x14,
582 0xc2, 0x31, 0x64, 0x25, 0x3d,
583 ];
584 assert_eq!(&hdr_key, &expected_client_hdr_key);
585
586 // Server.
587 assert!(
588 derive_server_initial_secret(&initial_secret, &mut secret).is_ok()
589 );
590 let expected_server_initial_secret = [
591 0x55, 0x43, 0x66, 0xb8, 0x19, 0x12, 0xff, 0x90, 0xbe, 0x41, 0xf1,
592 0x7e, 0x80, 0x22, 0x21, 0x30, 0x90, 0xab, 0x17, 0xd8, 0x14, 0x91,
593 0x79, 0xbc, 0xad, 0xf2, 0x22, 0xf2, 0x9f, 0xf2, 0xdd, 0xd5,
594 ];
595 assert_eq!(&secret, &expected_server_initial_secret);
596
597 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
598 let expected_server_pkt_key = [
599 0x5d, 0x51, 0xda, 0x9e, 0xe8, 0x97, 0xa2, 0x1b, 0x26, 0x59, 0xcc,
600 0xc7, 0xe5, 0xbf, 0xa5, 0x77,
601 ];
602 assert_eq!(&pkt_key, &expected_server_pkt_key);
603
604 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
605 let expected_server_pkt_iv = [
606 0x5e, 0x5a, 0xe6, 0x51, 0xfd, 0x1e, 0x84, 0x95, 0xaf, 0x13, 0x50,
607 0x8b,
608 ];
609 assert_eq!(&pkt_iv, &expected_server_pkt_iv);
610
611 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
612 let expected_server_hdr_key = [
613 0xa8, 0xed, 0x82, 0xe6, 0x66, 0x4f, 0x86, 0x5a, 0xed, 0xf6, 0x10,
614 0x69, 0x43, 0xf9, 0x5f, 0xb8,
615 ];
616 assert_eq!(&hdr_key, &expected_server_hdr_key);
617 }
618
619 #[test]
derive_chacha20_secrets()620 fn derive_chacha20_secrets() {
621 let secret = [
622 0x9a, 0xc3, 0x12, 0xa7, 0xf8, 0x77, 0x46, 0x8e, 0xbe, 0x69, 0x42,
623 0x27, 0x48, 0xad, 0x00, 0xa1, 0x54, 0x43, 0xf1, 0x82, 0x03, 0xa0,
624 0x7d, 0x60, 0x60, 0xf6, 0x88, 0xf3, 0x0f, 0x21, 0x63, 0x2b,
625 ];
626
627 let aead = Algorithm::ChaCha20_Poly1305;
628
629 let mut pkt_key = [0; 32];
630 let mut pkt_iv = [0; 12];
631 let mut hdr_key = [0; 32];
632
633 assert!(derive_pkt_key(aead, &secret, &mut pkt_key).is_ok());
634 let expected_pkt_key = [
635 0xc6, 0xd9, 0x8f, 0xf3, 0x44, 0x1c, 0x3f, 0xe1, 0xb2, 0x18, 0x20,
636 0x94, 0xf6, 0x9c, 0xaa, 0x2e, 0xd4, 0xb7, 0x16, 0xb6, 0x54, 0x88,
637 0x96, 0x0a, 0x7a, 0x98, 0x49, 0x79, 0xfb, 0x23, 0xe1, 0xc8,
638 ];
639 assert_eq!(&pkt_key, &expected_pkt_key);
640
641 assert!(derive_pkt_iv(aead, &secret, &mut pkt_iv).is_ok());
642 let expected_pkt_iv = [
643 0xe0, 0x45, 0x9b, 0x34, 0x74, 0xbd, 0xd0, 0xe4, 0x4a, 0x41, 0xc1,
644 0x44,
645 ];
646 assert_eq!(&pkt_iv, &expected_pkt_iv);
647
648 assert!(derive_hdr_key(aead, &secret, &mut hdr_key).is_ok());
649 let expected_hdr_key = [
650 0x25, 0xa2, 0x82, 0xb9, 0xe8, 0x2f, 0x06, 0xf2, 0x1f, 0x48, 0x89,
651 0x17, 0xa4, 0xfc, 0x8f, 0x1b, 0x73, 0x57, 0x36, 0x85, 0x60, 0x85,
652 0x97, 0xd0, 0xef, 0xcb, 0x07, 0x6b, 0x0a, 0xb7, 0xa7, 0xa4,
653 ];
654 assert_eq!(&hdr_key, &expected_hdr_key);
655 }
656 }
657