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::NtorV3Extension;
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
32
    fn read(&mut self, buffer: &mut [u8]) {
67
32
        self.0.read(buffer);
68
32
    }
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
384
    fn write_onto<B: Writer + ?Sized>(&self, b: &mut B) -> EncodeResult<()> {
79
384
        b.write_u64(self.0.len() as u64);
80
384
        b.write(self.0)
81
384
    }
82
}
83

            
84
impl<'a> Encap<'a> {
85
    /// Return the length of the underlying data in bytes.
86
96
    fn len(&self) -> usize {
87
96
        self.0.len()
88
96
    }
89
    /// Return the underlying data
90
96
    fn data(&self) -> &'a [u8] {
91
96
        self.0
92
96
    }
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
96
fn hash(t: &Encap<'_>, data: &[u8]) -> DigestVal {
137
96
    use digest::Digest;
138
96
    let mut d = Sha3_256::new();
139
96
    d.update((t.len() as u64).to_be_bytes());
140
96
    d.update(t.data());
141
96
    d.update(data);
142
96
    d.finalize().into()
143
96
}
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
96
fn encrypt(key: &EncKey, m: &[u8]) -> Vec<u8> {
150
96
    let mut d = m.to_vec();
151
96
    let zero_iv = Default::default();
152
96
    let mut cipher = Aes256Ctr::new(key.as_ref().into(), &zero_iv);
153
96
    cipher.apply_keystream(&mut d);
154
96
    d
155
96
}
156
/// Perform a symmetric decryption operation and return the encrypted data.
157
48
fn decrypt(key: &EncKey, m: &[u8]) -> Vec<u8> {
158
48
    encrypt(key, m)
159
48
}
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
1536
    fn write_all(&mut self, bytes: &[u8]) {
166
1536
        self.0.update(bytes);
167
1536
    }
168
}
169
impl<U> DigestWriter<U> {
170
    /// Consume this wrapper and return the underlying object.
171
192
    fn take(self) -> U {
172
192
        self.0
173
192
    }
174
}
175

            
176
/// Hash tweaked with T_KEY_SEED
177
48
fn h_key_seed(d: &[u8]) -> DigestVal {
178
48
    hash(&T_KEY_SEED, d)
179
48
}
180
/// Hash tweaked with T_VERIFY
181
48
fn h_verify(d: &[u8]) -> DigestVal {
182
48
    hash(&T_VERIFY, d)
183
48
}
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
48
fn kdf_msgkdf(
192
48
    xb: &curve25519::SharedSecret,
193
48
    relay_public: &NtorV3PublicKey,
194
48
    client_public: &curve25519::PublicKey,
195
48
    verification: &[u8],
196
48
) -> EncodeResult<(EncKey, DigestWriter<Sha3_256>)> {
197
48
    // secret_input_phase1 = Bx | ID | X | B | PROTOID | ENCAP(VER)
198
48
    // phase1_keys = KDF_msgkdf(secret_input_phase1)
199
48
    // (ENC_K1, MAC_K1) = PARTITION(phase1_keys, ENC_KEY_LEN, MAC_KEY_LEN
200
48
    use digest::{ExtendableOutput, XofReader};
201
48
    let mut msg_kdf = DigestWriter(Shake256::default());
202
48
    msg_kdf.write(&T_MSGKDF)?;
203
48
    msg_kdf.write(xb)?;
204
48
    msg_kdf.write(&relay_public.id)?;
205
48
    msg_kdf.write(client_public)?;
206
48
    msg_kdf.write(&relay_public.pk)?;
207
48
    msg_kdf.write(PROTOID)?;
208
48
    msg_kdf.write(&Encap(verification))?;
209
48
    let mut r = msg_kdf.take().finalize_xof();
210
48
    let mut enc_key = Zeroizing::new([0; ENC_KEY_LEN]);
211
48
    let mut mac_key = Zeroizing::new([0; MAC_KEY_LEN]);
212
48

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

            
224
48
    Ok((enc_key, mac))
225
48
}
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 = [NtorV3Extension];
235
    type ServerAuxData = Vec<NtorV3Extension>;
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
20
    fn client1<R: RngCore + CryptoRng, M: Borrow<[NtorV3Extension]>>(
243
20
        rng: &mut R,
244
20
        key: &NtorV3PublicKey,
245
20
        extensions: &M,
246
20
    ) -> Result<(Self::StateType, Vec<u8>)> {
247
20
        let mut message = Vec::new();
248
20
        NtorV3Extension::write_many_onto(extensions.borrow(), &mut message)
249
20
            .map_err(|e| Error::from_bytes_enc(e, "ntor3 handshake extensions"))?;
250
        Ok(
251
20
            client_handshake_ntor_v3(rng, key, &message, NTOR3_CIRC_VERIFICATION)
252
20
                .map_err(into_internal!("Can't encode ntor3 client handshake."))?,
253
        )
254
20
    }
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
20
    fn client2<T: AsRef<[u8]>>(
261
20
        state: Self::StateType,
262
20
        msg: T,
263
20
    ) -> Result<(Vec<NtorV3Extension>, Self::KeyGen)> {
264
20
        let (message, xofreader) =
265
20
            client_handshake_ntor_v3_part2(&state, msg.as_ref(), NTOR3_CIRC_VERIFICATION)?;
266
20
        let extensions = NtorV3Extension::decode(&message).map_err(|err| Error::CellDecodeErr {
267
            object: "ntor v3 extensions",
268
            err,
269
20
        })?;
270
20
        let keygen = NtorV3KeyGenerator { reader: xofreader };
271
20

            
272
20
        Ok((extensions, keygen))
273
20
    }
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 = [NtorV3Extension];
283
    type ServerAuxData = Vec<NtorV3Extension>;
