1 | /* |
2 | This file is part of Mtproto-proxy Library. |
3 | |
4 | Mtproto-proxy Library is free software: you can redistribute it and/or modify |
5 | it under the terms of the GNU Lesser General Public License as published by |
6 | the Free Software Foundation, either version 2 of the License, or |
7 | (at your option) any later version. |
8 | |
9 | Mtproto-proxy Library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public License |
15 | along with Mtproto-proxy Library. If not, see <http://www.gnu.org/licenses/>. |
16 | |
17 | Copyright 2010-2013 Vkontakte Ltd |
18 | 2010-2013 Nikolai Durov |
19 | 2010-2013 Andrey Lopatin |
20 | 2013 Vitaliy Valtman |
21 | |
22 | Copyright 2014-2016 Telegram Messenger Inc |
23 | 2014-2016 Nikolai Durov |
24 | 2014-2016 Vitaliy Valtman |
25 | |
26 | */ |
27 | |
28 | #pragma once |
29 | |
30 | #include <openssl/aes.h> |
31 | |
32 | #include "net/net-connections.h" |
33 | #include "crypto/aesni256.h" |
34 | #include "pid.h" |
35 | |
36 | #define MIN_PWD_LEN 32 |
37 | #define MAX_PWD_LEN 256 |
38 | |
39 | #define DEFAULT_PWD_FILE "secret" |
40 | |
41 | int aes_crypto_init (connection_job_t c, void *key_data, int key_data_len); /* < 0 = error */ |
42 | int aes_crypto_ctr128_init (connection_job_t c, void *key_data, int key_data_len); |
43 | int aes_crypto_free (connection_job_t c); |
44 | int aes_crypto_encrypt_output (connection_job_t c); /* 0 = all ok, >0 = so much more bytes needed to encrypt last block */ |
45 | int aes_crypto_decrypt_input (connection_job_t c); /* 0 = all ok, >0 = so much more bytes needed to decrypt last block */ |
46 | int aes_crypto_needed_output_bytes (connection_job_t c); /* returns # of bytes needed to complete last output block */ |
47 | |
48 | void fetch_aes_crypto_stat (int *allocated_aes_crypto_ptr, int *allocated_aes_crypto_temp_ptr); |
49 | |
50 | typedef struct aes_secret { |
51 | int refcnt; |
52 | int secret_len; |
53 | union { |
54 | char secret[MAX_PWD_LEN+4]; |
55 | int key_signature; |
56 | }; |
57 | } aes_secret_t; |
58 | |
59 | extern aes_secret_t main_secret; |
60 | |
61 | /* for aes_crypto_init */ |
62 | struct aes_key_data { |
63 | unsigned char read_key[32]; |
64 | unsigned char read_iv[16]; |
65 | unsigned char write_key[32]; |
66 | unsigned char write_iv[16]; |
67 | }; |
68 | |
69 | #define AES_KEY_DATA_LEN sizeof (struct aes_key_data) |
70 | |
71 | /* for c->crypto */ |
72 | struct aes_crypto { |
73 | unsigned char read_iv[16], write_iv[16]; |
74 | unsigned char read_ebuf[16], write_ebuf[16]; /* for AES-CTR modes */ |
75 | tg_aes_ctx_t read_aeskey __attribute__ ((aligned (16))); |
76 | tg_aes_ctx_t write_aeskey __attribute__ ((aligned (16))); |
77 | unsigned int read_num, write_num; /* for AES-CTR modes */ |
78 | // long long read_pos, write_pos; /* for AES-CTR modes */ |
79 | }; |
80 | |
81 | extern int aes_initialized; |
82 | |
83 | int aes_load_pwd_data (void *data, int len); |
84 | int aes_load_pwd_file (const char *filename); |
85 | int aes_load_random (void); |
86 | int aes_get_pwd_data (void *data, int len); |
87 | int aes_generate_nonce (char res[16]); |
88 | |
89 | int aes_create_keys (struct aes_key_data *R, int am_client, const char nonce_server[16], const char nonce_client[16], int client_timestamp, |
90 | unsigned server_ip, unsigned short server_port, const unsigned char server_ipv6[16], |
91 | unsigned client_ip, unsigned short client_port, const unsigned char client_ipv6[16], |
92 | const aes_secret_t *key, const unsigned char *temp_key, int temp_key_len); |
93 | |
94 | int aes_create_udp_keys (struct aes_key_data *R, struct process_id *local_pid, struct process_id *remote_pid, int generation, const aes_secret_t *key); |
95 | |
96 | void free_aes_secret (aes_secret_t *secret); |
97 | aes_secret_t *alloc_aes_secret (const char *key, int key_len); |
98 | static inline void aes_secret_decref (aes_secret_t *secret) { if (__sync_add_and_fetch (&secret->refcnt, -1) <= 0) { free_aes_secret (secret); } } |
99 | static inline void aes_secret_incref (aes_secret_t *secret) { __sync_fetch_and_add (&secret->refcnt, 1); } |
100 | void free_crypto_temp (void *crypto, int len); |
101 | void *alloc_crypto_temp (int len); |
102 | |