summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/_start_here.txt9
-rw-r--r--doc/instructions.txt10
-rw-r--r--rvcontroller.lua270
3 files changed, 285 insertions, 4 deletions
diff --git a/doc/_start_here.txt b/doc/_start_here.txt
index bf83857..fe40724 100644
--- a/doc/_start_here.txt
+++ b/doc/_start_here.txt
@@ -5,7 +5,7 @@ RVController is a program for use in Luacontrollers (from the mesecons mod) in L
It emulates a single RISC-V hart and a configurable amount (64KiB default) of RAM.
Features:
-* RV32IMACBZicboz_Zicfilp_Zicntr_Zicond_Zicsr_Zifencei_Zihintpause_Zihpm_Zilsd_Zimop_Zabha_Zacas_Zalasr_Zawrs_Zcb_Zclsd_Zcmop_Zcmp_Zcmt_Zbc_Zbkb_Zbkc_Zbkx_Zknh_Zkr_Zksh_Xh3bextm_Xh3misa instruction set provides:
+* RV32IMACBZicboz_Zicfilp_Zicntr_Zicond_Zicsr_Zifencei_Zihintpause_Zihpm_Zilsd_Zimop_Zabha_Zacas_Zalasr_Zawrs_Zcb_Zclsd_Zcmop_Zcmp_Zcmt_Zbc_Zk_Zkr_Zks_Xh3bextm_Xh3misa instruction set provides:
- 32-bit address space
- 32 32-bit registers (31 general-purpose + 1 zero register)
- Selectable endianness
@@ -78,10 +78,17 @@ RVController is intended to be compliant with the following specifications:
* "Zawrs" Extension for Wait-on-Reservation-Set instructions, Version 1.01
* Zbkb: Extension for Bit-manipulation for Cryptography, Version 1.0.0
* Zbkx: Extension for Crossbar permutations, Version 1.0.0
+* Zknd - NIST Suite: AES Decryption, Version 1.0.1
+* Zkne - NIST Suite: AES Encryption, Version 1.0.1
* Zknh - NIST Suite: Hash Function, Version 1.0.1
+* Zksed - ShangMi Suite: SM4 Block Cipher Instructions, Version 1.0.1
* Zkr - Entropy Source Extension, Version 1.0.1
- Note: Virtual source, backed by Lua math.random(), 16 bits available per clock cycle
* Zksh - ShangMi Suite: SM3 Hash Function, Version 1.0.1
+* Zkn - NIST Algorithm Suite, Version 1.0.1
+* Zks - ShangMi Algorithm Suite, Version 1.0.1
+* Zk - Standard scalar cryptography extension, Version 1.0.1
+* Zkt - Data Independent Execution Latency, Version 1.0.1
* Zicfilp: Control Flow Integrity - Landing Pad
* Xh3misa: Hazard3 ISA identification register, Version 1.0
- Note: Defined in the Hazard3 reference manual, available at https://github.com/Wren6991/Hazard3/releases/download/v1.1/hazard3.pdf
diff --git a/doc/instructions.txt b/doc/instructions.txt
index 49d9147..a45bfc5 100644
--- a/doc/instructions.txt
+++ b/doc/instructions.txt
@@ -298,6 +298,16 @@ Zbkx: Extension for Crossbar permutations, Version 1.0.0
* xperm4 rd,rs1,rs2 | Crossbar permutation (nibbles)
* xperm8 rd,rs1,rs2 | Crossbar permutation (bytes)
+Zknd - NIST Suite: AES Decryption
+* aes32dsi rd,rs1,rs2,bs | AES final round decrypt
+* aes32dsmi rd,rs1,rs2,bs | AES middle round decrypt
+* aes32esi rd,rs1,rs2,bs | AES final round encrypt
+* aes32esmi rd,rs1,rs2,bs | AES middle round encrypt
+
+Zksed - ShangMi Suite: SM4 Block Cipher Instructions
+* sm4ed rd,rs1,rs2,bs | SM4 encrypt/decrypt
+* sm4ks rd,rs1,rs2,bs | SM4 key schedule
+
Zknh - NIST Suite: Hash Function
* sha256sig0 rd,rs1 | SHA2-256 Sigma0
* sha256sig1 rd,rs1 | SHA2-256 Sigma1
diff --git a/rvcontroller.lua b/rvcontroller.lua
index 73de551..aad6e99 100644
--- a/rvcontroller.lua
+++ b/rvcontroller.lua
@@ -513,10 +513,10 @@ local function readcsr(address)
true, --Zicond
false, --Zihintntl
true, --Zihintpause
- false, --Zknd
- false, --Zkne
+ true, --Zknd
+ true, --Zkne
true, --Zknh
- false, --Zksed
+ true, --Zksed
true, --Zksh
true, --Zkt
true, --Ztso
@@ -856,6 +856,129 @@ local cmpushpopreglists = {
[15] = {registers = {1,8,9,18,19,20,21,22,23,24,25,26,27},stack = 64},
}
+local aessboxfwd = {
+ [0] = 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, --00-0f
+ 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, --10-1f
+ 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, --20-2f
+ 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, --30-3f
+ 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, --40-4f
+ 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, --50-5f
+ 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, --60-6f
+ 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, --70-7f
+ 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, --80-8f
+ 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, --90-9f
+ 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, --a0-af
+ 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, --b0-bf
+ 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, --c0-cf
+ 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, --d0-df
+ 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, --e0-ef
+ 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16, --f0-ff
+}
+
+local aessboxinv = {
+ [0] = 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb, --00-0f
+ 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb, --10-1f
+ 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e, --20-2f
+ 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25, --30-3f
+ 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92, --40-4f
+ 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84, --50-5f
+ 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06, --60-6f
+ 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b, --70-7f
+ 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73, --80-8f
+ 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e, --90-9f
+ 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b, --a0-af
+ 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4, --b0-bf
+ 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f, --c0-cf
+ 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef, --d0-df
+ 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61, --e0-ef
+ 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d, --f0-ff
+}
+
+local sm4sbox = {
+ [0] = 0xD6,0x90,0xE9,0xFE,0xCC,0xE1,0x3D,0xB7,0x16,0xB6,0x14,0xC2,0x28,0xFB,0x2C,0x05, --00-0f
+ 0x2B,0x67,0x9A,0x76,0x2A,0xBE,0x04,0xC3,0xAA,0x44,0x13,0x26,0x49,0x86,0x06,0x99, --10-1f
+ 0x9C,0x42,0x50,0xF4,0x91,0xEF,0x98,0x7A,0x33,0x54,0x0B,0x43,0xED,0xCF,0xAC,0x62, --20-2f
+ 0xE4,0xB3,0x1C,0xA9,0xC9,0x08,0xE8,0x95,0x80,0xDF,0x94,0xFA,0x75,0x8F,0x3F,0xA6, --30-3f
+ 0x47,0x07,0xA7,0xFC,0xF3,0x73,0x17,0xBA,0x83,0x59,0x3C,0x19,0xE6,0x85,0x4F,0xA8, --40-4f
+ 0x68,0x6B,0x81,0xB2,0x71,0x64,0xDA,0x8B,0xF8,0xEB,0x0F,0x4B,0x70,0x56,0x9D,0x35, --50-5f
+ 0x1E,0x24,0x0E,0x5E,0x63,0x58,0xD1,0xA2,0x25,0x22,0x7C,0x3B,0x01,0x21,0x78,0x87, --60-6f
+ 0xD4,0x00,0x46,0x57,0x9F,0xD3,0x27,0x52,0x4C,0x36,0x02,0xE7,0xA0,0xC4,0xC8,0x9E, --70-7f
+ 0xEA,0xBF,0x8A,0xD2,0x40,0xC7,0x38,0xB5,0xA3,0xF7,0xF2,0xCE,0xF9,0x61,0x15,0xA1, --80-8f
+ 0xE0,0xAE,0x5D,0xA4,0x9B,0x34,0x1A,0x55,0xAD,0x93,0x32,0x30,0xF5,0x8C,0xB1,0xE3, --90-9f
+ 0x1D,0xF6,0xE2,0x2E,0x82,0x66,0xCA,0x60,0xC0,0x29,0x23,0xAB,0x0D,0x53,0x4E,0x6F, --a0-af
+ 0xD5,0xDB,0x37,0x45,0xDE,0xFD,0x8E,0x2F,0x03,0xFF,0x6A,0x72,0x6D,0x6C,0x5B,0x51, --b0-bf
+ 0x8D,0x1B,0xAF,0x92,0xBB,0xDD,0xBC,0x7F,0x11,0xD9,0x5C,0x41,0x1F,0x10,0x5A,0xD8, --c0-cf
+ 0x0A,0xC1,0x31,0x88,0xA5,0xCD,0x7B,0xBD,0x2D,0x74,0xD0,0x12,0xB8,0xE5,0xB4,0xB0, --d0-df
+ 0x89,0x69,0x97,0x4A,0x0C,0x96,0x77,0x7E,0x65,0xB9,0xF1,0x09,0xC5,0x6E,0xC6,0x84, --e0-ef
+ 0x18,0xF0,0x7D,0xEC,0x3A,0xDC,0x4D,0x20,0x79,0xEE,0x5F,0x3E,0xD7,0xCB,0x39,0x48, --f0-ff
+}
+
+local function aesxt2(inbits)
+ local outbits = {}
+ local xorbits = explodebits(0x1b,8)
+ for i=0,7 do
+ outbits[i] = inbits[i-1]
+ if inbits[7] and xorbits[i] then outbits[i] = not outbits[i] end
+ end
+ return outbits
+end
+
+local function aesgfmul(xbits,y)
+ local ybits = explodebits(y,8)
+ local outbits = {}
+ local xt2bits1 = aesxt2(xbits)
+ local xt2bits2 = aesxt2(xt2bits1)
+ local xt2bits3 = aesxt2(xt2bits2)
+ if ybits[0] then
+ for i=0,7 do outbits[i] = xbits[i] end
+ end
+ if ybits[1] then
+ for i=0,7 do
+ if xt2bits1[i] then outbits[i] = not outbits[i] end
+ end
+ end
+ if ybits[2] then
+ for i=0,7 do
+ if xt2bits2[i] then outbits[i] = not outbits[i] end
+ end
+ end
+ if ybits[3] then
+ for i=0,7 do
+ if xt2bits3[i] then outbits[i] = not outbits[i] end
+ end
+ end
+ return outbits
+end
+
+local function aesmixcolumnbytefwd(inbits)
+ local gfmul3bits = aesgfmul(inbits,3)
+ local gfmul2bits = aesgfmul(inbits,2)
+ local outbits = {}
+ for i=0,7 do
+ outbits[i] = gfmul2bits[i]
+ outbits[i+8] = inbits[i]
+ outbits[i+16] = inbits[i]
+ outbits[i+24] = gfmul3bits[i]
+ end
+ return outbits
+end
+
+local function aesmixcolumnbyteinv(inbits)
+ local gfmulbbits = aesgfmul(inbits,0xb)
+ local gfmuldbits = aesgfmul(inbits,0xd)
+ local gfmul9bits = aesgfmul(inbits,9)
+ local gfmulebits = aesgfmul(inbits,0xe)
+ local outbits = {}
+ for i=0,7 do
+ outbits[i] = gfmulebits[i]
+ outbits[i+8] = gfmul9bits[i]
+ outbits[i+16] = gfmuldbits[i]
+ outbits[i+24] = gfmulbbits[i]
+ end
+ return outbits
+end
+
+
local operations = {
add = function(rd,rs1,rs2)
setreg(rd,getreg(rs1)+getreg(rs2))
@@ -2341,6 +2464,133 @@ local operations = {
end
setreg(rd,implodebits(outputbits,32))
end,
+ aes32esi = function(rd,rs1,rs2,bs)
+ local in1bits = explodebits(getreg(rs1),32)
+ local in2bits = explodebits(getreg(rs2),32)
+ local si = {}
+ for i=0,7 do
+ si[i] = in2bits[bs*8+i]
+ end
+ si = implodebits(si,8)
+ local so = explodebits(aessboxfwd[si],8)
+ local outbits = {}
+ for i=0,7 do
+ outbits[bs*8+i] = so[i]
+ end
+ for i=0,31 do
+ if in1bits[i] then outbits[i] = not outbits[i] end
+ end
+ setreg(rd,implodebits(outbits,32))
+ end,
+ aes32esmi = function(rd,rs1,rs2,bs)
+ local in1bits = explodebits(getreg(rs1),32)
+ local in2bits = explodebits(getreg(rs2),32)
+ local si = {}
+ for i=0,7 do
+ si[i] = in2bits[i+(8*bs)]
+ end
+ si = implodebits(si,8)
+ local so = explodebits(aessboxfwd[si],8)
+ local mixedbits = aesmixcolumnbytefwd(so)
+ local outbits = {}
+ for i=0,31 do
+ local inpos = (bs*-8+i)%32
+ outbits[i] = mixedbits[inpos]
+ end
+ for i=0,31 do
+ if in1bits[i] then outbits[i] = not outbits[i] end
+ end
+ setreg(rd,implodebits(outbits,32))
+ end,
+ aes32dsi = function(rd,rs1,rs2,bs)
+ local in1bits = explodebits(getreg(rs1),32)
+ local in2bits = explodebits(getreg(rs2),32)
+ local si = {}
+ for i=0,7 do
+ si[i] = in2bits[bs*8+i]
+ end
+ si = implodebits(si,8)
+ local so = explodebits(aessboxinv[si],8)
+ local outbits = {}
+ for i=0,7 do
+ outbits[bs*8+i] = so[i]
+ end
+ for i=0,31 do
+ if in1bits[i] then outbits[i] = not outbits[i] end
+ end
+ setreg(rd,implodebits(outbits,32))
+ end,
+ aes32dsmi = function(rd,rs1,rs2,bs)
+ local in1bits = explodebits(getreg(rs1),32)
+ local in2bits = explodebits(getreg(rs2),32)
+ local si = {}
+ for i=0,7 do
+ si[i] = in2bits[i+(8*bs)]
+ end
+ si = implodebits(si,8)
+ local so = explodebits(aessboxinv[si],8)
+ local mixedbits = aesmixcolumnbyteinv(so)
+ local outbits = {}
+ for i=0,31 do
+ local inpos = (bs*-8+i)%32
+ outbits[i] = mixedbits[inpos]
+ end
+ for i=0,31 do
+ if in1bits[i] then outbits[i] = not outbits[i] end
+ end
+ setreg(rd,implodebits(outbits,32))
+ end,
+ sm4ed = function(rd,rs1,rs2,bs)
+ local in1bits = explodebits(getreg(rs1),32)
+ local in2bits = explodebits(getreg(rs2),32)
+ local si = {}
+ for i=0,7 do si[i] = in2bits[bs*8+i] end
+ local x = sm4sbox[implodebits(si,8)]
+ x = explodebits(x,8)
+ local y = {}
+ local a1 = explodebits(0x3f,8)
+ local a2 = explodebits(0xc0,8)
+ for i=0,31 do
+ y[i] = x[i]
+ if x[i-8] then y[i] = not y[i] end
+ if x[i-2] then y[i] = not y[i] end
+ if x[i-18] then y[i] = not y[i] end
+ if x[i-26] and a1[i-26] then y[i] = not y[i] end
+ if x[i-10] and a2[i-10] then y[i] = not y[i] end
+ end
+ local z = {}
+ for i=0,31 do
+ z[i] = y[(bs*-8+i)%32]
+ if in1bits[i] then z[i] = not z[i] end
+ end
+ setreg(rd,implodebits(z,32))
+ end,
+ sm4ks = function(rd,rs1,rs2,bs)
+ local in1bits = explodebits(getreg(rs1),32)
+ local in2bits = explodebits(getreg(rs2),32)
+ local si = {}
+ for i=0,7 do si[i] = in2bits[bs*8+i] end
+ local x = sm4sbox[implodebits(si,8)]
+ x = explodebits(x,8)
+ local y = {}
+ local a1 = explodebits(0x07,8)
+ local a2 = explodebits(0xfe,8)
+ local a3 = explodebits(0x01,8)
+ local a4 = explodebits(0xf8,8)
+ for i=0,31 do
+ y[i] = x[i]
+ if x[i-29] and a1[i-29] then y[i] = not y[i] end
+ if x[i-7] and a2[i-7] then y[i] = not y[i] end
+ if x[i-23] and a3[i-23] then y[i] = not y[i] end
+ if x[i-13] and a4[i-13] then y[i] = not y[i] end
+ end
+ local z = {}
+ for i=0,31 do
+ z[i] = y[(bs*-8+i)%32]
+ if in1bits[i] then z[i] = not z[i] end
+ end
+ setreg(rd,implodebits(z,32))
+ end,
}
local function runinst(instruction)
@@ -2361,6 +2611,8 @@ local function runinst(instruction)
local rs1 = implodebits(rs1bits,5)
local rs2bits = {[0] = bits[20],bits[21],bits[22],bits[23],bits[24]}
local rs2 = implodebits(rs2bits,5)
+ local f5 = f7%2^5
+ local bs = math.floor(f7/2^5)
if f3 == 0x0 and f7 == 0x0 then
operations.add(rd,rs1,rs2)
elseif f3 == 0x0 and f7 == 0x20 then
@@ -2377,6 +2629,18 @@ local function runinst(instruction)
operations.sha512sig0h(rd,rs1,rs2)
elseif f3 == 0x0 and f7 == 0x2f then
operations.sha512sig1h(rd,rs1,rs2)
+ elseif f3 == 0x0 and f5 == 0x11 then
+ operations.aes32esi(rd,rs1,rs2,bs)
+ elseif f3 == 0x0 and f5 == 0x13 then
+ operations.aes32esmi(rd,rs1,rs2,bs)
+ elseif f3 == 0x0 and f5 == 0x15 then
+ operations.aes32dsi(rd,rs1,rs2,bs)
+ elseif f3 == 0x0 and f5 == 0x17 then
+ operations.aes32dsmi(rd,rs1,rs2,bs)
+ elseif f3 == 0x0 and f5 == 0x18 then
+ operations.sm4ed(rd,rs1,rs2,bs)
+ elseif f3 == 0x0 and f5 == 0x1a then
+ operations.sm4ks(rd,rs1,rs2,bs)
elseif f3 == 0x4 and f7 == 0x0 then
operations.xor(rd,rs1,rs2)
elseif f3 == 0x6 and f7 == 0x0 then