1+ //
2+ // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3+ //
4+ // Distributed under the Boost Software License, Version 1.0. (See accompanying
5+ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+ //
7+ #include " td/mtproto/AuthKey.h"
8+ #include " td/mtproto/Transport.h"
19
2- #include < stdio.h>
3- #include < openssl/evp.h>
4- #include < openssl/bio.h>
5- #include < openssl/pem.h>
6-
7- #include " td/utils/Status.h"
8- #include " td/utils/SharedSlice.h"
910#include " td/utils/base64.h"
10- #include " td/utils/tl_storers.h"
11-
11+ #include " td/utils/common.h"
1212#include " td/utils/crypto.h"
13+ #include " td/utils/logging.h"
14+ #include " td/utils/ScopeGuard.h"
15+ #include " td/utils/SharedSlice.h"
16+ #include " td/utils/Slice.h"
17+ #include " td/utils/Status.h"
18+ #include " td/utils/StringBuilder.h"
19+ #include " td/utils/UInt.h"
1320
14- #include " td/mtproto/AuthKey.h "
15- #include " td/mtproto/KDF.h "
16- #include " td/mtproto/Transport.h "
21+ #include < openssl/bio.h >
22+ #include < openssl/evp.h >
23+ #include < openssl/pem.h >
1724
1825class Handshake {
1926 public:
@@ -23,17 +30,18 @@ class Handshake {
2330 };
2431
2532 static td::Result<KeyPair> generate_key_pair () {
26- EVP_PKEY *pkey = NULL ;
27- EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id (NID_X25519 , NULL );
28- SCOPE_EXIT {
29- EVP_PKEY_CTX_free (pctx);
30- };
33+ EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id (NID_X25519 , nullptr );
3134 if (pctx == nullptr ) {
3235 return td::Status::Error (" Can't create EXP_PKEY_CTX" );
3336 }
37+ SCOPE_EXIT {
38+ EVP_PKEY_CTX_free (pctx);
39+ };
3440 if (EVP_PKEY_keygen_init (pctx) <= 0 ) {
3541 return td::Status::Error (" Can't init keygen" );
3642 }
43+
44+ EVP_PKEY *pkey = nullptr ;
3745 if (EVP_PKEY_keygen (pctx, &pkey) <= 0 ) {
3846 return td::Status::Error (" Can't generate key" );
3947 }
@@ -138,7 +146,7 @@ class Handshake {
138146 }
139147 char *data_ptr = nullptr ;
140148 auto data_size = BIO_get_mem_data (mem_bio, &data_ptr);
141- return std::string (data_ptr, data_size);
149+ return td::SecureString (data_ptr, data_size);
142150 }
143151};
144152
@@ -152,7 +160,7 @@ struct HandshakeTest {
152160
153161namespace td {
154162
155- void KDF2 (Slice auth_key, const UInt128 &msg_key, int X, UInt256 *aes_key, UInt128 *aes_iv) {
163+ static void KDF3 (Slice auth_key, const UInt128 &msg_key, int X, UInt256 *aes_key, UInt128 *aes_iv) {
156164 uint8 buf_raw[36 + 16 ];
157165 MutableSlice buf (buf_raw, 36 + 16 );
158166 Slice msg_key_slice = as_slice (msg_key);
@@ -183,9 +191,10 @@ void KDF2(Slice auth_key, const UInt128 &msg_key, int X, UInt256 *aes_key, UInt1
183191 aes_iv_slice.substr (4 ).copy_from (sha256_a.substr (8 , 8 ));
184192 aes_iv_slice.substr (12 ).copy_from (sha256_b.substr (24 , 4 ));
185193}
194+
186195} // namespace td
187196
188- td::SecureString encrypt (td::Slice key, td::Slice data, td::int32 seqno, int X) {
197+ static td::SecureString encrypt (td::Slice key, td::Slice data, td::int32 seqno, int X) {
189198 td::SecureString res (data.size () + 4 + 16 );
190199 res.as_mutable_slice ().substr (20 ).copy_from (data);
191200
@@ -201,15 +210,15 @@ td::SecureString encrypt(td::Slice key, td::Slice data, td::int32 seqno, int X)
201210 td::UInt128 msg_key = td::mtproto::Transport::calc_message_key2 (auth_key, X, payload).second ;
202211 td::UInt256 aes_key;
203212 td::UInt128 aes_iv;
204- td::KDF2 (key, msg_key, X, &aes_key, &aes_iv);
213+ td::KDF3 (key, msg_key, X, &aes_key, &aes_iv);
205214 td::AesCtrState aes;
206215 aes.init (aes_key.as_slice (), aes_iv.as_slice ());
207216 aes.encrypt (payload, payload);
208217 res.as_mutable_slice ().copy_from (msg_key.as_slice ());
209218 return res;
210219}
211220
212- HandshakeTest gen_test () {
221+ static HandshakeTest gen_test () {
213222 HandshakeTest res;
214223 res.alice = Handshake::generate_key_pair ().move_as_ok ();
215224
@@ -219,7 +228,7 @@ HandshakeTest gen_test() {
219228 return res;
220229}
221230
222- void run_test (const HandshakeTest &test) {
231+ static void run_test (const HandshakeTest &test) {
223232 auto alice_secret = Handshake::calc_shared_secret (test.alice .private_key , test.bob .public_key ).move_as_ok ();
224233 auto bob_secret = Handshake::calc_shared_secret (test.bob .private_key , test.alice .public_key ).move_as_ok ();
225234 auto key = Handshake::expand_secret (alice_secret);
@@ -229,13 +238,14 @@ void run_test(const HandshakeTest &test) {
229238 CHECK (key == test.key );
230239}
231240
232- td::StringBuilder &operator <<(td::StringBuilder &sb, const Handshake::KeyPair &key_pair) {
241+ static td::StringBuilder &operator <<(td::StringBuilder &sb, const Handshake::KeyPair &key_pair) {
233242 sb << " \t public_key (base64url) = " << td::base64url_encode (key_pair.public_key ) << " \n " ;
234243 sb << " \t private_key (base64url) = " << td::base64url_encode (key_pair.private_key ) << " \n " ;
235244 sb << " \t private_key (pem) = \n " << Handshake::privateKeyToPem (key_pair.private_key ).ok () << " \n " ;
236245 return sb;
237246}
238- td::StringBuilder &operator <<(td::StringBuilder &sb, const HandshakeTest &test) {
247+
248+ static td::StringBuilder &operator <<(td::StringBuilder &sb, const HandshakeTest &test) {
239249 sb << " Alice\n " << test.alice ;
240250 sb << " Bob\n " << test.bob ;
241251 sb << " SharedSecret\n\t " << td::base64url_encode (test.shared_secret ) << " \n " ;
@@ -247,7 +257,7 @@ td::StringBuilder &operator<<(td::StringBuilder &sb, const HandshakeTest &test)
247257 return sb;
248258}
249259
250- HandshakeTest pregenerated_test () {
260+ static HandshakeTest pregenerated_test () {
251261 HandshakeTest test;
252262 test.alice .public_key = td::base64url_decode_secure (" QlCME5fXLyyQQWeYnBiGAZbmzuD4ayOuADCFgmioOBY" ).move_as_ok ();
253263 test.alice .private_key = td::base64url_decode_secure (" 8NZGWKfRCJfiks74RG9_xHmYydarLiRsoq8VcJGPglg" ).move_as_ok ();
0 commit comments