diff options
| -rw-r--r-- | doc/_start_here.txt | 9 | ||||
| -rw-r--r-- | doc/instructions.txt | 10 | ||||
| -rw-r--r-- | rvcontroller.lua | 270 |
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 |
