1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use super::message::ServerAcceptVerificationToken;
use super::shared_secret::*;
use crate::*;
use ssb_crypto::{
handshake::HandshakeKeys, hash::hash, hash::Digest, secretbox, NetworkKey, PublicKey,
};
pub fn client_side_handshake_keys(
_v: ServerAcceptVerificationToken,
pk: &ClientPublicKey,
server_pk: &ServerPublicKey,
eph_pk: &ClientEphPublicKey,
server_eph_pk: &ServerEphPublicKey,
net_key: &NetworkKey,
shared_a: &SharedA,
shared_b: &SharedB,
shared_c: &SharedC,
) -> HandshakeKeys {
HandshakeKeys {
read_key: server_to_client_key(&pk, &net_key, &shared_a, &shared_b, &shared_c),
read_noncegen: NonceGen::new(&eph_pk.0, &net_key),
write_key: client_to_server_key(&server_pk, &net_key, &shared_a, &shared_b, &shared_c),
write_noncegen: NonceGen::new(&server_eph_pk.0, &net_key),
}
}
pub fn server_side_handshake_keys(
pk: &ServerPublicKey,
client_pk: &ClientPublicKey,
eph_pk: &ServerEphPublicKey,
client_eph_pk: &ClientEphPublicKey,
net_key: &NetworkKey,
shared_a: &SharedA,
shared_b: &SharedB,
shared_c: &SharedC,
) -> HandshakeKeys {
HandshakeKeys {
read_key: client_to_server_key(&pk, &net_key, &shared_a, &shared_b, &shared_c),
read_noncegen: NonceGen::new(&eph_pk.0, &net_key),
write_key: server_to_client_key(&client_pk, &net_key, &shared_a, &shared_b, &shared_c),
write_noncegen: NonceGen::new(&client_eph_pk.0, &net_key),
}
}
struct SharedKeyHash(Digest);
#[repr(C, packed)]
struct SharedKeyHashData {
net_key: NetworkKey,
shared_a: SharedA,
shared_b: SharedB,
shared_c: SharedC,
}
impl SharedKeyHashData {
fn into_hash(self) -> SharedKeyHash {
let h1 = unsafe { hash(utils::bytes(&self)) };
SharedKeyHash(hash(&h1[..]))
}
}
#[repr(C, packed)]
struct SharedKeyData {
double_hash: SharedKeyHash,
pk: PublicKey,
}
impl SharedKeyData {
fn into_key(self) -> secretbox::Key {
let digest = unsafe { hash(utils::bytes(&self)) };
secretbox::Key::from_slice(&digest[..]).unwrap()
}
}
fn build_shared_key(
pk: &PublicKey,
net_key: &NetworkKey,
shared_a: &SharedA,
shared_b: &SharedB,
shared_c: &SharedC,
) -> secretbox::Key {
let double_hash = SharedKeyHashData {
net_key: net_key.clone(),
shared_a: shared_a.clone(),
shared_b: shared_b.clone(),
shared_c: shared_c.clone(),
}
.into_hash();
SharedKeyData {
double_hash,
pk: *pk,
}
.into_key()
}
fn client_to_server_key(
server_pk: &ServerPublicKey,
net_key: &NetworkKey,
shared_a: &SharedA,
shared_b: &SharedB,
shared_c: &SharedC,
) -> secretbox::Key {
build_shared_key(&server_pk.0, net_key, shared_a, shared_b, shared_c)
}
fn server_to_client_key(
server_pk: &ClientPublicKey,
net_key: &NetworkKey,
shared_a: &SharedA,
shared_b: &SharedB,
shared_c: &SharedC,
) -> secretbox::Key {
build_shared_key(&server_pk.0, net_key, shared_a, shared_b, shared_c)
}