# HG changeset patch # User fyang # Date 1598689018 -28800 # Sat Aug 29 16:16:58 2020 +0800 # Node ID 33e8ee99a3eeedea36980afa1abe1dc1b0775c2c # Parent 02a6f02e70dfa5a34d60426562da1404f6aad572 8252204: AArch64: Implement SHA3 accelerator/intrinsic Reviewed-by: duke Contributed-by: dongbo4@huawei.com diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp @@ -2402,6 +2402,40 @@ #undef INSN +#define INSN(NAME, opc) \ + void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm, FloatRegister Va) { \ + starti; \ + assert(T == T16B, "arrangement must be T16B"); \ + f(0b11001110, 31, 24), f(opc, 23, 21), rf(Vm, 16), f(0b0, 15, 15), rf(Va, 10), rf(Vn, 5), rf(Vd, 0); \ + } + + INSN(eor3, 0b000); + INSN(bcax, 0b001); + +#undef INSN + +#define INSN(NAME, opc) \ + void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm, unsigned imm) { \ + starti; \ + assert(T == T2D, "arrangement must be T2D"); \ + f(0b11001110, 31, 24), f(opc, 23, 21), rf(Vm, 16), f(imm, 15, 10), rf(Vn, 5), rf(Vd, 0); \ + } + + INSN(xar, 0b100); + +#undef INSN + +#define INSN(NAME, opc) \ + void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \ + starti; \ + assert(T == T2D, "arrangement must be T2D"); \ + f(0b11001110, 31, 24), f(opc, 23, 21), rf(Vm, 16), f(0b100011, 15, 10), rf(Vn, 5), rf(Vd, 0); \ + } + + INSN(rax1, 0b011); + +#undef INSN + #define INSN(NAME, opc) \ void NAME(FloatRegister Vd, FloatRegister Vn) { \ starti; \ diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -3291,6 +3291,225 @@ return start; } + // Arguments: + // + // Inputs: + // c_rarg0 - byte[] source+offset + // c_rarg1 - byte[] SHA.state + // c_rarg2 - int digest_length + // c_rarg3 - int offset + // c_rarg4 - int limit + // + address generate_sha3_implCompress(bool multi_block, const char *name) { + static const uint64_t round_consts[24] = { + 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, + 0x8000000080008000L, 0x000000000000808BL, 0x0000000080000001L, + 0x8000000080008081L, 0x8000000000008009L, 0x000000000000008AL, + 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL, + 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, + 0x8000000000008003L, 0x8000000000008002L, 0x8000000000000080L, + 0x000000000000800AL, 0x800000008000000AL, 0x8000000080008081L, + 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L + }; + + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", name); + address start = __ pc(); + + Register buf = c_rarg0; + Register state = c_rarg1; + Register digest_length = c_rarg2; + Register ofs = c_rarg3; + Register limit = c_rarg4; + + Label sha3_loop, rounds24_loop; + Label sha3_512, sha3_384_or_224, sha3_256; + + __ stpd(v8, v9, __ pre(sp, -64)); + __ stpd(v10, v11, Address(sp, 16)); + __ stpd(v12, v13, Address(sp, 32)); + __ stpd(v14, v15, Address(sp, 48)); + + // load state + __ add(rscratch1, state, 32); + __ ld1(v0, v1, v2, v3, __ T1D, state); + __ ld1(v4, v5, v6, v7, __ T1D, __ post(rscratch1, 32)); + __ ld1(v8, v9, v10, v11, __ T1D, __ post(rscratch1, 32)); + __ ld1(v12, v13, v14, v15, __ T1D, __ post(rscratch1, 32)); + __ ld1(v16, v17, v18, v19, __ T1D, __ post(rscratch1, 32)); + __ ld1(v20, v21, v22, v23, __ T1D, __ post(rscratch1, 32)); + __ ld1(v24, __ T1D, rscratch1); + + __ BIND(sha3_loop); + + // 24 keccak rounds + __ movw(rscratch2, 24); + + // load round_constants base + __ lea(rscratch1, ExternalAddress((address) round_consts)); + + // load input + __ ld1(v25, v26, v27, v28, __ T8B, __ post(buf, 32)); + __ ld1(v29, v30, v31, __ T8B, __ post(buf, 24)); + __ eor(v0, __ T8B, v0, v25); + __ eor(v1, __ T8B, v1, v26); + __ eor(v2, __ T8B, v2, v27); + __ eor(v3, __ T8B, v3, v28); + __ eor(v4, __ T8B, v4, v29); + __ eor(v5, __ T8B, v5, v30); + __ eor(v6, __ T8B, v6, v31); + + // digest_length == 64, SHA3-512 + __ tbnz(digest_length, 6, sha3_512); + + __ ld1(v25, v26, v27, v28, __ T8B, __ post(buf, 32)); + __ ld1(v29, v30, __ T8B, __ post(buf, 16)); + __ eor(v7, __ T8B, v7, v25); + __ eor(v8, __ T8B, v8, v26); + __ eor(v9, __ T8B, v9, v27); + __ eor(v10, __ T8B, v10, v28); + __ eor(v11, __ T8B, v11, v29); + __ eor(v12, __ T8B, v12, v30); + + // digest_length == 28, SHA3-224; digest_length == 48, SHA3-384 + __ tbnz(digest_length, 4, sha3_384_or_224); + + // SHA3-256 + __ ld1(v25, v26, v27, v28, __ T8B, __ post(buf, 32)); + __ eor(v13, __ T8B, v13, v25); + __ eor(v14, __ T8B, v14, v26); + __ eor(v15, __ T8B, v15, v27); + __ eor(v16, __ T8B, v16, v28); + __ b(rounds24_loop); + + __ BIND(sha3_384_or_224); + __ tbz(digest_length, 2, rounds24_loop); // bit 2 cleared? SHA-384 + + // SHA3-224 + __ ld1(v25, v26, v27, v28, __ T8B, __ post(buf, 32)); + __ ld1(v29, __ T8B, __ post(buf, 8)); + __ eor(v13, __ T8B, v13, v25); + __ eor(v14, __ T8B, v14, v26); + __ eor(v15, __ T8B, v15, v27); + __ eor(v16, __ T8B, v16, v28); + __ eor(v17, __ T8B, v17, v29); + __ b(rounds24_loop); + + __ BIND(sha3_512); + __ ld1(v25, v26, __ T8B, __ post(buf, 16)); + __ eor(v7, __ T8B, v7, v25); + __ eor(v8, __ T8B, v8, v26); + + __ BIND(rounds24_loop); + __ subw(rscratch2, rscratch2, 1); + + __ eor3(v29, __ T16B, v4, v9, v14); + __ eor3(v26, __ T16B, v1, v6, v11); + __ eor3(v28, __ T16B, v3, v8, v13); + __ eor3(v25, __ T16B, v0, v5, v10); + __ eor3(v27, __ T16B, v2, v7, v12); + __ eor3(v29, __ T16B, v29, v19, v24); + __ eor3(v26, __ T16B, v26, v16, v21); + __ eor3(v28, __ T16B, v28, v18, v23); + __ eor3(v25, __ T16B, v25, v15, v20); + __ eor3(v27, __ T16B, v27, v17, v22); + + __ rax1(v30, __ T2D, v29, v26); + __ rax1(v26, __ T2D, v26, v28); + __ rax1(v28, __ T2D, v28, v25); + __ rax1(v25, __ T2D, v25, v27); + __ rax1(v27, __ T2D, v27, v29); + + __ eor(v0, __ T16B, v0, v30); + __ xar(v29, __ T2D, v1, v25, (64 - 1)); + __ xar(v1, __ T2D, v6, v25, (64 - 44)); + __ xar(v6, __ T2D, v9, v28, (64 - 20)); + __ xar(v9, __ T2D, v22, v26, (64 - 61)); + __ xar(v22, __ T2D, v14, v28, (64 - 39)); + __ xar(v14, __ T2D, v20, v30, (64 - 18)); + __ xar(v31, __ T2D, v2, v26, (64 - 62)); + __ xar(v2, __ T2D, v12, v26, (64 - 43)); + __ xar(v12, __ T2D, v13, v27, (64 - 25)); + __ xar(v13, __ T2D, v19, v28, (64 - 8)); + __ xar(v19, __ T2D, v23, v27, (64 - 56)); + __ xar(v23, __ T2D, v15, v30, (64 - 41)); + __ xar(v15, __ T2D, v4, v28, (64 - 27)); + __ xar(v28, __ T2D, v24, v28, (64 - 14)); + __ xar(v24, __ T2D, v21, v25, (64 - 2)); + __ xar(v8, __ T2D, v8, v27, (64 - 55)); + __ xar(v4, __ T2D, v16, v25, (64 - 45)); + __ xar(v16, __ T2D, v5, v30, (64 - 36)); + __ xar(v5, __ T2D, v3, v27, (64 - 28)); + __ xar(v27, __ T2D, v18, v27, (64 - 21)); + __ xar(v3, __ T2D, v17, v26, (64 - 15)); + __ xar(v25, __ T2D, v11, v25, (64 - 10)); + __ xar(v26, __ T2D, v7, v26, (64 - 6)); + __ xar(v30, __ T2D, v10, v30, (64 - 3)); + + __ bcax(v20, __ T16B, v31, v22, v8); + __ bcax(v21, __ T16B, v8, v23, v22); + __ bcax(v22, __ T16B, v22, v24, v23); + __ bcax(v23, __ T16B, v23, v31, v24); + __ bcax(v24, __ T16B, v24, v8, v31); + + __ ld1r(v31, __ T2D, __ post(rscratch1, 8)); + + __ bcax(v17, __ T16B, v25, v19, v3); + __ bcax(v18, __ T16B, v3, v15, v19); + __ bcax(v19, __ T16B, v19, v16, v15); + __ bcax(v15, __ T16B, v15, v25, v16); + __ bcax(v16, __ T16B, v16, v3, v25); + + __ bcax(v10, __ T16B, v29, v12, v26); + __ bcax(v11, __ T16B, v26, v13, v12); + __ bcax(v12, __ T16B, v12, v14, v13); + __ bcax(v13, __ T16B, v13, v29, v14); + __ bcax(v14, __ T16B, v14, v26, v29); + + __ bcax(v7, __ T16B, v30, v9, v4); + __ bcax(v8, __ T16B, v4, v5, v9); + __ bcax(v9, __ T16B, v9, v6, v5); + __ bcax(v5, __ T16B, v5, v30, v6); + __ bcax(v6, __ T16B, v6, v4, v30); + + __ bcax(v3, __ T16B, v27, v0, v28); + __ bcax(v4, __ T16B, v28, v1, v0); + __ bcax(v0, __ T16B, v0, v2, v1); + __ bcax(v1, __ T16B, v1, v27, v2); + __ bcax(v2, __ T16B, v2, v28, v27); + + __ eor(v0, __ T16B, v0, v31); + + __ cbnzw(rscratch2, rounds24_loop); + + if (multi_block) { + // block_size = 200 - 2 * digest_length, ofs += block_size + __ add(ofs, ofs, 200); + __ sub(ofs, ofs, digest_length, Assembler::LSL, 1); + + __ cmp(ofs, limit); + __ br(Assembler::LE, sha3_loop); + __ mov(c_rarg0, ofs); // return ofs + } + + __ st1(v0, v1, v2, v3, __ T1D, __ post(state, 32)); + __ st1(v4, v5, v6, v7, __ T1D, __ post(state, 32)); + __ st1(v8, v9, v10, v11, __ T1D, __ post(state, 32)); + __ st1(v12, v13, v14, v15, __ T1D, __ post(state, 32)); + __ st1(v16, v17, v18, v19, __ T1D, __ post(state, 32)); + __ st1(v20, v21, v22, v23, __ T1D, __ post(state, 32)); + __ st1(v24, __ T1D, state); + + __ ldpd(v14, v15, Address(sp, 48)); + __ ldpd(v12, v13, Address(sp, 32)); + __ ldpd(v10, v11, Address(sp, 16)); + __ ldpd(v8, v9, __ post(sp, 64)); + + __ ret(lr); + + return start; + } + // Safefetch stubs. void generate_safefetch(const char* name, int size, address* entry, address* fault_pc, address* continuation_pc) { @@ -6022,6 +6241,10 @@ StubRoutines::_sha512_implCompress = generate_sha512_implCompress(false, "sha512_implCompress"); StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(true, "sha512_implCompressMB"); } + if (UseSHA3Intrinsics) { + StubRoutines::_sha3_implCompress = generate_sha3_implCompress(false, "sha3_implCompress"); + StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(true, "sha3_implCompressMB"); + } // generate Adler32 intrinsics code if (UseAdler32Intrinsics) { diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -67,6 +67,10 @@ #define HWCAP_SHA512 (1 << 21) #endif +#ifndef HWCAP_SHA3 +#define HWCAP_SHA3 (1 << 17) +#endif + int VM_Version::_cpu; int VM_Version::_model; int VM_Version::_model2; @@ -291,6 +295,7 @@ if (auxv & HWCAP_SHA1) strcat(buf, ", sha1"); if (auxv & HWCAP_SHA2) strcat(buf, ", sha256"); if (auxv & HWCAP_SHA512) strcat(buf, ", sha512"); + if (auxv & HWCAP_SHA3) strcat(buf, ", sha3"); if (auxv & HWCAP_ATOMICS) strcat(buf, ", lse"); _features_string = os::strdup(buf); @@ -369,7 +374,7 @@ FLAG_SET_DEFAULT(UseMD5Intrinsics, false); } - if (auxv & (HWCAP_SHA1 | HWCAP_SHA2)) { + if (auxv & (HWCAP_SHA1 | HWCAP_SHA2 | HWCAP_SHA512 | HWCAP_SHA3)) { if (FLAG_IS_DEFAULT(UseSHA)) { FLAG_SET_DEFAULT(UseSHA, true); } @@ -406,7 +411,17 @@ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); } - if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) { + if (UseSHA && (auxv & HWCAP_SHA3)) { + // Do not auto-enable UseSHA3Intrinsics until it has been fully tested on hardware + // if (FLAG_IS_DEFAULT(UseSHA3Intrinsics)) { + // FLAG_SET_DEFAULT(UseSHA3Intrinsics, true); + // } + } else if (UseSHA3Intrinsics) { + warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA3Intrinsics, false); + } + + if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics || UseSHA3Intrinsics)) { FLAG_SET_DEFAULT(UseSHA, false); } diff --git a/src/hotspot/cpu/arm/vm_version_arm_32.cpp b/src/hotspot/cpu/arm/vm_version_arm_32.cpp --- a/src/hotspot/cpu/arm/vm_version_arm_32.cpp +++ b/src/hotspot/cpu/arm/vm_version_arm_32.cpp @@ -235,6 +235,11 @@ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); } + if (UseSHA3Intrinsics) { + warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA3Intrinsics, false); + } + if (UseCRC32Intrinsics) { if (!FLAG_IS_DEFAULT(UseCRC32Intrinsics)) warning("CRC32 intrinsics are not available on this CPU"); diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ppc.cpp --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp @@ -337,6 +337,11 @@ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); } + if (UseSHA3Intrinsics) { + warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA3Intrinsics, false); + } + if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) { FLAG_SET_DEFAULT(UseSHA, false); } diff --git a/src/hotspot/cpu/s390/vm_version_s390.cpp b/src/hotspot/cpu/s390/vm_version_s390.cpp --- a/src/hotspot/cpu/s390/vm_version_s390.cpp +++ b/src/hotspot/cpu/s390/vm_version_s390.cpp @@ -220,6 +220,11 @@ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); } + if (UseSHA3Intrinsics) { + warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA3Intrinsics, false); + } + if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) { FLAG_SET_DEFAULT(UseSHA, false); } diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -1028,6 +1028,11 @@ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); } + if (UseSHA3Intrinsics) { + warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA3Intrinsics, false); + } + if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) { FLAG_SET_DEFAULT(UseSHA, false); } diff --git a/src/hotspot/share/classfile/vmSymbols.cpp b/src/hotspot/share/classfile/vmSymbols.cpp --- a/src/hotspot/share/classfile/vmSymbols.cpp +++ b/src/hotspot/share/classfile/vmSymbols.cpp @@ -455,7 +455,7 @@ case vmIntrinsics::_counterMode_AESCrypt: return 1; case vmIntrinsics::_digestBase_implCompressMB: - return 4; + return 5; default: return 0; } @@ -711,8 +711,11 @@ case vmIntrinsics::_sha5_implCompress: if (!UseSHA512Intrinsics) return true; break; + case vmIntrinsics::_sha3_implCompress: + if (!UseSHA3Intrinsics) return true; + break; case vmIntrinsics::_digestBase_implCompressMB: - if (!(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return true; + if (!(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics || UseSHA3Intrinsics)) return true; break; case vmIntrinsics::_ghash_processBlocks: if (!UseGHASHIntrinsics) return true; diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -1062,6 +1062,10 @@ do_class(sun_security_provider_sha5, "sun/security/provider/SHA5") \ do_intrinsic(_sha5_implCompress, sun_security_provider_sha5, implCompress_name, implCompress_signature, F_R) \ \ + /* support for sun.security.provider.SHA3 */ \ + do_class(sun_security_provider_sha3, "sun/security/provider/SHA3") \ + do_intrinsic(_sha3_implCompress, sun_security_provider_sha3, implCompress_name, implCompress_signature, F_R) \ + \ /* support for sun.security.provider.DigestBase */ \ do_class(sun_security_provider_digestbase, "sun/security/provider/DigestBase") \ do_intrinsic(_digestBase_implCompressMB, sun_security_provider_digestbase, implCompressMB_name, implCompressMB_signature, F_R) \ diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -614,6 +614,7 @@ case vmIntrinsics::_sha_implCompress: case vmIntrinsics::_sha2_implCompress: case vmIntrinsics::_sha5_implCompress: + case vmIntrinsics::_sha3_implCompress: case vmIntrinsics::_digestBase_implCompressMB: case vmIntrinsics::_multiplyToLen: case vmIntrinsics::_squareToLen: diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp --- a/src/hotspot/share/opto/escape.cpp +++ b/src/hotspot/share/opto/escape.cpp @@ -1001,6 +1001,8 @@ strcmp(call->as_CallLeaf()->_name, "sha256_implCompressMB") == 0 || strcmp(call->as_CallLeaf()->_name, "sha512_implCompress") == 0 || strcmp(call->as_CallLeaf()->_name, "sha512_implCompressMB") == 0 || + strcmp(call->as_CallLeaf()->_name, "sha3_implCompress") == 0 || + strcmp(call->as_CallLeaf()->_name, "sha3_implCompressMB") == 0 || strcmp(call->as_CallLeaf()->_name, "multiplyToLen") == 0 || strcmp(call->as_CallLeaf()->_name, "squareToLen") == 0 || strcmp(call->as_CallLeaf()->_name, "mulAdd") == 0 || diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -308,10 +308,10 @@ bool inline_digestBase_implCompress(vmIntrinsics::ID id); bool inline_digestBase_implCompressMB(int predicate); bool inline_digestBase_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass, - bool long_state, address stubAddr, const char *stubName, + const char* state_type, address stubAddr, const char *stubName, Node* src_start, Node* ofs, Node* limit); - Node* get_state_from_digest_object(Node *digestBase_object); - Node* get_long_state_from_digest_object(Node *digestBase_object); + Node* get_state_from_digest_object(Node *digestBase_object, const char* state_type); + Node* get_digest_length_from_digest_object(Node *digestBase_object); Node* inline_digestBase_implCompressMB_predicate(int predicate); bool inline_encodeISOArray(); bool inline_updateCRC32(); @@ -830,6 +830,7 @@ case vmIntrinsics::_sha_implCompress: case vmIntrinsics::_sha2_implCompress: case vmIntrinsics::_sha5_implCompress: + case vmIntrinsics::_sha3_implCompress: return inline_digestBase_implCompress(intrinsic_id()); case vmIntrinsics::_digestBase_implCompressMB: @@ -6428,6 +6429,9 @@ // Calculate SHA5 (i.e., SHA-384 or SHA-512) for single-block byte[] array. // void com.sun.security.provider.SHA5.implCompress(byte[] buf, int ofs) // +// Calculate SHA3 (i.e., SHA3-224 or SHA3-256 or SHA3-384 or SHA3-512) for single-block byte[] array. +// void com.sun.security.provider.SHA3.implCompress(byte[] buf, int ofs) +// bool LibraryCallKit::inline_digestBase_implCompress(vmIntrinsics::ID id) { assert(callee()->signature()->size() == 2, "sha_implCompress has 2 parameters"); @@ -6450,34 +6454,43 @@ src = must_be_not_null(src, true); Node* src_start = array_element_address(src, ofs, src_elem); Node* state = NULL; + Node* digest_length = NULL; address stubAddr; const char *stubName; switch(id) { case vmIntrinsics::_md5_implCompress: assert(UseMD5Intrinsics, "need MD5 instruction support"); - state = get_state_from_digest_object(digestBase_obj); + state = get_state_from_digest_object(digestBase_obj, "[I"); stubAddr = StubRoutines::md5_implCompress(); stubName = "md5_implCompress"; break; case vmIntrinsics::_sha_implCompress: assert(UseSHA1Intrinsics, "need SHA1 instruction support"); - state = get_state_from_digest_object(digestBase_obj); + state = get_state_from_digest_object(digestBase_obj, "[I"); stubAddr = StubRoutines::sha1_implCompress(); stubName = "sha1_implCompress"; break; case vmIntrinsics::_sha2_implCompress: assert(UseSHA256Intrinsics, "need SHA256 instruction support"); - state = get_state_from_digest_object(digestBase_obj); + state = get_state_from_digest_object(digestBase_obj, "[I"); stubAddr = StubRoutines::sha256_implCompress(); stubName = "sha256_implCompress"; break; case vmIntrinsics::_sha5_implCompress: assert(UseSHA512Intrinsics, "need SHA512 instruction support"); - state = get_long_state_from_digest_object(digestBase_obj); + state = get_state_from_digest_object(digestBase_obj, "[J"); stubAddr = StubRoutines::sha512_implCompress(); stubName = "sha512_implCompress"; break; + case vmIntrinsics::_sha3_implCompress: + assert(UseSHA3Intrinsics, "need SHA3 instruction support"); + state = get_state_from_digest_object(digestBase_obj, "[B"); + stubAddr = StubRoutines::sha3_implCompress(); + stubName = "sha3_implCompress"; + digest_length = get_digest_length_from_digest_object(digestBase_obj); + if (digest_length == NULL) return false; + break; default: fatal_unexpected_iid(id); return false; @@ -6488,22 +6501,29 @@ if (stubAddr == NULL) return false; // Call the stub. - Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::digestBase_implCompress_Type(), - stubAddr, stubName, TypePtr::BOTTOM, - src_start, state); + Node* call; + if (digest_length == NULL) { + call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::digestBase_implCompress_Type(false), + stubAddr, stubName, TypePtr::BOTTOM, + src_start, state); + } else { + call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::digestBase_implCompress_Type(true), + stubAddr, stubName, TypePtr::BOTTOM, + src_start, state, digest_length); + } return true; } //------------------------------inline_digestBase_implCompressMB----------------------- // -// Calculate MD5/SHA/SHA2/SHA5 for multi-block byte[] array. +// Calculate MD5/SHA/SHA2/SHA5/SHA3 for multi-block byte[] array. // int com.sun.security.provider.DigestBase.implCompressMultiBlock(byte[] b, int ofs, int limit) // bool LibraryCallKit::inline_digestBase_implCompressMB(int predicate) { - assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics, - "need MD5/SHA1/SHA256/SHA512 instruction support"); - assert((uint)predicate < 4, "sanity"); + assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics || UseSHA3Intrinsics, + "need MD5/SHA1/SHA256/SHA512/SHA3 instruction support"); + assert((uint)predicate < 5, "sanity"); assert(callee()->signature()->size() == 3, "digestBase_implCompressMB has 3 parameters"); Node* digestBase_obj = argument(0); // The receiver was checked for NULL already. @@ -6529,7 +6549,7 @@ const char* klass_digestBase_name = NULL; const char* stub_name = NULL; address stub_addr = NULL; - bool long_state = false; + const char* state_type = "[I"; switch (predicate) { case 0: @@ -6558,7 +6578,15 @@ klass_digestBase_name = "sun/security/provider/SHA5"; stub_name = "sha512_implCompressMB"; stub_addr = StubRoutines::sha512_implCompressMB(); - long_state = true; + state_type = "[J"; + } + break; + case 4: + if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha3_implCompress)) { + klass_digestBase_name = "sun/security/provider/SHA3"; + stub_name = "sha3_implCompressMB"; + stub_addr = StubRoutines::sha3_implCompressMB(); + state_type = "[B"; } break; default: @@ -6576,33 +6604,43 @@ ciKlass* klass_digestBase = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_digestBase_name)); assert(klass_digestBase->is_loaded(), "predicate checks that this class is loaded"); ciInstanceKlass* instklass_digestBase = klass_digestBase->as_instance_klass(); - return inline_digestBase_implCompressMB(digestBase_obj, instklass_digestBase, long_state, stub_addr, stub_name, src_start, ofs, limit); + return inline_digestBase_implCompressMB(digestBase_obj, instklass_digestBase, state_type, stub_addr, stub_name, src_start, ofs, limit); } return false; } //------------------------------inline_digestBase_implCompressMB----------------------- bool LibraryCallKit::inline_digestBase_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_digestBase, - bool long_state, address stubAddr, const char *stubName, + const char* state_type, address stubAddr, const char *stubName, Node* src_start, Node* ofs, Node* limit) { const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_digestBase); const TypeOopPtr* xtype = aklass->as_instance_type(); Node* digest_obj = new CheckCastPPNode(control(), digestBase_obj, xtype); digest_obj = _gvn.transform(digest_obj); - Node* state; - if (long_state) { - state = get_long_state_from_digest_object(digest_obj); - } else { - state = get_state_from_digest_object(digest_obj); - } + Node* state = get_state_from_digest_object(digest_obj, state_type); if (state == NULL) return false; + Node* digest_length = NULL; + if (strcmp("sha3_implCompressMB", stubName) == 0) { + digest_length = get_digest_length_from_digest_object(digest_obj); + if (digest_length == NULL) return false; + } + // Call the stub. - Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, - OptoRuntime::digestBase_implCompressMB_Type(), - stubAddr, stubName, TypePtr::BOTTOM, - src_start, state, ofs, limit); + Node* call; + if (digest_length == NULL) { + call = make_runtime_call(RC_LEAF|RC_NO_FP, + OptoRuntime::digestBase_implCompressMB_Type(false), + stubAddr, stubName, TypePtr::BOTTOM, + src_start, state, ofs, limit); + } else { + call = make_runtime_call(RC_LEAF|RC_NO_FP, + OptoRuntime::digestBase_implCompressMB_Type(true), + stubAddr, stubName, TypePtr::BOTTOM, + src_start, state, digest_length, ofs, limit); + } + // return ofs (int) Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); set_result(result); @@ -6611,9 +6649,9 @@ } //------------------------------get_state_from_digest_object----------------------- -Node * LibraryCallKit::get_state_from_digest_object(Node *digest_object) { - Node* digest_state = load_field_from_object(digest_object, "state", "[I", /*is_exact*/ false); - assert (digest_state != NULL, "wrong version of sun.security.provider.MD5/SHA/SHA2"); +Node * LibraryCallKit::get_state_from_digest_object(Node *digest_object, const char *state_type) { + Node* digest_state = load_field_from_object(digest_object, "state", state_type, /*is_exact*/ false); + assert (digest_state != NULL, "wrong version of sun.security.provider.MD5/SHA/SHA2/SHA5/SHA3"); if (digest_state == NULL) return (Node *) NULL; // now have the array, need to get the start address of the state array @@ -6621,26 +6659,22 @@ return state; } -//------------------------------get_long_state_from_digest_object----------------------- -Node * LibraryCallKit::get_long_state_from_digest_object(Node *digest_object) { - Node* digest_state = load_field_from_object(digest_object, "state", "[J", /*is_exact*/ false); - assert (digest_state != NULL, "wrong version of sun.security.provider.SHA5"); - if (digest_state == NULL) return (Node *) NULL; - - // now have the array, need to get the start address of the state array - Node* state = array_element_address(digest_state, intcon(0), T_LONG); - return state; +//------------------------------get_digest_length_from_sha3_object---------------------------------- +Node * LibraryCallKit::get_digest_length_from_digest_object(Node *digest_object) { + Node* digest_length = load_field_from_object(digest_object, "digestLength", "I", /*is_exact*/ false); + assert (digest_length != NULL, "sanity"); + return digest_length; } //----------------------------inline_digestBase_implCompressMB_predicate---------------------------- // Return node representing slow path of predicate check. // the pseudo code we want to emulate with this predicate is: -// if (digestBaseObj instanceof MD5/SHA/SHA2/SHA5) do_intrinsic, else do_javapath +// if (digestBaseObj instanceof MD5/SHA/SHA2/SHA5/SHA3) do_intrinsic, else do_javapath // Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate) { - assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics, - "need MD5/SHA1/SHA256/SHA512 instruction support"); - assert((uint)predicate < 4, "sanity"); + assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics || UseSHA3Intrinsics, + "need MD5/SHA1/SHA256/SHA512/SHA3 instruction support"); + assert((uint)predicate < 5, "sanity"); // The receiver was checked for NULL already. Node* digestBaseObj = argument(0); @@ -6676,6 +6710,12 @@ klass_name = "sun/security/provider/SHA5"; } break; + case 4: + if (UseSHA3Intrinsics) { + // we want to do an instanceof comparison against the SHA3 class + klass_name = "sun/security/provider/SHA3"; + } + break; default: fatal("unknown SHA intrinsic predicate: %d", predicate); } diff --git a/src/hotspot/share/opto/runtime.cpp b/src/hotspot/share/opto/runtime.cpp --- a/src/hotspot/share/opto/runtime.cpp +++ b/src/hotspot/share/opto/runtime.cpp @@ -960,14 +960,15 @@ /* * void implCompress(byte[] buf, int ofs) */ -const TypeFunc* OptoRuntime::digestBase_implCompress_Type() { +const TypeFunc* OptoRuntime::digestBase_implCompress_Type(bool is_sha3) { // create input type (domain) - int num_args = 2; + int num_args = is_sha3 ? 3 : 2; int argcnt = num_args; const Type** fields = TypeTuple::fields(argcnt); int argp = TypeFunc::Parms; fields[argp++] = TypePtr::NOTNULL; // buf fields[argp++] = TypePtr::NOTNULL; // state + if (is_sha3) fields[argp++] = TypeInt::INT; // digest_length assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); @@ -981,14 +982,15 @@ /* * int implCompressMultiBlock(byte[] b, int ofs, int limit) */ -const TypeFunc* OptoRuntime::digestBase_implCompressMB_Type() { +const TypeFunc* OptoRuntime::digestBase_implCompressMB_Type(bool is_sha3) { // create input type (domain) - int num_args = 4; + int num_args = is_sha3 ? 5 : 4; int argcnt = num_args; const Type** fields = TypeTuple::fields(argcnt); int argp = TypeFunc::Parms; fields[argp++] = TypePtr::NOTNULL; // buf fields[argp++] = TypePtr::NOTNULL; // state + if (is_sha3) fields[argp++] = TypeInt::INT; // digest_length fields[argp++] = TypeInt::INT; // ofs fields[argp++] = TypeInt::INT; // limit assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); diff --git a/src/hotspot/share/opto/runtime.hpp b/src/hotspot/share/opto/runtime.hpp --- a/src/hotspot/share/opto/runtime.hpp +++ b/src/hotspot/share/opto/runtime.hpp @@ -278,8 +278,8 @@ static const TypeFunc* electronicCodeBook_aescrypt_Type(); static const TypeFunc* counterMode_aescrypt_Type(); - static const TypeFunc* digestBase_implCompress_Type(); - static const TypeFunc* digestBase_implCompressMB_Type(); + static const TypeFunc* digestBase_implCompress_Type(bool is_sha3); + static const TypeFunc* digestBase_implCompressMB_Type(bool is_sha3); static const TypeFunc* multiplyToLen_Type(); static const TypeFunc* montgomeryMultiply_Type(); diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -335,6 +335,10 @@ "Use intrinsics for SHA-384 and SHA-512 crypto hash functions. " \ "Requires that UseSHA is enabled.") \ \ + diagnostic(bool, UseSHA3Intrinsics, false, \ + "Use intrinsics for SHA3 crypto hash function. " \ + "Requires that UseSHA is enabled.") \ + \ diagnostic(bool, UseCRC32Intrinsics, false, \ "use intrinsics for java.util.zip.CRC32") \ \ diff --git a/src/hotspot/share/runtime/stubRoutines.cpp b/src/hotspot/share/runtime/stubRoutines.cpp --- a/src/hotspot/share/runtime/stubRoutines.cpp +++ b/src/hotspot/share/runtime/stubRoutines.cpp @@ -146,6 +146,8 @@ address StubRoutines::_sha256_implCompressMB = NULL; address StubRoutines::_sha512_implCompress = NULL; address StubRoutines::_sha512_implCompressMB = NULL; +address StubRoutines::_sha3_implCompress = NULL; +address StubRoutines::_sha3_implCompressMB = NULL; address StubRoutines::_updateBytesCRC32 = NULL; address StubRoutines::_crc_table_adr = NULL; diff --git a/src/hotspot/share/runtime/stubRoutines.hpp b/src/hotspot/share/runtime/stubRoutines.hpp --- a/src/hotspot/share/runtime/stubRoutines.hpp +++ b/src/hotspot/share/runtime/stubRoutines.hpp @@ -228,6 +228,8 @@ static address _sha256_implCompressMB; static address _sha512_implCompress; static address _sha512_implCompressMB; + static address _sha3_implCompress; + static address _sha3_implCompressMB; static address _updateBytesCRC32; static address _crc_table_adr; @@ -407,6 +409,8 @@ static address sha256_implCompressMB() { return _sha256_implCompressMB; } static address sha512_implCompress() { return _sha512_implCompress; } static address sha512_implCompressMB() { return _sha512_implCompressMB; } + static address sha3_implCompress() { return _sha3_implCompress; } + static address sha3_implCompressMB() { return _sha3_implCompressMB; } static address updateBytesCRC32() { return _updateBytesCRC32; } static address crc_table_addr() { return _crc_table_adr; } diff --git a/src/java.base/share/classes/sun/security/provider/SHA3.java b/src/java.base/share/classes/sun/security/provider/SHA3.java --- a/src/java.base/share/classes/sun/security/provider/SHA3.java +++ b/src/java.base/share/classes/sun/security/provider/SHA3.java @@ -25,6 +25,7 @@ package sun.security.provider; +import jdk.internal.HotSpotIntrinsicCandidate; import static sun.security.provider.ByteArrayAccess.*; import java.nio.*; import java.util.*; @@ -73,15 +74,25 @@ this.suffix = suffix; } + private void implCompressCheck(byte[] b, int ofs) { + Objects.requireNonNull(b); + } + /** * Core compression function. Processes blockSize bytes at a time * and updates the state of this object. */ void implCompress(byte[] b, int ofs) { - for (int i = 0; i < buffer.length; i++) { - state[i] ^= b[ofs++]; - } - keccak(); + implCompressCheck(b, ofs); + implCompress0(b, ofs); + } + + @HotSpotIntrinsicCandidate + private void implCompress0(byte[] b, int ofs) { + for (int i = 0; i < buffer.length; i++) { + state[i] ^= b[ofs++]; + } + keccak(); } /** @@ -94,10 +105,7 @@ if (numOfPadding < 1) { throw new ProviderException("Incorrect pad size: " + numOfPadding); } - for (int i = 0; i < buffer.length; i++) { - state[i] ^= buffer[i]; - } - keccak(); + implCompress(buffer, 0); System.arraycopy(state, 0, out, ofs, engineGetDigestLength()); } diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java @@ -572,6 +572,7 @@ if (!config.useSHA512Intrinsics()) { add(ignore, "sun/security/provider/SHA5." + shaCompressName + "([BI)V"); } + add(toBeInvestigated, "sun/security/provider/SHA3." + shaCompressName + "([BI)V"); } private static boolean isJDK9OrHigher() { diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/TestDigest.java b/test/hotspot/jtreg/compiler/intrinsics/sha/TestDigest.java --- a/test/hotspot/jtreg/compiler/intrinsics/sha/TestDigest.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/TestDigest.java @@ -24,7 +24,7 @@ /** * @test * @bug 8035968 - * @summary C2 support for MD5/SHA-1/SHA-224/SHA-256/SHA-384/SHA-512 + * @summary C2 support for MD5/SHA-1/SHA-224/SHA-256/SHA-384/SHA-512/SHA3 * * @run main/othervm/timeout=600 -Xbatch * -Dalgorithm=MD5 @@ -44,6 +44,18 @@ * @run main/othervm/timeout=600 -Xbatch * -Dalgorithm=SHA-512 * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-224 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-256 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-384 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-512 + * compiler.intrinsics.sha.TestDigest * * @run main/othervm/timeout=600 -Xbatch * -Dalgorithm=MD5 -Doffset=1 @@ -63,6 +75,18 @@ * @run main/othervm/timeout=600 -Xbatch * -Dalgorithm=SHA-512 -Doffset=1 * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-224 -Doffset=1 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-256 -Doffset=1 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-384 -Doffset=1 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-512 -Doffset=1 + * compiler.intrinsics.sha.TestDigest * * @run main/othervm/timeout=600 -Xbatch * -Dalgorithm=SHA-1 -Dalgorithm2=SHA-256 @@ -80,6 +104,31 @@ * @run main/othervm/timeout=600 -Xbatch * -Dalgorithm=MD5 -Dalgorithm2=SHA-1 * compiler.intrinsics.sha.TestDigest + * + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA-1 -Dalgorithm2=SHA3-224 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA-1 -Dalgorithm2=SHA3-256 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA-1 -Dalgorithm2=SHA3-384 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA-1 -Dalgorithm2=SHA3-512 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-224 -Dalgorithm2=SHA-1 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-256 -Dalgorithm2=SHA-1 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-384 -Dalgorithm2=SHA-1 + * compiler.intrinsics.sha.TestDigest + * @run main/othervm/timeout=600 -Xbatch + * -Dalgorithm=SHA3-512 -Dalgorithm2=SHA-1 + * compiler.intrinsics.sha.TestDigest */ package compiler.intrinsics.sha; diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/DigestOptionsBase.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/DigestOptionsBase.java --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/DigestOptionsBase.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/DigestOptionsBase.java @@ -45,6 +45,8 @@ = "UseSHA256Intrinsics"; public static final String USE_SHA512_INTRINSICS_OPTION = "UseSHA512Intrinsics"; + public static final String USE_SHA3_INTRINSICS_OPTION + = "UseSHA3Intrinsics"; // Intrinsics flags are of diagnostic type // and must be preceded by UnlockDiagnosticVMOptions. @@ -64,6 +66,8 @@ = "Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU."; protected static final String SHA512_INTRINSICS_ARE_NOT_AVAILABLE = "Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU."; + protected static final String SHA3_INTRINSICS_ARE_NOT_AVAILABLE + = "Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU."; private final TestCase[] testCases; @@ -89,6 +93,8 @@ return DigestOptionsBase.SHA256_INTRINSICS_ARE_NOT_AVAILABLE; case DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION: return DigestOptionsBase.SHA512_INTRINSICS_ARE_NOT_AVAILABLE; + case DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION: + return DigestOptionsBase.SHA3_INTRINSICS_ARE_NOT_AVAILABLE; default: throw new Error("Unexpected option " + optionName); } @@ -115,6 +121,8 @@ return IntrinsicPredicates.SHA256_INSTRUCTION_AVAILABLE; case DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION: return IntrinsicPredicates.SHA512_INSTRUCTION_AVAILABLE; + case DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION: + return IntrinsicPredicates.SHA3_INSTRUCTION_AVAILABLE; default: throw new Error("Unexpected option " + optionName); } diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA3IntrinsicsOptionOnSupportedCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA3IntrinsicsOptionOnSupportedCPU.java new file mode 100644 --- /dev/null +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA3IntrinsicsOptionOnSupportedCPU.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, Huawei Technologies Co. Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8252204 + * @summary Verify UseSHA3Intrinsics option processing on supported CPU. + * @library /test/lib testcases / + * @modules java.base/jdk.internal.misc + * java.management + * + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * compiler.intrinsics.sha.cli.TestUseSHA3IntrinsicsOptionOnSupportedCPU + */ + +package compiler.intrinsics.sha.cli; + +import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForSupportedCPU; + +public class TestUseSHA3IntrinsicsOptionOnSupportedCPU { + public static void main(String args[]) throws Throwable { + new DigestOptionsBase(new GenericTestCaseForSupportedCPU( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION)).test(); + } +} diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA3IntrinsicsOptionOnUnsupportedCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA3IntrinsicsOptionOnUnsupportedCPU.java new file mode 100644 --- /dev/null +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/TestUseSHA3IntrinsicsOptionOnUnsupportedCPU.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020, Huawei Technologies Co. Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8252204 + * @summary Verify UseSHA3Intrinsics option processing on unsupported CPU. + * @library /test/lib testcases / + * @modules java.base/jdk.internal.misc + * java.management + * + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * compiler.intrinsics.sha.cli.TestUseSHA3IntrinsicsOptionOnUnsupportedCPU + */ + +package compiler.intrinsics.sha.cli; + +import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForOtherCPU; +import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedAArch64CPU; +import compiler.intrinsics.sha.cli.testcases.GenericTestCaseForUnsupportedX86CPU; +import compiler.intrinsics.sha.cli.testcases.UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU; + +public class TestUseSHA3IntrinsicsOptionOnUnsupportedCPU { + public static void main(String args[]) throws Throwable { + new DigestOptionsBase( + new GenericTestCaseForUnsupportedX86CPU( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION), + new GenericTestCaseForUnsupportedAArch64CPU( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION), + new UseSHAIntrinsicsSpecificTestCaseForUnsupportedCPU( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION), + new GenericTestCaseForOtherCPU( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION)).test(); + } +} diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedCPU.java --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedCPU.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedCPU.java @@ -66,7 +66,9 @@ CommandLineOptionTest.prepareBooleanFlag( DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, false), CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, false)); + DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, false), + CommandLineOptionTest.prepareBooleanFlag( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION, false)); } @Override @@ -83,7 +85,9 @@ CommandLineOptionTest.prepareBooleanFlag( DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, false), CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, false)); + DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, false), + CommandLineOptionTest.prepareBooleanFlag( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION, false)); CommandLineOptionTest.verifyOptionValueForSameVM( // Verify that UseSHA is disabled when all UseSHA*Intrinsics are @@ -102,7 +106,9 @@ CommandLineOptionTest.prepareBooleanFlag( DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, false), CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, false)); + DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, false), + CommandLineOptionTest.prepareBooleanFlag( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION, false)); // Verify that explicitly disabled UseSHA option remains disabled even // if all UseSHA*Intrinsics options were enabled. @@ -121,6 +127,8 @@ CommandLineOptionTest.prepareBooleanFlag( DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, true), CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, true)); + DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, true), + CommandLineOptionTest.prepareBooleanFlag( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION, true)); } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedCPU.java b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedCPU.java --- a/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedCPU.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedCPU.java @@ -75,7 +75,9 @@ CommandLineOptionTest.prepareBooleanFlag( DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, true), CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, true)); + DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, true), + CommandLineOptionTest.prepareBooleanFlag( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION, true)); // Verify that UseSHA option remains disabled even if all // UseSHA*Intrinsics options were enabled and UseSHA was enabled as well. @@ -94,6 +96,8 @@ CommandLineOptionTest.prepareBooleanFlag( DigestOptionsBase.USE_SHA256_INTRINSICS_OPTION, true), CommandLineOptionTest.prepareBooleanFlag( - DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, true)); + DigestOptionsBase.USE_SHA512_INTRINSICS_OPTION, true), + CommandLineOptionTest.prepareBooleanFlag( + DigestOptionsBase.USE_SHA3_INTRINSICS_OPTION, true)); } } diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java --- a/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/DigestSanityTestBase.java @@ -45,6 +45,8 @@ = "_sha2_implCompress"; protected static final String SHA512_INTRINSIC_ID = "_sha5_implCompress"; + protected static final String SHA3_INTRINSIC_ID + = "_sha3_implCompress"; protected static final String MB_INTRINSIC_ID = "_digestBase_implCompressMB"; diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3Intrinsics.java b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3Intrinsics.java new file mode 100644 --- /dev/null +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3Intrinsics.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2020, Huawei Technologies Co. Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8252204 + * @summary Verify that SHA3-224, SHA3-256, SHA3-384, SHA3-512 intrinsic is actually used. + * @comment the test verifies compilation of java.base methods, so it can't be run w/ AOT'ed java.base + * @requires !vm.aot.enabled + * + * @library /test/lib / + * @modules java.base/jdk.internal.misc + * java.management + * + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_224.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics + * -Dalgorithm=SHA3-224 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=negative_224.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:-UseSHA3Intrinsics + * -Dalgorithm=SHA3-224 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_256.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics + * -Dalgorithm=SHA3-256 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=negative_256.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:-UseSHA3Intrinsics + * -Dalgorithm=SHA3-256 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_384.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics + * -Dalgorithm=SHA3-384 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=negative_384.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:-UseSHA3Intrinsics + * -Dalgorithm=SHA3-384 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_512.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics + * -Dalgorithm=SHA3-512 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=negative_512.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:-UseSHA3Intrinsics + * -Dalgorithm=SHA3-512 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE + * compiler.testlibrary.intrinsics.Verifier positive_224.log positive_256.log positive_384.log positive_512.log + * negative_224.log negative_256.log negative_384.log negative_512.log + */ + +package compiler.intrinsics.sha.sanity; + +import compiler.testlibrary.sha.predicate.IntrinsicPredicates; + +public class TestSHA3Intrinsics { + public static void main(String args[]) throws Exception { + new DigestSanityTestBase(IntrinsicPredicates.isSHA3IntrinsicAvailable(), + DigestSanityTestBase.SHA3_INTRINSIC_ID).test(); + } +} diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3MultiBlockIntrinsics.java b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3MultiBlockIntrinsics.java new file mode 100644 --- /dev/null +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3MultiBlockIntrinsics.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2020, Huawei Technologies Co. Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8252204 + * @summary Verify that SHA3-224, SHA3-256, SHA3-384, SHA3-512 multi block intrinsic is actually used. + * @comment the test verifies compilation of java.base methods, so it can't be run w/ AOT'ed java.base + * @requires !vm.aot.enabled + * + * @library /test/lib / + * @modules java.base/jdk.internal.misc + * java.management + * + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_224.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-224 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_224_def.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-224 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=negative_224.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 -XX:-UseSHA + * -Dalgorithm=SHA3-224 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_256.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-256 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_256_def.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-256 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=negative_256.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 -XX:-UseSHA + * -Dalgorithm=SHA3-256 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_384.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-384 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_384_def.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-384 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=negative_384.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 -XX:-UseSHA + * -Dalgorithm=SHA3-384 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_512.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-512 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_512_def.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-512 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=negative_512.log + * -XX:CompileOnly=sun/security/provider/DigestBase + * -XX:CompileOnly=sun/security/provider/SHA3 -XX:-UseSHA + * -Dalgorithm=SHA3-512 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE + * compiler.testlibrary.intrinsics.Verifier positive_224.log positive_256.log + * positive_384.log positive_512.log positive_224_def.log positive_256_def.log + * positive_384_def.log positive_512_def.log negative_224.log negative_256.log + * negative_384.log negative_512.log + */ + +package compiler.intrinsics.sha.sanity; + +import compiler.testlibrary.sha.predicate.IntrinsicPredicates; + +public class TestSHA3MultiBlockIntrinsics { + public static void main(String args[]) throws Exception { + new DigestSanityTestBase(IntrinsicPredicates.isSHA3IntrinsicAvailable(), + DigestSanityTestBase.MB_INTRINSIC_ID).test(); + } +} diff --git a/test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java b/test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java --- a/test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java +++ b/test/hotspot/jtreg/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java @@ -97,11 +97,14 @@ new OrPredicate(new CPUSpecificPredicate("amd64.*", new String[] { "avx2", "bmi2" }, null), new CPUSpecificPredicate("x86_64", new String[] { "avx2", "bmi2" }, null))))))))); + public static final BooleanSupplier SHA3_INSTRUCTION_AVAILABLE + // sha3 is only implemented on aarch64 for now + = new CPUSpecificPredicate("aarch64.*", new String[] {"sha3" }, null); + public static final BooleanSupplier ANY_SHA_INSTRUCTION_AVAILABLE = new OrPredicate(IntrinsicPredicates.SHA1_INSTRUCTION_AVAILABLE, - new OrPredicate( - IntrinsicPredicates.SHA256_INSTRUCTION_AVAILABLE, - IntrinsicPredicates.SHA512_INSTRUCTION_AVAILABLE)); + new OrPredicate(IntrinsicPredicates.SHA256_INSTRUCTION_AVAILABLE, + new OrPredicate(IntrinsicPredicates.SHA512_INSTRUCTION_AVAILABLE, IntrinsicPredicates.SHA3_INSTRUCTION_AVAILABLE))); public static BooleanSupplier isMD5IntrinsicAvailable() { return new AndPredicate(IntrinsicPredicates.COMPILABLE_BY_C2, @@ -123,6 +126,11 @@ IntrinsicPredicates.isIntrinsicAvailable("sun.security.provider.SHA5", "implCompress0")); } + public static BooleanSupplier isSHA3IntrinsicAvailable() { + return new AndPredicate(IntrinsicPredicates.COMPILABLE_BY_C2, + IntrinsicPredicates.isIntrinsicAvailable("sun.security.provider.SHA3", "implCompress0")); + } + private static BooleanSupplier isIntrinsicAvailable(String klass, String method) { try { Method m = Class.forName(klass).getDeclaredMethod(method, byte[].class, int.class); diff --git a/test/jdk/sun/security/provider/MessageDigest/SHA3.java b/test/jdk/sun/security/provider/MessageDigest/SHA3.java new file mode 100644 --- /dev/null +++ b/test/jdk/sun/security/provider/MessageDigest/SHA3.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2020, Huawei Technologies Co. Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.Asserts; + +import java.security.MessageDigest; +import java.util.Arrays; + +/** + * @test + * @bug 8252204 + * @library /test/lib + * @summary testing SHA3-224/256/384/512. + */ +public class SHA3 { + + static byte[] msg1600bits; + static { + msg1600bits = new byte[200]; + for (int i = 0; i < 200; i++) + msg1600bits[i] = (byte) 0xa3; + } + + public static void main(String[] args) throws Exception { + + MessageDigest md; + + // Test vectors obtained from + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-224_Msg0.pdf + md = MessageDigest.getInstance("SHA3-224"); + Asserts.assertTrue(Arrays.equals(md.digest("".getBytes()), + xeh("6B4E0342 3667DBB7 3B6E1545 4F0EB1AB D4597F9A 1B078E3F 5B5A6BC7"))); + // Test vectors obtained from + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-224_1600.pdf + Asserts.assertTrue(Arrays.equals(md.digest(msg1600bits), + xeh("9376816A BA503F72 F96CE7EB 65AC095D EEE3BE4B F9BBC2A1 CB7E11E0"))); + + // Test vectors obtained from + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-256_Msg0.pdf + md = MessageDigest.getInstance("SHA3-256"); + Asserts.assertTrue(Arrays.equals(md.digest("".getBytes()), + xeh("A7FFC6F8 BF1ED766 51C14756 A061D662 F580FF4D E43B49FA 82D80A4B 80F8434A"))); + // Test vectors obtained from + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-256_1600.pdf + Asserts.assertTrue(Arrays.equals(md.digest(msg1600bits), + xeh("79F38ADE C5C20307 A98EF76E 8324AFBF D46CFD81 B22E3973 C65FA1BD 9DE31787"))); + + // Test vectors obtained from + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-384_Msg0.pdf + md = MessageDigest.getInstance("SHA3-384"); + Asserts.assertTrue(Arrays.equals(md.digest("".getBytes()), + xeh("0C63A75B 845E4F7D 01107D85 2E4C2485 C51A50AA AA94FC61 995E71BB EE983A2A" + + "C3713831 264ADB47 FB6BD1E0 58D5F004"))); + // Test vectors obtained from + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-384_1600.pdf + Asserts.assertTrue(Arrays.equals(md.digest(msg1600bits), + xeh("1881DE2C A7E41EF9 5DC4732B 8F5F002B 189CC1E4 2B74168E D1732649 CE1DBCDD" + + "76197A31 FD55EE98 9F2D7050 DD473E8F"))); + + // Test vectors obtained from + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-512_Msg0.pdf + md = MessageDigest.getInstance("SHA3-512"); + Asserts.assertTrue(Arrays.equals(md.digest("".getBytes()), + xeh("A69F73CC A23A9AC5 C8B567DC 185A756E 97C98216 4FE25859 E0D1DCC1 475C80A6" + + "15B2123A F1F5F94C 11E3E940 2C3AC558 F500199D 95B6D3E3 01758586 281DCD26"))); + // Test vectors obtaned from + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-512_1600.pdf + Asserts.assertTrue(Arrays.equals(md.digest(msg1600bits), + xeh("E76DFAD2 2084A8B1 467FCF2F FA58361B EC7628ED F5F3FDC0 E4805DC4 8CAEECA8" + + "1B7C13C3 0ADF52A3 65958473 9A2DF46B E589C51C A1A4A841 6DF6545A 1CE8BA00"))); + } + + static byte[] xeh(String in) { + in = in.replaceAll(" ", ""); + int len = in.length() / 2; + byte[] out = new byte[len]; + for (int i = 0; i < len; i++) { + out[i] = (byte)Integer.parseInt(in.substring(i * 2, i * 2 + 2), 16); + } + return out; + } + +} diff --git a/test/micro/org/openjdk/bench/java/security/MessageDigests.java b/test/micro/org/openjdk/bench/java/security/MessageDigests.java --- a/test/micro/org/openjdk/bench/java/security/MessageDigests.java +++ b/test/micro/org/openjdk/bench/java/security/MessageDigests.java @@ -53,7 +53,7 @@ @Param({"64", "1024", "16384"}) private int length; - @Param({"md2", "md5", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512"}) + @Param({"md2", "md5", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512", "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512"}) private String digesterName; @Param({"DEFAULT", "SUN"})