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
41int aes_crypto_init (connection_job_t c, void *key_data, int key_data_len); /* < 0 = error */
42int aes_crypto_ctr128_init (connection_job_t c, void *key_data, int key_data_len);
43int aes_crypto_free (connection_job_t c);
44int aes_crypto_encrypt_output (connection_job_t c); /* 0 = all ok, >0 = so much more bytes needed to encrypt last block */
45int aes_crypto_decrypt_input (connection_job_t c); /* 0 = all ok, >0 = so much more bytes needed to decrypt last block */
46int aes_crypto_needed_output_bytes (connection_job_t c); /* returns # of bytes needed to complete last output block */
47
48void fetch_aes_crypto_stat (int *allocated_aes_crypto_ptr, int *allocated_aes_crypto_temp_ptr);
49
50typedef 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
59extern aes_secret_t main_secret;
60
61/* for aes_crypto_init */
62struct 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 */
72struct 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
81extern int aes_initialized;
82
83int aes_load_pwd_data (void *data, int len);
84int aes_load_pwd_file (const char *filename);
85int aes_load_random (void);
86int aes_get_pwd_data (void *data, int len);
87int aes_generate_nonce (char res[16]);
88
89int 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
94int 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
96void free_aes_secret (aes_secret_t *secret);
97aes_secret_t *alloc_aes_secret (const char *key, int key_len);
98static inline void aes_secret_decref (aes_secret_t *secret) { if (__sync_add_and_fetch (&secret->refcnt, -1) <= 0) { free_aes_secret (secret); } }
99static inline void aes_secret_incref (aes_secret_t *secret) { __sync_fetch_and_add (&secret->refcnt, 1); }
100void free_crypto_temp (void *crypto, int len);
101void *alloc_crypto_temp (int len);
102