mirror of
https://github.com/darlinghq/darling-openjdk.git
synced 2024-12-04 02:21:23 +00:00
Merge
This commit is contained in:
commit
f31d3d540e
@ -31,6 +31,7 @@
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/events.hpp"
|
||||
#include "utilities/formatBuffer.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/vmError.hpp"
|
||||
@ -1269,6 +1270,15 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t
|
||||
return true;
|
||||
}
|
||||
|
||||
bool os::signal_sent_by_kill(const void* siginfo) {
|
||||
const siginfo_t* const si = (const siginfo_t*)siginfo;
|
||||
return si->si_code == SI_USER || si->si_code == SI_QUEUE
|
||||
#ifdef SI_TKILL
|
||||
|| si->si_code == SI_TKILL
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
void os::print_siginfo(outputStream* os, const void* si0) {
|
||||
|
||||
const siginfo_t* const si = (const siginfo_t*) si0;
|
||||
@ -1299,7 +1309,7 @@ void os::print_siginfo(outputStream* os, const void* si0) {
|
||||
// so it depends on the context which member to use. For synchronous error signals,
|
||||
// we print si_addr, unless the signal was sent by another process or thread, in
|
||||
// which case we print out pid or tid of the sender.
|
||||
if (si->si_code == SI_USER || si->si_code == SI_QUEUE) {
|
||||
if (signal_sent_by_kill(si)) {
|
||||
const pid_t pid = si->si_pid;
|
||||
os->print(", si_pid: %ld", (long) pid);
|
||||
if (IS_VALID_PID(pid)) {
|
||||
@ -1325,6 +1335,25 @@ void os::print_siginfo(outputStream* os, const void* si0) {
|
||||
|
||||
}
|
||||
|
||||
bool os::signal_thread(Thread* thread, int sig, const char* reason) {
|
||||
OSThread* osthread = thread->osthread();
|
||||
if (osthread) {
|
||||
#if defined (SOLARIS)
|
||||
// Note: we cannot use pthread_kill on Solaris - not because
|
||||
// its missing, but because we do not have the pthread_t id.
|
||||
int status = thr_kill(osthread->thread_id(), sig);
|
||||
#else
|
||||
int status = pthread_kill(osthread->pthread_id(), sig);
|
||||
#endif
|
||||
if (status == 0) {
|
||||
Events::log(Thread::current(), "sent signal %d to Thread " INTPTR_FORMAT " because %s.",
|
||||
sig, p2i(thread), reason);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int os::Posix::unblock_thread_signal_mask(const sigset_t *set) {
|
||||
return pthread_sigmask(SIG_UNBLOCK, set, NULL);
|
||||
}
|
||||
|
@ -1797,6 +1797,11 @@ void os::print_memory_info(outputStream* st) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
bool os::signal_sent_by_kill(const void* siginfo) {
|
||||
// TODO: Is this possible?
|
||||
return false;
|
||||
}
|
||||
|
||||
void os::print_siginfo(outputStream *st, const void* siginfo) {
|
||||
const EXCEPTION_RECORD* const er = (EXCEPTION_RECORD*)siginfo;
|
||||
st->print("siginfo:");
|
||||
@ -1830,6 +1835,11 @@ void os::print_siginfo(outputStream *st, const void* siginfo) {
|
||||
st->cr();
|
||||
}
|
||||
|
||||
bool os::signal_thread(Thread* thread, int sig, const char* reason) {
|
||||
// TODO: Can we kill thread?
|
||||
return false;
|
||||
}
|
||||
|
||||
void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
|
||||
// do nothing
|
||||
}
|
||||
|
@ -274,15 +274,42 @@ class CompileReplay : public StackObj {
|
||||
// Parse a sequence of raw data encoded as bytes and return the
|
||||
// resulting data.
|
||||
char* parse_data(const char* tag, int& length) {
|
||||
if (!parse_tag_and_count(tag, length)) {
|
||||
int read_size = 0;
|
||||
if (!parse_tag_and_count(tag, read_size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char * result = NEW_RESOURCE_ARRAY(char, length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
int actual_size = sizeof(MethodData);
|
||||
char *result = NEW_RESOURCE_ARRAY(char, actual_size);
|
||||
int i = 0;
|
||||
if (read_size != actual_size) {
|
||||
tty->print_cr("Warning: ciMethodData parsing sees MethodData size %i in file, current is %i", read_size,
|
||||
actual_size);
|
||||
// Replay serializes the entire MethodData, but the data is at the end.
|
||||
// If the MethodData instance size has changed, we can pad or truncate in the beginning
|
||||
int padding = actual_size - read_size;
|
||||
if (padding > 0) {
|
||||
// pad missing data with zeros
|
||||
tty->print_cr("- Padding MethodData");
|
||||
for (; i < padding; i++) {
|
||||
result[i] = 0;
|
||||
}
|
||||
} else if (padding < 0) {
|
||||
// drop some data
|
||||
tty->print_cr("- Truncating MethodData");
|
||||
for (int j = 0; j < -padding; j++) {
|
||||
int val = parse_int("data");
|
||||
// discard val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(i < actual_size, "At least some data must remain to be copied");
|
||||
for (; i < actual_size; i++) {
|
||||
int val = parse_int("data");
|
||||
result[i] = val;
|
||||
}
|
||||
length = actual_size;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -679,7 +679,9 @@ void GenCollectedHeap::do_collection(bool full,
|
||||
// Track memory usage and detect low memory after GC finishes
|
||||
MemoryService::track_memory_usage();
|
||||
|
||||
gc_epilogue(complete);
|
||||
// Need to tell the epilogue code we are done with Full GC, regardless what was
|
||||
// the initial value for "complete" flag.
|
||||
gc_epilogue(true);
|
||||
|
||||
BiasedLocking::restore_marks();
|
||||
|
||||
|
@ -367,7 +367,7 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G);
|
||||
"Print out every time compilation is longer than " \
|
||||
"a given threshold") \
|
||||
\
|
||||
develop(bool, SafepointALot, false, \
|
||||
diagnostic(bool, SafepointALot, false, \
|
||||
"Generate a lot of safepoints. This works with " \
|
||||
"GuaranteedSafepointInterval") \
|
||||
\
|
||||
|
@ -288,13 +288,14 @@ void HandshakeState::process_self_inner(JavaThread* thread) {
|
||||
assert(Thread::current() == thread, "should call from thread");
|
||||
assert(!thread->is_terminated(), "should not be a terminated thread");
|
||||
|
||||
CautiouslyPreserveExceptionMark pem(thread);
|
||||
ThreadInVMForHandshake tivm(thread);
|
||||
if (!_semaphore.trywait()) {
|
||||
_semaphore.wait_with_safepoint_check(thread);
|
||||
}
|
||||
HandshakeOperation* op = OrderAccess::load_acquire(&_operation);
|
||||
if (op != NULL) {
|
||||
HandleMark hm(thread);
|
||||
CautiouslyPreserveExceptionMark pem(thread);
|
||||
// Disarm before execute the operation
|
||||
clear_handshake(thread);
|
||||
op->do_handshake(thread);
|
||||
|
@ -463,6 +463,9 @@ class os: AllStatic {
|
||||
static void pd_start_thread(Thread* thread);
|
||||
static void start_thread(Thread* thread);
|
||||
|
||||
// Returns true if successful.
|
||||
static bool signal_thread(Thread* thread, int sig, const char* reason);
|
||||
|
||||
static void free_thread(OSThread* osthread);
|
||||
|
||||
// thread id on Linux/64bit is 64bit, on Windows and Solaris, it's 32bit
|
||||
@ -637,6 +640,7 @@ class os: AllStatic {
|
||||
static void print_environment_variables(outputStream* st, const char** env_list);
|
||||
static void print_context(outputStream* st, const void* context);
|
||||
static void print_register_info(outputStream* st, const void* context);
|
||||
static bool signal_sent_by_kill(const void* siginfo);
|
||||
static void print_siginfo(outputStream* st, const void* siginfo);
|
||||
static void print_signal_handlers(outputStream* st, char* buf, size_t buflen);
|
||||
static void print_date_and_time(outputStream* st, char* buf, size_t buflen);
|
||||
|
@ -902,6 +902,16 @@ void SafepointSynchronize::print_safepoint_timeout() {
|
||||
// To debug the long safepoint, specify both AbortVMOnSafepointTimeout &
|
||||
// ShowMessageBoxOnError.
|
||||
if (AbortVMOnSafepointTimeout) {
|
||||
// Send the blocking thread a signal to terminate and write an error file.
|
||||
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur_thread = jtiwh.next(); ) {
|
||||
if (cur_thread->safepoint_state()->is_running()) {
|
||||
if (!os::signal_thread(cur_thread, SIGILL, "blocking a safepoint")) {
|
||||
break; // Could not send signal. Report fatal error.
|
||||
}
|
||||
// Give cur_thread a chance to report the error and terminate the VM.
|
||||
os::sleep(Thread::current(), 3000, false);
|
||||
}
|
||||
}
|
||||
fatal("Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.",
|
||||
SafepointTimeoutDelay, VMThread::vm_operation()->name());
|
||||
}
|
||||
|
@ -269,6 +269,9 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55382 and
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53017
|
||||
//
|
||||
#define ATTRIBUTE_ALIGNED(x) __attribute__((aligned(x+0)))
|
||||
// GCC versions older than 4.6.4 would fail even with "+0", and needs additional
|
||||
// cast to typeof(x) to work around the similar bug.
|
||||
//
|
||||
#define ATTRIBUTE_ALIGNED(x) __attribute__((aligned((typeof(x))x+0)))
|
||||
|
||||
#endif // SHARE_UTILITIES_GLOBALDEFINITIONS_GCC_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. 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
|
||||
@ -522,6 +522,9 @@ void VMError::report(outputStream* st, bool _verbose) {
|
||||
st->print("%s", buf);
|
||||
st->print(" (0x%x)", _id); // signal number
|
||||
st->print(" at pc=" PTR_FORMAT, p2i(_pc));
|
||||
if (_siginfo != NULL && os::signal_sent_by_kill(_siginfo)) {
|
||||
st->print(" (sent by kill)");
|
||||
}
|
||||
} else {
|
||||
if (should_report_bug(_id)) {
|
||||
st->print("Internal Error");
|
||||
|
@ -399,7 +399,6 @@ final class GaloisCounterMode extends FeedbackCipher {
|
||||
if (len > TRIGGERLEN) {
|
||||
int i = 0;
|
||||
int tlen; // incremental lengths
|
||||
// 96bit CTR x86 intrinsic
|
||||
final int plen = AES_BLOCK_SIZE * 6;
|
||||
// arbitrary formula to aid intrinsic without reaching buffer end
|
||||
final int count = len / 1024;
|
||||
@ -419,11 +418,11 @@ final class GaloisCounterMode extends FeedbackCipher {
|
||||
gctrPAndC.doFinal(in, inOfs, ilen, out, outOfs);
|
||||
processed += ilen;
|
||||
|
||||
int lastLen = len % AES_BLOCK_SIZE;
|
||||
int lastLen = ilen % AES_BLOCK_SIZE;
|
||||
if (lastLen != 0) {
|
||||
ghashAllToS.update(ct, ctOfs, len - lastLen);
|
||||
ghashAllToS.update(ct, ctOfs, ilen - lastLen);
|
||||
ghashAllToS.update(
|
||||
expandToOneBlock(ct, (ctOfs + len - lastLen), lastLen));
|
||||
expandToOneBlock(ct, (ctOfs + ilen - lastLen), lastLen));
|
||||
} else {
|
||||
ghashAllToS.update(ct, ctOfs, ilen);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2013, 2019, Oracle and/or its affiliates. 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
|
||||
@ -265,6 +265,7 @@ tier1_runtime = \
|
||||
-runtime/7158988/FieldMonitor.java \
|
||||
-runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \
|
||||
-runtime/CommandLine/PrintGCApplicationConcurrentTime.java \
|
||||
-runtime/CompressedOops/UseCompressedOops.java \
|
||||
-runtime/ConstantPool/IntfMethod.java \
|
||||
-runtime/ErrorHandling/CreateCoredumpOnCrash.java \
|
||||
-runtime/ErrorHandling/ErrorHandler.java \
|
||||
@ -346,6 +347,7 @@ hotspot_tier2_runtime = \
|
||||
runtime/ \
|
||||
serviceability/ \
|
||||
-runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \
|
||||
-runtime/CompressedOops/UseCompressedOops.java \
|
||||
-runtime/Thread/TestThreadDumpMonitorContention.java \
|
||||
-runtime/containers/ \
|
||||
-:tier1_runtime \
|
||||
|
@ -26,8 +26,8 @@
|
||||
* @bug 8148490
|
||||
* @summary Test correct saving and restoring of vector registers at safepoints.
|
||||
*
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:-TieredCompilation
|
||||
* -XX:+SafepointALot
|
||||
* @run main/othervm -Xbatch -XX:-TieredCompilation
|
||||
* -XX:+UnlockDiagnosticVMOptions -XX:+SafepointALot
|
||||
* -XX:CompileCommand=exclude,compiler.runtime.safepoints.TestRegisterRestoring::main
|
||||
* compiler.runtime.safepoints.TestRegisterRestoring
|
||||
*/
|
||||
|
@ -30,7 +30,7 @@
|
||||
* java.management
|
||||
* @build sun.hotspot.WhiteBox
|
||||
* @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. UseCompressedOops
|
||||
* @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. UseCompressedOops
|
||||
*/
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2019, SAP SE. 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.*;
|
||||
import jdk.test.lib.process.*;
|
||||
|
||||
/*
|
||||
* @test TestAbortVMOnSafepointTimeout
|
||||
* @summary Check if VM can kill thread which doesn't reach safepoint.
|
||||
* @bug 8219584
|
||||
* @requires vm.compiler2.enabled
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
*/
|
||||
|
||||
public class TestAbortVMOnSafepointTimeout {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length > 0) {
|
||||
int result = test_loop(3);
|
||||
System.out.println("This message would occur after some time with result " + result);
|
||||
return;
|
||||
}
|
||||
|
||||
testWith(500, 500);
|
||||
}
|
||||
|
||||
static int test_loop(int x) {
|
||||
int sum = 0;
|
||||
if (x != 0) {
|
||||
// Long running loop without safepoint.
|
||||
for (int y = 1; y < Integer.MAX_VALUE; ++y) {
|
||||
if (y % x == 0) ++sum;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static void testWith(int sfpt_interval, int timeout_delay) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+SafepointTimeout",
|
||||
"-XX:+SafepointALot",
|
||||
"-XX:+AbortVMOnSafepointTimeout",
|
||||
"-XX:SafepointTimeoutDelay=" + timeout_delay,
|
||||
"-XX:GuaranteedSafepointInterval=" + sfpt_interval,
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:-UseCountedLoopSafepoints",
|
||||
"-XX:LoopStripMiningIter=0",
|
||||
"-XX:LoopUnrollLimit=0",
|
||||
"-XX:CompileCommand=compileonly,TestAbortVMOnSafepointTimeout::test_loop",
|
||||
"-Xcomp",
|
||||
"-XX:-CreateCoredumpOnCrash",
|
||||
"-Xms64m",
|
||||
"TestAbortVMOnSafepointTimeout",
|
||||
"runTestLoop"
|
||||
);
|
||||
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
if (Platform.isWindows()) {
|
||||
output.shouldMatch("Safepoint sync time longer than");
|
||||
} else {
|
||||
output.shouldMatch("SIGILL");
|
||||
if (Platform.isLinux()) {
|
||||
output.shouldMatch("(sent by kill)");
|
||||
}
|
||||
output.shouldMatch("TestAbortVMOnSafepointTimeout.test_loop");
|
||||
}
|
||||
output.shouldNotHaveExitValue(0);
|
||||
}
|
||||
}
|
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. 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 javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.HashMap;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8220165
|
||||
* @summary Verify correctness of large data sizes for GCM.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This test stores the MD5 hash of correctly encrypted AES/GCM data for
|
||||
* particular data lengths. Those lengths are run on SunJCE to verify returns
|
||||
* the same MD5 hash of the encrypted data. These are not NIST data sets or
|
||||
* provided by any other organization. The data sets are known good values,
|
||||
* verified with two different JCE providers (solaris-sparcv9 ucrypto and
|
||||
* linux SunJCE).
|
||||
*
|
||||
* Lengths around 64k are chosen because 64k is the point where
|
||||
* com.sun.crypto.provider.GaloisCounterMode#doLastBlock() starts it's
|
||||
* intrinsic warmup
|
||||
*
|
||||
* Plaintext is all zeros. Preset key and IV.
|
||||
*
|
||||
* The choice of MD5 is for speed. Shortcoming of the algorithm are
|
||||
* not relevant for this test.
|
||||
*/
|
||||
|
||||
public class GCMLargeDataKAT {
|
||||
|
||||
// Hash of encrypted results of AES/GCM for particular lengths.
|
||||
// <data size, hash>
|
||||
static final HashMap<Integer, String> results = new HashMap<>() {{
|
||||
put(65534, "1397b91c31ce793895edace4e175bfee"); //64k-2
|
||||
put(65535, "4ad101c9f450e686668b3f8f05db96f0"); //64k-1
|
||||
put(65536, "fbfaee3451acd3f603200d6be0f39b24"); //64k
|
||||
put(65537, "e7dfca4a71495c65d20982c3c9b9813f"); //64k+1
|
||||
put(67583, "c8ebdcb3532ec6c165de961341af7635"); //66k-1
|
||||
put(67584, "36559d108dfd25dd29da3fec3455b9e5"); //66k
|
||||
put(67585, "1d21b42d80ea179810744fc23dc228b6"); //66k+1
|
||||
put(102400, "0d1544fcab20bbd4c8103b9d273f2c82"); //100k
|
||||
put(102401, "f2d53ef65fd12d0a861368659b23ea2e"); //100k+1
|
||||
put(102402, "97f0f524cf63d2d9d23d81e64d416ee0"); //100k+2
|
||||
put(102403, "4a6b4af55b7d9016b64114d6813d639c"); //100k+3
|
||||
put(102404, "ba63cc131fcde2f12ddf2ac634201be8"); //100k+4
|
||||
put(102405, "673d05c7fe5e283e42e5c0d049fdcea6"); //100k+5
|
||||
put(102406, "76cc99a7850ce857eb3cb43049cf9877"); //100k+6
|
||||
put(102407, "65863f99072cf2eb7fce18bd78b33f4e"); //100k+7
|
||||
put(102408, "b9184f0f272682cc1f791fa7070eddd4"); //100k+8
|
||||
put(102409, "45fe36afef43cc665bf22a9ca200c3c2"); //100k+9
|
||||
put(102410, "67249e41646edcb37a78a61b0743cf11"); //100k+0
|
||||
put(102411, "ffdc611e29c8849842e81ec78f32c415"); //100k+11
|
||||
put(102412, "b7fde7fd52221057dccc1c181a140125"); //100k+12
|
||||
put(102413, "4b1d6c64d56448105e5613157e69c0ae"); //100k+13
|
||||
put(102414, "6d2c0b26c0c8785c8eec3298a5f0080c"); //100k+14
|
||||
put(102415, "1df2061b114fbe56bdf3717e3ee61ef9"); //100k+15
|
||||
put(102416, "a691742692c683ac9d1254df5fc5f768"); //100k+16
|
||||
}};
|
||||
static final int HIGHLEN = 102416;
|
||||
|
||||
static final int GCM_TAG_LENGTH = 16;
|
||||
static final byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
static final byte[] key_code = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
static final GCMParameterSpec spec =
|
||||
new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
|
||||
static final SecretKey key = new SecretKeySpec(key_code, "AES");
|
||||
static boolean testresult = true;
|
||||
static byte[] plaintext = new byte[HIGHLEN];
|
||||
static MessageDigest md5;
|
||||
Cipher cipher;
|
||||
|
||||
GCMLargeDataKAT() {
|
||||
}
|
||||
|
||||
byte[] encrypt(int inLen) {
|
||||
try {
|
||||
cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
|
||||
return cipher.doFinal(plaintext, 0, inLen);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Encrypt Failure (length = " + inLen + ") : " +
|
||||
e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
static byte[] hash(byte[] data) {
|
||||
return md5.digest(data);
|
||||
}
|
||||
|
||||
// Decrypt the data and return a boolean if the plaintext is all 0's.
|
||||
boolean decrypt(byte[] data) {
|
||||
byte[] result = null;
|
||||
int len = data.length - GCM_TAG_LENGTH;
|
||||
if (data.length == 0) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, spec);
|
||||
result = cipher.doFinal(data);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Decrypt Failure (length = " + len + ") : " +
|
||||
e.getMessage());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result.length != len) {
|
||||
System.err.println("Decrypt Failure (length = " + len +
|
||||
") : plaintext length invalid = " + result.length);
|
||||
}
|
||||
// Return false if we find a non zero.
|
||||
int i = 0;
|
||||
while (result.length > i) {
|
||||
if (result[i++] != 0) {
|
||||
System.err.println("Decrypt Failure (length = " + len +
|
||||
") : plaintext invalid, char index " + i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void test() throws Exception {
|
||||
|
||||
// results order is not important
|
||||
for (int l : results.keySet()) {
|
||||
byte[] enc = new GCMLargeDataKAT().encrypt(l);
|
||||
|
||||
// verify hash with stored hash of that length
|
||||
String hashstr = toHex(hash(enc));
|
||||
boolean r = (hashstr.compareTo(results.get(l)) == 0);
|
||||
|
||||
System.out.println("---------------------------------------------");
|
||||
|
||||
// Encrypted test & results
|
||||
System.out.println("Encrypt data size " + l + " \tResult: " +
|
||||
(r ? "Pass" : "Fail"));
|
||||
if (!r) {
|
||||
if (enc.length != 0) {
|
||||
System.out.println("\tExpected: " + results.get(l));
|
||||
System.out.println("\tReturned: " + hashstr);
|
||||
}
|
||||
testresult = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Decrypted test & results
|
||||
r = decrypt(enc);
|
||||
System.out.println("Decrypt data size " + l + " \tResult: " +
|
||||
(r ? "Pass" : "Fail"));
|
||||
if (!r) {
|
||||
testresult = false;
|
||||
}
|
||||
}
|
||||
|
||||
// After test complete, throw an error if there was a failure
|
||||
if (!testresult) {
|
||||
throw new Exception("Tests failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* With no argument, the test will run the predefined data lengths
|
||||
*
|
||||
* With an integer argument, this test will print the hash of the encrypted
|
||||
* data of that integer length.
|
||||
*
|
||||
*/
|
||||
public static void main(String args[]) throws Exception {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
|
||||
if (args.length > 0) {
|
||||
int len = Integer.parseInt(args[0]);
|
||||
byte[] e = new GCMLargeDataKAT().encrypt(len);
|
||||
System.out.println(toHex(hash(e)));
|
||||
return;
|
||||
}
|
||||
|
||||
new GCMLargeDataKAT().test();
|
||||
}
|
||||
|
||||
// bytes to hex string
|
||||
static String toHex(byte[] bytes) {
|
||||
StringBuffer hexStringBuffer = new StringBuffer(32);
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
hexStringBuffer.append(byteToHex(bytes[i]));
|
||||
}
|
||||
return hexStringBuffer.toString();
|
||||
}
|
||||
// byte to hex
|
||||
static String byteToHex(byte num) {
|
||||
char[] hexDigits = new char[2];
|
||||
hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16);
|
||||
hexDigits[1] = Character.forDigit((num & 0xF), 16);
|
||||
return new String(hexDigits);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user