On Thu, Dec 19, 2019 at 12:19 PM Dmitry Vyukov <dvyukov@xxxxxxxxxx> wrote: > > Ahh, cool, okay. Netlink, device creation, and basic packet structure > > is a good start. What about the crypto, though? > > It depends. What exactly we need there? > syzkaller uses comparison operand interception which allows it e.g. to > guess signatures/checksums in some cases. I don't think you'll have too much luck with WireGuard here. Fuzzing your way to a valid handshake message involves guessing the 4th preimage of some elliptic curve scalar multiplication, with some random/changing data mixed in there every time you make a new try. There's a condensed protocol description here which should be less bad to glance at than the academic paper: https://www.wireguard.com/protocol/#first-message-initiator-to-responder . The fuzzers I've written for the crypto bits of WireGuard always involve taking a complete handshake implementation and mutating things from there. So maybe the "outer packet" won't be too fruitful without a bunch of work. At the very least, we can generate packets that have the right field sizes and such, and that should test the first level of error cases I guess. However, there's still a decent amount of surface on the "inner packet". For this, we can set up a pair of wireguard interfaces that are preconfigured to talk to each other (in common_linux.h, right? Or do you have some Go file that'd be easier to do that initialization in?), and then syzkaller will figure out itself how to send nasty IP packets through them with send/recv and such. There's a bit of surface here because sending packets provokes the aforementioned handshake, and also moves around the timer state machine. The receiver also needs to do some minimal parsing of the received packet to check "allowedips". So, good fodder for fuzzing.