Skip to content

Latest commit

 

History

History

SipHash-tofino

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Tofino implementation of HalfSipHash

This directory hosts P4 implementation of the HalfSipHash keyed hash function on the Barefoot Tofino programmable switch. For more details, please refer to our paper: Secure Keyed Hashing on Programmable Switches (Published in SIGCOMM 2021 Workshop on Secure Programmable network INfrastructure (SPIN 2021)).

Compiling and running P4 code

You can compile the P4 code using Barefoot's P4 compiler: bf-p4c p4src/halfsiphash24_ingressegress.p4. Please be patient!

To run the P4 code using tofino-model:

  • p4-build.sh p4src/halfsiphash24_ingressegress.p4
  • $SDE/run_switchd.sh -p halfsiphash24_ingressegress
  • $SDE/run_tofino_model.sh -p halfsiphash24_ingressegress

By default, the program takes in a 16-byte input (as 4x 32-bit words). You can change the NUM_WORDS macro variable to change the hash function's input length.

Hash key

Currently, the hash key is encoded as part of the source code. You can add a P4 match-action table and specify a new key as the action data.

We note that the key is only used at the beginning of the hash calculation to initialize the internal state before any SipHash rounds. The C reference implementation performs one additional XOR to v2 and v3.

Usage

When receiving a UDP packet with destination port 5555 and a payload of 4*NUM_WORDS bytes, the P4 program calculates the payload's HalfSipHash-2-4 value and output it as the first 4 bytes of the payload, erasing other bytes.

You can run the following command in Scapy to send a test packet, with payload 0x000102030405060708090a0b0c0d0e0f: sendp(Ether()/IP()/UDP(sport=1234,dport=5555)/("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"), iface="veth0")

The switch will bounce back a UDP packet with the hash value and padding zeros to the same port. You can examine the output by running the following command in Scapy: sniff(iface="veth0",count=2)

Block and padding

The HalfSipHash calculation requires splitting input bytes into 32-bit (4-byte) words. For variable-length inputs, you must adjust the number of rounds based on input length, and add padding correctly to the last block, to prevent Length Extension attack. At the end of input bytes, you need to appends a byte encoding the message length modulo 256, and fill null bytes to the end of last word.

Citing

If you find this HalfSipHash implementation or the discussions in our paper useful, please consider citing:

@article{2021siphash,
    title={Secure Keyed Hashing on Programmable Switches},
    author={Yoo, Sophia and Chen, Xiaoqi},
    journal={ACM SIGCOMM 2021 Workshop on Secure Programmable Network Infrastructure (SPIN 2021)},
    year={2021},
    publisher={ACM}
}

License

Copyright 2021 Sophia Yoo, Xiaoqi Chen, Princeton University.

The project's source code are released here under the GNU Affero General Public License v3. In particular,

  • You are entitled to redistribute the program or its modified version, however you must also make available the full source code and a copy of the license to the recipient. Any modified version or derivative work must also be licensed under the same licensing terms.
  • You also must make available a copy of the modified program's source code available, under the same licensing terms, to all users interacting with the modified program remotely through a computer network.

(TL;DR: you should also open-source your derivative work's P4 source code under AGPLv3.)