Exemplo n.º 1
0
    def forward_response(self, response):
        self.last_interaction = time()

        # cut the padding off
        response, _ = cut(response, -CTR_MODE_PADDING)

        msg_type, response = cut(response, MSG_TYPE_FLAG_LEN)

        msg_ctr, _ = cut(response, CTR_PREFIX_LEN)

        # todo find better way
        if msg_ctr != bytes(CTR_PREFIX_LEN):
            self.response_replay_detector.check_replay_window(b2i(msg_ctr))

        self.response_counter.next()

        cipher = ctr_cipher(self.key, int(self.response_counter))

        forward_msg = cipher.encrypt(response)

        print(self, "Data", "<-", len(forward_msg))

        response = msg_type + i2b(self.in_chan_id, CHAN_ID_SIZE) + bytes(self.response_counter) + forward_msg

        ChannelMid.responses.append(response)
Exemplo n.º 2
0
def gen_init_msg(pub_mix_keys, channel_keys, payload):
    assert len(pub_mix_keys) == len(channel_keys)

    y_mix_1, y_mix_2, y_mix_3 = pub_mix_keys

    x_msg_1 = params.group.gensecret()
    y_msg_1 = params.group.expon_base([x_msg_1])
    k_disp_1 = params.group.expon(y_mix_1, [x_msg_1])
    blind_1 = gen_blind(k_disp_1)

    x_msg_2 = params.group.expon(x_msg_1, [blind_1])
    k_disp_2 = params.group.expon(y_mix_2, [x_msg_2])
    blind_2 = gen_blind(k_disp_2)

    x_msg_3 = params.group.expon(x_msg_2, [blind_2])
    k_disp_3 = params.group.expon(y_mix_3, [x_msg_3])

    chan_key_onion = gen_sym_key() * 3
    payload_onion = payload

    for k_disp, k_chan in zip([k_disp_3, k_disp_2, k_disp_1],
                              reversed(channel_keys)):
        cipher = ctr_cipher(params.get_aes_key(k_disp), 0)

        chan_key_onion = cipher.encrypt(k_chan +
                                        chan_key_onion[0:-SYM_KEY_LEN])

        payload_onion = cipher.encrypt(payload_onion)

    return y_msg_1.export() + chan_key_onion + payload_onion
Exemplo n.º 3
0
    def _encrypt_fragment(self, fragment):
        self.request_counter.next()

        for key in reversed(self.sym_keys):
            counter = self.request_counter

            cipher = ctr_cipher(key, int(counter))

            fragment = bytes(counter) + cipher.encrypt(fragment)

        return fragment
Exemplo n.º 4
0
    def _decrypt_fragment(self, fragment):
        ctr = 0

        for key in self.sym_keys:
            ctr, cipher_text = cut(fragment, CTR_PREFIX_LEN)

            ctr = b2i(ctr)

            cipher = ctr_cipher(key, ctr)

            fragment = cipher.decrypt(cipher_text)

        self.replay_detector.check_replay_window(ctr)

        return fragment
Exemplo n.º 5
0
def test_encrypt_fragment():
    channel = ChannelEntry(src_addr, dest_addr, public_keys)

    sym_key = gen_sym_key()
    channel.sym_keys = [sym_key] * MIX_COUNT

    fragment = FragmentGenerator(bytes(100)).get_data_fragment()

    packet1 = channel._encrypt_fragment(fragment)

    packet2 = fragment
    counter = 1

    for _ in range(MIX_COUNT):
        cipher = ctr_cipher(sym_key, counter)

        packet2 = i2b(counter, CTR_PREFIX_LEN) + cipher.encrypt(packet2)

    assert packet1 == packet2
Exemplo n.º 6
0
def process(priv_mix_key, message):
    y_msg, chan_key_onion, payload_onion = cut_init_message(message)

    k_disp = params.group.expon(y_msg, [priv_mix_key])

    cipher = ctr_cipher(params.get_aes_key(k_disp), 0)

    k_chan, chan_key_onion = cut(cipher.decrypt(chan_key_onion), SYM_KEY_LEN)

    chan_key_onion += gen_sym_key()

    payload_onion = cipher.decrypt(payload_onion)

    blind_1 = gen_blind(k_disp)
    y_msg_2 = params.group.expon(y_msg, [blind_1])

    message = y_msg_2.export() + chan_key_onion + payload_onion

    return k_chan, payload_onion, message
Exemplo n.º 7
0
def test_decrypt_fragment():
    channel = ChannelEntry(src_addr, dest_addr, public_keys)

    sym_key = gen_sym_key()
    channel.sym_keys = [sym_key] * MIX_COUNT

    fragment = FragmentGenerator(bytes(100)).get_data_fragment()

    fragment = channel._encrypt_fragment(fragment)

    packet1 = channel._decrypt_fragment(fragment)

    for _ in range(MIX_COUNT):
        msg_ctr, fragment = cut(fragment, CTR_PREFIX_LEN)

        cipher = ctr_cipher(sym_key, b2i(msg_ctr))

        fragment = cipher.decrypt(fragment)

    packet2 = fragment

    assert packet1 == packet2
Exemplo n.º 8
0
    def forward_request(self, request):
        """Takes a mix fragment, already stripped of the channel id."""
        self.last_interaction = time()

        ctr, cipher_text = cut(request, CTR_PREFIX_LEN)
        ctr = b2i(ctr)

        self.request_replay_detector.check_replay_window(ctr)

        cipher = ctr_cipher(self.key, ctr)

        forward_msg = cipher.decrypt(cipher_text) + get_random_bytes(CTR_MODE_PADDING)

        print(self, "Data", "->", len(forward_msg) - CTR_PREFIX_LEN)

        ChannelMid.requests.append(DATA_MSG_FLAG + i2b(self.out_chan_id, CHAN_ID_SIZE) + forward_msg)

        timed_out = check_for_timed_out_channels(ChannelMid.table_in)

        for in_id in timed_out:
            out_id = ChannelMid.table_in[in_id].out_chan_id

            del ChannelMid.table_in[in_id]
            del ChannelMid.table_out[out_id]