SpinalHDL / VexRiscv

A FPGA friendly 32 bit RISC-V CPU implementation
MIT License
2.52k stars 420 forks source link

Add Zkn variant of AES plugin #417

Closed bunnie closed 4 months ago

bunnie commented 4 months ago

Since the creation of the AES plugin, RV org has ratified the Zkn extension to the specification, which is the "NIST Algorithm suite extension".

I poked around a bit at this, and convinced myself that the AES implementation is actually compliant with the spec, but just with a different instruction coding.

This pull request adds a variation of the AES plugin that complies to the instruction coding in the Zkn extension. I originally thought to make it a flag to configure the existing AES plugin, but I couldn't figure out a way to pass an alternate MaskedLiteral argument to the case class Plugin(encoding: MaskedLiteral) extends Plugin[VexRiscv] statement. So, a duplicated implementation with an alternate encoding was the best I could do.

The overall changes are pretty minor, just shuffling some bit fields around and inverting the sense of one bit.

I have tested this against instructions emitted by Rust/llvm with a #[target_feature(enable = "zkn")] directive wrapping some assembly routines that are a direct port of the validation test bench provided by riscv-cryptography. The relevant test bench code can be seen here (just one routine as an example):

https://github.com/buncram/nto-tests/blob/39f21e4abe96f138cdf4407e9b443eacfa700d6c/tests/src/aes.rs#L229-L312

And the original RISCV-cryptography test bench can be seen here:

https://github.com/riscv/riscv-crypto/blob/ef1eeb9074e57d4e08d77d3db43dc345e354bc7f/benchmarks/aes/zscrypto_rv32/aes_256_ks.S#L41-L99

I only ran a few ECB-type test vectors but usually for cryptography if one case can pass, all of them pass. That being said, I did implement the test bench mixing my original code that worked with the previous AES instructions and the incoming risc-v testbench code to ensure I wasn't in some sort of isomorphic transformation (like a sign inversion that happens twice) that would cause the test bench to pass but not be cross-compatible between libraries.

Anyways, with this version, you can now use any compiler that emits the zkn extension instructions to create code for Vex-AES, instead of dedicated assembly thunks that code magic words.

Dolu1990 commented 4 months ago

Thanks :D

No worries for the code duplication. Having a "AesZknPlugin.scala" file also make it clearer.

Cheers Charles