]> git.xonotic.org Git - xonotic/darkplaces.git/blob - crypto.h
Now with new Travis secret key.
[xonotic/darkplaces.git] / crypto.h
1 /*
2 Copyright (C) 2010-2015 Rudolf Polzer (divVerent)
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program 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.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20
21 #ifndef CRYPTO_H
22 #define CRYPTO_H
23
24 #include <stddef.h>
25 #include "qtypes.h"
26 struct lhnetaddress_s;
27
28 extern struct cvar_s crypto_developer;
29 extern struct cvar_s crypto_aeslevel;
30 #define ENCRYPTION_REQUIRED (crypto_aeslevel.integer >= 3)
31
32 extern int crypto_keyfp_recommended_length; // applies to LOCAL IDs, and to ALL keys
33
34 #define CRYPTO_HEADERSIZE 31
35 // AES case causes 16 to 31 bytes overhead
36 // SHA256 case causes 16 bytes overhead as we truncate to 128bit
37
38 #define FP64_SIZE 44
39 #define DHKEY_SIZE 16
40
41 typedef struct
42 {
43         unsigned char dhkey[DHKEY_SIZE]; // shared key, not NUL terminated
44         char client_idfp[FP64_SIZE+1];
45         char client_keyfp[FP64_SIZE+1];
46         qbool client_issigned;
47         char server_idfp[FP64_SIZE+1];
48         char server_keyfp[FP64_SIZE+1];
49         qbool server_issigned;
50         qbool authenticated;
51         qbool use_aes;
52         void *data;
53 }
54 crypto_t;
55
56 void Crypto_Init(void);
57 void Crypto_Init_Commands(void);
58 void Crypto_LoadKeys(void); // NOTE: when this is called, the SV_LockThreadMutex MUST be active
59 void Crypto_Shutdown(void);
60 qbool Crypto_Available(void);
61 void sha256(unsigned char *out, const unsigned char *in, int n); // may ONLY be called if Crypto_Available()
62 const void *Crypto_EncryptPacket(crypto_t *crypto, const void *data_src, size_t len_src, void *data_dst, size_t *len_dst, size_t len);
63 const void *Crypto_DecryptPacket(crypto_t *crypto, const void *data_src, size_t len_src, void *data_dst, size_t *len_dst, size_t len);
64 #define CRYPTO_NOMATCH 0        // process as usual (packet was not used)
65 #define CRYPTO_MATCH 1          // process as usual (packet was used)
66 #define CRYPTO_DISCARD 2        // discard this packet
67 #define CRYPTO_REPLACE 3        // make the buffer the current packet
68 int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out, size_t *len_out, struct lhnetaddress_s *peeraddress);
69 int Crypto_ServerParsePacket(const char *data_in, size_t len_in, char *data_out, size_t *len_out, struct lhnetaddress_s *peeraddress);
70
71 // if len_out is nonzero, the packet is to be sent to the client
72
73 qbool Crypto_ServerAppendToChallenge(const char *data_in, size_t len_in, char *data_out, size_t *len_out, size_t maxlen);
74 crypto_t *Crypto_ServerGetInstance(struct lhnetaddress_s *peeraddress);
75 qbool Crypto_FinishInstance(crypto_t *out, crypto_t *in); // also clears allocated memory, and frees the instance received by ServerGetInstance
76 const char *Crypto_GetInfoResponseDataString(void);
77
78 // retrieves a host key for an address (can be exposed to menuqc, or used by the engine to look up stored keys e.g. for server bookmarking)
79 // pointers may be NULL
80 qbool Crypto_RetrieveHostKey(struct lhnetaddress_s *peeraddress, int *keyid, char *keyfp, size_t keyfplen, char *idfp, size_t idfplen, int *aeslevel, qbool *issigned);
81 int Crypto_RetrieveLocalKey(int keyid, char *keyfp, size_t keyfplen, char *idfp, size_t idfplen, qbool *issigned); // return value: -1 if more to come, +1 if valid, 0 if end of list
82
83 size_t Crypto_SignData(const void *data, size_t datasize, int keyid, void *signed_data, size_t signed_size);
84 size_t Crypto_SignDataDetached(const void *data, size_t datasize, int keyid, void *signed_data, size_t signed_size);
85
86 // netconn protocol:
87 //   non-crypto:
88 //     getchallenge                                            >
89 //                                                             < challenge
90 //     connect                                                 >
91 //                                                             < accept (or: reject)
92 //   crypto:
93 //     getchallenge                                            >
94 //                                                             < challenge SP <challenge> NUL vlen <size> d0pk <fingerprints I can auth to> NUL NUL <other fingerprints I accept>
95 //
96 //     IF serverfp:
97 //     d0pk\cnt\0\challenge\<challenge>\aeslevel\<level> NUL <serverfp> NUL <clientfp>
98 //                                                             >
99 //                                                               check if client would get accepted; if not, do "reject" now
100 //     require non-control packets to be encrypted               require non-control packets to be encrypted
101 //     do not send anything yet                                  do not send anything yet
102 //     RESET to serverfp                                         RESET to serverfp
103 //                                                               d0_blind_id_authenticate_with_private_id_start() = 1
104 //                                                             < d0pk\cnt\1\aes\<aesenabled> NUL *startdata*
105 //     d0_blind_id_authenticate_with_private_id_challenge() = 1
106 //     d0pk\cnt\2 NUL *challengedata*                          >
107 //                                                               d0_blind_id_authenticate_with_private_id_response() = 0
108 //                                                             < d0pk\cnt\3 NUL *responsedata*
109 //     d0_blind_id_authenticate_with_private_id_verify() = 1
110 //     store server's fingerprint NOW
111 //     d0_blind_id_sessionkey_public_id() = 1                    d0_blind_id_sessionkey_public_id() = 1
112 //
113 //     IF clientfp AND NOT serverfp:
114 //     RESET to clientfp                                         RESET to clientfp
115 //     d0_blind_id_authenticate_with_private_id_start() = 1
116 //     d0pk\cnt\0\challenge\<challenge>\aeslevel\<level> NUL NUL <clientfp> NUL *startdata*
117 //                                                             >
118 //                                                               check if client would get accepted; if not, do "reject" now
119 //     require non-control packets to be encrypted               require non-control packets to be encrypted
120 //                                                               d0_blind_id_authenticate_with_private_id_challenge() = 1
121 //                                                             < d0pk\cnt\5\aes\<aesenabled> NUL *challengedata*
122 //
123 //     IF clientfp AND serverfp:
124 //     RESET to clientfp                                         RESET to clientfp
125 //     d0_blind_id_authenticate_with_private_id_start() = 1
126 //     d0pk\cnt\4 NUL *startdata*                              >
127 //                                                               d0_blind_id_authenticate_with_private_id_challenge() = 1
128 //                                                             < d0pk\cnt\5 NUL *challengedata*
129 //
130 //     IF clientfp:
131 //     d0_blind_id_authenticate_with_private_id_response() = 0
132 //     d0pk\cnt\6 NUL *responsedata*                           >
133 //                                                               d0_blind_id_authenticate_with_private_id_verify() = 1
134 //                                                               store client's fingerprint NOW
135 //     d0_blind_id_sessionkey_public_id() = 1                    d0_blind_id_sessionkey_public_id() = 1
136 //     note: the ... is the "connect" message, except without the challenge. Reinterpret as regular connect message on server side
137 //
138 //     enforce encrypted transmission (key is XOR of the two DH keys)
139 //
140 //     IF clientfp:
141 //                                                             < challenge (mere sync message)
142 //
143 //     connect\...                                             >
144 //                                                             < accept (ALWAYS accept if connection is encrypted, ignore challenge as it had been checked before)
145 //
146 //     commence with ingame protocol
147
148 // in short:
149 //   server:
150 //     getchallenge NUL d0_blind_id: reply with challenge with added fingerprints
151 //     cnt=0: IF server will auth, cnt=1, ELSE cnt=5
152 //     cnt=2: cnt=3
153 //     cnt=4: cnt=5
154 //     cnt=6: send "challenge"
155 //   client:
156 //     challenge with added fingerprints: cnt=0; if client will auth but not server, append client auth start
157 //     cnt=1: cnt=2
158 //     cnt=3: IF client will auth, cnt=4, ELSE rewrite as "challenge"
159 //     cnt=5: cnt=6, server will continue by sending "challenge" (let's avoid sending two packets as response to one)
160 // other change:
161 //   accept empty "challenge", and challenge-less connect in case crypto protocol has executed and finished
162 //   statusResponse and infoResponse get an added d0_blind_id key that lists
163 //   the keys the server can auth with and to in key@ca SPACE key@ca notation
164 //   any d0pk\ message has an appended "id" parameter; messages with an unexpected "id" are ignored to prevent errors from multiple concurrent auth runs
165
166
167 // comparison to OTR:
168 // - encryption: yes
169 // - authentication: yes
170 // - deniability: no (attacker requires the temporary session key to prove you
171 //   have sent a specific message, the private key itself does not suffice), no
172 //   measures are taken to provide forgeability to even provide deniability
173 //   against an attacker who knows the temporary session key, as using CTR mode
174 //   for the encryption - which, together with deriving the MAC key from the
175 //   encryption key, and MACing the ciphertexts instead of the plaintexts,
176 //   would provide forgeability and thus deniability - requires longer
177 //   encrypted packets and deniability was not a goal of this, as we may e.g.
178 //   reserve the right to capture packet dumps + extra state info to prove a
179 //   client/server has sent specific packets to prove cheating)
180 // - perfect forward secrecy: yes (session key is derived via DH key exchange)
181
182 #endif