284

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

            
299
20
        let (res, reader) = server_handshake_ntor_v3(
300
20
            rng,
301
20
            &mut bytes_reply_fn,
302
20
            msg.as_ref(),
303
20
            key,
304
20
            NTOR3_CIRC_VERIFICATION,
305
20
        )?;
306
20
        Ok((NtorV3KeyGenerator { reader }, res))
307
20
    }
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
16
    pub(crate) fn new(
334
16
        sk: curve25519::StaticSecret,
335
16
        pk: curve25519::PublicKey,
336
16
        id: Ed25519Identity,
337
16
    ) -> Self {
338
16
        Self {
339
16
            pk: NtorV3PublicKey { id, pk },
340
16
            sk,
341
16
        }
342
16
    }
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
6
        // Random bytes will work for testing, but aren't necessarily actually a valid id.
349
6
        rng.fill_bytes(&mut id);
350
6

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

            
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
24
    fn matches(&self, id: Ed25519Identity, pk: curve25519::PublicKey) -> Choice {
364
24
        // TODO: use similar pattern in ntor_v1!
365
24
        id.as_bytes().ct_eq(self.pk.id.as_bytes()) & pk.as_bytes().ct_eq(self.pk.pk.as_bytes())
366
24
    }
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
24
    fn expand(mut self, keylen: usize) -> Result<SecretBuf> {
395
24
        use digest::XofReader;
396
24
        let mut ret: SecretBuf = vec![0; keylen].into();
397
24
        self.reader.read(ret.as_mut());
398
24
        Ok(ret)
399
24
    }
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
22
fn client_handshake_ntor_v3<R: RngCore + CryptoRng>(
408
22
    rng: &mut R,
409
22
    relay_public: &NtorV3PublicKey,
410
22
    client_msg: &[u8],
411
22
    verification: &[u8],
412
22
) -> EncodeResult<(NtorV3HandshakeState, Vec<u8>)> {
413
22
    let my_sk = curve25519::StaticSecret::random_from_rng(rng);
414
22
    client_handshake_ntor_v3_no_keygen(relay_public, client_msg, verification, my_sk)
415
22
}
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
24
fn client_handshake_ntor_v3_no_keygen(
420
24
    relay_public: &NtorV3PublicKey,
421
24
    client_msg: &[u8],
422
24
    verification: &[u8],
423
24
    my_sk: curve25519::StaticSecret,
424
24
) -> EncodeResult<(NtorV3HandshakeState, Vec<u8>)> {
425
24
    let my_public = curve25519::PublicKey::from(&my_sk);
426
24
    let bx = my_sk.diffie_hellman(&relay_public.pk);
427

            
428
24
    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
24
    let encrypted_msg = encrypt(&enc_key, client_msg);
433
24
    let msg_mac: DigestVal = {
434
        use digest::Digest;
435
24
        mac.write(&encrypted_msg)?;
436
24
        mac.take().finalize().into()
437
24
    };
438
24

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

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

            
454
24
    Ok((state, message))
455
24
}
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
20
    fn reply(&mut self, msg: &[u8]) -> Option<Vec<u8>> {
474
20
        self(msg)
475
20
    }
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
22
fn server_handshake_ntor_v3<RNG: CryptoRng + RngCore, REPLY: MsgReply>(
489
22
    rng: &mut RNG,
490
22
    reply_fn: &mut REPLY,
491
22
    message: &[u8],
492
22
    keys: &[NtorV3SecretKey],
493
22
    verification: &[u8],
494
22
) -> RelayHandshakeResult<(Vec<u8>, NtorV3XofReader)> {
495
22
    let secret_key_y = curve25519::StaticSecret::random_from_rng(rng);
496
22
    server_handshake_ntor_v3_no_keygen(reply_fn, &secret_key_y, message, keys, verification)
497
22
}
498

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

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

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

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

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

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

            
545
24
    // It's not exactly constant time to use is_some() and
