Well this is slightly embarrassing. It turns out to be a very straightforward file format. There's a short header, followed by 32 byte C strings for the patch name, author, bank, and attributes, 280 bytes of unknown stuff that's mostly 0s, and then every parameter of the synth layer out as a single precision float, followed by a 32 byte C string for the parameter name and 32 byte text description of the value (though in many cases, this is an empty string).
Thanks to the Waldorf engineers for making this so straightforward!