mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8371968: RISC-V: implement AES CBC intrinsics
Reviewed-by: fyang, fjiang
This commit is contained in:
parent
d36a234c12
commit
a5968f9364
@ -2606,6 +2606,184 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
void cipherBlockChaining_encryptAESCrypt(int round, Register from, Register to, Register key,
|
||||
Register rvec, Register input_len) {
|
||||
const Register len = x29;
|
||||
|
||||
VectorRegister working_vregs[] = {
|
||||
v1, v2, v3, v4, v5, v6, v7, v8,
|
||||
v9, v10, v11, v12, v13, v14, v15
|
||||
};
|
||||
|
||||
const unsigned int BLOCK_SIZE = 16;
|
||||
|
||||
__ mv(len, input_len);
|
||||
// load init rvec
|
||||
__ vsetivli(x0, 4, Assembler::e32, Assembler::m1);
|
||||
__ vle32_v(v16, rvec);
|
||||
|
||||
generate_aes_loadkeys(key, working_vregs, round);
|
||||
Label L_enc_loop;
|
||||
__ bind(L_enc_loop);
|
||||
// Encrypt from source by block size
|
||||
__ vle32_v(v17, from);
|
||||
__ addi(from, from, BLOCK_SIZE);
|
||||
__ vxor_vv(v16, v16, v17);
|
||||
generate_aes_encrypt(v16, working_vregs, round);
|
||||
__ vse32_v(v16, to);
|
||||
__ addi(to, to, BLOCK_SIZE);
|
||||
__ subi(len, len, BLOCK_SIZE);
|
||||
__ bnez(len, L_enc_loop);
|
||||
|
||||
// save current rvec and return
|
||||
__ vse32_v(v16, rvec);
|
||||
__ mv(x10, input_len);
|
||||
__ leave();
|
||||
__ ret();
|
||||
}
|
||||
|
||||
// Arguments:
|
||||
//
|
||||
// Inputs:
|
||||
// c_rarg0 - source byte array address
|
||||
// c_rarg1 - destination byte array address
|
||||
// c_rarg2 - K (key) in little endian int array
|
||||
// c_rarg3 - r vector byte array address
|
||||
// c_rarg4 - input length
|
||||
//
|
||||
// Output:
|
||||
// x10 - input length
|
||||
//
|
||||
address generate_cipherBlockChaining_encryptAESCrypt() {
|
||||
assert(UseAESIntrinsics, "Must be");
|
||||
assert(UseZvkn, "need AES instructions (Zvkned extension) support");
|
||||
__ align(CodeEntryAlignment);
|
||||
StubId stub_id = StubId::stubgen_cipherBlockChaining_encryptAESCrypt_id;
|
||||
StubCodeMark mark(this, stub_id);
|
||||
|
||||
const Register from = c_rarg0;
|
||||
const Register to = c_rarg1;
|
||||
const Register key = c_rarg2;
|
||||
const Register rvec = c_rarg3;
|
||||
const Register input_len = c_rarg4;
|
||||
|
||||
const Register keylen = x28;
|
||||
|
||||
address start = __ pc();
|
||||
__ enter();
|
||||
|
||||
Label L_aes128, L_aes192;
|
||||
// Compute #rounds for AES based on the length of the key array
|
||||
__ lwu(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
|
||||
__ mv(t0, 52);
|
||||
__ bltu(keylen, t0, L_aes128);
|
||||
__ beq(keylen, t0, L_aes192);
|
||||
// Else we fallthrough to the biggest case (256-bit key size)
|
||||
|
||||
// Note: the following function performs key += 15*16
|
||||
cipherBlockChaining_encryptAESCrypt(15, from, to, key, rvec, input_len);
|
||||
|
||||
// Note: the following function performs key += 11*16
|
||||
__ bind(L_aes128);
|
||||
cipherBlockChaining_encryptAESCrypt(11, from, to, key, rvec, input_len);
|
||||
|
||||
// Note: the following function performs key += 13*16
|
||||
__ bind(L_aes192);
|
||||
cipherBlockChaining_encryptAESCrypt(13, from, to, key, rvec, input_len);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
void cipherBlockChaining_decryptAESCrypt(int round, Register from, Register to, Register key,
|
||||
Register rvec, Register input_len) {
|
||||
const Register len = x29;
|
||||
|
||||
VectorRegister working_vregs[] = {
|
||||
v1, v2, v3, v4, v5, v6, v7, v8,
|
||||
v9, v10, v11, v12, v13, v14, v15
|
||||
};
|
||||
|
||||
const unsigned int BLOCK_SIZE = 16;
|
||||
|
||||
__ mv(len, input_len);
|
||||
// load init rvec
|
||||
__ vsetivli(x0, 4, Assembler::e32, Assembler::m1);
|
||||
__ vle32_v(v16, rvec);
|
||||
|
||||
generate_aes_loadkeys(key, working_vregs, round);
|
||||
Label L_dec_loop;
|
||||
// Decrypt from source by block size
|
||||
__ bind(L_dec_loop);
|
||||
__ vle32_v(v17, from);
|
||||
__ addi(from, from, BLOCK_SIZE);
|
||||
__ vmv_v_v(v18, v17);
|
||||
generate_aes_decrypt(v17, working_vregs, round);
|
||||
__ vxor_vv(v17, v17, v16);
|
||||
__ vse32_v(v17, to);
|
||||
__ vmv_v_v(v16, v18);
|
||||
__ addi(to, to, BLOCK_SIZE);
|
||||
__ subi(len, len, BLOCK_SIZE);
|
||||
__ bnez(len, L_dec_loop);
|
||||
|
||||
// save current rvec and return
|
||||
__ vse32_v(v16, rvec);
|
||||
__ mv(x10, input_len);
|
||||
__ leave();
|
||||
__ ret();
|
||||
}
|
||||
|
||||
// Arguments:
|
||||
//
|
||||
// Inputs:
|
||||
// c_rarg0 - source byte array address
|
||||
// c_rarg1 - destination byte array address
|
||||
// c_rarg2 - K (key) in little endian int array
|
||||
// c_rarg3 - r vector byte array address
|
||||
// c_rarg4 - input length
|
||||
//
|
||||
// Output:
|
||||
// x10 - input length
|
||||
//
|
||||
address generate_cipherBlockChaining_decryptAESCrypt() {
|
||||
assert(UseAESIntrinsics, "Must be");
|
||||
assert(UseZvkn, "need AES instructions (Zvkned extension) support");
|
||||
__ align(CodeEntryAlignment);
|
||||
StubId stub_id = StubId::stubgen_cipherBlockChaining_decryptAESCrypt_id;
|
||||
StubCodeMark mark(this, stub_id);
|
||||
|
||||
const Register from = c_rarg0;
|
||||
const Register to = c_rarg1;
|
||||
const Register key = c_rarg2;
|
||||
const Register rvec = c_rarg3;
|
||||
const Register input_len = c_rarg4;
|
||||
|
||||
const Register keylen = x28;
|
||||
|
||||
address start = __ pc();
|
||||
__ enter();
|
||||
|
||||
Label L_aes128, L_aes192, L_aes128_loop, L_aes192_loop, L_aes256_loop;
|
||||
// Compute #rounds for AES based on the length of the key array
|
||||
__ lwu(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
|
||||
__ mv(t0, 52);
|
||||
__ bltu(keylen, t0, L_aes128);
|
||||
__ beq(keylen, t0, L_aes192);
|
||||
// Else we fallthrough to the biggest case (256-bit key size)
|
||||
|
||||
// Note: the following function performs key += 15*16
|
||||
cipherBlockChaining_decryptAESCrypt(15, from, to, key, rvec, input_len);
|
||||
|
||||
// Note: the following function performs key += 11*16
|
||||
__ bind(L_aes128);
|
||||
cipherBlockChaining_decryptAESCrypt(11, from, to, key, rvec, input_len);
|
||||
|
||||
// Note: the following function performs key += 13*16
|
||||
__ bind(L_aes192);
|
||||
cipherBlockChaining_decryptAESCrypt(13, from, to, key, rvec, input_len);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// Load big-endian 128-bit from memory.
|
||||
void be_load_counter_128(Register counter_hi, Register counter_lo, Register counter) {
|
||||
__ ld(counter_lo, Address(counter, 8)); // Load 128-bits from counter
|
||||
@ -2772,8 +2950,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// x10 - input length
|
||||
//
|
||||
address generate_counterMode_AESCrypt() {
|
||||
assert(UseAESCTRIntrinsics, "Must be");
|
||||
assert(UseZvkn, "need AES instructions (Zvkned extension) support");
|
||||
assert(UseAESCTRIntrinsics, "need AES instructions (Zvkned extension) support");
|
||||
assert(UseZbb, "need basic bit manipulation (Zbb extension) support");
|
||||
|
||||
__ align(CodeEntryAlignment);
|
||||
@ -7041,6 +7219,8 @@ static const int64_t right_3_bits = right_n_bits(3);
|
||||
if (UseAESIntrinsics) {
|
||||
StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
|
||||
StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock();
|
||||
StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
|
||||
StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt();
|
||||
}
|
||||
|
||||
if (UseAESCTRIntrinsics) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user