1 /* 2 * Copyright (c) 2013-2021, The PurpleI2P Project 3 * 4 * This file is part of Purple i2pd project and licensed under BSD3 5 * 6 * See full license text in LICENSE file at top of project tree 7 */ 8 9 #include <string.h> 10 #include <string> 11 #include <vector> 12 #include <mutex> 13 #include <memory> 14 #include <openssl/dh.h> 15 #include <openssl/md5.h> 16 #include <openssl/crypto.h> 17 #include "TunnelBase.h" 18 #include <openssl/ssl.h> 19 #if OPENSSL_HKDF 20 #include <openssl/kdf.h> 21 #endif 22 #if !OPENSSL_AEAD_CHACHA20_POLY1305 23 #include "ChaCha20.h" 24 #include "Poly1305.h" 25 #endif 26 #include "Crypto.h" 27 #include "Ed25519.h" 28 #include "I2PEndian.h" 29 #include "Log.h" 30 31 namespace i2p 32 { 33 namespace crypto 34 { 35 const uint8_t elgp_[256]= 36 { 37 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 38 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 39 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 40 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 41 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 42 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 43 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 44 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 45 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, 46 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 47 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 48 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, 49 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, 50 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 51 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, 52 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 53 }; 54 55 const int elgg_ = 2; 56 57 const uint8_t dsap_[128]= 58 { 59 0x9c, 0x05, 0xb2, 0xaa, 0x96, 0x0d, 0x9b, 0x97, 0xb8, 0x93, 0x19, 0x63, 0xc9, 0xcc, 0x9e, 0x8c, 60 0x30, 0x26, 0xe9, 0xb8, 0xed, 0x92, 0xfa, 0xd0, 0xa6, 0x9c, 0xc8, 0x86, 0xd5, 0xbf, 0x80, 0x15, 61 0xfc, 0xad, 0xae, 0x31, 0xa0, 0xad, 0x18, 0xfa, 0xb3, 0xf0, 0x1b, 0x00, 0xa3, 0x58, 0xde, 0x23, 62 0x76, 0x55, 0xc4, 0x96, 0x4a, 0xfa, 0xa2, 0xb3, 0x37, 0xe9, 0x6a, 0xd3, 0x16, 0xb9, 0xfb, 0x1c, 63 0xc5, 0x64, 0xb5, 0xae, 0xc5, 0xb6, 0x9a, 0x9f, 0xf6, 0xc3, 0xe4, 0x54, 0x87, 0x07, 0xfe, 0xf8, 64 0x50, 0x3d, 0x91, 0xdd, 0x86, 0x02, 0xe8, 0x67, 0xe6, 0xd3, 0x5d, 0x22, 0x35, 0xc1, 0x86, 0x9c, 65 0xe2, 0x47, 0x9c, 0x3b, 0x9d, 0x54, 0x01, 0xde, 0x04, 0xe0, 0x72, 0x7f, 0xb3, 0x3d, 0x65, 0x11, 66 0x28, 0x5d, 0x4c, 0xf2, 0x95, 0x38, 0xd9, 0xe3, 0xb6, 0x05, 0x1f, 0x5b, 0x22, 0xcc, 0x1c, 0x93 67 }; 68 69 const uint8_t dsaq_[20]= 70 { 71 0xa5, 0xdf, 0xc2, 0x8f, 0xef, 0x4c, 0xa1, 0xe2, 0x86, 0x74, 0x4c, 0xd8, 0xee, 0xd9, 0xd2, 0x9d, 72 0x68, 0x40, 0x46, 0xb7 73 }; 74 75 const uint8_t dsag_[128]= 76 { 77 0x0c, 0x1f, 0x4d, 0x27, 0xd4, 0x00, 0x93, 0xb4, 0x29, 0xe9, 0x62, 0xd7, 0x22, 0x38, 0x24, 0xe0, 78 0xbb, 0xc4, 0x7e, 0x7c, 0x83, 0x2a, 0x39, 0x23, 0x6f, 0xc6, 0x83, 0xaf, 0x84, 0x88, 0x95, 0x81, 79 0x07, 0x5f, 0xf9, 0x08, 0x2e, 0xd3, 0x23, 0x53, 0xd4, 0x37, 0x4d, 0x73, 0x01, 0xcd, 0xa1, 0xd2, 80 0x3c, 0x43, 0x1f, 0x46, 0x98, 0x59, 0x9d, 0xda, 0x02, 0x45, 0x18, 0x24, 0xff, 0x36, 0x97, 0x52, 81 0x59, 0x36, 0x47, 0xcc, 0x3d, 0xdc, 0x19, 0x7d, 0xe9, 0x85, 0xe4, 0x3d, 0x13, 0x6c, 0xdc, 0xfc, 82 0x6b, 0xd5, 0x40, 0x9c, 0xd2, 0xf4, 0x50, 0x82, 0x11, 0x42, 0xa5, 0xe6, 0xf8, 0xeb, 0x1c, 0x3a, 83 0xb5, 0xd0, 0x48, 0x4b, 0x81, 0x29, 0xfc, 0xf1, 0x7b, 0xce, 0x4f, 0x7f, 0x33, 0x32, 0x1c, 0x3c, 84 0xb3, 0xdb, 0xb1, 0x4a, 0x90, 0x5e, 0x7b, 0x2b, 0x3e, 0x93, 0xbe, 0x47, 0x08, 0xcb, 0xcc, 0x82 85 }; 86 87 const int rsae_ = 65537; 88 89 struct CryptoConstants 90 { 91 // DH/ElGamal 92 BIGNUM * elgp; 93 BIGNUM * elgg; 94 95 // DSA 96 BIGNUM * dsap; 97 BIGNUM * dsaq; 98 BIGNUM * dsag; 99 100 // RSA 101 BIGNUM * rsae; 102 CryptoConstantsi2p::crypto::CryptoConstants103 CryptoConstants (const uint8_t * elgp_, int elgg_, const uint8_t * dsap_, 104 const uint8_t * dsaq_, const uint8_t * dsag_, int rsae_) 105 { 106 elgp = BN_new (); 107 BN_bin2bn (elgp_, 256, elgp); 108 elgg = BN_new (); 109 BN_set_word (elgg, elgg_); 110 dsap = BN_new (); 111 BN_bin2bn (dsap_, 128, dsap); 112 dsaq = BN_new (); 113 BN_bin2bn (dsaq_, 20, dsaq); 114 dsag = BN_new (); 115 BN_bin2bn (dsag_, 128, dsag); 116 rsae = BN_new (); 117 BN_set_word (rsae, rsae_); 118 } 119 ~CryptoConstantsi2p::crypto::CryptoConstants120 ~CryptoConstants () 121 { 122 BN_free (elgp); BN_free (elgg); BN_free (dsap); BN_free (dsaq); BN_free (dsag); BN_free (rsae); 123 } 124 }; 125 GetCryptoConstants()126 static const CryptoConstants& GetCryptoConstants () 127 { 128 static CryptoConstants cryptoConstants (elgp_, elgg_, dsap_, dsaq_, dsag_, rsae_); 129 return cryptoConstants; 130 } 131 bn2buf(const BIGNUM * bn,uint8_t * buf,size_t len)132 bool bn2buf (const BIGNUM * bn, uint8_t * buf, size_t len) 133 { 134 int offset = len - BN_num_bytes (bn); 135 if (offset < 0) return false; 136 BN_bn2bin (bn, buf + offset); 137 memset (buf, 0, offset); 138 return true; 139 } 140 141 // RSA 142 #define rsae GetCryptoConstants ().rsae GetRSAE()143 const BIGNUM * GetRSAE () 144 { 145 return rsae; 146 } 147 148 // DSA 149 #define dsap GetCryptoConstants ().dsap 150 #define dsaq GetCryptoConstants ().dsaq 151 #define dsag GetCryptoConstants ().dsag CreateDSA()152 DSA * CreateDSA () 153 { 154 DSA * dsa = DSA_new (); 155 DSA_set0_pqg (dsa, BN_dup (dsap), BN_dup (dsaq), BN_dup (dsag)); 156 DSA_set0_key (dsa, NULL, NULL); 157 return dsa; 158 } 159 160 // DH/ElGamal 161 162 const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226; 163 const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS/8+1; 164 const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048; 165 const int ELGAMAL_FULL_EXPONENT_NUM_BYTES = ELGAMAL_FULL_EXPONENT_NUM_BITS/8; 166 167 #define elgp GetCryptoConstants ().elgp 168 #define elgg GetCryptoConstants ().elgg 169 170 static BN_MONT_CTX * g_MontCtx = nullptr; PrecalculateElggTable(BIGNUM * table[][255],int len)171 static void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums 172 { 173 if (len <= 0) return; 174 BN_CTX * ctx = BN_CTX_new (); 175 g_MontCtx = BN_MONT_CTX_new (); 176 BN_MONT_CTX_set (g_MontCtx, elgp, ctx); 177 auto montCtx = BN_MONT_CTX_new (); 178 BN_MONT_CTX_copy (montCtx, g_MontCtx); 179 for (int i = 0; i < len; i++) 180 { 181 table[i][0] = BN_new (); 182 if (!i) 183 BN_to_montgomery (table[0][0], elgg, montCtx, ctx); 184 else 185 BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], montCtx, ctx); 186 for (int j = 1; j < 255; j++) 187 { 188 table[i][j] = BN_new (); 189 BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], montCtx, ctx); 190 } 191 } 192 BN_MONT_CTX_free (montCtx); 193 BN_CTX_free (ctx); 194 } 195 DestroyElggTable(BIGNUM * table[][255],int len)196 static void DestroyElggTable (BIGNUM * table[][255], int len) 197 { 198 for (int i = 0; i < len; i++) 199 for (int j = 0; j < 255; j++) 200 { 201 BN_free (table[i][j]); 202 table[i][j] = nullptr; 203 } 204 BN_MONT_CTX_free (g_MontCtx); 205 } 206 ElggPow(const uint8_t * exp,int len,BIGNUM * table[][255],BN_CTX * ctx)207 static BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx) 208 // exp is in Big Endian 209 { 210 if (len <= 0) return nullptr; 211 auto montCtx = BN_MONT_CTX_new (); 212 BN_MONT_CTX_copy (montCtx, g_MontCtx); 213 BIGNUM * res = nullptr; 214 for (int i = 0; i < len; i++) 215 { 216 if (res) 217 { 218 if (exp[i]) 219 BN_mod_mul_montgomery (res, res, table[len-1-i][exp[i]-1], montCtx, ctx); 220 } 221 else if (exp[i]) 222 res = BN_dup (table[len-i-1][exp[i]-1]); 223 } 224 if (res) 225 BN_from_montgomery (res, res, montCtx, ctx); 226 BN_MONT_CTX_free (montCtx); 227 return res; 228 } 229 ElggPow(const BIGNUM * exp,BIGNUM * table[][255],BN_CTX * ctx)230 static BIGNUM * ElggPow (const BIGNUM * exp, BIGNUM * table[][255], BN_CTX * ctx) 231 { 232 auto len = BN_num_bytes (exp); 233 uint8_t * buf = new uint8_t[len]; 234 BN_bn2bin (exp, buf); 235 auto ret = ElggPow (buf, len, table, ctx); 236 delete[] buf; 237 return ret; 238 } 239 240 static BIGNUM * (* g_ElggTable)[255] = nullptr; 241 242 // DH 243 DHKeys()244 DHKeys::DHKeys () 245 { 246 m_DH = DH_new (); 247 DH_set0_pqg (m_DH, BN_dup (elgp), NULL, BN_dup (elgg)); 248 DH_set0_key (m_DH, NULL, NULL); 249 } 250 ~DHKeys()251 DHKeys::~DHKeys () 252 { 253 DH_free (m_DH); 254 } 255 GenerateKeys()256 void DHKeys::GenerateKeys () 257 { 258 BIGNUM * priv_key = NULL, * pub_key = NULL; 259 #if !defined(__x86_64__) // use short exponent for non x64 260 priv_key = BN_new (); 261 BN_rand (priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); 262 #endif 263 if (g_ElggTable) 264 { 265 #if defined(__x86_64__) 266 priv_key = BN_new (); 267 BN_rand (priv_key, ELGAMAL_FULL_EXPONENT_NUM_BITS, 0, 1); 268 #endif 269 auto ctx = BN_CTX_new (); 270 pub_key = ElggPow (priv_key, g_ElggTable, ctx); 271 DH_set0_key (m_DH, pub_key, priv_key); 272 BN_CTX_free (ctx); 273 } 274 else 275 { 276 DH_set0_key (m_DH, NULL, priv_key); 277 DH_generate_key (m_DH); 278 DH_get0_key (m_DH, (const BIGNUM **)&pub_key, (const BIGNUM **)&priv_key); 279 } 280 281 bn2buf (pub_key, m_PublicKey, 256); 282 } 283 Agree(const uint8_t * pub,uint8_t * shared)284 void DHKeys::Agree (const uint8_t * pub, uint8_t * shared) 285 { 286 BIGNUM * pk = BN_bin2bn (pub, 256, NULL); 287 DH_compute_key (shared, pk, m_DH); 288 BN_free (pk); 289 } 290 291 // x25519 X25519Keys()292 X25519Keys::X25519Keys () 293 { 294 #if OPENSSL_X25519 295 m_Ctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL); 296 m_Pkey = nullptr; 297 #else 298 m_Ctx = BN_CTX_new (); 299 #endif 300 } 301 X25519Keys(const uint8_t * priv,const uint8_t * pub)302 X25519Keys::X25519Keys (const uint8_t * priv, const uint8_t * pub) 303 { 304 #if OPENSSL_X25519 305 m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); 306 m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); 307 if (pub) 308 memcpy (m_PublicKey, pub, 32); // TODO: verify against m_Pkey 309 else 310 { 311 size_t len = 32; 312 EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); 313 } 314 #else 315 m_Ctx = BN_CTX_new (); 316 memcpy (m_PrivateKey, priv, 32); 317 if (pub) 318 memcpy (m_PublicKey, pub, 32); 319 else 320 GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); 321 #endif 322 } 323 ~X25519Keys()324 X25519Keys::~X25519Keys () 325 { 326 #if OPENSSL_X25519 327 EVP_PKEY_CTX_free (m_Ctx); 328 if (m_Pkey) EVP_PKEY_free (m_Pkey); 329 #else 330 BN_CTX_free (m_Ctx); 331 #endif 332 } 333 GenerateKeys()334 void X25519Keys::GenerateKeys () 335 { 336 #if OPENSSL_X25519 337 if (m_Pkey) 338 { 339 EVP_PKEY_free (m_Pkey); 340 m_Pkey = nullptr; 341 } 342 EVP_PKEY_keygen_init (m_Ctx); 343 EVP_PKEY_keygen (m_Ctx, &m_Pkey); 344 EVP_PKEY_CTX_free (m_Ctx); 345 m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); // TODO: do we really need to re-create m_Ctx? 346 size_t len = 32; 347 EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); 348 #else 349 RAND_bytes (m_PrivateKey, 32); 350 GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); 351 #endif 352 } 353 Agree(const uint8_t * pub,uint8_t * shared)354 bool X25519Keys::Agree (const uint8_t * pub, uint8_t * shared) 355 { 356 if (!pub || (pub[31] & 0x80)) return false; // not x25519 key 357 #if OPENSSL_X25519 358 EVP_PKEY_derive_init (m_Ctx); 359 auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32); 360 if (!pkey) return false; 361 EVP_PKEY_derive_set_peer (m_Ctx, pkey); 362 size_t len = 32; 363 EVP_PKEY_derive (m_Ctx, shared, &len); 364 EVP_PKEY_free (pkey); 365 #else 366 GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx); 367 #endif 368 return true; 369 } 370 GetPrivateKey(uint8_t * priv) const371 void X25519Keys::GetPrivateKey (uint8_t * priv) const 372 { 373 #if OPENSSL_X25519 374 size_t len = 32; 375 EVP_PKEY_get_raw_private_key (m_Pkey, priv, &len); 376 #else 377 memcpy (priv, m_PrivateKey, 32); 378 #endif 379 } 380 SetPrivateKey(const uint8_t * priv,bool calculatePublic)381 void X25519Keys::SetPrivateKey (const uint8_t * priv, bool calculatePublic) 382 { 383 #if OPENSSL_X25519 384 if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); 385 if (m_Pkey) EVP_PKEY_free (m_Pkey); 386 m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); 387 m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); 388 if (calculatePublic) 389 { 390 size_t len = 32; 391 EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); 392 } 393 #else 394 memcpy (m_PrivateKey, priv, 32); 395 if (calculatePublic) 396 GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); 397 #endif 398 } 399 400 // ElGamal ElGamalEncrypt(const uint8_t * key,const uint8_t * data,uint8_t * encrypted)401 void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted) 402 { 403 BN_CTX * ctx = BN_CTX_new (); 404 BN_CTX_start (ctx); 405 // everything, but a, because a might come from table 406 BIGNUM * k = BN_CTX_get (ctx); 407 BIGNUM * y = BN_CTX_get (ctx); 408 BIGNUM * b1 = BN_CTX_get (ctx); 409 BIGNUM * b = BN_CTX_get (ctx); 410 // select random k 411 #if defined(__x86_64__) 412 BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 413 #else 414 BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits 415 #endif 416 // calculate a 417 BIGNUM * a; 418 if (g_ElggTable) 419 a = ElggPow (k, g_ElggTable, ctx); 420 else 421 { 422 a = BN_new (); 423 BN_mod_exp (a, elgg, k, elgp, ctx); 424 } 425 426 // restore y from key 427 BN_bin2bn (key, 256, y); 428 // calculate b1 429 BN_mod_exp (b1, y, k, elgp, ctx); 430 // create m 431 uint8_t m[255]; 432 m[0] = 0xFF; 433 memcpy (m+33, data, 222); 434 SHA256 (m+33, 222, m+1); 435 // calculate b = b1*m mod p 436 BN_bin2bn (m, 255, b); 437 BN_mod_mul (b, b1, b, elgp, ctx); 438 // copy a and b 439 encrypted[0] = 0; 440 bn2buf (a, encrypted + 1, 256); 441 encrypted[257] = 0; 442 bn2buf (b, encrypted + 258, 256); 443 444 BN_free (a); 445 BN_CTX_end (ctx); 446 BN_CTX_free (ctx); 447 } 448 ElGamalDecrypt(const uint8_t * key,const uint8_t * encrypted,uint8_t * data)449 bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data) 450 { 451 BN_CTX * ctx = BN_CTX_new (); 452 BN_CTX_start (ctx); 453 BIGNUM * x = BN_CTX_get (ctx), * a = BN_CTX_get (ctx), * b = BN_CTX_get (ctx); 454 BN_bin2bn (key, 256, x); 455 BN_sub (x, elgp, x); BN_sub_word (x, 1); // x = elgp - x- 1 456 BN_bin2bn (encrypted + 1, 256, a); 457 BN_bin2bn (encrypted + 258, 256, b); 458 // m = b*(a^x mod p) mod p 459 BN_mod_exp (x, a, x, elgp, ctx); 460 BN_mod_mul (b, b, x, elgp, ctx); 461 uint8_t m[255]; 462 bn2buf (b, m, 255); 463 BN_CTX_end (ctx); 464 BN_CTX_free (ctx); 465 uint8_t hash[32]; 466 SHA256 (m + 33, 222, hash); 467 if (memcmp (m + 1, hash, 32)) 468 { 469 LogPrint (eLogError, "ElGamal decrypt hash doesn't match"); 470 return false; 471 } 472 memcpy (data, m + 33, 222); 473 return true; 474 } 475 GenerateElGamalKeyPair(uint8_t * priv,uint8_t * pub)476 void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub) 477 { 478 #if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) 479 RAND_bytes (priv, 256); 480 #else 481 // lower 226 bits (28 bytes and 2 bits) only. short exponent 482 auto numBytes = (ELGAMAL_SHORT_EXPONENT_NUM_BITS)/8 + 1; // 29 483 auto numZeroBytes = 256 - numBytes; 484 RAND_bytes (priv + numZeroBytes, numBytes); 485 memset (priv, 0, numZeroBytes); 486 priv[numZeroBytes] &= 0x03; 487 #endif 488 BN_CTX * ctx = BN_CTX_new (); 489 BIGNUM * p = BN_new (); 490 BN_bin2bn (priv, 256, p); 491 BN_mod_exp (p, elgg, p, elgp, ctx); 492 bn2buf (p, pub, 256); 493 BN_free (p); 494 BN_CTX_free (ctx); 495 } 496 497 // ECIES ECIESEncrypt(const EC_GROUP * curve,const EC_POINT * key,const uint8_t * data,uint8_t * encrypted)498 void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted) 499 { 500 BN_CTX * ctx = BN_CTX_new (); 501 BN_CTX_start (ctx); 502 BIGNUM * q = BN_CTX_get (ctx); 503 EC_GROUP_get_order(curve, q, ctx); 504 int len = BN_num_bytes (q); 505 BIGNUM * k = BN_CTX_get (ctx); 506 BN_rand_range (k, q); // 0 < k < q 507 // point for shared secret 508 auto p = EC_POINT_new (curve); 509 EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx); 510 BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); 511 EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); 512 encrypted[0] = 0; 513 bn2buf (x, encrypted + 1, len); 514 bn2buf (y, encrypted + 1 + len, len); 515 RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len); 516 // encryption key and iv 517 EC_POINT_mul (curve, p, nullptr, key, k, ctx); 518 EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); 519 uint8_t keyBuf[64], iv[64], shared[32]; 520 bn2buf (x, keyBuf, len); 521 bn2buf (y, iv, len); 522 SHA256 (keyBuf, len, shared); 523 // create buffer 524 uint8_t m[256]; 525 m[0] = 0xFF; m[255] = 0xFF; 526 memcpy (m+33, data, 222); 527 SHA256 (m+33, 222, m+1); 528 // encrypt 529 CBCEncryption encryption; 530 encryption.SetKey (shared); 531 encryption.SetIV (iv); 532 encrypted[257] = 0; 533 encryption.Encrypt (m, 256, encrypted + 258); 534 EC_POINT_free (p); 535 BN_CTX_end (ctx); 536 BN_CTX_free (ctx); 537 } 538 ECIESDecrypt(const EC_GROUP * curve,const BIGNUM * key,const uint8_t * encrypted,uint8_t * data)539 bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data) 540 { 541 bool ret = true; 542 BN_CTX * ctx = BN_CTX_new (); 543 BN_CTX_start (ctx); 544 BIGNUM * q = BN_CTX_get (ctx); 545 EC_GROUP_get_order(curve, q, ctx); 546 int len = BN_num_bytes (q); 547 // point for shared secret 548 BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); 549 BN_bin2bn (encrypted + 1, len, x); 550 BN_bin2bn (encrypted + 1 + len, len, y); 551 auto p = EC_POINT_new (curve); 552 if (EC_POINT_set_affine_coordinates_GFp (curve, p, x, y, nullptr)) 553 { 554 auto s = EC_POINT_new (curve); 555 EC_POINT_mul (curve, s, nullptr, p, key, ctx); 556 EC_POINT_get_affine_coordinates_GFp (curve, s, x, y, nullptr); 557 EC_POINT_free (s); 558 uint8_t keyBuf[64], iv[64], shared[32]; 559 bn2buf (x, keyBuf, len); 560 bn2buf (y, iv, len); 561 SHA256 (keyBuf, len, shared); 562 // decrypt 563 uint8_t m[256]; 564 CBCDecryption decryption; 565 decryption.SetKey (shared); 566 decryption.SetIV (iv); 567 decryption.Decrypt (encrypted + 258, 256, m); 568 // verify and copy 569 uint8_t hash[32]; 570 SHA256 (m + 33, 222, hash); 571 if (!memcmp (m + 1, hash, 32)) 572 memcpy (data, m + 33, 222); 573 else 574 { 575 LogPrint (eLogError, "ECIES decrypt hash doesn't match"); 576 ret = false; 577 } 578 } 579 else 580 { 581 LogPrint (eLogError, "ECIES decrypt point is invalid"); 582 ret = false; 583 } 584 585 EC_POINT_free (p); 586 BN_CTX_end (ctx); 587 BN_CTX_free (ctx); 588 return ret; 589 } 590 GenerateECIESKeyPair(const EC_GROUP * curve,BIGNUM * & priv,EC_POINT * & pub)591 void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub) 592 { 593 BN_CTX * ctx = BN_CTX_new (); 594 BIGNUM * q = BN_new (); 595 EC_GROUP_get_order(curve, q, ctx); 596 priv = BN_new (); 597 BN_rand_range (priv, q); 598 pub = EC_POINT_new (curve); 599 EC_POINT_mul (curve, pub, priv, nullptr, nullptr, ctx); 600 BN_free (q); 601 BN_CTX_free (ctx); 602 } 603 604 // HMAC 605 const uint64_t IPAD = 0x3636363636363636; 606 const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C; 607 608 609 static const uint64_t ipads[] = { IPAD, IPAD, IPAD, IPAD }; 610 static const uint64_t opads[] = { OPAD, OPAD, OPAD, OPAD }; 611 HMACMD5Digest(uint8_t * msg,size_t len,const MACKey & key,uint8_t * digest)612 void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest) 613 // key is 32 bytes 614 // digest is 16 bytes 615 // block size is 64 bytes 616 { 617 uint64_t buf[256]; 618 uint64_t hash[12]; // 96 bytes 619 #if (defined(__x86_64__) || defined(__i386__)) && defined(__AVX__) // not all X86 targets supports AVX (like old Pentium, see #1600) 620 if(i2p::cpu::avx) 621 { 622 __asm__ 623 ( 624 "vmovups %[key], %%ymm0 \n" 625 "vmovups %[ipad], %%ymm1 \n" 626 "vmovups %%ymm1, 32(%[buf]) \n" 627 "vxorps %%ymm0, %%ymm1, %%ymm1 \n" 628 "vmovups %%ymm1, (%[buf]) \n" 629 "vmovups %[opad], %%ymm1 \n" 630 "vmovups %%ymm1, 32(%[hash]) \n" 631 "vxorps %%ymm0, %%ymm1, %%ymm1 \n" 632 "vmovups %%ymm1, (%[hash]) \n" 633 "vzeroall \n" // end of AVX 634 "movups %%xmm0, 80(%[hash]) \n" // zero last 16 bytes 635 : 636 : [key]"m"(*(const uint8_t *)key), [ipad]"m"(*ipads), [opad]"m"(*opads), 637 [buf]"r"(buf), [hash]"r"(hash) 638 : "memory", "%xmm0" // TODO: change to %ymm0 later 639 ); 640 } 641 else 642 #endif 643 { 644 // ikeypad 645 buf[0] = key.GetLL ()[0] ^ IPAD; 646 buf[1] = key.GetLL ()[1] ^ IPAD; 647 buf[2] = key.GetLL ()[2] ^ IPAD; 648 buf[3] = key.GetLL ()[3] ^ IPAD; 649 buf[4] = IPAD; 650 buf[5] = IPAD; 651 buf[6] = IPAD; 652 buf[7] = IPAD; 653 // okeypad 654 hash[0] = key.GetLL ()[0] ^ OPAD; 655 hash[1] = key.GetLL ()[1] ^ OPAD; 656 hash[2] = key.GetLL ()[2] ^ OPAD; 657 hash[3] = key.GetLL ()[3] ^ OPAD; 658 hash[4] = OPAD; 659 hash[5] = OPAD; 660 hash[6] = OPAD; 661 hash[7] = OPAD; 662 // fill last 16 bytes with zeros (first hash size assumed 32 bytes in I2P) 663 memset (hash + 10, 0, 16); 664 } 665 666 // concatenate with msg 667 memcpy (buf + 8, msg, len); 668 // calculate first hash 669 MD5((uint8_t *)buf, len + 64, (uint8_t *)(hash + 8)); // 16 bytes 670 671 // calculate digest 672 MD5((uint8_t *)hash, 96, digest); 673 } 674 675 // AES 676 #ifdef __AES__ 677 #define KeyExpansion256(round0,round1) \ 678 "pshufd $0xff, %%xmm2, %%xmm2 \n" \ 679 "movaps %%xmm1, %%xmm4 \n" \ 680 "pslldq $4, %%xmm4 \n" \ 681 "pxor %%xmm4, %%xmm1 \n" \ 682 "pslldq $4, %%xmm4 \n" \ 683 "pxor %%xmm4, %%xmm1 \n" \ 684 "pslldq $4, %%xmm4 \n" \ 685 "pxor %%xmm4, %%xmm1 \n" \ 686 "pxor %%xmm2, %%xmm1 \n" \ 687 "movaps %%xmm1, "#round0"(%[sched]) \n" \ 688 "aeskeygenassist $0, %%xmm1, %%xmm4 \n" \ 689 "pshufd $0xaa, %%xmm4, %%xmm2 \n" \ 690 "movaps %%xmm3, %%xmm4 \n" \ 691 "pslldq $4, %%xmm4 \n" \ 692 "pxor %%xmm4, %%xmm3 \n" \ 693 "pslldq $4, %%xmm4 \n" \ 694 "pxor %%xmm4, %%xmm3 \n" \ 695 "pslldq $4, %%xmm4 \n" \ 696 "pxor %%xmm4, %%xmm3 \n" \ 697 "pxor %%xmm2, %%xmm3 \n" \ 698 "movaps %%xmm3, "#round1"(%[sched]) \n" 699 #endif 700 701 #ifdef __AES__ ExpandKey(const AESKey & key)702 void ECBCryptoAESNI::ExpandKey (const AESKey& key) 703 { 704 __asm__ 705 ( 706 "movups (%[key]), %%xmm1 \n" 707 "movups 16(%[key]), %%xmm3 \n" 708 "movaps %%xmm1, (%[sched]) \n" 709 "movaps %%xmm3, 16(%[sched]) \n" 710 "aeskeygenassist $1, %%xmm3, %%xmm2 \n" 711 KeyExpansion256(32,48) 712 "aeskeygenassist $2, %%xmm3, %%xmm2 \n" 713 KeyExpansion256(64,80) 714 "aeskeygenassist $4, %%xmm3, %%xmm2 \n" 715 KeyExpansion256(96,112) 716 "aeskeygenassist $8, %%xmm3, %%xmm2 \n" 717 KeyExpansion256(128,144) 718 "aeskeygenassist $16, %%xmm3, %%xmm2 \n" 719 KeyExpansion256(160,176) 720 "aeskeygenassist $32, %%xmm3, %%xmm2 \n" 721 KeyExpansion256(192,208) 722 "aeskeygenassist $64, %%xmm3, %%xmm2 \n" 723 // key expansion final 724 "pshufd $0xff, %%xmm2, %%xmm2 \n" 725 "movaps %%xmm1, %%xmm4 \n" 726 "pslldq $4, %%xmm4 \n" 727 "pxor %%xmm4, %%xmm1 \n" 728 "pslldq $4, %%xmm4 \n" 729 "pxor %%xmm4, %%xmm1 \n" 730 "pslldq $4, %%xmm4 \n" 731 "pxor %%xmm4, %%xmm1 \n" 732 "pxor %%xmm2, %%xmm1 \n" 733 "movups %%xmm1, 224(%[sched]) \n" 734 : // output 735 : [key]"r"((const uint8_t *)key), [sched]"r"(GetKeySchedule ()) // input 736 : "%xmm1", "%xmm2", "%xmm3", "%xmm4", "memory" // clogged 737 ); 738 } 739 #endif 740 741 742 #ifdef __AES__ 743 #define EncryptAES256(sched) \ 744 "pxor (%["#sched"]), %%xmm0 \n" \ 745 "aesenc 16(%["#sched"]), %%xmm0 \n" \ 746 "aesenc 32(%["#sched"]), %%xmm0 \n" \ 747 "aesenc 48(%["#sched"]), %%xmm0 \n" \ 748 "aesenc 64(%["#sched"]), %%xmm0 \n" \ 749 "aesenc 80(%["#sched"]), %%xmm0 \n" \ 750 "aesenc 96(%["#sched"]), %%xmm0 \n" \ 751 "aesenc 112(%["#sched"]), %%xmm0 \n" \ 752 "aesenc 128(%["#sched"]), %%xmm0 \n" \ 753 "aesenc 144(%["#sched"]), %%xmm0 \n" \ 754 "aesenc 160(%["#sched"]), %%xmm0 \n" \ 755 "aesenc 176(%["#sched"]), %%xmm0 \n" \ 756 "aesenc 192(%["#sched"]), %%xmm0 \n" \ 757 "aesenc 208(%["#sched"]), %%xmm0 \n" \ 758 "aesenclast 224(%["#sched"]), %%xmm0 \n" 759 #endif 760 Encrypt(const ChipherBlock * in,ChipherBlock * out)761 void ECBEncryption::Encrypt (const ChipherBlock * in, ChipherBlock * out) 762 { 763 #ifdef __AES__ 764 if(i2p::cpu::aesni) 765 { 766 __asm__ 767 ( 768 "movups (%[in]), %%xmm0 \n" 769 EncryptAES256(sched) 770 "movups %%xmm0, (%[out]) \n" 771 : : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory" 772 ); 773 } 774 else 775 #endif 776 { 777 AES_encrypt (in->buf, out->buf, &m_Key); 778 } 779 } 780 781 #ifdef __AES__ 782 #define DecryptAES256(sched) \ 783 "pxor 224(%["#sched"]), %%xmm0 \n" \ 784 "aesdec 208(%["#sched"]), %%xmm0 \n" \ 785 "aesdec 192(%["#sched"]), %%xmm0 \n" \ 786 "aesdec 176(%["#sched"]), %%xmm0 \n" \ 787 "aesdec 160(%["#sched"]), %%xmm0 \n" \ 788 "aesdec 144(%["#sched"]), %%xmm0 \n" \ 789 "aesdec 128(%["#sched"]), %%xmm0 \n" \ 790 "aesdec 112(%["#sched"]), %%xmm0 \n" \ 791 "aesdec 96(%["#sched"]), %%xmm0 \n" \ 792 "aesdec 80(%["#sched"]), %%xmm0 \n" \ 793 "aesdec 64(%["#sched"]), %%xmm0 \n" \ 794 "aesdec 48(%["#sched"]), %%xmm0 \n" \ 795 "aesdec 32(%["#sched"]), %%xmm0 \n" \ 796 "aesdec 16(%["#sched"]), %%xmm0 \n" \ 797 "aesdeclast (%["#sched"]), %%xmm0 \n" 798 #endif 799 Decrypt(const ChipherBlock * in,ChipherBlock * out)800 void ECBDecryption::Decrypt (const ChipherBlock * in, ChipherBlock * out) 801 { 802 #ifdef __AES__ 803 if(i2p::cpu::aesni) 804 { 805 __asm__ 806 ( 807 "movups (%[in]), %%xmm0 \n" 808 DecryptAES256(sched) 809 "movups %%xmm0, (%[out]) \n" 810 : : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory" 811 ); 812 } 813 else 814 #endif 815 { 816 AES_decrypt (in->buf, out->buf, &m_Key); 817 } 818 } 819 820 #ifdef __AES__ 821 #define CallAESIMC(offset) \ 822 "movaps "#offset"(%[shed]), %%xmm0 \n" \ 823 "aesimc %%xmm0, %%xmm0 \n" \ 824 "movaps %%xmm0, "#offset"(%[shed]) \n" 825 #endif 826 SetKey(const AESKey & key)827 void ECBEncryption::SetKey (const AESKey& key) 828 { 829 #ifdef __AES__ 830 if(i2p::cpu::aesni) 831 { 832 ExpandKey (key); 833 } 834 else 835 #endif 836 { 837 AES_set_encrypt_key (key, 256, &m_Key); 838 } 839 } 840 SetKey(const AESKey & key)841 void ECBDecryption::SetKey (const AESKey& key) 842 { 843 #ifdef __AES__ 844 if(i2p::cpu::aesni) 845 { 846 ExpandKey (key); // expand encryption key first 847 // then invert it using aesimc 848 __asm__ 849 ( 850 CallAESIMC(16) 851 CallAESIMC(32) 852 CallAESIMC(48) 853 CallAESIMC(64) 854 CallAESIMC(80) 855 CallAESIMC(96) 856 CallAESIMC(112) 857 CallAESIMC(128) 858 CallAESIMC(144) 859 CallAESIMC(160) 860 CallAESIMC(176) 861 CallAESIMC(192) 862 CallAESIMC(208) 863 : : [shed]"r"(GetKeySchedule ()) : "%xmm0", "memory" 864 ); 865 } 866 else 867 #endif 868 { 869 AES_set_decrypt_key (key, 256, &m_Key); 870 } 871 } 872 Encrypt(int numBlocks,const ChipherBlock * in,ChipherBlock * out)873 void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out) 874 { 875 #ifdef __AES__ 876 if(i2p::cpu::aesni) 877 { 878 __asm__ 879 ( 880 "movups (%[iv]), %%xmm1 \n" 881 "1: \n" 882 "movups (%[in]), %%xmm0 \n" 883 "pxor %%xmm1, %%xmm0 \n" 884 EncryptAES256(sched) 885 "movaps %%xmm0, %%xmm1 \n" 886 "movups %%xmm0, (%[out]) \n" 887 "add $16, %[in] \n" 888 "add $16, %[out] \n" 889 "dec %[num] \n" 890 "jnz 1b \n" 891 "movups %%xmm1, (%[iv]) \n" 892 : 893 : [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()), 894 [in]"r"(in), [out]"r"(out), [num]"r"(numBlocks) 895 : "%xmm0", "%xmm1", "cc", "memory" 896 ); 897 } 898 else 899 #endif 900 { 901 for (int i = 0; i < numBlocks; i++) 902 { 903 *m_LastBlock.GetChipherBlock () ^= in[i]; 904 m_ECBEncryption.Encrypt (m_LastBlock.GetChipherBlock (), m_LastBlock.GetChipherBlock ()); 905 out[i] = *m_LastBlock.GetChipherBlock (); 906 } 907 } 908 } 909 Encrypt(const uint8_t * in,std::size_t len,uint8_t * out)910 void CBCEncryption::Encrypt (const uint8_t * in, std::size_t len, uint8_t * out) 911 { 912 // len/16 913 int numBlocks = len >> 4; 914 if (numBlocks > 0) 915 Encrypt (numBlocks, (const ChipherBlock *)in, (ChipherBlock *)out); 916 } 917 Encrypt(const uint8_t * in,uint8_t * out)918 void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out) 919 { 920 #ifdef __AES__ 921 if(i2p::cpu::aesni) 922 { 923 __asm__ 924 ( 925 "movups (%[iv]), %%xmm1 \n" 926 "movups (%[in]), %%xmm0 \n" 927 "pxor %%xmm1, %%xmm0 \n" 928 EncryptAES256(sched) 929 "movups %%xmm0, (%[out]) \n" 930 "movups %%xmm0, (%[iv]) \n" 931 : 932 : [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()), 933 [in]"r"(in), [out]"r"(out) 934 : "%xmm0", "%xmm1", "memory" 935 ); 936 } 937 else 938 #endif 939 Encrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out); 940 } 941 Decrypt(int numBlocks,const ChipherBlock * in,ChipherBlock * out)942 void CBCDecryption::Decrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out) 943 { 944 #ifdef __AES__ 945 if(i2p::cpu::aesni) 946 { 947 __asm__ 948 ( 949 "movups (%[iv]), %%xmm1 \n" 950 "1: \n" 951 "movups (%[in]), %%xmm0 \n" 952 "movaps %%xmm0, %%xmm2 \n" 953 DecryptAES256(sched) 954 "pxor %%xmm1, %%xmm0 \n" 955 "movups %%xmm0, (%[out]) \n" 956 "movaps %%xmm2, %%xmm1 \n" 957 "add $16, %[in] \n" 958 "add $16, %[out] \n" 959 "dec %[num] \n" 960 "jnz 1b \n" 961 "movups %%xmm1, (%[iv]) \n" 962 : 963 : [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()), 964 [in]"r"(in), [out]"r"(out), [num]"r"(numBlocks) 965 : "%xmm0", "%xmm1", "%xmm2", "cc", "memory" 966 ); 967 } 968 else 969 #endif 970 { 971 for (int i = 0; i < numBlocks; i++) 972 { 973 ChipherBlock tmp = in[i]; 974 m_ECBDecryption.Decrypt (in + i, out + i); 975 out[i] ^= *m_IV.GetChipherBlock (); 976 *m_IV.GetChipherBlock () = tmp; 977 } 978 } 979 } 980 Decrypt(const uint8_t * in,std::size_t len,uint8_t * out)981 void CBCDecryption::Decrypt (const uint8_t * in, std::size_t len, uint8_t * out) 982 { 983 int numBlocks = len >> 4; 984 if (numBlocks > 0) 985 Decrypt (numBlocks, (const ChipherBlock *)in, (ChipherBlock *)out); 986 } 987 Decrypt(const uint8_t * in,uint8_t * out)988 void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out) 989 { 990 #ifdef __AES__ 991 if(i2p::cpu::aesni) 992 { 993 __asm__ 994 ( 995 "movups (%[iv]), %%xmm1 \n" 996 "movups (%[in]), %%xmm0 \n" 997 "movups %%xmm0, (%[iv]) \n" 998 DecryptAES256(sched) 999 "pxor %%xmm1, %%xmm0 \n" 1000 "movups %%xmm0, (%[out]) \n" 1001 : 1002 : [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()), 1003 [in]"r"(in), [out]"r"(out) 1004 : "%xmm0", "%xmm1", "memory" 1005 ); 1006 } 1007 else 1008 #endif 1009 Decrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out); 1010 } 1011 Encrypt(const uint8_t * in,uint8_t * out)1012 void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out) 1013 { 1014 #ifdef __AES__ 1015 if(i2p::cpu::aesni) 1016 { 1017 __asm__ 1018 ( 1019 // encrypt IV 1020 "movups (%[in]), %%xmm0 \n" 1021 EncryptAES256(sched_iv) 1022 "movaps %%xmm0, %%xmm1 \n" 1023 // double IV encryption 1024 EncryptAES256(sched_iv) 1025 "movups %%xmm0, (%[out]) \n" 1026 // encrypt data, IV is xmm1 1027 "1: \n" 1028 "add $16, %[in] \n" 1029 "add $16, %[out] \n" 1030 "movups (%[in]), %%xmm0 \n" 1031 "pxor %%xmm1, %%xmm0 \n" 1032 EncryptAES256(sched_l) 1033 "movaps %%xmm0, %%xmm1 \n" 1034 "movups %%xmm0, (%[out]) \n" 1035 "dec %[num] \n" 1036 "jnz 1b \n" 1037 : 1038 : [sched_iv]"r"(m_IVEncryption.GetKeySchedule ()), [sched_l]"r"(m_LayerEncryption.ECB().GetKeySchedule ()), 1039 [in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes 1040 : "%xmm0", "%xmm1", "cc", "memory" 1041 ); 1042 } 1043 else 1044 #endif 1045 { 1046 m_IVEncryption.Encrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv 1047 m_LayerEncryption.SetIV (out); 1048 m_LayerEncryption.Encrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data 1049 m_IVEncryption.Encrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv 1050 } 1051 } 1052 Decrypt(const uint8_t * in,uint8_t * out)1053 void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out) 1054 { 1055 #ifdef __AES__ 1056 if(i2p::cpu::aesni) 1057 { 1058 __asm__ 1059 ( 1060 // decrypt IV 1061 "movups (%[in]), %%xmm0 \n" 1062 DecryptAES256(sched_iv) 1063 "movaps %%xmm0, %%xmm1 \n" 1064 // double IV encryption 1065 DecryptAES256(sched_iv) 1066 "movups %%xmm0, (%[out]) \n" 1067 // decrypt data, IV is xmm1 1068 "1: \n" 1069 "add $16, %[in] \n" 1070 "add $16, %[out] \n" 1071 "movups (%[in]), %%xmm0 \n" 1072 "movaps %%xmm0, %%xmm2 \n" 1073 DecryptAES256(sched_l) 1074 "pxor %%xmm1, %%xmm0 \n" 1075 "movups %%xmm0, (%[out]) \n" 1076 "movaps %%xmm2, %%xmm1 \n" 1077 "dec %[num] \n" 1078 "jnz 1b \n" 1079 : 1080 : [sched_iv]"r"(m_IVDecryption.GetKeySchedule ()), [sched_l]"r"(m_LayerDecryption.ECB().GetKeySchedule ()), 1081 [in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes 1082 : "%xmm0", "%xmm1", "%xmm2", "cc", "memory" 1083 ); 1084 } 1085 else 1086 #endif 1087 { 1088 m_IVDecryption.Decrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv 1089 m_LayerDecryption.SetIV (out); 1090 m_LayerDecryption.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data 1091 m_IVDecryption.Decrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv 1092 } 1093 } 1094 1095 // AEAD/ChaCha20/Poly1305 1096 AEADChaCha20Poly1305(const uint8_t * msg,size_t msgLen,const uint8_t * ad,size_t adLen,const uint8_t * key,const uint8_t * nonce,uint8_t * buf,size_t len,bool encrypt)1097 bool AEADChaCha20Poly1305 (const uint8_t * msg, size_t msgLen, const uint8_t * ad, size_t adLen, const uint8_t * key, const uint8_t * nonce, uint8_t * buf, size_t len, bool encrypt) 1098 { 1099 if (len < msgLen) return false; 1100 if (encrypt && len < msgLen + 16) return false; 1101 bool ret = true; 1102 #if OPENSSL_AEAD_CHACHA20_POLY1305 1103 int outlen = 0; 1104 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new (); 1105 if (encrypt) 1106 { 1107 EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0); 1108 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, 0); 1109 EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce); 1110 EVP_EncryptUpdate(ctx, NULL, &outlen, ad, adLen); 1111 EVP_EncryptUpdate(ctx, buf, &outlen, msg, msgLen); 1112 EVP_EncryptFinal_ex(ctx, buf, &outlen); 1113 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, buf + msgLen); 1114 } 1115 else 1116 { 1117 EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0); 1118 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, 0); 1119 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, (uint8_t *)(msg + msgLen)); 1120 EVP_DecryptInit_ex(ctx, NULL, NULL, key, nonce); 1121 EVP_DecryptUpdate(ctx, NULL, &outlen, ad, adLen); 1122 EVP_DecryptUpdate(ctx, buf, &outlen, msg, msgLen); 1123 ret = EVP_DecryptFinal_ex(ctx, buf + outlen, &outlen) > 0; 1124 } 1125 1126 EVP_CIPHER_CTX_free (ctx); 1127 #else 1128 chacha::Chacha20State state; 1129 // generate one time poly key 1130 chacha::Chacha20Init (state, nonce, key, 0); 1131 uint64_t polyKey[8]; 1132 memset(polyKey, 0, sizeof(polyKey)); 1133 chacha::Chacha20Encrypt (state, (uint8_t *)polyKey, 64); 1134 // create Poly1305 hash 1135 Poly1305 polyHash (polyKey); 1136 if (!ad) adLen = 0; 1137 uint8_t padding[16]; memset (padding, 0, 16); 1138 if (ad) 1139 { 1140 polyHash.Update (ad, adLen);// additional authenticated data 1141 auto rem = adLen & 0x0F; // %16 1142 if (rem) 1143 { 1144 // padding1 1145 rem = 16 - rem; 1146 polyHash.Update (padding, rem); 1147 } 1148 } 1149 // encrypt/decrypt data and add to hash 1150 Chacha20SetCounter (state, 1); 1151 if (buf != msg) 1152 memcpy (buf, msg, msgLen); 1153 if (encrypt) 1154 { 1155 chacha::Chacha20Encrypt (state, buf, msgLen); // encrypt 1156 polyHash.Update (buf, msgLen); // after encryption 1157 } 1158 else 1159 { 1160 polyHash.Update (buf, msgLen); // before decryption 1161 chacha::Chacha20Encrypt (state, buf, msgLen); // decrypt 1162 } 1163 1164 auto rem = msgLen & 0x0F; // %16 1165 if (rem) 1166 { 1167 // padding2 1168 rem = 16 - rem; 1169 polyHash.Update (padding, rem); 1170 } 1171 // adLen and msgLen 1172 htole64buf (padding, adLen); 1173 htole64buf (padding + 8, msgLen); 1174 polyHash.Update (padding, 16); 1175 1176 if (encrypt) 1177 // calculate Poly1305 tag and write in after encrypted data 1178 polyHash.Finish ((uint64_t *)(buf + msgLen)); 1179 else 1180 { 1181 uint64_t tag[4]; 1182 // calculate Poly1305 tag 1183 polyHash.Finish (tag); 1184 if (memcmp (tag, msg + msgLen, 16)) ret = false; // compare with provided 1185 } 1186 #endif 1187 return ret; 1188 } 1189 AEADChaCha20Poly1305Encrypt(const std::vector<std::pair<uint8_t *,size_t>> & bufs,const uint8_t * key,const uint8_t * nonce,uint8_t * mac)1190 void AEADChaCha20Poly1305Encrypt (const std::vector<std::pair<uint8_t *, size_t> >& bufs, const uint8_t * key, const uint8_t * nonce, uint8_t * mac) 1191 { 1192 if (bufs.empty ()) return; 1193 #if OPENSSL_AEAD_CHACHA20_POLY1305 1194 int outlen = 0; 1195 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new (); 1196 EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0); 1197 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, 0); 1198 EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce); 1199 for (const auto& it: bufs) 1200 EVP_EncryptUpdate(ctx, it.first, &outlen, it.first, it.second); 1201 EVP_EncryptFinal_ex(ctx, NULL, &outlen); 1202 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, mac); 1203 EVP_CIPHER_CTX_free (ctx); 1204 #else 1205 chacha::Chacha20State state; 1206 // generate one time poly key 1207 chacha::Chacha20Init (state, nonce, key, 0); 1208 uint64_t polyKey[8]; 1209 memset(polyKey, 0, sizeof(polyKey)); 1210 chacha::Chacha20Encrypt (state, (uint8_t *)polyKey, 64); 1211 Poly1305 polyHash (polyKey); 1212 // encrypt buffers 1213 Chacha20SetCounter (state, 1); 1214 size_t size = 0; 1215 for (const auto& it: bufs) 1216 { 1217 chacha::Chacha20Encrypt (state, it.first, it.second); 1218 polyHash.Update (it.first, it.second); // after encryption 1219 size += it.second; 1220 } 1221 // padding 1222 uint8_t padding[16]; 1223 memset (padding, 0, 16); 1224 auto rem = size & 0x0F; // %16 1225 if (rem) 1226 { 1227 // padding2 1228 rem = 16 - rem; 1229 polyHash.Update (padding, rem); 1230 } 1231 // adLen and msgLen 1232 // adLen is always zero 1233 htole64buf (padding + 8, size); 1234 polyHash.Update (padding, 16); 1235 // MAC 1236 polyHash.Finish ((uint64_t *)mac); 1237 #endif 1238 } 1239 ChaCha20(const uint8_t * msg,size_t msgLen,const uint8_t * key,const uint8_t * nonce,uint8_t * out)1240 void ChaCha20 (const uint8_t * msg, size_t msgLen, const uint8_t * key, const uint8_t * nonce, uint8_t * out) 1241 { 1242 #if OPENSSL_AEAD_CHACHA20_POLY1305 1243 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new (); 1244 uint32_t iv[4]; 1245 iv[0] = htole32 (1); memcpy (iv + 1, nonce, 12); // counter | nonce 1246 EVP_EncryptInit_ex(ctx, EVP_chacha20 (), NULL, key, (const uint8_t *)iv); 1247 int outlen = 0; 1248 EVP_EncryptUpdate(ctx, out, &outlen, msg, msgLen); 1249 EVP_EncryptFinal_ex(ctx, NULL, &outlen); 1250 EVP_CIPHER_CTX_free (ctx); 1251 #else 1252 chacha::Chacha20State state; 1253 chacha::Chacha20Init (state, nonce, key, 1); 1254 if (out != msg) memcpy (out, msg, msgLen); 1255 chacha::Chacha20Encrypt (state, out, msgLen); 1256 #endif 1257 } 1258 HKDF(const uint8_t * salt,const uint8_t * key,size_t keyLen,const std::string & info,uint8_t * out,size_t outLen)1259 void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, 1260 uint8_t * out, size_t outLen) 1261 { 1262 #if OPENSSL_HKDF 1263 EVP_PKEY_CTX * pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, nullptr); 1264 EVP_PKEY_derive_init (pctx); 1265 EVP_PKEY_CTX_set_hkdf_md (pctx, EVP_sha256()); 1266 if (key && keyLen) 1267 { 1268 EVP_PKEY_CTX_set1_hkdf_salt (pctx, salt, 32); 1269 EVP_PKEY_CTX_set1_hkdf_key (pctx, key, keyLen); 1270 } 1271 else 1272 { 1273 // zerolen 1274 EVP_PKEY_CTX_hkdf_mode (pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY); 1275 uint8_t tempKey[32]; unsigned int len; 1276 HMAC(EVP_sha256(), salt, 32, nullptr, 0, tempKey, &len); 1277 EVP_PKEY_CTX_set1_hkdf_key (pctx, tempKey, len); 1278 } 1279 if (info.length () > 0) 1280 EVP_PKEY_CTX_add1_hkdf_info (pctx, (const uint8_t *)info.c_str (), info.length ()); 1281 EVP_PKEY_derive (pctx, out, &outLen); 1282 EVP_PKEY_CTX_free (pctx); 1283 #else 1284 uint8_t prk[32]; unsigned int len; 1285 HMAC(EVP_sha256(), salt, 32, key, keyLen, prk, &len); 1286 auto l = info.length (); 1287 memcpy (out, info.c_str (), l); out[l] = 0x01; 1288 HMAC(EVP_sha256(), prk, 32, out, l + 1, out, &len); 1289 if (outLen > 32) // 64 1290 { 1291 memcpy (out + 32, info.c_str (), l); out[l + 32] = 0x02; 1292 HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len); 1293 } 1294 #endif 1295 } 1296 1297 // Noise 1298 MixHash(const uint8_t * buf,size_t len)1299 void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len) 1300 { 1301 SHA256_CTX ctx; 1302 SHA256_Init (&ctx); 1303 SHA256_Update (&ctx, m_H, 32); 1304 SHA256_Update (&ctx, buf, len); 1305 SHA256_Final (m_H, &ctx); 1306 } 1307 MixKey(const uint8_t * sharedSecret)1308 void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret) 1309 { 1310 HKDF (m_CK, sharedSecret, 32, "", m_CK); 1311 // new ck is m_CK[0:31], key is m_CK[32:63] 1312 } 1313 InitNoiseState(NoiseSymmetricState & state,const uint8_t * ck,const uint8_t * hh,const uint8_t * pub)1314 static void InitNoiseState (NoiseSymmetricState& state, const uint8_t * ck, 1315 const uint8_t * hh, const uint8_t * pub) 1316 { 1317 // pub is Bob's public static key, hh = SHA256(h) 1318 memcpy (state.m_CK, ck, 32); 1319 SHA256_CTX ctx; 1320 SHA256_Init (&ctx); 1321 SHA256_Update (&ctx, hh, 32); 1322 SHA256_Update (&ctx, pub, 32); 1323 SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) 1324 } 1325 InitNoiseNState(NoiseSymmetricState & state,const uint8_t * pub)1326 void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub) 1327 { 1328 static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars 1329 static const uint8_t hh[32] = 1330 { 1331 0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1, 1332 0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54 1333 }; // hh = SHA256(protocol_name || 0) 1334 InitNoiseState (state, (const uint8_t *)protocolName, hh, pub); // ck = protocol_name || 0 1335 } 1336 InitNoiseXKState(NoiseSymmetricState & state,const uint8_t * pub)1337 void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub) 1338 { 1339 static const uint8_t protocolNameHash[] = 1340 { 1341 0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed, 1342 0xf2, 0x28, 0x98, 0x17, 0x71, 0x21, 0x8c, 0x1f, 0x62, 0x4e, 0x20, 0x6f, 0x28, 0xd3, 0x2f, 0x71 1343 }; // SHA256 ("Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256") 1344 static const uint8_t hh[32] = 1345 { 1346 0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5, 1347 0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e 1348 }; // SHA256 (protocolNameHash) 1349 InitNoiseState (state, protocolNameHash, hh, pub); 1350 } 1351 InitNoiseIKState(NoiseSymmetricState & state,const uint8_t * pub)1352 void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub) 1353 { 1354 static const uint8_t protocolNameHash[32] = 1355 { 1356 0x4c, 0xaf, 0x11, 0xef, 0x2c, 0x8e, 0x36, 0x56, 0x4c, 0x53, 0xe8, 0x88, 0x85, 0x06, 0x4d, 0xba, 1357 0xac, 0xbe, 0x00, 0x54, 0xad, 0x17, 0x8f, 0x80, 0x79, 0xa6, 0x46, 0x82, 0x7e, 0x6e, 0xe4, 0x0c 1358 }; // SHA256("Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"), 40 bytes 1359 static const uint8_t hh[32] = 1360 { 1361 0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32, 1362 0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c 1363 }; // SHA256 (protocolNameHash) 1364 InitNoiseState (state, protocolNameHash, hh, pub); 1365 } 1366 1367 // init and terminate 1368 1369 /* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes; 1370 static void OpensslLockingCallback(int mode, int type, const char * file, int line) 1371 { 1372 if (type > 0 && (size_t)type < m_OpenSSLMutexes.size ()) 1373 { 1374 if (mode & CRYPTO_LOCK) 1375 m_OpenSSLMutexes[type]->lock (); 1376 else 1377 m_OpenSSLMutexes[type]->unlock (); 1378 } 1379 }*/ 1380 InitCrypto(bool precomputation,bool aesni,bool avx,bool force)1381 void InitCrypto (bool precomputation, bool aesni, bool avx, bool force) 1382 { 1383 i2p::cpu::Detect (aesni, avx, force); 1384 #if LEGACY_OPENSSL 1385 SSL_library_init (); 1386 #endif 1387 /* auto numLocks = CRYPTO_num_locks(); 1388 for (int i = 0; i < numLocks; i++) 1389 m_OpenSSLMutexes.emplace_back (new std::mutex); 1390 CRYPTO_set_locking_callback (OpensslLockingCallback);*/ 1391 if (precomputation) 1392 { 1393 #if defined(__x86_64__) 1394 g_ElggTable = new BIGNUM * [ELGAMAL_FULL_EXPONENT_NUM_BYTES][255]; 1395 PrecalculateElggTable (g_ElggTable, ELGAMAL_FULL_EXPONENT_NUM_BYTES); 1396 #else 1397 g_ElggTable = new BIGNUM * [ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255]; 1398 PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); 1399 #endif 1400 } 1401 } 1402 TerminateCrypto()1403 void TerminateCrypto () 1404 { 1405 if (g_ElggTable) 1406 { 1407 DestroyElggTable (g_ElggTable, 1408 #if defined(__x86_64__) 1409 ELGAMAL_FULL_EXPONENT_NUM_BYTES 1410 #else 1411 ELGAMAL_SHORT_EXPONENT_NUM_BYTES 1412 #endif 1413 ); 1414 delete[] g_ElggTable; g_ElggTable = nullptr; 1415 } 1416 /* CRYPTO_set_locking_callback (nullptr); 1417 m_OpenSSLMutexes.clear ();*/ 1418 } 1419 } 1420 } 1421