public static (GarlicAESBlock, I2PSessionKey) EGDecryptGarlic( GarlicMessage garlic, I2PPrivateKey privkey) { var cipher = new CbcBlockCipher(new AesEngine()); var egdata = garlic.EGData; var egbuf = new BufLen(egdata, 0, 514); var egheader = ElGamalCrypto.Decrypt(egbuf, privkey, true); var sessionkey = new I2PSessionKey(new BufLen(egheader, 0, 32)); var preiv = new BufLen(egheader, 32, 32); var egpadding = new BufLen(egheader, 64, 158); var aesbuf = new BufLen(egdata, 514); var pivh = I2PHashSHA256.GetHash(preiv); cipher.Init(false, sessionkey.Key.ToParametersWithIV(new BufLen(pivh, 0, 16))); cipher.ProcessBytes(aesbuf); GarlicAESBlock aesblock = new GarlicAESBlock(new BufRefLen(aesbuf)); if (!aesblock.VerifyPayloadHash()) { throw new ChecksumFailureException("AES block hash check failed!"); } return(aesblock, sessionkey); }
public static (GarlicAESBlock, I2PSessionKey) RetrieveAESBlock( GarlicMessage garlic, I2PPrivateKey privatekey, Func <I2PSessionTag, I2PSessionKey> findsessionkey) { GarlicAESBlock result; var cipher = new CbcBlockCipher(new AesEngine()); var tag = new I2PSessionTag(new BufRefLen(garlic.EGData, 0, 32)); var sessionkey = findsessionkey?.Invoke(tag); #if LOG_ALL_LEASE_MGMT Logging.LogDebug($"Garlic: Session key found {sessionkey}"); #endif if (sessionkey != null) { var aesbuf = new BufLen(garlic.EGData, 32); var pivh = I2PHashSHA256.GetHash(tag.Value); cipher.Init(false, sessionkey.Key.ToParametersWithIV(new BufLen(pivh, 0, 16))); cipher.ProcessBytes(aesbuf); try { result = new GarlicAESBlock(new BufRefLen(aesbuf)); if (!result.VerifyPayloadHash()) { Logging.LogDebug("Garlic: DecryptMessage: AES block SHA256 check failed."); return(null, null); } return(result, sessionkey); } catch (ArgumentException ex) { Logging.Log("Garlic", ex); } catch (Exception ex) { Logging.Log("Garlic", ex); return(null, null); } } #if LOG_ALL_LEASE_MGMT Logging.LogDebug("Garlic: No session key. Using ElGamal to decrypt."); #endif try { (result, sessionkey) = Garlic.EGDecryptGarlic(garlic, privatekey); #if LOG_ALL_LEASE_MGMT Logging.LogDebug($"Garlic: EG session key {sessionkey}"); #endif } catch (Exception ex) { Logging.LogDebug("Garlic: ElGamal DecryptMessage failed"); Logging.LogDebugData($"ReceivedSessions {ex}"); return(null, null); } return(result, sessionkey); }