546
24
    // unwrap_or_else() here, but that should be somewhat
547
24
    // hidden by the rest of the computation.
548
24
    okay &= ct::bool_to_choice(reply.is_some());
549
24
    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
24
    let secret_input = {
555
24
        let mut si = SecretBuf::new();
556
24
        si.write(&xy)
557
24
            .and_then(|_| si.write(&xb))
558
24
            .and_then(|_| si.write(&keypair.pk.id))
559
24
            .and_then(|_| si.write(&keypair.pk.pk))
560
24
            .and_then(|_| si.write(&client_pk))
561
24
            .and_then(|_| si.write(&y_pk))
562
24
            .and_then(|_| si.write(PROTOID))
563
24
            .and_then(|_| si.write(&Encap(verification)))
564
24
            .map_err(into_internal!("can't derive ntor3 secret_input"))?;
565
24
        si
566
24
    };
567
24
    let ntor_key_seed = h_key_seed(&secret_input);
568
24
    let verify = h_verify(&secret_input);
569

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

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

            
609
24
    if okay.into() {
610
24
        Ok((reply, NtorV3XofReader(keystream)))
611
    } else {
612
        Err(RelayHandshakeError::BadClientHandshake)
613
    }
614
24
}
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
24
fn client_handshake_ntor_v3_part2(
624
24
    state: &NtorV3HandshakeState,
625
24
    relay_handshake: &[u8],
626
24
    verification: &[u8],
627
24
) -> Result<(Vec<u8>, NtorV3XofReader)> {
628
24
    let mut reader = Reader::from_slice(relay_handshake);
629
24
    let y_pk: curve25519::PublicKey = reader
630
24
        .extract()
631
24
        .map_err(|e| Error::from_bytes_err(e, "v3 ntor handshake"))?;
632
24
    let auth: DigestVal = reader
633
24
        .extract()
634
24
        .map_err(|e| Error::from_bytes_err(e, "v3 ntor handshake"))?;
635
24
    let encrypted_msg = reader.into_rest();
636
24

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

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

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

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

            
690
24
    if okay.into() {
691
24
        Ok((server_reply, NtorV3XofReader(keystream)))
692
    } else {
693
        Err(Error::BadCircHandshakeAuth)
694
    }
695
24
}
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_duration_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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
792
        let client_exts = vec![NtorV3Extension::RequestCongestionControl];
