-
Notifications
You must be signed in to change notification settings - Fork 84
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Start work on formal model for the crypto extension. - Committed code contains an implementation of the scalar 32-bit instructions. - Split into two files: the 32-bit instructions and a common types and utility functions file. - See issue #20 On branch dev/sail Changes to be committed: new file: sail/riscv_crypto_types.sail new file: sail/riscv_insts_crypto_rv32.sail Changes not staged for commit: modified: extern/riscv-gnu-toolchain (modified content) modified: extern/riscv-isa-sim (modified content)
- Loading branch information
1 parent
86e3919
commit f6c6641
Showing
2 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
|
||
/* | ||
* file: riscv_crypto_types.sail | ||
* | ||
* This file contains types, mappings and functions used across the | ||
* cryptography extension instructions. | ||
* | ||
*/ | ||
|
||
/* | ||
* Cryptography extension types. | ||
* ---------------------------------------------------------------------- | ||
*/ | ||
|
||
/* Byte shift parameter for scalar 32-bit aes instructions */ | ||
type saes_bs = bits(2) | ||
|
||
/* Scalar AES round instruction operations. Used for 32,64-bit versions */ | ||
enum saes_op = { | ||
ENCS, ENCSM, DECS, DECSM | ||
} | ||
|
||
/* Map between f5 encoding field and scalar round function instrucitons. */ | ||
mapping encdec_saes32_op : saes_op <-> bits(5) = { | ||
ENCSM <-> 0b00000, | ||
ENCS <-> 0b00001, | ||
DECSM <-> 0b00010, | ||
DECS <-> 0b00011 | ||
} | ||
|
||
/* Map 32-bit operations to assembly mnemonics - for disassemly */ | ||
mapping saes32_op_to_mnemonic : saes_op <-> string = { | ||
ENCSM <-> "saes32.encsm" , | ||
ENCS <-> "saes32.encs" , | ||
DECSM <-> "saes32.decsm" , | ||
DECS <-> "saes32.decs" | ||
} | ||
|
||
/* Map byte shift amounts to strings - for disassemly */ | ||
val saes32_bs_to_str : saes_bs <-> string | ||
mapping saes32_bs_to_str : saes_bs <-> string = { | ||
0b00 <-> "0", | ||
0b01 <-> "1", | ||
0b10 <-> "2", | ||
0b11 <-> "3" | ||
} | ||
|
||
/* Map scalar instruction round function ops to whether they enc or dec? */ | ||
mapping saes_op_to_enc : saes_op <-> bool = { | ||
ENCSM <-> true , | ||
ENCS <-> true , | ||
DECSM <-> false , | ||
DECS <-> false | ||
} | ||
|
||
/* Map scalar instruction round function ops to whether they perform mix? */ | ||
mapping saes_op_to_mix : saes_op <-> bool = { | ||
ENCSM <-> true , | ||
ENCS <-> false , | ||
DECSM <-> true , | ||
DECS <-> false | ||
} | ||
|
||
|
||
/* | ||
* Cryptography extension shared / utility functions | ||
* ---------------------------------------------------------------------- | ||
*/ | ||
|
||
/* Auxiliary function for performing GF multiplicaiton */ | ||
val xt2 : bits(8) -> bits(8) | ||
function xt2 (x) = { | ||
(x << 1) ^ ( match (bit_to_bool(x[7]) ) { | ||
false => 0x00, | ||
true => 0x1B | ||
}) | ||
} | ||
|
||
/* Multiply 8-bit field element by 4-bit value for AES MixCols step */ | ||
val gfmul : (bits(8), bits(8)) -> bits(8) | ||
function gfmul( x, y) = { | ||
(if(bit_to_bool(y[0])) then x else 0x00) ^ | ||
(if(bit_to_bool(y[1])) then xt2( x) else 0x00) ^ | ||
(if(bit_to_bool(y[2])) then xt2(xt2( x)) else 0x00) ^ | ||
(if(bit_to_bool(y[3])) then xt2(xt2(xt2(x))) else 0x00) | ||
} | ||
|
||
|
||
/* Multiply aes byte shift encoding by eight to get actual shift amount. | ||
* - Translate to 6-bit value since we need to perform "32-shamt" for | ||
* the rotate operation at the end of the 32-bit instructions, and | ||
* the type checker isn't happy about mixing 5/6 bit ops | ||
*/ | ||
val aes_bs_to_shamt : bits(2) <-> bits(6) | ||
mapping aes_bs_to_shamt : bits(2) <-> bits(6) = { | ||
0b00 <-> 0b000000, | ||
0b01 <-> 0b001000, | ||
0b10 <-> 0b010000, | ||
0b11 <-> 0b011000 | ||
} | ||
|
||
/* AES SBox - forwards */ | ||
let aes_sbox_fwd_table : list(bits(8)) = [| | ||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, | ||
0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, | ||
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, | ||
0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, | ||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, | ||
0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, | ||
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, | ||
0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, | ||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, | ||
0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, | ||
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, | ||
0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, | ||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, | ||
0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, | ||
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, | ||
0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, | ||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, | ||
0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, | ||
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, | ||
0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, | ||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, | ||
0xb0, 0x54, 0xbb, 0x16 | ||
|] | ||
|
||
/* AES SBox - Inverse */ | ||
let aes_sbox_inv_table : list(bits(8)) = [| | ||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, | ||
0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, | ||
0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, | ||
0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, | ||
0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, | ||
0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, | ||
0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, | ||
0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, | ||
0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, | ||
0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, | ||
0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, | ||
0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, | ||
0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, | ||
0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, | ||
0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, | ||
0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, | ||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, | ||
0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, | ||
0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, | ||
0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d | ||
|] | ||
|
||
|
||
/* Lookup function - takes an index and a list, and retrieves the | ||
* x'th element of that list. | ||
*/ | ||
val aes_sbox_lookup : (bits(8), list(bits(8))) -> bits(8) | ||
function aes_sbox_lookup (x, table) = { | ||
match (x, table) { | ||
(0x00, t0::tn) => t0, | ||
( y , t0::tn) => aes_sbox_lookup(x - 0x01,tn) | ||
} | ||
} | ||
|
||
/* Easy function to perform a forward AES SBox operation on 1 byte. */ | ||
val aes_sbox_fwd : bits(8) -> bits(8) | ||
function aes_sbox_fwd (x) = { | ||
aes_sbox_lookup(x, aes_sbox_fwd_table) | ||
} | ||
|
||
/* Easy function to perform an inverse AES SBox operation on 1 byte. */ | ||
val aes_sbox_inv : bits(8) -> bits(8) | ||
function aes_sbox_inv (x) = { | ||
aes_sbox_lookup(x, aes_sbox_inv_table) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
|
||
/* | ||
* file: riscv_insts_crypto_rv32.sail | ||
* | ||
* This file contains the 32-bit specific cryptography extension | ||
* instructions. | ||
* | ||
*/ | ||
|
||
/* | ||
* Scalar Cryptography Extension - Scalar 32-bit AES instructions | ||
* ---------------------------------------------------------------------- | ||
*/ | ||
|
||
union clause ast = SAES32 : (saes_bs, regidx, regidx, regidx, saes_op) | ||
|
||
|
||
/* Encrypt/Decrypt mapping for 32-bit scalar AES instructions. */ | ||
mapping clause encdec = SAES32 (saes_bs, rs2 , rs1 , rd , op ) | ||
<-> saes_bs @ encdec_saes32_op(op) @ rs2 @ rs1 @ 0b010 @ rd @ 0b0101011 | ||
|
||
|
||
/* Map between an AST representation of SAES32 and a disassembly string. */ | ||
mapping clause assembly = SAES32 ( bs, rs2 , rs1 , rd , op ) | ||
<-> saes32_op_to_mnemonic(op) ^ spc() ^ | ||
reg_name(rd) ^ sep() ^ | ||
reg_name(rs1) ^ sep() ^ | ||
reg_name(rs2) ^ sep() ^ | ||
saes32_bs_to_str(bs) | ||
|
||
|
||
/* Execute the scalar 32-bit AES instructions. | ||
* - op : The exact instruciton variant to perform. | ||
* - rd : Destination register address | ||
* - rs1: Source register 1 address | ||
* - rs2: Source register 2 address | ||
* - bs : 2-bit byte shift. | ||
*/ | ||
function clause execute (SAES32 ( bs, rs2 , rs1 , rd , op))={ | ||
let rs1_val : xlenbits = X(rs1); | ||
let rs2_val : xlenbits = X(rs2); | ||
let shamt : bits(6) = aes_bs_to_shamt(bs); | ||
let sb_in : bits(8) = (rs2_val >>shamt)[7..0]; | ||
let sb_out : bits(8) = | ||
if (saes_op_to_enc(op)) then aes_sbox_fwd(sb_in) | ||
else aes_sbox_inv(sb_in) | ||
; | ||
let mixed : xlenbits = | ||
if(saes_op_to_mix(op)) then | ||
if(saes_op_to_enc(op)) then | ||
gfmul(sb_out, 0x03) @ sb_out @ | ||
sb_out @ gfmul(sb_out, 0x02) | ||
else | ||
gfmul(sb_out, 0x0b) @ gfmul(sb_out, 0x0d) @ | ||
gfmul(sb_out, 0x09) @ gfmul(sb_out, 0x0e) | ||
else | ||
0x000000 @ sb_out | ||
; | ||
let rotated: xlenbits = (mixed << shamt) ^ (mixed >> (0b100000-shamt)); | ||
X(rd) = rotated ^ rs1_val; | ||
RETIRE_SUCCESS | ||
} | ||
|
||
/* | ||
* Scalar Cryptography Extension - Scalar 32-bit SHA2 instructions | ||
* ---------------------------------------------------------------------- | ||
*/ | ||
|
||
|
||
/* TBD */ | ||
|
||
|
||
/* | ||
* Scalar Cryptography Extension - Scalar SM3 instructions | ||
* ---------------------------------------------------------------------- | ||
*/ | ||
|
||
|
||
/* TBD */ | ||
|
||
|
||
/* | ||
* Scalar Cryptography Extension - Scalar SM4 instructions | ||
* ---------------------------------------------------------------------- | ||
*/ | ||
|
||
|
||
/* TBD */ | ||
|