1
//! Implements the ntor v3 key exchange, as described in proposal 332.
2
//!
3
//! The main difference between the ntor v3r handshake and the
4
//! original ntor handshake is that this this one allows each party to
5
//! encrypt data (without forward secrecy) after it sends the first
6
//! message.
7

            
8
// TODO:
9
//    Remove the "allow" item for dead_code.
10
//    Make terminology and variable names consistent with spec.
11

            
12
// This module is still unused: so allow some dead code for now.
13
#![allow(dead_code)]
14

            
15
use std::borrow::Borrow;
16

            
17
use super::{RelayHandshakeError, RelayHandshakeResult};
18
use crate::util::ct;
19
use crate::{Error, Result};
20
use tor_bytes::{EncodeResult, Reader, SecretBuf, Writeable, Writer};
21
use tor_error::into_internal;
22
use tor_llcrypto::d::{Sha3_256, Shake256, Shake256Reader};
23
use tor_llcrypto::pk::{curve25519, ed25519::Ed25519Identity};
24
use tor_llcrypto::util::ct::ct_lookup;
25

            
26
use cipher::{KeyIvInit, StreamCipher};
27

            
28
use crate::crypto::handshake::KeyGenerator;
29
use rand_core::{CryptoRng, RngCore};
30
use subtle::{Choice, ConstantTimeEq};
31
use tor_cell::relaycell::extend::{CircRequestExt, CircResponseExt};
32
use tor_llcrypto::cipher::aes::Aes256Ctr;
33
use zeroize::Zeroizing;
34

            
35
/// The verification string to be used for circuit extension.
36
const NTOR3_CIRC_VERIFICATION: &[u8] = b"circuit extend";
37

            
38
/// The size of an encryption key in bytes.
39
const ENC_KEY_LEN: usize = 32;
40
/// The size of a MAC key in bytes.
41
const MAC_KEY_LEN: usize = 32;
42
/// The size of a curve25519 public key in bytes.
43
const PUB_KEY_LEN: usize = 32;
44
/// The size of a digest output in bytes.
45
const DIGEST_LEN: usize = 32;
46
/// The length of a MAC output in bytes.
47
const MAC_LEN: usize = 32;
48
/// The length of a node identity in bytes.
49
const ID_LEN: usize = 32;
50

            
51
/// The output of the digest, as an array.
52
type DigestVal = [u8; DIGEST_LEN];
53
/// The output of the MAC.
54
type MacVal = [u8; MAC_LEN];
55
/// A key for symmetric encryption or decryption.
56
//
57
// TODO (nickm): Any move operations applied to this key could subvert the zeroizing.
58
type EncKey = Zeroizing<[u8; ENC_KEY_LEN]>;
59
/// A key for message authentication codes.
60
type MacKey = [u8; MAC_KEY_LEN];
61

            
62
/// Opaque wrapper type for NtorV3's hash reader.
63
struct NtorV3XofReader(Shake256Reader);
64

            
65
impl digest::XofReader for NtorV3XofReader {
66
52
    fn read(&mut self, buffer: &mut [u8]) {
67
52
        self.0.read(buffer);
68
52
    }
69
}
70

            
71
/// An encapsulated value for passing as input to a MAC, digest, or
72
/// KDF algorithm.
73
///
74
/// This corresponds to the ENCAP() function in proposal 332.
75
struct Encap<'a>(&'a [u8]);
76

            
77
impl<'a> Writeable for Encap<'a> {
78
704
    fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
79
704
        b.write_u64(self.0.len() as u64);
80
704
        b.write(self.0)
81
704
    }
82
}
83

            
84
impl<'a> Encap<'a> {
85
    /// Return the length of the underlying data in bytes.
86
176
    fn len(&self) -> usize {
87
176
        self.0.len()
88
176
    }
89
    /// Return the underlying data
90
176
    fn data(&self) -> &'a [u8] {
91
176
        self.0
92
176
    }
