1#![deny(unsafe_code)]
13
14pub mod aes;
15mod auth_key;
16mod deque_buffer;
17mod factorize;
18pub mod rsa;
19mod sha;
20
21pub use auth_key::AuthKey;
22pub use deque_buffer::DequeBuffer;
23pub use factorize::factorize;
24
25#[derive(Clone, Debug, PartialEq)]
29pub enum DecryptError {
30 InvalidBuffer,
32 AuthKeyMismatch,
34 MessageKeyMismatch,
36}
37
38impl std::fmt::Display for DecryptError {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 match self {
41 Self::InvalidBuffer => write!(f, "invalid ciphertext buffer length"),
42 Self::AuthKeyMismatch => write!(f, "auth_key_id mismatch"),
43 Self::MessageKeyMismatch => write!(f, "msg_key mismatch"),
44 }
45 }
46}
47impl std::error::Error for DecryptError {}
48
49enum Side { Client, Server }
50impl Side {
51 fn x(&self) -> usize { match self { Side::Client => 0, Side::Server => 8 } }
52}
53
54fn calc_key(auth_key: &AuthKey, msg_key: &[u8; 16], side: Side) -> ([u8; 32], [u8; 32]) {
55 let x = side.x();
56 let sha_a = sha256!(msg_key, &auth_key.data[x..x + 36]);
57 let sha_b = sha256!(&auth_key.data[40 + x..40 + x + 36], msg_key);
58
59 let mut aes_key = [0u8; 32];
60 aes_key[..8].copy_from_slice(&sha_a[..8]);
61 aes_key[8..24].copy_from_slice(&sha_b[8..24]);
62 aes_key[24..].copy_from_slice(&sha_a[24..]);
63
64 let mut aes_iv = [0u8; 32];
65 aes_iv[..8].copy_from_slice(&sha_b[..8]);
66 aes_iv[8..24].copy_from_slice(&sha_a[8..24]);
67 aes_iv[24..].copy_from_slice(&sha_b[24..]);
68
69 (aes_key, aes_iv)
70}
71
72fn padding_len(len: usize) -> usize {
73 16 + (16 - (len % 16))
74}
75
76pub fn encrypt_data_v2(buffer: &mut DequeBuffer, auth_key: &AuthKey) {
80 let mut rnd = [0u8; 32];
81 getrandom::getrandom(&mut rnd).expect("getrandom failed");
82 do_encrypt_data_v2(buffer, auth_key, &rnd);
83}
84
85pub(crate) fn do_encrypt_data_v2(buffer: &mut DequeBuffer, auth_key: &AuthKey, rnd: &[u8; 32]) {
86 let pad = padding_len(buffer.len());
87 buffer.extend(rnd.iter().take(pad).copied());
88
89 let x = Side::Client.x();
90 let msg_key_large = sha256!(&auth_key.data[88 + x..88 + x + 32], buffer.as_ref());
91 let mut msg_key = [0u8; 16];
92 msg_key.copy_from_slice(&msg_key_large[8..24]);
93
94 let (key, iv) = calc_key(auth_key, &msg_key, Side::Client);
95 aes::ige_encrypt(buffer.as_mut(), &key, &iv);
96
97 buffer.extend_front(&msg_key);
98 buffer.extend_front(&auth_key.key_id);
99}
100
101pub fn decrypt_data_v2<'a>(buffer: &'a mut [u8], auth_key: &AuthKey) -> Result<&'a mut [u8], DecryptError> {
106 if buffer.len() < 24 || (buffer.len() - 24) % 16 != 0 {
107 return Err(DecryptError::InvalidBuffer);
108 }
109 if auth_key.key_id != buffer[..8] {
110 return Err(DecryptError::AuthKeyMismatch);
111 }
112 let mut msg_key = [0u8; 16];
113 msg_key.copy_from_slice(&buffer[8..24]);
114
115 let (key, iv) = calc_key(auth_key, &msg_key, Side::Server);
116 aes::ige_decrypt(&mut buffer[24..], &key, &iv);
117
118 let x = Side::Server.x();
119 let our_key = sha256!(&auth_key.data[88 + x..88 + x + 32], &buffer[24..]);
120 if msg_key != our_key[8..24] {
121 return Err(DecryptError::MessageKeyMismatch);
122 }
123 Ok(&mut buffer[24..])
124}
125
126pub fn generate_key_data_from_nonce(server_nonce: &[u8; 16], new_nonce: &[u8; 32]) -> ([u8; 32], [u8; 32]) {
128 let h1 = sha1!(new_nonce, server_nonce);
129 let h2 = sha1!(server_nonce, new_nonce);
130 let h3 = sha1!(new_nonce, new_nonce);
131
132 let mut key = [0u8; 32];
133 key[..20].copy_from_slice(&h1);
134 key[20..].copy_from_slice(&h2[..12]);
135
136 let mut iv = [0u8; 32];
137 iv[..8].copy_from_slice(&h2[12..]);
138 iv[8..28].copy_from_slice(&h3);
139 iv[28..].copy_from_slice(&new_nonce[..4]);
140
141 (key, iv)
142}