793
        let reply_exts = vec![NtorV3Extension::AckCongestionControl { sendme_inc: 42 }];
794

            
795
        let (c_state, c_handshake) = NtorV3Client::client1(
796
            &mut rng,
797
            &relay_private.pk,
798
            &[NtorV3Extension::RequestCongestionControl],
799
        )
800
        .unwrap();
801

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

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

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

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

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

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

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

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

            
845
        assert_eq!(client_handshake[..], hex!("9fad2af287ef942632833d21f946c6260c33fae6172b60006e86e4a6911753a2f8307a2bc1870b00b828bb74dbb8fd88e632a6375ab3bcd1ae706aaa8b6cdd1d252fe9ae91264c91d4ecb8501f79d0387e34ad8ca0f7c995184f7d11d5da4f463bebd9151fd3b47c180abc9e044d53565f04d82bbb3bebed3d06cea65db8be9c72b68cd461942088502f67")[..]);
846

            
847
        struct Replier(Vec<u8>, Vec<u8>, bool);
848
        impl MsgReply for Replier {
849
            fn reply(&mut self, msg: &[u8]) -> Option<Vec<u8>> {
850
                assert_eq!(msg, &self.0);
851
                self.2 = true;
852
                Some(self.1.clone())
853
            }
854
        }
855
        let mut rep = Replier(client_message.to_vec(), server_message.to_vec(), false);
856

            
857
        let (server_handshake, mut server_keygen) = server_handshake_ntor_v3_no_keygen(
858
            &mut rep,
859
            &y,
860
            &client_handshake,
861
            &[relay_private],
862
            &verification,
863
        )
864
        .unwrap();
865
        assert!(rep.2);
866

            
867
        assert_eq!(server_handshake[..], hex!("4bf4814326fdab45ad5184f5518bd7fae25dc59374062698201a50a22954246d2fc5f8773ca824542bc6cf6f57c7c29bbf4e5476461ab130c5b18ab0a91276651202c3e1e87c0d32054c")[..]);
868

            
869
        let (server_msg_received, mut client_keygen) =
870
            client_handshake_ntor_v3_part2(&state, &server_handshake, &verification).unwrap();
871
        assert_eq!(&server_msg_received, &server_message);
872

            
873
        let (c_keys, s_keys) = {
874
            use digest::XofReader;
875
            let mut c = [0_u8; 256];
876
            let mut s = [0_u8; 256];
877
            client_keygen.read(&mut c);
878
            server_keygen.read(&mut s);
879
            (c, s)
880
        };
881
        assert_eq!(c_keys, s_keys);
882
        assert_eq!(c_keys[..], hex!("9c19b631fd94ed86a817e01f6c80b0743a43f5faebd39cfaa8b00fa8bcc65c3bfeaa403d91acbd68a821bf6ee8504602b094a254392a07737d5662768c7a9fb1b2814bb34780eaee6e867c773e28c212ead563e98a1cd5d5b4576f5ee61c59bde025ff2851bb19b721421694f263818e3531e43a9e4e3e2c661e2ad547d8984caa28ebecd3e4525452299be26b9185a20a90ce1eac20a91f2832d731b54502b09749b5a2a2949292f8cfcbeffb790c7790ed935a9d251e7e336148ea83b063a5618fcff674a44581585fd22077ca0e52c59a24347a38d1a1ceebddbf238541f226b8f88d0fb9c07a1bcd2ea764bbbb5dacdaf5312a14c0b9e4f06309b0333b4a")[..]);
883
    }
884
}