93
}
94

            
95
/// Helper to define a set of tweak values as instances of `Encap`.
96
macro_rules! define_tweaks {
97
    {
98
        $(#[$pid_meta:meta])*
99
        PROTOID = $protoid:expr;
100
        $( $(#[$meta:meta])* $name:ident <= $suffix:expr ; )*
101
    } => {
102
        $(#[$pid_meta])*
103
        const PROTOID: &'static [u8] = $protoid.as_bytes();
104
        $(
105
            $(#[$meta])*
106
            const $name : Encap<'static> =
107
                Encap(concat!($protoid, ":", $suffix).as_bytes());
108
        )*
109
    }
110
}
111

            
112
define_tweaks! {
113
    /// Protocol ID: concatenated with other things in the protocol to
114
    /// prevent hash confusion.
115
    PROTOID =  "ntor3-curve25519-sha3_256-1";
116

            
117
    /// Message MAC tweak: used to compute the MAC of an encrypted client
118
    /// message.
119
    T_MSGMAC <= "msg_mac";
120
    /// Message KDF tweak: used when deriving keys for encrypting and MACing
121
    /// client message.
122
    T_MSGKDF <= "kdf_phase1";
123
    /// Key seeding tweak: used to derive final KDF input from secret_input.
124
    T_KEY_SEED <= "key_seed";
125
    /// Verifying tweak: used to derive 'verify' value from secret_input.
126
    T_VERIFY <= "verify";
127
    /// Final KDF tweak: used to derive keys for encrypting relay message
128
    /// and for the actual tor circuit.
129
    T_FINAL <= "kdf_final";
130
    /// Authentication tweak: used to derive the final authentication
131
    /// value for the handshake.
132
    T_AUTH <= "auth_final";
133
}
134

            
135
/// Compute a tweaked hash.
136
176
fn hash(t: &Encap<'_>, data: &[u8]) -> DigestVal {
137
    use digest::Digest;
138
176
    let mut d = Sha3_256::new();
139
176
    d.update((t.len() as u64).to_be_bytes());
140
176
    d.update(t.data());
141
176
    d.update(data);
142
176
    d.finalize().into()
143
176
}
144

            
145
/// Perform a symmetric encryption operation and return the encrypted data.
146
///
147
/// (This isn't safe to do more than once with the same key, but we never
148
/// do that in this protocol.)
149
176
fn encrypt(key: &EncKey, m: &[u8]) -> Vec<u8> {
150
176
    let mut d = m.to_vec();
151
176
    let zero_iv = Default::default();
152
176
    let mut cipher = Aes256Ctr::new(key.as_ref().into(), &zero_iv);
153
176
    cipher.apply_keystream(&mut d);
154
176
    d
155
176
}
156
/// Perform a symmetric decryption operation and return the encrypted data.
157
88
fn decrypt(key: &EncKey, m: &[u8]) -> Vec<u8> {
158
88
    encrypt(key, m)
159
88
}
160

            
161
/// Wrapper around a Digest or ExtendedOutput object that lets us use it
162
/// as a tor_bytes::Writer.
163
struct DigestWriter<U>(U);
164
impl<U: digest::Update> tor_bytes::Writer for DigestWriter<U> {
165
2816
    fn write_all(&mut self, bytes: &[u8]) {
166
2816
        self.0.update(bytes);
167
2816
    }
168
}
169
impl<U> DigestWriter<U> {
170
    /// Consume this wrapper and return the underlying object.
171
352
    fn take(self) -> U {
172
352
        self.0
173
352
    }
174
}
175

            
176
/// Hash tweaked with T_KEY_SEED
177
88
fn h_key_seed(d: &[u8]) -> DigestVal {
178
88
    hash(&T_KEY_SEED, d)
179
88
}
180
/// Hash tweaked with T_VERIFY
181
88
fn h_verify(d: &[u8]) -> DigestVal {
182
88
    hash(&T_VERIFY, d)
183
88
}
184

            
185
/// Helper: compute the encryption key and mac_key for the client's
186
/// encrypted message.
187
///
188
/// Takes as inputs `xb` (the shared secret derived from
189
/// diffie-hellman as Bx or Xb), the relay's public key information,
190
/// the client's public key (B), and the shared verification string.
191
88
fn kdf_msgkdf(
192
88
    xb: &curve25519::SharedSecret,
193
88
    relay_public: &NtorV3PublicKey,
194
88
    client_public: &curve25519::PublicKey,
195
88
    verification: &[u8],
196
88
) -> EncodeResult<(EncKey, DigestWriter<Sha3_256>)> {
197
    // secret_input_phase1 = Bx | ID | X | B | PROTOID | ENCAP(VER)
198
    // phase1_keys = KDF_msgkdf(secret_input_phase1)
199
    // (ENC_K1, MAC_K1) = PARTITION(phase1_keys, ENC_KEY_LEN, MAC_KEY_LEN
200
    use digest::{ExtendableOutput, XofReader};
201
88
    let mut msg_kdf = DigestWriter(Shake256::default());
202
88
    msg_kdf.write(&T_MSGKDF)?;
203
88
    msg_kdf.write(xb)?;
204
88
    msg_kdf.write(&relay_public.id)?;
205
88
    msg_kdf.write(client_public)?;
206
88
    msg_kdf.write(&relay_public.pk)?;
207
88
    msg_kdf.write(PROTOID)?;
208
88
    msg_kdf.write(&Encap(verification))?;
209
88
    let mut r = msg_kdf.take().finalize_xof();
210
88
    let mut enc_key = Zeroizing::new([0; ENC_KEY_LEN]);
211
88
    let mut mac_key = Zeroizing::new([0; MAC_KEY_LEN]);
212

            
213
88
    r.read(&mut enc_key[..]);
214
88
    r.read(&mut mac_key[..]);
215
88
    let mut mac = DigestWriter(Sha3_256::default());
216
    {
217
88
        mac.write(&T_MSGMAC)?;
218
88
        mac.write(&Encap(&mac_key[..]))?;
219
88
        mac.write(&relay_public.id)?;
220
88
        mac.write(&relay_public.pk)?;
221
88
        mac.write(client_public)?;
222
    }
223

            
224
88
    Ok((enc_key, mac))
225
88
}
226

            
227
/// Client side of the ntor v3 handshake.
228
pub(crate) struct NtorV3Client;
229

            
230
impl super::ClientHandshake for NtorV3Client {
231
    type KeyType = NtorV3PublicKey;
232
    type StateType = NtorV3HandshakeState;
233
    type KeyGen = NtorV3KeyGenerator;
234
    type ClientAuxData = [CircRequestExt];
235
    type ServerAuxData = Vec<CircResponseExt>;
236

            
237
    /// Generate a new client onionskin for a relay with a given onion key.
238
    /// If any `extensions` are provided, encode them into to the onionskin.
239
    ///
240
    /// On success, return a state object that will be used to complete the handshake, along
241
    /// with the message to send.
242
40
    fn client1<R: RngCore + CryptoRng, M: Borrow<[CircRequestExt]>>(
243
40
        rng: &mut R,
244
40
        key: &NtorV3PublicKey,
245
40
        extensions: &M,
246
40
    ) -> Result<(Self::StateType, Vec<u8>)> {
247
40
        let mut message = Vec::new();
248
40
        CircRequestExt::write_many_onto(extensions.borrow(), &mut message)
249
40
            .map_err(|e| Error::from_bytes_enc(e, "ntor3 handshake extensions"))?;
250
        Ok(
251
40
            client_handshake_ntor_v3(rng, key, &message, NTOR3_CIRC_VERIFICATION)
252
40
                .map_err(into_internal!("Can't encode ntor3 client handshake."))?,
253
        )
254
40
    }
255

            
256
    /// Handle an onionskin from a relay, and produce a key generator.
257
    ///
258
    /// The state object must match the one that was used to make the
259
    /// client onionskin that the server is replying to.
260
40
    fn client2<T: AsRef<[u8]>>(
261
40
        state: Self::StateType,
262
40
        msg: T,
263
40
    ) -> Result<(Vec<CircResponseExt>, Self::KeyGen)> {
264
40
        let (message, xofreader) =
265
40
            client_handshake_ntor_v3_part2(&state, msg.as_ref(), NTOR3_CIRC_VERIFICATION)?;
266
40
        let extensions = CircResponseExt::decode(&message).map_err(|err| Error::CellDecodeErr {
267
            object: "ntor v3 extensions",
268
            err,
269
        })?;
270
40
        let keygen = NtorV3KeyGenerator { reader: xofreader };
271

            
272
40
        Ok((extensions, keygen))
273
40
    }
274
}
275

            
276
/// Server side of the ntor v3 handshake.
277
pub(crate) struct NtorV3Server;
278

            
279
impl super::ServerHandshake for NtorV3Server {
280
    type KeyType = NtorV3SecretKey;
281
    type KeyGen = NtorV3KeyGenerator;
282
    type ClientAuxData = [CircRequestExt];
283
    type ServerAuxData = Vec<CircResponseExt>;
284

            
285
40
    fn server<R: RngCore + CryptoRng, REPLY: super::AuxDataReply<Self>, T: AsRef<[u8]>>(
286
40
        rng: &mut R,
287
40
        reply_fn: &mut REPLY,
288
40
        key: &[Self::KeyType],
289
40
        msg: T,
290
40
    ) -> RelayHandshakeResult<(Self::KeyGen, Vec<u8>)> {
291
40
        let mut bytes_reply_fn = |bytes: &[u8]| -> Option<Vec<u8>> {
292
40
            let client_exts = CircRequestExt::decode(bytes).ok()?;
293
40
            let reply_exts = reply_fn.reply(&client_exts)?;
294
40
            let mut out = vec![];
295
40
            CircResponseExt::write_many_onto(&reply_exts, &mut out).ok()?;
296
40
            Some(out)
297
40
        };
298

            
299
40
        let (res, reader) = server_handshake_ntor_v3(
300
40
            rng,
301
40
            &mut bytes_reply_fn,
302
40
            msg.as_ref(),
303
40
            key,
304
40
            NTOR3_CIRC_VERIFICATION,
305
        )?;
306
40
        Ok((NtorV3KeyGenerator { reader }, res))
307
40
    }
308
}
309

            
310
/// Key information about a relay used for the ntor v3 handshake.
311
///
312
/// Contains a single curve25519 ntor onion key, and the relay's ed25519
313
/// identity.
314
#[derive(Clone, Debug)]
315
pub(crate) struct NtorV3PublicKey {
316
    /// The relay's identity.
317
    pub(crate) id: Ed25519Identity,
318
    /// The relay's onion key.
319
    pub(crate) pk: curve25519::PublicKey,
320
}
321

            
322
/// Secret key information used by a relay for the ntor v3 handshake.
323
pub(crate) struct NtorV3SecretKey {
324
    /// The relay's public key information
325
    pk: NtorV3PublicKey,
326
    /// The secret onion key.
327
    sk: curve25519::StaticSecret,
328
}
329

            
330
impl NtorV3SecretKey {
331
    /// Construct a new NtorV3SecretKey from its components.
332
    #[allow(unused)]
333
36
    pub(crate) fn new(
334
36
        sk: curve25519::StaticSecret,
335
36
        pk: curve25519::PublicKey,
336
36
        id: Ed25519Identity,
337
36
    ) -> Self {
338
36
        Self {
339
36
            pk: NtorV3PublicKey { id, pk },
340
36
            sk,
341
36
        }
342
36
    }
343

            
344
    /// Generate a key using the given `rng`, suitable for testing.
345
    #[cfg(test)]
346
6
    pub(crate) fn generate_for_test<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
347
6
        let mut id = [0_u8; 32];
348
        // Random bytes will work for testing, but aren't necessarily actually a valid id.
349
6
        rng.fill_bytes(&mut id);
350

            
351
6
        let sk = curve25519::StaticSecret::random_from_rng(rng);
352

            
353
6
        let pk = NtorV3PublicKey {
354
6
            pk: (&sk).into(),
355
6
            id: id.into(),
356
6
        };
357
6
        Self { pk, sk }
358
6
    }
359

            
360
    /// Checks whether `id` and `pk` match this secret key.
361
    ///
362
    /// Used to perform a constant-time secret key lookup.
363
44
    fn matches(&self, id: Ed25519Identity, pk: curve25519::PublicKey) -> Choice {
364
        // TODO: use similar pattern in ntor_v1!
365
44
        id.as_bytes().ct_eq(self.pk.id.as_bytes()) & pk.as_bytes().ct_eq(self.pk.pk.as_bytes())
366
44
    }
367
}
368

            
369
/// Client state for the ntor v3 handshake.
370
///
371
/// The client needs to hold this state between when it sends its part
372
/// of the handshake and when it receives the relay's reply.
373
pub(crate) struct NtorV3HandshakeState {
374
    /// The public key of the relay we're communicating with.
375
    relay_public: NtorV3PublicKey, // B, ID.
376
    /// Our ephemeral secret key for this handshake.
377
    my_sk: curve25519::StaticSecret, // x
378
    /// Our ephemeral public key for this handshake.
379
    my_public: curve25519::PublicKey, // X
380

            
381
    /// The shared secret generated as Bx or Xb.
382
    shared_secret: curve25519::SharedSecret, // Bx
383
    /// The MAC of our original encrypted message.
384
    msg_mac: MacVal, // msg_mac
385
}
386

            
387
/// A key generator returned from an ntor v3 handshake.
388
pub(crate) struct NtorV3KeyGenerator {
389
    /// The underlying `digest::XofReader`.
390
    reader: NtorV3XofReader,
391
}
392

            
393
impl KeyGenerator for NtorV3KeyGenerator {
394
44
    fn expand(mut self, keylen: usize) -> Result<SecretBuf> {
395
        use digest::XofReader;
396
44
        let mut ret: SecretBuf = vec![0; keylen].into();
397
44
        self.reader.read(ret.as_mut());
398
44
        Ok(ret)
399
44
    }
400
}
401

            
402
/// Client-side Ntor version 3 handshake, part one.
403
///
404
/// Given a secure `rng`, a relay's public key, a secret message to send,
405
/// and a shared verification string, generate a new handshake state
406
/// and a message to send to the relay.
407
42
fn client_handshake_ntor_v3<R: RngCore + CryptoRng>(
408
42
    rng: &mut R,
409
42
    relay_public: &NtorV3PublicKey,
410
42
    client_msg: &[u8],
411
42
    verification: &[u8],
412
42
) -> EncodeResult<(NtorV3HandshakeState, Vec<u8>)> {
413
42
    let my_sk = curve25519::StaticSecret::random_from_rng(rng);
414
42
    client_handshake_ntor_v3_no_keygen(relay_public, client_msg, verification, my_sk)
415
42
}
416

            
417
/// As `client_handshake_ntor_v3`, but don't generate an ephemeral DH
418
/// key: instead take that key an arguments `my_sk`.
419
44
fn client_handshake_ntor_v3_no_keygen(
420
44
    relay_public: &NtorV3PublicKey,
421
44
    client_msg: &[u8],
422
44
    verification: &[u8],
423
44
    my_sk: curve25519::StaticSecret,
424
44
) -> EncodeResult<(NtorV3HandshakeState, Vec<u8>)> {
425
44
    let my_public = curve25519::PublicKey::from(&my_sk);
426
44
    let bx = my_sk.diffie_hellman(&relay_public.pk);
427

            
428
44
    let (enc_key, mut mac) = kdf_msgkdf(&bx, relay_public, &my_public, verification)?;
429

            
430
    //encrypted_msg = ENC(ENC_K1, CM)
431
    // msg_mac = MAC_msgmac(MAC_K1, ID | B | X | encrypted_msg)
432
44
    let encrypted_msg = encrypt(&enc_key, client_msg);
433
44
    let msg_mac: DigestVal = {
434
        use digest::Digest;
435
44
        mac.write(&encrypted_msg)?;
436
44
        mac.take().finalize().into()
437
    };
438

            
439
44
    let mut message = Vec::new();
440
44
    message.write(&relay_public.id)?;
441
44
    message.write(&relay_public.pk)?;
442
44
    message.write(&my_public)?;
443
44
    message.write(&encrypted_msg)?;
444
44
    message.write(&msg_mac)?;
445

            
446
44
    let state = NtorV3HandshakeState {
447
44
        relay_public: relay_public.clone(),
448
44
        my_sk,
449
44
        my_public,
450
44
        shared_secret: bx,
451
44
        msg_mac,
452
44
    };
453

            
454
44
    Ok((state, message))
455
44
}
456

            
457
/// Trait for an object that handle and incoming client message and
458
/// return a server's reply.
459
///
460
/// This is implemented for `FnMut(&[u8]) -> Option<Vec<u8>>` automatically.
461
pub(crate) trait MsgReply {
462
    /// Given a message received from a client, parse it and decide
463
    /// how (and whether) to reply.
464
    ///
465
    /// Return None if the handshake should fail.
466
    fn reply(&mut self, msg: &[u8]) -> Option<Vec<u8>>;
467
}
468

            
469
impl<F> MsgReply for F
470
where
471
    F: FnMut(&[u8]) -> Option<Vec<u8>>,
472
{
473
40
    fn reply(&mut self, msg: &[u8]) -> Option<Vec<u8>> {
474
40
        self(msg)
475
40
    }
476
}
477

            
478
/// Complete an ntor v3 handshake as a server.
479
///
480
/// Use the provided `rng` to generate keys; use the provided
481
/// `reply_fn` to handle incoming client secret message and decide how
482
/// to reply.  The client's handshake is in `message`.  Our private
483
/// key(s) are in `keys`.  The `verification` string must match the
484
/// string provided by the client.
485
///
486
/// On success, return the server handshake message to send, and an XofReader
487
/// to use in generating circuit keys.
488
42
fn server_handshake_ntor_v3<RNG: CryptoRng + RngCore, REPLY: MsgReply>(
489
42
    rng: &mut RNG,
490
42
    reply_fn: &mut REPLY,
491
42
    message: &[u8],
492
42
    keys: &[NtorV3SecretKey],
493
42
    verification: &[u8],
494
42
) -> RelayHandshakeResult<(Vec<u8>, NtorV3XofReader)> {
495
42
    let secret_key_y = curve25519::StaticSecret::random_from_rng(rng);
496
42
    server_handshake_ntor_v3_no_keygen(reply_fn, &secret_key_y, message, keys, verification)
497
42
}
498

            
499
/// As `server_handshake_ntor_v3`, but take a secret key instead of an RNG.
500
44
fn server_handshake_ntor_v3_no_keygen<REPLY: MsgReply>(
501
44
    reply_fn: &mut REPLY,
502
44
    secret_key_y: &curve25519::StaticSecret,
503
44
    message: &[u8],
504
44
    keys: &[NtorV3SecretKey],
505
44
    verification: &[u8],
506
44
) -> RelayHandshakeResult<(Vec<u8>, NtorV3XofReader)> {
507
    // Decode the message.
508
44
    let mut r = Reader::from_slice(message);
509
44
    let id: Ed25519Identity = r.extract()?;
510
44
    let requested_pk: curve25519::PublicKey = r.extract()?;
511
44
    let client_pk: curve25519::PublicKey = r.extract()?;
512
44
    let client_msg = r.take_all_but(MAC_LEN)?;
513
44
    let msg_mac: MacVal = r.extract()?;
514
44
    r.should_be_exhausted()?;
515

            
516
    // See if we recognize the provided (id,requested_pk) pair.
517
44
    let keypair = ct_lookup(keys, |key| key.matches(id, requested_pk));
518
44
    let keypair = match keypair {
519
44
        Some(k) => k,
520
        None => return Err(RelayHandshakeError::MissingKey),
521
    };
522

            
523
44
    let xb = keypair.sk.diffie_hellman(&client_pk);
524
44
    let (enc_key, mut mac) = kdf_msgkdf(&xb, &keypair.pk, &client_pk, verification)
525
44
        .map_err(into_internal!("Can't apply ntor3 kdf."))?;
526
    // Verify the message we received.
527
44
    let computed_mac: DigestVal = {
528
        use digest::Digest;
529
44
        mac.write(client_msg)
530
44
            .map_err(into_internal!("Can't compute MAC input."))?;
531
44
        mac.take().finalize().into()
532
    };
533
44
    let y_pk: curve25519::PublicKey = (secret_key_y).into();
534
44
    let xy = secret_key_y.diffie_hellman(&client_pk);
535

            
536
44
    let mut okay = computed_mac.ct_eq(&msg_mac)
537
44
        & ct::bool_to_choice(xy.was_contributory())
538
44
        & ct::bool_to_choice(xb.was_contributory());
539

            
540
44
    let plaintext_msg = decrypt(&enc_key, client_msg);
541

            
542
    // Handle the message and decide how to reply.
543
44
    let reply = reply_fn.reply(&plaintext_msg);
544

            
545
    // It's not exactly constant time to use is_some() and
546
    // unwrap_or_else() here, but that should be somewhat
547
    // hidden by the rest of the computation.
548
44
    okay &= ct::bool_to_choice(reply.is_some());
549
44
    let reply = reply.unwrap_or_default();
550

            
551
    // If we reach this point, we are actually replying, or pretending
552
    // that we're going to reply.
553

            
554
44
    let secret_input = {
555
44
        let mut si = SecretBuf::new();
556
44
        si.write(&xy)
557
44
            .and_then(|_| si.write(&xb))
558
44
            .and_then(|_| si.write(&keypair.pk.id))
559
44
            .and_then(|_| si.write(&keypair.pk.pk))
560
44
            .and_then(|_| si.write(&client_pk))
561
44
            .and_then(|_| si.write(&y_pk))
562
44
            .and_then(|_| si.write(PROTOID))
563
44
            .and_then(|_| si.write(&Encap(verification)))
564
44
            .map_err(into_internal!("can't derive ntor3 secret_input"))?;
565
44
        si
566
    };
567
44
    let ntor_key_seed = h_key_seed(&secret_input);
568
44
    let verify = h_verify(&secret_input);
569

            
570
44
    let (enc_key, keystream) = {
571
        use digest::{ExtendableOutput, XofReader};
572
44
        let mut xof = DigestWriter(Shake256::default());
573
44
        xof.write(&T_FINAL)
574
44
            .and_then(|_| xof.write(&ntor_key_seed))
575
44
            .map_err(into_internal!("can't generate ntor3 xof."))?;
576
44
        let mut r = xof.take().finalize_xof();
577
44
        let mut enc_key = Zeroizing::new([0_u8; ENC_KEY_LEN]);
578
44
        r.read(&mut enc_key[..]);
579
44
        (enc_key, r)
580
    };
581
44
    let encrypted_reply = encrypt(&enc_key, &reply);
582
44
    let auth: DigestVal = {
583
        use digest::Digest;
584
44
        let mut auth = DigestWriter(Sha3_256::default());
585
44
        auth.write(&T_AUTH)
586
44
            .and_then(|_| auth.write(&verify))
587
44
            .and_then(|_| auth.write(&keypair.pk.id))
588
44
            .and_then(|_| auth.write(&keypair.pk.pk))
589
44
            .and_then(|_| auth.write(&y_pk))
590
44
            .and_then(|_| auth.write(&client_pk))
591
44
            .and_then(|_| auth.write(&msg_mac))
592
44
            .and_then(|_| auth.write(&Encap(&encrypted_reply)))
593
44
            .and_then(|_| auth.write(PROTOID))
594
44
            .and_then(|_| auth.write(&b"Server"[..]))
595
44
            .map_err(into_internal!("can't derive ntor3 authentication"))?;
596
44
        auth.take().finalize().into()
597
    };
598

            
599
44
    let reply = {
600
44
        let mut reply = Vec::new();
601
44
        reply
602
44
            .write(&y_pk)
603
44
            .and_then(|_| reply.write(&auth))
604
44
            .and_then(|_| reply.write(&encrypted_reply))
605
44
            .map_err(into_internal!("can't encode ntor3 reply."))?;
606
44
        reply
607
    };
608

            
609
44
    if okay.into() {
610
44
        Ok((reply, NtorV3XofReader(keystream)))
611
    } else {
612
        Err(RelayHandshakeError::BadClientHandshake)
613
    }
614
44
}
615

            
616
/// Finalize the handshake on the client side.
617
///
618
/// Called after we've received a message from the relay: try to
619
/// complete the handshake and verify its correctness.
620
///
621
/// On success, return the server's reply to our original encrypted message,
622
/// and an `XofReader` to use in generating circuit keys.
623
44
fn client_handshake_ntor_v3_part2(
624
44
    state: &NtorV3HandshakeState,
625
44
    relay_handshake: &[u8],
626
44
    verification: &[u8],
627
44
) -> Result<(Vec<u8>, NtorV3XofReader)> {
628
44
    let mut reader = Reader::from_slice(relay_handshake);
629
44
    let y_pk: curve25519::PublicKey = reader
630
44
        .extract()
631
44
        .map_err(|e| Error::from_bytes_err(e, "v3 ntor handshake"))?;
632
44
    let auth: DigestVal = reader
633
44
        .extract()
634
44
        .map_err(|e| Error::from_bytes_err(e, "v3 ntor handshake"))?;
635
44
    let encrypted_msg = reader.into_rest();
636

            
637
    // TODO: Some of this code is duplicated from the server handshake code!  It
638
    // would be better to factor it out.
639
44
    let yx = state.my_sk.diffie_hellman(&y_pk);
640
44
    let secret_input = {
641
44
        let mut si = SecretBuf::new();
642
44
        si.write(&yx)
643
66
            .and_then(|_| si.write(&state.shared_secret))
644
66
            .and_then(|_| si.write(&state.relay_public.id))
645
66
            .and_then(|_| si.write(&state.relay_public.pk))
646
66
            .and_then(|_| si.write(&state.my_public))
647
66
            .and_then(|_| si.write(&y_pk))
648
66
            .and_then(|_| si.write(PROTOID))
649
66
            .and_then(|_| si.write(&Encap(verification)))
650
44
            .map_err(into_internal!("error encoding ntor3 secret_input"))?;
651
44
        si
652
    };
653
44
    let ntor_key_seed = h_key_seed(&secret_input);
654
44
    let verify = h_verify(&secret_input);
655

            
656
44
    let computed_auth: DigestVal = {
657
        use digest::Digest;
658
44
        let mut auth = DigestWriter(Sha3_256::default());
659
44
        auth.write(&T_AUTH)
660
66
            .and_then(|_| auth.write(&verify))
661
66
            .and_then(|_| auth.write(&state.relay_public.id))
662
66
            .and_then(|_| auth.write(&state.relay_public.pk))
663
66
            .and_then(|_| auth.write(&y_pk))
664
66
            .and_then(|_| auth.write(&state.my_public))
665
66
            .and_then(|_| auth.write(&state.msg_mac))
666
66
            .and_then(|_| auth.write(&Encap(encrypted_msg)))
667
66
            .and_then(|_| auth.write(PROTOID))
668
66
            .and_then(|_| auth.write(&b"Server"[..]))
669
44
            .map_err(into_internal!("error encoding ntor3 authentication input"))?;
670
44
        auth.take().finalize().into()
671
    };
672

            
673
44
    let okay = computed_auth.ct_eq(&auth)
674
44
        & ct::bool_to_choice(yx.was_contributory())
675
44
        & ct::bool_to_choice(state.shared_secret.was_contributory());
676

            
677
44
    let (enc_key, keystream) = {
678
        use digest::{ExtendableOutput, XofReader};
679
44
        let mut xof = DigestWriter(Shake256::default());
680
44
        xof.write(&T_FINAL)
681
66
            .and_then(|_| xof.write(&ntor_key_seed))
682
44
            .map_err(into_internal!("error encoding ntor3 xof input"))?;
683
44
        let mut r = xof.take().finalize_xof();
684
44
        let mut enc_key = Zeroizing::new([0_u8; ENC_KEY_LEN]);
685
44
        r.read(&mut enc_key[..]);
686
44
        (enc_key, r)
687
    };
688
44
    let server_reply = decrypt(&enc_key, encrypted_msg);
689

            
690
44
    if okay.into() {
691
44
        Ok((server_reply, NtorV3XofReader(keystream)))
692
    } else {
693
        Err(Error::BadCircHandshakeAuth)
694
    }
695
44
}
696

            
697
#[cfg(test)]
698
#[allow(non_snake_case)] // to enable variable names matching the spec.
699
#[allow(clippy::many_single_char_names)] // ibid
700
mod test {
701
    // @@ begin test lint list maintained by maint/add_warning @@
702
    #![allow(clippy::bool_assert_comparison)]
703
    #![allow(clippy::clone_on_copy)]
704
    #![allow(clippy::dbg_macro)]
705
    #![allow(clippy::mixed_attributes_style)]
706
    #![allow(clippy::print_stderr)]
707
    #![allow(clippy::print_stdout)]
708
    #![allow(clippy::single_char_pattern)]
709
    #![allow(clippy::unwrap_used)]
710
    #![allow(clippy::unchecked_time_subtraction)]
711
    #![allow(clippy::useless_vec)]
712
    #![allow(clippy::needless_pass_by_value)]
713
    //! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
714
    use crate::crypto::handshake::{ClientHandshake, ServerHandshake};
715

            
716
    use super::*;
717
    use hex_literal::hex;
718
    use tor_basic_utils::test_rng::testing_rng;
719
    use tor_cell::relaycell::extend::{CcRequest, CcResponse, CircResponseExt};
720

            
721
    #[test]
722
    fn test_ntor3_roundtrip() {
723
        let mut rng = rand::rng();
724
        let relay_private = NtorV3SecretKey::generate_for_test(&mut testing_rng());
725

            
726
        let verification = &b"shared secret"[..];
727
        let client_message = &b"Hello. I am a client. Let's be friends!"[..];
728
        let relay_message = &b"Greetings, client. I am a robot. Beep boop."[..];
729

            
730
        let (c_state, c_handshake) =
731
            client_handshake_ntor_v3(&mut rng, &relay_private.pk, client_message, verification)
732
                .unwrap();
733

            
734
        struct Rep(Vec<u8>, Vec<u8>);
735
        impl MsgReply for Rep {
736
            fn reply(&mut self, msg: &[u8]) -> Option<Vec<u8>> {
737
                self.0 = msg.to_vec();
738
                Some(self.1.clone())
739
            }
740
        }
741
        let mut rep = Rep(Vec::new(), relay_message.to_vec());
742

            
743
        let (s_handshake, mut s_keygen) = server_handshake_ntor_v3(
744
            &mut rng,
745
            &mut rep,
746
            &c_handshake,
747
            &[relay_private],
748
            verification,
749
        )
750
        .unwrap();
751

            
752
        let (s_msg, mut c_keygen) =
753
            client_handshake_ntor_v3_part2(&c_state, &s_handshake, verification).unwrap();
754

            
755
        assert_eq!(rep.0[..], client_message[..]);
756
        assert_eq!(s_msg[..], relay_message[..]);
757
        use digest::XofReader;
758
        let mut s_keys = [0_u8; 100];
759
        let mut c_keys = [0_u8; 1000];
760
        s_keygen.read(&mut s_keys);
761
        c_keygen.read(&mut c_keys);
762
        assert_eq!(s_keys[..], c_keys[..100]);
763
    }
764

            
765
    // Same as previous test, but use the higher-level APIs instead.
766
    #[test]
767
    fn test_ntor3_roundtrip_highlevel() {
768
        let mut rng = rand::rng();
769
        let relay_private = NtorV3SecretKey::generate_for_test(&mut testing_rng());
770

            
771
        let (c_state, c_handshake) =
772
            NtorV3Client::client1(&mut rng, &relay_private.pk, &[]).unwrap();
773

            
774
        let mut rep = |_: &[CircRequestExt]| Some(vec![]);
775

            
776
        let (s_keygen, s_handshake) =
777
            NtorV3Server::server(&mut rng, &mut rep, &[relay_private], &c_handshake).unwrap();
778

            
779
        let (extensions, keygen) = NtorV3Client::client2(c_state, s_handshake).unwrap();
780

            
781
        assert!(extensions.is_empty());
782
        let c_keys = keygen.expand(1000).unwrap();
783
        let s_keys = s_keygen.expand(100).unwrap();
784
        assert_eq!(s_keys[..], c_keys[..100]);
785
    }
786

            
787
    // Same as previous test, but encode some congestion control extensions.
788
    #[test]
789
    fn test_ntor3_roundtrip_highlevel_cc() {
790
        let mut rng = rand::rng();
791
        let relay_private = NtorV3SecretKey::generate_for_test(&mut testing_rng());
792

            
793
        let client_exts = vec![CircRequestExt::CcRequest(CcRequest::default())];
794
        let reply_exts = vec![CircResponseExt::CcResponse(CcResponse::new(42))];
795

            
796
        let (c_state, c_handshake) = NtorV3Client::client1(
797
            &mut rng,
798
            &relay_private.pk,
799
            &[CircRequestExt::CcRequest(CcRequest::default())],
800
        )
801
        .unwrap();
802

            
803
        let mut rep = |msg: &[CircRequestExt]| -> Option<Vec<CircResponseExt>> {
804
            assert_eq!(msg, client_exts);
805
            Some(reply_exts.clone())
806
        };
807

            
808
        let (s_keygen, s_handshake) =
809
            NtorV3Server::server(&mut rng, &mut rep, &[relay_private], &c_handshake).unwrap();
810

            
811
        let (extensions, keygen) = NtorV3Client::client2(c_state, s_handshake).unwrap();
812

            
813
        assert_eq!(extensions, reply_exts);
814
        let c_keys = keygen.expand(1000).unwrap();
815
        let s_keys = s_keygen.expand(100).unwrap();
816
        assert_eq!(s_keys[..], c_keys[..100]);
817
    }
818

            
819
    #[test]
820
    fn test_ntor3_testvec() {
821
        let b = hex!("4051daa5921cfa2a1c27b08451324919538e79e788a81b38cbed097a5dff454a");
822
        let id = hex!("9fad2af287ef942632833d21f946c6260c33fae6172b60006e86e4a6911753a2");
823
        let x = hex!("b825a3719147bcbe5fb1d0b0fcb9c09e51948048e2e3283d2ab7b45b5ef38b49");
824
        let y = hex!("4865a5b7689dafd978f529291c7171bc159be076b92186405d13220b80e2a053");
825
        let b: curve25519::StaticSecret = b.into();
826
        let B: curve25519::PublicKey = (&b).into();
827
        let id: Ed25519Identity = id.into();
828
        let x: curve25519::StaticSecret = x.into();
829
        //let X = (&x).into();
830
        let y: curve25519::StaticSecret = y.into();
831

            
832
        let client_message = hex!("68656c6c6f20776f726c64");
833
        let verification = hex!("78797a7a79");
834
        let server_message = hex!("486f6c61204d756e646f");
835

            
836
        let relay_public = NtorV3PublicKey { pk: B, id };
837
        let relay_private = NtorV3SecretKey {
838
            sk: b,
839
            pk: relay_public.clone(),
840
        };
841

            
842
        let (state, client_handshake) =
843
            client_handshake_ntor_v3_no_keygen(&relay_public, &client_message, &verification, x)
844
                .unwrap();
845

            
846
        assert_eq!(
847
            client_handshake[..],
848
            hex!(
849
                "9fad2af287ef942632833d21f946c6260c33fae6172b60006e86e4a6911753a2f8307a2bc1870b00b828bb74dbb8fd88e632a6375ab3bcd1ae706aaa8b6cdd1d252fe9ae91264c91d4ecb8501f79d0387e34ad8ca0f7c995184f7d11d5da4f463bebd9151fd3b47c180abc9e044d53565f04d82bbb3bebed3d06cea65db8be9c72b68cd461942088502f67"
850
            )[..]
851
        );
852

            
853
        struct Replier(Vec<u8>, Vec<u8>, bool);
854
        impl MsgReply for Replier {
855
            fn reply(&mut self, msg: &[u8]) -> Option<Vec<u8>> {
856
                assert_eq!(msg, &self.0);
857
                self.2 = true;
858
                Some(self.1.clone())
859
            }
860
        }
861
        let mut rep = Replier(client_message.to_vec(), server_message.to_vec(), false);
862

            
863
        let (server_handshake, mut server_keygen) = server_handshake_ntor_v3_no_keygen(
864
            &mut rep,
865
            &y,
866
            &client_handshake,
867
            &[relay_private],
868
            &verification,
869
        )
870
        .unwrap();
871
        assert!(rep.2);
872

            
873
        assert_eq!(
874
            server_handshake[..],
875
            hex!(
876
                "4bf4814326fdab45ad5184f5518bd7fae25dc59374062698201a50a22954246d2fc5f8773ca824542bc6cf6f57c7c29bbf4e5476461ab130c5b18ab0a91276651202c3e1e87c0d32054c"
877
            )[..]
878
        );
879

            
880
        let (server_msg_received, mut client_keygen) =
881
            client_handshake_ntor_v3_part2(&state, &server_handshake, &verification).unwrap();
882
        assert_eq!(&server_msg_received, &server_message);
883

            
884
        let (c_keys, s_keys) = {
885
            use digest::XofReader;
886
            let mut c = [0_u8; 256];
887
            let mut s = [0_u8; 256];
888
            client_keygen.read(&mut c);
889
            server_keygen.read(&mut s);
890
            (c, s)
891
        };
892
        assert_eq!(c_keys, s_keys);
893
        assert_eq!(
894
            c_keys[..],
895
            hex!(
896
                "9c19b631fd94ed86a817e01f6c80b0743a43f5faebd39cfaa8b00fa8bcc65c3bfeaa403d91acbd68a821bf6ee8504602b094a254392a07737d5662768c7a9fb1b2814bb34780eaee6e867c773e28c212ead563e98a1cd5d5b4576f5ee61c59bde025ff2851bb19b721421694f263818e3531e43a9e4e3e2c661e2ad547d8984caa28ebecd3e4525452299be26b9185a20a90ce1eac20a91f2832d731b54502b09749b5a2a2949292f8cfcbeffb790c7790ed935a9d251e7e336148ea83b063a5618fcff674a44581585fd22077ca0e52c59a24347a38d1a1ceebddbf238541f226b8f88d0fb9c07a1bcd2ea764bbbb5dacdaf5312a14c0b9e4f06309b0333b4a"
897
            )[..]
898
        );
899
    }
900
}