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):
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.
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 thecase 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.