def deriveRelayCrypto(self, cell): '''Derive shared key material for this ntor handshake; create and return actual cipher and hash instances inside a RelayCrypto object. .. note:: See tor-spec Section 5.1.4, 5.2.2 for more details. :param cell cell: Created2 cell or Extended2 cell used to derive shared keys :returns: **oppy.crypto.relaycrypto.RelayCrypto** object initialized with the derived key material. ''' self.is_bad = False hdata = cell.hdata relay_pubkey = cell.hdata[: CURVE25519_PUBKEY_LEN] AUTH = hdata[CURVE25519_PUBKEY_LEN: CURVE25519_PUBKEY_LEN + DIGEST_LEN] secret_input = self._buildSecretInput(relay_pubkey) verify = util.makeHMACSHA256(msg=secret_input, key=T_VERIFY) auth_input = self._buildAuthInput(verify, relay_pubkey) auth_input = util.makeHMACSHA256(msg=auth_input, key=T_MAC) self.is_bad |= util.constantStrEqual(AUTH, auth_input) ret = self._makeRelayCrypto(secret_input) # don't fail until the very end to avoid leaking timing information if self.is_bad: raise KeyDerivationFailed() return ret
def deriveRelayCrypto(self, cell): '''Derive shared key material for this ntor handshake; create and return actual cipher and hash instances inside a RelayCrypto object. .. note:: See tor-spec Section 5.1.4, 5.2.2 for more details. :param cell cell: Created2 cell or Extended2 cell used to derive shared keys :returns: **oppy.crypto.relaycrypto.RelayCrypto** object initialized with the derived key material. ''' self.is_bad = False hdata = cell.hdata relay_pubkey = cell.hdata[:CURVE25519_PUBKEY_LEN] AUTH = hdata[CURVE25519_PUBKEY_LEN:CURVE25519_PUBKEY_LEN + DIGEST_LEN] secret_input = self._buildSecretInput(relay_pubkey) verify = util.makeHMACSHA256(msg=secret_input, key=T_VERIFY) auth_input = self._buildAuthInput(verify, relay_pubkey) auth_input = util.makeHMACSHA256(msg=auth_input, key=T_MAC) self.is_bad |= util.constantStrEqual(AUTH, auth_input) ret = self._makeRelayCrypto(secret_input) # don't fail until the very end to avoid leaking timing information if self.is_bad: raise KeyDerivationFailed() return ret
def test_makeHMACSHA256(self, mock_hmac): mock_m = mock.Mock() mock_m.digest = mock.Mock() mock_m.digest.return_value = 'digest' mock_hmac.return_value = mock_m ret = util.makeHMACSHA256('msg', 'key') mock_hmac.assert_called_once_with(msg='msg', key='key', digestmod=hashlib.sha256) self.assertEqual(ret, 'digest')