undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
58
test/jdk/ProblemList-AotJdk.txt
Normal file
58
test/jdk/ProblemList-AotJdk.txt
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#
|
||||
# Copyright (c) 2024, 2026, 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.
|
||||
#
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# List of quarantined tests for testing in AOT_JDK mode.
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
java/math/BigInteger/largeMemory/DivisionOverflow.java 0000000 generic-all
|
||||
java/math/BigInteger/largeMemory/StringConstructorOverflow.java 0000000 generic-all
|
||||
|
||||
jdk/internal/misc/CDS/ArchivedEnumTest.java 0000000 generic-all
|
||||
|
||||
java/lang/module/ModuleDescriptorHashCodeTest.java 0000000 generic-all
|
||||
|
||||
|
||||
# The test case is incorrect. There's no guarantee that running a JVM with the following
|
||||
# parameters will always cause the class java/lang/invoke/MethodHandleStatics to be initialized
|
||||
java/lang/invoke/DumpMethodHandleInternals.java 0000000 generic-all
|
||||
|
||||
# This test checks for a warning message that's already printed by
|
||||
# sun.util.locale.BaseLocale.<clinit> during the training run. Because BaseLocale is aot-initialized,
|
||||
# this message will not be printed in the production run.
|
||||
java/util/Locale/UseOldISOCodesTest.java 0000000 generic-all
|
||||
|
||||
#############################################################################
|
||||
|
||||
# Preview project specific failures go here at the end of the file.
|
||||
#
|
||||
# These are NOT failures that occur with the '--enable-preview' option
|
||||
# specified; those go in the appropriate ProblemList-enable-preview.txt file.
|
||||
# These are failures that occur WITHOUT the '--enable-preview' option
|
||||
# specified AND occur because of some issue with preview project code,
|
||||
# in either implementation or test code.
|
||||
|
||||
#############################################################################
|
||||
|
||||
39
test/jdk/ProblemList-StaticJdk.txt
Normal file
39
test/jdk/ProblemList-StaticJdk.txt
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
###########################################################################
|
||||
#
|
||||
# Copyright (c) 2025, 2026, 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.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Currently empty
|
||||
|
||||
#############################################################################
|
||||
|
||||
# Preview project specific failures go here at the end of the file.
|
||||
#
|
||||
# These are NOT failures that occur with the '--enable-preview' option
|
||||
# specified; those go in the appropriate ProblemList-enable-preview.txt file.
|
||||
# These are failures that occur WITHOUT the '--enable-preview' option
|
||||
# specified AND occur because of some issue with preview project code,
|
||||
# in either implementation or test code.
|
||||
|
||||
#############################################################################
|
||||
|
||||
48
test/jdk/ProblemList-Virtual.txt
Normal file
48
test/jdk/ProblemList-Virtual.txt
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#
|
||||
# Copyright (c) 2022, 2026, 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.
|
||||
#
|
||||
|
||||
com/sun/jdi/EATests.java#id0 8264699 generic-all
|
||||
|
||||
##########
|
||||
## Tests failing when main() is executed in additional vthread or in vthread instead of thread
|
||||
#
|
||||
|
||||
com/sun/jdi/ExceptionEvents.java 8278470 generic-all
|
||||
com/sun/jdi/RedefineCrossStart.java 8278470 generic-all
|
||||
|
||||
java/lang/ScopedValue/StressStackOverflow.java#default 8309646 generic-all
|
||||
java/lang/ScopedValue/StressStackOverflow.java#no-TieredCompilation 8309646 generic-all
|
||||
java/lang/ScopedValue/StressStackOverflow.java#TieredStopAtLevel1 8309646 generic-all
|
||||
|
||||
#############################################################################
|
||||
|
||||
# Preview project specific failures go here at the end of the file.
|
||||
#
|
||||
# These are NOT failures that occur with the '--enable-preview' option
|
||||
# specified; those go in the appropriate ProblemList-enable-preview.txt file.
|
||||
# These are failures that occur WITHOUT the '--enable-preview' option
|
||||
# specified AND occur because of some issue with preview project code,
|
||||
# in either implementation or test code.
|
||||
|
||||
#############################################################################
|
||||
|
||||
44
test/jdk/ProblemList-Xcomp.txt
Normal file
44
test/jdk/ProblemList-Xcomp.txt
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# Copyright (c) 2018, 2026, 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.
|
||||
#
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# List of quarantined tests for testing in Xcomp mode.
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all
|
||||
java/lang/reflect/callerCache/ReflectionCallerCacheTest.java 8332028 generic-all
|
||||
|
||||
#############################################################################
|
||||
|
||||
# Preview project specific failures go here at the end of the file.
|
||||
#
|
||||
# These are NOT failures that occur with the '--enable-preview' option
|
||||
# specified; those go in the appropriate ProblemList-enable-preview.txt file.
|
||||
# These are failures that occur WITHOUT the '--enable-preview' option
|
||||
# specified AND occur because of some issue with preview project code,
|
||||
# in either implementation or test code.
|
||||
|
||||
#############################################################################
|
||||
|
||||
41
test/jdk/ProblemList-coh.txt
Normal file
41
test/jdk/ProblemList-coh.txt
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# Copyright (c) 2026, 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.
|
||||
#
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# List of quarantined tests for testing with -XX:+UseCompactObjectHeaders
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
|
||||
# Preview project specific failures go here at the end of the file.
|
||||
#
|
||||
# These are NOT failures that occur with the '--enable-preview' option
|
||||
# specified; those go in the appropriate ProblemList-enable-preview.txt file.
|
||||
# These are failures that occur WITHOUT the '--enable-preview' option
|
||||
# specified AND occur because of some issue with preview project code,
|
||||
# in either implementation or test code.
|
||||
|
||||
#############################################################################
|
||||
|
||||
32
test/jdk/ProblemList-enable-preview.txt
Normal file
32
test/jdk/ProblemList-enable-preview.txt
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# Copyright (c) 2025, 2026, 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.
|
||||
#
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# List of quarantined tests for testing with --enable-preview
|
||||
#
|
||||
# These are failures that ONLY occur with the '--enable-preview' option
|
||||
# specified. There are separate sub-sections for each preview project.
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
44
test/jdk/ProblemList-jvmti-stress-agent.txt
Normal file
44
test/jdk/ProblemList-jvmti-stress-agent.txt
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# Copyright (c) 2025, 2026, 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.
|
||||
#
|
||||
|
||||
# List of tests incompatible with jvmti stress agent or requiring more investigation
|
||||
|
||||
com/sun/jdi/EATests.java#id0 0000000 generic-all
|
||||
com/sun/jdi/ThreadMemoryLeakTest.java 0000000 generic-all
|
||||
|
||||
# weak referenced are not cleared
|
||||
java/lang/WeakPairMap/Driver.java 0000000 generic-all
|
||||
java/lang/ref/ReachabilityFenceTest.java 0000000 generic-all
|
||||
|
||||
#############################################################################
|
||||
|
||||
# Preview project specific failures go here at the end of the file.
|
||||
#
|
||||
# These are NOT failures that occur with the '--enable-preview' option
|
||||
# specified; those go in the appropriate ProblemList-enable-preview.txt file.
|
||||
# These are failures that occur WITHOUT the '--enable-preview' option
|
||||
# specified AND occur because of some issue with preview project code,
|
||||
# in either implementation or test code.
|
||||
|
||||
#############################################################################
|
||||
|
||||
72
test/jdk/ProblemList-shenandoah.txt
Normal file
72
test/jdk/ProblemList-shenandoah.txt
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#
|
||||
# Copyright Amazon.com Inc. 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.
|
||||
#
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# List of quarantined tests for testing with Shenandoah.
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
# Quiet all LeakProfiler tests
|
||||
|
||||
jdk/jfr/api/consumer/TestRecordingFileWrite.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestAllocationTime.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestArrayInformation.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestCircularReference.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestClassLoaderLeak.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestFieldInformation.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestG1.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestHeapDeep.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestHeapShallow.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestLargeRootSet.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestLastKnownHeapUsage.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestListenerLeak.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestMetadataRetention.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestObjectAge.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestObjectDescription.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestObjectSize.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestParallel.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestReferenceChainLimit.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestSanityDefault.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestSerial.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestShenandoah.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestThreadLocalLeak.java 8342951 generic-all
|
||||
jdk/jfr/event/oldobject/TestZ.java 8342951 generic-all
|
||||
jdk/jfr/jcmd/TestJcmdDump.java 8342951 generic-all
|
||||
jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java 8342951 generic-all
|
||||
jdk/jfr/jcmd/TestJcmdStartPathToGCRoots.java 8342951 generic-all
|
||||
jdk/jfr/jvm/TestWaste.java 8342951 generic-all
|
||||
jdk/jfr/startupargs/TestOldObjectQueueSize.java 8342951 generic-all
|
||||
|
||||
#############################################################################
|
||||
|
||||
# Preview project specific failures go here at the end of the file.
|
||||
#
|
||||
# These are NOT failures that occur with the '--enable-preview' option
|
||||
# specified; those go in the appropriate ProblemList-enable-preview.txt file.
|
||||
# These are failures that occur WITHOUT the '--enable-preview' option
|
||||
# specified AND occur because of some issue with preview project code,
|
||||
# in either implementation or test code.
|
||||
|
||||
#############################################################################
|
||||
|
||||
43
test/jdk/ProblemList-zgc.txt
Normal file
43
test/jdk/ProblemList-zgc.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#
|
||||
# Copyright (c) 2020, 2026, 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.
|
||||
#
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# List of quarantined tests for testing with ZGC.
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
com/sun/jdi/ThreadMemoryLeakTest.java 8307402 generic-all
|
||||
|
||||
#############################################################################
|
||||
|
||||
# Preview project specific failures go here at the end of the file.
|
||||
#
|
||||
# These are NOT failures that occur with the '--enable-preview' option
|
||||
# specified; those go in the appropriate ProblemList-enable-preview.txt file.
|
||||
# These are failures that occur WITHOUT the '--enable-preview' option
|
||||
# specified AND occur because of some issue with preview project code,
|
||||
# in either implementation or test code.
|
||||
|
||||
#############################################################################
|
||||
|
||||
795
test/jdk/ProblemList.txt
Normal file
795
test/jdk/ProblemList.txt
Normal file
|
|
@ -0,0 +1,795 @@
|
|||
###########################################################################
|
||||
#
|
||||
# Copyright (c) 2009, 2026, 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.
|
||||
#
|
||||
###########################################################################
|
||||
#
|
||||
# List of tests that should not be run by test/Makefile, for various reasons:
|
||||
# 1. Does not run with jtreg -samevm mode
|
||||
# 2. Causes problems in jtreg -samevm mode for jtreg or tests that follow it
|
||||
# 3. The test is too slow or consumes too many system resources
|
||||
# 4. The test fails when run on any official build systems
|
||||
#
|
||||
# It is possible that a test being on this list is a mistake, and that some
|
||||
# other test in samevm mode caused tests to fail, mistakes happen.
|
||||
#
|
||||
# Tests marked @ignore are not run by test/Makefile, but harmless to be listed.
|
||||
#
|
||||
# Tests that explicitly state "@run main/othervm ...", and are not listed here,
|
||||
# will be run in the same batch as the samevm tests.
|
||||
#
|
||||
# Shell tests are othervm by default.
|
||||
#
|
||||
# List items are testnames followed by labels, all MUST BE commented
|
||||
# as to why they are here and use a label:
|
||||
# generic-all Problems on all platforms
|
||||
# generic-ARCH Where ARCH is one of: x64, i586, ppc64, ppc64le, s390x, aarch64 etc.
|
||||
# OSNAME-all Where OSNAME is one of: linux, windows, macosx, aix
|
||||
# OSNAME-ARCH Specific on to one OSNAME and ARCH, e.g. macosx-x64
|
||||
# OSNAME-REV Specific on to one OSNAME and REV, e.g. macosx-10.7.4
|
||||
#
|
||||
# More than one label is allowed but must be on the same line comma seperated,
|
||||
# without spaces.
|
||||
# If there are several lines mentioning the same test, the last one is used.
|
||||
#
|
||||
#############################################################################
|
||||
#
|
||||
# Running the tests:
|
||||
# cd test && make JT_HOME=jtreg_home PRODUCT_HOME=jdk_home jdk_all
|
||||
# Or instead of jdk_all, use any of the jdk_* targets.
|
||||
#
|
||||
# Samevm Notes:
|
||||
# * Although some tests may have only been seen to fail on some platforms,
|
||||
# they might be flagged as 'generic-all' because the problem they have
|
||||
# could cause hidden slowdowns on other platforms.
|
||||
# Most samevm problems will be generic-all, but windows usually dislikes
|
||||
# them the most.
|
||||
# Address already in use or connection errors indicate a generic port issue.
|
||||
# (this is not necessarily a samevm issue, but an issue for running the tests
|
||||
# on shared machines, two people or two test runs will collide).
|
||||
# * Samevm problem (windows in particular) is not closing all input/output
|
||||
# * Samevm problem when a test calls setSecurityManager()
|
||||
# * Samevm problem with setHttps*() is used? (not exactly sure here)
|
||||
# * Samevm problem when stuffing system properties with non Strings or anything
|
||||
# * Samevm problem when changing vm settings, or registering any vm actions
|
||||
# * Samevm problems with deleteOnExit(), if it must happen at end of test
|
||||
# * Samevm problems with URLClassLoader? (no details here)
|
||||
# * Samevm problems with dependence on predictable GC or finalizations
|
||||
#
|
||||
# Any of the above problems may mean the test needs to be flagged as "othervm".
|
||||
#
|
||||
#############################################################################
|
||||
#
|
||||
# Fixing the tests:
|
||||
#
|
||||
# Some tests just may need to be run with "othervm", and that can easily be
|
||||
# done by adding a @run line (or modifying any existing @run):
|
||||
# @run main/othervm NameOfMainClass
|
||||
# Make sure this @run follows any use of @library.
|
||||
# Otherwise, if the test is a samevm possibility, make sure the test is
|
||||
# cleaning up after itself, closing all streams, deleting temp files, etc.
|
||||
#
|
||||
# Keep in mind that the bug could be in many places, and even different per
|
||||
# platform, it could be a bug in any one of:
|
||||
# - the testcase
|
||||
# - the jdk (jdk classes, native code, or hotspot)
|
||||
# - the native compiler
|
||||
# - the javac compiler
|
||||
# - the OS (depends on what the testcase does)
|
||||
#
|
||||
# If you managed to really fix one of these tests, here is how you can
|
||||
# remove tests from this list:
|
||||
# 1. Make sure test passes on all platforms with samevm, or mark it othervm
|
||||
# 2. Make sure test passes on all platforms when run with it's entire group
|
||||
# 3. Make sure both VMs are tested, -server and -client, if possible
|
||||
# 4. Use your favorite build and test system to verify these results
|
||||
# 5. Delete lines in this file, include the changes with your test changes
|
||||
#
|
||||
# You may need to repeat your testing 2 or even 3 times to verify good
|
||||
# results, some of these samevm failures are not very predictable.
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_awt
|
||||
|
||||
java/awt/event/MouseEvent/MouseClickTest/MouseClickTest.java 8168389 windows-all,macosx-all
|
||||
java/awt/event/KeyEvent/SwallowKeyEvents/SwallowKeyEvents.java 8224055 macosx-all
|
||||
java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java 8081489 generic-all
|
||||
java/awt/Focus/IconifiedFrameFocusChangeTest/IconifiedFrameFocusChangeTest.java 6849364 generic-all
|
||||
java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java 6848406 generic-all
|
||||
java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java 6848407 generic-all
|
||||
java/awt/Frame/MaximizedToMaximized/MaximizedToMaximized.java 8340374 macosx-all
|
||||
java/awt/Frame/MaximizedUndecorated/MaximizedUndecorated.java 8022302 generic-all
|
||||
java/awt/Frame/RestoreToOppositeScreen/RestoreToOppositeScreen.java 8286840 linux-all
|
||||
java/awt/Frame/InitialIconifiedTest.java 7144049,8203920 macosx-all,linux-all
|
||||
java/awt/Frame/FocusTest.java 8341480 macosx-all
|
||||
java/awt/FileDialog/FileDialogIconTest/FileDialogIconTest.java 8160558 windows-all
|
||||
java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java 8060176 windows-all,macosx-all
|
||||
java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java 8060176 windows-all,macosx-all
|
||||
java/awt/dnd/FileListBetweenJVMsTest/FileListBetweenJVMsTest.java 8353673 macosx-all
|
||||
java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.java 8171510 macosx-all
|
||||
java/awt/dnd/MissingDragExitEventTest/MissingDragExitEventTest.java 8288839 windows-x64,macosx-all
|
||||
java/awt/dnd/DragExitBeforeDropTest.java 8242805 macosx-all
|
||||
java/awt/dnd/DragThresholdTest.java 8076299 macosx-all
|
||||
java/awt/dnd/CustomDragCursorTest.java 8242805 macosx-all
|
||||
java/awt/Focus/ChoiceFocus/ChoiceFocus.java 8169103 windows-all,macosx-all
|
||||
java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java 8198618 macosx-all
|
||||
java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java 6986252 macosx-all
|
||||
java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java 8194753 linux-all,macosx-all
|
||||
java/awt/Focus/NoAutotransferToDisabledCompTest/NoAutotransferToDisabledCompTest.java 7152980 macosx-all
|
||||
java/awt/Focus/ToFrontFocusTest/ToFrontFocus.java 7156130 linux-all
|
||||
java/awt/Focus/WrongKeyTypedConsumedTest/WrongKeyTypedConsumedTest.java 8169096 macosx-all
|
||||
java/awt/Focus/TestDisabledAutoTransfer.java 8159871 macosx-all,windows-all
|
||||
java/awt/Focus/TestDisabledAutoTransferSwing.java 6962362 windows-all
|
||||
java/awt/Focus/ActivateOnProperAppContextTest.java 8136516 macosx-all
|
||||
java/awt/Focus/FocusPolicyTest.java 7160904 linux-all
|
||||
java/awt/Graphics/SmallPrimitives.java 8047070 macosx-all,linux-all
|
||||
java/awt/EventQueue/6980209/bug6980209.java 8198615 macosx-all
|
||||
java/awt/EventQueue/PushPopDeadlock/PushPopDeadlock.java 8024034 generic-all
|
||||
java/awt/grab/EmbeddedFrameTest1/EmbeddedFrameTest1.java 7080150 macosx-all
|
||||
java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java 8168646 generic-all
|
||||
java/awt/List/KeyEventsTest/KeyEventsTest.java 8201307 linux-all
|
||||
java/awt/List/NoEvents/ProgrammaticChange.java 8201307 linux-all
|
||||
java/awt/Paint/ListRepaint.java 8201307 linux-all
|
||||
java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java 8370584 windows-x64
|
||||
java/awt/Mixing/AWT_Mixing/OpaqueOverlappingChoice.java 8048171 generic-all
|
||||
java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java 8159451 linux-all,windows-all,macosx-all
|
||||
java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java 6986109 generic-all
|
||||
java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java 6986109 windows-all
|
||||
java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java 8049405 generic-all
|
||||
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8049405 macosx-all
|
||||
java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java 8049405 macosx-all
|
||||
java/awt/Mixing/AWT_Mixing/JTableInGlassPaneOverlapping.java 8357360 windows-all,linux-all
|
||||
java/awt/Mixing/NonOpaqueInternalFrame.java 7124549 macosx-all
|
||||
java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java 6829264 generic-all
|
||||
java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java 8080982 generic-all
|
||||
java/awt/datatransfer/SystemFlavorMap/AddFlavorTest.java 8079268 linux-all
|
||||
java/awt/datatransfer/ClipboardPerformanceTest.java 8029022 windows-all
|
||||
java/awt/datatransfer/HTMLTransferConsoleOutputTest.java 8237254 macosx-all
|
||||
java/awt/datatransfer/ImageTransferCrashTest.java 8237253 macosx-all
|
||||
java/awt/Toolkit/RealSync/Test.java 6849383 linux-all
|
||||
java/awt/LightweightComponent/LightweightEventTest/LightweightEventTest.java 8159252 windows-all
|
||||
java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java 8072110 macosx-all
|
||||
java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java 8073636 macosx-all
|
||||
java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java 7019055,8266245 windows-all,linux-all,macosx-all
|
||||
java/awt/FullScreen/BufferStrategyExceptionTest/BufferStrategyExceptionTest.java 8246558 windows-all
|
||||
java/awt/Focus/8013611/JDK8013611.java 8175366 windows-all,macosx-all
|
||||
java/awt/Focus/6981400/Test1.java 8029675 windows-all,macosx-all
|
||||
java/awt/Focus/6981400/Test3.java 8173264 generic-all
|
||||
java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java 8169476 windows-all,macosx-all
|
||||
java/awt/event/KeyEvent/KeyChar/KeyCharTest.java 8169474,8224055 macosx-all,windows-all
|
||||
java/awt/event/KeyEvent/KeyTyped/CtrlASCII.java 8298910 linux-all
|
||||
|
||||
java/awt/dnd/DnDRemoveFocusOwnerCrashTest.java 8242805 macosx-all
|
||||
java/awt/dnd/DnDCursorCrashTest.java 8242805 macosx-all
|
||||
java/awt/dnd/DnDClipboardDeadlockTest.java 8079553 linux-all
|
||||
java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.java 8194947 generic-all
|
||||
java/awt/Frame/FramesGC/FramesGC.java 8079069 macosx-all
|
||||
java/awt/TrayIcon/ActionCommand/ActionCommand.java 8150540 windows-all
|
||||
java/awt/TrayIcon/ActionEventMask/ActionEventMask.java 8150540,8295300 windows-all,linux-all
|
||||
java/awt/TrayIcon/ActionEventTest/ActionEventTest.java 8150540,8242801 windows-all,macosx-all
|
||||
java/awt/TrayIcon/ModalityTest/ModalityTest.java 8150540,8295300 windows-all,macosx-all,linux-all
|
||||
java/awt/TrayIcon/MouseEventMask/MouseEventMaskTest.java 8150540,8295300 windows-all,linux-all
|
||||
java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java 8150540,8295300 windows-all,linux-all
|
||||
java/awt/TrayIcon/SecurityCheck/FunctionalityCheck/FunctionalityCheck.java 8150540,8295300 windows-all,linux-all
|
||||
java/awt/TrayIcon/TrayIconEventModifiers/TrayIconEventModifiersTest.java 8150540,8295300 windows-all,linux-all
|
||||
java/awt/TrayIcon/TrayIconEvents/TrayIconEventsTest.java 8150540,8295300 windows-all,linux-all
|
||||
java/awt/TrayIcon/TrayIconMouseTest/TrayIconMouseTest.java 8150540 windows-all
|
||||
java/awt/TrayIcon/TrayIconPopup/TrayIconPopupClickTest.java 8150540 windows-all,macosx-all
|
||||
java/awt/TrayIcon/TrayIconPopup/TrayIconPopupTest.java 8150540 windows-all
|
||||
java/awt/TrayIcon/MouseMoveTest.java 8203053 linux-all
|
||||
java/awt/TrayIcon/TrayIconKeySelectTest.java 8341557 windows-all
|
||||
java/awt/TrayIcon/TrayIconTest.java 8341559 generic-all
|
||||
|
||||
java/awt/Window/ShapedAndTranslucentWindows/SetShapeAndClick.java 8197936 macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/SetShapeDynamicallyAndClick.java 8013450 macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/ShapedTranslucentWindowClick.java 8013450 macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/FocusAWTTest.java 8222328 windows-all,linux-all,macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/Shaped.java 8222328 windows-all,linux-all,macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/ShapedByAPI.java 8222328 windows-all,linux-all,macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/ShapedTranslucent.java 8222328 windows-all,linux-all,macosx-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/StaticallyShaped.java 8165218,8222328 windows-all,macosx-all,linux-all
|
||||
java/awt/Window/ShapedAndTranslucentWindows/Translucent.java 8222328 windows-all,linux-all,macosx-all
|
||||
java/awt/Window/AlwaysOnTop/AutoTestOnTop.java 6847593 linux-all
|
||||
java/awt/Window/GrabSequence/GrabSequence.java 6848409 macosx-all,linux-all
|
||||
java/awt/Window/LocationAtScreenCorner/LocationAtScreenCorner.java 8203371 linux-all
|
||||
java/awt/font/TextLayout/TextLayoutBounds.java 8169188 generic-all
|
||||
java/awt/image/BufferedImage/ICMColorDataTest/ICMColorDataTest.java 8233028 generic-all
|
||||
java/awt/image/DrawImage/IncorrectAlphaSurface2SW.java 8056077 linux-all
|
||||
java/awt/print/Headless/HeadlessPrinterJob.java 8196088 windows-all
|
||||
sun/awt/datatransfer/SuplementaryCharactersTransferTest.java 8011371 generic-all
|
||||
sun/awt/shell/ShellFolderMemoryLeak.java 8197794 windows-all
|
||||
sun/java2d/DirectX/OverriddenInsetsTest/OverriddenInsetsTest.java 8196102 generic-all
|
||||
sun/java2d/DirectX/RenderingToCachedGraphicsTest/RenderingToCachedGraphicsTest.java 8196180 windows-all,macosx-all
|
||||
sun/java2d/OpenGL/MultiWindowFillTest.java 8378506 macosx-all
|
||||
sun/java2d/OpenGL/OpaqueDest.java#id1 8367574 macosx-all
|
||||
sun/java2d/OpenGL/ScaleParamsOOB.java#id0 8377908 linux-all
|
||||
sun/java2d/SunGraphics2D/EmptyClipRenderingTest.java 8144029 macosx-all,linux-all
|
||||
sun/java2d/SunGraphics2D/DrawImageBilinear.java 8297175 linux-all
|
||||
sun/java2d/SunGraphics2D/PolyVertTest.java 6986565 generic-all
|
||||
sun/java2d/SunGraphics2D/SimplePrimQuality.java 6992007 generic-all
|
||||
sun/java2d/SunGraphics2D/SourceClippingBlitTest/SourceClippingBlitTest.java 8196185 generic-all
|
||||
|
||||
java/awt/FullScreen/DisplayChangeVITest/DisplayChangeVITest.java 8169469,8273617 windows-all,macosx-aarch64
|
||||
java/awt/FullScreen/UninitializedDisplayModeChangeTest/UninitializedDisplayModeChangeTest.java 8273617 macosx-all
|
||||
java/awt/print/PrinterJob/PSQuestionMark.java 7003378 generic-all
|
||||
java/awt/print/PrinterJob/GlyphPositions.java 7003378 generic-all
|
||||
java/awt/Component/GetScreenLocTest/GetScreenLocTest.java 4753654 generic-all
|
||||
java/awt/Component/SetEnabledPerformance/SetEnabledPerformance.java 8165863 macosx-all
|
||||
java/awt/Clipboard/PasteNullToTextComponentsTest.java 8234140 macosx-all,windows-all
|
||||
java/awt/Clipboard/NoOwnerNoTargetsTest.java 8234140 macosx-all
|
||||
java/awt/Clipboard/LostOwnershipChainTest/SystemClipboard2ProcTest.java 8234140 macosx-all
|
||||
java/awt/Clipboard/HTMLTransferTest/HTMLTransferTest.java 8017454 macosx-all
|
||||
java/awt/Clipboard/ClipboardSecurity.java 8054809 macosx-all
|
||||
java/awt/Clipboard/GetAltContentsTest/SystemClipboardTest.java 8234140 macosx-all
|
||||
java/awt/Clipboard/ImageTransferTest.java 8030710 generic-all
|
||||
java/awt/Clipboard/NoDataConversionFailureTest.java 8234140 macosx-all
|
||||
java/awt/Dialog/ModalExcludedTest.java 7125054 macosx-all
|
||||
java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244 macosx-aarch64
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal1Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal2Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal3Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal4Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal5Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogAppModal6Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal1Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal2Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal3Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal4Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal5Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal6Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogDocModal7Test.java 7186009 macosx-all,linux-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal1Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal2Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal3Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal4Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal5Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogModal6Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal1Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal2Test.java 7186009 macosx-all,linux-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal3Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal4Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal5Test.java 7186009 macosx-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal6Test.java 7186009 macosx-all,linux-all
|
||||
java/awt/Modal/FileDialog/FileDialogNonModal7Test.java 7186009 macosx-all,linux-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal1Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal2Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal3Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal4Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal5Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal6Test.java 8196430 generic-all
|
||||
java/awt/Modal/FileDialog/FileDialogTKModal7Test.java 8196430 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDAppModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDDocModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDModelessTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDNonModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDSetModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDDToolkitModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFAppModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFSetModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFToolkitModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFWModeless1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFWModeless2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFWNonModal1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDFWNonModal2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingDocModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDModelessTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDNonModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWDocModal1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWDocModal2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWDocModal3Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWDocModal4Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWModeless1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWModeless2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWModeless3Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWModeless4Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWNonModal1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWNonModal2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWNonModal3Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingFDWNonModal4Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsAppModal1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsAppModal2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsAppModal3Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsAppModal4Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsAppModal5Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsAppModal6Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsDocModal1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsDocModal2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsSetModal1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsSetModal2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsSetModal3Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsSetModal4Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsSetModal5Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsSetModal6Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsToolkitModal1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsToolkitModal2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsToolkitModal3Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsToolkitModal4Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsToolkitModal5Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/BlockingWindowsToolkitModal6Test.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/UnblockedDialogAppModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/UnblockedDialogDocModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/UnblockedDialogModelessTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/UnblockedDialogNonModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/UnblockedDialogSetModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalBlockingTests/UnblockedDialogToolkitModalTest.java 8198665 macosx-all
|
||||
java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java 8066259 macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ApplicationExcludeFrameFileTest.java 8047179 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ApplicationExcludeDialogFileTest.java 8047179 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ApplicationExcludeDialogPageSetupTest.java 8196431 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ApplicationExcludeDialogPrintSetupTest.java 8196431 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ApplicationExcludeFramePageSetupTest.java 8196431 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ApplicationExcludeFramePrintSetupTest.java 8196431 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ToolkitExcludeFrameFileTest.java 8047179 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ToolkitExcludeDialogFileTest.java 8047179 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ToolkitExcludeDialogPageSetupTest.java 8196431 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ToolkitExcludeDialogPrintSetupTest.java 8196431 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ToolkitExcludeFramePageSetupTest.java 8196431 linux-all,macosx-all
|
||||
java/awt/Modal/ModalExclusionTests/ToolkitExcludeFramePrintSetupTest.java 8196431 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFAppModal2Test.java 8058813 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFModeless2Test.java 8196191 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFDocModalTest.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFModelessTest.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFNonModalTest.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsModelessTest.java 8196432 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsNonModalTest.java 8196432 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFDWDocModalTest.java 8196432 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFDWModelessTest.java 8196432 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFDWNonModalTest.java 8196432 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDAppModal1Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDAppModal2Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDAppModal3Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDAppModal4Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDDocModal1Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDDocModal2Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDDocModal3Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDDocModal4Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDModeless1Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDModeless2Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDModeless3Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDModeless4Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDNonModal1Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDNonModal2Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDNonModal3Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferFWDNonModal4Test.java 8196432 linux-all,macosx-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFDocModal2Test.java 8196432 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal2Test.java 8196432 linux-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs3Test.java 8198665 macosx-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs4Test.java 8198665 macosx-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs5Test.java 8198665 macosx-all
|
||||
java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java 8177326 macosx-all
|
||||
java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java 8005021 macosx-all
|
||||
java/awt/Mouse/EnterExitEvents/FullscreenEnterEventTest.java 8051455 macosx-all
|
||||
java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Standard.java 7124407,8302787 macosx-all,windows-all
|
||||
java/awt/Mouse/RemovedComponentMouseListener/RemovedComponentMouseListener.java 8157170 macosx-all
|
||||
java/awt/Modal/ToFront/DialogToFrontNonModalTest.java 8221899 linux-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal1Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal2Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal3Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal4Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal5Test.java 8196441 macosx-all
|
||||
java/awt/Modal/ToBack/ToBackAppModal6Test.java 8196441 linux-all
|
||||
java/awt/Modal/ToBack/ToBackModal1Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackModal2Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackModal3Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackModal4Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal1Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal2Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal3Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal4Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackTKModal5Test.java 8196441 macosx-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal1Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal2Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal3Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal4Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackDocModal5Test.java 8196441 linux-all,macosx-all
|
||||
java/awt/Modal/ToBack/ToBackModeless1Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackModeless2Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackModeless3Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackModeless4Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackModeless5Test.java 8196441 macosx-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal1Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal2Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal3Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal4Test.java 8196441 macosx-all,linux-all
|
||||
java/awt/Modal/ToBack/ToBackNonModal5Test.java 8196441 macosx-all
|
||||
javax/print/PrintSEUmlauts/PrintSEUmlauts.java 8135174 generic-all
|
||||
java/awt/font/Rotate/RotatedTextTest.java 8219641 linux-all
|
||||
java/awt/font/TextLayout/LigatureCaretTest.java 8266312 generic-all
|
||||
java/awt/image/VolatileImage/CustomCompositeTest.java 8199002 windows-all,linux-all
|
||||
java/awt/image/VolatileImage/GradientPaints.java 8199003 linux-all
|
||||
java/awt/JAWT/JAWT.sh 8197798 windows-all,linux-all
|
||||
java/awt/datatransfer/ConstructFlavoredObjectTest/ConstructFlavoredObjectTest.java 8202860 linux-all
|
||||
java/awt/FileDialog/FilenameFilterTest/FilenameFilterTest.java 8202882 linux-all
|
||||
java/awt/Focus/NonFocusableBlockedOwnerTest/NonFocusableBlockedOwnerTest.java 7124275 macosx-all
|
||||
java/awt/Focus/TranserFocusToWindow/TranserFocusToWindow.java 6848810 macosx-all,linux-all
|
||||
java/awt/FileDialog/ModalFocus/FileDialogModalFocusTest.java 8194751 linux-all
|
||||
java/awt/image/VolatileImage/BitmaskVolatileImage.java 8133102 linux-all
|
||||
java/awt/ScrollPane/ScrollPaneEventType.java 8296516 macosx-all
|
||||
java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java 7107528 linux-all,macosx-all
|
||||
java/awt/Mouse/MouseDragEvent/MouseDraggedTest.java 8080676 linux-all
|
||||
java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersInKeyEvent.java 8157147 linux-all,windows-all,macosx-all
|
||||
java/awt/Mouse/MouseClickCount.java 8017182 macosx-all
|
||||
java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java 6847163 linux-all
|
||||
java/awt/xembed/server/RunTestXEmbed.java 7034201 linux-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsDocModalTest.java 8164473 linux-all
|
||||
|
||||
java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java 7099223,8274106 macosx-all,linux-all,windows-all
|
||||
java/awt/keyboard/AllKeyCode/AllKeyCode.java 8242930 macosx-all
|
||||
java/awt/FullScreen/8013581/bug8013581.java 8169471 macosx-all
|
||||
java/awt/event/MouseEvent/RobotLWTest/RobotLWTest.java 8233568 macosx-all
|
||||
java/awt/event/MouseEvent/MultipleMouseButtonsTest/MultipleMouseButtonsTest.java 8233568 macosx-all
|
||||
java/awt/event/MouseEvent/ClickDuringKeypress/ClickDuringKeypress.java 8233568 macosx-all
|
||||
java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java 8233568 macosx-all
|
||||
java/awt/event/KeyEvent/DeadKey/deadKeyMacOSX.java 8233568 macosx-all
|
||||
java/awt/TrayIcon/RightClickWhenBalloonDisplayed/RightClickWhenBalloonDisplayed.java 8238720 windows-all
|
||||
java/awt/PopupMenu/PopupMenuLocation.java 8259913 windows-all
|
||||
java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java 8238720,8324782 windows-all,macosx-all
|
||||
java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720,8324782 windows-all,macosx-all
|
||||
java/awt/GridBagLayout/ComponentShortage.java 8355280 windows-all,linux-all
|
||||
java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.java 8238720 windows-all
|
||||
|
||||
# Several tests which fail sometimes on macos11
|
||||
java/awt/Window/MainKeyWindowTest/TestMainKeyWindow.java 8265985 macosx-all
|
||||
java/awt/Robot/Delay/InterruptOfDelay.java 8265986 macosx-all
|
||||
java/awt/Robot/InfiniteLoopException.java 8342638 windows-all,linux-all
|
||||
java/awt/MenuBar/TestNoScreenMenuBar.java 8265987 macosx-all
|
||||
|
||||
java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java 8266283 generic-all
|
||||
java/awt/Graphics2D/DrawString/RotTransText.java 8316878 linux-all
|
||||
java/awt/KeyboardFocusmanager/TypeAhead/ButtonActionKeyTest/ButtonActionKeyTest.java 8257529 windows-x64
|
||||
java/awt/KeyboardFocusmanager/ConsumeNextMnemonicKeyTypedTest/ConsumeForModalDialogTest/ConsumeForModalDialogTest.java 8302787 windows-all
|
||||
java/awt/KeyboardFocusmanager/TypeAhead/MenuItemActivatedTest/MenuItemActivatedTest.java 8302787 windows-all
|
||||
|
||||
java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64
|
||||
java/awt/Dialog/ChoiceModalDialogTest.java 8161475 macosx-all
|
||||
java/awt/Dialog/FileDialogUserFilterTest.java 8001142 generic-all
|
||||
|
||||
java/awt/dnd/BadSerializationTest/BadSerializationTest.java 8277817 linux-x64,windows-x64
|
||||
java/awt/dnd/DragSourceMotionListenerTest.java 8225131 windows-all
|
||||
java/awt/dnd/RejectDragTest.java 7124259 macosx-all
|
||||
java/awt/dnd/DnDHTMLToOutlookTest/DnDHTMLToOutlookTest.java 8027424 generic-all
|
||||
java/awt/GraphicsDevice/DisplayModes/UnknownRefrshRateTest.java 8286436 macosx-aarch64
|
||||
java/awt/image/multiresolution/MultiresolutionIconTest.java 8291979 linux-x64,windows-all
|
||||
java/awt/event/SequencedEvent/MultipleContextsFunctionalTest.java 8305061 macosx-x64
|
||||
sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java 8301177 linux-x64
|
||||
sun/awt/image/bug8038000.java 8373065 generic-all
|
||||
|
||||
# Several tests which fail on some hidpi systems/macosx12-aarch64 system
|
||||
java/awt/Window/8159168/SetShapeTest.java 8274106 macosx-aarch64
|
||||
java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java 8274106 macosx-aarch64
|
||||
|
||||
# Wayland related
|
||||
|
||||
java/awt/FullScreen/SetFullScreenTest.java 8332155 linux-x64
|
||||
sun/java2d/ClassCastExceptionForInvalidSurface.java 8354097 linux-x64
|
||||
sun/java2d/GdiRendering/ClipShapeRendering.java 8354097 linux-x64
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_beans
|
||||
|
||||
java/beans/Introspector/8132566/OverridePropertyInfoTest.java 8132565 generic-all
|
||||
java/beans/Introspector/8132566/OverrideUserDefPropertyInfoTest.java 8132565 generic-all
|
||||
|
||||
java/beans/XMLEncoder/Test6570354.java 8015593 macosx-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_lang
|
||||
|
||||
java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java 8151492 generic-all
|
||||
java/lang/invoke/LFCaching/LFGarbageCollectedTest.java 8078602 generic-all
|
||||
java/lang/invoke/lambda/LambdaFileEncodingSerialization.java 8249079 linux-all
|
||||
java/lang/invoke/RicochetTest.java 8251969 generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_instrument
|
||||
|
||||
java/lang/instrument/RedefineBigClass.sh 8065756 generic-all
|
||||
java/lang/instrument/RetransformBigClass.sh 8065756 generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_io
|
||||
|
||||
java/io/pathNames/GeneralWin32.java 8180264 windows-all
|
||||
java/lang/IO/IO.java 8337935 linux-ppc64le
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_management
|
||||
|
||||
|
||||
java/lang/management/MemoryMXBean/Pending.java 8158837 generic-all
|
||||
java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java 8247426 generic-all
|
||||
|
||||
sun/management/jdp/JdpDefaultsTest.java 8308807,8241865 aix-ppc64,macosx-all
|
||||
sun/management/jdp/JdpJmxRemoteDynamicPortTest.java 8308807,8241865 aix-ppc64,macosx-all
|
||||
sun/management/jdp/JdpSpecificAddressTest.java 8308807,8241865 aix-ppc64,macosx-all
|
||||
sun/management/jdp/JdpOffTest.java 8308807 aix-ppc64
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_jmx
|
||||
|
||||
|
||||
javax/management/remote/mandatory/connection/BrokenConnectionTest.java 8262312 linux-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_net
|
||||
|
||||
java/net/DatagramSocket/DatagramSocketExample.java 8308807 aix-ppc64
|
||||
java/net/DatagramSocket/DatagramSocketMulticasting.java 8308807 aix-ppc64
|
||||
|
||||
java/net/MulticastSocket/B6427403.java 8308807 aix-ppc64
|
||||
java/net/MulticastSocket/IPMulticastIF.java 8308807 aix-ppc64
|
||||
java/net/MulticastSocket/JoinLeave.java 8308807 aix-ppc64
|
||||
java/net/MulticastSocket/MulticastAddresses.java 8308807 aix-ppc64
|
||||
java/net/MulticastSocket/NoLoopbackPackets.java 7122846,8308807 macosx-all,aix-ppc64
|
||||
java/net/MulticastSocket/NoSetNetworkInterface.java 8308807 aix-ppc64
|
||||
java/net/MulticastSocket/Promiscuous.java 8308807 aix-ppc64
|
||||
java/net/MulticastSocket/SetGetNetworkInterfaceTest.java 8308807 aix-ppc64
|
||||
java/net/MulticastSocket/SetLoopbackMode.java 7122846,8308807 macosx-all,aix-ppc64
|
||||
java/net/MulticastSocket/SetOutgoingIf.java 8308807 aix-ppc64
|
||||
java/net/MulticastSocket/Test.java 7145658,8308807 macosx-all,aix-ppc64
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_nio
|
||||
|
||||
java/nio/channels/DatagramChannel/AdaptorMulticasting.java 8308807,8144003 aix-ppc64,macosx-all
|
||||
java/nio/channels/DatagramChannel/AfterDisconnect.java 8308807 aix-ppc64
|
||||
java/nio/channels/DatagramChannel/ManySourcesAndTargets.java 8264385 macosx-aarch64
|
||||
java/nio/channels/DatagramChannel/Unref.java 8233437 generic-all
|
||||
java/nio/channels/DatagramChannel/BasicMulticastTests.java 8144003 macosx-all
|
||||
java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java 8144003 macosx-all
|
||||
java/nio/channels/DatagramChannel/Promiscuous.java 8144003 macosx-all
|
||||
java/nio/channels/SocketChannel/CloseDuringConnect.java 8375658 macosx-26.0,macosx-26.1,macosx-26.2,macosx-26.3
|
||||
java/nio/channels/SocketChannel/OpenLeak.java 8375658 macosx-26.0,macosx-26.1,macosx-26.2,macosx-26.3
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_rmi
|
||||
|
||||
java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java 7140992 generic-all
|
||||
|
||||
java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java 7146541 linux-all
|
||||
|
||||
java/rmi/registry/readTest/CodebaseTest.java 8173324 windows-all
|
||||
java/rmi/registry/multipleRegistries/MultipleRegistries.java 8268182 macosx-all
|
||||
java/rmi/Naming/DefaultRegistryPort.java 8005619 windows-all
|
||||
java/rmi/Naming/legalRegistryNames/LegalRegistryNames.java 8005619 windows-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_sctp
|
||||
|
||||
com/sun/nio/sctp/SctpMultiChannel/SendFailed.java 8141694 linux-all
|
||||
|
||||
com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java 8141694 linux-all
|
||||
|
||||
com/sun/nio/sctp/SctpChannel/SocketOptionTests.java 8141694 linux-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_security
|
||||
|
||||
sun/security/smartcardio/TestChannel.java 8039280 generic-all
|
||||
sun/security/smartcardio/TestConnect.java 8039280 generic-all
|
||||
sun/security/smartcardio/TestConnectAgain.java 8039280 generic-all
|
||||
sun/security/smartcardio/TestControl.java 8039280 generic-all
|
||||
sun/security/smartcardio/TestDefault.java 8039280 generic-all
|
||||
sun/security/smartcardio/TestDirect.java 8039280 generic-all
|
||||
sun/security/smartcardio/TestExclusive.java 8039280 generic-all
|
||||
sun/security/smartcardio/TestMultiplePresent.java 8039280 generic-all
|
||||
sun/security/smartcardio/TestPresent.java 8039280 generic-all
|
||||
sun/security/smartcardio/TestTransmit.java 8039280 generic-all
|
||||
|
||||
sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java 8316183 linux-ppc64le
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_sound
|
||||
|
||||
javax/sound/sampled/Clip/Drain/ClipDrain.java 7062792 generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_imageio
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_swing
|
||||
|
||||
javax/swing/plaf/basic/BasicTextUI/8001470/bug8001470.java 8233177 linux-all,windows-all
|
||||
javax/swing/plaf/basic/BasicDirectoryModel/LoaderThreadCount.java 8333880 windows-all
|
||||
|
||||
javax/swing/JFrame/MaximizeWindowTest.java 8321289 linux-all
|
||||
javax/swing/JWindow/ShapedAndTranslucentWindows/ShapedTranslucentPerPixelTranslucentGradient.java 8233582 linux-all
|
||||
javax/swing/JWindow/ShapedAndTranslucentWindows/ShapedPerPixelTranslucentGradient.java 8233582 linux-all
|
||||
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentSwing.java 8194128 macosx-all
|
||||
javax/swing/JWindow/ShapedAndTranslucentWindows/SetShapeAndClickSwing.java 8013450 macosx-all
|
||||
javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentJComboBox.java 8024627 macosx-all
|
||||
# The next test below is an intermittent failure
|
||||
javax/swing/JTree/DnD/LastNodeLowerHalfDrop.java 8159131 linux-all
|
||||
javax/swing/JTree/4633594/JTreeFocusTest.java 7105441 macosx-all
|
||||
javax/swing/AbstractButton/6711682/bug6711682.java 8060765 windows-all,macosx-all
|
||||
javax/swing/JFileChooser/6396844/TwentyThousandTest.java 8198003 generic-all
|
||||
javax/swing/JFileChooser/8194044/FileSystemRootTest.java 8327236 windows-all
|
||||
javax/swing/JPopupMenu/6800513/bug6800513.java 7184956 macosx-all
|
||||
javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java 8160720 generic-all
|
||||
javax/swing/JFileChooser/bug6798062.java 8146446 windows-all
|
||||
javax/swing/JPopupMenu/4870644/bug4870644.java 8194130 macosx-all,linux-all
|
||||
javax/swing/dnd/8139050/NativeErrorsInTableDnD.java 8202765 macosx-all,linux-all
|
||||
javax/swing/JEditorPane/6917744/bug6917744.java 8213124 macosx-all
|
||||
|
||||
# Several tests which fail on some hidpi systems/macosx12-aarch64 system
|
||||
javax/swing/JFrame/8175301/ScaledFrameBackgroundTest.java 8274106 macosx-aarch64
|
||||
|
||||
javax/swing/JColorChooser/Test6827032.java 8224968 windows-x64
|
||||
|
||||
sanity/client/SwingSet/src/ToolTipDemoTest.java 8293001 linux-all
|
||||
sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java 8265770 macosx-all
|
||||
sanity/client/SwingSet/src/EditorPaneDemoTest.java 8212240 linux-x64
|
||||
|
||||
# This test fails on macOS 14
|
||||
javax/swing/plaf/synth/7158712/bug7158712.java 8324782 macosx-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_text
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_time
|
||||
|
||||
############################################################################
|
||||
|
||||
# core_tools
|
||||
|
||||
############################################################################
|
||||
|
||||
# core_svc
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_jdi
|
||||
|
||||
com/sun/jdi/InvokeHangTest.java 8218463 linux-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_time
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_util
|
||||
java/util/zip/CloseInflaterDeflaterTest.java 8339216 linux-s390x
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_instrument
|
||||
|
||||
############################################################################
|
||||
|
||||
# svc_tools
|
||||
|
||||
sun/tools/jstatd/TestJstatdRmiPort.java 8251259,8293577 generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_other
|
||||
|
||||
jdk/incubator/vector/ShortMaxVectorTests.java 8306592 generic-i586
|
||||
jdk/incubator/vector/LoadJsvmlTest.java 8305390 windows-x64
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_jfr
|
||||
|
||||
jdk/jfr/event/compiler/TestCodeSweeper.java 8338127 generic-all
|
||||
jdk/jfr/event/oldobject/TestShenandoah.java 8342951 generic-all
|
||||
jdk/jfr/event/runtime/TestResidentSetSizeEvent.java 8309846 aix-ppc64
|
||||
jdk/jfr/jvm/TestWaste.java 8371630 generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_internal
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_jpackage
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_foreign
|
||||
|
||||
java/foreign/TestBufferStackStress.java 8350455 macosx-all
|
||||
|
||||
############################################################################
|
||||
# Client manual tests
|
||||
|
||||
javax/swing/JFileChooser/6698013/bug6698013.java 8024419 macosx-all
|
||||
javax/swing/JColorChooser/8065098/bug8065098.java 8065647 macosx-all
|
||||
javax/swing/JTabbedPane/bug4499556.java 8267500 macosx-all
|
||||
javax/swing/JTabbedPane/TestJTabbedPaneOpaqueColor.java 8345090 windows-all,linux-all
|
||||
javax/swing/SwingUtilities/TestTextPosInPrint.java 8227025 windows-all
|
||||
javax/swing/JInternalFrame/bug4134077.java 8184985 windows-all
|
||||
|
||||
java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter_1.java 7131438,8022539 generic-all
|
||||
java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter_2.java 7131438,8022539 generic-all
|
||||
java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java 7187741 linux-all,macosx-all
|
||||
java/awt/xembed/server/TestXEmbedServerJava.java 8001150,8004031 generic-all
|
||||
java/awt/image/VolatileImage/VolatileImageConfigurationTest.java 8171069 macosx-all,linux-all
|
||||
java/awt/Modal/InvisibleParentTest/InvisibleParentTest.java 8172245 linux-all
|
||||
java/awt/Frame/FrameStateTest/FrameStateTest.java 8203920 macosx-all,linux-all
|
||||
java/awt/print/PrinterJob/ScaledText/ScaledText.java 8231226 macosx-all
|
||||
java/awt/print/PrinterJob/PrintTextTest.java 8148334 macosx-all
|
||||
java/awt/font/GlyphVector/TestGlyphVectorLayout.java 8354987 generic-all
|
||||
java/awt/font/TextLayout/TestJustification.java 8250791 macosx-all
|
||||
java/awt/TrayIcon/DragEventSource/DragEventSource.java 8252242 macosx-all
|
||||
java/awt/FileDialog/DefaultFocusOwner/DefaultFocusOwner.java 7187728 macosx-all,linux-all
|
||||
java/awt/FileDialog/DoubleActionESC.java 8356981 linux-all
|
||||
java/awt/print/PageFormat/Orient.java 8016055 macosx-all
|
||||
java/awt/TextArea/TextAreaCursorTest/HoveringAndDraggingTest.java 8024986 macosx-all,linux-all
|
||||
java/awt/TextComponent/SelectionAndCaretColor.java 7017622 linux-all
|
||||
java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter.java 8254841 macosx-all
|
||||
java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java 8258103 linux-all
|
||||
java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-x64
|
||||
java/awt/Frame/SizeMinimizedTest.java 8305915 linux-x64
|
||||
java/awt/PopupMenu/PopupHangTest.java 8340022 windows-all
|
||||
java/awt/Focus/MinimizeNonfocusableWindowTest.java 8024487 windows-all
|
||||
java/awt/List/HandlingKeyEventIfMousePressedTest.java 6848358 macosx-all,windows-all
|
||||
java/awt/List/ListScrollbarCursorTest.java 8066410 generic-all
|
||||
java/awt/Checkbox/CheckboxBoxSizeTest.java 8340870 windows-all
|
||||
java/awt/Checkbox/CheckboxIndicatorSizeTest.java 8340870 windows-all
|
||||
java/awt/Checkbox/CheckboxNullLabelTest.java 8340870 windows-all
|
||||
java/awt/dnd/WinMoveFileToShellTest.java 8341665 windows-all
|
||||
java/awt/Menu/MenuVisibilityTest.java 8161110 macosx-all
|
||||
java/awt/Modal/NativeDialogToFrontBackTest.java 7188049 windows-all,linux-all
|
||||
java/awt/Cursor/CursorDragTest/ListDragCursor.java 7177297 macosx-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_since_checks
|
||||
|
||||
tools/sincechecker/modules/jdk.management.jfr/JdkManagementJfrCheckSince.java 8354921 generic-all
|
||||
|
||||
#############################################################################
|
||||
|
||||
# Preview project specific failures go here at the end of the file.
|
||||
#
|
||||
# These are NOT failures that occur with the '--enable-preview' option
|
||||
# specified; those go in the appropriate ProblemList-enable-preview.txt file.
|
||||
# These are failures that occur WITHOUT the '--enable-preview' option
|
||||
# specified AND occur because of some issue with preview project code,
|
||||
# in either implementation or test code.
|
||||
|
||||
#############################################################################
|
||||
|
||||
131
test/jdk/TEST.ROOT
Normal file
131
test/jdk/TEST.ROOT
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This file identifies the root of the test-suite hierarchy.
|
||||
# It also contains test-suite configuration information.
|
||||
#
|
||||
# The list of keywords supported in the entire test suite. The
|
||||
# "intermittent" keyword marks tests known to fail intermittently.
|
||||
# The "randomness" keyword marks tests using randomness with test
|
||||
# cases differing from run to run. (A test using a fixed random seed
|
||||
# would not count as "randomness" by this definition.) Extra care
|
||||
# should be taken to handle test failures of intermittent or
|
||||
# randomness tests.
|
||||
#
|
||||
# A test flagged with cgroups uses cgroups.
|
||||
#
|
||||
# Notes on "client" keywords : headful sound printer multimon
|
||||
# ===========================================================
|
||||
#
|
||||
# These keywords are there to help with test selection so that
|
||||
# tests that need a particular resource can be selected to run on a system
|
||||
# with that resource. Conversely "!somekeyword" can be used to exclude tests
|
||||
# on a system without such a resource.
|
||||
# Caution: If you are always excluding tests using any of these keywords then you
|
||||
# are likely missing many important tests.
|
||||
#
|
||||
# "headful". A "headful" test requires a graphical environment to meaningfully run.
|
||||
# This does not have to mean a physical host, since a VM can be configured as headful.
|
||||
# Tests that are not headful are "headless".
|
||||
# Note: all manual tests are assumed to be headful and do not need the keyword.
|
||||
#
|
||||
# "printer". Not all tests of printing APIs require a printer, but many do.
|
||||
# So a "printer" test requires a printer to be installed to do anything meaningful.
|
||||
# Tests may not fail if there is none, instead just silently return.
|
||||
# But they also may legitimately throw an Exception depending on the test.
|
||||
# Also printer tests are not necessarily headful, but some are, and some are automated.
|
||||
#
|
||||
# "sound". Similarly, not all sound tests require audio devices, but many do.
|
||||
# A test flagged with key "sound" needs audio devices on the system.
|
||||
# Also they are not necessarily "headful", since they don't require a display etc.
|
||||
# But sometimes they may be accompanied by the headful keyword, since sound
|
||||
# is often linked to access to desktop resources and headful systems are
|
||||
# also more likely to have audio devices (ie meaning both input and output)
|
||||
#
|
||||
# "multimon" should be used in conjunction with headful and is used to identify
|
||||
# tests which require two displays connected.
|
||||
|
||||
keys=headful sound printer multimon \
|
||||
i18n intermittent randomness cgroups
|
||||
|
||||
# Tests that must run in othervm mode
|
||||
othervm.dirs=java/awt java/beans javax/accessibility javax/imageio javax/sound javax/swing javax/print \
|
||||
com/apple/laf com/apple/eawt com/sun/java/accessibility com/sun/java/swing sanity/client demo/jfc \
|
||||
javax/management sun/awt sun/java2d javax/xml/jaxp/testng/validation java/lang/ProcessHandle
|
||||
|
||||
# Tests that cannot run concurrently
|
||||
exclusiveAccess.dirs=java/math/BigInteger/largeMemory \
|
||||
java/rmi/Naming java/util/prefs sun/management/jmxremote \
|
||||
sun/tools/jstatd sun/security/mscapi java/util/Arrays/largeMemory \
|
||||
java/util/BitSet/stream javax/rmi java/net/httpclient/websocket \
|
||||
com/sun/net/httpserver/simpleserver sun/tools/jhsdb
|
||||
|
||||
# Group definitions
|
||||
groups=TEST.groups
|
||||
|
||||
# Allow querying of various System properties in @requires clauses
|
||||
#
|
||||
# Source files for classes that will be used at the beginning of each test suite run,
|
||||
# to determine additional characteristics of the system for use with the @requires tag.
|
||||
# Note: compiled bootlibs classes will be added to BCP.
|
||||
requires.extraPropDefns = ../jtreg-ext/requires/VMProps.java
|
||||
requires.extraPropDefns.bootlibs = ../lib/jdk/test/whitebox
|
||||
requires.extraPropDefns.libs = \
|
||||
../lib/jdk/test/lib/Platform.java \
|
||||
../lib/jdk/test/lib/Container.java
|
||||
requires.extraPropDefns.javacOpts = \
|
||||
--add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED
|
||||
requires.extraPropDefns.vmOpts = \
|
||||
-XX:+UnlockDiagnosticVMOptions \
|
||||
-XX:+LogVMOutput -XX:-DisplayVMOutput -XX:LogFile=vmprops.flags.final.vm.log \
|
||||
-XX:+PrintFlagsFinal \
|
||||
-XX:+WhiteBoxAPI \
|
||||
--add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED
|
||||
requires.properties= \
|
||||
sun.arch.data.model \
|
||||
java.runtime.name \
|
||||
java.enablePreview \
|
||||
vm.flagless \
|
||||
vm.gc.G1 \
|
||||
vm.gc.Serial \
|
||||
vm.gc.Parallel \
|
||||
vm.gc.Shenandoah \
|
||||
vm.gc.Epsilon \
|
||||
vm.gc.Z \
|
||||
vm.graal.enabled \
|
||||
vm.compiler1.enabled \
|
||||
vm.compiler2.enabled \
|
||||
vm.cds \
|
||||
vm.cds.write.archived.java.heap \
|
||||
vm.cds.write.mapped.java.heap \
|
||||
vm.cds.write.streamed.java.heap \
|
||||
vm.continuations \
|
||||
vm.musl \
|
||||
vm.asan \
|
||||
vm.ubsan \
|
||||
vm.debug \
|
||||
vm.hasSA \
|
||||
vm.hasJFR \
|
||||
vm.jvmci \
|
||||
vm.jvmci.enabled \
|
||||
vm.jvmti \
|
||||
vm.cpu.features \
|
||||
container.support \
|
||||
systemd.support \
|
||||
release.implementor \
|
||||
jdk.containerized \
|
||||
jdk.foreign.linker \
|
||||
jlink.runtime.linkable \
|
||||
jlink.packagedModules \
|
||||
jdk.static
|
||||
|
||||
# Minimum jtreg version
|
||||
requiredVersion=8.2.1+1
|
||||
|
||||
# Path to libraries in the topmost test directory. This is needed so @library
|
||||
# does not need ../../ notation to reach them
|
||||
external.lib.roots = ../../
|
||||
|
||||
683
test/jdk/TEST.groups
Normal file
683
test/jdk/TEST.groups
Normal file
|
|
@ -0,0 +1,683 @@
|
|||
# Copyright (c) 2013, 2026, 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.
|
||||
#
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# All tests
|
||||
#
|
||||
|
||||
all = \
|
||||
:jdk_all
|
||||
|
||||
jdk_all = \
|
||||
/
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Tiered testing definitions
|
||||
#
|
||||
|
||||
# When adding tests to tier1, make sure they end up in one of the tier1_partX groups
|
||||
tier1 = \
|
||||
:tier1_part1 \
|
||||
:tier1_part2 \
|
||||
:tier1_part3
|
||||
|
||||
tier1_part1 = \
|
||||
:jdk_lang
|
||||
|
||||
tier1_part2 = \
|
||||
:jdk_util
|
||||
|
||||
tier1_part3 = \
|
||||
:jdk_math \
|
||||
:jdk_svc_sanity \
|
||||
:jdk_foreign \
|
||||
:jdk_vector_sanity \
|
||||
java/nio/Buffer \
|
||||
com/sun/crypto/provider/Cipher \
|
||||
jdk/classfile \
|
||||
sun/nio/cs/ISO8859x.java
|
||||
|
||||
# When adding tests to tier2, make sure they end up in one of the tier2_partX groups
|
||||
tier2 = \
|
||||
:tier2_part1 \
|
||||
:tier2_part2 \
|
||||
:tier2_part3
|
||||
|
||||
# com/sun/crypto/provider/Cipher is in tier1 because of JDK-8132855
|
||||
tier2_part1 = \
|
||||
:jdk_security \
|
||||
-com/sun/crypto/provider/Cipher
|
||||
|
||||
# sun/nio/cs/ISO8859x.java and java/nio/Buffer are in tier1 because of JDK-8132854
|
||||
tier2_part2 = \
|
||||
:core_tools \
|
||||
:jdk_io \
|
||||
:jdk_nio \
|
||||
-java/nio/Buffer \
|
||||
-sun/nio/cs/ISO8859x.java \
|
||||
:jdk_other \
|
||||
:jdk_text \
|
||||
:jdk_time
|
||||
|
||||
tier2_part3 = \
|
||||
:jdk_net
|
||||
|
||||
# These sub groups of tier3 allow for running certain tests separately from the
|
||||
# rest. When adding tests to tier3, in most cases they should be added to
|
||||
# tier3_part1.
|
||||
tier3 = \
|
||||
:tier3_part1 \
|
||||
:tier3_jpackage
|
||||
|
||||
tier3_part1 = \
|
||||
:build \
|
||||
:jdk_vector \
|
||||
-:jdk_vector_sanity \
|
||||
:jdk_rmi \
|
||||
:jdk_svc \
|
||||
-:jdk_svc_sanity \
|
||||
-:svc_tools \
|
||||
:jdk_since_checks
|
||||
|
||||
# The jpackage tests on Windows require permissions that aren't always present
|
||||
tier3_jpackage = \
|
||||
:jdk_jpackage
|
||||
|
||||
# Everything not in other tiers
|
||||
tier4 = \
|
||||
/ \
|
||||
-:tier1 \
|
||||
-:tier2 \
|
||||
-:tier3 \
|
||||
:jdk_foreign_stress
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Other test definitions; generally smaller granularity than tiers
|
||||
#
|
||||
|
||||
# Build source checking
|
||||
build = \
|
||||
build
|
||||
|
||||
# java.lang package and VM runtime support
|
||||
jdk_lang = \
|
||||
java/lang \
|
||||
-java/lang/management \
|
||||
-java/lang/instrument \
|
||||
sun/invoke \
|
||||
sun/misc \
|
||||
sun/reflect \
|
||||
jdk/internal/reflect \
|
||||
jdk/lambda \
|
||||
jdk/internal/loader \
|
||||
jdk/internal/misc \
|
||||
jdk/internal/ref \
|
||||
jdk/internal/jimage \
|
||||
jdk/internal/math \
|
||||
jdk/internal/vm \
|
||||
jdk/modules \
|
||||
jni/nullCaller
|
||||
|
||||
# All of the java.util package
|
||||
jdk_util = \
|
||||
:jdk_util_other \
|
||||
:jdk_collections \
|
||||
:jdk_concurrent \
|
||||
:jdk_stream
|
||||
|
||||
# All util components not part of some other util category
|
||||
jdk_util_other = \
|
||||
java/util \
|
||||
sun/util \
|
||||
jdk/internal/util \
|
||||
-:jdk_collections \
|
||||
-:jdk_concurrent \
|
||||
-:jdk_stream
|
||||
|
||||
# All collections, core and concurrent
|
||||
jdk_collections = \
|
||||
:jdk_collections_core \
|
||||
:jdk_concurrent
|
||||
|
||||
# java.util.concurrent
|
||||
# Includes concurrent collections plus other stuff
|
||||
# Maintained by JSR-166 EG (Doug Lea et al)
|
||||
jdk_concurrent = \
|
||||
java/util/concurrent
|
||||
|
||||
# Java Collections Framework core classes
|
||||
jdk_collections_core = \
|
||||
java/util/AbstractCollection \
|
||||
java/util/AbstractList \
|
||||
java/util/AbstractMap \
|
||||
java/util/AbstractSequentialList \
|
||||
java/util/ArrayDeque \
|
||||
java/util/ArrayList \
|
||||
java/util/Arrays \
|
||||
java/util/BitSet \
|
||||
java/util/Collection \
|
||||
java/util/Collections \
|
||||
java/util/Comparator \
|
||||
java/util/Deque \
|
||||
java/util/EnumMap \
|
||||
java/util/EnumSet \
|
||||
java/util/HashMap \
|
||||
java/util/HashSet \
|
||||
java/util/Hashtable \
|
||||
java/util/IdentityHashMap \
|
||||
java/util/Iterator \
|
||||
java/util/LinkedHashMap \
|
||||
java/util/LinkedHashSet \
|
||||
java/util/LinkedList \
|
||||
java/util/List \
|
||||
java/util/Map \
|
||||
java/util/NavigableMap \
|
||||
java/util/PriorityQueue \
|
||||
java/util/SequencedCollection \
|
||||
java/util/TimSort \
|
||||
java/util/TreeMap \
|
||||
java/util/Vector \
|
||||
java/util/WeakHashMap
|
||||
|
||||
# java.util.stream (JSR-335)
|
||||
jdk_stream = \
|
||||
java/util/Optional \
|
||||
java/util/function \
|
||||
java/util/stream
|
||||
|
||||
jdk_math = \
|
||||
java/math
|
||||
|
||||
jdk_io = \
|
||||
java/io
|
||||
|
||||
jdk_nio = \
|
||||
java/nio \
|
||||
sun/nio \
|
||||
jdk/nio
|
||||
|
||||
jdk_net = \
|
||||
java/net \
|
||||
com/sun/net/httpserver \
|
||||
sun/net \
|
||||
jdk/net
|
||||
|
||||
jdk_time = \
|
||||
java/time
|
||||
|
||||
jdk_rmi = \
|
||||
java/rmi \
|
||||
sun/rmi
|
||||
|
||||
jdk_security1 = \
|
||||
java/security
|
||||
|
||||
jdk_security2 = \
|
||||
javax/crypto \
|
||||
javax/xml/crypto \
|
||||
com/sun/org/apache/xml/internal/security \
|
||||
com/sun/crypto
|
||||
|
||||
jdk_security3 = \
|
||||
javax/security \
|
||||
-javax/security/auth/kerberos \
|
||||
com/sun/security \
|
||||
-com/sun/security/jgss \
|
||||
jdk/security \
|
||||
sun/security \
|
||||
-sun/security/krb5 \
|
||||
-sun/security/jgss \
|
||||
javax/net
|
||||
|
||||
jdk_security4 = \
|
||||
com/sun/security/jgss \
|
||||
javax/security/auth/kerberos \
|
||||
sun/security/krb5 \
|
||||
sun/security/jgss
|
||||
|
||||
jdk_security = \
|
||||
:jdk_security1 \
|
||||
:jdk_security2 \
|
||||
:jdk_security3 \
|
||||
:jdk_security4
|
||||
|
||||
# Tests in this group are manual as they depend on external infra
|
||||
# and may fail with external reasons, for instance - change in CA test portal.
|
||||
jdk_security_infra = \
|
||||
security/infra
|
||||
|
||||
jdk_text = \
|
||||
java/text \
|
||||
sun/text
|
||||
|
||||
jdk_management = \
|
||||
java/lang/management \
|
||||
jdk/management \
|
||||
com/sun/management \
|
||||
sun/management \
|
||||
jdk/internal/agent
|
||||
|
||||
jdk_instrument = \
|
||||
java/lang/instrument
|
||||
|
||||
jdk_jmx = \
|
||||
javax/management \
|
||||
com/sun/jmx
|
||||
|
||||
jdk_jdi = \
|
||||
com/sun/jdi
|
||||
|
||||
jdk_native_sanity = \
|
||||
native_sanity
|
||||
|
||||
# java launcher specific tests.
|
||||
jdk_launcher = \
|
||||
tools/launcher \
|
||||
sun/tools
|
||||
|
||||
jdk_loom = \
|
||||
com/sun/management/HotSpotDiagnosticMXBean \
|
||||
com/sun/management/ThreadMXBean \
|
||||
jdk/management/VirtualThreadSchedulerMXBean \
|
||||
java/lang/Thread \
|
||||
java/lang/ThreadGroup \
|
||||
java/lang/management/ThreadMXBean \
|
||||
java/util/concurrent \
|
||||
java/net/vthread \
|
||||
java/nio/channels/vthread \
|
||||
jdk/internal/misc/ThreadFlock \
|
||||
jdk/internal/vm/Continuation \
|
||||
jdk/jfr/threading
|
||||
|
||||
#
|
||||
# Tool (and tool API) tests are mostly split into core and svc groups
|
||||
#
|
||||
core_tools = \
|
||||
tools \
|
||||
-tools/jpackage \
|
||||
jdk/internal/jrtfs
|
||||
|
||||
svc_tools = \
|
||||
com/sun/tools/attach \
|
||||
sun/tools \
|
||||
sun/jvmstat
|
||||
|
||||
jdk_tools = \
|
||||
:core_tools \
|
||||
:svc_tools \
|
||||
:jdk_jpackage
|
||||
|
||||
jdk_jfr = \
|
||||
jdk/jfr
|
||||
|
||||
jdk_jpackage = \
|
||||
tools/jpackage
|
||||
|
||||
#
|
||||
# Catch-all for other areas with a small number of tests
|
||||
#
|
||||
jdk_other = \
|
||||
java/sql \
|
||||
javax/sql \
|
||||
javax/transaction \
|
||||
javax/rmi \
|
||||
javax/naming \
|
||||
javax/script \
|
||||
javax/smartcardio \
|
||||
javax/xml \
|
||||
-javax/xml/crypto \
|
||||
jdk/dynalink \
|
||||
jdk/internal/jline \
|
||||
com/sun/jndi \
|
||||
lib/testlibrary
|
||||
|
||||
#
|
||||
# SCTP is its own group as it is highly sensitive to kernel/network config
|
||||
#
|
||||
jdk_sctp = \
|
||||
com/sun/nio/sctp
|
||||
|
||||
|
||||
#
|
||||
# core group to run all core area tests
|
||||
#
|
||||
jdk_core = \
|
||||
:jdk_lang \
|
||||
:jdk_util \
|
||||
:jdk_math \
|
||||
:jdk_io \
|
||||
:jdk_nio \
|
||||
:jdk_net \
|
||||
:jdk_rmi \
|
||||
:jdk_time \
|
||||
:jdk_security \
|
||||
:jdk_text \
|
||||
:core_tools \
|
||||
:jdk_other
|
||||
|
||||
#
|
||||
# svc group to run all serviceability area tests
|
||||
#
|
||||
jdk_svc = \
|
||||
:jdk_management \
|
||||
:jdk_instrument \
|
||||
:jdk_jmx \
|
||||
:jdk_jdi \
|
||||
:jdk_jfr \
|
||||
:svc_tools
|
||||
|
||||
jdk_foreign = \
|
||||
java/foreign \
|
||||
jdk/internal/reflect/CallerSensitive/CheckCSMs.java \
|
||||
-java/foreign/TestMatrix.java \
|
||||
-java/foreign/TestUpcallStress.java
|
||||
|
||||
jdk_foreign_stress = \
|
||||
java/foreign/TestUpcallStress.java
|
||||
|
||||
jdk_vector = \
|
||||
jdk/incubator/vector
|
||||
|
||||
jdk_vector_sanity = \
|
||||
jdk/incubator/vector/PreferredSpeciesTest.java \
|
||||
jdk/incubator/vector/VectorHash.java \
|
||||
jdk/incubator/vector/VectorRuns.java
|
||||
|
||||
#############################
|
||||
|
||||
#
|
||||
# Client area groups
|
||||
#
|
||||
|
||||
jdk_awt = \
|
||||
java/awt \
|
||||
com/apple/eawt \
|
||||
com/apple/laf \
|
||||
sun/awt
|
||||
|
||||
jdk_2d = \
|
||||
javax/print \
|
||||
sun/java2d
|
||||
|
||||
jdk_beans = \
|
||||
java/beans
|
||||
|
||||
jdk_swing = \
|
||||
javax/swing \
|
||||
com/sun/java/swing
|
||||
|
||||
jdk_sound = \
|
||||
javax/sound
|
||||
|
||||
jdk_imageio = \
|
||||
javax/imageio
|
||||
|
||||
jdk_accessibility = \
|
||||
javax/accessibility
|
||||
|
||||
jfc_demo = \
|
||||
demo/jfc
|
||||
|
||||
jdk_editpad = \
|
||||
jdk/editpad
|
||||
|
||||
jdk_desktop = \
|
||||
:jdk_desktop_part1 \
|
||||
:jdk_desktop_part2 \
|
||||
:jdk_desktop_part3
|
||||
|
||||
jdk_desktop_part1 = \
|
||||
:jdk_client_sanity \
|
||||
:jdk_swing \
|
||||
:jdk_2d \
|
||||
:jdk_sound \
|
||||
:jdk_imageio \
|
||||
:jdk_editpad \
|
||||
:jfc_demo \
|
||||
:jdk_accessibility \
|
||||
:jdk_beans
|
||||
|
||||
jdk_desktop_part2 = \
|
||||
:jdk_awt \
|
||||
-java/awt/Component \
|
||||
-java/awt/Modal \
|
||||
-java/awt/datatransfer \
|
||||
-java/awt/Window
|
||||
|
||||
jdk_desktop_part3 = \
|
||||
java/awt/Component \
|
||||
java/awt/Modal \
|
||||
java/awt/datatransfer \
|
||||
java/awt/Window
|
||||
|
||||
# SwingSet3 tests.
|
||||
jdk_client_sanity = \
|
||||
sanity/client/SwingSet
|
||||
|
||||
# This test group represents a subset of tests which are expected to
|
||||
# exercise most of the most commonly used code in Swing applications.
|
||||
# New failures in this area may be a problem.
|
||||
jdk_swing_core = \
|
||||
:jdk_client_sanity \
|
||||
javax/swing
|
||||
|
||||
# The most commonly used printing APIs are included here along with swing core.
|
||||
jdk_desktop_core = \
|
||||
:jdk_swing_core \
|
||||
java/awt/print
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Serviceability sanity groups
|
||||
#
|
||||
# These groups specify a subset of Serviceability tests that are supposed to
|
||||
# guard against breakage of Serviceability features by other component teams.
|
||||
|
||||
jdk_svc_sanity = \
|
||||
:jdk_management_sanity \
|
||||
:jdk_instrument_sanity \
|
||||
:jdk_jmx_sanity \
|
||||
:jdk_jdi_sanity \
|
||||
:jdk_jfr_sanity \
|
||||
:svc_tools_sanity
|
||||
|
||||
jdk_management_sanity =
|
||||
|
||||
jdk_instrument_sanity =
|
||||
|
||||
jdk_jmx_sanity =
|
||||
|
||||
jdk_jdi_sanity = \
|
||||
com/sun/jdi/AcceptTimeout.java \
|
||||
com/sun/jdi/AccessSpecifierTest.java \
|
||||
com/sun/jdi/AfterThreadDeathTest.java \
|
||||
com/sun/jdi/ArrayRangeTest.java \
|
||||
com/sun/jdi/ConstantPoolInfo.java \
|
||||
com/sun/jdi/CountFilterTest.java \
|
||||
com/sun/jdi/EarlyReturnNegativeTest.java \
|
||||
com/sun/jdi/EarlyReturnTest.java \
|
||||
com/sun/jdi/FieldWatchpoints.java \
|
||||
com/sun/jdi/FramesTest.java \
|
||||
com/sun/jdi/InstanceFilter.java \
|
||||
com/sun/jdi/InterfaceMethodsTest.java \
|
||||
com/sun/jdi/InvokeTest.java \
|
||||
com/sun/jdi/LocalVariableEqual.java \
|
||||
com/sun/jdi/LocationTest.java \
|
||||
com/sun/jdi/ModificationWatchpoints.java \
|
||||
com/sun/jdi/MonitorEventTest.java \
|
||||
com/sun/jdi/MonitorFrameInfo.java \
|
||||
com/sun/jdi/NullThreadGroupNameTest.java \
|
||||
com/sun/jdi/PopAndStepTest.java \
|
||||
com/sun/jdi/PopAsynchronousTest.java \
|
||||
com/sun/jdi/ProcessAttachTest.java \
|
||||
com/sun/jdi/ReferrersTest.java \
|
||||
com/sun/jdi/RequestReflectionTest.java \
|
||||
com/sun/jdi/ResumeOneThreadTest.java \
|
||||
com/sun/jdi/RunToExit.java \
|
||||
com/sun/jdi/SourceNameFilterTest.java \
|
||||
com/sun/jdi/SuspendAfterDeath.java \
|
||||
com/sun/jdi/VarargsTest.java \
|
||||
com/sun/jdi/Vars.java \
|
||||
com/sun/jdi/redefineMethod/RedefineTest.java \
|
||||
com/sun/jdi/sde/MangleTest.java \
|
||||
com/sun/jdi/sde/TemperatureTableTest.java
|
||||
|
||||
jdk_jfr_sanity = \
|
||||
jdk/jfr/api/recording/event/TestLoadEventAfterStart.java \
|
||||
jdk/jfr/api/recording/state/TestState.java \
|
||||
jdk/jfr/event/os/TestCPULoad.java \
|
||||
jdk/jfr/event/allocation/TestObjectAllocationSampleEvent.java \
|
||||
jdk/jfr/jcmd/TestJcmdStartStopDefault.java \
|
||||
jdk/jfr/event/io/TestFileStreamEvents.java \
|
||||
jdk/jfr/event/compiler/TestCompilerCompile.java \
|
||||
jdk/jfr/event/gc/collection/TestGCGarbageCollectionEvent.java \
|
||||
jdk/jfr/event/runtime/TestClassLoadEvent.java \
|
||||
jdk/jfr/event/runtime/TestJavaBlockedEvent.java \
|
||||
jdk/jfr/event/gc/collection/TestGCWithFasttime.java \
|
||||
jdk/jfr/event/gc/configuration/TestGCConfigurationEvent.java \
|
||||
jdk/jfr/event/metadata/TestDefaultConfigurations.java \
|
||||
jdk/jfr/event/oldobject/TestDFSWithSmallStack.java \
|
||||
jdk/jfr/startupargs/TestDumpOnExit.java \
|
||||
jdk/jfr/api/consumer/recordingstream/TestBasics.java
|
||||
|
||||
svc_tools_sanity =
|
||||
|
||||
#############################
|
||||
#
|
||||
# Stable test groups
|
||||
#
|
||||
|
||||
jdk_stable = \
|
||||
:jdk_core \
|
||||
:jdk_svc \
|
||||
:jdk_beans \
|
||||
:jdk_imageio \
|
||||
:jdk_sound \
|
||||
:jdk_sctp \
|
||||
javax/accessibility \
|
||||
com/sun/java/swing
|
||||
|
||||
needs_g1gc = \
|
||||
jdk/jfr/event/gc/refstat/TestRefStatEventWithG1ConcurrentMark.java \
|
||||
jdk/jfr/event/gc/refstat/TestRefStatEventWithG1FullCollection.java \
|
||||
jdk/jfr/event/gc/refstat/TestRefStatEventWithG1New.java \
|
||||
jdk/jfr/event/gc/detailed/TestEvacuationFailedEvent.java \
|
||||
jdk/jfr/event/gc/detailed/TestEvacuationInfoEvent.java \
|
||||
jdk/jfr/event/gc/detailed/TestG1ConcurrentModeFailureEvent.java \
|
||||
jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java \
|
||||
jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java \
|
||||
jdk/jfr/event/gc/collection/TestYoungGarbageCollectionEventWithG1New.java \
|
||||
jdk/jfr/event/gc/collection/TestGCEventMixedWithG1FullCollection.java \
|
||||
jdk/jfr/event/gc/collection/TestGCEventMixedWithG1ConcurrentMark.java \
|
||||
jdk/jfr/event/gc/collection/TestG1ParallelPhases.java \
|
||||
jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1FullCollection.java \
|
||||
jdk/jfr/event/gc/objectcount/TestObjectCountAfterGCEventWithG1ConcurrentMark.java \
|
||||
jdk/jfr/event/gc/heapsummary/TestHeapSummaryEventG1.java
|
||||
|
||||
# This set of tests will be executed in an ipv6 only environment
|
||||
|
||||
jdk_ipv6_only = \
|
||||
:jdk_net \
|
||||
:jdk_nio_networkchannel
|
||||
|
||||
jdk_nio_networkchannel = \
|
||||
java/nio/channels/AsyncCloseAndInterrupt.java \
|
||||
java/nio/channels/AsynchronousServerSocketChannel \
|
||||
java/nio/channels/AsynchronousSocketChannel \
|
||||
java/nio/channels/DatagramChannel \
|
||||
java/nio/channels/ServerSocketChannel \
|
||||
java/nio/channels/SocketChannel \
|
||||
java/nio/channels/Selector \
|
||||
java/nio/channels/etc
|
||||
|
||||
jdk_core_manual = \
|
||||
:jdk_core_manual_no_input \
|
||||
:jdk_security_manual_no_input \
|
||||
:jdk_core_manual_interactive \
|
||||
:jdk_security_manual_interactive
|
||||
|
||||
jdk_core_manual_no_input = \
|
||||
java/net/HugeDataTransferTest.java \
|
||||
java/net/httpclient/BodyProcessorInputStreamTest.java \
|
||||
java/net/httpclient/HttpInputStreamTest.java \
|
||||
java/util/zip/ZipFile/TestZipFile.java \
|
||||
javax/net/ssl/compatibility/AlpnTest.java \
|
||||
javax/net/ssl/compatibility/BasicConnectTest.java \
|
||||
javax/net/ssl/compatibility/HrrTest.java \
|
||||
javax/net/ssl/compatibility/SniTest.java \
|
||||
jdk/nio/zipfs/LargeCompressedEntrySizeTest.java \
|
||||
java/util/ArrayList/Bug8146568.java \
|
||||
java/util/Vector/Bug8148174.java \
|
||||
com/sun/net/httpserver/simpleserver/CommandLinePortNotSpecifiedTest.java \
|
||||
com/sun/net/httpserver/simpleserver/jwebserver/CommandLinePortNotSpecifiedTest.java \
|
||||
com/sun/net/httpserver/simpleserver/DocRootDirPermissionsWinTest.java \
|
||||
javax/xml/jaxp/datatype/8033980/GregorianCalAndDurSerDataUtil.java \
|
||||
java/util/zip/ZipFile/CenSizeMaximum.java
|
||||
|
||||
jdk_security_manual_no_input = \
|
||||
:jdk_security_infra \
|
||||
com/sun/crypto/provider/Cipher/AEAD/GCMIncrementByte4.java \
|
||||
com/sun/crypto/provider/Cipher/AEAD/GCMIncrementDirect4.java \
|
||||
sun/security/smartcardio/TestChannel.java \
|
||||
sun/security/smartcardio/TestConnect.java \
|
||||
sun/security/smartcardio/TestConnectAgain.java \
|
||||
sun/security/smartcardio/TestControl.java \
|
||||
sun/security/smartcardio/TestDefault.java \
|
||||
sun/security/smartcardio/TestDirect.java \
|
||||
sun/security/smartcardio/TestExclusive.java \
|
||||
sun/security/smartcardio/TestMultiplePresent.java \
|
||||
sun/security/smartcardio/TestPresent.java \
|
||||
sun/security/smartcardio/TestTransmit.java \
|
||||
sun/security/tools/jarsigner/compatibility/Compatibility.java \
|
||||
sun/security/tools/keytool/ListKeyChainStore.java
|
||||
|
||||
jdk_core_manual_interactive = \
|
||||
com/sun/jndi/dns/Test6991580.java \
|
||||
java/util/TimeZone/DefaultTimeZoneTest.java \
|
||||
java/nio/MappedByteBuffer/PmemTest.java \
|
||||
java/rmi/registry/nonLocalRegistry/NonLocalRegistryTest.java \
|
||||
java/rmi/registry/nonLocalRegistry/NonLocalSkeletonTest.java \
|
||||
java/foreign/TestMatrix.java \
|
||||
java/nio/channels/FileChannel/BlockDeviceSize.java
|
||||
|
||||
jdk_security_manual_interactive = \
|
||||
sun/security/tools/keytool/i18n.java \
|
||||
com/sun/security/auth/callback/TextCallbackHandler/Password.java \
|
||||
sun/security/krb5/config/native/TestDynamicStore.java \
|
||||
sun/security/tools/keytool/EchoPassword.java
|
||||
|
||||
# Test sets for running inside container environment
|
||||
jdk_containers_extended = \
|
||||
:jdk_io \
|
||||
:jdk_nio \
|
||||
:jdk_svc
|
||||
|
||||
jdk_core_no_security = \
|
||||
:jdk_core \
|
||||
-:jdk_security
|
||||
|
||||
# Set of tests for `@since` checks in source code documentation
|
||||
jdk_since_checks = \
|
||||
tools/sincechecker/
|
||||
340
test/jdk/build/AbsPathsInImage.java
Normal file
340
test/jdk/build/AbsPathsInImage.java
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2025, 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 java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8226346
|
||||
* @summary Check all output files for absolute path fragments
|
||||
* @requires !vm.debug
|
||||
* @comment ASAN keeps the 'unwanted' paths in the binaries because of its build options
|
||||
* @requires !vm.asan
|
||||
* @run main AbsPathsInImage
|
||||
*/
|
||||
public class AbsPathsInImage {
|
||||
|
||||
// Set this property on command line to scan an alternate dir or file:
|
||||
// JTREG=JAVA_OPTIONS=-Djdk.test.build.AbsPathInImage.dir=/path/to/dir
|
||||
public static final String DIR_PROPERTY = "jdk.test.build.AbsPathsInImage.dir";
|
||||
private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().contains("windows");
|
||||
private static final boolean IS_LINUX = System.getProperty("os.name").toLowerCase().contains("linux");
|
||||
private static final int DEFAULT_BUFFER_SIZE = 8192;
|
||||
private static List<byte[]> searchPatterns = new ArrayList<>();
|
||||
private static List<int[]> prefixTables = new ArrayList<>();
|
||||
|
||||
private boolean matchFound = false;
|
||||
|
||||
record Match(int begin, int end) { }
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String jdkPathString = System.getProperty("test.jdk");
|
||||
Path jdkHome = Paths.get(jdkPathString);
|
||||
|
||||
Path dirToScan = jdkHome;
|
||||
String overrideDir = System.getProperty(DIR_PROPERTY);
|
||||
if (overrideDir != null) {
|
||||
dirToScan = Paths.get(overrideDir);
|
||||
}
|
||||
|
||||
String buildWorkspaceRoot = null;
|
||||
String buildOutputRoot = null;
|
||||
String testImageDirString = System.getenv("TEST_IMAGE_DIR");
|
||||
if (testImageDirString != null) {
|
||||
Path testImageDir = Paths.get(testImageDirString);
|
||||
Path buildInfoPropertiesFile = testImageDir.resolve("build-info.properties");
|
||||
System.out.println("Getting patterns from " + buildInfoPropertiesFile.toString());
|
||||
Properties buildInfoProperties = new Properties();
|
||||
try (InputStream inStream = Files.newInputStream(buildInfoPropertiesFile)) {
|
||||
buildInfoProperties.load(inStream);
|
||||
}
|
||||
buildWorkspaceRoot = buildInfoProperties.getProperty("build.workspace.root");
|
||||
buildOutputRoot = buildInfoProperties.getProperty("build.output.root");
|
||||
} else {
|
||||
System.out.println("Getting patterns from local environment");
|
||||
// Try to resolve the workspace root based on the jtreg test root dir
|
||||
String testRootDirString = System.getProperty("test.root");
|
||||
if (testRootDirString != null) {
|
||||
Path testRootDir = Paths.get(testRootDirString);
|
||||
// Remove /test/jdk suffix
|
||||
buildWorkspaceRoot = testRootDir.getParent().getParent().toString();
|
||||
}
|
||||
// Remove /jdk
|
||||
Path buildOutputRootPath = jdkHome.getParent();
|
||||
if (buildOutputRootPath.endsWith("images")) {
|
||||
buildOutputRootPath = buildOutputRootPath.getParent();
|
||||
}
|
||||
buildOutputRoot = buildOutputRootPath.toString();
|
||||
}
|
||||
if (buildWorkspaceRoot == null) {
|
||||
throw new Error("Could not find workspace root, test cannot run");
|
||||
}
|
||||
if (buildOutputRoot == null) {
|
||||
throw new Error("Could not find build output root, test cannot run");
|
||||
}
|
||||
// Validate the root paths
|
||||
if (!Paths.get(buildWorkspaceRoot).isAbsolute()) {
|
||||
throw new Error("Workspace root is not an absolute path: " + buildWorkspaceRoot);
|
||||
}
|
||||
if (!Paths.get(buildOutputRoot).isAbsolute()) {
|
||||
throw new Error("Output root is not an absolute path: " + buildOutputRoot);
|
||||
}
|
||||
|
||||
expandPatterns(buildWorkspaceRoot);
|
||||
expandPatterns(buildOutputRoot);
|
||||
createPrefixTables();
|
||||
|
||||
System.out.println("Looking for:");
|
||||
for (byte[] searchPattern : searchPatterns) {
|
||||
System.out.println(new String(searchPattern));
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
AbsPathsInImage absPathsInImage = new AbsPathsInImage();
|
||||
absPathsInImage.scanFiles(dirToScan);
|
||||
|
||||
if (absPathsInImage.matchFound) {
|
||||
throw new Exception("Test failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add path pattern to list of patterns to search for. Create all possible
|
||||
* variants depending on platform.
|
||||
*/
|
||||
private static void expandPatterns(String pattern) {
|
||||
if (IS_WINDOWS) {
|
||||
String forward = pattern.replace('\\', '/');
|
||||
String back = pattern.replace('/', '\\');
|
||||
if (pattern.charAt(1) == ':') {
|
||||
String forwardUpper = String.valueOf(pattern.charAt(0)).toUpperCase() + forward.substring(1);
|
||||
String forwardLower = String.valueOf(pattern.charAt(0)).toLowerCase() + forward.substring(1);
|
||||
String backUpper = String.valueOf(pattern.charAt(0)).toUpperCase() + back.substring(1);
|
||||
String backLower = String.valueOf(pattern.charAt(0)).toLowerCase() + back.substring(1);
|
||||
searchPatterns.add(forwardUpper.getBytes());
|
||||
searchPatterns.add(forwardLower.getBytes());
|
||||
searchPatterns.add(backUpper.getBytes());
|
||||
searchPatterns.add(backLower.getBytes());
|
||||
} else {
|
||||
searchPatterns.add(forward.getBytes());
|
||||
searchPatterns.add(back.getBytes());
|
||||
}
|
||||
} else {
|
||||
searchPatterns.add(pattern.getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The failure function for KMP. Returns the correct index in the pattern to jump
|
||||
* back to when encountering a mismatched character. Used in both
|
||||
* createPrefixTables (pre-processing) and scanBytes (matching).
|
||||
*/
|
||||
private static int getPrefixIndex(int patternIdx, int state, byte match) {
|
||||
if (state == 0) {
|
||||
return 0;
|
||||
}
|
||||
byte[] searchPattern = searchPatterns.get(patternIdx);
|
||||
int[] prefixTable = prefixTables.get(patternIdx);
|
||||
int i = prefixTable[state - 1];
|
||||
while (i > 0 && searchPattern[i] != match) {
|
||||
i = prefixTable[i - 1];
|
||||
}
|
||||
return searchPattern[i] == match ? i + 1 : i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-processing string patterns for Knuth–Morris–Pratt (KMP) search algorithm.
|
||||
* Lookup tables of longest prefixes at each given index are created for each
|
||||
* search pattern string. These tables are later used in scanBytes during matching
|
||||
* as lookups for failure state transitions.
|
||||
*/
|
||||
private static void createPrefixTables() {
|
||||
for (int patternIdx = 0; patternIdx < searchPatterns.size(); patternIdx++) {
|
||||
int patternLen = searchPatterns.get(patternIdx).length;
|
||||
int[] prefixTable = new int[patternLen];
|
||||
prefixTables.add(prefixTable);
|
||||
for (int i = 1; i < patternLen; i++) {
|
||||
prefixTable[i] = getPrefixIndex(patternIdx, i, searchPatterns.get(patternIdx)[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scanFiles(Path root) throws IOException {
|
||||
Files.walkFileTree(root, new SimpleFileVisitor<>() {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||
String dirName = dir.toString();
|
||||
if (dirName.endsWith(".dSYM")) {
|
||||
return FileVisitResult.SKIP_SUBTREE;
|
||||
}
|
||||
return super.preVisitDirectory(dir, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
String fileName = file.toString();
|
||||
if (Files.isSymbolicLink(file)) {
|
||||
return super.visitFile(file, attrs);
|
||||
} else if ((fileName.endsWith(".debuginfo") && !IS_LINUX) || fileName.endsWith(".pdb")) {
|
||||
// Do nothing
|
||||
} else if (fileName.endsWith(".zip")) {
|
||||
scanZipFile(file);
|
||||
} else {
|
||||
scanFile(file);
|
||||
}
|
||||
return super.visitFile(file, attrs);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void scanFile(Path file) throws IOException {
|
||||
List<Match> matches;
|
||||
try (InputStream inputStream = Files.newInputStream(file)) {
|
||||
matches = scanBytes(inputStream);
|
||||
}
|
||||
// test succeeds
|
||||
if (matches.size() == 0) {
|
||||
return;
|
||||
}
|
||||
// test fails; pay penalty and re-scan file for debug output
|
||||
try (InputStream inputStream = Files.newInputStream(file)) {
|
||||
printDebugOutput(inputStream, matches, file + ":");
|
||||
}
|
||||
}
|
||||
|
||||
private void scanZipFile(Path zipFile) throws IOException {
|
||||
List<List<Match>> entryMatches = new ArrayList<>();
|
||||
boolean found = false;
|
||||
ZipEntry zipEntry;
|
||||
try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(zipFile))) {
|
||||
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
|
||||
List<Match> matches = scanBytes(zipInputStream);
|
||||
if (matches.size() > 0) {
|
||||
entryMatches.add(matches);
|
||||
found = true;
|
||||
} else {
|
||||
entryMatches.add(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
// test succeeds
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
// test fails
|
||||
try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(zipFile))) {
|
||||
int i = 0;
|
||||
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
|
||||
List<Match> matches = entryMatches.get(i);
|
||||
i++;
|
||||
if (matches != null) {
|
||||
printDebugOutput(zipInputStream, matches, zipFile + ", " + zipEntry.getName() + ":");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans each byte until encounters a match with one of searchPatterns. Uses KMP to
|
||||
* perform matches. Keep track of current matched index (states) for each search
|
||||
* pattern. At each given byte, update states accordingly (increment if match or
|
||||
* failure function transition if mismatch). Returns a list of Match objects.
|
||||
*/
|
||||
private List<Match> scanBytes(InputStream input) throws IOException {
|
||||
List<Match> matches = new ArrayList<>();
|
||||
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
|
||||
int[] states = new int[searchPatterns.size()];
|
||||
int fileIdx = 0;
|
||||
int bytesRead, patternLen;
|
||||
while ((bytesRead = input.read(buf)) != -1) {
|
||||
for (int bufIdx = 0; bufIdx < bytesRead; bufIdx++, fileIdx++) {
|
||||
byte datum = buf[bufIdx];
|
||||
for (int i = 0; i < searchPatterns.size(); i++) {
|
||||
patternLen = searchPatterns.get(i).length;
|
||||
if (datum != searchPatterns.get(i)[states[i]]) {
|
||||
states[i] = getPrefixIndex(i, states[i], datum);
|
||||
} else if (++states[i] == patternLen) {
|
||||
// technically at last match, state should reset according to failure function
|
||||
// but in original test, matching didn't search same string for multiple matches
|
||||
states[i] = 0;
|
||||
matches.add(new Match(fileIdx - patternLen + 1, fileIdx));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* In original test, failed test output would backtrack to last non-ascii byte on
|
||||
* matched pattern. This is incompatible with the new buffered approach (and a
|
||||
* proper solution requires a 2nd dynamic buffer). Instead, on failed test case,
|
||||
* files are scanned a 2nd time to print debug output. Failed runs will pay
|
||||
* additional performance/space penalty, but passing runs are faster.
|
||||
*/
|
||||
private void printDebugOutput(InputStream input, List<Match> matches, final String HEADER) throws IOException{
|
||||
matchFound = true;
|
||||
System.out.println(HEADER);
|
||||
matches.sort(comparing(Match::begin));
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
|
||||
int matchIdx = 0;
|
||||
int fileIdx = 0;
|
||||
int bytesRead;
|
||||
while (matchIdx < matches.size() && (bytesRead = input.read(buf)) != -1) {
|
||||
for (int i = 0; matchIdx < matches.size() && i < bytesRead; i++, fileIdx++) {
|
||||
byte datum = buf[i];
|
||||
if (datum >= 32 && datum <= 126) {
|
||||
output.write(datum);
|
||||
} else if (fileIdx < matches.get(matchIdx).begin()) {
|
||||
output.reset();
|
||||
} else if (fileIdx > matches.get(matchIdx).end()) {
|
||||
System.out.println(output.toString());
|
||||
output.reset();
|
||||
// This imperfect as incorrect in edge cases with patterns containing non-ascii?
|
||||
// but high-accuracy not priority + output still legible and useful
|
||||
for (; matchIdx < matches.size() && matches.get(matchIdx).end() < fileIdx; matchIdx++);
|
||||
} else {
|
||||
output.write(datum);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
244
test/jdk/build/CheckFiles.java
Normal file
244
test/jdk/build/CheckFiles.java
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
* Copyright (c) 2026 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2026, 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 java.io.IOException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import jdk.test.lib.Platform;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Check for unwanted files (types/extensions) in the jdk image
|
||||
* @library /test/lib
|
||||
* @requires !vm.debug
|
||||
* @run main CheckFiles
|
||||
*/
|
||||
public class CheckFiles {
|
||||
|
||||
// Set this property on command line to scan an alternate dir or file:
|
||||
// JTREG=JAVA_OPTIONS=-Djdk.test.build.CheckFiles.dir=/path/to/dir
|
||||
public static final String DIR_PROPERTY = "jdk.test.build.CheckFiles.dir";
|
||||
|
||||
private static boolean isGpl(Path myFile) {
|
||||
if (myFile == null || !Files.exists(myFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
String firstLine = Files.readAllLines(myFile).stream()
|
||||
.findFirst().orElse("");
|
||||
return firstLine.contains("The GNU General Public License (GPL)");
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String jdkPathString = System.getProperty("test.jdk");
|
||||
Path jdkHome = Paths.get(jdkPathString);
|
||||
|
||||
Path mainDirToScan = jdkHome;
|
||||
String overrideDir = System.getProperty(DIR_PROPERTY);
|
||||
if (overrideDir != null) {
|
||||
mainDirToScan = Paths.get(overrideDir);
|
||||
}
|
||||
|
||||
System.out.println("Main directory to scan:" + mainDirToScan);
|
||||
Path binDir = mainDirToScan.resolve("bin");
|
||||
Path libDir = mainDirToScan.resolve("lib");
|
||||
Path includeDir = mainDirToScan.resolve("include");
|
||||
Path jmodsDir = mainDirToScan.resolve("jmods");
|
||||
|
||||
System.out.println("Bin directory to scan:" + binDir);
|
||||
ArrayList<String> allowedEndingsBinDir = new ArrayList<>();
|
||||
// UNIX - no extensions are allowed; Windows : .dll, .exe, .pdb, .jsa
|
||||
if (Platform.isWindows()) {
|
||||
allowedEndingsBinDir.add(".dll");
|
||||
allowedEndingsBinDir.add(".exe");
|
||||
allowedEndingsBinDir.add(".pdb");
|
||||
allowedEndingsBinDir.add(".jsa");
|
||||
}
|
||||
boolean binDirRes = scanFiles(binDir, allowedEndingsBinDir);
|
||||
|
||||
System.out.println("Lib directory to scan:" + libDir);
|
||||
ArrayList<String> allowedEndingsLibDir = new ArrayList<>();
|
||||
allowedEndingsLibDir.add(".jfc"); // jfr config files
|
||||
allowedEndingsLibDir.add("cacerts");
|
||||
allowedEndingsLibDir.add("blocked.certs");
|
||||
allowedEndingsLibDir.add("public_suffix_list.dat");
|
||||
allowedEndingsLibDir.add("classlist");
|
||||
allowedEndingsLibDir.add("fontconfig.bfc");
|
||||
allowedEndingsLibDir.add("fontconfig.properties.src");
|
||||
allowedEndingsLibDir.add("ct.sym");
|
||||
allowedEndingsLibDir.add("jrt-fs.jar");
|
||||
allowedEndingsLibDir.add("jvm.cfg");
|
||||
allowedEndingsLibDir.add("modules");
|
||||
allowedEndingsLibDir.add("psfontj2d.properties");
|
||||
allowedEndingsLibDir.add("psfont.properties.ja");
|
||||
allowedEndingsLibDir.add("src.zip");
|
||||
allowedEndingsLibDir.add("tzdb.dat");
|
||||
allowedEndingsLibDir.add("javafx-swt.jar");
|
||||
allowedEndingsLibDir.add("javafx.properties");
|
||||
if (Platform.isWindows()) {
|
||||
allowedEndingsLibDir.add(".lib");
|
||||
allowedEndingsLibDir.add("tzmappings");
|
||||
} else {
|
||||
allowedEndingsLibDir.add("jexec");
|
||||
allowedEndingsLibDir.add("jspawnhelper");
|
||||
allowedEndingsLibDir.add(".jsa");
|
||||
if (Platform.isOSX()) {
|
||||
allowedEndingsLibDir.add("shaders.metallib");
|
||||
allowedEndingsLibDir.add(".dylib");
|
||||
} else {
|
||||
allowedEndingsLibDir.add(".so");
|
||||
}
|
||||
if (Platform.isAix()) {
|
||||
allowedEndingsLibDir.add("tzmappings");
|
||||
}
|
||||
}
|
||||
boolean libDirRes = scanFiles(libDir, allowedEndingsLibDir);
|
||||
|
||||
if (binDirRes) {
|
||||
System.out.println("Bin directory scan successful.");
|
||||
} else {
|
||||
throw new Error("bin dir scan failed");
|
||||
}
|
||||
|
||||
if (libDirRes) {
|
||||
System.out.println("Lib directory scan successful.");
|
||||
} else {
|
||||
throw new Error("lib dir scan failed");
|
||||
}
|
||||
|
||||
if (Files.isDirectory(includeDir)) {
|
||||
System.out.println("Include directory to scan:" + includeDir);
|
||||
ArrayList<String> allowedEndingsIncludeDir = new ArrayList<>();
|
||||
allowedEndingsIncludeDir.add(".h");
|
||||
allowedEndingsIncludeDir.add(".hpp");
|
||||
boolean includeDirRes = scanFiles(includeDir, allowedEndingsIncludeDir);
|
||||
if (includeDirRes) {
|
||||
System.out.println("Include directory scan successful.");
|
||||
} else {
|
||||
throw new Error("include dir scan failed");
|
||||
}
|
||||
}
|
||||
|
||||
// when enabling "JEP 493: Linking Run-Time Images without JMODs" we do not
|
||||
// have the jmods folder at all, so first test the presence of the folder
|
||||
if (Files.isDirectory(jmodsDir)) {
|
||||
System.out.println("Jmods directory to scan:" + jmodsDir);
|
||||
ArrayList<String> allowedEndingsJmodsDir = new ArrayList<>();
|
||||
allowedEndingsJmodsDir.add(".jmod");
|
||||
boolean jmodsDirRes = scanFiles(jmodsDir, allowedEndingsJmodsDir);
|
||||
if (jmodsDirRes) {
|
||||
System.out.println("Jmods directory scan successful.");
|
||||
} else {
|
||||
throw new Error("jmods dir scan failed");
|
||||
}
|
||||
}
|
||||
|
||||
Path legalDir = mainDirToScan.resolve("legal");
|
||||
Path javabaseLicenseFile = mainDirToScan.resolve("legal/java.base/LICENSE");
|
||||
if (isGpl(javabaseLicenseFile)) { // for now check only legal dir of GPL based images; other ones might have other content
|
||||
System.out.println("GPL info found in java.base LICENSE file");
|
||||
ArrayList<String> allowedEndingsLegalDir = new ArrayList<>();
|
||||
allowedEndingsLegalDir.add(".md");
|
||||
allowedEndingsLegalDir.add("ADDITIONAL_LICENSE_INFO");
|
||||
allowedEndingsLegalDir.add("ASSEMBLY_EXCEPTION");
|
||||
allowedEndingsLegalDir.add("LICENSE");
|
||||
|
||||
ArrayList<String> requiredFilesInLegalSubdirs = new ArrayList<>();
|
||||
requiredFilesInLegalSubdirs.add("LICENSE");
|
||||
requiredFilesInLegalSubdirs.add("ADDITIONAL_LICENSE_INFO");
|
||||
requiredFilesInLegalSubdirs.add("ASSEMBLY_EXCEPTION");
|
||||
|
||||
System.out.println("Legal directory to scan:" + legalDir);
|
||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(legalDir)) {
|
||||
for (Path subfolder : stream) {
|
||||
if (Files.isDirectory(subfolder)) {
|
||||
System.out.println("Checking legal dir subfolder for required files: " + subfolder.getFileName());
|
||||
|
||||
for (String fileName : requiredFilesInLegalSubdirs) {
|
||||
Path filePath = subfolder.resolve(fileName);
|
||||
if (Files.exists(filePath)) {
|
||||
System.out.println(" Found " + fileName);
|
||||
} else {
|
||||
System.out.println(" Missing " + fileName);
|
||||
throw new Error("legal dir scan for required files failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean legalDirRes = scanFiles(legalDir, allowedEndingsLegalDir);
|
||||
if (legalDirRes) {
|
||||
System.out.println("Legal directory scan successful.");
|
||||
} else {
|
||||
throw new Error("Legal dir scan failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean scanFiles(Path root, ArrayList<String> allowedEndings) throws IOException {
|
||||
AtomicBoolean badFileFound = new AtomicBoolean(false);
|
||||
|
||||
Files.walkFileTree(root, new SimpleFileVisitor<>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
String fullFileName = file.toString();
|
||||
String fileName = file.getFileName().toString();
|
||||
System.out.println(" visiting file:" + fullFileName);
|
||||
checkFile(fileName, allowedEndings);
|
||||
return super.visitFile(file, attrs);
|
||||
}
|
||||
|
||||
private void checkFile(String name, ArrayList<String> allowedEndings) {
|
||||
if (allowedEndings.isEmpty()) { // no file extensions allowed
|
||||
int lastDot = name.lastIndexOf('.');
|
||||
if (lastDot > 0) {
|
||||
System.out.println(" --> ERROR this file is not allowed:" + name);
|
||||
badFileFound.set(true);
|
||||
}
|
||||
} else {
|
||||
boolean allowed = allowedEndings.stream().anyMatch(name::endsWith);
|
||||
if (! allowed) {
|
||||
System.out.println(" --> ERROR this file is not allowed:" + name);
|
||||
badFileFound.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return !badFileFound.get();
|
||||
}
|
||||
}
|
||||
141
test/jdk/build/releaseFile/CheckReleaseFile.java
Normal file
141
test/jdk/build/releaseFile/CheckReleaseFile.java
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2023, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8193660 8303476
|
||||
* @summary Check SOURCE line and JAVA_RUNTIME_VERSION in "release" file
|
||||
* @run main CheckReleaseFile
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CheckReleaseFile {
|
||||
|
||||
public static final String SRC_HASH_REGEXP = ":git:[a-z0-9]*\\+?";
|
||||
|
||||
public static void main(String args[]) throws IOException {
|
||||
String jdkPath = System.getProperty("test.jdk");
|
||||
String runtime = System.getProperty("java.runtime.name");
|
||||
|
||||
System.out.println("JDK Path : " + jdkPath);
|
||||
System.out.println("Runtime Name : " + runtime);
|
||||
|
||||
checkReleaseFile(Path.of(jdkPath));
|
||||
}
|
||||
|
||||
private static void checkReleaseFile(Path javaHome) throws IOException {
|
||||
String source = null;
|
||||
String runtimeVersion = null;
|
||||
|
||||
Path releaseFile = javaHome.resolve("release");
|
||||
|
||||
// open the stream to read in for Entries
|
||||
try (BufferedReader buffRead = Files.newBufferedReader(releaseFile)) {
|
||||
|
||||
// this is the string read
|
||||
String readIn;
|
||||
|
||||
// let's read some strings!
|
||||
while ((readIn = buffRead.readLine()) != null) {
|
||||
readIn = readIn.trim();
|
||||
|
||||
// throw out blank lines
|
||||
if (readIn.length() == 0)
|
||||
continue;
|
||||
|
||||
// grab SOURCE line
|
||||
if (readIn.startsWith("SOURCE=")) {
|
||||
source = readIn;
|
||||
continue;
|
||||
}
|
||||
|
||||
// grab JAVA_RUNTIME_VERSION line
|
||||
if (readIn.startsWith("JAVA_RUNTIME_VERSION=")) {
|
||||
runtimeVersion = readIn;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// was SOURCE even found?
|
||||
if (source == null) {
|
||||
throw new RuntimeException("SOURCE line was not found!");
|
||||
}
|
||||
checkSource(source);
|
||||
|
||||
if (runtimeVersion == null) {
|
||||
throw new RuntimeException("JAVA_RUNTIME_VERSION line was not found!");
|
||||
}
|
||||
String expected = "JAVA_RUNTIME_VERSION=\"" + Runtime.version() + "\"";
|
||||
if (!expected.equals(runtimeVersion)) {
|
||||
throw new RuntimeException("Mismatched runtime version: " +
|
||||
runtimeVersion + " expected: " + expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkSource(String source) {
|
||||
|
||||
System.out.println("The source string found: " + source);
|
||||
|
||||
// Extract the value of SOURCE=
|
||||
Pattern valuePattern = Pattern.compile("SOURCE=\"(.*)\"");
|
||||
Matcher valueMatcher = valuePattern.matcher(source);
|
||||
if (!valueMatcher.matches()) {
|
||||
throw new RuntimeException("SOURCE string has bad format, should be SOURCE=\"<value>\"");
|
||||
}
|
||||
String valueString = valueMatcher.group(1);
|
||||
|
||||
|
||||
String[] values = valueString.split(" ");
|
||||
|
||||
// First value MUST start with ".:" regardless of Oracle or OpenJDK
|
||||
String rootRegexp = "\\." + SRC_HASH_REGEXP;
|
||||
if (!values[0].matches(rootRegexp)) {
|
||||
throw new RuntimeException("The test failed, first element did not match regexp: " + rootRegexp);
|
||||
}
|
||||
|
||||
// If it's an Oracle build, it can be either OpenJDK or OracleJDK. Other
|
||||
// builds may have any number of additional elements in any format.
|
||||
String runtime = System.getProperty("java.runtime.name");
|
||||
String vendor = System.getProperty("java.vendor");
|
||||
if (runtime.contains("OpenJDK") && vendor.contains("Oracle Corporation")) {
|
||||
System.out.println("Oracle built OpenJDK, verifying SOURCE format");
|
||||
if (values.length != 1) {
|
||||
throw new RuntimeException("The test failed, wrong number of elements in SOURCE list." +
|
||||
" Should be 1 for Oracle built OpenJDK.");
|
||||
}
|
||||
} else {
|
||||
System.out.println("Not Oracle built OpenJDK, skipping further SOURCE verification");
|
||||
}
|
||||
|
||||
// Everything was fine
|
||||
System.out.println("The test passed!");
|
||||
}
|
||||
}
|
||||
114
test/jdk/build/translations/VerifyTranslations.java
Normal file
114
test/jdk/build/translations/VerifyTranslations.java
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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 java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires release.implementor == "Oracle Corporation"
|
||||
* @modules jdk.jlink/jdk.tools.jimage
|
||||
* @summary Oracle builds of OpenJDK should only contain english, chinese and
|
||||
* japanese translations
|
||||
*/
|
||||
public class VerifyTranslations {
|
||||
|
||||
/**
|
||||
* The set of translations we want to see in an Oracle built image
|
||||
*/
|
||||
private static final Set<String> VALID_TRANSLATION_SUFFIXES = Set.of(
|
||||
"_en", "_en_US", "_en_US_POSIX", "_ja", "_zh_CN", "_de"
|
||||
);
|
||||
|
||||
/**
|
||||
* This regexp will not match locales with 3 letter lang strings because
|
||||
* doing so would trigger a ton of false positives all over the source
|
||||
* tree. This is ok for now but is a potential future flaw in the test.
|
||||
*/
|
||||
private static final String BASE_LOCALE_REGEXP
|
||||
= "(_[a-z]{2}(_[A-Z][a-z]{3})?(_([A-Z]{2})|([0-9]{3}))?(_[a-zA-Z]+)?)";
|
||||
|
||||
public static void main(String[] args) {
|
||||
String jdkPath = System.getProperty("test.jdk");
|
||||
String modulesFile = jdkPath + "/lib/modules";
|
||||
|
||||
// Run jimage tool to extract list of all classes and resources in the jdk
|
||||
StringWriter output = new StringWriter();
|
||||
jdk.tools.jimage.Main.run(new String[] { "list", modulesFile }, new PrintWriter(output));
|
||||
|
||||
Pattern classesLocalePattern = Pattern.compile(BASE_LOCALE_REGEXP + "\\.(class|properties)");
|
||||
|
||||
boolean failed = false;
|
||||
String module = "";
|
||||
for (String line : output.toString().split("\n")) {
|
||||
if (line.startsWith("Module: ")) {
|
||||
module = line.substring(8).trim();
|
||||
}
|
||||
// We do not filter resources in jdk.localedata
|
||||
if (!module.equals("jdk.localedata")) {
|
||||
Matcher matcher = classesLocalePattern.matcher(line);
|
||||
if (matcher.find()) {
|
||||
if (!VALID_TRANSLATION_SUFFIXES.contains(matcher.group(1))) {
|
||||
System.out.println("Unsupported translation found in lib/modules: "
|
||||
+ module + "/" + line.trim());
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check all files in src.zip
|
||||
Pattern sourceLocalePattern = Pattern.compile(BASE_LOCALE_REGEXP + "\\.java");
|
||||
String srcZip = jdkPath + "/lib/src.zip";
|
||||
try (ZipInputStream srcZipInput = new ZipInputStream(
|
||||
new BufferedInputStream(new FileInputStream(srcZip)))) {
|
||||
ZipEntry entry;
|
||||
while ((entry = srcZipInput.getNextEntry()) != null) {
|
||||
String name = entry.getName();
|
||||
if (!name.startsWith("jdk.localedata")) {
|
||||
Matcher matcher = sourceLocalePattern.matcher(name);
|
||||
if (matcher.find()) {
|
||||
if (!VALID_TRANSLATION_SUFFIXES.contains(matcher.group(1))) {
|
||||
System.out.println("Unsupported translation found in lib/src.zip: " + name);
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
throw new RuntimeException("lib/modules contains unsupported translations");
|
||||
}
|
||||
}
|
||||
}
|
||||
104
test/jdk/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java
Normal file
104
test/jdk/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2021, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8007267 8233648
|
||||
* @summary [macosx] com.apple.eawt.Application.setDefaultMenuBar is not working
|
||||
* @requires (os.family == "mac")
|
||||
* @modules java.desktop/com.apple.eawt
|
||||
* @run main/othervm DefaultMenuBarTest
|
||||
*/
|
||||
|
||||
import java.awt.Robot;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
|
||||
public class DefaultMenuBarTest {
|
||||
static KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.META_MASK);
|
||||
|
||||
static volatile int listenerCallCounter = 0;
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (!System.getProperty("os.name").contains("OS X")) {
|
||||
System.out.println("This test is for MacOS only. Automatically passed on other platforms.");
|
||||
return;
|
||||
}
|
||||
|
||||
System.setProperty("apple.laf.useScreenMenuBar", "true");
|
||||
SwingUtilities.invokeAndWait(DefaultMenuBarTest::createAndShowGUI);
|
||||
|
||||
Robot robot = new Robot();
|
||||
robot.setAutoDelay(100);
|
||||
robot.waitForIdle();
|
||||
|
||||
robot.keyPress(KeyEvent.VK_META);
|
||||
robot.keyPress(ks.getKeyCode());
|
||||
robot.keyRelease(ks.getKeyCode());
|
||||
robot.keyRelease(KeyEvent.VK_META);
|
||||
|
||||
robot.waitForIdle();
|
||||
|
||||
if (listenerCallCounter != 1) {
|
||||
throw new Exception("Test failed: ActionListener either wasn't called or was called more than once");
|
||||
}
|
||||
}
|
||||
|
||||
private static void createAndShowGUI() {
|
||||
JMenu menu = new JMenu("File");
|
||||
JMenuItem newItem = new JMenuItem("Open");
|
||||
|
||||
newItem.setAccelerator(ks);
|
||||
newItem.addActionListener(e -> listenerCallCounter++);
|
||||
menu.add(newItem);
|
||||
|
||||
JMenuBar defaultMenu = new JMenuBar();
|
||||
defaultMenu.add(menu);
|
||||
|
||||
// Application.getApplication().setDefaultMenuBar(defaultMenu);
|
||||
try {
|
||||
Class appClass = Class.forName("com.apple.eawt.Application");
|
||||
if (appClass != null) {
|
||||
Method method = appClass.getMethod("getApplication");
|
||||
if (method != null) {
|
||||
Object app = method.invoke(null, new Object[]{});
|
||||
if (app != null) {
|
||||
method = appClass.getMethod("setDefaultMenuBar", new Class[]{JMenuBar.class});
|
||||
if (method != null) {
|
||||
method.invoke(app, new Object[]{defaultMenu});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
test/jdk/com/apple/eawt/TEST.properties
Normal file
2
test/jdk/com/apple/eawt/TEST.properties
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
modules=java.desktop
|
||||
|
||||
209
test/jdk/com/apple/laf/RootPane/RootPaneDefaultButtonTest.java
Normal file
209
test/jdk/com/apple/laf/RootPane/RootPaneDefaultButtonTest.java
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8344697
|
||||
* @summary Default button in AquaRootPaneUI should paint special background color
|
||||
* @requires (os.family == "mac")
|
||||
* @run main RootPaneDefaultButtonTest
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
/**
|
||||
* This presents two dialogs, each with two possible default buttons. The
|
||||
* background color of the default button should change based on which radio
|
||||
* button is selected.
|
||||
* <p>
|
||||
* Note we've never expected this test to fail. This test was introduced
|
||||
* because the resolution to JDK-8344697 involved removing code, and we wanted
|
||||
* to double-check that the removed code didn't negatively affect how default
|
||||
* buttons are repainted.
|
||||
*/
|
||||
public class RootPaneDefaultButtonTest {
|
||||
|
||||
static class TestDialog extends JDialog {
|
||||
|
||||
JButton button1 = new JButton("Button 1");
|
||||
JButton button2 = new JButton("Button 2");
|
||||
|
||||
TestDialog() {
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
getContentPane().add(createPushButtonRow(), BorderLayout.SOUTH);
|
||||
setUndecorated(true);
|
||||
pack();
|
||||
}
|
||||
|
||||
private JPanel createPushButtonRow() {
|
||||
JPanel p = new JPanel(new GridLayout(1, 2));
|
||||
p.add(button1);
|
||||
p.add(button2);
|
||||
p.setBorder(new EmptyBorder(5,5,5,5));
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We want 2 dialogs: one in the foreground and one not in the foreground
|
||||
*/
|
||||
static class TestScene {
|
||||
boolean isButton1Default, isButton2Default;
|
||||
|
||||
TestScene(boolean isButton1Default, boolean isButton2Default) {
|
||||
this.isButton1Default = isButton1Default;
|
||||
this.isButton2Default = isButton2Default;
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
System.out.println(
|
||||
"Testing isButton1Default = " + isButton1Default +
|
||||
" isButton2Default = " + isButton2Default);
|
||||
TestDialog window1 = new TestDialog();
|
||||
TestDialog window2 = new TestDialog();
|
||||
|
||||
if (isButton1Default) {
|
||||
window1.getRootPane().setDefaultButton(window1.button1);
|
||||
}
|
||||
if (isButton2Default) {
|
||||
window1.getRootPane().setDefaultButton(window1.button2);
|
||||
}
|
||||
|
||||
Rectangle r1 = new Rectangle(0, 100,
|
||||
window1.getWidth(), window1.getHeight());
|
||||
window1.setBounds(r1);
|
||||
|
||||
Rectangle r2 = new Rectangle((int) (r1.getMaxX() + 10), 100,
|
||||
window2.getWidth(), window2.getHeight());
|
||||
window2.setBounds(r2);
|
||||
|
||||
window1.setVisible(true);
|
||||
window2.setVisible(true);
|
||||
|
||||
Rectangle sum = new Rectangle();
|
||||
sum.add(r1);
|
||||
sum.add(r2);
|
||||
BufferedImage bi = new BufferedImage(sum.width, sum.height,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = bi.createGraphics();
|
||||
window1.paint(g.create(r1.x, r1.y, r1.width, r1.height));
|
||||
window2.paint(g.create(r2.x, r2.y, r2.width, r2.height));
|
||||
g.dispose();
|
||||
|
||||
// the exact colors may change depending on your system's
|
||||
// appearance. Depending on how you've configured "Appearance"
|
||||
// in the System Settings app: the default button may be blue
|
||||
// (the default), red, purple, etc. So instead of checking for
|
||||
// a specific color: we'll make sure 3-4 are the same color,
|
||||
// and one is significantly different.
|
||||
Color defaultColor = null;
|
||||
Color nonDefaultColor = null;
|
||||
|
||||
JButton[] buttons = new JButton[] {window1.button1,
|
||||
window1.button2, window2.button1, window2.button2};
|
||||
|
||||
try {
|
||||
for (int a = 0; a < buttons.length; a++) {
|
||||
try {
|
||||
JButton b = buttons[a];
|
||||
|
||||
Point p = b.getLocationOnScreen();
|
||||
int x = p.x + 20;
|
||||
int y = p.y + 10;
|
||||
|
||||
Color c = new Color(bi.getRGB(x - sum.x, y - sum.y));
|
||||
if (b.isDefaultButton()) {
|
||||
if (defaultColor == null) {
|
||||
defaultColor = c;
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"there should only be at most 1 " +
|
||||
"default button");
|
||||
}
|
||||
} else {
|
||||
if (nonDefaultColor == null) {
|
||||
nonDefaultColor = c;
|
||||
} else if (!isSimilar(nonDefaultColor, c)) {
|
||||
throw new IllegalStateException(
|
||||
"these two colors should match: " + c +
|
||||
", " + nonDefaultColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultColor != null && nonDefaultColor != null &&
|
||||
isSimilar(defaultColor, nonDefaultColor)) {
|
||||
throw new IllegalStateException(
|
||||
"The default button and non-default " +
|
||||
"buttons should look " +
|
||||
"different: " + defaultColor +
|
||||
" matches " + nonDefaultColor);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
System.err.println("a = " + a);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
System.out.println("defaultColor = " + defaultColor +
|
||||
" nonDefaultColor = " + nonDefaultColor);
|
||||
|
||||
window1.dispose();
|
||||
window2.dispose();
|
||||
}
|
||||
|
||||
System.out.println("Test passed successfully\n");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSimilar(Color c1, Color c2) {
|
||||
if (Math.abs(c1.getRed() - c2.getRed()) > 15) {
|
||||
return false;
|
||||
}
|
||||
if (Math.abs(c1.getGreen() - c2.getGreen()) > 15) {
|
||||
return false;
|
||||
}
|
||||
if (Math.abs(c1.getBlue() - c2.getBlue()) > 15) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (!System.getProperty("os.name").contains("OS X")) {
|
||||
System.out.println("This test is for MacOS only.");
|
||||
return;
|
||||
}
|
||||
|
||||
new TestScene(true, false).run();
|
||||
new TestScene(false, true).run();
|
||||
new TestScene(false, false).run();
|
||||
}
|
||||
}
|
||||
108
test/jdk/com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java
Normal file
108
test/jdk/com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2018, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8158325 8180821 8202878
|
||||
* @summary Memory leak in com.apple.laf.ScreenMenu: removed JMenuItems are still referenced
|
||||
* @requires (os.family == "mac")
|
||||
* @library /javax/swing/regtesthelpers
|
||||
* @build Util
|
||||
* @run main/timeout=300/othervm -Xmx16m ScreenMenuMemoryLeakTest
|
||||
*/
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
public class ScreenMenuMemoryLeakTest {
|
||||
|
||||
private static WeakReference<JMenuItem> sMenuItem;
|
||||
private static JFrame sFrame;
|
||||
private static JMenu sMenu;
|
||||
|
||||
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
|
||||
EventQueue.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
System.setProperty("apple.laf.useScreenMenuBar", "true");
|
||||
showUI();
|
||||
}
|
||||
});
|
||||
|
||||
EventQueue.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
removeMenuItemFromMenu();
|
||||
}
|
||||
});
|
||||
|
||||
Util.generateOOME();
|
||||
JMenuItem menuItem = sMenuItem.get();
|
||||
EventQueue.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
sFrame.dispose();
|
||||
}
|
||||
});
|
||||
if (menuItem != null) {
|
||||
throw new RuntimeException("The menu item should have been GC-ed");
|
||||
}
|
||||
}
|
||||
|
||||
private static void showUI() {
|
||||
sFrame = new JFrame();
|
||||
sFrame.add(new JLabel("Some dummy content"));
|
||||
|
||||
JMenuBar menuBar = new JMenuBar();
|
||||
|
||||
sMenu = new JMenu("Menu");
|
||||
JMenuItem item = new JMenuItem("Item");
|
||||
sMenu.add(item);
|
||||
|
||||
sMenuItem = new WeakReference<>(item);
|
||||
|
||||
menuBar.add(sMenu);
|
||||
|
||||
sFrame.setJMenuBar(menuBar);
|
||||
|
||||
sFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
sFrame.pack();
|
||||
sFrame.setVisible(true);
|
||||
}
|
||||
|
||||
private static void removeMenuItemFromMenu() {
|
||||
JMenuItem menuItem = sMenuItem.get();
|
||||
Objects.requireNonNull(menuItem, "The menu item should still be available at this point");
|
||||
sMenu.remove(menuItem);
|
||||
}
|
||||
}
|
||||
2
test/jdk/com/apple/laf/TEST.properties
Normal file
2
test/jdk/com/apple/laf/TEST.properties
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
modules=java.desktop
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8322133
|
||||
* @summary Make sure getParameterSpec returns std name for EC AlgorithmParameters
|
||||
* @modules java.base/sun.security.util
|
||||
*/
|
||||
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
|
||||
public class CurveGetParameterSpec {
|
||||
public static void main(String[] args) throws Exception {
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
|
||||
kpg.initialize(new ECGenParameterSpec("secp384r1"));
|
||||
var k = kpg.generateKeyPair().getPublic();
|
||||
var a = AlgorithmParameters.getInstance("EC");
|
||||
a.init(k.getParams());
|
||||
String name = a.getParameterSpec(ECGenParameterSpec.class).getName();
|
||||
if (!name.equals("secp384r1")) {
|
||||
throw new Exception("EC getParameterSpec does not return std name secp384r1. Instead returns: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 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.spec.OAEPParameterSpec;
|
||||
import javax.crypto.spec.PSource;
|
||||
import java.io.IOException;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.spec.MGF1ParameterSpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8246797
|
||||
* @summary Ensures OAEPParameters read correct encoding and
|
||||
* reject encoding with invalid ordering
|
||||
*/
|
||||
|
||||
public class OAEPOrder {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Do not use default fields
|
||||
OAEPParameterSpec spec = new OAEPParameterSpec(
|
||||
"SHA-384", "MGF1", MGF1ParameterSpec.SHA384,
|
||||
new PSource.PSpecified(new byte[10]));
|
||||
AlgorithmParameters alg = AlgorithmParameters.getInstance("OAEP");
|
||||
alg.init(spec);
|
||||
byte[] encoded = alg.getEncoded();
|
||||
|
||||
// Extract the fields inside encoding
|
||||
// [0] HashAlgorithm
|
||||
byte[] a0 = Arrays.copyOfRange(encoded, 2, encoded[3] + 4);
|
||||
// [1] MaskGenAlgorithm + [2] PSourceAlgorithm
|
||||
byte[] a12 = Arrays.copyOfRange(encoded, 2 + a0.length, encoded.length);
|
||||
|
||||
// and rearrange [1] and [2] before [0]
|
||||
System.arraycopy(a12, 0, encoded, 2, a12.length);
|
||||
System.arraycopy(a0, 0, encoded, 2 + a12.length, a0.length);
|
||||
|
||||
AlgorithmParameters alg2 = AlgorithmParameters.getInstance("OAEP");
|
||||
try {
|
||||
alg2.init(encoded);
|
||||
throw new RuntimeException("Should fail");
|
||||
} catch (IOException ioe) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
}
|
||||
116
test/jdk/com/sun/crypto/provider/CICO/CICOChainingTest.java
Normal file
116
test/jdk/com/sun/crypto/provider/CICO/CICOChainingTest.java
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2015, 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 java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @summary This test verifies the assertion "The chaining feature of
|
||||
* Filter streams should be supported." for feature "CipherInputStream &
|
||||
* CipherOutputStream"
|
||||
* @run main CICOChainingTest
|
||||
*/
|
||||
public class CICOChainingTest {
|
||||
/**
|
||||
* Plain text length.
|
||||
*/
|
||||
private static final int PLAIN_TEXT_LENGTH = 200;
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
CICOChainingTest test = new CICOChainingTest();
|
||||
test.chainTest(true);
|
||||
test.chainTest(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chain CipherInputStream/CipherOutputStream with other stream, encrypt
|
||||
* the text and decrypt it, recovered text is supposed to be same as
|
||||
* original text.
|
||||
* @param useInt true if read byte by byte false if read with buffer.
|
||||
* @throws IOException any I/O operation failed.
|
||||
*/
|
||||
public void chainTest(boolean useInt) throws IOException {
|
||||
byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH);
|
||||
byte[] recoveredText = new byte[plainText.length];
|
||||
// Do initialization
|
||||
try (MyNullCipherInputStream ciInput1 = new MyNullCipherInputStream(
|
||||
new ByteArrayInputStream(plainText));
|
||||
PipedOutputStream piOut = new PipedOutputStream();
|
||||
MyNullCipherInputStream ciInput2 = new MyNullCipherInputStream(
|
||||
new PipedInputStream(piOut));
|
||||
MyNullCipherOutputStream ciOut = new MyNullCipherOutputStream(
|
||||
piOut);) {
|
||||
if (useInt) {
|
||||
int buffer = ciInput1.read();
|
||||
while (buffer != -1) {
|
||||
piOut.write(buffer);
|
||||
buffer = ciInput1.read();
|
||||
}
|
||||
} else {
|
||||
byte[] buffer = new byte[20];
|
||||
int len = ciInput1.read(buffer);
|
||||
while (len != -1) {
|
||||
ciOut.write(buffer, 0, len);
|
||||
len = ciInput1.read(buffer);
|
||||
}
|
||||
}
|
||||
ciOut.flush();
|
||||
piOut.flush();
|
||||
// Get the output
|
||||
ciInput2.read(recoveredText);
|
||||
if (ciInput2.available() > 0) {
|
||||
throw new RuntimeException("Expected no data from ciInput2, but"
|
||||
+ " ciInput2.available() = " + ciInput2.available());
|
||||
}
|
||||
}
|
||||
// Verify output is same to input.
|
||||
if (!Arrays.equals(plainText, recoveredText)) {
|
||||
throw new RuntimeException("plainText:" + new String(plainText)
|
||||
+ " recoveredText:" + new String(recoveredText)
|
||||
+ " Test failed due to result compare fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MyNullCipherInputStream extends CipherInputStream {
|
||||
|
||||
public MyNullCipherInputStream(InputStream is) {
|
||||
super(is);
|
||||
}
|
||||
}
|
||||
|
||||
class MyNullCipherOutputStream extends CipherOutputStream {
|
||||
|
||||
public MyNullCipherOutputStream(OutputStream os) {
|
||||
super(os);
|
||||
}
|
||||
}
|
||||
143
test/jdk/com/sun/crypto/provider/CICO/CICODESFuncTest.java
Normal file
143
test/jdk/com/sun/crypto/provider/CICO/CICODESFuncTest.java
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 static java.lang.System.out;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @summary to verify cipherInputStream and cipherInputStream cipher function
|
||||
* @run main CICODESFuncTest
|
||||
*/
|
||||
public class CICODESFuncTest {
|
||||
/**
|
||||
* Algorithms name.
|
||||
*/
|
||||
private static final String[] ALGORITHMS = { "DES", "DESede", "Blowfish" };
|
||||
private static final String[] MODES = { "ECB", "CBC", "CFB", "CFB24",
|
||||
"CFB32", "CFB40", "CFB72", "OFB", "OFB20", "OFB48", "OFB56",
|
||||
"OFB64", "PCBC" };
|
||||
/**
|
||||
* Padding mode.
|
||||
*/
|
||||
private static final String[] PADDINGS = { "noPadding", "pkcs5padding" };
|
||||
/**
|
||||
* Plain text length.
|
||||
*/
|
||||
private static final int TEXT_LENGTH = 80;
|
||||
/**
|
||||
* Initialization vector length.
|
||||
*/
|
||||
private static final int IV_LENGTH = 8;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Provider provider = Security.getProvider(
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
if (provider == null) {
|
||||
throw new RuntimeException("SunJCE provider does not exist.");
|
||||
}
|
||||
for (String algorithm : ALGORITHMS) {
|
||||
for (String mode : MODES) {
|
||||
// We only test noPadding and pkcs5padding for CFB72, OFB20, ECB
|
||||
// PCBC and CBC. Otherwise test noPadding only.
|
||||
int padKinds = 1;
|
||||
if (mode.equalsIgnoreCase("CFB72")
|
||||
|| mode.equalsIgnoreCase("OFB20")
|
||||
|| mode.equalsIgnoreCase("ECB")
|
||||
|| mode.equalsIgnoreCase("PCBC")
|
||||
|| mode.equalsIgnoreCase("CBC")) {
|
||||
padKinds = PADDINGS.length;
|
||||
}
|
||||
// PKCS5padding is meaningful only for ECB, CBC, PCBC
|
||||
for (int k = 0; k < padKinds; k++) {
|
||||
for (ReadModel readMode : ReadModel.values()) {
|
||||
runTest(provider, algorithm, mode, PADDINGS[k], readMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runTest(Provider p, String algo, String mo, String pad,
|
||||
ReadModel whichRead) throws GeneralSecurityException, IOException {
|
||||
// Do initialization
|
||||
byte[] plainText = TestUtilities.generateBytes(TEXT_LENGTH);
|
||||
byte[] iv = TestUtilities.generateBytes(IV_LENGTH);
|
||||
AlgorithmParameterSpec aps = new IvParameterSpec(iv);
|
||||
try {
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algo, p);
|
||||
out.println(algo + "/" + mo + "/" + pad + "/" + whichRead);
|
||||
SecretKey key = kg.generateKey();
|
||||
Cipher ci1 = Cipher.getInstance(algo + "/" + mo + "/" + pad, p);
|
||||
if ("CFB72".equalsIgnoreCase(mo) || "OFB20".equalsIgnoreCase(mo)) {
|
||||
throw new RuntimeException(
|
||||
"NoSuchAlgorithmException not throw when mode"
|
||||
+ " is CFB72 or OFB20");
|
||||
}
|
||||
Cipher ci2 = Cipher.getInstance(algo + "/" + mo + "/" + pad, p);
|
||||
if ("ECB".equalsIgnoreCase(mo)) {
|
||||
ci1.init(Cipher.ENCRYPT_MODE, key);
|
||||
ci2.init(Cipher.DECRYPT_MODE, key);
|
||||
} else {
|
||||
ci1.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
ci2.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
}
|
||||
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
|
||||
try (CipherInputStream cInput
|
||||
= new CipherInputStream(
|
||||
new ByteArrayInputStream(plainText), ci1);
|
||||
CipherOutputStream ciOutput
|
||||
= new CipherOutputStream(baOutput, ci2);) {
|
||||
// Read from the input and write to the output using 2 types
|
||||
// of buffering : byte[] and int
|
||||
whichRead.read(cInput, ciOutput, ci1, plainText.length);
|
||||
}
|
||||
// Verify input and output are same.
|
||||
if (!Arrays.equals(plainText, baOutput.toByteArray())) {
|
||||
throw new RuntimeException("Test failed due to compare fail ");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException nsaEx) {
|
||||
if ("CFB72".equalsIgnoreCase(mo) || "OFB20".equalsIgnoreCase(mo)) {
|
||||
out.println("NoSuchAlgorithmException is expected for CFB72 and OFB20");
|
||||
} else {
|
||||
throw new RuntimeException("Unexpected exception testing: "
|
||||
+ algo + "/" + mo + "/" + pad + "/" + whichRead, nsaEx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
271
test/jdk/com/sun/crypto/provider/CICO/CICOSkipTest.java
Normal file
271
test/jdk/com/sun/crypto/provider/CICO/CICOSkipTest.java
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 static java.lang.System.out;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.PBEParameterSpec;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @summary This test verifies the assertion "The skip feature of Filter
|
||||
* streams should be supported." for feature
|
||||
* CipherInputStream and CipherOutputStream
|
||||
*/
|
||||
public class CICOSkipTest {
|
||||
/**
|
||||
* Block length.
|
||||
*/
|
||||
private static final int BLOCK = 50;
|
||||
|
||||
/**
|
||||
* Saving bytes length.
|
||||
*/
|
||||
private static final int SAVE = 45;
|
||||
|
||||
/**
|
||||
* Plain text length.
|
||||
*/
|
||||
private static final int PLAIN_TEXT_LENGTH = 800;
|
||||
|
||||
/**
|
||||
* Skip reading byte size. This should be same to BLOCK - SAVE
|
||||
*/
|
||||
private static final int DISCARD = BLOCK - SAVE;
|
||||
|
||||
private static final String[] ALGOS = {"DES", "DESede", "Blowfish"};
|
||||
private static final String[] MODES = {"ECB", "CBC", "CFB", "CFB32",
|
||||
"OFB", "OFB64", "PCBC"};
|
||||
private static final String[] PADDINGS = {"NoPadding", "Pkcs5Padding"};
|
||||
private static final String[] PBE_ALGOS = {"PBEWithMD5AndDES",
|
||||
"PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithSHA1AndDESede"};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// how many kinds of padding mode such as PKCS5padding and NoPadding
|
||||
for (String algo : ALGOS) {
|
||||
for (String mode : MODES) {
|
||||
int padKinds = 1;
|
||||
if (mode.equalsIgnoreCase("ECB")
|
||||
|| mode.equalsIgnoreCase("PCBC")
|
||||
|| mode.equalsIgnoreCase("CBC")) {
|
||||
padKinds = PADDINGS.length;
|
||||
}
|
||||
// PKCS5padding is meaningful only for ECB, CBC, PCBC
|
||||
for (int k = 0; k < padKinds; k++) {
|
||||
String info = algo + "/" + mode + "/" + PADDINGS[k];
|
||||
try {
|
||||
CipherGenerator cg = new CipherGenerator(algo, mode,
|
||||
PADDINGS[k]);
|
||||
for (ReadMethod model : ReadMethod.values()) {
|
||||
runTest(cg.getPair(), info, model);
|
||||
}
|
||||
} catch (LengthLimitException exp) {
|
||||
// skip this if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
out.println(exp.getMessage() + " is expected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String pbeAlgo : PBE_ALGOS) {
|
||||
for (ReadMethod model : ReadMethod.values()) {
|
||||
System.out.println("Testing Algorithm : " + pbeAlgo
|
||||
+ " ReadMethod : " + model);
|
||||
runTest(new CipherGenerator(pbeAlgo).getPair(), pbeAlgo, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runTest(Cipher[] pair, String info, ReadMethod whichRead)
|
||||
throws IOException {
|
||||
byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH);
|
||||
out.println("Testing: " + info + "/" + whichRead);
|
||||
try (ByteArrayInputStream baInput = new ByteArrayInputStream(plainText);
|
||||
CipherInputStream ciInput1 = new CipherInputStream(baInput,
|
||||
pair[0]);
|
||||
CipherInputStream ciInput2 = new CipherInputStream(ciInput1,
|
||||
pair[1]);) {
|
||||
// Skip 5 bytes after read 45 bytes and repeat until finish
|
||||
// (Read from the input and write to the output using 2 types
|
||||
// of buffering : byte[] and int)
|
||||
// So output has size:
|
||||
// (OVERALL/BLOCK)* SAVE = (800 / 50) * 45 = 720 bytes
|
||||
int numOfBlocks = plainText.length / BLOCK;
|
||||
|
||||
// Output buffer.
|
||||
byte[] outputText = new byte[numOfBlocks * SAVE];
|
||||
int index = 0;
|
||||
for (int i = 0; i < numOfBlocks; i++) {
|
||||
index = whichRead.readByte(ciInput2, outputText, SAVE, index);
|
||||
// If available is more than expected discard byte size. Skip
|
||||
// discard bytes, otherwise try to read discard bytes by read.
|
||||
if (ciInput2.available() >= DISCARD) {
|
||||
ciInput2.skip(DISCARD);
|
||||
} else {
|
||||
for (int k = 0; k < DISCARD; k++) {
|
||||
ciInput2.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Verify output is same as input
|
||||
if (!TestUtilities
|
||||
.equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) {
|
||||
throw new RuntimeException("Test failed with compare fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CipherGenerator {
|
||||
/**
|
||||
* Initialization vector length.
|
||||
*/
|
||||
private static final int IV_LENGTH = 8;
|
||||
|
||||
private static final String PASSWD = "Sesame!(@#$%^&*)";
|
||||
|
||||
private final Cipher[] pair = new Cipher[2];
|
||||
|
||||
// For DES/DESede ciphers
|
||||
CipherGenerator(String algo, String mo, String pad)
|
||||
throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException, InvalidKeyException,
|
||||
NoSuchPaddingException, SecurityException, LengthLimitException {
|
||||
// Do initialization
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algo);
|
||||
SecretKey key = kg.generateKey();
|
||||
if (key.getEncoded().length * 8 > Cipher.getMaxAllowedKeyLength(algo)) {
|
||||
// skip this if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
throw new LengthLimitException(
|
||||
"Skip this test if key length is larger than what's"
|
||||
+ "configured in the jce jurisdiction policy files");
|
||||
}
|
||||
AlgorithmParameterSpec aps = null;
|
||||
if (!mo.equalsIgnoreCase("ECB")) {
|
||||
byte[] iv = TestUtilities.generateBytes(IV_LENGTH);
|
||||
aps = new IvParameterSpec(iv);
|
||||
}
|
||||
initCiphers(algo + "/" + mo + "/" + pad, key, aps);
|
||||
}
|
||||
|
||||
// For PBE ciphers
|
||||
CipherGenerator(String algo) throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException, InvalidKeyException,
|
||||
NoSuchPaddingException, InvalidKeySpecException {
|
||||
// Do initialization
|
||||
byte[] salt = TestUtilities.generateBytes(IV_LENGTH);
|
||||
int iterCnt = 6;
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.split("/")[0]);
|
||||
SecretKey key = skf
|
||||
.generateSecret(new PBEKeySpec(PASSWD.toCharArray()));
|
||||
AlgorithmParameterSpec aps = new PBEParameterSpec(salt, iterCnt);
|
||||
initCiphers(algo, key, aps);
|
||||
}
|
||||
|
||||
private void initCiphers(String algo, SecretKey key,
|
||||
AlgorithmParameterSpec aps) throws NoSuchAlgorithmException,
|
||||
NoSuchPaddingException, InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
String providerName = System.getProperty("test.provider.name", "SunJCE");
|
||||
Provider provider = Security.getProvider(providerName);
|
||||
if (provider == null) {
|
||||
throw new RuntimeException(providerName + " provider does not exist.");
|
||||
}
|
||||
Cipher ci1 = Cipher.getInstance(algo, provider);
|
||||
ci1.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
pair[0] = ci1;
|
||||
Cipher ci2 = Cipher.getInstance(algo, provider);
|
||||
ci2.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
pair[1] = ci2;
|
||||
}
|
||||
|
||||
Cipher[] getPair() {
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
|
||||
enum ReadMethod {
|
||||
// read one byte at a time for save times
|
||||
READ_ONE_BYTE {
|
||||
@Override
|
||||
int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
|
||||
int index) throws IOException {
|
||||
for (int j = 0; j < save; j++, index++) {
|
||||
int buffer0 = ciIn2.read();
|
||||
if (buffer0 != -1) {
|
||||
outputText[index] = (byte) buffer0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
},
|
||||
// read a chunk of save bytes if possible
|
||||
READ_BLOCK {
|
||||
@Override
|
||||
int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
|
||||
int index) throws IOException {
|
||||
int len1 = ciIn2.read(outputText, index, save);
|
||||
out.println("Init: index=" + index + ",len=" + len1);
|
||||
// read more until save bytes
|
||||
index += len1;
|
||||
int len2 = 0;
|
||||
while (len1 != save && len2 != -1) {
|
||||
len2 = ciIn2.read(outputText, index, save - len1);
|
||||
out.println("Cont: index=" + index + ",len=" + len2);
|
||||
len1 += len2;
|
||||
index += len2;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
};
|
||||
|
||||
abstract int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
|
||||
int index) throws IOException;
|
||||
};
|
||||
|
||||
class LengthLimitException extends Exception {
|
||||
|
||||
public LengthLimitException(String string) {
|
||||
super(string);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 java.security.AlgorithmParameters;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
|
||||
/**
|
||||
* Wrapper class to test a given AES-based PBE algorithm.
|
||||
*/
|
||||
public class AESPBEWrapper extends AbstractPBEWrapper {
|
||||
/**
|
||||
* the algorithm parameters.
|
||||
*/
|
||||
private AlgorithmParameters pbeParams;
|
||||
|
||||
/**
|
||||
* the encryption key.
|
||||
*/
|
||||
private final SecretKey key;
|
||||
|
||||
/**
|
||||
* The Wrapper constructor. Instantiate Cipher using the given AES-based PBE
|
||||
* algorithm.
|
||||
*
|
||||
* @param algo AES-based PBE algorithm.
|
||||
* @param passwd password phrase.
|
||||
* @throws GeneralSecurityException all security exceptions are thrown.
|
||||
*/
|
||||
public AESPBEWrapper(PBEAlgorithm algo, String passwd)
|
||||
throws GeneralSecurityException {
|
||||
// salt and iteration count will be generated during encryption
|
||||
super(algo, passwd, 0);
|
||||
|
||||
// Generate secret key. We expect no mode and padding specified.
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.baseAlgo);
|
||||
key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the Cipher object using given "mode".
|
||||
* @return a cipher object.
|
||||
* @throws GeneralSecurityException all security exceptions are thrown.
|
||||
*/
|
||||
@Override
|
||||
protected Cipher initCipher(int mode) throws GeneralSecurityException {
|
||||
String providerName = System.getProperty("test.provider.name", "SunJCE");
|
||||
Provider provider = Security.getProvider(providerName);
|
||||
if (provider == null) {
|
||||
throw new RuntimeException(providerName + ": provider does not exist.");
|
||||
}
|
||||
// get Cipher instance
|
||||
Cipher ci = Cipher.getInstance(transformation, provider);
|
||||
if (Cipher.ENCRYPT_MODE == mode) {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
pbeParams = ci.getParameters();
|
||||
} else {
|
||||
ci.init(Cipher.DECRYPT_MODE, key, pbeParams);
|
||||
}
|
||||
return ci;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2025, 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 java.security.GeneralSecurityException;
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
/**
|
||||
* PBEWrapper is an abstract class for all concrete PBE Cipher wrappers.
|
||||
*/
|
||||
public abstract class AbstractPBEWrapper {
|
||||
/**
|
||||
* Iteration count.
|
||||
*/
|
||||
public static final int DEFAULT_ITERATION = 1000;
|
||||
|
||||
public static final String PBKDF2 = "PBKDF2";
|
||||
public static final String AES = "AES";
|
||||
public static final String DEFAULT = "default";
|
||||
|
||||
/**
|
||||
* transformation the name of the transformation, e.g.,
|
||||
* DES/CBC/PKCS5Padding
|
||||
*/
|
||||
protected final String transformation;
|
||||
|
||||
/**
|
||||
* the standard name of the requested secret key algorithm.
|
||||
*/
|
||||
protected final String baseAlgo;
|
||||
|
||||
/**
|
||||
* The contents of salt are copied to protect against subsequent
|
||||
* modification.
|
||||
*/
|
||||
protected final byte[] salt;
|
||||
|
||||
/**
|
||||
* Password.
|
||||
*/
|
||||
protected final String password;
|
||||
|
||||
/**
|
||||
* PBEWrapper creator.
|
||||
*
|
||||
* @param algo PBE algorithm to test
|
||||
* @param passwd a password phrase
|
||||
* @return PBEWrapper in accordance to requested algo.
|
||||
* @throws GeneralSecurityException all exceptions are thrown.
|
||||
*/
|
||||
public static AbstractPBEWrapper createWrapper(PBEAlgorithm algo, String passwd)
|
||||
throws GeneralSecurityException {
|
||||
switch (algo.type) {
|
||||
case PBKDF2:
|
||||
return new PBKDF2Wrapper(algo, passwd);
|
||||
case AES:
|
||||
return new AESPBEWrapper(algo, passwd);
|
||||
default:
|
||||
return new DefaultPBEWrapper(algo, passwd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PBEWrapper constructor.
|
||||
*
|
||||
* @param algo algorithm to wrap
|
||||
* @param password password phrase
|
||||
* @param saltSize salt size (defined in subclasses)
|
||||
*/
|
||||
protected AbstractPBEWrapper(PBEAlgorithm algo, String password, int saltSize) {
|
||||
this.transformation = algo.getTransformation();
|
||||
this.baseAlgo = algo.baseAlgo;
|
||||
this.salt = TestUtilities.generateBytes(saltSize);
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Cipher object for the operation requested in the mode parameter.
|
||||
*
|
||||
* @param mode encryption or decryption
|
||||
* @return a cipher initialize by mode.
|
||||
* @throws GeneralSecurityException all security exceptions are thrown.
|
||||
*/
|
||||
protected abstract Cipher initCipher(int mode) throws GeneralSecurityException;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2015, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @summary This test verifies the assertion "The encrypt/decrypt
|
||||
* mechanism of cipher should perform correctly." for feature
|
||||
* "CipherInputStream & CipherOutputStream".
|
||||
* @library ../
|
||||
* @run main CICOPBEFuncTest
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
public class CICOPBEFuncTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (PBEAlgorithm algorithm : PBEAlgorithm.values()) {
|
||||
// int buffertin test
|
||||
String algo = algorithm.baseAlgo.toUpperCase();
|
||||
if (!algo.contains("TRIPLEDES") && !algo.contains("AES_256")
|
||||
|| Cipher.getMaxAllowedKeyLength(algo) > 128) {
|
||||
// skip this if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
System.out.println("Testing " + algorithm.getTransformation());
|
||||
for (String type : Arrays.asList(CICO_PBE_Test.INT_BYTE_BUFFER,
|
||||
CICO_PBE_Test.BYTE_ARR_BUFFER)) {
|
||||
new CICO_PBE_RW_Test(algorithm)
|
||||
.proceedTest(type);
|
||||
new CICO_PBE_SKIP_Test(algorithm)
|
||||
.proceedTest(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2015, 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 java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import javax.crypto.CipherOutputStream;
|
||||
|
||||
/**
|
||||
* CICO PBE Read/Write functional test.
|
||||
*
|
||||
* Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is
|
||||
* performed correctly for CipherInputStream and CipherOutputStream.
|
||||
*
|
||||
* Test scenario:
|
||||
* 1. initializes plain text with random generated data.
|
||||
* 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers.
|
||||
* 3. instantiates CipherInputStream with the encrypt Cipher.
|
||||
* 4. instantiates CipherOutputStream with the decrypt Cipher.
|
||||
* 5. performs reading from the CipherInputStream (encryption data) and writing
|
||||
* to the CipherOutputStream (decryption). As a result the output of the
|
||||
* CipherOutputStream should be the same as an original plain text.
|
||||
* 6. compares if the original plain text is the same as the output of the
|
||||
* CipherOutputStream.
|
||||
*
|
||||
* The test implements 2 test cases in accordance with buffering type:
|
||||
* 1. byte array buffering
|
||||
* 2. int buffering
|
||||
*/
|
||||
public class CICO_PBE_RW_Test extends CICO_PBE_Test {
|
||||
|
||||
public CICO_PBE_RW_Test(PBEAlgorithm pbeAlgo)
|
||||
throws GeneralSecurityException {
|
||||
super(pbeAlgo);
|
||||
}
|
||||
|
||||
/**
|
||||
* The CICO PBE RW test specific part of the super.doTest(). Implements the
|
||||
* scenario in accordance to the class description.
|
||||
* @param type byteArrayBuffering or intByteBuffering
|
||||
* @throws IOException any I/O operation failed.
|
||||
* @throws GeneralSecurityException any security error.
|
||||
*/
|
||||
@Override
|
||||
public void proceedTest(String type) throws IOException,
|
||||
GeneralSecurityException {
|
||||
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
|
||||
try (CipherOutputStream ciOutput = new CipherOutputStream(baOutput,
|
||||
getDecryptCipher())) {
|
||||
if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) {
|
||||
proceedTestUsingByteArrayBuffer(ciOutput);
|
||||
} else {
|
||||
proceedTestUsingIntBuffer(ciOutput);
|
||||
}
|
||||
ciOutput.flush();
|
||||
}
|
||||
// Compare input and output
|
||||
if (!TestUtilities.equalsBlock(plainText, baOutput.toByteArray(), TEXT_SIZE)) {
|
||||
throw new RuntimeException("outputText not same with expectedText"
|
||||
+ " when test " + type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements byte array buffering type test case of the CICO PBE RW test.
|
||||
* @param ciOutput output stream for data written.
|
||||
* @throws java.io.IOException any I/O operation failed.
|
||||
*/
|
||||
public void proceedTestUsingByteArrayBuffer(
|
||||
CipherOutputStream ciOutput) throws IOException {
|
||||
byte[] buffer = new byte[TEXT_SIZE];
|
||||
int len = getCiInput().read(buffer);
|
||||
while (len != -1) {
|
||||
ciOutput.write(buffer, 0, len);
|
||||
len = getCiInput().read(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements int buffering type test case.
|
||||
* @param ciOutput output stream for data written.
|
||||
* @throws java.io.IOException any I/O operation failed.
|
||||
*/
|
||||
public void proceedTestUsingIntBuffer(CipherOutputStream ciOutput)
|
||||
throws IOException {
|
||||
int buffer = getCiInput().read();
|
||||
while (buffer != -1) {
|
||||
ciOutput.write(buffer);
|
||||
buffer = getCiInput().read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2015, 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 java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.CipherInputStream;
|
||||
|
||||
/**
|
||||
* CICO PBE SKIP functional test.
|
||||
*
|
||||
* Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is
|
||||
* performed correctly for CipherInputStream when skip() method is used.
|
||||
*
|
||||
* Test scenario:
|
||||
* 1. initializes plain text with random generated data with length TEXT_SIZE.
|
||||
* 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers.
|
||||
* 3. instantiates CipherInputStream 1 with the encrypt Cipher.
|
||||
* 4. instantiates CipherInputStream 2 with the CipherInputStream 1 and decrypt
|
||||
* Cipher.
|
||||
* 5. the plain text is divided on TEXT_SIZE/BLOCK blocks. Reading from
|
||||
* CipherInputStream 2 one block at time. The last BLOCK - SAVE bytes are
|
||||
* skipping for each block. Therefor the plain text data go through
|
||||
* CipherInputStream 1 (encrypting) and CipherInputStream 2 (decrypting).
|
||||
* As a result the output should equal to the original text except DISCARD
|
||||
* byte for each block are skipped.
|
||||
* 6. get the standard output.
|
||||
* 7. compares the expected standard output with the output of the
|
||||
* CipherInputStream 2. If it is the same the test passed. Otherwise it
|
||||
* failed. Any uncaught exceptions should be considered as an error.
|
||||
* The test implements 2 test cases in accordance with a buffering type:
|
||||
* 1. byte array buffering
|
||||
* 2. int buffering
|
||||
*/
|
||||
public class CICO_PBE_SKIP_Test extends CICO_PBE_Test {
|
||||
/**
|
||||
* Block size.
|
||||
*/
|
||||
private static final int BLOCK = 50;
|
||||
|
||||
/**
|
||||
* Valid reading byte size.
|
||||
*/
|
||||
private static final int SAVE = 45;
|
||||
|
||||
/**
|
||||
* Skip reading byte size. This should be same to BLOCK - SAVE
|
||||
*/
|
||||
private static final int DISCARD = BLOCK - SAVE;
|
||||
|
||||
/**
|
||||
* Number of blocks.
|
||||
*/
|
||||
private static final int NUMBER_OF_BLOCKS = TEXT_SIZE / BLOCK;
|
||||
|
||||
private final byte[] outputText;
|
||||
/**
|
||||
* CICO PBE Skip test constructor
|
||||
*
|
||||
* @param pbeAlgo the PBE algorithm to test.
|
||||
* @throws java.security.GeneralSecurityException
|
||||
*/
|
||||
public CICO_PBE_SKIP_Test(PBEAlgorithm pbeAlgo)
|
||||
throws GeneralSecurityException {
|
||||
super(pbeAlgo);
|
||||
outputText = new byte[NUMBER_OF_BLOCKS * SAVE];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements byte array buffering type test case of the CICO SKIP test.
|
||||
*
|
||||
* @param blockNum block number to read.
|
||||
*/
|
||||
private void proceedSkipTestUsingByteArrayBufferingType(
|
||||
CipherInputStream ciIn2, int blockNum) throws IOException {
|
||||
int index = blockNum * SAVE;
|
||||
int len1 = ciIn2.read(outputText, index, SAVE);
|
||||
// read more until SAVE bytes
|
||||
index += len1;
|
||||
int len2 = 0;
|
||||
int totalRead = len1;
|
||||
while (len1 != SAVE && len2 != -1) {
|
||||
len2 = ciIn2.read(outputText, index, SAVE - len1);
|
||||
len1 += len2;
|
||||
index += len2;
|
||||
totalRead += len2;
|
||||
}
|
||||
if (totalRead != SAVE) {
|
||||
throw new RuntimeException("Read bytes number " + totalRead
|
||||
+ " does not equal to given number " + SAVE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements int buffering type test case of the CICO SKIP test.
|
||||
*
|
||||
* @param blockNum block number to read.
|
||||
*/
|
||||
private void proceedSkipTestUsingIntBufferingType(CipherInputStream ciIn2,
|
||||
int blockNum) throws IOException {
|
||||
int index = blockNum * SAVE;
|
||||
int totalRead = 0;
|
||||
for (int j = 0; j < SAVE; j++, index++) {
|
||||
int buffer0 = ciIn2.read();
|
||||
if (buffer0 != -1) {
|
||||
outputText[index] = (byte) buffer0;
|
||||
totalRead++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (totalRead != SAVE) {
|
||||
throw new RuntimeException("Read bytes number " + totalRead
|
||||
+ " does not equal to given number " + SAVE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The CICO PBE SKIP test specific part of the super.doTest(). Implements
|
||||
* the scenario in accordance to the class description.
|
||||
* @throws java.io.IOException any I/O failed.
|
||||
*/
|
||||
@Override
|
||||
public void proceedTest(String type) throws IOException {
|
||||
System.out.println("Test type: " + type);
|
||||
// init second input stream with decrypt Cipher
|
||||
try (CipherInputStream ciIn2 = new CipherInputStream(getCiInput(),
|
||||
getDecryptCipher())) {
|
||||
for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
|
||||
if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) {
|
||||
proceedSkipTestUsingByteArrayBufferingType(ciIn2, i);
|
||||
} else {
|
||||
proceedSkipTestUsingIntBufferingType(ciIn2, i);
|
||||
}
|
||||
if (ciIn2.available() >= DISCARD) {
|
||||
ciIn2.skip(DISCARD);
|
||||
} else {
|
||||
for (int k = 0; k < DISCARD; k++) {
|
||||
ciIn2.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!TestUtilities.equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) {
|
||||
throw new RuntimeException("outputText not same with expectedText"
|
||||
+ " when test " + type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2015, 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 java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
|
||||
/**
|
||||
* This is an abstract class for CipherInputStream/CipherOutputStream PBE
|
||||
* functional tests.
|
||||
*/
|
||||
public abstract class CICO_PBE_Test {
|
||||
/**
|
||||
* Sample string for byte buffer.
|
||||
*/
|
||||
public static final String BYTE_ARR_BUFFER = "byteArrayBuffering";
|
||||
|
||||
/**
|
||||
* Sample string for int buffer.
|
||||
*/
|
||||
public static final String INT_BYTE_BUFFER = "intByteBuffering";
|
||||
public static final String PASS_PHRASE = "Some password phrase!";
|
||||
|
||||
/**
|
||||
* Text string size.
|
||||
*/
|
||||
public static final int TEXT_SIZE = 800;
|
||||
|
||||
protected final byte[] plainText;
|
||||
private final Cipher encryptCipher, decryptCipher;
|
||||
|
||||
/**
|
||||
* An CipherInputStream for reading cipher and plain text.
|
||||
*/
|
||||
private final CipherInputStream ciInput;
|
||||
|
||||
/**
|
||||
* Constructor by algorithm.
|
||||
* @param pbeAlgo PBE algorithm to test.
|
||||
* @throws GeneralSecurityException if any security error.
|
||||
*/
|
||||
public CICO_PBE_Test(PBEAlgorithm pbeAlgo) throws GeneralSecurityException {
|
||||
// Do initialization of the plainText
|
||||
plainText = TestUtilities.generateBytes(TEXT_SIZE);
|
||||
// Do initialization of the ciphers
|
||||
AbstractPBEWrapper pbeWrap = AbstractPBEWrapper.createWrapper(pbeAlgo, PASS_PHRASE);
|
||||
encryptCipher = pbeWrap.initCipher(Cipher.ENCRYPT_MODE);
|
||||
decryptCipher = pbeWrap.initCipher(Cipher.DECRYPT_MODE);
|
||||
// init cipher input stream
|
||||
ciInput = new CipherInputStream(new ByteArrayInputStream(plainText),
|
||||
encryptCipher);
|
||||
}
|
||||
|
||||
protected byte[] getPlainText() {
|
||||
return plainText;
|
||||
}
|
||||
|
||||
/**
|
||||
* The body of the test. Should be defined in subclasses.
|
||||
* @param type byteArrayBuffering or intByteBuffering
|
||||
* @throws IOException I/O operation failed.
|
||||
* @throws GeneralSecurityException all exceptions thrown.
|
||||
*/
|
||||
protected abstract void proceedTest(String type)
|
||||
throws IOException, GeneralSecurityException;
|
||||
|
||||
protected Cipher getEncryptCipher() {
|
||||
return encryptCipher;
|
||||
}
|
||||
|
||||
public CipherInputStream getCiInput() {
|
||||
return ciInput;
|
||||
}
|
||||
|
||||
public Cipher getDecryptCipher() {
|
||||
return decryptCipher;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2017, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @library ../ /test/lib
|
||||
* @build jdk.test.lib.RandomFactory
|
||||
* @run main CipherNCFuncTest
|
||||
* @summary This test verifies the assertion "There should be no transformation
|
||||
* on the plaintext/ciphertext in encryption/decryption mechanism" for
|
||||
* feature "NullCipher".
|
||||
*/
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NullCipher;
|
||||
import javax.crypto.ShortBufferException;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
|
||||
public class CipherNCFuncTest {
|
||||
public static void main(String[] args) throws ShortBufferException,
|
||||
IllegalBlockSizeException, BadPaddingException {
|
||||
byte[] plainText = new byte[801];
|
||||
// Initialization
|
||||
RandomFactory.getRandom().nextBytes(plainText);
|
||||
Cipher ci = new NullCipher();
|
||||
// Encryption
|
||||
byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = ci.update(plainText, 0, plainText.length, cipherText, 0);
|
||||
ci.doFinal(cipherText, offset);
|
||||
// Decryption
|
||||
byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
|
||||
int len = ci.doFinal(cipherText, 0, cipherText.length, recoveredText);
|
||||
// Comparison
|
||||
if (len != plainText.length ||
|
||||
!TestUtilities.equalsBlock(plainText, cipherText, len) ||
|
||||
!TestUtilities.equalsBlock(plainText, recoveredText, len)) {
|
||||
throw new RuntimeException(
|
||||
"Test failed because plainText not equal to cipherText and revoveredText");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 java.security.GeneralSecurityException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.PBEParameterSpec;
|
||||
|
||||
/**
|
||||
* Default wrapper for a password based encryption Cipher.
|
||||
*/
|
||||
|
||||
public class DefaultPBEWrapper extends AbstractPBEWrapper {
|
||||
/**
|
||||
* Define default SALT size as 8.
|
||||
*/
|
||||
private static final int PBE_SALT_SIZE = 8;
|
||||
|
||||
/**
|
||||
* Default PBE wrapper constructor.
|
||||
*
|
||||
* @param algo PGE algorithm to wrap.
|
||||
* @param passwd password phrase
|
||||
*/
|
||||
public DefaultPBEWrapper(PBEAlgorithm algo, String passwd) {
|
||||
super(algo, passwd, PBE_SALT_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate Cipher for the PBE algorithm.
|
||||
*
|
||||
* @param mode Cipher mode: encrypt or decrypt.
|
||||
* @return Cipher in accordance to the PBE algorithm
|
||||
* @throws java.security.GeneralSecurityException
|
||||
*/
|
||||
@Override
|
||||
protected Cipher initCipher(int mode) throws GeneralSecurityException {
|
||||
String providerName = System.getProperty("test.provider.name", "SunJCE");
|
||||
Provider provider = Security.getProvider(providerName);
|
||||
if (provider == null) {
|
||||
throw new RuntimeException(providerName + ": provider does not exist.");
|
||||
}
|
||||
SecretKey key = SecretKeyFactory.getInstance(baseAlgo)
|
||||
.generateSecret(new PBEKeySpec(password.toCharArray()));
|
||||
Cipher ci = Cipher.getInstance(transformation, provider);
|
||||
ci.init(mode, key, new PBEParameterSpec(salt, DEFAULT_ITERATION));
|
||||
return ci;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2022, 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 java.util.StringJoiner;
|
||||
|
||||
public enum PBEAlgorithm {
|
||||
MD5_DES("PBEWithMD5ANDdes", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
MD5_DES_CBC_PKCS5("PBEWithMD5AndDES", "CBC", "PKCS5Padding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
MD5_TRIPLEDES("PBEWithMD5ANDtripledes", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
MD5_TRIPLEDES_CBC_PKCS5("PBEWithMD5AndTRIPLEDES", "CBC", "PKCS5Padding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_DESEDE("PBEwithSHA1AndDESede", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_DESEDE_CBC_PKCS5("PBEwithSHA1AndDESede", "CBC", "PKCS5Padding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC2_40("PBEwithSHA1AndRC2_40", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC2_40_PKCS5("PBEwithSHA1Andrc2_40", "CBC", "PKCS5Padding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC2_128("PBEWithSHA1AndRC2_128", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC2_128_PKCS5("PBEWithSHA1andRC2_128", "CBC", "PKCS5Padding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC4_40("PBEWithSHA1AndRC4_40", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC4_40_ECB_NOPADDING("PBEWithsha1AndRC4_40", "ECB", "NoPadding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC4_128("PBEWithSHA1AndRC4_128", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC4_128_ECB_NOPADDING("pbeWithSHA1AndRC4_128", "ECB", "NoPadding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
HMAC_SHA1_AES_128("PBEWithHmacSHA1AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA224_AES_128("PBEWithHmacSHA224AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA256_AES_128("PBEWithHmacSHA256AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA384_AES_128("PBEWithHmacSHA384AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA512_AES_128("PBEWithHmacSHA512AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA512_224_AES_128("PBEWithHmacSHA512/224AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA512_256_AES_128("PBEWithHmacSHA512/256AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA1_AES_256("PBEWithHmacSHA1AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA224_AES_256("PBEWithHmacSHA224AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA256_AES_256("PBEWithHmacSHA256AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA384_AES_256("PBEWithHmacSHA384AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA512_AES_256("PBEWithHmacSHA512AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA512_224_AES_256("PBEWithHmacSHA512/224AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA512_256_AES_256("PBEWithHmacSHA512/256AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
PBKDF_HMAC_SHA1("PBKDF2WithHmacSHA1", "", "", AbstractPBEWrapper.PBKDF2),
|
||||
PBKDF_HMAC_SHA224("PBKDF2WithHmacSHA224", "", "", AbstractPBEWrapper.PBKDF2),
|
||||
PBKDF_HMAC_SHA256("PBKDF2WithHmacSHA256", "", "", AbstractPBEWrapper.PBKDF2),
|
||||
PBKDF_HMAC_SHA384("PBKDF2WithHmacSHA384", "", "", AbstractPBEWrapper.PBKDF2),
|
||||
PBKDF_HMAC_SHA512("PBKDF2WithHmacSHA512", "", "", AbstractPBEWrapper.PBKDF2),
|
||||
PBKDF_HMAC_SHA512_224("PBKDF2WithHmacSHA512/224", "", "", AbstractPBEWrapper.PBKDF2),
|
||||
PBKDF_HMAC_SHA512_256("PBKDF2WithHmacSHA512/256", "", "", AbstractPBEWrapper.PBKDF2);
|
||||
|
||||
final String baseAlgo;
|
||||
final String mode;
|
||||
final String padding;
|
||||
final String type;
|
||||
|
||||
PBEAlgorithm(String alg, String mode, String padding, String type) {
|
||||
this.baseAlgo = alg;
|
||||
this.mode = mode;
|
||||
this.padding = padding;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getTransformation() {
|
||||
StringJoiner sj = new StringJoiner("/");
|
||||
sj.add(baseAlgo);
|
||||
if (!mode.equals("")) {
|
||||
sj.add(this.mode);
|
||||
}
|
||||
if (!padding.equals("")) {
|
||||
sj.add(this.padding);
|
||||
}
|
||||
return sj.toString();
|
||||
}
|
||||
}
|
||||
110
test/jdk/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java
Normal file
110
test/jdk/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 java.security.GeneralSecurityException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* Wrapper class to test a given SecretKeyFactory.PBKDF2 algorithm.
|
||||
*/
|
||||
public class PBKDF2Wrapper extends AbstractPBEWrapper {
|
||||
/**
|
||||
* Default salt size.
|
||||
*/
|
||||
public static final int PBKDF2_SALT_SIZE = 64;
|
||||
|
||||
/**
|
||||
* Default key length.
|
||||
*/
|
||||
public static final int PKDF2_DEFAULT_KEY_LEN = 128;
|
||||
|
||||
/**
|
||||
* Default transformation.
|
||||
*/
|
||||
public static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";
|
||||
|
||||
/**
|
||||
* Algorithm name.
|
||||
*/
|
||||
public static final String KEY_ALGORITHM = "AES";
|
||||
|
||||
/**
|
||||
* Initialization vector length.
|
||||
*/
|
||||
private static final int IV_LENGTH = 16;
|
||||
|
||||
/**
|
||||
* The buffer with the IV.
|
||||
*/
|
||||
private final byte[] iv;
|
||||
|
||||
/**
|
||||
* PBKDF2Wrapper constructor. Instantiate Cipher using
|
||||
* "AES/CBC/PKCS5Padding" transformation. Generate a secret key using PKDF2
|
||||
* algorithms given in the "algo" parameter.
|
||||
*
|
||||
* @param algo AES-based PBE algorithm.
|
||||
* @param passwd password phrase.
|
||||
* @throws GeneralSecurityException all security exceptions are thrown.
|
||||
*/
|
||||
public PBKDF2Wrapper(PBEAlgorithm algo, String passwd)
|
||||
throws GeneralSecurityException {
|
||||
super(algo, passwd, PBKDF2_SALT_SIZE);
|
||||
iv = TestUtilities.generateBytes(IV_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the Cipher object for PBKDF2 algorithm using given "mode".
|
||||
*
|
||||
* @param mode Cipher mode: encrypt or decrypt
|
||||
* @return Cipher object for PBKDF2 algorithm
|
||||
* @throws GeneralSecurityException all security exceptions are thrown.
|
||||
*/
|
||||
@Override
|
||||
protected Cipher initCipher(int mode) throws GeneralSecurityException {
|
||||
String providerName = System.getProperty("test.provider.name", "SunJCE");
|
||||
Provider provider = Security.getProvider(providerName);
|
||||
if (provider == null) {
|
||||
throw new RuntimeException(providerName + ": provider does not exist.");
|
||||
}
|
||||
// Generate secret key
|
||||
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(),
|
||||
salt, DEFAULT_ITERATION, PKDF2_DEFAULT_KEY_LEN);
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(baseAlgo);
|
||||
SecretKey key = keyFactory.generateSecret(pbeKeySpec);
|
||||
|
||||
// get Cipher instance
|
||||
Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION, provider);
|
||||
cipher.init(mode,
|
||||
new SecretKeySpec(key.getEncoded(),KEY_ALGORITHM),
|
||||
new IvParameterSpec(iv));
|
||||
return cipher;
|
||||
}
|
||||
}
|
||||
77
test/jdk/com/sun/crypto/provider/CICO/ReadModel.java
Normal file
77
test/jdk/com/sun/crypto/provider/CICO/ReadModel.java
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2015, 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 java.io.IOException;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
|
||||
/**
|
||||
* ReadModel provides different way to test
|
||||
* CipherInputStream.read()/read(byte[])/read(byte[], int, int) and
|
||||
* CipherOutputStream.write(int)/write(byte[], int, int)/read(byte[]) API
|
||||
*/
|
||||
enum ReadModel {
|
||||
READ_BYTE {
|
||||
@Override
|
||||
public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
|
||||
Cipher ciIn, int inputLen) throws IOException {
|
||||
int buffer0 = cInput.read();
|
||||
while (buffer0 != -1) {
|
||||
ciOutput.write(buffer0);
|
||||
buffer0 = cInput.read();
|
||||
}
|
||||
}
|
||||
},
|
||||
READ_BUFFER {
|
||||
@Override
|
||||
public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
|
||||
Cipher ciIn, int inputLen) throws IOException {
|
||||
byte[] buffer1 = new byte[20];
|
||||
int len1;
|
||||
while ((len1 = cInput.read(buffer1)) != -1) {
|
||||
ciOutput.write(buffer1, 0, len1);
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
READ_BUFFER_OFFSET {
|
||||
@Override
|
||||
public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
|
||||
Cipher ciIn, int inputLen) throws IOException {
|
||||
byte[] buffer2 = new byte[ciIn.getOutputSize(inputLen)];
|
||||
int offset2 = 0;
|
||||
int len2 = 0;
|
||||
while (len2 != -1) {
|
||||
len2 = cInput.read(buffer2, offset2, buffer2.length - offset2);
|
||||
offset2 += len2;
|
||||
}
|
||||
ciOutput.write(buffer2);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
abstract public void read(CipherInputStream cInput,
|
||||
CipherOutputStream ciOutput, Cipher ciIn, int inputLen)
|
||||
throws IOException;
|
||||
}
|
||||
90
test/jdk/com/sun/crypto/provider/CICO/TestUtilities.java
Normal file
90
test/jdk/com/sun/crypto/provider/CICO/TestUtilities.java
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2015, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* utility class
|
||||
*/
|
||||
|
||||
public class TestUtilities {
|
||||
public static boolean equalsBlock(byte[] b1, byte[] b2, int len) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (b1[i] != b2[i]) {
|
||||
System.err.println("b1[" + i + "] : " + b1[i]
|
||||
+ " b2[" + i + "] : " + b2[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean equals(byte[] b1, byte[] b2) {
|
||||
if (b2.length != b1.length) {
|
||||
System.err.println("b1.length = " + b1.length
|
||||
+ " b2.length = " + b2.length );
|
||||
return false;
|
||||
}
|
||||
return equalsBlock(b1, b2, b1.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify b1's partial part is same as b2. compares b1 and b2 by chopping up
|
||||
* b1 into blocks of b1BKSize and b2 into blocks of b2BKSize, and then
|
||||
* compare the first b2BKSize bytes of each block, return true if they equal
|
||||
* , otherwise return false.
|
||||
* @param b1 byte array to be compared.
|
||||
* @param b2 saved byte array.
|
||||
* @param b1BKSize b1's block size.
|
||||
* @param b2BKSize b2's block size.
|
||||
* @return true is same. false otherwise.
|
||||
*/
|
||||
public static boolean equalsBlockPartial(byte[] b1, byte[] b2, int b1BKSize,
|
||||
int b2BKSize) {
|
||||
int numOfBlock = b1.length / b1BKSize;
|
||||
for (int b = 0; b < numOfBlock; b++) {
|
||||
for (int i = 0; i < b2BKSize; i++) {
|
||||
int j1 = b * b1BKSize + i;
|
||||
int j2 = b * b2BKSize + i;
|
||||
if (b1[j1] != b2[j2]) {
|
||||
System.err.println("Compare failed at b1[" + j1 + "]:" +
|
||||
b1[j1] + " b2[" + j2 + "]:" + b2[j2]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a byte block by given length. The content of byte block
|
||||
* is determined by the index.
|
||||
* @param length length of byte array
|
||||
* @return a byte array
|
||||
*/
|
||||
public static byte[] generateBytes(int length) {
|
||||
byte[] bytes = new byte[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
bytes[i] = (byte) (i & 0xff);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
970
test/jdk/com/sun/crypto/provider/Cipher/AEAD/AEADBufferTest.java
Normal file
970
test/jdk/com/sun/crypto/provider/Cipher/AEAD/AEADBufferTest.java
Normal file
|
|
@ -0,0 +1,970 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Use Cipher update and doFinal with a mixture of byte[], bytebuffer,
|
||||
* and offset while verifying return values. Also using different and
|
||||
* in-place buffers.
|
||||
*
|
||||
* in-place is not tested with different buffer types as it is not a logical
|
||||
* scenario and is complicated by getOutputSize calculations.
|
||||
*/
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
|
||||
public class AEADBufferTest implements Cloneable {
|
||||
|
||||
// Data type for the operation
|
||||
enum dtype { BYTE, HEAP, DIRECT };
|
||||
// Data map
|
||||
static HashMap<String, List<Data>> datamap = new HashMap<>();
|
||||
// List of enum values for order of operation
|
||||
List<dtype> ops;
|
||||
|
||||
static final String AES = "AES";
|
||||
// The remaining input data length is inserted at the particular index
|
||||
// in sizes[] during execution.
|
||||
static final int REMAINDER = -1;
|
||||
|
||||
String algo;
|
||||
boolean same = true;
|
||||
int[] sizes;
|
||||
boolean incremental = false;
|
||||
// In some cases the theoretical check is too complicated to verify
|
||||
boolean theoreticalCheck;
|
||||
List<Data> dataSet;
|
||||
int inOfs = 0, outOfs = 0;
|
||||
static HexFormat hex = HexFormat.of();
|
||||
|
||||
static class Data {
|
||||
int id;
|
||||
SecretKey key;
|
||||
byte[] iv;
|
||||
int counter; // for CC20
|
||||
byte[] pt;
|
||||
byte[] aad;
|
||||
byte[] ct;
|
||||
byte[] tag;
|
||||
int blockSize; // 16 for GCM, 0 for CC20
|
||||
|
||||
Data(String keyalgo, int id, String key, String iv, byte[] pt, String aad,
|
||||
String ct, String tag) {
|
||||
this(keyalgo, id, key, iv, 0,pt, aad, ct,tag);
|
||||
}
|
||||
|
||||
Data(String keyalgo, int id, String key, String iv, String pt, String aad,
|
||||
String ct, String tag) {
|
||||
this(keyalgo, id, key, iv, HexToBytes(pt), aad, ct, tag);
|
||||
}
|
||||
|
||||
Data(String keyalgo, int id, String key, String iv, int counter, byte[] pt, String aad,
|
||||
String ct, String tag) {
|
||||
this.id = id;
|
||||
this.key = new SecretKeySpec(HexToBytes(key), keyalgo);
|
||||
this.iv = HexToBytes(iv);
|
||||
this.counter = counter;
|
||||
this.pt = pt;
|
||||
this.aad = HexToBytes(aad);
|
||||
this.ct = HexToBytes(ct);
|
||||
this.tag = HexToBytes(tag);
|
||||
this.blockSize = (keyalgo.equals(AES) ? 16 : 0);
|
||||
}
|
||||
|
||||
Data(String keyalgo, int id, String key, String iv, int counter, String pt, String aad,
|
||||
String ct, String tag) {
|
||||
this(keyalgo, id, key, iv, counter, HexToBytes(pt), aad, ct, tag);
|
||||
}
|
||||
|
||||
Data(String keyalgo, int id, String key, int ivLen, int ptlen) {
|
||||
this.id = id;
|
||||
this.key = new SecretKeySpec(HexToBytes(key), keyalgo);
|
||||
iv = new byte[ivLen];
|
||||
counter = 0;
|
||||
pt = new byte[ptlen];
|
||||
tag = new byte[16];
|
||||
aad = new byte[0];
|
||||
boolean isGCM = keyalgo.equals(AES);
|
||||
this.blockSize = (isGCM ? 16 : 0);
|
||||
byte[] tct = null;
|
||||
try {
|
||||
SecureRandom r = new SecureRandom();
|
||||
r.nextBytes(iv);
|
||||
r.nextBytes(pt);
|
||||
Cipher c = Cipher.getInstance(isGCM ? "AES/GCM/NoPadding": "ChaCha20-Poly1305");
|
||||
c.init(Cipher.ENCRYPT_MODE, this.key,
|
||||
getAPS(keyalgo, tag.length, iv));
|
||||
tct = c.doFinal(pt);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error in generating data for length " +
|
||||
ptlen, e);
|
||||
}
|
||||
ct = new byte[ptlen];
|
||||
System.arraycopy(tct, 0, ct, 0, ct.length);
|
||||
System.arraycopy(tct, ct.length, tag, 0, tag.length);
|
||||
}
|
||||
|
||||
private static byte[] HexToBytes(String hexVal) {
|
||||
if (hexVal == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
return hex.parseHex(hexVal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a test with an algorithm and a list of dtype.
|
||||
* @param algo Algorithm string
|
||||
* @param ops List of dtypes. If only one dtype is specified, only a
|
||||
* doFinal operation will occur. If multiple dtypes are
|
||||
* specified, the last is a doFinal, the others are updates.
|
||||
*/
|
||||
AEADBufferTest(String algo, List<dtype> ops) {
|
||||
this.algo = algo;
|
||||
this.ops = ops;
|
||||
theoreticalCheck = true;
|
||||
dataSet = datamap.get(algo);
|
||||
}
|
||||
|
||||
public AEADBufferTest clone() throws CloneNotSupportedException{
|
||||
return (AEADBufferTest)super.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define particular data sizes to be tested. "REMAINDER", which has a
|
||||
* value of -1, can be used to insert the remaining input text length at
|
||||
* that index during execution.
|
||||
* @param sizes Data sizes for each dtype in the list.
|
||||
*/
|
||||
AEADBufferTest dataSegments(int[] sizes) {
|
||||
this.sizes = sizes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not perform in-place operations
|
||||
*/
|
||||
AEADBufferTest differentBufferOnly() {
|
||||
this.same = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable incrementing through each data size available. This can only be
|
||||
* used when the List has more than one dtype entry.
|
||||
*/
|
||||
AEADBufferTest incrementalSegments() {
|
||||
this.incremental = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a particular test dataset.
|
||||
*
|
||||
* @param id id value for the test data to used in this test.
|
||||
*/
|
||||
AEADBufferTest dataSet(int id) throws Exception {
|
||||
for (Data d : datamap.get(algo)) {
|
||||
if (d.id == id) {
|
||||
dataSet = List.of(d);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new Exception("Unable to find dataSet id = " + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set both input and output offsets to the same offset
|
||||
* @param offset value for inOfs and outOfs
|
||||
* @return
|
||||
*/
|
||||
AEADBufferTest offset(int offset) {
|
||||
this.inOfs = offset;
|
||||
this.outOfs = offset;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input offset
|
||||
* @param offset value for input offset
|
||||
*/
|
||||
AEADBufferTest inOfs(int offset) {
|
||||
this.inOfs = offset;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output offset
|
||||
* @param offset value for output offset
|
||||
*/
|
||||
AEADBufferTest outOfs(int offset) {
|
||||
this.outOfs = offset;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse recursive loop that starts at the end-1 index, going to 0, in
|
||||
* the size array to calculate all the possible sizes.
|
||||
* It returns the remaining data size not used in the loop. This remainder
|
||||
* is used for the end index which is the doFinal op.
|
||||
*/
|
||||
int inc(int index, int max, int total) {
|
||||
if (sizes[index] == max - total) {
|
||||
sizes[index + 1]++;
|
||||
total++;
|
||||
sizes[index] = 0;
|
||||
} else if (index == 0) {
|
||||
sizes[index]++;
|
||||
}
|
||||
|
||||
total += sizes[index];
|
||||
if (index > 0) {
|
||||
return inc(index - 1, max, total);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
// Call recursive loop and take returned remainder value for last index
|
||||
boolean incrementSizes(int max) {
|
||||
sizes[ops.size() - 1] = max - inc(ops.size() - 2, max, 0);
|
||||
if (sizes[ops.size() - 2] == max) {
|
||||
// We are at the end, exit test loop
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void test() throws Exception {
|
||||
int i = 1;
|
||||
System.err.println("Algo: " + algo + " \tOps: " + ops.toString());
|
||||
for (Data data : dataSet) {
|
||||
|
||||
// If incrementalSegments is enabled, run through that test only
|
||||
if (incremental) {
|
||||
if (ops.size() < 2) {
|
||||
throw new Exception("To do incrementalSegments you must " +
|
||||
"have more that 1 dtype in the list");
|
||||
}
|
||||
sizes = new int[ops.size()];
|
||||
|
||||
while (incrementSizes(data.pt.length)) {
|
||||
System.err.print("Encrypt: Data Index: " + i + " \tSizes[ ");
|
||||
for (int v : sizes) {
|
||||
System.err.print(v + " ");
|
||||
}
|
||||
System.err.println("]");
|
||||
encrypt(data);
|
||||
}
|
||||
Arrays.fill(sizes, 0);
|
||||
|
||||
while (incrementSizes(data.ct.length + data.tag.length)) {
|
||||
System.err.print("Decrypt: Data Index: " + i + " \tSizes[ ");
|
||||
for (int v : sizes) {
|
||||
System.err.print(v + " ");
|
||||
}
|
||||
System.err.println("]");
|
||||
decrypt(data);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Default test of 0 and 2 offset doing in place and different
|
||||
// i/o buffers
|
||||
System.err.println("Encrypt: Data Index: " + i);
|
||||
encrypt(data);
|
||||
|
||||
System.err.println("Decrypt: Data Index: " + i);
|
||||
decrypt(data);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup data for encryption
|
||||
void encrypt(Data data) throws Exception {
|
||||
byte[] input, output;
|
||||
|
||||
input = data.pt;
|
||||
output = new byte[data.ct.length + data.tag.length];
|
||||
System.arraycopy(data.ct, 0, output, 0, data.ct.length);
|
||||
System.arraycopy(data.tag, 0, output, data.ct.length,
|
||||
data.tag.length);
|
||||
|
||||
// Test different input/output buffers
|
||||
System.err.println("\tinput len: " + input.length + " inOfs " +
|
||||
inOfs + " outOfs " + outOfs + " in/out buffer: different");
|
||||
crypto(true, data, input, output);
|
||||
|
||||
// Test with in-place buffers
|
||||
if (same) {
|
||||
System.err.println("\tinput len: " + input.length + " inOfs " +
|
||||
inOfs + " outOfs " + outOfs + " in/out buffer: in-place");
|
||||
cryptoSameBuffer(true, data, input, output);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup data for decryption
|
||||
void decrypt(Data data) throws Exception {
|
||||
byte[] input, output;
|
||||
|
||||
input = new byte[data.ct.length + data.tag.length];
|
||||
System.arraycopy(data.ct, 0, input, 0, data.ct.length);
|
||||
System.arraycopy(data.tag, 0, input, data.ct.length, data.tag.length);
|
||||
output = data.pt;
|
||||
|
||||
// Test different input/output buffers
|
||||
System.err.println("\tinput len: " + input.length + " inOfs " +
|
||||
inOfs + " outOfs " + outOfs + " in/out buffer: different");
|
||||
crypto(false, data, input, output);
|
||||
|
||||
// Test with in-place buffers
|
||||
if (same) {
|
||||
System.err.println("\tinput len: " + input.length + " inOfs " +
|
||||
inOfs + " outOfs " + outOfs + " in-place: same");
|
||||
cryptoSameBuffer(false, data, input, output);
|
||||
}
|
||||
}
|
||||
|
||||
static AlgorithmParameterSpec getAPS(String algo, int tLen, byte[] iv) {
|
||||
return switch (algo) {
|
||||
case "AES", "AES/GCM/NoPadding" ->
|
||||
new GCMParameterSpec(tLen * 8, iv);
|
||||
case "CC20", "ChaCha20-Poly1305" -> new IvParameterSpec(iv);
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform cipher operation using different input and output buffers.
|
||||
* This method allows mixing of data types (byte, heap, direct).
|
||||
*/
|
||||
void crypto(boolean encrypt, Data d, byte[] input, byte[] output)
|
||||
throws Exception {
|
||||
byte[] pt = new byte[input.length + inOfs];
|
||||
System.arraycopy(input, 0, pt, inOfs, input.length);
|
||||
byte[] expectedOut = new byte[output.length + outOfs];
|
||||
System.arraycopy(output, 0, expectedOut, outOfs, output.length);
|
||||
int plen = input.length / ops.size(); // partial input length
|
||||
int theoreticallen;// expected output length
|
||||
int dataoffset = 0; // offset of unconsumed data in pt
|
||||
int index = 0; // index of which op we are on
|
||||
int rlen; // result length
|
||||
int pbuflen = 0; // plen remaining in the internal buffers
|
||||
|
||||
Cipher cipher = Cipher.getInstance(algo);
|
||||
cipher.init((encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE),
|
||||
d.key, getAPS(algo, d.tag.length, d.iv));
|
||||
cipher.updateAAD(d.aad);
|
||||
|
||||
ByteArrayOutputStream ba = new ByteArrayOutputStream();
|
||||
ba.write(new byte[outOfs], 0, outOfs);
|
||||
for (dtype v : ops) {
|
||||
if (index < ops.size() - 1) {
|
||||
if (sizes != null && input.length > 0) {
|
||||
if (sizes[index] == -1) {
|
||||
plen = input.length - dataoffset;
|
||||
} else {
|
||||
if (sizes[index] > input.length) {
|
||||
plen = input.length;
|
||||
} else {
|
||||
plen = sizes[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int olen = cipher.getOutputSize(plen) + outOfs;
|
||||
|
||||
/*
|
||||
* The theoretical limit is the length of the data sent to
|
||||
* update() + any data might be setting in CipherCore or AEAD
|
||||
* internal buffers % the block size.
|
||||
*/
|
||||
theoreticallen = (plen + pbuflen) - (d.blockSize > 0 ?
|
||||
(plen + pbuflen) % d.blockSize : 0);
|
||||
|
||||
// Update operations
|
||||
switch (v) {
|
||||
case BYTE -> {
|
||||
byte[] out = new byte[olen];
|
||||
rlen = cipher.update(pt, dataoffset + inOfs, plen, out,
|
||||
outOfs);
|
||||
ba.write(out, outOfs, rlen);
|
||||
}
|
||||
case HEAP -> {
|
||||
ByteBuffer b = ByteBuffer.allocate(plen + outOfs);
|
||||
b.position(outOfs);
|
||||
b.put(pt, dataoffset + inOfs, plen);
|
||||
b.flip();
|
||||
b.position(outOfs);
|
||||
ByteBuffer out = ByteBuffer.allocate(olen);
|
||||
out.position(outOfs);
|
||||
rlen = cipher.update(b, out);
|
||||
ba.write(out.array(), outOfs, rlen);
|
||||
}
|
||||
case DIRECT -> {
|
||||
ByteBuffer b = ByteBuffer.allocateDirect(plen + outOfs);
|
||||
b.position(outOfs);
|
||||
b.put(pt, dataoffset + inOfs, plen);
|
||||
b.flip();
|
||||
b.position(outOfs);
|
||||
ByteBuffer out = ByteBuffer.allocateDirect(olen);
|
||||
out.position(outOfs);
|
||||
rlen = cipher.update(b, out);
|
||||
byte[] o = new byte[rlen];
|
||||
out.flip();
|
||||
out.position(outOfs);
|
||||
out.get(o, 0, rlen);
|
||||
ba.write(o);
|
||||
}
|
||||
default -> throw new Exception("Unknown op: " + v.name());
|
||||
}
|
||||
|
||||
if (theoreticalCheck) {
|
||||
pbuflen += plen - rlen;
|
||||
if (encrypt && rlen != theoreticallen) {
|
||||
throw new Exception("Wrong update return len (" +
|
||||
v.name() + "): " + "rlen=" + rlen +
|
||||
", expected output len=" + theoreticallen);
|
||||
}
|
||||
}
|
||||
|
||||
dataoffset += plen;
|
||||
index++;
|
||||
|
||||
} else {
|
||||
// doFinal operation
|
||||
plen = input.length - dataoffset;
|
||||
|
||||
int olen = cipher.getOutputSize(plen) + outOfs;
|
||||
switch (v) {
|
||||
case BYTE -> {
|
||||
byte[] out = new byte[olen];
|
||||
rlen = cipher.doFinal(pt, dataoffset + inOfs,
|
||||
plen, out, outOfs);
|
||||
ba.write(out, outOfs, rlen);
|
||||
}
|
||||
case HEAP -> {
|
||||
ByteBuffer b = ByteBuffer.allocate(plen + inOfs);
|
||||
b.limit(b.capacity());
|
||||
b.position(inOfs);
|
||||
b.put(pt, dataoffset + inOfs, plen);
|
||||
b.flip();
|
||||
b.position(inOfs);
|
||||
ByteBuffer out = ByteBuffer.allocate(olen);
|
||||
out.limit(out.capacity());
|
||||
out.position(outOfs);
|
||||
rlen = cipher.doFinal(b, out);
|
||||
ba.write(out.array(), outOfs, rlen);
|
||||
}
|
||||
case DIRECT -> {
|
||||
ByteBuffer b = ByteBuffer.allocateDirect(plen + inOfs);
|
||||
b.limit(b.capacity());
|
||||
b.position(inOfs);
|
||||
b.put(pt, dataoffset + inOfs, plen);
|
||||
b.flip();
|
||||
b.position(inOfs);
|
||||
ByteBuffer out = ByteBuffer.allocateDirect(olen);
|
||||
out.limit(out.capacity());
|
||||
out.position(outOfs);
|
||||
rlen = cipher.doFinal(b, out);
|
||||
byte[] o = new byte[rlen];
|
||||
out.flip();
|
||||
out.position(outOfs);
|
||||
out.get(o, 0, rlen);
|
||||
ba.write(o);
|
||||
}
|
||||
default -> throw new Exception("Unknown op: " + v.name());
|
||||
}
|
||||
|
||||
if (theoreticalCheck && rlen != olen - outOfs) {
|
||||
throw new Exception("Wrong doFinal return len (" +
|
||||
v.name() + "): " + "rlen=" + rlen +
|
||||
", expected output len=" + (olen - outOfs));
|
||||
}
|
||||
|
||||
// Verify results
|
||||
byte[] ctresult = ba.toByteArray();
|
||||
if (ctresult.length != expectedOut.length ||
|
||||
Arrays.compare(ctresult, expectedOut) != 0) {
|
||||
String s = "Ciphertext mismatch (" + v.name() +
|
||||
"):\nresult (len=" + ctresult.length + "): " +
|
||||
hex.formatHex(ctresult) +
|
||||
"\nexpected (len=" + output.length + "): " +
|
||||
hex.formatHex(output);
|
||||
System.err.println(s);
|
||||
throw new Exception(s);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform cipher operation using in-place buffers. This method does not
|
||||
* allow mixing of data types (byte, heap, direct).
|
||||
*
|
||||
* Mixing data types makes no sense for in-place operations and would
|
||||
* greatly complicate the test code.
|
||||
*/
|
||||
void cryptoSameBuffer(boolean encrypt, Data d, byte[] input, byte[] output) throws Exception {
|
||||
|
||||
byte[] data, out;
|
||||
if (encrypt) {
|
||||
data = new byte[output.length + Math.max(inOfs, outOfs)];
|
||||
} else {
|
||||
data = new byte[input.length + Math.max(inOfs, outOfs)];
|
||||
}
|
||||
|
||||
ByteBuffer bbin = null, bbout = null;
|
||||
System.arraycopy(input, 0, data, inOfs, input.length);
|
||||
byte[] expectedOut = new byte[output.length + outOfs];
|
||||
System.arraycopy(output, 0, expectedOut, outOfs, output.length);
|
||||
int plen = input.length / ops.size(); // partial input length
|
||||
int theorticallen = plen -
|
||||
(d.blockSize > 0 ? plen % d.blockSize : 0); // output length
|
||||
int dataoffset = 0;
|
||||
int index = 0;
|
||||
int rlen = 0; // result length
|
||||
int len = 0;
|
||||
|
||||
Cipher cipher = Cipher.getInstance(algo);
|
||||
cipher.init((encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE),
|
||||
d.key, getAPS(algo, d.tag.length, d.iv));
|
||||
cipher.updateAAD(d.aad);
|
||||
|
||||
// Prepare data
|
||||
switch (ops.get(0)) {
|
||||
case HEAP -> {
|
||||
bbin = ByteBuffer.wrap(data);
|
||||
bbin.limit(input.length + inOfs);
|
||||
bbout = bbin.duplicate();
|
||||
}
|
||||
case DIRECT -> {
|
||||
bbin = ByteBuffer.allocateDirect(data.length);
|
||||
bbout = bbin.duplicate();
|
||||
bbin.put(data, 0, input.length + inOfs);
|
||||
bbin.flip();
|
||||
}
|
||||
}
|
||||
|
||||
// Set data limits for bytebuffers
|
||||
if (bbin != null) {
|
||||
bbin.position(inOfs);
|
||||
bbout.limit(output.length + outOfs);
|
||||
bbout.position(outOfs);
|
||||
}
|
||||
|
||||
// Iterate through each operation
|
||||
for (dtype v : ops) {
|
||||
if (index < ops.size() - 1) {
|
||||
switch (v) {
|
||||
case BYTE -> {
|
||||
rlen = cipher.update(data, dataoffset + inOfs, plen,
|
||||
data, len + outOfs);
|
||||
}
|
||||
case HEAP, DIRECT -> {
|
||||
theorticallen = bbin.remaining() - (d.blockSize > 0 ?
|
||||
bbin.remaining() % d.blockSize : 0);
|
||||
rlen = cipher.update(bbin, bbout);
|
||||
}
|
||||
default -> throw new Exception("Unknown op: " + v.name());
|
||||
}
|
||||
|
||||
// Check that the theoretical return value matches the actual.
|
||||
if (theoreticalCheck && encrypt && rlen != theorticallen) {
|
||||
throw new Exception("Wrong update return len (" +
|
||||
v.name() + "): " + "rlen=" + rlen +
|
||||
", expected output len=" + theorticallen);
|
||||
}
|
||||
|
||||
dataoffset += plen;
|
||||
len += rlen;
|
||||
index++;
|
||||
|
||||
} else {
|
||||
// Run doFinal op
|
||||
plen = input.length - dataoffset;
|
||||
|
||||
switch (v) {
|
||||
case BYTE -> {
|
||||
rlen = cipher.doFinal(data, dataoffset + inOfs,
|
||||
plen, data, len + outOfs);
|
||||
out = Arrays.copyOfRange(data, 0,len + rlen + outOfs);
|
||||
}
|
||||
case HEAP, DIRECT -> {
|
||||
rlen = cipher.doFinal(bbin, bbout);
|
||||
bbout.flip();
|
||||
out = new byte[bbout.remaining()];
|
||||
bbout.get(out);
|
||||
}
|
||||
default -> throw new Exception("Unknown op: " + v.name());
|
||||
}
|
||||
len += rlen;
|
||||
|
||||
// Verify results
|
||||
if (len != output.length ||
|
||||
Arrays.compare(out, 0, len, expectedOut, 0,
|
||||
output.length) != 0) {
|
||||
String s = "Ciphertext mismatch (" + v.name() +
|
||||
"):\nresult (len=" + len + "):\n" +
|
||||
hex.formatHex(out) +
|
||||
"\nexpected (len=" + output.length + "):\n" +
|
||||
hex.formatHex(output);
|
||||
System.err.println(s);
|
||||
throw new Exception(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static void offsetTests(AEADBufferTest t) throws Exception {
|
||||
t.clone().offset(2).test();
|
||||
t.clone().inOfs(2).test();
|
||||
// Test not designed for overlap situations
|
||||
t.clone().outOfs(2).differentBufferOnly().test();
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
AEADBufferTest t;
|
||||
|
||||
initTest();
|
||||
|
||||
// **** GCM Tests
|
||||
|
||||
// Test single byte array
|
||||
new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE)).test();
|
||||
offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE)));
|
||||
// Test update-doFinal with byte arrays
|
||||
new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE)).test();
|
||||
offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE)));
|
||||
// Test update-update-doFinal with byte arrays
|
||||
new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).test();
|
||||
offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)));
|
||||
|
||||
// Test single heap bytebuffer
|
||||
new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP)).test();
|
||||
offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP)));
|
||||
// Test update-doFinal with heap bytebuffer
|
||||
new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.HEAP, dtype.HEAP)).test();
|
||||
offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP, dtype.HEAP)));
|
||||
// Test update-update-doFinal with heap bytebuffer
|
||||
new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)).test();
|
||||
offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)));
|
||||
|
||||
// Test single direct bytebuffer
|
||||
new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.DIRECT)).test();
|
||||
offsetTests(new AEADBufferTest("AES/GCM/NoPadding", List.of(dtype.DIRECT)));
|
||||
// Test update-doFinal with direct bytebuffer
|
||||
new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT)).test();
|
||||
offsetTests(new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT)));
|
||||
// Test update-update-doFinal with direct bytebuffer
|
||||
new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).test();
|
||||
offsetTests(new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)));
|
||||
|
||||
// Test update-update-doFinal with byte arrays and preset data sizes
|
||||
t = new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).dataSegments(
|
||||
new int[] { 1, 1, AEADBufferTest.REMAINDER});
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
|
||||
// Test update-doFinal with a byte array and a direct bytebuffer
|
||||
t = new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.BYTE, dtype.DIRECT)).differentBufferOnly();
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
// Test update-doFinal with a byte array and heap and direct bytebuffer
|
||||
t = new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.BYTE, dtype.HEAP, dtype.DIRECT)).differentBufferOnly();
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
|
||||
// Test update-doFinal with a direct bytebuffer and a byte array.
|
||||
t = new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly();
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
|
||||
// Test update-doFinal with a direct bytebuffer and a byte array with
|
||||
// preset data sizes.
|
||||
t = new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly().
|
||||
dataSegments(new int[] { 20, AEADBufferTest.REMAINDER });
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
// Test update-update-doFinal with a direct and heap bytebuffer and a
|
||||
// byte array with preset data sizes.
|
||||
t = new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.DIRECT, dtype.BYTE, dtype.HEAP)).
|
||||
differentBufferOnly().dataSet(5).
|
||||
dataSegments(new int[] { 5000, 1000, AEADBufferTest.REMAINDER });
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
|
||||
// Test update-update-doFinal with byte arrays, incrementing through
|
||||
// every data size combination for the Data set 0
|
||||
new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).incrementalSegments().
|
||||
dataSet(0).test();
|
||||
// Test update-update-doFinal with direct bytebuffers, incrementing through
|
||||
// every data size combination for the Data set 0
|
||||
new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).
|
||||
incrementalSegments().dataSet(0).test();
|
||||
|
||||
new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).
|
||||
dataSegments(new int[] { 49, 0, 2 }).dataSet(0).test();
|
||||
|
||||
// **** CC20P1305 Tests
|
||||
|
||||
// Test single byte array
|
||||
new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE)).test();
|
||||
offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE)));
|
||||
// Test update-doFinal with byte arrays
|
||||
new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE, dtype.BYTE)).test();
|
||||
offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE, dtype.BYTE)));
|
||||
// Test update-update-doFinal with byte arrays
|
||||
new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).test();
|
||||
offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)));
|
||||
|
||||
// Test single heap bytebuffer
|
||||
new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP)).test();
|
||||
offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP)));
|
||||
// Test update-doFinal with heap bytebuffer
|
||||
new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.HEAP, dtype.HEAP)).test();
|
||||
offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP, dtype.HEAP)));
|
||||
// Test update-update-doFinal with heap bytebuffer
|
||||
new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)).test();
|
||||
offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)));
|
||||
|
||||
// Test single direct bytebuffer
|
||||
new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.DIRECT)).test();
|
||||
offsetTests(new AEADBufferTest("ChaCha20-Poly1305", List.of(dtype.DIRECT)));
|
||||
// Test update-doFinal with direct bytebuffer
|
||||
new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT)).test();
|
||||
offsetTests(new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT)));
|
||||
// Test update-update-doFinal with direct bytebuffer
|
||||
new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).test();
|
||||
offsetTests(new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)));
|
||||
|
||||
// Test update-update-doFinal with byte arrays and preset data sizes
|
||||
t = new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).dataSegments(
|
||||
new int[] { 1, 1, AEADBufferTest.REMAINDER});
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
|
||||
// Test update-doFinal with a byte array and a direct bytebuffer
|
||||
t = new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.BYTE, dtype.DIRECT)).differentBufferOnly();
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
// Test update-doFinal with a byte array and heap and direct bytebuffer
|
||||
t = new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.BYTE, dtype.HEAP, dtype.DIRECT)).differentBufferOnly();
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
|
||||
// Test update-doFinal with a direct bytebuffer and a byte array.
|
||||
t = new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly();
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
|
||||
// Test update-doFinal with a direct bytebuffer and a byte array with
|
||||
// preset data sizes.
|
||||
t = new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly().
|
||||
dataSegments(new int[] { 20, AEADBufferTest.REMAINDER });
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
// Test update-update-doFinal with a direct and heap bytebuffer and a
|
||||
// byte array with preset data sizes.
|
||||
t = new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.DIRECT, dtype.BYTE, dtype.HEAP)).
|
||||
differentBufferOnly().dataSet(1).
|
||||
dataSegments(new int[] { 5000, 1000, AEADBufferTest.REMAINDER });
|
||||
t.clone().test();
|
||||
offsetTests(t.clone());
|
||||
|
||||
// Test update-update-doFinal with byte arrays, incrementing through
|
||||
// every data size combination for the Data set 0
|
||||
new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).incrementalSegments().
|
||||
dataSet(0).test();
|
||||
// Test update-update-doFinal with direct bytebuffers, incrementing through
|
||||
// every data size combination for the Data set 0
|
||||
new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).
|
||||
incrementalSegments().dataSet(0).test();
|
||||
|
||||
new AEADBufferTest("ChaCha20-Poly1305",
|
||||
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).
|
||||
dataSegments(new int[] { 49, 0, 2 }).dataSet(0).test();
|
||||
}
|
||||
|
||||
// Test data
|
||||
static void initTest() {
|
||||
|
||||
datamap.put("AES/GCM/NoPadding", List.of(
|
||||
// GCM KAT
|
||||
new Data(AES, 0,
|
||||
"141f1ce91989b07e7eb6ae1dbd81ea5e",
|
||||
"49451da24bd6074509d3cebc2c0394c972e6934b45a1d91f3ce1d3ca69e19" +
|
||||
"4aa1958a7c21b6f21d530ce6d2cc5256a3f846b6f9d2f38df0102c4791e5" +
|
||||
"7df038f6e69085646007df999751e248e06c47245f4cd3b8004585a7470d" +
|
||||
"ee1690e9d2d63169a58d243c0b57b3e5b4a481a3e4e8c60007094ef3adea" +
|
||||
"2e8f05dd3a1396f",
|
||||
"d384305af2388699aa302f510913fed0f2cb63ba42efa8c5c9de2922a2ec" +
|
||||
"2fe87719dadf1eb0aef212b51e74c9c5b934104a43",
|
||||
"630cf18a91cc5a6481ac9eefd65c24b1a3c93396bd7294d6b8ba3239517" +
|
||||
"27666c947a21894a079ef061ee159c05beeb4",
|
||||
"f4c34e5fbe74c0297313268296cd561d59ccc95bbfcdfcdc71b0097dbd83" +
|
||||
"240446b28dc088abd42b0fc687f208190ff24c0548",
|
||||
"dbb93bbb56d0439cd09f620a57687f5d"),
|
||||
// GCM KAT
|
||||
new Data(AES, 1, "11754cd72aec309bf52f7687212e8957",
|
||||
"3c819d9a9bed087615030b65",
|
||||
new byte[0], null, null,
|
||||
"250327c674aaf477aef2675748cf6971"),
|
||||
// Random test data
|
||||
new Data(AES, 4, "272f16edb81a7abbea887357a58c1917",
|
||||
"794ec588176c703d3d2a7a07",
|
||||
new byte[2075], null,
|
||||
"15b461672153270e8ba1e6789f7641c5411f3e642abda731b6086f535c216457" +
|
||||
"e87305bc59a1ff1f7e1e0bbdf302b75549b136606c67d7e5f71277aeca4bc670" +
|
||||
"07a98f78e0cfa002ed183e62f07893ad31fe67aad1bb37e15b957a14d145f14f" +
|
||||
"7483d041f2c3612ad5033155984470bdfc64d18df73c2745d92f28461bb09832" +
|
||||
"33524811321ba87d213692825815dd13f528dba601a3c319cac6be9b48686c23" +
|
||||
"a0ce23d5062916ea8827bbb243f585e446131489e951354c8ab24661f625c02e" +
|
||||
"15536c5bb602244e98993ff745f3e523399b2059f0e062d8933fad2366e7e147" +
|
||||
"510a931282bb0e3f635efe7bf05b1dd715f95f5858261b00735224256b6b3e80" +
|
||||
"7364cb53ff6d4e88f928cf67ac70da127718a8a35542efbae9dd7567c818a074" +
|
||||
"9a0c74bd69014639f59768bc55056d1166ea5523e8c66f9d78d980beb8f0d83b" +
|
||||
"a9e2c5544b94dc3a1a4b6f0f95f897b010150e89ebcacf0daee3c2793d6501a0" +
|
||||
"b58b411de273dee987e8e8cf8bb29ef2e7f655b46b55fabf64c6a4295e0d080b" +
|
||||
"6a570ace90eb0fe0f5b5d878bdd90eddaa1150e4d5a6505b350aac814fe99615" +
|
||||
"317ecd0516a464c7904011ef5922409c0d65b1e43b69d7c3293a8f7d3e9fbee9" +
|
||||
"eb91ec0007a7d6f72e64deb675d459c5ba07dcfd58d08e6820b100465e6e04f0" +
|
||||
"663e310584a00d36d23699c1bffc6afa094c75184fc7cde7ad35909c0f49f2f3" +
|
||||
"fe1e6d745ab628d74ea56b757047de57ce18b4b3c71e8af31a6fac16189cb0a3" +
|
||||
"a97a1bea447042ce382fcf726560476d759c24d5c735525ea26a332c2094408e" +
|
||||
"671c7deb81d5505bbfd178f866a6f3a011b3cfdbe089b4957a790688028dfdf7" +
|
||||
"9a096b3853f9d0d6d3feef230c7f5f46ffbf7486ebdaca5804dc5bf9d202415e" +
|
||||
"e0d67b365c2f92a17ea740807e4f0b198b42b54f15faa9dff2c7c35d2cf8d72e" +
|
||||
"b8f8b18875a2e7b5c43d1e0aa5139c461e8153c7f632895aa46ffe2b134e6a0d" +
|
||||
"dfbf6a336e709adfe951bd52c4dfc7b07a15fb3888fc35b7e758922f87a104c4" +
|
||||
"563c5c7839cfe5a7edbdb97264a7c4ebc90367b10cbe09dbf2390767ad7afaa8" +
|
||||
"8fb46b39d3f55f216d2104e5cf040bf3d39b758bea28e2dbce576c808d17a8eb" +
|
||||
"e2fd183ef42a774e39119dff1f539efeb6ad15d889dfcb0d54d0d4d4cc03c8d9" +
|
||||
"aa6c9ebd157f5e7170183298d6a30ada8792dcf793d931e2a1eafccbc63c11c0" +
|
||||
"c5c5ed60837f30017d693ccb294df392a8066a0594a56954aea7b78a16e9a11f" +
|
||||
"4a8bc2104070a7319f5fab0d2c4ccad8ec5cd8f47c839179bfd54a7bf225d502" +
|
||||
"cd0a318752fe763e8c09eb88fa57fc5399ad1f797d0595c7b8afdd23f13603e9" +
|
||||
"6802192bb51433b7723f4e512bd4f799feb94b458e7f9792f5f9bd6733828f70" +
|
||||
"a6b7ffbbc0bb7575021f081ec2a0d37fecd7cda2daec9a3a9d9dfe1c8034cead" +
|
||||
"e4b56b581cc82bd5b74b2b30817967d9da33850336f171a4c68e2438e03f4b11" +
|
||||
"96da92f01b3b7aeab795180ccf40a4b090b1175a1fc0b67c95f93105c3aef00e" +
|
||||
"13d76cc402539192274fee703730cd0d1c5635257719cc96cacdbad00c6255e2" +
|
||||
"bd40c775b43ad09599e84f2c3205d75a6661ca3f151183be284b354ce21457d1" +
|
||||
"3ba65b9b2cdb81874bd14469c2008b3ddec78f7225ecc710cc70de7912ca6a6d" +
|
||||
"348168322ab59fdafcf5c833bfa0ad4046f4b6da90e9f263db7079af592eda07" +
|
||||
"5bf16c6b1a8346da9c292a48bf660860a4fc89eaef40bc132779938eca294569" +
|
||||
"787c740af2b5a8de7f5e10ac750d1e3d0ef3ed168ba408a676e10b8a20bd4be8" +
|
||||
"3e8336b45e54481726d73e1bd19f165a98e242aca0d8387f2dd22d02d74e23db" +
|
||||
"4cef9a523587413e0a44d7e3260019a34d3a6b38426ae9fa4655be338d721970" +
|
||||
"cb9fe76c073f26f9303093a033022cd2c62b2790bce633ba9026a1c93b6535f1" +
|
||||
"1882bf5880e511b9e1b0b7d8f23a993aae5fd275faac3a5b4ccaf7c06b0b266a" +
|
||||
"ee970a1e3a4cd7a41094f516960630534e692545b25a347c30e3f328bba4825f" +
|
||||
"ed754e5525d846131ecba7ca120a6aeabc7bab9f59c890c80b7e31f9bc741591" +
|
||||
"55d292433ce9558e104102f2cc63ee267c1c8333e841522707ea6d595cb802b9" +
|
||||
"61697da77bbc4cb404ea62570ab335ebffa2023730732ac5ddba1c3dbb5be408" +
|
||||
"3c50aea462c1ffa166d7cc3db4b742b747e81b452db2363e91374dee8c6b40f0" +
|
||||
"e7fbf50e60eaf5cc5649f6bb553aae772c185026ceb052af088c545330a1ffbf" +
|
||||
"50615b8c7247c6cd386afd7440654f4e15bcfae0c45442ec814fe88433a9d616" +
|
||||
"ee6cc3f163f0d3d325526d05f25d3b37ad5eeb3ca77248ad86c9042b16c65554" +
|
||||
"aebb6ad3e17b981492b13f42c5a5dc088e991da303e5a273fdbb8601aece4267" +
|
||||
"47b01f6cb972e6da1743a0d7866cf206e95f23c6f8e337c901b9cd34a9a1fbbe" +
|
||||
"1694f2c26b00dfa4d02c0d54540163e798fbdc9c25f30d6406f5b4c13f7ed619" +
|
||||
"34e350f4059c13aa5e973307a9e3058917cda96fdd082e9c629ccfb2a9f98d12" +
|
||||
"5c6e4703a7b0f348f5cdeb63cef2133d1c6c1a087591e0a2bca29d09c6565e66" +
|
||||
"e91042f83b0e74e60a5d57562c23e2fbcd6599c29d7c19e47cf625c2ce24bb8a" +
|
||||
"13f8e54041498437eec2cedd1e3d8e57a051baa962c0a62d70264d99c5ee716d" +
|
||||
"5c8b9078db08c8b2c5613f464198a7aff43f76c5b4612b46a4f1cd2a494386c5" +
|
||||
"7fd28f3d199f0ba8d8e39116cc7db16ce6188205ee49a9dce3d4fa32ea394919" +
|
||||
"f6e91ef58b84d00b99596b4306c2d9f432d917bb4ac73384c42ae12adb4920d8" +
|
||||
"c33a816febcb299dcddf3ec7a8eb6e04cdc90891c6e145bd9fc5f41dc4061a46" +
|
||||
"9feba38545b64ec8203f386ceef52785619e991d274ae80af7e54af535e0b011" +
|
||||
"5effdf847472992875e09398457604d04e0bb965db692c0cdcf11a",
|
||||
"687cc09c89298491deb51061d709af"),
|
||||
// Randomly generated data at the time of execution.
|
||||
new Data(AES, 5, "11754cd72aec309bf52f7687212e8957",
|
||||
16, 12345)));
|
||||
|
||||
datamap.put("ChaCha20-Poly1305", List.of(
|
||||
new Data("CC20", 0,
|
||||
"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
|
||||
"070000004041424344454647",
|
||||
1,
|
||||
"4c616469657320616e642047656e746c656d656e206f662074686520636c6173" +
|
||||
"73206f66202739393a204966204920636f756c64206f6666657220796f75206f" +
|
||||
"6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" +
|
||||
"637265656e20776f756c642062652069742e",
|
||||
"50515253c0c1c2c3c4c5c6c7",
|
||||
"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d6" +
|
||||
"3dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b36" +
|
||||
"92ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc" +
|
||||
"3ff4def08e4b7a9de576d26586cec64b61161ae10b59",
|
||||
"4f09e26a7e902ecbd0600691"),
|
||||
// Randomly generated data at the time of execution.
|
||||
new Data("CC20", 1,
|
||||
"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
|
||||
12, 12345)));
|
||||
}
|
||||
}
|
||||
759
test/jdk/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java
Normal file
759
test/jdk/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java
Normal file
|
|
@ -0,0 +1,759 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 java.nio.ByteBuffer;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048596
|
||||
* @summary AEAD encryption/decryption test
|
||||
*/
|
||||
|
||||
/*
|
||||
* The test does the following:
|
||||
* - create an input text and additional data
|
||||
* - generate a secret key
|
||||
* - instantiate a cipher according to the GCM transformation
|
||||
* - generate an outputText using a single-part encryption/decryption
|
||||
* in AEAD mode
|
||||
* - perform 16 different combinations of multiple-part encryption/decryption
|
||||
* operation in AEAD mode (in encryption mode new Cipher object is created
|
||||
* and initialized with the same secret key and parameters)
|
||||
* - check that all 17 results are equal
|
||||
*
|
||||
* Combinations:
|
||||
*
|
||||
* combination #1
|
||||
* updateAAD(byte[] src)
|
||||
* update(byte[], int, int)
|
||||
* doFinal(byte[], int, int)
|
||||
*
|
||||
* combination #2
|
||||
* updateAAD(byte[] src)
|
||||
* update(byte[], int, int)
|
||||
* doFinal(byte[], int, int, byte[], int)
|
||||
*
|
||||
* combination #3
|
||||
* updateAAD(byte[] src)
|
||||
* update(byte[], int, int, byte[], int)
|
||||
* doFinal(byte[], int, int)
|
||||
*
|
||||
* combination #4
|
||||
* updateAAD(byte[] src)
|
||||
* update(byte[], int, int, byte[], int)
|
||||
* doFinal(byte[], int, int, byte[], int)
|
||||
*
|
||||
* combination #5 - #8 are similar to #1 -#4,
|
||||
* but with updateAAD(byte[] src, int offset, int len)
|
||||
*
|
||||
* combination #9 - #12 are similar to #1 - #4,
|
||||
* but with updateAAD(ByteBuffer src)
|
||||
*
|
||||
* combination #13 - #16 are similar to #9 - #12 but with directly allocated
|
||||
* ByteBuffer and update(ByteBuffer input, ByteBuffer output)
|
||||
*
|
||||
*/
|
||||
public class Encrypt {
|
||||
|
||||
private static final String ALGORITHMS[] = { "AES" };
|
||||
private static final int KEY_STRENGTHS[] = { 128, 192, 256 };
|
||||
private static final int TEXT_LENGTHS[] = { 0, 256, 1024 };
|
||||
private static final int AAD_LENGTHS[] = { 0, 8, 128, 256, 1024 };
|
||||
private static final int ARRAY_OFFSET = 8;
|
||||
|
||||
private final String transformation;
|
||||
private final Provider provider;
|
||||
private final SecretKey key;
|
||||
private final int textLength;
|
||||
private final int AADLength;
|
||||
|
||||
/**
|
||||
* @param provider Security provider
|
||||
* @param algorithm Security algorithm to test
|
||||
* @param mode The mode (GCM is only expected)
|
||||
* @param padding Algorithm padding
|
||||
* @param keyStrength key length
|
||||
* @param textLength Plain text length
|
||||
* @param AADLength Additional data length
|
||||
*/
|
||||
public Encrypt(Provider provider, String algorithm, String mode,
|
||||
String padding, int keyStrength, int textLength, int AADLength)
|
||||
throws Exception {
|
||||
|
||||
// init a secret Key
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algorithm, provider);
|
||||
kg.init(keyStrength);
|
||||
key = kg.generateKey();
|
||||
|
||||
this.provider = provider;
|
||||
this.transformation = algorithm + "/" + mode + "/" + padding;
|
||||
this.textLength = textLength;
|
||||
this.AADLength = AADLength;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Provider p = Security.getProvider(
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
for (String alg : ALGORITHMS) {
|
||||
for (int keyStrength : KEY_STRENGTHS) {
|
||||
if (keyStrength > Cipher.getMaxAllowedKeyLength(alg)) {
|
||||
// skip this if this key length is larger than what's
|
||||
// configured in the JCE jurisdiction policy files
|
||||
continue;
|
||||
}
|
||||
for (int textLength : TEXT_LENGTHS) {
|
||||
for (int AADLength : AAD_LENGTHS) {
|
||||
Encrypt test = new Encrypt(p, alg,
|
||||
"GCM", "NoPadding", keyStrength, textLength,
|
||||
AADLength);
|
||||
Cipher cipher = test.createCipher(Cipher.ENCRYPT_MODE,
|
||||
null);
|
||||
AlgorithmParameters params = cipher.getParameters();
|
||||
test.doTest(params);
|
||||
System.out.println("Test " + alg + ":"
|
||||
+ keyStrength + ":" + textLength + ":"
|
||||
+ AADLength + " passed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void doTest(AlgorithmParameters params) throws Exception {
|
||||
System.out.println("Test transformation = " + transformation
|
||||
+ ", textLength = " + textLength
|
||||
+ ", AADLength = " + AADLength);
|
||||
byte[] input = Helper.generateBytes(textLength);
|
||||
byte[] AAD = Helper.generateBytes(AADLength);
|
||||
byte[] result = execute(Cipher.ENCRYPT_MODE, AAD, input, params);
|
||||
result = execute(Cipher.DECRYPT_MODE, AAD, result, params);
|
||||
if (!Arrays.equals(input, result)) {
|
||||
throw new RuntimeException("Test failed");
|
||||
}
|
||||
System.out.println("Test passed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Cipher object for the requested encryption/decryption mode.
|
||||
*
|
||||
* @param mode encryption or decryption mode
|
||||
* @return Cipher object initiated to perform requested mode operation
|
||||
*/
|
||||
private Cipher createCipher(int mode, AlgorithmParameters params)
|
||||
throws Exception {
|
||||
Cipher ci;
|
||||
if (Cipher.ENCRYPT_MODE == mode) {
|
||||
// create a new Cipher object for encryption
|
||||
ci = Cipher.getInstance(transformation, provider);
|
||||
|
||||
// initiate it with the saved parameters
|
||||
if (params != null) {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key, params);
|
||||
} else {
|
||||
// initiate the cipher without parameters
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
}
|
||||
} else {
|
||||
// it is expected that parameters already generated
|
||||
// before decryption
|
||||
ci = Cipher.getInstance(transformation, provider);
|
||||
ci.init(Cipher.DECRYPT_MODE, key, params);
|
||||
}
|
||||
|
||||
return ci;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test AEAD combinations
|
||||
*
|
||||
* @param mode decryption or encryption
|
||||
* @param AAD additional data for AEAD operations
|
||||
* @param inputText plain text to decrypt/encrypt
|
||||
* @return output text after encrypt/decrypt
|
||||
*/
|
||||
public byte[] execute(int mode, byte[] AAD, byte[] inputText,
|
||||
AlgorithmParameters params) throws Exception {
|
||||
|
||||
Cipher cipher = createCipher(mode, params);
|
||||
|
||||
// results of each combination will be saved in the outputTexts
|
||||
List<byte[]> outputTexts = new ArrayList<>();
|
||||
|
||||
// generate a standard outputText using a single-part en/de-cryption
|
||||
cipher.updateAAD(AAD);
|
||||
byte[] output = cipher.doFinal(inputText);
|
||||
|
||||
// execute multiple-part encryption/decryption combinations
|
||||
combination_1(outputTexts, mode, AAD, inputText, params);
|
||||
combination_2(outputTexts, mode, AAD, inputText, params);
|
||||
combination_3(outputTexts, mode, AAD, inputText, params);
|
||||
combination_4(outputTexts, mode, AAD, inputText, params);
|
||||
combination_5(outputTexts, mode, AAD, inputText, params);
|
||||
combination_6(outputTexts, mode, AAD, inputText, params);
|
||||
combination_7(outputTexts, mode, AAD, inputText, params);
|
||||
combination_8(outputTexts, mode, AAD, inputText, params);
|
||||
combination_9(outputTexts, mode, AAD, inputText, params);
|
||||
combination_10(outputTexts, mode, AAD, inputText, params);
|
||||
combination_11(outputTexts, mode, AAD, inputText, params);
|
||||
combination_12(outputTexts, mode, AAD, inputText, params);
|
||||
combination_13(outputTexts, mode, AAD, inputText, params);
|
||||
combination_14(outputTexts, mode, AAD, inputText, params);
|
||||
combination_15(outputTexts, mode, AAD, inputText, params);
|
||||
combination_16(outputTexts, mode, AAD, inputText, params);
|
||||
|
||||
for (int k = 0; k < outputTexts.size(); k++) {
|
||||
HexFormat hex = HexFormat.of().withUpperCase();
|
||||
if (!Arrays.equals(output, outputTexts.get(k))) {
|
||||
System.out.println("Combination #" + (k + 1) + "\nresult " +
|
||||
hex.formatHex(outputTexts.get(k)) +
|
||||
"\nexpected: " + hex.formatHex(output));
|
||||
throw new RuntimeException("Combination #" + (k + 1) + " failed");
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #1:
|
||||
* updateAAD(byte[] src)
|
||||
* update(byte[], int, int)
|
||||
* doFinal(byte[], int, int)
|
||||
*/
|
||||
private void combination_1(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher c = createCipher(mode, params);
|
||||
c.updateAAD(AAD);
|
||||
byte[] part11 = c.update(plainText, 0, plainText.length);
|
||||
int part11_length = part11 == null ? 0 : part11.length;
|
||||
byte[] part12 = c.doFinal();
|
||||
byte[] outputText1 = new byte[part11_length + part12.length];
|
||||
if (part11 != null) {
|
||||
System.arraycopy(part11, 0, outputText1, 0, part11_length);
|
||||
}
|
||||
System.arraycopy(part12, 0, outputText1, part11_length, part12.length);
|
||||
results.add(outputText1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #2:
|
||||
* updateAAD(byte[] src)
|
||||
* update(byte[], int, int)
|
||||
* doFinal(byte[], int, int, byte[], int)
|
||||
*/
|
||||
private void combination_2(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher c = createCipher(mode, params);
|
||||
c.updateAAD(AAD);
|
||||
int t = 0;
|
||||
int offset = 0;
|
||||
if (plainText.length > ARRAY_OFFSET) {
|
||||
t = plainText.length - ARRAY_OFFSET;
|
||||
offset = ARRAY_OFFSET;
|
||||
}
|
||||
byte[] part21 = c.update(plainText, 0, t);
|
||||
byte[] part22 = new byte[c.getOutputSize(plainText.length)];
|
||||
int len2 = c.doFinal(plainText, t, offset, part22, 0);
|
||||
int part21Length = part21 != null ? part21.length : 0;
|
||||
byte[] outputText2 = new byte[part21Length + len2];
|
||||
if (part21 != null) {
|
||||
System.arraycopy(part21, 0, outputText2, 0, part21Length);
|
||||
}
|
||||
System.arraycopy(part22, 0, outputText2, part21Length, len2);
|
||||
results.add(outputText2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #3
|
||||
* updateAAD(byte[] src)
|
||||
* update(byte[], int, int, byte[], int)
|
||||
* doFinal(byte[], int, int)
|
||||
*/
|
||||
private void combination_3(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher ci = createCipher(mode, params);
|
||||
ci.updateAAD(AAD);
|
||||
byte[] part31 = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
|
||||
int len = ci.update(plainText, 0, plainText.length - offset, part31, 0);
|
||||
byte[] part32 = ci.doFinal(plainText, plainText.length - offset,
|
||||
offset);
|
||||
byte[] outputText3 = new byte[len + part32.length];
|
||||
System.arraycopy(part31, 0, outputText3, 0, len);
|
||||
System.arraycopy(part32, 0, outputText3, len, part32.length);
|
||||
results.add(outputText3);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #4:
|
||||
* updateAAD(byte[] src)
|
||||
* update(byte[], int, int, byte[], int)
|
||||
* doFinal(byte[], int, int, byte[], int)
|
||||
*/
|
||||
private void combination_4(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher ci = createCipher(mode, params);
|
||||
ci.updateAAD(AAD);
|
||||
byte[] part41 = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
|
||||
int len = ci.update(plainText, 0, plainText.length - offset, part41, 0);
|
||||
int rest4 = ci.doFinal(plainText, plainText.length - offset, offset,
|
||||
part41, len);
|
||||
byte[] outputText4 = new byte[len + rest4];
|
||||
System.arraycopy(part41, 0, outputText4, 0, outputText4.length);
|
||||
results.add(outputText4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #5:
|
||||
* updateAAD(byte[] src, int offset, int len)
|
||||
* update(byte[], int, int)
|
||||
* doFinal(byte[], int, int)
|
||||
*/
|
||||
private void combination_5(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher c = createCipher(mode, params);
|
||||
c.updateAAD(AAD, 0, AAD.length);
|
||||
byte[] part51 = c.update(plainText, 0, plainText.length);
|
||||
byte[] part52 = c.doFinal();
|
||||
int part51Length = part51 != null ? part51.length : 0;
|
||||
byte[] outputText5 = new byte[part51Length + part52.length];
|
||||
if (part51 != null) {
|
||||
System.arraycopy(part51, 0, outputText5, 0, part51Length);
|
||||
}
|
||||
System.arraycopy(part52, 0, outputText5, part51Length, part52.length);
|
||||
results.add(outputText5);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #6:
|
||||
* updateAAD(byte[] src, int offset, int len)
|
||||
* updateAAD(byte[] src, int offset, int len)
|
||||
* update(byte[], int, int) doFinal(byte[], int, int, byte[], int)
|
||||
*/
|
||||
private void combination_6(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher c = createCipher(mode, params);
|
||||
c.updateAAD(AAD, 0, AAD.length / 2);
|
||||
c.updateAAD(AAD, AAD.length / 2, AAD.length - AAD.length / 2);
|
||||
int t = 0;
|
||||
int offset = 0;
|
||||
if (plainText.length > ARRAY_OFFSET) {
|
||||
t = plainText.length - ARRAY_OFFSET;
|
||||
offset = ARRAY_OFFSET;
|
||||
}
|
||||
byte[] part61 = c.update(plainText, 0, t);
|
||||
byte[] part62 = new byte[c.getOutputSize(plainText.length)];
|
||||
int len = c.doFinal(plainText, t, offset, part62, 0);
|
||||
int part61Length = part61 != null ? part61.length : 0;
|
||||
byte[] outputText6 = new byte[part61Length + len];
|
||||
if (part61 != null) {
|
||||
System.arraycopy(part61, 0, outputText6, 0, part61Length);
|
||||
}
|
||||
System.arraycopy(part62, 0, outputText6, part61Length, len);
|
||||
results.add(outputText6);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #7
|
||||
* updateAAD(byte[] src, int offset, int len)
|
||||
* updateAAD(byte[] src, src.length, 0)
|
||||
* update(byte[], int, int, byte[], int) doFinal(byte[],int, int)
|
||||
*/
|
||||
private void combination_7(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher ci = createCipher(mode, params);
|
||||
ci.updateAAD(AAD, 0, AAD.length);
|
||||
ci.updateAAD(AAD, AAD.length, 0);
|
||||
byte[] part71 = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
|
||||
int len = ci.update(plainText, 0, plainText.length - offset, part71, 0);
|
||||
byte[] part72 = ci.doFinal(plainText, plainText.length - offset, offset);
|
||||
byte[] outputText7 = new byte[len + part72.length];
|
||||
System.arraycopy(part71, 0, outputText7, 0, len);
|
||||
System.arraycopy(part72, 0, outputText7, len, part72.length);
|
||||
results.add(outputText7);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #8:
|
||||
* updateAAD(byte[] src, 0, 0)
|
||||
* updateAAD(byte[] src, 0, src.length)
|
||||
* update(byte[], int, int, byte[], int)
|
||||
* doFinal(byte[], int, int, byte[], int)
|
||||
*/
|
||||
private void combination_8(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher ci = createCipher(mode, params);
|
||||
ci.updateAAD(AAD, 0, 0);
|
||||
ci.updateAAD(AAD, 0, AAD.length);
|
||||
byte[] part81 = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
|
||||
int len = ci.update(plainText, 0, plainText.length - offset, part81, 0);
|
||||
int rest = ci.doFinal(plainText, plainText.length - offset, offset,
|
||||
part81, len);
|
||||
byte[] outputText8 = new byte[len + rest];
|
||||
System.arraycopy(part81, 0, outputText8, 0, outputText8.length);
|
||||
results.add(outputText8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #9:
|
||||
* updateAAD(ByteBuffer src)
|
||||
* update(byte[], int, int) doFinal(byte[], int, int)
|
||||
*/
|
||||
private void combination_9(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
|
||||
// prepare ByteBuffer to test
|
||||
ByteBuffer buf = ByteBuffer.allocate(AAD.length);
|
||||
buf.put(AAD);
|
||||
buf.position(0);
|
||||
buf.limit(AAD.length);
|
||||
|
||||
// Get Cipher object and do the combination
|
||||
Cipher c = createCipher(mode, params);
|
||||
c.updateAAD(buf);
|
||||
byte[] part91 = c.update(plainText, 0, plainText.length);
|
||||
int part91_length = part91 == null ? 0 : part91.length;
|
||||
byte[] part92 = c.doFinal();
|
||||
byte[] outputText9 = new byte[part91_length + part92.length];
|
||||
|
||||
// form result of the combination
|
||||
if (part91 != null) {
|
||||
System.arraycopy(part91, 0, outputText9, 0, part91_length);
|
||||
}
|
||||
System.arraycopy(part92, 0, outputText9, part91_length, part92.length);
|
||||
results.add(outputText9);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #10:
|
||||
* updateAAD(ByteBuffer src)
|
||||
* updateAAD(ByteBuffer src) update(byte[], int, int)
|
||||
* doFinal(byte[], int, int, byte[], int)
|
||||
*/
|
||||
private void combination_10(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
|
||||
// prepare ByteBuffer to test
|
||||
ByteBuffer buf = ByteBuffer.allocate(AAD.length);
|
||||
buf.put(AAD);
|
||||
buf.position(0);
|
||||
buf.limit(AAD.length / 2);
|
||||
|
||||
// get a Cipher object and do the combination
|
||||
Cipher c = createCipher(mode, params);
|
||||
|
||||
// process the first half of AAD data
|
||||
c.updateAAD(buf);
|
||||
|
||||
// process the rest of AAD data
|
||||
buf.limit(AAD.length);
|
||||
c.updateAAD(buf);
|
||||
|
||||
// prapare variables for the combination
|
||||
int t = 0;
|
||||
int offset = 0;
|
||||
if (plainText.length > ARRAY_OFFSET) {
|
||||
t = plainText.length - ARRAY_OFFSET;
|
||||
offset = ARRAY_OFFSET;
|
||||
}
|
||||
|
||||
// encrypt the text
|
||||
byte[] part10_1 = c.update(plainText, 0, t);
|
||||
int part10_1_Length = part10_1 != null ? part10_1.length : 0;
|
||||
byte[] part10_2 = new byte[c.getOutputSize(plainText.length)];
|
||||
int len2 = c.doFinal(plainText, t, offset, part10_2, 0);
|
||||
|
||||
// form the combination's result
|
||||
byte[] outputText10 = new byte[part10_1_Length + len2];
|
||||
if (part10_1 != null) {
|
||||
System.arraycopy(part10_1, 0, outputText10, 0, part10_1_Length);
|
||||
}
|
||||
System.arraycopy(part10_2, 0, outputText10, part10_1_Length, len2);
|
||||
results.add(outputText10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #11
|
||||
* updateAAD(ByteBuffer src1)
|
||||
* updateAAD(ByteBuffer src2)
|
||||
* update(byte[],int, int, byte[], int)
|
||||
* doFinal(byte[], int, int)
|
||||
*/
|
||||
private void combination_11(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
|
||||
// prepare ByteBuffer1 to test
|
||||
ByteBuffer buf1 = ByteBuffer.allocate(AAD.length / 2);
|
||||
buf1.put(AAD, 0, AAD.length / 2);
|
||||
buf1.position(0);
|
||||
buf1.limit(AAD.length / 2);
|
||||
|
||||
// get a Cipher object and do combination
|
||||
Cipher ci = createCipher(mode, params);
|
||||
|
||||
// process the first half of AAD data
|
||||
ci.updateAAD(buf1);
|
||||
|
||||
// prepare ByteBuffer2 to test
|
||||
ByteBuffer buf2 = ByteBuffer.allocate(AAD.length - AAD.length / 2);
|
||||
buf2.put(AAD, AAD.length / 2, AAD.length - AAD.length / 2);
|
||||
buf2.position(0);
|
||||
buf2.limit(AAD.length - AAD.length / 2);
|
||||
|
||||
// process the rest of AAD data
|
||||
ci.updateAAD(buf2);
|
||||
|
||||
// encrypt plain text
|
||||
byte[] part11_1 = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
|
||||
int len_11 = ci.update(plainText, 0, plainText.length - offset,
|
||||
part11_1, 0);
|
||||
byte[] part11_2 = ci.doFinal(plainText, plainText.length - offset,
|
||||
offset);
|
||||
byte[] outputText11 = new byte[len_11 + part11_2.length];
|
||||
System.arraycopy(part11_1, 0, outputText11, 0, len_11);
|
||||
System.arraycopy(part11_2, 0, outputText11, len_11, part11_2.length);
|
||||
results.add(outputText11);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #12:
|
||||
* updateAAD(ByteBuffer src)
|
||||
* updateAAD(ByteBuffer emptyByteBuffer)
|
||||
* update(byte[], int, int, byte[], int)
|
||||
* doFinal(byte[], int, int, byte[], int)
|
||||
*/
|
||||
private void combination_12(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
|
||||
// prepare ByteBuffer to test
|
||||
ByteBuffer buf = ByteBuffer.allocate(AAD.length);
|
||||
buf.put(AAD);
|
||||
buf.position(0);
|
||||
buf.limit(AAD.length);
|
||||
Cipher ci = createCipher(mode, params);
|
||||
ci.updateAAD(buf);
|
||||
|
||||
// prepare an empty ByteBuffer
|
||||
ByteBuffer emptyBuf = ByteBuffer.allocate(0);
|
||||
emptyBuf.put(new byte[0]);
|
||||
ci.updateAAD(emptyBuf);
|
||||
byte[] part12_1 = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = plainText.length > ARRAY_OFFSET ? ARRAY_OFFSET : 0;
|
||||
int len12 = ci.update(plainText, 0, plainText.length - offset,
|
||||
part12_1, 0);
|
||||
int rest12 = ci.doFinal(plainText, plainText.length - offset, offset,
|
||||
part12_1, len12);
|
||||
byte[] outputText12 = new byte[len12 + rest12];
|
||||
System.arraycopy(part12_1, 0, outputText12, 0, outputText12.length);
|
||||
results.add(outputText12);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #13:
|
||||
* updateAAD(ByteBuffer src), where src is directly allocated
|
||||
* update(ByteBuffer input, ByteBuffer out)
|
||||
* doFinal(ByteBuffer input, ByteBuffer out)
|
||||
*/
|
||||
private void combination_13(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher c = createCipher(mode, params);
|
||||
|
||||
// prepare ByteBuffer to test
|
||||
ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length);
|
||||
buf.put(AAD);
|
||||
buf.position(0);
|
||||
buf.limit(AAD.length);
|
||||
c.updateAAD(buf);
|
||||
|
||||
// prepare buffers to encrypt/decrypt
|
||||
ByteBuffer in = ByteBuffer.allocateDirect(plainText.length);
|
||||
in.put(plainText);
|
||||
in.position(0);
|
||||
in.limit(plainText.length);
|
||||
ByteBuffer output = ByteBuffer.allocateDirect(
|
||||
c.getOutputSize(in.limit()));
|
||||
output.position(0);
|
||||
output.limit(c.getOutputSize(in.limit()));
|
||||
|
||||
// process input text
|
||||
c.update(in, output);
|
||||
c.doFinal(in, output);
|
||||
int resultSize = output.position();
|
||||
byte[] result13 = new byte[resultSize];
|
||||
output.position(0);
|
||||
output.limit(resultSize);
|
||||
output.get(result13, 0, resultSize);
|
||||
results.add(result13);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #14:
|
||||
* updateAAD(ByteBuffer src) updateAAD(ByteBuffer src),
|
||||
* where src is directly allocated
|
||||
* update(ByteBuffer input, ByteBuffer out)
|
||||
* doFinal(ByteBuffer input, ByteBuffer out)
|
||||
*/
|
||||
private void combination_14(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher c = createCipher(mode, params);
|
||||
// prepare ByteBuffer to test
|
||||
ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length);
|
||||
buf.put(AAD);
|
||||
|
||||
// process the first half of AAD data
|
||||
buf.position(0);
|
||||
buf.limit(AAD.length / 2);
|
||||
c.updateAAD(buf);
|
||||
|
||||
// process the rest of AAD data
|
||||
buf.limit(AAD.length);
|
||||
c.updateAAD(buf);
|
||||
|
||||
// prepare buffers to encrypt/decrypt
|
||||
ByteBuffer in = ByteBuffer.allocate(plainText.length);
|
||||
in.put(plainText);
|
||||
in.position(0);
|
||||
in.limit(plainText.length);
|
||||
ByteBuffer out = ByteBuffer.allocate(c.getOutputSize(in.limit()));
|
||||
out.position(0);
|
||||
out.limit(c.getOutputSize(in.limit()));
|
||||
|
||||
// process input text
|
||||
c.update(in, out);
|
||||
c.doFinal(in, out);
|
||||
int resultSize = out.position();
|
||||
byte[] result14 = new byte[resultSize];
|
||||
out.position(0);
|
||||
out.limit(resultSize);
|
||||
out.get(result14, 0, resultSize);
|
||||
results.add(result14);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #15
|
||||
* updateAAD(ByteBuffer src1), where src1 is directly allocated
|
||||
* updateAAD(ByteBuffer src2), where src2 is directly allocated
|
||||
* doFinal(ByteBuffer input, ByteBuffer out)
|
||||
*/
|
||||
private void combination_15(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher c = createCipher(mode, params);
|
||||
|
||||
// prepare ByteBuffer1 to test
|
||||
ByteBuffer buf1 = ByteBuffer.allocateDirect(AAD.length / 2);
|
||||
buf1.put(AAD, 0, AAD.length / 2);
|
||||
buf1.position(0);
|
||||
buf1.limit(AAD.length / 2);
|
||||
|
||||
// process the first half of AAD data
|
||||
c.updateAAD(buf1);
|
||||
|
||||
// prepare ByteBuffer2 to test
|
||||
ByteBuffer buf2 = ByteBuffer.allocateDirect(
|
||||
AAD.length - AAD.length / 2);
|
||||
buf2.put(AAD, AAD.length / 2, AAD.length - AAD.length / 2);
|
||||
buf2.position(0);
|
||||
buf2.limit(AAD.length - AAD.length / 2);
|
||||
|
||||
// process the rest of AAD data
|
||||
c.updateAAD(buf2);
|
||||
|
||||
// prepare buffers to encrypt/decrypt
|
||||
ByteBuffer in = ByteBuffer.allocateDirect(plainText.length);
|
||||
in.put(plainText);
|
||||
in.position(0);
|
||||
in.limit(plainText.length);
|
||||
ByteBuffer output = ByteBuffer.allocateDirect(
|
||||
c.getOutputSize(in.limit()));
|
||||
output.position(0);
|
||||
output.limit(c.getOutputSize(in.limit()));
|
||||
|
||||
// process input text
|
||||
c.doFinal(in, output);
|
||||
int resultSize = output.position();
|
||||
byte[] result15 = new byte[resultSize];
|
||||
output.position(0);
|
||||
output.limit(resultSize);
|
||||
output.get(result15, 0, resultSize);
|
||||
results.add(result15);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute multiple-part encryption/decryption combination #16:
|
||||
* updateAAD(ByteBuffer src)
|
||||
* updateAAD(ByteBuffer emptyByteBuffer)
|
||||
* update(ByteBuffer input, ByteBuffer out)
|
||||
* doFinal(EmptyByteBuffer, ByteBuffer out)
|
||||
*/
|
||||
private void combination_16(List<byte[]> results, int mode, byte[] AAD,
|
||||
byte[] plainText, AlgorithmParameters params) throws Exception {
|
||||
Cipher c = createCipher(mode, params);
|
||||
|
||||
// prepare ByteBuffer to test
|
||||
ByteBuffer buf = ByteBuffer.allocateDirect(AAD.length);
|
||||
buf.put(AAD);
|
||||
buf.position(0);
|
||||
buf.limit(AAD.length);
|
||||
c.updateAAD(buf);
|
||||
|
||||
// prepare empty ByteBuffer
|
||||
ByteBuffer emptyBuf = ByteBuffer.allocateDirect(0);
|
||||
emptyBuf.put(new byte[0]);
|
||||
c.updateAAD(emptyBuf);
|
||||
|
||||
// prepare buffers to encrypt/decrypt
|
||||
ByteBuffer in = ByteBuffer.allocateDirect(plainText.length);
|
||||
in.put(plainText);
|
||||
in.position(0);
|
||||
in.limit(plainText.length);
|
||||
ByteBuffer output = ByteBuffer.allocateDirect(
|
||||
c.getOutputSize(in.limit()));
|
||||
output.position(0);
|
||||
output.limit(c.getOutputSize(in.limit()));
|
||||
|
||||
// process input text with an empty buffer
|
||||
c.update(in, output);
|
||||
ByteBuffer emptyBuf2 = ByteBuffer.allocate(0);
|
||||
emptyBuf2.put(new byte[0]);
|
||||
c.doFinal(emptyBuf2, output);
|
||||
int resultSize = output.position();
|
||||
byte[] result16 = new byte[resultSize];
|
||||
output.position(0);
|
||||
output.limit(resultSize);
|
||||
output.get(result16, 0, resultSize);
|
||||
results.add(result16);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 2024, 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 java.util.List;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Uses AEADBufferTest to run a long test with incrementing through
|
||||
* each byte in each byte array using AES GCM
|
||||
* @run main/manual GCMIncrementByte4
|
||||
*/
|
||||
|
||||
public class GCMIncrementByte4 {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
AEADBufferTest.initTest();
|
||||
new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(AEADBufferTest.dtype.BYTE, AEADBufferTest.dtype.BYTE,
|
||||
AEADBufferTest.dtype.BYTE)).incrementalSegments().dataSet(4).
|
||||
test();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 2024, 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 java.util.List;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Uses AEADBufferTest to run a long test with incrementing through
|
||||
* each byte in each direct bytebuffer using AES GCM
|
||||
* @run main/manual GCMIncrementDirect4
|
||||
*/
|
||||
|
||||
public class GCMIncrementDirect4 {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
AEADBufferTest.initTest();
|
||||
new AEADBufferTest("AES/GCM/NoPadding",
|
||||
List.of(AEADBufferTest.dtype.DIRECT, AEADBufferTest.dtype.DIRECT,
|
||||
AEADBufferTest.dtype.DIRECT)).incrementalSegments().dataSet(4).
|
||||
test();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2024, 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",
|
||||
System.getProperty("test.provider.name", "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",
|
||||
System.getProperty("test.provider.name", "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);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048596
|
||||
* @summary Check if GCMParameterSpec works as expected
|
||||
*/
|
||||
public class GCMParameterSpecTest {
|
||||
|
||||
private static final int[] IV_LENGTHS = { 96, 8, 1024 };
|
||||
private static final int[] KEY_LENGTHS = { 128, 192, 256 };
|
||||
private static final int[] DATA_LENGTHS = { 0, 128, 1024 };
|
||||
private static final int[] AAD_LENGTHS = { 0, 128, 1024 };
|
||||
private static final int[] TAG_LENGTHS = { 128, 120, 112, 104, 96 };
|
||||
private static final int[] OFFSETS = { 0, 2, 5, 99 };
|
||||
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
|
||||
private static final String TEMPLATE = "Test:\n tag = %d\n"
|
||||
+ " IV length = %d\n data length = %d\n"
|
||||
+ " AAD length = %d\n offset = %d\n keylength = %d\n";
|
||||
|
||||
private final byte[] IV;
|
||||
private final byte[] IVO;
|
||||
private final byte[] data;
|
||||
private final byte[] AAD;
|
||||
private final SecretKey key;
|
||||
private final int tagLength;
|
||||
private final int IVlength;
|
||||
private final int offset;
|
||||
|
||||
/**
|
||||
* Initialize IV, IV with offset, plain text, AAD and SecretKey
|
||||
*
|
||||
* @param keyLength length of a secret key
|
||||
* @param tagLength tag length
|
||||
* @param IVlength IV length
|
||||
* @param offset offset in a buffer for IV
|
||||
* @param textLength plain text length
|
||||
* @param AADLength AAD length
|
||||
*/
|
||||
public GCMParameterSpecTest(int keyLength, int tagLength, int IVlength,
|
||||
int offset, int textLength, int AADLength)
|
||||
throws NoSuchAlgorithmException, NoSuchProviderException {
|
||||
this.tagLength = tagLength; // save tag length
|
||||
this.IVlength = IVlength; // save IV length
|
||||
this.offset = offset; // save IV offset
|
||||
|
||||
// prepare IV
|
||||
IV = Helper.generateBytes(IVlength);
|
||||
|
||||
// prepare IV with offset
|
||||
IVO = new byte[this.IVlength + this.offset];
|
||||
System.arraycopy(IV, 0, IVO, offset, this.IVlength);
|
||||
|
||||
// prepare data
|
||||
data = Helper.generateBytes(textLength);
|
||||
|
||||
// prepare AAD
|
||||
AAD = Helper.generateBytes(AADLength);
|
||||
|
||||
// init a secret key
|
||||
KeyGenerator kg = KeyGenerator.getInstance("AES",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
kg.init(keyLength);
|
||||
key = kg.generateKey();
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the test for each key length, tag length, IV length, plain text
|
||||
* length, AAD length and offset.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
boolean success = true;
|
||||
for (int k : KEY_LENGTHS) {
|
||||
if (k > Cipher.getMaxAllowedKeyLength(TRANSFORMATION)) {
|
||||
// skip this if this key length is larger than what's
|
||||
// allowed in the jce jurisdiction policy files
|
||||
continue;
|
||||
}
|
||||
for (int t : TAG_LENGTHS) {
|
||||
for (int n : IV_LENGTHS) {
|
||||
for (int p : DATA_LENGTHS) {
|
||||
for (int a : AAD_LENGTHS) {
|
||||
for (int o : OFFSETS) {
|
||||
System.out.printf(TEMPLATE, t, n, p, a, o, k);
|
||||
success &= new GCMParameterSpecTest(
|
||||
k, t, n, o, p, a).doTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
throw new RuntimeException("At least one test case failed");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the test:
|
||||
* - check if result of encryption of plain text is the same
|
||||
* when parameters constructed with different GCMParameterSpec
|
||||
* constructors are used
|
||||
* - check if GCMParameterSpec.getTLen() is equal to actual tag length
|
||||
* - check if ciphertext has the same length as plaintext
|
||||
*/
|
||||
private boolean doTest() throws Exception {
|
||||
GCMParameterSpec spec1 = new GCMParameterSpec(tagLength, IV);
|
||||
GCMParameterSpec spec2 = new GCMParameterSpec(tagLength, IVO, offset,
|
||||
IVlength);
|
||||
byte[] cipherText1 = getCipherTextBySpec(spec1);
|
||||
if (cipherText1 == null) {
|
||||
return false;
|
||||
}
|
||||
byte[] cipherText2 = getCipherTextBySpec(spec2);
|
||||
if (cipherText2 == null) {
|
||||
return false;
|
||||
}
|
||||
if (!Arrays.equals(cipherText1, cipherText2)) {
|
||||
System.out.println("Cipher texts are different");
|
||||
return false;
|
||||
}
|
||||
if (spec1.getTLen() != spec2.getTLen()) {
|
||||
System.out.println("Tag lengths are not equal");
|
||||
return false;
|
||||
}
|
||||
byte[] recoveredText1 = recoverCipherText(cipherText1, spec2);
|
||||
if (recoveredText1 == null) {
|
||||
return false;
|
||||
}
|
||||
byte[] recoveredText2 = recoverCipherText(cipherText2, spec1);
|
||||
if (recoveredText2 == null) {
|
||||
return false;
|
||||
}
|
||||
if (!Arrays.equals(recoveredText1, recoveredText2)) {
|
||||
System.out.println("Recovered texts are different");
|
||||
return false;
|
||||
}
|
||||
if (!Arrays.equals(recoveredText1, data)) {
|
||||
System.out.println("Recovered and original texts are not equal");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypt a plain text, and check if GCMParameterSpec.getIV()
|
||||
* is equal to Cipher.getIV()
|
||||
*/
|
||||
private byte[] getCipherTextBySpec(GCMParameterSpec spec) throws Exception {
|
||||
// init a cipher
|
||||
Cipher cipher = createCipher(Cipher.ENCRYPT_MODE, spec);
|
||||
cipher.updateAAD(AAD);
|
||||
byte[] cipherText = cipher.doFinal(data);
|
||||
|
||||
// check IVs
|
||||
if (!Arrays.equals(cipher.getIV(), spec.getIV())) {
|
||||
System.out.println("IV in parameters is incorrect");
|
||||
return null;
|
||||
}
|
||||
if (spec.getTLen() != (cipherText.length - data.length) * 8) {
|
||||
System.out.println("Tag length is incorrect");
|
||||
return null;
|
||||
}
|
||||
return cipherText;
|
||||
}
|
||||
|
||||
private byte[] recoverCipherText(byte[] cipherText, GCMParameterSpec spec)
|
||||
throws Exception {
|
||||
// init a cipher
|
||||
Cipher cipher = createCipher(Cipher.DECRYPT_MODE, spec);
|
||||
|
||||
// check IVs
|
||||
if (!Arrays.equals(cipher.getIV(), spec.getIV())) {
|
||||
System.out.println("IV in parameters is incorrect");
|
||||
return null;
|
||||
}
|
||||
|
||||
cipher.updateAAD(AAD);
|
||||
return cipher.doFinal(cipherText);
|
||||
}
|
||||
|
||||
private Cipher createCipher(int mode, GCMParameterSpec spec)
|
||||
throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(TRANSFORMATION,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
cipher.init(mode, key, spec);
|
||||
return cipher;
|
||||
}
|
||||
}
|
||||
123
test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortBuffer.java
Normal file
123
test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMShortBuffer.java
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 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.ShortBufferException;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.HexFormat;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Call decrypt doFinal() with different output values to see if the
|
||||
* the operation can complete after a ShortBufferException
|
||||
*/
|
||||
public class GCMShortBuffer {
|
||||
static Cipher c;
|
||||
static final GCMParameterSpec iv = new GCMParameterSpec(128, new byte[16]);
|
||||
static final SecretKeySpec keySpec = new SecretKeySpec(new byte[16], "AES");
|
||||
static byte cipherText[], plaintext[] = new byte[51];
|
||||
boolean error = false;
|
||||
|
||||
GCMShortBuffer(byte[] out) throws Exception {
|
||||
int len = cipherText.length - 1;
|
||||
|
||||
c.init(Cipher.DECRYPT_MODE, keySpec, iv);
|
||||
byte[] pt = new byte[c.getOutputSize(cipherText.length)];
|
||||
c.update(cipherText, 0, 1);
|
||||
try {
|
||||
c.doFinal(cipherText, 1, len, out, 0);
|
||||
} catch (ShortBufferException e) {
|
||||
System.out.println("ShortBuffer caught");
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
int r = c.doFinal(cipherText, 1, len, pt, 0);
|
||||
if (r != pt.length) {
|
||||
System.out.println(
|
||||
"doFinal() return ( " + r + ") is not the same " +
|
||||
"as getOutputSize returned" + pt.length);
|
||||
error = true;
|
||||
}
|
||||
if (Arrays.compare(pt, plaintext) != 0) {
|
||||
System.out.println("output : " + HexFormat.of().formatHex(pt));
|
||||
System.out.println("expected: " +
|
||||
HexFormat.of().formatHex(plaintext));
|
||||
System.out.println("output and plaintext do not match");
|
||||
error = true;
|
||||
}
|
||||
if (error) {
|
||||
throw new Exception("An error has occurred");
|
||||
}
|
||||
}
|
||||
|
||||
GCMShortBuffer(ByteBuffer dst) throws Exception {
|
||||
int len = cipherText.length - 1;
|
||||
ByteBuffer out = ByteBuffer.allocate(plaintext.length);
|
||||
|
||||
c.init(Cipher.DECRYPT_MODE, keySpec, iv);
|
||||
c.update(cipherText, 0, 1);
|
||||
ByteBuffer ct = ByteBuffer.wrap(cipherText, 1, len);
|
||||
try {
|
||||
c.doFinal(ct , dst);
|
||||
} catch (ShortBufferException e) {
|
||||
System.out.println("ShortBuffer caught");
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
int r = c.doFinal(ByteBuffer.wrap(cipherText, 1, len), out);
|
||||
out.flip();
|
||||
if (r != out.capacity()) {
|
||||
System.out.println(
|
||||
"doFinal() return ( " + r + ") is not the same" +
|
||||
" as getOutputSize returned" + out.capacity());
|
||||
error = true;
|
||||
}
|
||||
if (out.compareTo(ByteBuffer.wrap(plaintext)) != 0) {
|
||||
System.out.println("output and plaintext do not match");
|
||||
System.out.println("output : " +
|
||||
HexFormat.of().formatHex(out.array()));
|
||||
System.out.println("expected: " +
|
||||
HexFormat.of().formatHex(plaintext));
|
||||
error = true;
|
||||
}
|
||||
if (error) {
|
||||
throw new Exception("An error has occurred");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
c = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
c.init(Cipher.ENCRYPT_MODE, keySpec, iv);
|
||||
cipherText = c.doFinal(plaintext);
|
||||
|
||||
new GCMShortBuffer(new byte[13]);
|
||||
new GCMShortBuffer(new byte[50]);
|
||||
new GCMShortBuffer(ByteBuffer.allocate(13));
|
||||
new GCMShortBuffer(ByteBuffer.allocate(50));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Alphabet LLC. 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 8314045
|
||||
* @summary ArithmeticException in GaloisCounterMode
|
||||
*/
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.crypto.AEADBadTagException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class GCMShortInput {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
SecretKeySpec keySpec =
|
||||
new SecretKeySpec(
|
||||
new byte[] {
|
||||
88, 26, 43, -100, -24, -29, -70, 10, 34, -85, 52, 101, 45, -68, -105,
|
||||
-123
|
||||
},
|
||||
"AES");
|
||||
GCMParameterSpec params =
|
||||
new GCMParameterSpec(8 * 16, new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
|
||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, keySpec, params);
|
||||
try {
|
||||
cipher.doFinal(ByteBuffer.allocate(0), ByteBuffer.allocate(0));
|
||||
throw new AssertionError("AEADBadTagException expected");
|
||||
} catch (AEADBadTagException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
}
|
||||
33
test/jdk/com/sun/crypto/provider/Cipher/AEAD/Helper.java
Normal file
33
test/jdk/com/sun/crypto/provider/Cipher/AEAD/Helper.java
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
|
||||
public class Helper {
|
||||
|
||||
public static byte[] generateBytes(int length) {
|
||||
byte[] bytes = new byte[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
bytes[i] = (byte) (i % 256);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
87
test/jdk/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java
Normal file
87
test/jdk/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 java.security.AlgorithmParameters;
|
||||
import java.security.Key;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048596
|
||||
* @summary Check if a key wrapper works properly with GCM mode
|
||||
*/
|
||||
public class KeyWrapper {
|
||||
|
||||
static final String AES = "AES";
|
||||
static final String TRANSFORMATION = "AES/GCM/NoPadding";
|
||||
static final String PROVIDER = System.getProperty("test.provider.name", "SunJCE");
|
||||
static final int KEY_LENGTH = 128;
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
doTest(PROVIDER, TRANSFORMATION);
|
||||
}
|
||||
|
||||
private static void doTest(String provider, String algo) throws Exception {
|
||||
SecretKey key;
|
||||
SecretKey keyToWrap;
|
||||
|
||||
// init a secret Key
|
||||
KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER);
|
||||
kg.init(KEY_LENGTH);
|
||||
key = kg.generateKey();
|
||||
keyToWrap = kg.generateKey();
|
||||
|
||||
// initialization
|
||||
Cipher cipher = Cipher.getInstance(algo, provider);
|
||||
cipher.init(Cipher.WRAP_MODE, key);
|
||||
AlgorithmParameters params = cipher.getParameters();
|
||||
|
||||
// wrap the key
|
||||
byte[] keyWrapper = cipher.wrap(keyToWrap);
|
||||
try {
|
||||
// check if we can't wrap it again with the same key/IV
|
||||
keyWrapper = cipher.wrap(keyToWrap);
|
||||
throw new RuntimeException(
|
||||
"FAILED: expected IllegalStateException hasn't "
|
||||
+ "been thrown ");
|
||||
} catch (IllegalStateException ise) {
|
||||
System.out.println(ise.getMessage());
|
||||
System.out.println("Expected exception");
|
||||
}
|
||||
|
||||
// unwrap the key
|
||||
cipher.init(Cipher.UNWRAP_MODE, key, params);
|
||||
cipher.unwrap(keyWrapper, algo, Cipher.SECRET_KEY);
|
||||
|
||||
// check if we can unwrap second time
|
||||
Key unwrapKey = cipher.unwrap(keyWrapper, algo, Cipher.SECRET_KEY);
|
||||
|
||||
if (!Arrays.equals(keyToWrap.getEncoded(), unwrapKey.getEncoded())) {
|
||||
throw new RuntimeException(
|
||||
"FAILED: original and unwrapped keys are not equal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 2024, 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.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary This tests overlapping buffers using ByteBuffer.slice() with
|
||||
* array-backed ByteBuffer, read only array-backed, ByteBuffer, and direct
|
||||
* ByteBuffer.
|
||||
* @run main OverlapByteBuffer AES/GCM/NoPadding
|
||||
* @run main OverlapByteBuffer ChaCha20-Poly1305
|
||||
*/
|
||||
|
||||
/*
|
||||
* This tests overlapping buffers created with ByteBuffer.slice(). That is
|
||||
* when the input and output ByteBuffers have shared memory (use the same
|
||||
* underlying buffer space, commonly used for in-place crypto). The
|
||||
* complication is the Cipher object specifies that it must be copy-safe. That
|
||||
* means the output buffer will not overwrite any input data that has not been
|
||||
* processed. If the output buffer's position or offset is greater than the
|
||||
* input's overwriting will occur.
|
||||
*/
|
||||
|
||||
public class OverlapByteBuffer {
|
||||
|
||||
byte[] baseBuf = new byte[8192];
|
||||
ByteBuffer output, input, in;
|
||||
int outOfs;
|
||||
String algorithm;
|
||||
SecretKeySpec key;
|
||||
AlgorithmParameterSpec params;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new OverlapByteBuffer(args[0]).test();
|
||||
}
|
||||
|
||||
OverlapByteBuffer(String algorithm) throws Exception {
|
||||
this.algorithm = algorithm;
|
||||
switch (algorithm) {
|
||||
case "AES/GCM/NoPadding" -> {
|
||||
params = new GCMParameterSpec(128, new byte[12]);
|
||||
key = new SecretKeySpec(new byte[16], "AES");
|
||||
}
|
||||
case "ChaCha20-Poly1305" -> {
|
||||
params = new IvParameterSpec(new byte[12]);
|
||||
key = new SecretKeySpec(new byte[32], "");
|
||||
}
|
||||
default -> throw new Exception("unknown algorithm: " + algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
void test() throws Exception {
|
||||
// Output offset from the baseBuf
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (outOfs = -1; outOfs <= 1; outOfs++) {
|
||||
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, params);
|
||||
|
||||
// Offset on the particular ByteBuffer (aka position())
|
||||
int inOfsInBuf = 1;
|
||||
int outOfsInBuf = inOfsInBuf + outOfs;
|
||||
int sliceLen = cipher.getOutputSize(baseBuf.length);
|
||||
int bufferSize = sliceLen + Math.max(inOfsInBuf, outOfsInBuf);
|
||||
byte[] buffer;
|
||||
// Create overlapping input and output buffers
|
||||
switch (i) {
|
||||
case 0 -> {
|
||||
buffer = new byte[bufferSize];
|
||||
output = ByteBuffer.wrap(buffer, outOfsInBuf, sliceLen).
|
||||
slice();
|
||||
input = ByteBuffer.wrap(buffer, inOfsInBuf, sliceLen).
|
||||
slice();
|
||||
System.out.println("Using array-backed ByteBuffer");
|
||||
in = input.duplicate();
|
||||
}
|
||||
case 1 -> {
|
||||
buffer = new byte[bufferSize];
|
||||
output = ByteBuffer.wrap(buffer, outOfsInBuf, sliceLen).
|
||||
slice();
|
||||
input = ByteBuffer.wrap(buffer, inOfsInBuf, sliceLen).
|
||||
slice();
|
||||
|
||||
System.out.println("Using read-only array-backed " +
|
||||
"ByteBuffer");
|
||||
in = input.asReadOnlyBuffer();
|
||||
}
|
||||
case 2 -> {
|
||||
System.out.println("Using direct ByteBuffer");
|
||||
ByteBuffer buf = ByteBuffer.allocateDirect(bufferSize);
|
||||
output = buf.duplicate();
|
||||
output.position(outOfsInBuf);
|
||||
output.limit(sliceLen + outOfsInBuf);
|
||||
output = output.slice();
|
||||
|
||||
input = buf.duplicate();
|
||||
input.position(inOfsInBuf);
|
||||
input.limit(sliceLen + inOfsInBuf);
|
||||
input = input.slice();
|
||||
|
||||
in = input.duplicate();
|
||||
}
|
||||
default -> throw new Exception("Unknown index " + i);
|
||||
}
|
||||
|
||||
System.out.println("inOfsInBuf = " + inOfsInBuf);
|
||||
System.out.println("outOfsInBuf = " + outOfsInBuf);
|
||||
|
||||
// Copy data into shared buffer
|
||||
input.put(baseBuf);
|
||||
input.flip();
|
||||
in.limit(input.limit());
|
||||
|
||||
try {
|
||||
int ctSize = cipher.doFinal(in, output);
|
||||
|
||||
// Get ready to decrypt
|
||||
byte[] tmp = new byte[ctSize];
|
||||
output.flip();
|
||||
output.get(tmp);
|
||||
output.clear();
|
||||
|
||||
input.clear();
|
||||
input.put(tmp);
|
||||
input.flip();
|
||||
|
||||
in.clear();
|
||||
in.limit(input.limit());
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, params);
|
||||
cipher.doFinal(in, output);
|
||||
|
||||
output.flip();
|
||||
ByteBuffer b = ByteBuffer.wrap(baseBuf);
|
||||
if (b.compareTo(output) != 0) {
|
||||
System.err.println(
|
||||
"\nresult (" + output + "):\n" +
|
||||
byteToHex(output) +
|
||||
"\nexpected (" + b + "):\n" +
|
||||
byteToHex(b));
|
||||
throw new Exception("Mismatch");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new Exception("Error with base offset " + outOfs, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private static String byteToHex(ByteBuffer bb) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
while (bb.remaining() > 0) {
|
||||
s.append(String.format("%02x", bb.get()));
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
317
test/jdk/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java
Normal file
317
test/jdk/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048596
|
||||
* @summary Test CICO AEAD read/write/skip operations
|
||||
*/
|
||||
public class ReadWriteSkip {
|
||||
|
||||
static enum BufferType {
|
||||
BYTE_ARRAY_BUFFERING, INT_BYTE_BUFFERING
|
||||
}
|
||||
|
||||
static final int KEY_LENGTHS[] = {128, 192, 256};
|
||||
static final int TXT_LENGTHS[] = {800, 0};
|
||||
static final int AAD_LENGTHS[] = {0, 100};
|
||||
static final int BLOCK = 50;
|
||||
static final int SAVE = 45;
|
||||
static final int DISCARD = BLOCK - SAVE;
|
||||
static final String PROVIDER = System.getProperty("test.provider.name", "SunJCE");
|
||||
static final String AES = "AES";
|
||||
static final String GCM = "GCM";
|
||||
static final String PADDING = "NoPadding";
|
||||
static final String TRANSFORM = AES + "/" + GCM + "/" + PADDING;
|
||||
|
||||
final SecretKey key;
|
||||
final byte[] plaintext;
|
||||
final byte[] AAD;
|
||||
final int textLength;;
|
||||
final int keyLength;
|
||||
Cipher encryptCipher;
|
||||
Cipher decryptCipher;
|
||||
CipherInputStream ciInput;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
boolean success = true;
|
||||
for (int keyLength : KEY_LENGTHS) {
|
||||
if (keyLength > Cipher.getMaxAllowedKeyLength(TRANSFORM)) {
|
||||
// skip this if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
continue;
|
||||
}
|
||||
for (int textLength : TXT_LENGTHS) {
|
||||
for (int AADLength : AAD_LENGTHS) {
|
||||
System.out.println("Key length = " + keyLength
|
||||
+ ", text length = " + textLength
|
||||
+ ", AAD length = " + AADLength);
|
||||
try {
|
||||
run(keyLength, textLength, AADLength);
|
||||
System.out.println("Test case passed");
|
||||
} catch (Exception e) {
|
||||
System.out.println("Test case failed: " + e);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
throw new RuntimeException("At least one test case failed");
|
||||
}
|
||||
|
||||
System.out.println("Test passed");
|
||||
}
|
||||
|
||||
ReadWriteSkip(int keyLength, int textLength, int AADLength)
|
||||
throws Exception {
|
||||
this.keyLength = keyLength;
|
||||
this.textLength = textLength;
|
||||
|
||||
// init AAD
|
||||
this.AAD = Helper.generateBytes(AADLength);
|
||||
|
||||
// init a secret Key
|
||||
KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER);
|
||||
kg.init(this.keyLength);
|
||||
this.key = kg.generateKey();
|
||||
|
||||
this.plaintext = Helper.generateBytes(textLength);
|
||||
}
|
||||
|
||||
final void doTest(BufferType type) throws Exception {
|
||||
// init ciphers
|
||||
encryptCipher = createCipher(Cipher.ENCRYPT_MODE);
|
||||
decryptCipher = createCipher(Cipher.DECRYPT_MODE);
|
||||
|
||||
// init cipher input stream
|
||||
ciInput = new CipherInputStream(new ByteArrayInputStream(plaintext),
|
||||
encryptCipher);
|
||||
|
||||
runTest(type);
|
||||
}
|
||||
|
||||
void runTest(BufferType type) throws Exception {}
|
||||
|
||||
private Cipher createCipher(int mode) throws GeneralSecurityException {
|
||||
Cipher cipher = Cipher.getInstance(TRANSFORM, PROVIDER);
|
||||
if (mode == Cipher.ENCRYPT_MODE) {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
} else {
|
||||
if (encryptCipher != null) {
|
||||
cipher.init(Cipher.DECRYPT_MODE, key,
|
||||
encryptCipher.getParameters());
|
||||
} else {
|
||||
throw new RuntimeException("Can't create a cipher");
|
||||
}
|
||||
}
|
||||
cipher.updateAAD(AAD);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run test cases
|
||||
*/
|
||||
static void run(int keyLength, int textLength, int AADLength)
|
||||
throws Exception {
|
||||
new ReadWriteTest(keyLength, textLength, AADLength)
|
||||
.doTest(BufferType.BYTE_ARRAY_BUFFERING);
|
||||
new ReadWriteTest(keyLength, textLength, AADLength)
|
||||
.doTest(BufferType.INT_BYTE_BUFFERING);
|
||||
new SkipTest(keyLength, textLength, AADLength)
|
||||
.doTest(BufferType.BYTE_ARRAY_BUFFERING);
|
||||
new SkipTest(keyLength, textLength, AADLength)
|
||||
.doTest(BufferType.INT_BYTE_BUFFERING);
|
||||
}
|
||||
|
||||
static void check(byte[] first, byte[] second) {
|
||||
if (!Arrays.equals(first, second)) {
|
||||
throw new RuntimeException("Arrays are not equal");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* CICO AEAD read/write functional test.
|
||||
*
|
||||
* Check if encrypt/decrypt operations work correctly.
|
||||
*
|
||||
* Test scenario:
|
||||
* - initializes plain text
|
||||
* - for given AEAD algorithm instantiates encrypt and decrypt Ciphers
|
||||
* - instantiates CipherInputStream with the encrypt Cipher
|
||||
* - instantiates CipherOutputStream with the decrypt Cipher
|
||||
* - performs reading from the CipherInputStream (encryption data)
|
||||
* and writing to the CipherOutputStream (decryption). As a result,
|
||||
* output of the CipherOutputStream should be equal
|
||||
* with original plain text
|
||||
* - check if the original plain text is equal to output
|
||||
* of the CipherOutputStream
|
||||
* - if it is equal the test passes, otherwise it fails
|
||||
*/
|
||||
static class ReadWriteTest extends ReadWriteSkip {
|
||||
|
||||
public ReadWriteTest(int keyLength, int textLength, int AADLength)
|
||||
throws Exception {
|
||||
super(keyLength, textLength, AADLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTest(BufferType bufType) throws IOException,
|
||||
GeneralSecurityException {
|
||||
|
||||
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
|
||||
try (CipherOutputStream ciOutput = new CipherOutputStream(baOutput,
|
||||
decryptCipher)) {
|
||||
if (bufType == BufferType.BYTE_ARRAY_BUFFERING) {
|
||||
doByteTest(ciOutput);
|
||||
} else {
|
||||
doIntTest(ciOutput);
|
||||
}
|
||||
}
|
||||
|
||||
check(plaintext, baOutput.toByteArray());
|
||||
}
|
||||
|
||||
/*
|
||||
* Implements byte array buffering type test case
|
||||
*/
|
||||
public void doByteTest(CipherOutputStream out) throws IOException {
|
||||
byte[] buffer = Helper.generateBytes(textLength + 1);
|
||||
int len = ciInput.read(buffer);
|
||||
while (len != -1) {
|
||||
out.write(buffer, 0, len);
|
||||
len = ciInput.read(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Implements integer buffering type test case
|
||||
*/
|
||||
public void doIntTest(CipherOutputStream out) throws IOException {
|
||||
int buffer = ciInput.read();
|
||||
while (buffer != -1) {
|
||||
out.write(buffer);
|
||||
buffer = ciInput.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* CICO AEAD SKIP functional test.
|
||||
*
|
||||
* Checks if the encrypt/decrypt operations work correctly
|
||||
* when skip() method is used.
|
||||
*
|
||||
* Test scenario:
|
||||
* - initializes a plain text
|
||||
* - initializes ciphers
|
||||
* - initializes cipher streams
|
||||
* - split plain text to TEXT_SIZE/BLOCK blocks
|
||||
* - read from CipherInputStream2 one block at time
|
||||
* - the last DISCARD = BLOCK - SAVE bytes are skipping for each block
|
||||
* - therefore, plain text data go through CipherInputStream1 (encrypting)
|
||||
* and CipherInputStream2 (decrypting)
|
||||
* - as a result, output should equal to the original text
|
||||
* except DISCART byte for each block
|
||||
* - check result buffers
|
||||
*/
|
||||
static class SkipTest extends ReadWriteSkip {
|
||||
|
||||
private final int numberOfBlocks;
|
||||
private final byte[] outputText;
|
||||
|
||||
public SkipTest(int keyLength, int textLength, int AADLength)
|
||||
throws Exception {
|
||||
super(keyLength, textLength, AADLength);
|
||||
numberOfBlocks = this.textLength / BLOCK;
|
||||
outputText = new byte[numberOfBlocks * SAVE];
|
||||
}
|
||||
|
||||
private void doByteTest(int blockNum, CipherInputStream cis)
|
||||
throws IOException {
|
||||
int index = blockNum * SAVE;
|
||||
int len = cis.read(outputText, index, SAVE);
|
||||
index += len;
|
||||
int read = 0;
|
||||
while (len != SAVE && read != -1) {
|
||||
read = cis.read(outputText, index, SAVE - len);
|
||||
len += read;
|
||||
index += read;
|
||||
}
|
||||
}
|
||||
|
||||
private void doIntTest(int blockNum, CipherInputStream cis)
|
||||
throws IOException {
|
||||
int i = blockNum * SAVE;
|
||||
for (int j = 0; j < SAVE && i < outputText.length; j++, i++) {
|
||||
int b = cis.read();
|
||||
if (b != -1) {
|
||||
outputText[i] = (byte) b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTest(BufferType type) throws IOException,
|
||||
NoSuchAlgorithmException {
|
||||
try (CipherInputStream cis = new CipherInputStream(ciInput,
|
||||
decryptCipher)) {
|
||||
for (int i = 0; i < numberOfBlocks; i++) {
|
||||
if (type == BufferType.BYTE_ARRAY_BUFFERING) {
|
||||
doByteTest(i, cis);
|
||||
} else {
|
||||
doIntTest(i, cis);
|
||||
}
|
||||
if (cis.available() >= DISCARD) {
|
||||
cis.skip(DISCARD);
|
||||
} else {
|
||||
for (int k = 0; k < DISCARD; k++) {
|
||||
cis.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte[] expectedText = new byte[numberOfBlocks * SAVE];
|
||||
for (int m = 0; m < numberOfBlocks; m++) {
|
||||
for (int n = 0; n < SAVE; n++) {
|
||||
expectedText[m * SAVE + n] = plaintext[m * BLOCK + n];
|
||||
}
|
||||
}
|
||||
check(expectedText, outputText);
|
||||
}
|
||||
}
|
||||
}
|
||||
435
test/jdk/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java
Normal file
435
test/jdk/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 java.nio.ByteBuffer;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.util.HexFormat;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import jdk.test.lib.Convert;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048596
|
||||
* @summary Check if AEAD operations work correctly when buffers used
|
||||
* for storing plain text and cipher text are overlapped or the same
|
||||
* @library /test/lib
|
||||
*/
|
||||
public class SameBuffer {
|
||||
|
||||
private static final String PROVIDER = System.getProperty("test.provider.name", "SunJCE");
|
||||
private static final String AES = "AES";
|
||||
private static final String GCM = "GCM";
|
||||
private static final String PADDING = "NoPadding";
|
||||
private static final int OFFSET = 2;
|
||||
private static final int OFFSETS = 4;
|
||||
private static final int KEY_LENGTHS[] = { 128, 192, 256 };
|
||||
private static final int TEXT_LENGTHS[] = { 0, 1024 };
|
||||
private static final int AAD_LENGTHS[] = { 0, 1024 };
|
||||
|
||||
private final Provider provider;
|
||||
private final SecretKey key;
|
||||
private final String transformation;
|
||||
private final int textLength;
|
||||
private final int AADLength;
|
||||
|
||||
/**
|
||||
* Constructor of the test
|
||||
*
|
||||
* @param provider security provider
|
||||
* @param keyStrength key length
|
||||
* @param textLength length of data
|
||||
* @param AADLength AAD length
|
||||
*/
|
||||
public SameBuffer(Provider provider, String algorithm, String mode,
|
||||
String padding, int keyStrength, int textLength, int AADLength)
|
||||
throws Exception {
|
||||
|
||||
// init a secret key
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algorithm, provider);
|
||||
kg.init(keyStrength);
|
||||
key = kg.generateKey();
|
||||
|
||||
this.transformation = algorithm + "/" + mode + "/" + padding;
|
||||
this.provider = provider;
|
||||
this.textLength = textLength;
|
||||
this.AADLength = AADLength;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Provider p = Security.getProvider(PROVIDER);
|
||||
for (int keyLength : KEY_LENGTHS) {
|
||||
for (int textLength : TEXT_LENGTHS) {
|
||||
for (int AADLength : AAD_LENGTHS) {
|
||||
for (int i = 0; i < OFFSETS; i++) {
|
||||
// try different offsets
|
||||
int offset = i * OFFSET;
|
||||
runTest(p, AES, GCM, PADDING, keyLength, textLength,
|
||||
AADLength, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Run single test case with given parameters
|
||||
*/
|
||||
static void runTest(Provider p, String algo, String mode,
|
||||
String padding, int keyLength, int textLength, int AADLength,
|
||||
int offset) throws Exception {
|
||||
System.out.println("Testing " + keyLength + " key length; "
|
||||
+ textLength + " text length; " + AADLength + " AAD length; "
|
||||
+ offset + " offset");
|
||||
if (keyLength > Cipher.getMaxAllowedKeyLength(algo)) {
|
||||
// skip this if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
return;
|
||||
}
|
||||
SameBuffer test = new SameBuffer(p, algo, mode,
|
||||
padding, keyLength, textLength, AADLength);
|
||||
|
||||
/*
|
||||
* There are four test cases:
|
||||
* 1. AAD and text are placed in separated byte arrays
|
||||
* 2. AAD and text are placed in the same byte array
|
||||
* 3. AAD and text are placed in separated byte buffers
|
||||
* 4. AAD and text are placed in the same byte buffer
|
||||
*/
|
||||
Cipher ci = test.createCipher(Cipher.ENCRYPT_MODE, null);
|
||||
AlgorithmParameters params = ci.getParameters();
|
||||
test.doTestWithSeparateArrays(offset, params);
|
||||
test.doTestWithSameArrays(offset, params);
|
||||
test.doTestWithSeparatedBuffer(offset, params);
|
||||
test.doTestWithSameBuffer(offset, params);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the test in case when AAD and text are placed in separated byte
|
||||
* arrays.
|
||||
*/
|
||||
private void doTestWithSeparateArrays(int offset,
|
||||
AlgorithmParameters params) throws Exception {
|
||||
// prepare buffers to test
|
||||
Cipher c = createCipher(Cipher.ENCRYPT_MODE, params);
|
||||
int outputLength = c.getOutputSize(textLength);
|
||||
int outputBufSize = outputLength + offset * 2;
|
||||
|
||||
byte[] inputText = Helper.generateBytes(outputBufSize);
|
||||
byte[] AAD = Helper.generateBytes(AADLength);
|
||||
|
||||
// do the test
|
||||
runGCMWithSeparateArray(Cipher.ENCRYPT_MODE, AAD, inputText, offset * 2,
|
||||
textLength, offset, params);
|
||||
int tagLength = c.getParameters()
|
||||
.getParameterSpec(GCMParameterSpec.class).getTLen() / 8;
|
||||
runGCMWithSeparateArray(Cipher.DECRYPT_MODE, AAD, inputText, offset,
|
||||
textLength + tagLength, offset, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the test in case when AAD and text are placed in the same byte
|
||||
* array.
|
||||
*/
|
||||
private void doTestWithSameArrays(int offset, AlgorithmParameters params)
|
||||
throws Exception {
|
||||
// prepare buffers to test
|
||||
Cipher c = createCipher(Cipher.ENCRYPT_MODE, params);
|
||||
int outputLength = c.getOutputSize(textLength);
|
||||
int outputBufSize = AADLength + outputLength + offset * 2;
|
||||
|
||||
byte[] AAD_and_text = Helper.generateBytes(outputBufSize);
|
||||
|
||||
// do the test
|
||||
runGCMWithSameArray(Cipher.ENCRYPT_MODE, AAD_and_text, AADLength + offset,
|
||||
textLength, params);
|
||||
int tagLength = c.getParameters()
|
||||
.getParameterSpec(GCMParameterSpec.class).getTLen() / 8;
|
||||
runGCMWithSameArray(Cipher.DECRYPT_MODE, AAD_and_text, AADLength + offset,
|
||||
textLength + tagLength, params);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the test in case when AAD and text are placed in separated ByteBuffer
|
||||
*/
|
||||
private void doTestWithSeparatedBuffer(int offset,
|
||||
AlgorithmParameters params) throws Exception {
|
||||
// prepare AAD byte buffers to test
|
||||
byte[] AAD = Helper.generateBytes(AADLength);
|
||||
ByteBuffer AAD_Buf = ByteBuffer.allocate(AADLength);
|
||||
AAD_Buf.put(AAD, 0, AAD.length);
|
||||
AAD_Buf.flip();
|
||||
|
||||
// prepare text byte buffer to encrypt/decrypt
|
||||
Cipher c = createCipher(Cipher.ENCRYPT_MODE, params);
|
||||
int outputLength = c.getOutputSize(textLength);
|
||||
int outputBufSize = outputLength + offset;
|
||||
byte[] inputText = Helper.generateBytes(outputBufSize);
|
||||
ByteBuffer plainTextBB = ByteBuffer.allocateDirect(inputText.length);
|
||||
plainTextBB.put(inputText);
|
||||
plainTextBB.position(offset);
|
||||
plainTextBB.limit(offset + textLength);
|
||||
|
||||
// do test
|
||||
runGCMWithSeparateBuffers(Cipher.ENCRYPT_MODE, AAD_Buf, plainTextBB, offset,
|
||||
textLength, params);
|
||||
int tagLength = c.getParameters()
|
||||
.getParameterSpec(GCMParameterSpec.class).getTLen() / 8;
|
||||
plainTextBB.position(offset);
|
||||
plainTextBB.limit(offset + textLength + tagLength);
|
||||
runGCMWithSeparateBuffers(Cipher.DECRYPT_MODE, AAD_Buf, plainTextBB, offset,
|
||||
textLength + tagLength, params);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the test in case when AAD and text are placed in the same ByteBuffer
|
||||
*/
|
||||
private void doTestWithSameBuffer(int offset, AlgorithmParameters params)
|
||||
throws Exception {
|
||||
// calculate output length
|
||||
Cipher c = createCipher(Cipher.ENCRYPT_MODE, params);
|
||||
int outputLength = c.getOutputSize(textLength);
|
||||
|
||||
// prepare byte buffer contained AAD and plain text
|
||||
int bufSize = AADLength + offset + outputLength;
|
||||
byte[] AAD_and_Text = Helper.generateBytes(bufSize);
|
||||
ByteBuffer AAD_and_Text_Buf = ByteBuffer.allocate(bufSize);
|
||||
AAD_and_Text_Buf.put(AAD_and_Text, 0, AAD_and_Text.length);
|
||||
|
||||
// do test
|
||||
runGCMWithSameBuffer(Cipher.ENCRYPT_MODE, AAD_and_Text_Buf, offset,
|
||||
textLength, params);
|
||||
int tagLength = c.getParameters()
|
||||
.getParameterSpec(GCMParameterSpec.class).getTLen() / 8;
|
||||
AAD_and_Text_Buf.limit(AADLength + offset + textLength + tagLength);
|
||||
runGCMWithSameBuffer(Cipher.DECRYPT_MODE, AAD_and_Text_Buf, offset,
|
||||
textLength + tagLength, params);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute GCM encryption/decryption of a text placed in a byte array.
|
||||
* AAD is placed in the separated byte array.
|
||||
* Data are processed twice:
|
||||
* - in a separately allocated buffer
|
||||
* - in the text buffer
|
||||
* Check if two results are equal
|
||||
*/
|
||||
private void runGCMWithSeparateArray(int mode, byte[] AAD, byte[] text,
|
||||
int txtOffset, int length, int offset, AlgorithmParameters params)
|
||||
throws Exception {
|
||||
// first, generate the cipher text at an allocated buffer
|
||||
Cipher cipher = createCipher(mode, params);
|
||||
cipher.updateAAD(AAD);
|
||||
byte[] outputText = cipher.doFinal(text, txtOffset, length);
|
||||
|
||||
// new cipher for encrypt operation
|
||||
Cipher anotherCipher = createCipher(mode, params);
|
||||
anotherCipher.updateAAD(AAD);
|
||||
|
||||
// next, generate cipher text again at the same buffer of plain text
|
||||
int myoff = offset;
|
||||
int off = anotherCipher.update(text, txtOffset, length, text, myoff);
|
||||
anotherCipher.doFinal(text, myoff + off);
|
||||
|
||||
// check if two resutls are equal
|
||||
if (!isEqual(text, myoff, outputText, 0, outputText.length)) {
|
||||
System.err.println(
|
||||
"\noutputText: len = " + outputText.length + " txtOffset = " + txtOffset + "\n" +
|
||||
HexFormat.of().withUpperCase().formatHex(outputText) + "\n" +
|
||||
"text: len = " + text.length + " myoff = " + myoff + "\n" +
|
||||
HexFormat.of().withUpperCase().formatHex(text) + "\n" +
|
||||
"length " + length);
|
||||
System.err.println("tlen = " + params.getParameterSpec(GCMParameterSpec.class).getTLen() / 8);
|
||||
throw new RuntimeException("Two results not equal, mode:" + mode);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute GCM encrption/decryption of a text. The AAD and text to process
|
||||
* are placed in the same byte array. Data are processed twice:
|
||||
* - in a separetly allocated buffer
|
||||
* - in a buffer that shares content of the AAD_and_Text_BA
|
||||
* Check if two results are equal
|
||||
*/
|
||||
private void runGCMWithSameArray(int mode, byte[] array, int txtOffset,
|
||||
int length, AlgorithmParameters params) throws Exception {
|
||||
// first, generate cipher text at an allocated buffer
|
||||
Cipher cipher = createCipher(mode, params);
|
||||
cipher.updateAAD(array, 0, AADLength);
|
||||
byte[] outputText = cipher.doFinal(array, txtOffset, length);
|
||||
|
||||
// new cipher for encrypt operation
|
||||
Cipher anotherCipher = createCipher(mode, params);
|
||||
anotherCipher.updateAAD(array, 0, AADLength);
|
||||
|
||||
// next, generate cipher text again at the same buffer of plain text
|
||||
int off = anotherCipher.update(array, txtOffset, length,
|
||||
array, txtOffset);
|
||||
anotherCipher.doFinal(array, txtOffset + off);
|
||||
|
||||
// check if two results are equal or not
|
||||
if (!isEqual(array, txtOffset, outputText, 0,
|
||||
outputText.length)) {
|
||||
throw new RuntimeException(
|
||||
"Two results are not equal, mode:" + mode);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute GCM encryption/decryption of textBB. AAD and text to process are
|
||||
* placed in different byte buffers. Data are processed twice:
|
||||
* - in a separately allocated buffer
|
||||
* - in a buffer that shares content of the textBB
|
||||
* Check if results are equal
|
||||
*/
|
||||
private void runGCMWithSeparateBuffers(int mode, ByteBuffer buffer,
|
||||
ByteBuffer textBB, int txtOffset, int dataLength,
|
||||
AlgorithmParameters params) throws Exception {
|
||||
// take offset into account
|
||||
textBB.position(txtOffset);
|
||||
textBB.mark();
|
||||
|
||||
// first, generate the cipher text at an allocated buffer
|
||||
Cipher cipher = createCipher(mode, params);
|
||||
cipher.updateAAD(buffer);
|
||||
buffer.flip();
|
||||
ByteBuffer outBB = ByteBuffer.allocateDirect(
|
||||
cipher.getOutputSize(dataLength));
|
||||
|
||||
cipher.doFinal(textBB, outBB);// get cipher text in outBB
|
||||
outBB.flip();
|
||||
|
||||
// restore positions
|
||||
textBB.reset();
|
||||
|
||||
// next, generate cipher text again in a buffer that shares content
|
||||
Cipher anotherCipher = createCipher(mode, params);
|
||||
anotherCipher.updateAAD(buffer);
|
||||
buffer.flip();
|
||||
ByteBuffer buf2 = textBB.duplicate(); // buf2 shares textBuf context
|
||||
buf2.limit(txtOffset + anotherCipher.getOutputSize(dataLength));
|
||||
int dataProcessed2 = anotherCipher.doFinal(textBB, buf2);
|
||||
buf2.position(txtOffset);
|
||||
buf2.limit(txtOffset + dataProcessed2);
|
||||
|
||||
if (!buf2.equals(outBB)) {
|
||||
throw new RuntimeException(
|
||||
"Two results are not equal, mode:" + mode);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute GCM encryption/decryption of text. AAD and a text to process are
|
||||
* placed in the same buffer. Data is processed twice:
|
||||
* - in a separately allocated buffer
|
||||
* - in a buffer that shares content of the AAD_and_Text_BB
|
||||
*/
|
||||
private void runGCMWithSameBuffer(int mode, ByteBuffer buffer,
|
||||
int txtOffset, int length, AlgorithmParameters params)
|
||||
throws Exception {
|
||||
|
||||
// allocate a separate buffer
|
||||
Cipher cipher = createCipher(mode, params);
|
||||
ByteBuffer outBB = ByteBuffer.allocateDirect(
|
||||
cipher.getOutputSize(length));
|
||||
|
||||
// first, generate the cipher text at an allocated buffer
|
||||
buffer.flip();
|
||||
buffer.limit(AADLength);
|
||||
cipher.updateAAD(buffer);
|
||||
buffer.limit(AADLength + txtOffset + length);
|
||||
buffer.position(AADLength + txtOffset);
|
||||
cipher.doFinal(buffer, outBB);
|
||||
outBB.flip(); // cipher text in outBB
|
||||
|
||||
// next, generate cipherText again in the same buffer
|
||||
Cipher anotherCipher = createCipher(mode, params);
|
||||
buffer.flip();
|
||||
buffer.limit(AADLength);
|
||||
anotherCipher.updateAAD(buffer);
|
||||
buffer.limit(AADLength + txtOffset + length);
|
||||
buffer.position(AADLength + txtOffset);
|
||||
|
||||
// share textBuf context
|
||||
ByteBuffer buf2 = buffer.duplicate();
|
||||
buf2.limit(AADLength + txtOffset + anotherCipher.getOutputSize(length));
|
||||
int dataProcessed2 = anotherCipher.doFinal(buffer, buf2);
|
||||
buf2.position(AADLength + txtOffset);
|
||||
buf2.limit(AADLength + txtOffset + dataProcessed2);
|
||||
|
||||
if (!buf2.equals(outBB)) {
|
||||
throw new RuntimeException(
|
||||
"Two results are not equal, mode:" + mode);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEqual(byte[] A, int offsetA, byte[] B, int offsetB,
|
||||
int bytesToCompare) {
|
||||
System.out.println("offsetA: " + offsetA + " offsetB: " + offsetA
|
||||
+ " bytesToCompare: " + bytesToCompare);
|
||||
for (int i = 0; i < bytesToCompare; i++) {
|
||||
int setA = i + offsetA;
|
||||
int setB = i + offsetB;
|
||||
if (setA > A.length - 1 || setB > B.length - 1
|
||||
|| A[setA] != B[setB]) {
|
||||
System.err.println("i = " + i + " A[setA] = " + A[setA] +
|
||||
" B[setB] = " + B[setB]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a Cipher object for testing: for encryption it creates new Cipher
|
||||
* based on previously saved parameters (it is prohibited to use the same
|
||||
* Cipher twice for encription during GCM mode), or returns initiated
|
||||
* existing Cipher.
|
||||
*/
|
||||
private Cipher createCipher(int mode, AlgorithmParameters params)
|
||||
throws Exception {
|
||||
Cipher cipher = Cipher.getInstance(transformation, provider);
|
||||
if (Cipher.ENCRYPT_MODE == mode) {
|
||||
// initiate it with the saved parameters
|
||||
if (params != null) {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, params);
|
||||
} else {
|
||||
// intiate the cipher and save parameters
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
}
|
||||
} else if (cipher != null) {
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, params);
|
||||
} else {
|
||||
throw new RuntimeException("Can't create cipher");
|
||||
}
|
||||
|
||||
return cipher;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 java.security.AlgorithmParameters;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SealedObject;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048596
|
||||
* @summary Check if the seal/unseal feature works properly in AEAD/GCM mode.
|
||||
*/
|
||||
public class SealedObjectTest {
|
||||
|
||||
private static final String AES = "AES";
|
||||
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
|
||||
private static final String PROVIDER = System.getProperty("test.provider.name", "SunJCE");
|
||||
private static final int KEY_LENGTH = 128;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the test:
|
||||
* - init a cipher with AES/GCM/NoPadding transformation
|
||||
* - seal an object
|
||||
* - check if we can't seal it again with the same key/IV
|
||||
* - unseal the object using different methods of SealedObject class
|
||||
* - check if the original and sealed objects are equal
|
||||
*/
|
||||
static void doTest() throws Exception {
|
||||
// init a secret Key
|
||||
KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER);
|
||||
kg.init(KEY_LENGTH);
|
||||
SecretKey key = kg.generateKey();
|
||||
|
||||
// initialization
|
||||
Cipher cipher = Cipher.getInstance(TRANSFORMATION, PROVIDER);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
AlgorithmParameters params = cipher.getParameters();
|
||||
|
||||
// seal an object
|
||||
SealedObject so = new SealedObject(key, cipher);
|
||||
try {
|
||||
// check if we can't seal it again with the same key/IV
|
||||
so = new SealedObject(key, cipher);
|
||||
throw new RuntimeException(
|
||||
"FAILED: expected IllegalStateException hasn't "
|
||||
+ "been thrown");
|
||||
} catch (IllegalStateException ise) {
|
||||
System.out.println("Expected exception when seal it again with"
|
||||
+ " the same key/IV: " + ise);
|
||||
}
|
||||
|
||||
// unseal the object using getObject(Cipher) and compare
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, params);
|
||||
SecretKey unsealedKey = (SecretKey) so.getObject(cipher);
|
||||
assertKeysSame(unsealedKey, key, "SealedObject.getObject(Cipher)");
|
||||
|
||||
// unseal the object using getObject(Key) and compare
|
||||
unsealedKey = (SecretKey) so.getObject(key);
|
||||
assertKeysSame(unsealedKey, key, "SealedObject.getObject(Key)");
|
||||
|
||||
// unseal the object using getObject(Key, String) and compare
|
||||
unsealedKey = (SecretKey) so.getObject(key, PROVIDER);
|
||||
|
||||
assertKeysSame(unsealedKey, key,
|
||||
"SealedObject.getObject(Key, String)");
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two SecretKey objects.
|
||||
*
|
||||
* @param key1 first key
|
||||
* @param key2 second key
|
||||
* @param meth method that was used for unsealing the SecretKey object
|
||||
* @return true if key1 and key2 are the same, false otherwise.
|
||||
*/
|
||||
static void assertKeysSame(SecretKey key1, SecretKey key2, String meth) {
|
||||
if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {
|
||||
throw new RuntimeException(
|
||||
"FAILED: original and unsealed objects aren't the same for "
|
||||
+ meth);
|
||||
}
|
||||
}
|
||||
}
|
||||
174
test/jdk/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java
Normal file
174
test/jdk/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2024, 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 java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048596
|
||||
* @summary Check if wrong or empty AAD is rejected
|
||||
*/
|
||||
public class WrongAAD {
|
||||
|
||||
private static final String PROVIDER = System.getProperty("test.provider.name", "SunJCE");
|
||||
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
|
||||
private static final int TEXT_SIZE = 800;
|
||||
private static final int KEY_SIZE = 128;
|
||||
private static final int AAD_SIZE = 128;
|
||||
|
||||
private final SecretKey key;
|
||||
private final byte[] plainText;
|
||||
private final Cipher encryptCipher;
|
||||
|
||||
public WrongAAD() throws Exception {
|
||||
// init a secret key
|
||||
KeyGenerator kg = KeyGenerator.getInstance("AES", PROVIDER);
|
||||
kg.init(KEY_SIZE);
|
||||
key = kg.generateKey();
|
||||
|
||||
// generate a plain text
|
||||
plainText = Helper.generateBytes(TEXT_SIZE);
|
||||
|
||||
// init AADs
|
||||
byte[] AAD = Helper.generateBytes(AAD_SIZE);
|
||||
|
||||
// init a cipher
|
||||
encryptCipher = createCipher(Cipher.ENCRYPT_MODE, null);
|
||||
encryptCipher.updateAAD(AAD);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
WrongAAD test = new WrongAAD();
|
||||
test.decryptWithEmptyAAD();
|
||||
test.decryptWithWrongAAD();
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to decrypt a cipher text using Cipher object
|
||||
* initialized without AAD used for encryption.
|
||||
*/
|
||||
private void decryptWithEmptyAAD() throws Exception {
|
||||
System.out.println("decryptWithEmptyAAD() started");
|
||||
// initialize it with empty AAD to get exception during decryption
|
||||
Cipher decryptCipher = createCipher(Cipher.DECRYPT_MODE,
|
||||
encryptCipher.getParameters());
|
||||
try (ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
|
||||
CipherOutputStream ciOutput = new CipherOutputStream(baOutput,
|
||||
decryptCipher)) {
|
||||
if (decrypt(ciOutput, baOutput)) {
|
||||
throw new RuntimeException(
|
||||
"Decryption has been perfomed successfully in"
|
||||
+ " spite of the decrypt Cipher has NOT been"
|
||||
+ " initialized with AAD");
|
||||
}
|
||||
}
|
||||
System.out.println("decryptWithEmptyAAD() passed");
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to decrypt the cipher text using Cipher object
|
||||
* initialized with some fake AAD.
|
||||
*/
|
||||
private void decryptWithWrongAAD() throws Exception {
|
||||
System.out.println("decrypt with wrong AAD");
|
||||
|
||||
// initialize it with wrong AAD to get an exception during decryption
|
||||
Cipher decryptCipher = createCipher(Cipher.DECRYPT_MODE,
|
||||
encryptCipher.getParameters());
|
||||
byte[] someAAD = Helper.generateBytes(AAD_SIZE + 1);
|
||||
decryptCipher.updateAAD(someAAD);
|
||||
|
||||
// init output stream
|
||||
try (ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
|
||||
CipherOutputStream ciOutput = new CipherOutputStream(baOutput,
|
||||
decryptCipher);) {
|
||||
if (decrypt(ciOutput, baOutput)) {
|
||||
throw new RuntimeException(
|
||||
"A decryption has been perfomed successfully in"
|
||||
+ " spite of the decrypt Cipher has been"
|
||||
+ " initialized with fake AAD");
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Passed");
|
||||
}
|
||||
|
||||
private boolean decrypt(CipherOutputStream ciOutput,
|
||||
ByteArrayOutputStream baOutput) throws IOException {
|
||||
try (ByteArrayInputStream baInput = new ByteArrayInputStream(plainText);
|
||||
CipherInputStream ciInput = new CipherInputStream(baInput,
|
||||
encryptCipher)) {
|
||||
byte[] buffer = new byte[TEXT_SIZE];
|
||||
int len = ciInput.read(buffer);
|
||||
|
||||
while (len != -1) {
|
||||
ciOutput.write(buffer, 0, len);
|
||||
len = ciInput.read(buffer);
|
||||
}
|
||||
ciOutput.flush();
|
||||
byte[] recoveredText = baOutput.toByteArray();
|
||||
System.out.println("recoveredText: " + new String(recoveredText));
|
||||
|
||||
/*
|
||||
* See bug 8012900, AEADBadTagException is swalloed by CI/CO streams
|
||||
* If recovered text is empty, than decryption failed
|
||||
*/
|
||||
if (recoveredText.length == 0) {
|
||||
return false;
|
||||
}
|
||||
return Arrays.equals(plainText, recoveredText);
|
||||
} catch (IllegalStateException e) {
|
||||
System.out.println("Expected IllegalStateException: "
|
||||
+ e.getMessage());
|
||||
e.printStackTrace(System.out);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Cipher createCipher(int mode, AlgorithmParameters params)
|
||||
throws NoSuchAlgorithmException, NoSuchProviderException,
|
||||
NoSuchPaddingException, InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
Cipher cipher = Cipher.getInstance(TRANSFORMATION, PROVIDER);
|
||||
if (params != null) {
|
||||
cipher.init(mode, key, params);
|
||||
} else {
|
||||
cipher.init(mode, key);
|
||||
}
|
||||
return cipher;
|
||||
}
|
||||
}
|
||||
187
test/jdk/com/sun/crypto/provider/Cipher/AES/CICO.java
Normal file
187
test/jdk/com/sun/crypto/provider/Cipher/AES/CICO.java
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2024, 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 java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Random;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8043836
|
||||
* @summary Test AES ciphers with different modes and padding schemes (ECB mode
|
||||
* doesn't use IV). The test tries 3 different read methods of
|
||||
* CipherInputStream.
|
||||
* @key randomness
|
||||
*/
|
||||
public class CICO {
|
||||
private static final String ALGORITHM = "aEs";
|
||||
private static final String[] MODES = { "PCBC", "ECb", "cbC", "cFB",
|
||||
"cFB24", "cFB32", "Cfb40", "CFB72", "OfB", "OfB20", "OfB48",
|
||||
"OfB56", "OFB64", "OFB112", "CFB112", "pCbC" };
|
||||
private static final String[] PADDING = { "noPadding", "pkcs5padding" };
|
||||
private static final String PROVIDER = System.getProperty("test.provider.name", "SunJCE");
|
||||
private static final int NREADS = 3;
|
||||
private static final int KEY_LENGTH = 128;
|
||||
|
||||
private final byte[] plainText = new byte[1600000];
|
||||
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
CICO test = new CICO();
|
||||
for (String mode : MODES) {
|
||||
for (String pad : PADDING) {
|
||||
for (int m = 0; m < NREADS; m++) {
|
||||
test.runTest(ALGORITHM, mode, pad, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void runTest(String algo, String mo, String pad, int whichRead) throws Exception {
|
||||
Cipher ci1 = null;
|
||||
Cipher ci2 = null;
|
||||
byte[] iv = null;
|
||||
AlgorithmParameterSpec aps = null;
|
||||
SecretKey key = null;
|
||||
|
||||
try {
|
||||
// Do initialization
|
||||
Random rdm = new Random();
|
||||
rdm.nextBytes(plainText);
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER);
|
||||
if (!kg.getAlgorithm().equals(algo)) {
|
||||
throw new RuntimeException("Unexpected algorithm <"
|
||||
+ kg.getAlgorithm() + ">, expected value is <" + algo
|
||||
+ ">");
|
||||
}
|
||||
|
||||
kg.init(KEY_LENGTH);
|
||||
key = kg.generateKey();
|
||||
|
||||
ci1 = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
|
||||
|
||||
if (mo.equalsIgnoreCase("ECB")) {
|
||||
ci1.init(Cipher.ENCRYPT_MODE, key);
|
||||
} else {
|
||||
ci1.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
}
|
||||
|
||||
if (!mo.equalsIgnoreCase("ECB")) {
|
||||
iv = ci1.getIV();
|
||||
aps = new IvParameterSpec(iv);
|
||||
} else {
|
||||
aps = null;
|
||||
}
|
||||
|
||||
ci2 = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
|
||||
if (mo.equalsIgnoreCase("ECB")) {
|
||||
ci2.init(Cipher.DECRYPT_MODE, key);
|
||||
} else {
|
||||
ci2.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
}
|
||||
|
||||
ByteArrayInputStream baInput = new ByteArrayInputStream(plainText);
|
||||
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
|
||||
try (CipherInputStream ciInput = new CipherInputStream(baInput, ci1);
|
||||
CipherOutputStream ciOutput = new CipherOutputStream(
|
||||
baOutput, ci2)) {
|
||||
// According to specification, CipherInputStream does not support the
|
||||
// mark and reset methods
|
||||
if (ciInput.markSupported()) {
|
||||
throw new RuntimeException(
|
||||
"CipherInputStream unexpectedly supports the mark and reset methods");
|
||||
}
|
||||
|
||||
// Read from the input and write to the output using 2 types
|
||||
// of buffering : byte[] and int
|
||||
switch (whichRead) {
|
||||
case 0:
|
||||
int buffer0 = ciInput.read();
|
||||
while (buffer0 != -1) {
|
||||
ciOutput.write(buffer0);
|
||||
buffer0 = ciInput.read();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
byte[] buffer1 = new byte[20];
|
||||
int len1 = ciInput.read(buffer1);
|
||||
while (len1 != -1) {
|
||||
ciOutput.write(buffer1, 0, len1);
|
||||
len1 = ciInput.read(buffer1);
|
||||
}
|
||||
break;
|
||||
case NREADS - 1:
|
||||
byte[] buffer2 = new byte[ci1
|
||||
.getOutputSize(plainText.length)];
|
||||
int offset2 = 0;
|
||||
int len2 = 0;
|
||||
while (len2 != -1) {
|
||||
len2 = ciInput.read(buffer2, offset2, buffer2.length
|
||||
- offset2);
|
||||
offset2 += len2;
|
||||
}
|
||||
ciOutput.write(buffer2, 0, buffer2.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the output
|
||||
byte[] recoveredText = new byte[baOutput.size()];
|
||||
recoveredText = baOutput.toByteArray();
|
||||
if (!java.util.Arrays.equals(plainText, recoveredText)) {
|
||||
throw new RuntimeException(
|
||||
"Original text is not equal with recovered text, with "
|
||||
+ algo + "/" + mo + "/" + pad + "/" + whichRead);
|
||||
}
|
||||
|
||||
// Compare input and output
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
//OFB20 is for negative testing
|
||||
if (!mo.equalsIgnoreCase("OFB20")) {
|
||||
System.out.println("Unexpected NoSuchAlgorithmException with "
|
||||
+ algo + "/" + mo + "/" + pad + "/" + whichRead);
|
||||
throw new RuntimeException("Test failed!");
|
||||
}
|
||||
} catch (IOException | NoSuchProviderException | NoSuchPaddingException
|
||||
| InvalidKeyException | InvalidAlgorithmParameterException e) {
|
||||
System.out.println("Unexpected Exception with "
|
||||
+ algo + "/" + mo + "/" + pad + "/" + whichRead);
|
||||
System.out.println("Test failed!");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
147
test/jdk/com/sun/crypto/provider/Cipher/AES/CTR.java
Normal file
147
test/jdk/com/sun/crypto/provider/Cipher/AES/CTR.java
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2024, 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 java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.ShortBufferException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8043836
|
||||
* @summary Test AES ciphers with 4 different modes with NoPadding. Check if
|
||||
* data before encryption and after decryption is the same.
|
||||
* @key randomness
|
||||
*/
|
||||
|
||||
public class CTR {
|
||||
|
||||
private static final String ALGORITHM = "AES";
|
||||
|
||||
private static final String PROVIDER =
|
||||
System.getProperty("test.provider.name", "SunJCE");
|
||||
|
||||
private static final String[] MODES = {"CTR","CFB24","OFB32","GCM"};
|
||||
|
||||
private static final String PADDING = "NoPadding";
|
||||
|
||||
|
||||
private static final int KEY_LENGTH = 128;
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
CTR test = new CTR();
|
||||
for (String mode : MODES) {
|
||||
test.runTest(ALGORITHM, mode, PADDING);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void runTest(String algo, String mo, String pad) throws Exception {
|
||||
Cipher ci = null;
|
||||
byte[] iv = null;
|
||||
AlgorithmParameterSpec aps = null;
|
||||
SecretKey key = null;
|
||||
|
||||
try {
|
||||
Random rdm = new Random();
|
||||
byte[] plainText;
|
||||
|
||||
ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER);
|
||||
kg.init(KEY_LENGTH);
|
||||
key = kg.generateKey();
|
||||
|
||||
for (int i = 0; i < 15; i++) {
|
||||
plainText = new byte[1600 + i + 1];
|
||||
rdm.nextBytes(plainText);
|
||||
|
||||
if (!mo.equalsIgnoreCase("GCM")) {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
} else {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
}
|
||||
|
||||
byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = ci.update(plainText, 0, plainText.length,
|
||||
cipherText, 0);
|
||||
|
||||
ci.doFinal(cipherText, offset);
|
||||
|
||||
if (!mo.equalsIgnoreCase("ECB")) {
|
||||
iv = ci.getIV();
|
||||
aps = new IvParameterSpec(iv);
|
||||
} else {
|
||||
aps = null;
|
||||
}
|
||||
|
||||
if (!mo.equalsIgnoreCase("GCM")) {
|
||||
ci.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
} else {
|
||||
ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters());
|
||||
}
|
||||
|
||||
byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
|
||||
int len = ci.doFinal(cipherText, 0, cipherText.length,
|
||||
recoveredText);
|
||||
byte[] tmp = new byte[len];
|
||||
|
||||
for (int j = 0; j < len; j++) {
|
||||
tmp[j] = recoveredText[j];
|
||||
}
|
||||
Arrays.toString(plainText);
|
||||
if (!java.util.Arrays.equals(plainText, tmp)) {
|
||||
System.out.println("Original: ");
|
||||
dumpBytes(plainText);
|
||||
System.out.println("Recovered: ");
|
||||
dumpBytes(tmp);
|
||||
throw new RuntimeException("Original text is not equal with recovered text, with mode:" + mo);
|
||||
}
|
||||
}
|
||||
} catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException
|
||||
| InvalidKeyException | InvalidAlgorithmParameterException
|
||||
| ShortBufferException | IllegalBlockSizeException
|
||||
| BadPaddingException e) {
|
||||
System.out.println("Test failed!");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpBytes(byte[] bytes){
|
||||
for (byte b : bytes){
|
||||
System.out.print(Integer.toHexString(b));
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
157
test/jdk/com/sun/crypto/provider/Cipher/AES/Padding.java
Normal file
157
test/jdk/com/sun/crypto/provider/Cipher/AES/Padding.java
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2024, 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 java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Random;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.ShortBufferException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8043836
|
||||
* @summary Test AES ciphers with different modes and padding schemes (ECB mode
|
||||
* doesn't use IV). The test tries 3 different read methods of
|
||||
* CipherInputStream.
|
||||
* @key randomness
|
||||
*/
|
||||
public class Padding {
|
||||
|
||||
private static final String ALGORITHM = "AES";
|
||||
private static final String PROVIDER =
|
||||
System.getProperty("test.provider.name", "SunJCE");
|
||||
private static final String[] MODES_PKCS5PAD = {
|
||||
"ECb", "CbC", "PCBC", "OFB",
|
||||
"OFB150", "cFB", "CFB7", "cFB8", "cFB16", "cFB24", "cFB32",
|
||||
"Cfb40", "cfB48", "cfB56", "cfB64", "cfB72", "cfB80", "cfB88",
|
||||
"cfB96", "cfb104", "cfB112", "cfB120", "OFB8", "OFB16", "OFB24",
|
||||
"OFB32", "OFB40", "OFB48", "OFB56", "OFB64", "OFB72", "OFB80",
|
||||
"OFB88", "OFB96", "OFB104", "OFB112", "OFB120" };
|
||||
private static final String[] MODES_NOPAD = { "CTR", "CTS", "GCM" };
|
||||
|
||||
private static final int KEY_LENGTH = 128;
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
Padding test = new Padding();
|
||||
for (String mode : MODES_PKCS5PAD) {
|
||||
test.runTest(ALGORITHM, mode, "PKCS5Padding");
|
||||
}
|
||||
for (String mode : MODES_NOPAD) {
|
||||
test.runTest(ALGORITHM, mode, "NoPadding");
|
||||
}
|
||||
}
|
||||
|
||||
public void runTest(String algo, String mo, String pad) throws Exception {
|
||||
Cipher ci = null;
|
||||
byte[] iv = null;
|
||||
AlgorithmParameterSpec aps = null;
|
||||
SecretKey key = null;
|
||||
try {
|
||||
Random rdm = new Random();
|
||||
byte[] plainText;
|
||||
|
||||
ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER);
|
||||
kg.init(KEY_LENGTH);
|
||||
key = kg.generateKey();
|
||||
|
||||
for (int i = 0; i < 15; i++) {
|
||||
plainText = new byte[1600 + i + 1];
|
||||
rdm.nextBytes(plainText);
|
||||
|
||||
if (!mo.equalsIgnoreCase("GCM")) {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
} else {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
}
|
||||
|
||||
byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = ci.update(plainText, 0, plainText.length,
|
||||
cipherText, 0);
|
||||
ci.doFinal(cipherText, offset);
|
||||
if (!mo.equalsIgnoreCase("ECB")) {
|
||||
iv = ci.getIV();
|
||||
aps = new IvParameterSpec(iv);
|
||||
} else {
|
||||
aps = null;
|
||||
}
|
||||
|
||||
if (!mo.equalsIgnoreCase("GCM")) {
|
||||
ci.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
} else {
|
||||
ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters());
|
||||
}
|
||||
|
||||
byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
|
||||
int len = ci.doFinal(cipherText, 0, cipherText.length,
|
||||
recoveredText);
|
||||
byte[] tmp = new byte[len];
|
||||
|
||||
for (int j = 0; j < len; j++) {
|
||||
tmp[j] = recoveredText[j];
|
||||
}
|
||||
|
||||
if (!java.util.Arrays.equals(plainText, tmp)) {
|
||||
System.out.println("Original: ");
|
||||
dumpBytes(plainText);
|
||||
System.out.println("Recovered: ");
|
||||
dumpBytes(tmp);
|
||||
throw new RuntimeException(
|
||||
"Original text is not equal with recovered text, with mode:"
|
||||
+ mo);
|
||||
}
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
//CFB7 and OFB150 are for negative testing
|
||||
if (!mo.equalsIgnoreCase("CFB7") && !mo.equalsIgnoreCase("OFB150")) {
|
||||
System.out
|
||||
.println("Unexpected NoSuchAlgorithmException with mode: "
|
||||
+ mo);
|
||||
throw new RuntimeException("Test failed!");
|
||||
}
|
||||
} catch ( NoSuchProviderException | NoSuchPaddingException
|
||||
| InvalidKeyException | InvalidAlgorithmParameterException
|
||||
| ShortBufferException | IllegalBlockSizeException
|
||||
| BadPaddingException e) {
|
||||
System.out.println("Test failed!");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpBytes(byte[] bytes) {
|
||||
for (byte b : bytes) {
|
||||
System.out.print(Integer.toHexString(b));
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
71
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4511676.java
Normal file
71
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4511676.java
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4511676
|
||||
* @summary Verify that AES cipher.init method check key size correctly
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
import java.io.PrintStream;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.security.Provider;
|
||||
|
||||
public class Test4511676 {
|
||||
private static final String ALGO = "AES";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
|
||||
Cipher ci = Cipher.getInstance(ALGO,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
|
||||
// TEST FIX 4511676
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
kg.init(KEYSIZE*8);
|
||||
SecretKey key = kg.generateKey();
|
||||
try {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
} catch (InvalidKeyException ex) {
|
||||
throw new Exception("key length is mis-intepreted!");
|
||||
}
|
||||
|
||||
// passed all tests...hooray!
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
|
||||
Test4511676 test = new Test4511676();
|
||||
String testName = test.getClass().getName() + "[" + ALGO +
|
||||
"]";
|
||||
if (test.execute()) {
|
||||
System.out.println(testName + ": Passed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
73
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4512524.java
Normal file
73
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4512524.java
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4512524
|
||||
* @summary Verify that AES cipher can work with mode "CBC", "OFB", "CFB"
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
import java.io.PrintStream;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.security.Provider;
|
||||
|
||||
public class Test4512524 {
|
||||
|
||||
private static final String ALGO = "AES";
|
||||
private static final String PADDING = "NoPadding";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
|
||||
public void execute(String mode) throws Exception {
|
||||
|
||||
String transformation = ALGO+"/"+mode+"/"+PADDING;
|
||||
Cipher ci = Cipher.getInstance(transformation,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
|
||||
// TEST FIX 4512524
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
kg.init(KEYSIZE*8);
|
||||
SecretKey key = kg.generateKey();
|
||||
|
||||
try{
|
||||
AlgorithmParameterSpec aps = null;
|
||||
ci.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
} catch (NullPointerException ex) {
|
||||
throw new Exception("null parameter is not handled correctly!");
|
||||
}
|
||||
|
||||
// passed all tests...hooray!
|
||||
System.out.println(transformation + ": Passed");
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Test4512524 test = new Test4512524();
|
||||
test.execute("CBC");
|
||||
test.execute("GCM");
|
||||
}
|
||||
}
|
||||
69
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4512704.java
Normal file
69
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4512704.java
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4512704
|
||||
* @summary Verify that AES cipher can generate default IV in encrypt mode
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
import java.io.PrintStream;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.security.Provider;
|
||||
|
||||
public class Test4512704 {
|
||||
private static final String ALGO = "AES";
|
||||
private static final String PADDING = "NoPadding";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
|
||||
public void execute(String mode) throws Exception {
|
||||
|
||||
AlgorithmParameterSpec aps = null;
|
||||
String transformation = ALGO + "/" + mode + "/"+PADDING;
|
||||
Cipher ci = Cipher.getInstance(transformation,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
kg.init(KEYSIZE*8);
|
||||
SecretKey key = kg.generateKey();
|
||||
// TEST FIX 4512704
|
||||
try {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
} catch(InvalidAlgorithmParameterException ex) {
|
||||
throw new Exception("parameter should be generated when null is specified!");
|
||||
}
|
||||
System.out.println(transformation + ": Passed");
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Test4512704 test = new Test4512704();
|
||||
test.execute("CBC");
|
||||
test.execute("GCM");
|
||||
}
|
||||
}
|
||||
96
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4513830.java
Normal file
96
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4513830.java
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4513830
|
||||
* @summary Verify the output size returned by AES cipher.getOutputSize
|
||||
* method in DECRYPT mode does not add extra bytes for padding
|
||||
* @author Valerie Peng
|
||||
* @key randomness
|
||||
*/
|
||||
import java.io.PrintStream;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.security.Provider;
|
||||
|
||||
public class Test4513830 {
|
||||
|
||||
private static final String ALGO = "AES";
|
||||
private static final String MODE = "ECB";
|
||||
private static final String PADDING = "PKCS5Padding";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
private static final int TEXTLENGTHS[] = {
|
||||
16, 17, 18, 19, 20, 21, 22, 23 };
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
Random rdm = new Random();
|
||||
byte[] plainText=new byte[125];
|
||||
rdm.nextBytes(plainText);
|
||||
|
||||
Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
|
||||
// TEST FIX 4513830
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
kg.init(KEYSIZE*8);
|
||||
SecretKey key = kg.generateKey();
|
||||
|
||||
ci.init(Cipher.DECRYPT_MODE, key);
|
||||
int recoveredTextLength = ci.getOutputSize(16);
|
||||
|
||||
if (recoveredTextLength != 16) {
|
||||
throw new Exception("output size should not increase when decrypting!");
|
||||
}
|
||||
|
||||
// BONUS TESTS
|
||||
// 1. call getOutputSize with various lengths and see if
|
||||
// the returned size is correct.
|
||||
for (int i=0; i<TEXTLENGTHS.length; i++) {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
int cipherTextLength = ci.getOutputSize(TEXTLENGTHS[i]);
|
||||
if (cipherTextLength != 32) {
|
||||
throw new Exception("output size " + cipherTextLength
|
||||
+ " for input size " + TEXTLENGTHS[i]
|
||||
+ " when encrypting is wrong!");
|
||||
}
|
||||
}
|
||||
|
||||
// passed all tests...hooray!
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Test4513830 test = new Test4513830();
|
||||
String testName = test.getClass().getName() + "[" + ALGO +
|
||||
"/" + MODE + "/" + PADDING + "]";
|
||||
if (test.execute()) {
|
||||
System.out.println(testName + ": Passed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
104
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4517355.java
Normal file
104
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4517355.java
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4517355
|
||||
* @summary Verify that AES cipher.doFinal method does NOT need more
|
||||
* than necessary bytes in decrypt mode
|
||||
* @author Valerie Peng
|
||||
* @key randomness
|
||||
*/
|
||||
import java.io.PrintStream;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.security.Provider;
|
||||
|
||||
public class Test4517355 {
|
||||
|
||||
private static final String ALGO = "AES";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
|
||||
private static byte[] plainText = new byte[125];
|
||||
|
||||
public void execute(String mode, String padding) throws Exception {
|
||||
String transformation = ALGO + "/" + mode + "/" + padding;
|
||||
|
||||
Cipher ci = Cipher.getInstance(transformation,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
kg.init(KEYSIZE*8);
|
||||
SecretKey key = kg.generateKey();
|
||||
|
||||
// TEST FIX 4517355
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
byte[] cipherText = ci.doFinal(plainText);
|
||||
|
||||
if (mode.equalsIgnoreCase("GCM")) {
|
||||
AlgorithmParameters params = ci.getParameters();
|
||||
ci.init(Cipher.DECRYPT_MODE, key, params);
|
||||
} else {
|
||||
byte[] iv = ci.getIV();
|
||||
AlgorithmParameterSpec aps = new IvParameterSpec(iv);
|
||||
ci.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
}
|
||||
byte[] recoveredText = new byte[plainText.length];
|
||||
try {
|
||||
int len = ci.doFinal(cipherText, 0, cipherText.length,
|
||||
recoveredText);
|
||||
} catch (ShortBufferException ex) {
|
||||
throw new Exception("output buffer is the right size!");
|
||||
}
|
||||
|
||||
// BONUS TESTS
|
||||
// 1. make sure the recoveredText is the same as the plainText
|
||||
if (!Arrays.equals(plainText, recoveredText)) {
|
||||
throw new Exception("encryption/decryption does not work!");
|
||||
}
|
||||
// 2. make sure encryption does happen
|
||||
if (Arrays.equals(plainText, cipherText)) {
|
||||
throw new Exception("encryption does not work!");
|
||||
}
|
||||
// 3. make sure padding is working
|
||||
if (padding.equalsIgnoreCase("PKCS5Padding")) {
|
||||
if ((cipherText.length/16)*16 != cipherText.length) {
|
||||
throw new Exception("padding does not work!");
|
||||
}
|
||||
}
|
||||
System.out.println(transformation + ": Passed");
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Test4517355 test = new Test4517355();
|
||||
Random rdm = new Random();
|
||||
rdm.nextBytes(test.plainText);
|
||||
|
||||
test.execute("CBC", "PKCS5Padding");
|
||||
test.execute("GCM", "NoPadding");
|
||||
}
|
||||
}
|
||||
69
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4626070.java
Normal file
69
test/jdk/com/sun/crypto/provider/Cipher/AES/Test4626070.java
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4626070
|
||||
* @summary Verify that AES cipher can wrap and unwrap keys
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class Test4626070 {
|
||||
private static final String ALGO = "AES";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
|
||||
public void execute(String mode, String padding) throws Exception {
|
||||
String transformation = ALGO + "/" + mode + "/" + padding;
|
||||
Cipher ci = Cipher.getInstance(transformation,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
kg.init(KEYSIZE*8);
|
||||
SecretKey key = kg.generateKey();
|
||||
|
||||
AlgorithmParameters params = ci.getParameters();
|
||||
|
||||
// TEST FIX 4626070
|
||||
ci.init(Cipher.WRAP_MODE, key, params);
|
||||
byte[] wrappedKeyEncoding = ci.wrap(key);
|
||||
params = ci.getParameters();
|
||||
ci.init(Cipher.UNWRAP_MODE, key, params);
|
||||
Key recoveredKey = ci.unwrap(wrappedKeyEncoding, "AES",
|
||||
Cipher.SECRET_KEY);
|
||||
if (!key.equals(recoveredKey)) {
|
||||
throw new Exception(
|
||||
"key after wrap/unwrap is different from the original!");
|
||||
}
|
||||
System.out.println(transformation + ": Passed");
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Test4626070 test = new Test4626070();
|
||||
test.execute("CBC", "PKCS5Padding");
|
||||
test.execute("GCM", "NoPadding");
|
||||
}
|
||||
}
|
||||
149
test/jdk/com/sun/crypto/provider/Cipher/AES/TestAESCipher.java
Normal file
149
test/jdk/com/sun/crypto/provider/Cipher/AES/TestAESCipher.java
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2024, 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 java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.HexFormat;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.ShortBufferException;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8043836
|
||||
* @summary Test AES ciphers with different modes and padding schemes (ECB mode
|
||||
* doesn't use IV).
|
||||
* @author Liwen Wang
|
||||
* @author Parag Salvi
|
||||
*/
|
||||
public class TestAESCipher {
|
||||
|
||||
private static final String ALGORITHM = "AES";
|
||||
private static final String PROVIDER = System.getProperty("test.provider.name", "SunJCE");
|
||||
private static final String[] MODES = { "ECb", "CbC", "CTR", "PCBC", "OFB",
|
||||
"OFB150", "cFB", "CFB7", "cFB8", "cFB16", "cFB24", "cFB32",
|
||||
"Cfb40", "cfB48", "cfB56", "cfB64", "cfB72", "cfB80", "cfB88",
|
||||
"cfB96", "cfb104", "cfB112", "cfB120", "OFB8", "OFB16", "OFB24",
|
||||
"OFB32", "OFB40", "OFB48", "OFB56", "OFB64", "OFB72", "OFB80",
|
||||
"OFB88", "OFB96", "OFB104", "OFB112", "OFB120", "GCM" };
|
||||
private static final String[] PADDING = { "NoPadding", "PKCS5Padding" };
|
||||
private static final int KEY_LENGTH = 16;
|
||||
static byte[] plainText = new byte[128];
|
||||
static byte[] key = new byte[KEY_LENGTH];
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
TestAESCipher test = new TestAESCipher();
|
||||
for (String mode : MODES) {
|
||||
int padKinds = 1;
|
||||
if (mode.equalsIgnoreCase("ECB") || mode.equalsIgnoreCase("PCBC")
|
||||
|| mode.equalsIgnoreCase("CBC")) {
|
||||
padKinds = PADDING.length;
|
||||
}
|
||||
|
||||
for (int k = 0; k < padKinds; k++) {
|
||||
test.runTest(ALGORITHM, mode, PADDING[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void runTest(String algo, String mo, String pad) throws Exception {
|
||||
Cipher ci;
|
||||
System.out.println("Testing " + algo + "/" + mo + "/" + pad);
|
||||
|
||||
byte[] iv = new byte[16];
|
||||
AlgorithmParameterSpec aps = new GCMParameterSpec(128, iv);
|
||||
SecretKey key = new SecretKeySpec(this.key, 0, KEY_LENGTH,"AES");
|
||||
|
||||
try {
|
||||
// Initialization
|
||||
ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
|
||||
|
||||
// encrypt
|
||||
if (mo.equalsIgnoreCase("GCM")) {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
} else if (mo.equalsIgnoreCase("ECB")) {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key, (AlgorithmParameterSpec)null);
|
||||
} else {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
|
||||
}
|
||||
|
||||
byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = ci.update(plainText, 0, plainText.length, cipherText,
|
||||
0);
|
||||
ci.doFinal(cipherText, offset);
|
||||
|
||||
if (!mo.equalsIgnoreCase("ECB")) {
|
||||
iv = ci.getIV();
|
||||
aps = new IvParameterSpec(iv);
|
||||
} else {
|
||||
aps = null;
|
||||
}
|
||||
|
||||
if (!mo.equalsIgnoreCase("GCM")) {
|
||||
ci.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
} else {
|
||||
ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters());
|
||||
}
|
||||
|
||||
byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
|
||||
int len = ci.doFinal(cipherText, 0, cipherText.length,
|
||||
recoveredText);
|
||||
|
||||
// Comparison
|
||||
if (!java.util.Arrays.equals(plainText, 0 , plainText.length,
|
||||
recoveredText, 0, len)) {
|
||||
System.out.println("Original: ");
|
||||
System.out.println(HexFormat.of().formatHex(plainText));
|
||||
System.out.println("Recovered: ");
|
||||
System.out.println(HexFormat.of().
|
||||
formatHex(recoveredText, 0, len));
|
||||
throw new RuntimeException("Original text is not equal with " +
|
||||
"recovered text, with mode:" + mo);
|
||||
}
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
//CFB7 and OFB150 are for negative testing
|
||||
if (!mo.equalsIgnoreCase("CFB7") && !mo.equalsIgnoreCase("OFB150")) {
|
||||
System.out.println("Unexpected NoSuchAlgorithmException with" +
|
||||
" mode: " + mo);
|
||||
throw new RuntimeException("Test failed!");
|
||||
}
|
||||
} catch ( NoSuchProviderException | NoSuchPaddingException
|
||||
| InvalidKeyException | InvalidAlgorithmParameterException
|
||||
| ShortBufferException | IllegalBlockSizeException
|
||||
| BadPaddingException e) {
|
||||
System.out.println("Test failed!");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2024, 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 java.io.PrintStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
public class Dynamic {
|
||||
|
||||
static final String ALGORITHM = "AES";
|
||||
static final String[] MODE = {
|
||||
"ECb", "CbC", "CTR", "PCBC", "OFB", "OFB150", "cFB", "CFB7",
|
||||
"cFB8", "cFB16", "cFB24", "cFB32", "Cfb40", "cfB48", "cfB56",
|
||||
"cfB64", "cfB72", "cfB80", "cfB88", "cfB96", "cfb104", "cfB112",
|
||||
"cfB120", "cfB128", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40",
|
||||
"OFB48", "OFB56", "OFB64", "OFB72", "OFB80", "OFB88", "OFB96",
|
||||
"OFB104", "OFB112", "OFB120", "OFB128", "GCM"
|
||||
};
|
||||
static final String[] PADDING = {
|
||||
"NoPadding", "PKCS5Padding", "ISO10126Padding"
|
||||
};
|
||||
static final String PROVIDER = System.getProperty("test.provider.name", "SunJCE");
|
||||
|
||||
Cipher ci = null;
|
||||
byte[] iv = null;
|
||||
AlgorithmParameterSpec aps = null;
|
||||
SecretKey key = null;
|
||||
int keyStrength;
|
||||
static int DefaultSize = 128;
|
||||
|
||||
public void run(String[] argv) throws Exception {
|
||||
if (!runAllTest(argv, System.out)) {
|
||||
throw new Exception("Test Failed");
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean runAllTest(String argv[], PrintStream out) {
|
||||
boolean result = true;
|
||||
StringBuilder failedList = new StringBuilder();
|
||||
int failedCnt = 0;
|
||||
int testCount = 0;
|
||||
int padKinds; // how many kinds of padding mode such as PKCS5padding and
|
||||
// NoPadding.
|
||||
|
||||
try {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
keyStrength = DefaultSize + i * 64; // obtain the key size 128,
|
||||
// 192, 256
|
||||
|
||||
for (int j = 0; j < MODE.length; j++) {
|
||||
if (MODE[j].equalsIgnoreCase("ECB")
|
||||
|| MODE[j].equalsIgnoreCase("PCBC")
|
||||
|| MODE[j].equalsIgnoreCase("CBC")) {
|
||||
padKinds = PADDING.length;
|
||||
} else {
|
||||
padKinds = 1;
|
||||
}
|
||||
|
||||
for (int k = 0; k < padKinds; k++) {
|
||||
testCount++;
|
||||
try {
|
||||
if (!runTest(ALGORITHM, MODE[j], PADDING[k])) {
|
||||
result = false;
|
||||
failedCnt++;
|
||||
failedList.append(ALGORITHM + "/" + MODE[j]
|
||||
+ "/" + PADDING[k] + " ");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
result = false;
|
||||
failedCnt++;
|
||||
failedList.append(ALGORITHM + "/" + MODE[j] + "/"
|
||||
+ PADDING[k] + " ");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
out.println("STATUS:Passed. Test " + testCount
|
||||
+ " cases, All Passed");
|
||||
return true;
|
||||
}
|
||||
out.println("STATUS:Failed. " + failedCnt + " Failed: "
|
||||
+ failedList);
|
||||
return false;
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
out.println("STATUS:Failed. Unexpected Exception: " + ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean runTest(String algo, String mo, String pad)
|
||||
throws Exception {
|
||||
boolean result = true;
|
||||
try {
|
||||
byte[] plainText = new byte[160000];
|
||||
new Random().nextBytes(plainText);
|
||||
|
||||
String transformation = algo + "/" + mo + "/" + pad;
|
||||
ci = Cipher.getInstance(transformation, PROVIDER);
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER);
|
||||
if (keyStrength > Cipher.getMaxAllowedKeyLength(transformation)) {
|
||||
// skip if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
System.out.println(keyStrength
|
||||
+ " is larger than what's configured "
|
||||
+ "in the jce jurisdiction policy files");
|
||||
return result;
|
||||
}
|
||||
kg.init(keyStrength);
|
||||
key = kg.generateKey();
|
||||
|
||||
if (!mo.equalsIgnoreCase("GCM")) {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
} else {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
}
|
||||
byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = ci.update(plainText, 0, plainText.length, cipherText,
|
||||
0);
|
||||
ci.doFinal(cipherText, offset);
|
||||
ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters());
|
||||
|
||||
byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
|
||||
int len = ci.doFinal(cipherText, 0, cipherText.length,
|
||||
recoveredText);
|
||||
|
||||
byte[] tmp = new byte[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
tmp[i] = recoveredText[i];
|
||||
}
|
||||
|
||||
result = Arrays.equals(plainText, tmp);
|
||||
} catch (NoSuchAlgorithmException nsaEx) {
|
||||
// CFB7 and OFB150 are negative test,SunJCE not support this
|
||||
// algorithm
|
||||
result = mo.equalsIgnoreCase("CFB7")
|
||||
|| mo.equalsIgnoreCase("OFB150");
|
||||
if (!result) {
|
||||
// only report unexpected exception
|
||||
nsaEx.printStackTrace();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2015, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044193
|
||||
* @summary Test AES ciphers with different modes and padding schemes with
|
||||
* default provider
|
||||
*/
|
||||
|
||||
public class TestAESWithDefaultProvider extends Dynamic {
|
||||
public static void main(String argv[]) throws Exception {
|
||||
new TestAESWithDefaultProvider().run(argv);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* Copyright (c) 2012, 2024, 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 java.security.Security;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044193
|
||||
* @summary Test AES ciphers with different modes and padding schemes after
|
||||
* remove then add provider.
|
||||
* @modules java.base/com.sun.crypto.provider
|
||||
*/
|
||||
|
||||
public class TestAESWithProviderChange extends Dynamic {
|
||||
public static void main(String argv[]) throws Exception {
|
||||
Security.removeProvider(PROVIDER);
|
||||
Security.addProvider(new com.sun.crypto.provider.SunJCE());
|
||||
new TestAESWithProviderChange().run(argv);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2024, 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 java.security.*;
|
||||
import java.security.Provider;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044193
|
||||
* @summary Test AES ciphers with different modes and padding schemes after
|
||||
* remove default provider then add it back.
|
||||
*/
|
||||
|
||||
public class TestAESWithRemoveAddProvider extends Dynamic {
|
||||
public static void main(String argv[]) throws Exception {
|
||||
Provider pJCE = Security.getProvider(PROVIDER);
|
||||
Security.removeProvider(PROVIDER);
|
||||
Security.addProvider(pJCE);
|
||||
new TestAESWithRemoveAddProvider().run(argv);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8012637
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main TestCICOWithGCM
|
||||
* @summary Test CipherInputStream/OutputStream with AES GCM mode.
|
||||
* @author Valerie Peng
|
||||
* @key randomness
|
||||
*/
|
||||
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.math.*;
|
||||
import java.io.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TestCICOWithGCM {
|
||||
public static void main(String[] args) throws Exception {
|
||||
//init Secret Key
|
||||
KeyGenerator kg = KeyGenerator.getInstance("AES",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
kg.init(128);
|
||||
SecretKey key = kg.generateKey();
|
||||
|
||||
//do initialization of the plainText
|
||||
byte[] plainText = new byte[800];
|
||||
Random rdm = new Random();
|
||||
rdm.nextBytes(plainText);
|
||||
|
||||
//init ciphers
|
||||
Cipher encCipher = Cipher.getInstance("AES/GCM/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
encCipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
Cipher decCipher = Cipher.getInstance("AES/GCM/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
decCipher.init(Cipher.DECRYPT_MODE, key, encCipher.getParameters());
|
||||
|
||||
//init cipher streams
|
||||
ByteArrayInputStream baInput = new ByteArrayInputStream(plainText);
|
||||
CipherInputStream ciInput = new CipherInputStream(baInput, encCipher);
|
||||
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
|
||||
CipherOutputStream ciOutput = new CipherOutputStream(baOutput, decCipher);
|
||||
|
||||
//do test
|
||||
byte[] buffer = new byte[800];
|
||||
int len = ciInput.read(buffer);
|
||||
System.out.println("read " + len + " bytes from input buffer");
|
||||
|
||||
while (len != -1) {
|
||||
ciOutput.write(buffer, 0, len);
|
||||
System.out.println("wite " + len + " bytes to output buffer");
|
||||
len = ciInput.read(buffer);
|
||||
if (len != -1) {
|
||||
System.out.println("read " + len + " bytes from input buffer");
|
||||
} else {
|
||||
System.out.println("finished reading");
|
||||
}
|
||||
}
|
||||
|
||||
ciOutput.flush();
|
||||
ciInput.close();
|
||||
ciOutput.close();
|
||||
byte[] recovered = baOutput.toByteArray();
|
||||
System.out.println("recovered " + recovered.length + " bytes");
|
||||
if (!Arrays.equals(plainText, recovered)) {
|
||||
throw new RuntimeException("diff check failed!");
|
||||
} else {
|
||||
System.out.println("diff check passed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8012900
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main TestCICOWithGCMAndAAD
|
||||
* @summary Test CipherInputStream/OutputStream with AES GCM mode with AAD.
|
||||
* @author Valerie Peng
|
||||
* @key randomness
|
||||
*/
|
||||
import java.io.*;
|
||||
import java.security.*;
|
||||
import java.util.*;
|
||||
import javax.crypto.*;
|
||||
|
||||
public class TestCICOWithGCMAndAAD {
|
||||
public static void main(String[] args) throws Exception {
|
||||
//init Secret Key
|
||||
KeyGenerator kg = KeyGenerator.getInstance("AES",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
kg.init(128);
|
||||
SecretKey key = kg.generateKey();
|
||||
|
||||
//Do initialization of the plainText
|
||||
byte[] plainText = new byte[700];
|
||||
Random rdm = new Random();
|
||||
rdm.nextBytes(plainText);
|
||||
|
||||
byte[] aad = new byte[128];
|
||||
rdm.nextBytes(aad);
|
||||
byte[] aad2 = aad.clone();
|
||||
aad2[50]++;
|
||||
|
||||
Cipher encCipher = Cipher.getInstance("AES/GCM/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
encCipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
encCipher.updateAAD(aad);
|
||||
Cipher decCipher = Cipher.getInstance("AES/GCM/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
decCipher.init(Cipher.DECRYPT_MODE, key, encCipher.getParameters());
|
||||
decCipher.updateAAD(aad);
|
||||
|
||||
byte[] recovered = test(encCipher, decCipher, plainText);
|
||||
if (!Arrays.equals(plainText, recovered)) {
|
||||
throw new Exception("sameAAD: diff check failed!");
|
||||
} else System.out.println("sameAAD: passed");
|
||||
|
||||
encCipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
encCipher.updateAAD(aad2);
|
||||
recovered = test(encCipher, decCipher, plainText);
|
||||
if (recovered != null && recovered.length != 0) {
|
||||
throw new Exception("diffAAD: no data should be returned!");
|
||||
} else System.out.println("diffAAD: passed");
|
||||
}
|
||||
|
||||
private static byte[] test(Cipher encCipher, Cipher decCipher, byte[] plainText)
|
||||
throws Exception {
|
||||
//init cipher streams
|
||||
ByteArrayInputStream baInput = new ByteArrayInputStream(plainText);
|
||||
CipherInputStream ciInput = new CipherInputStream(baInput, encCipher);
|
||||
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
|
||||
CipherOutputStream ciOutput = new CipherOutputStream(baOutput, decCipher);
|
||||
|
||||
//do test
|
||||
byte[] buffer = new byte[200];
|
||||
int len = ciInput.read(buffer);
|
||||
System.out.println("read " + len + " bytes from input buffer");
|
||||
|
||||
while (len != -1) {
|
||||
ciOutput.write(buffer, 0, len);
|
||||
System.out.println("wite " + len + " bytes to output buffer");
|
||||
len = ciInput.read(buffer);
|
||||
if (len != -1) {
|
||||
System.out.println("read " + len + " bytes from input buffer");
|
||||
} else {
|
||||
System.out.println("finished reading");
|
||||
}
|
||||
}
|
||||
|
||||
ciOutput.flush();
|
||||
ciInput.close();
|
||||
ciOutput.close();
|
||||
|
||||
return baOutput.toByteArray();
|
||||
}
|
||||
}
|
||||
184
test/jdk/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java
Normal file
184
test/jdk/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8026943 8027575
|
||||
* @summary Verify that same buffer can be used as input and output when
|
||||
* using Cipher objects.
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
public class TestCopySafe {
|
||||
|
||||
private static boolean DEBUG = false;
|
||||
private static int INPUT_LENGTH = 160; // must be multiple of block size
|
||||
private static byte[] PT = new byte[INPUT_LENGTH];
|
||||
private static SecretKey KEY = new SecretKeySpec(new byte[16], "AES");
|
||||
private static byte[] IV = new byte[16];
|
||||
|
||||
private static int[] OFFSETS = { 1, 8, 9, 16, 17, 32, 33 };
|
||||
|
||||
private static final String[] MODES = {
|
||||
"ECB", "CBC", "PCBC", "CTR", "CTS",
|
||||
"CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40",
|
||||
"CFB48", "CFB56", "CFB64",
|
||||
"OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40",
|
||||
"OFB48", "OFB56", "OFB64",
|
||||
"GCM"
|
||||
};
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
|
||||
Provider p = Security.getProvider(
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
|
||||
AlgorithmParameterSpec params = null;
|
||||
boolean result = true;
|
||||
for (String mode : MODES) {
|
||||
String transformation = "AES/" + mode + "/NoPadding";
|
||||
boolean isGCM = (mode == "GCM");
|
||||
if (isGCM) {
|
||||
params = new GCMParameterSpec(128, IV);
|
||||
} else if (mode != "ECB") {
|
||||
params = new IvParameterSpec(IV);
|
||||
}
|
||||
Cipher c = Cipher.getInstance(transformation, p);
|
||||
System.out.println("Testing " + transformation + ":");
|
||||
for (int offset : OFFSETS) {
|
||||
System.out.print("=> offset " + offset + ": ");
|
||||
try {
|
||||
test(c, params, offset, isGCM);
|
||||
System.out.println("Passed");
|
||||
} catch(Exception ex) {
|
||||
ex.printStackTrace();
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result) {
|
||||
throw new Exception("One or more test failed");
|
||||
}
|
||||
}
|
||||
|
||||
private static void test(Cipher c, AlgorithmParameterSpec params,
|
||||
int offset, boolean isGCM) throws Exception {
|
||||
|
||||
// Test encryption first
|
||||
if (isGCM) {
|
||||
// re-init with only key value first to bypass the
|
||||
// Key+IV-uniqueness check for GCM encryption
|
||||
c.init(Cipher.ENCRYPT_MODE, KEY);
|
||||
}
|
||||
c.init(Cipher.ENCRYPT_MODE, KEY, params);
|
||||
byte[] answer = c.doFinal(PT);
|
||||
byte[] pt2 = Arrays.copyOf(PT, answer.length + offset);
|
||||
|
||||
// #1: outOfs = inOfs = 0
|
||||
if (isGCM) {
|
||||
c.init(Cipher.ENCRYPT_MODE, KEY);
|
||||
c.init(Cipher.ENCRYPT_MODE, KEY, params);
|
||||
}
|
||||
c.doFinal(pt2, 0, PT.length, pt2, 0);
|
||||
if (!isTwoArraysEqual(pt2, 0, answer, 0, answer.length)) {
|
||||
throw new Exception("Enc#1 diff check failed!");
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Enc#1 diff check passed");
|
||||
}
|
||||
|
||||
// #2: inOfs = 0, outOfs = offset
|
||||
System.arraycopy(PT, 0, pt2, 0, PT.length);
|
||||
if (isGCM) {
|
||||
c.init(Cipher.ENCRYPT_MODE, KEY);
|
||||
c.init(Cipher.ENCRYPT_MODE, KEY, params);
|
||||
}
|
||||
c.doFinal(pt2, 0, PT.length, pt2, offset);
|
||||
if (!isTwoArraysEqual(pt2, offset, answer, 0, answer.length)) {
|
||||
throw new Exception("Enc#2 diff check failed");
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Enc#2 diff check passed");
|
||||
}
|
||||
|
||||
// #3: inOfs = offset, outOfs = 0
|
||||
System.arraycopy(PT, 0, pt2, offset, PT.length);
|
||||
if (isGCM) {
|
||||
c.init(Cipher.ENCRYPT_MODE, KEY);
|
||||
c.init(Cipher.ENCRYPT_MODE, KEY, params);
|
||||
}
|
||||
c.doFinal(pt2, offset, PT.length, pt2, 0);
|
||||
if (!isTwoArraysEqual(pt2, 0, answer, 0, answer.length)) {
|
||||
throw new Exception("Enc#3 diff check failed");
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Enc#3 diff check passed");
|
||||
}
|
||||
|
||||
// Test decryption now, we should get back PT as a result
|
||||
c.init(Cipher.DECRYPT_MODE, KEY, params);
|
||||
pt2 = Arrays.copyOf(answer, answer.length + offset);
|
||||
|
||||
// #1: outOfs = inOfs = 0
|
||||
c.doFinal(pt2, 0, answer.length, pt2, 0);
|
||||
if (!isTwoArraysEqual(pt2, 0, PT, 0, PT.length)) {
|
||||
throw new Exception("Dec#1 diff check failed!");
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Dec#1 diff check passed");
|
||||
}
|
||||
|
||||
// #2: inOfs = 0, outOfs = offset
|
||||
System.arraycopy(answer, 0, pt2, 0, answer.length);
|
||||
c.doFinal(pt2, 0, answer.length, pt2, offset);
|
||||
if (!isTwoArraysEqual(pt2, offset, PT, 0, PT.length)) {
|
||||
throw new Exception("Dec#2 diff check failed");
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Dec#2 diff check passed");
|
||||
}
|
||||
|
||||
// #3: inOfs = offset, outOfs = 0
|
||||
System.arraycopy(answer, 0, pt2, offset, answer.length);
|
||||
c.doFinal(pt2, offset, answer.length, pt2, 0);
|
||||
if (!isTwoArraysEqual(pt2, 0, PT, 0, PT.length)) {
|
||||
throw new Exception("Dec#3 diff check failed");
|
||||
} else if (DEBUG) {
|
||||
System.out.println("Dec#3 diff check passed");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isTwoArraysEqual(byte[] a, int aOff, byte[] b, int bOff,
|
||||
int len) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (a[aOff + i] != b[bOff + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6996769
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main TestGCMKeyAndIvCheck
|
||||
* @summary Ensure that same key+iv can't be repeated used for encryption.
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
|
||||
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.math.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TestGCMKeyAndIvCheck {
|
||||
|
||||
private static final byte[] AAD = new byte[5];
|
||||
private static final byte[] PT = new byte[18];
|
||||
|
||||
private static void checkISE(Cipher c) throws Exception {
|
||||
// Subsequent encryptions should fail
|
||||
try {
|
||||
c.updateAAD(AAD);
|
||||
throw new Exception("Should throw ISE for updateAAD()");
|
||||
} catch (IllegalStateException ise) {
|
||||
// expected
|
||||
}
|
||||
|
||||
try {
|
||||
c.update(PT);
|
||||
throw new Exception("Should throw ISE for update()");
|
||||
} catch (IllegalStateException ise) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
c.doFinal(PT);
|
||||
throw new Exception("Should throw ISE for doFinal()");
|
||||
} catch (IllegalStateException ise) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void test() throws Exception {
|
||||
Cipher c = Cipher.getInstance("AES/GCM/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
|
||||
SecretKey key = new SecretKeySpec(new byte[16], "AES");
|
||||
// First try parameter-less init.
|
||||
c.init(Cipher.ENCRYPT_MODE, key);
|
||||
c.updateAAD(AAD);
|
||||
byte[] ctPlusTag = c.doFinal(PT);
|
||||
|
||||
// subsequent encryption should fail unless re-init w/ different key+iv
|
||||
checkISE(c);
|
||||
|
||||
// Validate the retrieved parameters against the IV and tag length.
|
||||
AlgorithmParameters params = c.getParameters();
|
||||
if (params == null) {
|
||||
throw new Exception("getParameters() should not return null");
|
||||
}
|
||||
GCMParameterSpec spec = params.getParameterSpec(GCMParameterSpec.class);
|
||||
if (spec.getTLen() != (ctPlusTag.length - PT.length)*8) {
|
||||
throw new Exception("Parameters contains incorrect TLen value");
|
||||
}
|
||||
if (!Arrays.equals(spec.getIV(), c.getIV())) {
|
||||
throw new Exception("Parameters contains incorrect IV value");
|
||||
}
|
||||
|
||||
// Should be ok to use the same key+iv for decryption
|
||||
c.init(Cipher.DECRYPT_MODE, key, params);
|
||||
c.updateAAD(AAD);
|
||||
byte[] recovered = c.doFinal(ctPlusTag);
|
||||
if (!Arrays.equals(recovered, PT)) {
|
||||
throw new Exception("decryption result mismatch");
|
||||
}
|
||||
|
||||
// Now try to encrypt again using the same key+iv; should fail also
|
||||
try {
|
||||
c.init(Cipher.ENCRYPT_MODE, key, params);
|
||||
throw new Exception("Should throw exception when same key+iv is used");
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// expected
|
||||
}
|
||||
|
||||
// Now try to encrypt again using parameter-less init; should work
|
||||
c.init(Cipher.ENCRYPT_MODE, key);
|
||||
c.doFinal(PT);
|
||||
|
||||
// make sure a different iv is used
|
||||
byte[] iv = c.getIV();
|
||||
if (Arrays.equals(spec.getIV(), iv)) {
|
||||
throw new Exception("IV should be different now");
|
||||
}
|
||||
|
||||
// Now try to encrypt again using a different parameter; should work
|
||||
c.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, new byte[30]));
|
||||
c.updateAAD(AAD);
|
||||
c.doFinal(PT);
|
||||
// subsequent encryption should fail unless re-init w/ different key+iv
|
||||
checkISE(c);
|
||||
|
||||
// Now try decryption twice in a row; no re-init required and
|
||||
// same parameters is used.
|
||||
c.init(Cipher.DECRYPT_MODE, key, params);
|
||||
c.updateAAD(AAD);
|
||||
recovered = c.doFinal(ctPlusTag);
|
||||
|
||||
c.updateAAD(AAD);
|
||||
recovered = c.doFinal(ctPlusTag);
|
||||
if (!Arrays.equals(recovered, PT)) {
|
||||
throw new Exception("decryption result mismatch");
|
||||
}
|
||||
|
||||
// Now try decryption again and re-init using the same parameters
|
||||
c.init(Cipher.DECRYPT_MODE, key, params);
|
||||
c.updateAAD(AAD);
|
||||
recovered = c.doFinal(ctPlusTag);
|
||||
|
||||
// init to decrypt w/o parameters; should fail with IKE as
|
||||
// javadoc specified
|
||||
try {
|
||||
c.init(Cipher.DECRYPT_MODE, key);
|
||||
throw new Exception("Should throw IKE for dec w/o params");
|
||||
} catch (InvalidKeyException ike) {
|
||||
// expected
|
||||
}
|
||||
|
||||
// Lastly, try encryption AND decryption w/ wrong type of parameters,
|
||||
// e.g. IvParameterSpec
|
||||
try {
|
||||
c.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
|
||||
throw new Exception("Should throw IAPE");
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
|
||||
throw new Exception("Should throw IAPE");
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// expected
|
||||
}
|
||||
|
||||
System.out.println("Test Passed!");
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
TestGCMKeyAndIvCheck t = new TestGCMKeyAndIvCheck();
|
||||
t.test();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Google LLC. 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 8371864
|
||||
* @run main/othervm/timeout=600 TestGCMSplitBound
|
||||
* @requires (os.simpleArch == "x64" & (vm.cpu.features ~= ".*avx2.*" |
|
||||
* vm.cpu.features ~= ".*avx512.*"))
|
||||
* @summary Test GaloisCounterMode.implGCMCrypt0 AVX512/AVX2 intrinsics.
|
||||
*/
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class TestGCMSplitBound {
|
||||
|
||||
static final SecureRandom SECURE_RANDOM = newDefaultSecureRandom();
|
||||
|
||||
private static SecureRandom newDefaultSecureRandom() {
|
||||
SecureRandom retval = new SecureRandom();
|
||||
retval.nextLong(); // force seeding
|
||||
return retval;
|
||||
}
|
||||
|
||||
private static byte[] randBytes(int size) {
|
||||
byte[] rand = new byte[size];
|
||||
SECURE_RANDOM.nextBytes(rand);
|
||||
return rand;
|
||||
}
|
||||
|
||||
private static final int IV_SIZE_IN_BYTES = 12;
|
||||
private static final int TAG_SIZE_IN_BYTES = 16;
|
||||
|
||||
private Cipher getCipher(final byte[] key, final byte[] aad,
|
||||
final byte[] nonce, int mode)
|
||||
throws Exception {
|
||||
SecretKey keySpec = new SecretKeySpec(key, "AES");
|
||||
AlgorithmParameterSpec params =
|
||||
new GCMParameterSpec(8 * TAG_SIZE_IN_BYTES, nonce, 0, nonce.length);
|
||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
cipher.init(mode, keySpec, params);
|
||||
if (aad != null && aad.length != 0) {
|
||||
cipher.updateAAD(aad);
|
||||
}
|
||||
return cipher;
|
||||
}
|
||||
|
||||
private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext,
|
||||
final byte[] aad)
|
||||
throws Exception {
|
||||
byte[] nonce = randBytes(IV_SIZE_IN_BYTES);
|
||||
Cipher cipher = getCipher(key, aad, nonce, Cipher.ENCRYPT_MODE);
|
||||
int outputSize = cipher.getOutputSize(plaintext.length);
|
||||
int len = IV_SIZE_IN_BYTES + outputSize;
|
||||
byte[] output = new byte[len];
|
||||
System.arraycopy(nonce, 0, output, 0, IV_SIZE_IN_BYTES);
|
||||
cipher.doFinal(plaintext, 0, plaintext.length, output,
|
||||
IV_SIZE_IN_BYTES);
|
||||
return output;
|
||||
}
|
||||
|
||||
private byte[] gcmDecrypt(final byte[] key, final byte[] ciphertext,
|
||||
final byte[] aad)
|
||||
throws Exception {
|
||||
byte[] nonce = new byte[IV_SIZE_IN_BYTES];
|
||||
System.arraycopy(ciphertext, 0, nonce, 0, IV_SIZE_IN_BYTES);
|
||||
Cipher cipher = getCipher(key, aad, nonce, Cipher.DECRYPT_MODE);
|
||||
return cipher.doFinal(ciphertext, IV_SIZE_IN_BYTES,
|
||||
ciphertext.length - IV_SIZE_IN_BYTES);
|
||||
}
|
||||
|
||||
// x86-64 parallel intrinsic data size
|
||||
private static final int PARALLEL_LEN = 512;
|
||||
// max data size for x86-64 intrinsic
|
||||
private static final int SPLIT_LEN = 1048576; // 1MB
|
||||
|
||||
private void encryptAndDecrypt(byte[] key, byte[] aad, byte[] message,
|
||||
int messageSize)
|
||||
throws Exception {
|
||||
byte[] ciphertext = gcmEncrypt(key, message, aad);
|
||||
byte[] decrypted = gcmDecrypt(key, ciphertext, aad);
|
||||
if (ciphertext == null) {
|
||||
throw new RuntimeException("ciphertext is null");
|
||||
}
|
||||
if (Arrays.compare(decrypted, 0, messageSize,
|
||||
message, 0, messageSize) != 0) {
|
||||
throw new RuntimeException(
|
||||
"Decrypted message is different from the original message");
|
||||
}
|
||||
}
|
||||
|
||||
private void run() throws Exception {
|
||||
byte[] aad = randBytes(20);
|
||||
byte[] key = randBytes(16);
|
||||
// Force JIT.
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
byte[] message = randBytes(PARALLEL_LEN);
|
||||
encryptAndDecrypt(key, aad, message, PARALLEL_LEN);
|
||||
}
|
||||
for (int messageSize = SPLIT_LEN - 300; messageSize <= SPLIT_LEN + 300;
|
||||
messageSize++) {
|
||||
byte[] message = randBytes(messageSize);
|
||||
try {
|
||||
encryptAndDecrypt(key, aad, message, messageSize);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed for messageSize "
|
||||
+ Integer.toHexString(messageSize), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
TestGCMSplitBound test = new TestGCMSplitBound();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
test.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
187
test/jdk/com/sun/crypto/provider/Cipher/AES/TestGHASH.java
Normal file
187
test/jdk/com/sun/crypto/provider/Cipher/AES/TestGHASH.java
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Red Hat, Inc.
|
||||
* Copyright (c) 2015, Oracle, Inc.
|
||||
* 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 8069072
|
||||
* @modules java.base/com.sun.crypto.provider:open
|
||||
* @summary Test vectors for com.sun.crypto.provider.GHASH.
|
||||
*
|
||||
* Single iteration to verify software-only GHASH algorithm.
|
||||
* @run main TestGHASH
|
||||
*
|
||||
* Multi-iteration to verify test intrinsics GHASH, if available.
|
||||
* Many iterations are needed so we are sure hotspot will use intrinsic
|
||||
* @run main TestGHASH -n 10000
|
||||
*/
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class TestGHASH {
|
||||
|
||||
private final Constructor<?> GHASH;
|
||||
private final Method UPDATE;
|
||||
private final Method DIGEST;
|
||||
|
||||
TestGHASH(String className) throws Exception {
|
||||
Class<?> cls = Class.forName(className);
|
||||
GHASH = cls.getDeclaredConstructor(byte[].class);
|
||||
GHASH.setAccessible(true);
|
||||
UPDATE = cls.getDeclaredMethod("update", byte[].class);
|
||||
UPDATE.setAccessible(true);
|
||||
DIGEST = cls.getDeclaredMethod("digest");
|
||||
DIGEST.setAccessible(true);
|
||||
}
|
||||
|
||||
|
||||
private Object newGHASH(byte[] H) throws Exception {
|
||||
return GHASH.newInstance(H);
|
||||
}
|
||||
|
||||
private void updateGHASH(Object hash, byte[] data)
|
||||
throws Exception {
|
||||
UPDATE.invoke(hash, data);
|
||||
}
|
||||
|
||||
private byte[] digestGHASH(Object hash) throws Exception {
|
||||
return (byte[]) DIGEST.invoke(hash);
|
||||
}
|
||||
|
||||
private static final String HEX_DIGITS = "0123456789abcdef";
|
||||
|
||||
private static String hex(byte[] bs) {
|
||||
StringBuilder sb = new StringBuilder(2 * bs.length);
|
||||
for (byte b : bs) {
|
||||
sb.append(HEX_DIGITS.charAt((b >> 4) & 0xF));
|
||||
sb.append(HEX_DIGITS.charAt(b & 0xF));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static byte[] bytes(String hex) {
|
||||
if ((hex.length() & 1) != 0) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
byte[] result = new byte[hex.length() / 2];
|
||||
for (int i = 0; i < result.length; ++i) {
|
||||
int a = HEX_DIGITS.indexOf(hex.charAt(2 * i));
|
||||
int b = HEX_DIGITS.indexOf(hex.charAt(2 * i + 1));
|
||||
if ((a | b) < 0) {
|
||||
if (a < 0) {
|
||||
throw new AssertionError(
|
||||
"bad character " + (int) hex.charAt(2 * i));
|
||||
}
|
||||
throw new AssertionError(
|
||||
"bad character " + (int) hex.charAt(2 * i + 1));
|
||||
}
|
||||
result[i] = (byte) ((a << 4) | b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] bytes(long L0, long L1) {
|
||||
return ByteBuffer.allocate(16)
|
||||
.putLong(L0)
|
||||
.putLong(L1)
|
||||
.array();
|
||||
}
|
||||
|
||||
private void check(int testCase, String H, String A,
|
||||
String C, String expected) throws Exception {
|
||||
int lenA = A.length() * 4;
|
||||
while ((A.length() % 32) != 0) {
|
||||
A += '0';
|
||||
}
|
||||
int lenC = C.length() * 4;
|
||||
while ((C.length() % 32) != 0) {
|
||||
C += '0';
|
||||
}
|
||||
|
||||
Object hash = newGHASH(bytes(H));
|
||||
updateGHASH(hash, bytes(A));
|
||||
updateGHASH(hash, bytes(C));
|
||||
updateGHASH(hash, bytes(lenA, lenC));
|
||||
byte[] digest = digestGHASH(hash);
|
||||
String actual = hex(digest);
|
||||
if (!expected.equals(actual)) {
|
||||
throw new AssertionError(String.format("%d: expected %s, got %s",
|
||||
testCase, expected, actual));
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
TestGHASH test;
|
||||
String test_class = "com.sun.crypto.provider.GHASH";
|
||||
int i = 0;
|
||||
int num_of_loops = 1;
|
||||
while (args.length > i) {
|
||||
if (args[i].compareTo("-c") == 0) {
|
||||
test_class = args[++i];
|
||||
} else if (args[i].compareTo("-n") == 0) {
|
||||
num_of_loops = Integer.parseInt(args[++i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
System.out.println("Running " + num_of_loops + " iterations.");
|
||||
test = new TestGHASH(test_class);
|
||||
i = 0;
|
||||
|
||||
while (num_of_loops > i) {
|
||||
// Test vectors from David A. McGrew, John Viega,
|
||||
// "The Galois/Counter Mode of Operation (GCM)", 2005.
|
||||
// <http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf>
|
||||
test.check(1, "66e94bd4ef8a2c3b884cfa59ca342b2e", "", "",
|
||||
"00000000000000000000000000000000");
|
||||
test.check(2,
|
||||
"66e94bd4ef8a2c3b884cfa59ca342b2e", "",
|
||||
"0388dace60b6a392f328c2b971b2fe78",
|
||||
"f38cbb1ad69223dcc3457ae5b6b0f885");
|
||||
test.check(3,
|
||||
"b83b533708bf535d0aa6e52980d53b78", "",
|
||||
"42831ec2217774244b7221b784d0d49c" +
|
||||
"e3aa212f2c02a4e035c17e2329aca12e" +
|
||||
"21d514b25466931c7d8f6a5aac84aa05" +
|
||||
"1ba30b396a0aac973d58e091473f5985",
|
||||
"7f1b32b81b820d02614f8895ac1d4eac");
|
||||
test.check(4,
|
||||
"b83b533708bf535d0aa6e52980d53b78",
|
||||
"feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
|
||||
"42831ec2217774244b7221b784d0d49c" +
|
||||
"e3aa212f2c02a4e035c17e2329aca12e" +
|
||||
"21d514b25466931c7d8f6a5aac84aa05" +
|
||||
"1ba30b396a0aac973d58e091",
|
||||
"698e57f70e6ecc7fd9463b7260a9ae5f");
|
||||
test.check(5, "b83b533708bf535d0aa6e52980d53b78",
|
||||
"feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
|
||||
"61353b4c2806934a777ff51fa22a4755" +
|
||||
"699b2a714fcdc6f83766e5f97b6c7423" +
|
||||
"73806900e49f24b22b097544d4896b42" +
|
||||
"4989b5e1ebac0f07c23f4598",
|
||||
"df586bb4c249b92cb6922877e444d37b");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4921443
|
||||
* @summary Ensure ISO10126Padding works correctly.
|
||||
* @author Valerie Peng
|
||||
* @key randomness
|
||||
*/
|
||||
import java.util.Arrays;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.security.Provider;
|
||||
|
||||
public class TestISO10126Padding {
|
||||
private static final String ALGO = "AES";
|
||||
private static final String TRANS = "AES/ECB";
|
||||
private static final int KEYSIZE = 16; // in bytes
|
||||
|
||||
private SecretKey key;
|
||||
|
||||
private TestISO10126Padding() throws Exception {
|
||||
// setup
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGO,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
kg.init(KEYSIZE*8);
|
||||
key = kg.generateKey();
|
||||
}
|
||||
|
||||
private void runTest(int dataLength) throws Exception {
|
||||
// setup
|
||||
byte[] data = new byte[dataLength];
|
||||
new SecureRandom().nextBytes(data);
|
||||
System.out.println("Testing data length: " + dataLength);
|
||||
|
||||
// TEST#1 --
|
||||
// generate the cipher text using manually-supplied
|
||||
// XML Encryption padding
|
||||
Cipher ci = Cipher.getInstance(TRANS + "/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
byte[] paddedData = new byte[ci.getBlockSize()];
|
||||
System.arraycopy(data, 0, paddedData, 0, data.length);
|
||||
int padValue = paddedData.length - data.length;
|
||||
paddedData[paddedData.length-1] = (byte) padValue;
|
||||
byte[] cipherText = ci.doFinal(paddedData);
|
||||
|
||||
// decrypt using ISO10126Padding
|
||||
ci = Cipher.getInstance(TRANS + "/ISO10126Padding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
ci.init(Cipher.DECRYPT_MODE, key);
|
||||
byte[] recovered = ci.doFinal(cipherText);
|
||||
if (!Arrays.equals(data, recovered)) {
|
||||
throw new Exception("TEST#1: decryption failed");
|
||||
}
|
||||
// TEST#2 --
|
||||
// generate the cipher text using ISO10126Padding
|
||||
ci = Cipher.getInstance(TRANS + "/ISO10126Padding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
cipherText = ci.doFinal(data);
|
||||
|
||||
// decrypt using ISO10126Padding
|
||||
ci.init(Cipher.DECRYPT_MODE, key);
|
||||
recovered = ci.doFinal(cipherText);
|
||||
if (!Arrays.equals(data, recovered)) {
|
||||
throw new Exception("TEST#2: decryption failed");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
TestISO10126Padding test = new TestISO10126Padding();
|
||||
for (int i = 0; i<16; i++) {
|
||||
test.runTest(i);
|
||||
}
|
||||
System.out.println("Test Passed");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4635086
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main TestKATForECB_IV
|
||||
* @summary Known Answer Test for AES cipher with ECB mode
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.math.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TestKATForECB_IV
|
||||
{
|
||||
private static final String ALGO = "AES";
|
||||
private static final String MODE = "ECB";
|
||||
private static final String PADDING = "NoPadding";
|
||||
|
||||
//ecb-iv.txt
|
||||
private static String[] PTS = {
|
||||
"000102030405060708090A0B0C0D0E0F",
|
||||
"000102030405060708090A0B0C0D0E0F",
|
||||
"000102030405060708090A0B0C0D0E0F"
|
||||
};
|
||||
private static String[] CTS = {
|
||||
"0A940BB5416EF045F1C39458C653EA5A",
|
||||
"0060BFFE46834BB8DA5CF9A61FF220AE",
|
||||
"5A6E045708FB7196F02E553D02C3A692"
|
||||
};
|
||||
private static String[] KEYS = {
|
||||
"000102030405060708090A0B0C0D0E0F",
|
||||
"000102030405060708090A0B0C0D0E0F1011121314151617",
|
||||
"000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"
|
||||
};
|
||||
|
||||
private static SecretKey constructAESKey(String s) throws Exception {
|
||||
int len = s.length()/2;
|
||||
if ((len != 16) && (len != 24) && (len != 32)) {
|
||||
throw new IllegalArgumentException("Wrong Key Length: " + len);
|
||||
}
|
||||
byte[] rawKeyValue = constructByteArray(s);
|
||||
SecretKeySpec key = new SecretKeySpec(rawKeyValue, "AES");
|
||||
return key;
|
||||
}
|
||||
|
||||
private static byte[] constructByteArray(String s) {
|
||||
int len = s.length()/2;
|
||||
byte[] tempValue = new byte[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
tempValue[i] = Integer.valueOf(s.substring(2*i, 2*i+2),
|
||||
16).byteValue();
|
||||
}
|
||||
return tempValue;
|
||||
|
||||
}
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
String transformation = ALGO+"/"+MODE+"/"+PADDING;
|
||||
Cipher c = Cipher.getInstance(transformation,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
for (int i=0; i<KEYS.length; i++) {
|
||||
SecretKey aesKey = constructAESKey(KEYS[i]);
|
||||
if (aesKey.getEncoded().length*8 >
|
||||
Cipher.getMaxAllowedKeyLength(transformation)) {
|
||||
// skip if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
c.init(Cipher.ENCRYPT_MODE, aesKey);
|
||||
byte[] plainText = constructByteArray(PTS[i]);
|
||||
byte[] cipherText = c.doFinal(plainText);
|
||||
byte[] answer = constructByteArray(CTS[i]);
|
||||
if (!Arrays.equals(cipherText, answer)) {
|
||||
throw new Exception((i+1) + "th known answer test failed for encryption");
|
||||
}
|
||||
|
||||
c.init(Cipher.DECRYPT_MODE, aesKey);
|
||||
byte[] recoveredText = c.doFinal(answer);
|
||||
if (!Arrays.equals(recoveredText, plainText)) {
|
||||
throw new Exception("known answer test failed for decryption");
|
||||
}
|
||||
System.out.println("Finished KAT for " + aesKey.getEncoded().length + "-byte key");
|
||||
} catch (SecurityException se) {
|
||||
TestUtil.handleSE(se);
|
||||
}
|
||||
}
|
||||
|
||||
// passed all tests...hooray!
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
TestKATForECB_IV test = new TestKATForECB_IV();
|
||||
String testName = test.getClass().getName() + "[" + ALGO +
|
||||
"/" + MODE + "/" + PADDING + "]";
|
||||
if (test.execute()) {
|
||||
System.out.println(testName + ": Passed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,756 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4635086
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main TestKATForECB_VK
|
||||
* @summary Known Answer Test for AES cipher with ECB mode
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.math.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TestKATForECB_VK
|
||||
{
|
||||
private static final String ALGO = "AES";
|
||||
private static final String MODE = "ECB";
|
||||
private static final String PADDING = "NoPadding";
|
||||
|
||||
//ecb-vk.txt
|
||||
private static byte[] PT = new byte[16];
|
||||
|
||||
private static String[][] CTS = {
|
||||
// Cipher Texts for 128-bit key
|
||||
{
|
||||
"0EDD33D3C621E546455BD8BA1418BEC8",
|
||||
"C0CC0C5DA5BD63ACD44A80774FAD5222",
|
||||
"2F0B4B71BC77851B9CA56D42EB8FF080",
|
||||
"6B1E2FFFE8A114009D8FE22F6DB5F876",
|
||||
"9AA042C315F94CBB97B62202F83358F5",
|
||||
"DBE01DE67E346A800C4C4B4880311DE4",
|
||||
"C117D2238D53836ACD92DDCDB85D6A21",
|
||||
"DC0ED85DF9611ABB7249CDD168C5467E",
|
||||
"807D678FFF1F56FA92DE3381904842F2",
|
||||
"0E53B3FCAD8E4B130EF73AEB957FB402",
|
||||
"969FFD3B7C35439417E7BDE923035D65",
|
||||
"A99B512C19CA56070491166A1503BF15",
|
||||
"6E9985252126EE344D26AE369D2327E3",
|
||||
"B85F4809F904C275491FCDCD1610387E",
|
||||
"ED365B8D7D20C1F5D53FB94DD211DF7B",
|
||||
"B3A575E86A8DB4A7135D604C43304896",
|
||||
"89704BCB8E69F846259EB0ACCBC7F8A2",
|
||||
"C56EE7C92197861F10D7A92B90882055",
|
||||
"92F296F6846E0EAF9422A5A24A08B069",
|
||||
"E67E32BB8F11DEB8699318BEE9E91A60",
|
||||
"B08EEF85EAF626DD91B65C4C3A97D92B",
|
||||
"661083A6ADDCE79BB4E0859AB5538013",
|
||||
"55DFE2941E0EB10AFC0B333BD34DE1FE",
|
||||
"6BFE5945E715C9662609770F8846087A",
|
||||
"79848E9C30C2F8CDA8B325F7FED2B139",
|
||||
"7A713A53B99FEF34AC04DEEF80965BD0",
|
||||
"18144A2B46620D32C3C32CE52D49257F",
|
||||
"872E827C70887C80749F7B8BB1847C7E",
|
||||
"6B86C6A4FE6A60C59B1A3102F8DE49F3",
|
||||
"9848BB3DFDF6F532F094679A4C231A20",
|
||||
"925AD528E852E329B2091CD3F1C2BCEE",
|
||||
"80DF436544B0DD596722E46792A40CD8",
|
||||
"525DAF18F93E83E1E74BBBDDE4263BBA",
|
||||
"F65C9D2EE485D24701FFA3313B9D5BE6",
|
||||
"E4FC8D8BCA06425BDF94AFA40FCC14BA",
|
||||
"A53F0A5CA1E4E6440BB975FF320DE6F8",
|
||||
"D55313B9394080462E87E02899B553F0",
|
||||
"34A71D761F71BCD344384C7F97D27906",
|
||||
"233F3D819599612EBC89580245C996A8",
|
||||
"B4F1374E5268DBCB676E447529E53F89",
|
||||
"0816BD27861D2BA891D1044E39951E96",
|
||||
"F3BE9EA3F10C73CA64FDE5DB13A951D1",
|
||||
"2448086A8106FBD03048DDF857D3F1C8",
|
||||
"670756E65BEC8B68F03D77CDCDCE7B91",
|
||||
"EF968CF0D36FD6C6EFFD225F6FB44CA9",
|
||||
"2E8767157922E3826DDCEC1B0CC1E105",
|
||||
"78CE7EEC670E45A967BAB17E26A1AD36",
|
||||
"3C5CEE825655F098F6E81A2F417DA3FB",
|
||||
"67BFDB431DCE1292200BC6F5207ADB12",
|
||||
"7540FD38E447C0779228548747843A6F",
|
||||
"B85E513301F8A936EA9EC8A21A85B5E6",
|
||||
"04C67DBF16C11427D507A455DE2C9BC5",
|
||||
"03F75EB8959E55079CFFB4FF149A37B6",
|
||||
"74550287F666C63BB9BC7838433434B0",
|
||||
"7D537200195EBC3AEFD1EAAB1C385221",
|
||||
"CE24E4D40C68A82B535CBD3C8E21652A",
|
||||
"AB20072405AA8FC40265C6F1F3DC8BC0",
|
||||
"6CFD2CF688F566B093F67B9B3839E80A",
|
||||
"BD95977E6B7239D407A012C5544BF584",
|
||||
"DF9C0130AC77E7C72C997F587B46DBE0",
|
||||
"E7F1B82CADC53A648798945B34EFEFF2",
|
||||
"932C6DBF69255CF13EDCDB72233ACEA3",
|
||||
"5C76002BC7206560EFE550C80B8F12CC",
|
||||
"F6B7BDD1CAEEBAB574683893C4475484",
|
||||
"A920E37CC6DC6B31DA8C0169569F5034",
|
||||
"919380ECD9C778BC513148B0C28D65FD",
|
||||
"EE67308DD3F2D9E6C2170755E5784BE1",
|
||||
"3CC73E53B85609023A05E149B223AE09",
|
||||
"983E8AF7CF05EBB28D71EB841C9406E6",
|
||||
"0F3099B2D31FA5299EE5BF43193287FC",
|
||||
"B763D84F38C27FE6931DCEB6715D4DB6",
|
||||
"5AE3C9B0E3CC29C0C61565CD01F8A248",
|
||||
"F58083572CD90981958565D48D2DEE25",
|
||||
"7E6255EEF8F70C0EF10337AAB1CCCEF8",
|
||||
"AAD4BAC34DB22821841CE2F631961902",
|
||||
"D7431C0409BB1441BA9C6858DC7D4E81",
|
||||
"EF9298C65E339F6E801A59C626456993",
|
||||
"53FE29F68FF541ABC3F0EF3350B72F7E",
|
||||
"F6BBA5C10DB02529E2C2DA3FB582CC14",
|
||||
"E4239AA37FC531A386DAD1126FC0E9CD",
|
||||
"8F7758F857D15BBE7BFD0E416404C365",
|
||||
"D273EB57C687BCD1B4EA7218A509E7B8",
|
||||
"65D64F8D76E8B3423FA25C4EB58A210A",
|
||||
"623D802B4EC450D66A16625702FCDBE0",
|
||||
"7496460CB28E5791BAEAF9B68FB00022",
|
||||
"34EA600F18BB0694B41681A49D510C1D",
|
||||
"5F8FF0D47D5766D29B5D6E8F46423BD8",
|
||||
"225F9286C5928BF09F84D3F93F541959",
|
||||
"B21E90D25DF383416A5F072CEBEB1FFB",
|
||||
"4AEFCDA089318125453EB9E8EB5E492E",
|
||||
"4D3E75C6CD40EC4869BC85158591ADB8",
|
||||
"63A8B904405436A1B99D7751866771B7",
|
||||
"64F0DAAE47529199792EAE172BA53293",
|
||||
"C3EEF84BEA18225D515A8C852A9047EE",
|
||||
"A44AC422B47D47B81AF73B3E9AC9596E",
|
||||
"D16E04A8FBC435094F8D53ADF25F5084",
|
||||
"EF13DC34BAB03E124EEAD8B6BF44B532",
|
||||
"D94799075C24DCC067AF0D392049250D",
|
||||
"14F431771EDDCE4764C21A2254B5E3C8",
|
||||
"7039329F36F2ED682B02991F28D64679",
|
||||
"124EE24EDE5551639DB8B8B941F6141D",
|
||||
"C2852879A34D5184E478EC918B993FEE",
|
||||
"86A806A3525B93E432053C9AB5ABBEDF",
|
||||
"C1609BF5A4F07E37C17A36366EC23ECC",
|
||||
"7E81E7CB92159A51FFCEA331B1E8EA53",
|
||||
"37A7BE002856C5A59A6E03EAFCE7729A",
|
||||
"BDF98A5A4F91E890C9A1D1E5FAAB138F",
|
||||
"4E96ACB66E051F2BC739CC3D3E34A26B",
|
||||
"EE996CDD120EB86E21ECFA49E8E1FCF1",
|
||||
"61B9E6B579DBF6070C351A1440DD85FF",
|
||||
"AC369E484316440B40DFC83AA96E28E7",
|
||||
"0A2D16DE985C76D45C579C1159413BBE",
|
||||
"DA3FDC38DA1D374FA4802CDA1A1C6B0F",
|
||||
"B842523D4C41C2211AFE43A5800ADCE3",
|
||||
"9E2CDA90D8E992DBA6C73D8229567192",
|
||||
"D49583B781D9E20F5BE101415957FC49",
|
||||
"EF09DA5C12B376E458B9B8670032498E",
|
||||
"A96BE0463DA774461A5E1D5A9DD1AC10",
|
||||
"32CEE3341060790D2D4B1362EF397090",
|
||||
"21CEA416A3D3359D2C4D58FB6A035F06",
|
||||
"172AEAB3D507678ECAF455C12587ADB7",
|
||||
"B6F897941EF8EBFF9FE80A567EF38478",
|
||||
"A9723259D94A7DC662FB0C782CA3F1DD",
|
||||
"2F91C984B9A4839F30001B9F430493B4",
|
||||
"0472406345A610B048CB99EE0EF3FA0F",
|
||||
"F5F39086646F8C05ED16EFA4B617957C",
|
||||
"26D50F485A30408D5AF47A5736292450",
|
||||
"0545AAD56DA2A97C3663D1432A3D1C84"
|
||||
},
|
||||
// Cipher Texts for 192-bit key
|
||||
{
|
||||
"DE885DC87F5A92594082D02CC1E1B42C",
|
||||
"C749194F94673F9DD2AA1932849630C1",
|
||||
"0CEF643313912934D310297B90F56ECC",
|
||||
"C4495D39D4A553B225FBA02A7B1B87E1",
|
||||
"636D10B1A0BCAB541D680A7970ADC830",
|
||||
"07CF045786BD6AFCC147D99E45A901A7",
|
||||
"6A8E3F425A7599348F95398448827976",
|
||||
"5518276836148A00D91089A20D8BFF57",
|
||||
"F267E07B5E87E3BC20B969C61D4FCB06",
|
||||
"5A1CDE69571D401BFCD20DEBADA2212C",
|
||||
"70A9057263254701D12ADD7D74CD509E",
|
||||
"35713A7E108031279388A33A0FE2E190",
|
||||
"E74EDE82B1254714F0C7B4B243108655",
|
||||
"39272E3100FAA37B55B862320D1B3EB3",
|
||||
"6D6E24C659FC5AEF712F77BCA19C9DD0",
|
||||
"76D18212F972370D3CC2C6C372C6CF2F",
|
||||
"B21A1F0BAE39E55C7594ED570A7783EA",
|
||||
"77DE202111895AC48DD1C974B358B458",
|
||||
"67810B311969012AAF7B504FFAF39FD1",
|
||||
"C22EA2344D3E9417A6BA07843E713AEA",
|
||||
"C79CAF4B97BEE0BD0630AB354539D653",
|
||||
"135FD1AF761D9AE23DF4AA6B86760DB4",
|
||||
"D4659D0B06ACD4D56AB8D11A16FD83B9",
|
||||
"F7D270028FC188E4E4F35A4AAA25D4D4",
|
||||
"345CAE5A8C9620A9913D5473985852FF",
|
||||
"4E8980ADDE60B0E42C0B287FEA41E729",
|
||||
"F11B6D74E1F15155633DC39743C1A527",
|
||||
"9C87916C0180064F9D3179C6F5DD8C35",
|
||||
"71AB186BCAEA518E461D4F7FAD230E6A",
|
||||
"C4A31BBC3DAAF742F9141C2A5001A49C",
|
||||
"E7C47B7B1D40F182A8928C8A55671D07",
|
||||
"8E17F294B28FA373C6249538868A7EEF",
|
||||
"754404096A5CBC08AF09491BE249141A",
|
||||
"101CB56E55F05D86369B6D1069204F0A",
|
||||
"73F19BB6604205C6EE227B9759791E41",
|
||||
"6270C0028F0D136C37A56B2CB64D24D6",
|
||||
"A3BF7C2C38D1114A087ECF212E694346",
|
||||
"49CABFF2CEF7D9F95F5EFB1F7A1A7DDE",
|
||||
"EC7F8A47CC59B849469255AD49F62752",
|
||||
"68FAE55A13EFAF9B07B3552A8A0DC9D1",
|
||||
"211E6B19C69FAEF481F64F24099CDA65",
|
||||
"DBB918C75BC5732416F79FB0C8EE4C5C",
|
||||
"98D494E5D963A6C8B92536D3EC35E3FD",
|
||||
"C9A873404D403D6F074190851D67781A",
|
||||
"073AEF4A7C77D921928CB0DD9D27CAE7",
|
||||
"89BDE25CEE36FDE769A10E52298CF90F",
|
||||
"26D0842D37EAD38557C65E0A5E5F122E",
|
||||
"F8294BA375AF46B3F22905BBAFFAB107",
|
||||
"2AD63EB4D0D43813B979CF72B35BDB94",
|
||||
"7710C171EE0F4EFA39BE4C995180181D",
|
||||
"C0CB2B40DBA7BE8C0698FAE1E4B80FF8",
|
||||
"97970E505194622FD955CA1B80B784E9",
|
||||
"7CB1824B29F850900DF2CAD9CF04C1CF",
|
||||
"FDF4F036BB988E42F2F62DE63FE19A64",
|
||||
"08908CFE2C82606B2C15DF61B75CF3E2",
|
||||
"B3AA689EF2D07FF365ACB9ADBA2AF07A",
|
||||
"F2672CD8EAA3B98776660D0263656F5C",
|
||||
"5BDEAC00E986687B9E1D94A0DA7BF452",
|
||||
"E6D57BD66EA1627363EE0C4B711B0B21",
|
||||
"03730DD6ACB4AD9996A63BE7765EC06F",
|
||||
"A470E361AA5437B2BE8586D2F78DE582",
|
||||
"7567FEEFA559911FD479670246B484E3",
|
||||
"29829DEA15A4E7A4C049045E7B106E29",
|
||||
"A407834C3D89D48A2CB7A152208FA4ED",
|
||||
"68F948053F78FEF0D8F9FE7EF3A89819",
|
||||
"B605174CAB13AD8FE3B20DA3AE7B0234",
|
||||
"CCAB8F0AEBFF032893996D383CBFDBFA",
|
||||
"AF14BB8428C9730B7DC17B6C1CBEBCC8",
|
||||
"5A41A21332040877EB7B89E8E80D19FE",
|
||||
"AC1BA52EFCDDE368B1596F2F0AD893A0",
|
||||
"41B890E31B9045E6ECDC1BC3F2DB9BCC",
|
||||
"4D54A549728E55B19A23660424A0F146",
|
||||
"A917581F41C47C7DDCFFD5285E2D6A61",
|
||||
"604DF24BA6099B93A7405A524D764FCB",
|
||||
"78D9D156F28B190E232D1B7AE7FC730A",
|
||||
"5A12C39E442CD7F27B3CD77F5D029582",
|
||||
"FF2BF2F47CF7B0F28EE25AF95DBF790D",
|
||||
"1863BB7D193BDA39DF090659EB8AE48B",
|
||||
"38178F2FB4CFCF31E87E1ABCDC023EB5",
|
||||
"F5B13DC690CC0D541C6BA533023DC8C9",
|
||||
"48EC05238D7375D126DC9D08884D4827",
|
||||
"ACD0D81139691B310B92A6E377BACC87",
|
||||
"9A4AA43578B55CE9CC178F0D2E162C79",
|
||||
"08AD94BC737DB3C87D49B9E01B720D81",
|
||||
"3BCFB2D5D210E8332900C5991D551A2A",
|
||||
"C5F0C6B9397ACB29635CE1A0DA2D8D96",
|
||||
"844A29EFC693E2FA9900F87FBF5DCD5F",
|
||||
"5126A1C41051FEA158BE41200E1EA59D",
|
||||
"302123CA7B4F46D667FFFB0EB6AA7703",
|
||||
"A9D16BCE7DB5C024277709EE2A88D91A",
|
||||
"F013C5EC123A26CFC34B598C992A996B",
|
||||
"E38A825CD971A1D2E56FB1DBA248F2A8",
|
||||
"6E701773C0311E0BD4C5A097406D22B3",
|
||||
"754262CEF0C64BE4C3E67C35ABE439F7",
|
||||
"C9C2D4C47DF7D55CFA0EE5F1FE5070F4",
|
||||
"6AB4BEA85B172573D8BD2D5F4329F13D",
|
||||
"11F03EF28E2CC9AE5165C587F7396C8C",
|
||||
"0682F2EB1A68BAC7949922C630DD27FA",
|
||||
"ABB0FEC0413D659AFE8E3DCF6BA873BB",
|
||||
"FE86A32E19F805D6569B2EFADD9C92AA",
|
||||
"E434E472275D1837D3D717F2EECC88C3",
|
||||
"74E57DCD12A21D26EF8ADAFA5E60469A",
|
||||
"C275429D6DAD45DDD423FA63C816A9C1",
|
||||
"7F6EC1A9AE729E86F7744AED4B8F4F07",
|
||||
"48B5A71AB9292BD4F9E608EF102636B2",
|
||||
"076FB95D5F536C78CBED3181BCCF3CF1",
|
||||
"BFA76BEA1E684FD3BF9256119EE0BC0F",
|
||||
"7D395923D56577F3FF8670998F8C4A71",
|
||||
"BA02C986E529AC18A882C34BA389625F",
|
||||
"3DFCF2D882AFE75D3A191193013A84B5",
|
||||
"FAD1FDE1D0241784B63080D2C74D236C",
|
||||
"7D6C80D39E41F007A14FB9CD2B2C15CD",
|
||||
"7975F401FC10637BB33EA2DB058FF6EC",
|
||||
"657983865C55A818F02B7FCD52ED7E99",
|
||||
"B32BEB1776F9827FF4C3AC9997E84B20",
|
||||
"2AE2C7C374F0A41E3D46DBC3E66BB59F",
|
||||
"4D835E4ABDD4BDC6B88316A6E931A07F",
|
||||
"E07EFABFF1C353F7384EBB87B435A3F3",
|
||||
"ED3088DC3FAF89AD87B4356FF1BB09C2",
|
||||
"4324D01140C156FC898C2E32BA03FB05",
|
||||
"BE15D016FACB5BAFBC24FA9289132166",
|
||||
"AC9B7048EDB1ACF4D97A5B0B3F50884B",
|
||||
"448BECE1F86C7845DFA9A4BB2A016FB3",
|
||||
"10DD445E87686EB46EA9B1ABC49257F0",
|
||||
"B7FCCF7659FA756D4B7303EEA6C07458",
|
||||
"289117115CA3513BAA7640B1004872C2",
|
||||
"57CB42F7EE7186051F50B93FFA7B35BF",
|
||||
"F2741BFBFB81663B9136802FB9C3126A",
|
||||
"E32DDDC5C7398C096E3BD535B31DB5CE",
|
||||
"81D3C204E608AF9CC713EAEBCB72433F",
|
||||
"D4DEEF4BFC36AAA579496E6935F8F98E",
|
||||
"C356DB082B97802B038571C392C5C8F6",
|
||||
"A3919ECD4861845F2527B77F06AC6A4E",
|
||||
"A53858E17A2F802A20E40D44494FFDA0",
|
||||
"5D989E122B78C758921EDBEEB827F0C0",
|
||||
"4B1C0C8F9E7830CC3C4BE7BD226FA8DE",
|
||||
"82C40C5FD897FBCA7B899C70713573A1",
|
||||
"ED13EE2D45E00F75CCDB51EA8E3E36AD",
|
||||
"F121799EEFE8432423176A3CCF6462BB",
|
||||
"4FA0C06F07997E98271DD86F7B355C50",
|
||||
"849EB364B4E81D058649DC5B1BF029B9",
|
||||
"F48F9E0DE8DE7AD944A207809335D9B1",
|
||||
"E59E9205B5A81A4FD26DFCF308966022",
|
||||
"3A91A1BE14AAE9ED700BDF9D70018804",
|
||||
"8ABAD78DCB79A48D79070E7DA89664EC",
|
||||
"B68377D98AAE6044938A7457F6C649D9",
|
||||
"E4E1275C42F5F1B63D662C099D6CE33D",
|
||||
"7DEF32A34C6BE668F17DA1BB193B06EF",
|
||||
"78B6000CC3D30CB3A74B68D0EDBD2B53",
|
||||
"0A47531DE88DD8AE5C23EAE4F7D1F2D5",
|
||||
"667B24E8000CF68231EC484581D922E5",
|
||||
"39DAA5EBD4AACAE130E9C33236C52024",
|
||||
"E3C88760B3CB21360668A63E55BB45D1",
|
||||
"F131EE903C1CDB49D416866FD5D8DE51",
|
||||
"7A1916135B0447CF4033FC13047A583A",
|
||||
"F7D55FB27991143DCDFA90DDF0424FCB",
|
||||
"EA93E7D1CA1111DBD8F7EC111A848C0C",
|
||||
"2A689E39DFD3CBCBE221326E95888779",
|
||||
"C1CE399CA762318AC2C40D1928B4C57D",
|
||||
"D43FB6F2B2879C8BFAF0092DA2CA63ED",
|
||||
"224563E617158DF97650AF5D130E78A5",
|
||||
"6562FDF6833B7C4F7484AE6EBCC243DD",
|
||||
"93D58BA7BED22615D661D002885A7457",
|
||||
"9A0EF559003AD9E52D3E09ED3C1D3320",
|
||||
"96BAF5A7DC6F3DD27EB4C717A85D261C",
|
||||
"B8762E06884900E8452293190E19CCDB",
|
||||
"785416A22BD63CBABF4B1789355197D3",
|
||||
"A0D20CE1489BAA69A3612DCE90F7ABF6",
|
||||
"700244E93DC94230CC607FFBA0E48F32",
|
||||
"85329E476829F872A2B4A7E59F91FF2D",
|
||||
"E4219B4935D988DB719B8B8B2B53D247",
|
||||
"6ACDD04FD13D4DB4409FE8DD13FD737B",
|
||||
"9EB7A670AB59E15BE582378701C1EC14",
|
||||
"29DF2D6935FE657763BC7A9F22D3D492",
|
||||
"99303359D4A13AFDBE6C784028CE533A",
|
||||
"FF5C70A6334545F33B9DBF7BEA0417CA",
|
||||
"289F58A17E4C50EDA4269EFB3DF55815",
|
||||
"EA35DCB416E9E1C2861D1682F062B5EB",
|
||||
"3A47BF354BE775383C50B0C0A83E3A58",
|
||||
"BF6C1DC069FB95D05D43B01D8206D66B",
|
||||
"046D1D580D5898DA6595F32FD1F0C33D",
|
||||
"5F57803B7B82A110F7E9855D6A546082",
|
||||
"25336ECF34E7BE97862CDFF715FF05A8",
|
||||
"ACBAA2A943D8078022D693890E8C4FEF",
|
||||
"3947597879F6B58E4E2F0DF825A83A38",
|
||||
"4EB8CC3335496130655BF3CA570A4FC0",
|
||||
"BBDA7769AD1FDA425E18332D97868824",
|
||||
"5E7532D22DDB0829A29C868198397154",
|
||||
"E66DA67B630AB7AE3E682855E1A1698E",
|
||||
"4D93800F671B48559A64D1EA030A590A",
|
||||
"F33159FCC7D9AE30C062CD3B322AC764",
|
||||
"8BAE4EFB70D33A9792EEA9BE70889D72"
|
||||
},
|
||||
// Cipher Texts for 256-bit key
|
||||
{
|
||||
"E35A6DCB19B201A01EBCFA8AA22B5759",
|
||||
"5075C2405B76F22F553488CAE47CE90B",
|
||||
"49DF95D844A0145A7DE01C91793302D3",
|
||||
"E7396D778E940B8418A86120E5F421FE",
|
||||
"05F535C36FCEDE4657BE37F4087DB1EF",
|
||||
"D0C1DDDD10DA777C68AB36AF51F2C204",
|
||||
"1C55FB811B5C6464C4E5DE1535A75514",
|
||||
"52917F3AE957D5230D3A2AF57C7B5A71",
|
||||
"C6E3D5501752DD5E9AEF086D6B45D705",
|
||||
"A24A9C7AF1D9B1E17E1C9A3E711B3FA7",
|
||||
"B881ECA724A6D43DBC6B96F6F59A0D20",
|
||||
"EC524D9A24DFFF2A9639879B83B8E137",
|
||||
"34C4F345F5466215A037F443635D6F75",
|
||||
"5BA5055BEDB8895F672E29F2EB5A355D",
|
||||
"B3F692AA3A435259EBBEF9B51AD1E08D",
|
||||
"414FEB4376F2C64A5D2FBB2ED531BA7D",
|
||||
"A20D519E3BCA3303F07E81719F61605E",
|
||||
"A08D10E520AF811F45BD60A2DC0DC4B1",
|
||||
"B06893A8C563C430E6F3858826EFBBE4",
|
||||
"0FFEE26AE2D3929C6BD9C6BEDFF84409",
|
||||
"4D0F5E906ED77801FC0EF53EDC5F9E2B",
|
||||
"8B6EC00119AD8B026DCE56EA7DEFE930",
|
||||
"69026591D43363EE9D83B5007F0B484E",
|
||||
"27135D86950C6A2F86872706279A4761",
|
||||
"35E6DB8723F281DA410C3AC8535ED77C",
|
||||
"57427CF214B8C28E4BBF487CCB8D0E09",
|
||||
"6DF01BF56E5131AC87F96E99CAB86367",
|
||||
"3856C5B55790B768BBF7D43031579BCF",
|
||||
"1E6ED8FB7C15BC4D2F63BA7037ED44D0",
|
||||
"E1B2ED6CD8D93D455534E401156D4BCF",
|
||||
"EFBCCA5BDFDAD10E875F02336212CE36",
|
||||
"0B777F02FD18DCE2646DCFE868DFAFAD",
|
||||
"C8A104B5693D1B14F5BF1F10100BF508",
|
||||
"4CCE6615244AFCB38408FECE219962EA",
|
||||
"F99E7845D3A255B394C9C050CBA258B1",
|
||||
"B4AFBB787F9BCFB7B55FDF447F611295",
|
||||
"AE1C426A697FAF2808B7EF6ADDB5C020",
|
||||
"7572F92811A85B9BDD38DEAD9945BCAE",
|
||||
"71BC7AA46E43FB95A181527D9F6A360F",
|
||||
"5542EF2923066F1EC8F546DD0D8E7CA8",
|
||||
"6B92317C7D623790B748FDD7EFC42422",
|
||||
"0FE7C097E899C71EF045360F8D6C25CF",
|
||||
"4ECE7EE107D0264D04693151C25B9DF6",
|
||||
"FD6AE687CBFCA9E301045888D3BB9605",
|
||||
"476B579C8556C7254424902CC1D6D36E",
|
||||
"4133CBCDFDD6B8860A1FC18665D6D71B",
|
||||
"3B36EC2664798C108B816812C65DFDC7",
|
||||
"364E20A234FEA385D48DC5A09C9E70CF",
|
||||
"4A4BA25969DE3F5EE5642C71AAD0EFD1",
|
||||
"E42CBAAE43297F67A76C1C501BB79E36",
|
||||
"23CEDEDA4C15B4C037E8C61492217937",
|
||||
"A1719147A1F4A1A1180BD16E8593DCDE",
|
||||
"AB82337E9FB0EC60D1F25A1D0014192C",
|
||||
"74BF2D8FC5A8388DF1A3A4D7D33FC164",
|
||||
"D5B493317E6FBC6FFFD664B3C491368A",
|
||||
"BA767381586DA56A2A8D503D5F7ADA0B",
|
||||
"E8E6BC57DFE9CCADB0DECABF4E5CF91F",
|
||||
"3C8E5A5CDC9CEED90815D1F84BB2998C",
|
||||
"283843020BA38F056001B2FD585F7CC9",
|
||||
"D8ADC7426F623ECE8741A70621D28870",
|
||||
"D7C5C215592D06F00E6A80DA69A28EA9",
|
||||
"52CF6FA433C3C870CAC70190358F7F16",
|
||||
"F63D442A584DA71786ADEC9F3346DF75",
|
||||
"549078F4B0CA7079B45F9A5ADAFAFD99",
|
||||
"F2A5986EE4E9984BE2BAFB79EA8152FA",
|
||||
"8A74535017B4DB2776668A1FAE64384C",
|
||||
"E613342F57A97FD95DC088711A5D0ECD",
|
||||
"3FFAEBF6B22CF1DC82AE17CD48175B01",
|
||||
"BAFD52EFA15C248CCBF9757735E6B1CE",
|
||||
"7AF94BC018D9DDD4539D2DD1C6F4000F",
|
||||
"FE177AD61CA0FDB281086FBA8FE76803",
|
||||
"74DBEA15E2E9285BAD163D7D534251B6",
|
||||
"23DD21331B3A92F200FE56FF050FFE74",
|
||||
"A69C5AA34AB20A858CAFA766EACED6D8",
|
||||
"3F72BB4DF2A4F941A4A09CB78F04B97A",
|
||||
"72CC43577E1FD5FD14622D24D97FCDCC",
|
||||
"D83AF8EBE93E0B6B99CAFADE224937D1",
|
||||
"44042329128D56CAA8D084C8BD769D1E",
|
||||
"14102D72290DE4F2C430ADD1ED64BA1D",
|
||||
"449124097B1ECD0AE7065206DF06F03C",
|
||||
"D060A99F8CC153A42E11E5F97BD7584A",
|
||||
"65605B3EA9261488D53E48602ADEA299",
|
||||
"C5E5CAD7A208DE8EA6BE049EFE5C7346",
|
||||
"4C280C46D2181646048DD5BC0C0831A5",
|
||||
"5DD65CF37F2A0929559AABAFDA08E730",
|
||||
"31F2335CAAF264172F69A693225E6D22",
|
||||
"3E28B35F99A72662590DA96426DD377F",
|
||||
"570F40F5D7B20441486578ED344343BE",
|
||||
"C54308AD1C9E3B19F8B7417873045A8C",
|
||||
"CBF335E39CE13ADE2B696179E8FD0CE1",
|
||||
"9C2FBF422355D8293083D51F4A3C18A9",
|
||||
"5ED8B5A31ECEFAB16C9AA6986DA67BCE",
|
||||
"627815DCFC814ABC75900041B1DD7B59",
|
||||
"9EF3E82A50A59F166260494F7A7F2CC3",
|
||||
"878CD0D8D920888B5935D6C351128737",
|
||||
"E44429474D6FC3084EB2A6B8B46AF754",
|
||||
"EBAACF9641D54E1FB18D0A2BE4F19BE5",
|
||||
"13B3BF497CEE780E123C7E193DEA3A01",
|
||||
"6E8F381DE00A41161F0DF03B4155BFD4",
|
||||
"35E4F29BBA2BAE01144910783C3FEF49",
|
||||
"55B17BD66788CEAC366398A31F289FFB",
|
||||
"11341F56C0D6D1008D28741DAA7679CE",
|
||||
"4DF7253DF421D83358BDBE924745D98C",
|
||||
"BAE2EE651116D93EDC8E83B5F3347BE1",
|
||||
"F9721ABD06709157183AF3965A659D9D",
|
||||
"19A1C252A613FE2860A4AE6D75CE6FA3",
|
||||
"B5DDB2F5D9752C949FBDE3FFF5556C6E",
|
||||
"81B044FCFFC78ECCFCD171AAD0405C66",
|
||||
"C640566D3C06020EB2C42F1D62E56A9B",
|
||||
"EA6C4BCF425291679FDFFD26A424FBCC",
|
||||
"57F6901465D9440D9F15EE2CBA5A4090",
|
||||
"FBCFA74CADC7406260F63D96C8AAB6B1",
|
||||
"DFF4F096CEA211D4BBDACA033D0EC7D1",
|
||||
"1EE5190D551F0F42F675227A381296A9",
|
||||
"F98E1905012E580F097623C10B93054F",
|
||||
"E7D43743D21DD3C9F168C86856558B9A",
|
||||
"632A9DDA730DAB67593C5D08D8AC1059",
|
||||
"E084317000715B9057BC9DE9F3AB6124",
|
||||
"61F9EF33A0BB4E666C2ED99101919FAB",
|
||||
"6DC1D68A11834657D46703C22578D59A",
|
||||
"53AC1548863D3D16F1D4DC7242E05F2C",
|
||||
"E82CD587A408306AD78CEAE0916B9F8C",
|
||||
"0FD2D40EA6AD17A3A767F0A8600D6295",
|
||||
"AD84CC8255ADB39DFCA23F92761AE7E9",
|
||||
"F4F20CF7D51BEE7DA024A2B11A7ECA0B",
|
||||
"5057691B85D9CE93A193214DB0A016B6",
|
||||
"0F58C960876390BDEF4BB6BE95CAA1EE",
|
||||
"9A3E66EEBC21BC0BD9430B341EF465FA",
|
||||
"20415035F34B8BCBCB28ABF07F78F0D4",
|
||||
"AC89FC7BA10479EBF10DE65BCEF89B3C",
|
||||
"068FA75A30BE443171AF3F6FEB1A20D2",
|
||||
"50E02F213246C525A8C27700CA34B502",
|
||||
"227DA47D5A0906DB3AB042BB0A695FB6",
|
||||
"8663AC30ED12514F1DE46777F4514BFC",
|
||||
"A987D4BC12E1DE9F4B6DF43567C34A8B",
|
||||
"6D5A0370F599ACA605F63B04E5143D0C",
|
||||
"9809266E378B07B7AFDB3BAA97B7E442",
|
||||
"8F753252B30CCCACE12D9A301F4D5090",
|
||||
"032465F6C0CE34D41962F561692A1AFF",
|
||||
"C50E9AD5BEB8F3B00821DD47FF8AC093",
|
||||
"9C6FEA3D46268D54A6829B2AD25BB276",
|
||||
"0FD8575E87706F561343D7B3A41E044A",
|
||||
"BEE9BEB3739540D88CBCE77925F0A114",
|
||||
"D24EAEE7FFFBAC3D6F26C2DCE0DCDE28",
|
||||
"47771A90398FF0F7FA821C2F8F5E1398",
|
||||
"4639741B6F84B135AD118C8249B64ED0",
|
||||
"8EE5505EC85567697A3306F250A27720",
|
||||
"7C8A19AC1AEFBC5E0119D91A5F05D4C2",
|
||||
"5141B9B672E54773B672E3A6C424887B",
|
||||
"B5A2D3CD206653C6402F34FB0AE3613D",
|
||||
"0F5BD9408738231D114B0A82753279A3",
|
||||
"FEF033FF4268EA487FC74C5E43A45338",
|
||||
"A3EDC09DCD529B113910D904AD855581",
|
||||
"AB8FBB6F27A0AC7C55B59FDD36B72F1C",
|
||||
"EEA44D5ED4D769CC930CD83D8999EC46",
|
||||
"6972276803AE9AA7C6F431AB10979C34",
|
||||
"86DEAA9F39244101818178474D7DBDE9",
|
||||
"88C6B466EA361D662D8D08CBF181F4FE",
|
||||
"91AB2C6B7C63FF59F7CBEEBF91B20B95",
|
||||
"2DFE6C146AD5B3D8C3C1718F13B48E01",
|
||||
"C7CFF1623451711391A302EEC3584AAA",
|
||||
"089FE845CC05011686C66019D18BE050",
|
||||
"08C8410B9B427211A67124B0DCCEAD48",
|
||||
"8D91592F5566085254784606334D7629",
|
||||
"3298FEAAF2E1201D6299FF8846639C97",
|
||||
"C497CB9F0BDFE0EFC8C2F3F90760AA72",
|
||||
"2788AFD046E0309CBE4424690DA2AB89",
|
||||
"E9891707F25EF29FEE372890D4258982",
|
||||
"DB041D94A23D45D4D4DCED5A030CAF61",
|
||||
"FFAFDBF0ECB18DF9EA02C27077448E6D",
|
||||
"2DAAA42A7D0A1D3B0E4761D99CF2150A",
|
||||
"3B7A54CB7CF30ABE263DD6ED5BFE8D63",
|
||||
"EEFA090174C590C448A55D43648F534A",
|
||||
"9E15798731ED42F43EA2740A691DA872",
|
||||
"31FBD661540A5DEAAD1017CFD3909EC8",
|
||||
"CDA9AE05F224140E28CB951721B44D6A",
|
||||
"0C5BC512C60A1EAC3434EFB1A8FBB182",
|
||||
"AA863610DEEEEB62D045E87EA30B59B5",
|
||||
"6AC2448DE568D279C7EEBE1DF403920C",
|
||||
"E2011E3D292B26888AE801215FD0CB40",
|
||||
"E06F3E15EE3A61672D1C99BADE5B9DBE",
|
||||
"BB7027F0548CF6712CEB4C7A4B28E178",
|
||||
"061EC21FB70FADBDF87C3BD2AE23825B",
|
||||
"4C21F26FE94ABBAC381352375314C3EB",
|
||||
"F7CEE6DD99909C2B569EEDA61ED8942E",
|
||||
"CE98C4A876C65E4CCB261EBB1D9DF7F5",
|
||||
"A5491881CF833C3604ABC08044F402AC",
|
||||
"A1BA16E64CCCB3087D57A768507B0BFC",
|
||||
"D55951E202D2949EBD3BE43120C738BF",
|
||||
"EBB8E43069E69F450EFEC65DCD52B7FD",
|
||||
"2B292135663B4AA5ABFE9423D57E7EE9",
|
||||
"E91BF974B3BE3AD966249D8655292A85",
|
||||
"384365998EAA9562236CC58F6ADF9610",
|
||||
"C2E997012AA3D4D8D359C9A947CBE69F",
|
||||
"F49421204148BA213BE87E2D5C22B0BF",
|
||||
"82ED0ED9953AA92E4DF30929CA65C00F",
|
||||
"291EB1D11653C8479437C74A977F5106",
|
||||
"BCB997B1939B8983ABD550D6025683E3",
|
||||
"1FBA2592C6F489775CAADA71F9B983E9",
|
||||
"969F66F217AF1A3DB9E41C1B29039824",
|
||||
"A54BB7D6B17E423AC0A7744C19073CB8",
|
||||
"B0AC6E6578D1021F47DCF9748A32EAD5",
|
||||
"B87B361C3B7B194C77A4358D4669153E",
|
||||
"46A133847F96EAA8282A799DC8899D58",
|
||||
"2265EC3A9F2D5C9547A091CC8CFB18EA",
|
||||
"54CBF3A6FC4FE56D426117AA1FFD1DDE",
|
||||
"5312877CCEAB6CFB0905394A370A8003",
|
||||
"7190BD6EC613FE38B84ECFE28F702FE4",
|
||||
"D1FA5B9CA89A43B04C05F0EF29EF68CD",
|
||||
"808285751548ED934FD1056D2D9AE8BA",
|
||||
"2758DEF3E7B95A9AE89777BE64D5A6CF",
|
||||
"07D81F87DB3E0ACC82B01E08FB22F3C1",
|
||||
"8DA250E5553D650711A75EE1CB4FD1C7",
|
||||
"A93D946BD0E87F32719DF5F158CEE669",
|
||||
"03945236EC2A4D4EAF30B8ABEB54330D",
|
||||
"11CC35301F24B79DDE31AEA2D1354F88",
|
||||
"E73715B3E8D9A290F44AE6FFBF247E5D",
|
||||
"7345E07732B71CB158BBF64CCA5C5B96",
|
||||
"6E128F296D24705A1924FD9B70C4ED04",
|
||||
"95A789776F036783FBD330947083F54F",
|
||||
"360DEC2533EA4AA2E3E54FD3DE2906EB",
|
||||
"E68EFD7FECF4D601EA22727BD764965B",
|
||||
"9065C64A8BFF44AC33EDBB611CF83D7B",
|
||||
"8F33C8DF2A7A51CE8090E8F123BC3723",
|
||||
"807F391FFBA8291BA625623210F99018",
|
||||
"5E8B3F3A701522CE5CAA761C929D6292",
|
||||
"3BA404DC38735A78289E3809E8364835",
|
||||
"D23BEDBAD229F8305DC425B6B759DCC9",
|
||||
"44880F21CF5913040AE376AEE2A10AD8",
|
||||
"9BC98E29D057C0E828C3B5CCE69256C1",
|
||||
"B293CC7A975DA141A68279368057CC41",
|
||||
"8D60FB87ACD91385B313BE5F1D7BD30F",
|
||||
"2C8E56132D70291B303C48FDF75543CD",
|
||||
"D1F80035B826791F6CE4E59B7DB1BB0D",
|
||||
"42CE6224FC36469339A133DD08173BD4",
|
||||
"61817155EA41BCBA2AF7F06AE7CBF585",
|
||||
"D1923A9866068D2EF5FB77D57C3315B6",
|
||||
"B37CBDB5D719F49691CA968EF2E84140",
|
||||
"EC974E653A055D7F8F22171030F68E1D",
|
||||
"DDE5D3B9AAD9C32213BB3675A822499C",
|
||||
"D3B6E9216EA1AE57EB1C628A3C38AB78",
|
||||
"82C99ECC69472B7E96324B042AE8B87A",
|
||||
"97144DC5338C43600F84439C0AA0D147",
|
||||
"400AC4A0BBADA1DB2121EB144C7E5209",
|
||||
"EFD9D550EB419ED278F4885A490AB54C",
|
||||
"2AB7816E149B7C0404C88A8857793670",
|
||||
"5B591DFF9E8DEE15BAD24C025DBCA481",
|
||||
"0C06633E30721C3749F49AD8CBF2B754",
|
||||
"96D6D31A41B5123B2035FD91A921D4CA",
|
||||
"E7F6C34D86668BC2805CA7793C5E86AD",
|
||||
"F46DFF5FF500D6879C4D3E45CF0CF0F3",
|
||||
"60D842D9C61DA7495C116197B7CECBBE",
|
||||
"D45B24EDB673353EBDF248B8FA06B67A",
|
||||
"119EAEBCC165D0BD02C0D35DC82EF992",
|
||||
"E673143680414ADA301D0ED34626B9FE",
|
||||
"6B6CFE160A6263631B292F879EEFF926"
|
||||
}
|
||||
};
|
||||
|
||||
private static int[] KEY_SIZES = {
|
||||
16, 24, 32
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs an AES Key according to the specified key size and
|
||||
* round number.
|
||||
* @param len key size in bytes, i.e. 16, 24, or 32
|
||||
* @param rounds round number starting from 0, i.e. valid from 0 to len-1.
|
||||
*/
|
||||
private static SecretKey constructAESKey(int len, int rounds)
|
||||
throws IllegalArgumentException {
|
||||
if ((len != 16) && (len != 24) && (len != 32)) {
|
||||
throw new IllegalArgumentException("Wrong Key Length: " + len);
|
||||
}
|
||||
byte[] rawKeyValue = constructKeyValue(len, rounds);
|
||||
SecretKeySpec key = new SecretKeySpec(rawKeyValue, "AES");
|
||||
return key;
|
||||
}
|
||||
|
||||
private static byte[] constructKeyValue(int keysize, int rounds) {
|
||||
byte[] tempKeyValue = new byte[keysize];
|
||||
Arrays.fill(tempKeyValue, (byte)0);
|
||||
|
||||
int whichByte = rounds/8;
|
||||
int whichDigit = rounds % 8;
|
||||
if ((whichByte >= keysize) || (whichDigit < 0) ||
|
||||
(whichDigit > 8)) {
|
||||
throw new IllegalArgumentException("Invalid keysize/rounds " +
|
||||
"combination :" + keysize +
|
||||
"/" + rounds);
|
||||
}
|
||||
switch (whichDigit) {
|
||||
case 0:
|
||||
tempKeyValue[whichByte] = (byte)0x80;
|
||||
break;
|
||||
case 1:
|
||||
tempKeyValue[whichByte] = (byte)0x40;
|
||||
break;
|
||||
case 2:
|
||||
tempKeyValue[whichByte] = (byte)0x20;
|
||||
break;
|
||||
case 3:
|
||||
tempKeyValue[whichByte] = (byte)0x10;
|
||||
break;
|
||||
case 4:
|
||||
tempKeyValue[whichByte] = (byte)0x08;
|
||||
break;
|
||||
case 5:
|
||||
tempKeyValue[whichByte] = (byte)0x04;
|
||||
break;
|
||||
case 6:
|
||||
tempKeyValue[whichByte] = (byte)0x02;
|
||||
break;
|
||||
case 7:
|
||||
tempKeyValue[whichByte] = (byte)0x01;
|
||||
break;
|
||||
}
|
||||
return tempKeyValue;
|
||||
}
|
||||
|
||||
private static byte[] constructByteArray(String s) {
|
||||
int len = s.length()/2;
|
||||
byte[] tempValue = new byte[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
tempValue[i] = Integer.valueOf(s.substring(2*i, 2*i+2),
|
||||
16).byteValue();
|
||||
}
|
||||
return tempValue;
|
||||
}
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
String transformation = ALGO+"/"+MODE+"/"+PADDING;
|
||||
Cipher c = Cipher.getInstance(transformation,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
|
||||
for (int i=0; i<KEY_SIZES.length; i++) {
|
||||
if (KEY_SIZES[i]*8 >
|
||||
Cipher.getMaxAllowedKeyLength(transformation)) {
|
||||
// skip if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
continue;
|
||||
}
|
||||
int rounds = KEY_SIZES[i] * 8;
|
||||
byte[] plainText = PT;
|
||||
byte[] cipherText = null;
|
||||
try {
|
||||
for (int j=0; j < rounds; j++) {
|
||||
SecretKey aesKey = constructAESKey(KEY_SIZES[i], j);
|
||||
c.init(Cipher.ENCRYPT_MODE, aesKey);
|
||||
cipherText = c.doFinal(plainText);
|
||||
byte[] answer = constructByteArray(CTS[i][j]);
|
||||
if (!Arrays.equals(cipherText, answer)) {
|
||||
throw new Exception((i+1) + "th known answer test failed for encryption");
|
||||
}
|
||||
c.init(Cipher.DECRYPT_MODE, aesKey);
|
||||
byte[] restored = c.doFinal(cipherText);
|
||||
if (!Arrays.equals(plainText, restored)) {
|
||||
throw new Exception((i+1) + "th known answer test failed for decryption");
|
||||
}
|
||||
}
|
||||
System.out.println("Finished KAT for " + KEY_SIZES[i] + "-byte key");
|
||||
} catch (SecurityException se) {
|
||||
TestUtil.handleSE(se);
|
||||
}
|
||||
}
|
||||
|
||||
// passed all tests...hooray!
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
TestKATForECB_VK test = new TestKATForECB_VK();
|
||||
String testName = test.getClass().getName() + "[" + ALGO +
|
||||
"/" + MODE + "/" + PADDING + "]";
|
||||
if (test.execute()) {
|
||||
System.out.println(testName + ": Passed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,565 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4635086
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main TestKATForECB_VT
|
||||
* @summary Known Answer Test for AES cipher with ECB mode
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.math.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TestKATForECB_VT
|
||||
{
|
||||
private static final String ALGO = "AES";
|
||||
private static final String MODE = "ECB";
|
||||
private static final String PADDING = "NoPadding";
|
||||
|
||||
private static String[][] CTS = {
|
||||
// Cipher Texts for 128-bit key
|
||||
{
|
||||
"3AD78E726C1EC02B7EBFE92B23D9EC34",
|
||||
"45BC707D29E8204D88DFBA2F0B0CAD9B",
|
||||
"161556838018F52805CDBD6202002E3F",
|
||||
"F5569B3AB6A6D11EFDE1BF0A64C6854A",
|
||||
"64E82B50E501FBD7DD4116921159B83E",
|
||||
"BAAC12FB613A7DE11450375C74034041",
|
||||
"BCF176A7EAAD8085EBACEA362462A281",
|
||||
"47711816E91D6FF059BBBF2BF58E0FD3",
|
||||
"B970DFBE40698AF1638FE38BD3DF3B2F",
|
||||
"F95B59A44F391E14CF20B74BDC32FCFF",
|
||||
"720F74AE04A2A435B9A7256E49378F5B",
|
||||
"2A0445F61D36BFA7E277070730CF76DA",
|
||||
"8D0536B997AEFEC1D94011BAB6699A03",
|
||||
"674F002E19F6ED47EFF319E51FAD4498",
|
||||
"292C02C5CB9163C80AC0F6CF1DD8E92D",
|
||||
"FA321CF18EF5FE727DD82A5C1E945141",
|
||||
"A5A7AFE1034C39CCCEBE3C584BC0BE05",
|
||||
"4FF5A52E697E77D081205DBDB21CEA39",
|
||||
"209E88DC94C9003000CE0769AF7B7166",
|
||||
"5DEE41AF864CB4B650E5F51551824D38",
|
||||
"A79A63FA7E4503AE6D6E09F5F9053030",
|
||||
"A48316749FAE7FAC7002031A6AFD8BA7",
|
||||
"D6EEE8A7357A0E1D64262CA9C337AC42",
|
||||
"B013CA8A62A858053E9FB667ED39829E",
|
||||
"DF6EA9E4538A45A52D5C1A43C88F4B55",
|
||||
"7D03BA451371591D3FD5547D9165C73B",
|
||||
"0E0426281A6277E186499D365D5F49FF",
|
||||
"DBC02169DD2059E6CC4C57C1FEDF5AB4",
|
||||
"826590E05D167DA6F00DCC75E22788EB",
|
||||
"34A73F21A04421D9786335FAAB49423A",
|
||||
"ED347D0E0128EE1A7392A1D36AB78AA9",
|
||||
"EE944B2FE6E9FC888042608DA9615F75",
|
||||
"9E7C85A909EF7218BA7947CFB4718F46",
|
||||
"811AE07A0B2B1F816587FA73699AE77D",
|
||||
"68466FBF43C2FE13D4B18F7EC5EA745F",
|
||||
"D20B015C7191B219780956E6101F9354",
|
||||
"5939D5C1BBF54EE1B3E326D757BDDE25",
|
||||
"B1FDAFE9A0240E8FFEA19CE94B5105D3",
|
||||
"D62962ECE02CDD68C06BDFEFB2F9495B",
|
||||
"B3BB2DE6F3C26587BA8BAC4F7AD9499A",
|
||||
"E0B1072D6D9FF703D6FBEF77852B0A6B",
|
||||
"D8DD51C907F478DE0228E83E61FD1758",
|
||||
"A42DFFE6E7C1671C06A25236FDD10017",
|
||||
"25ACF141550BFAB9EF451B6C6A5B2163",
|
||||
"4DA7FCA3949B16E821DBC84F19581018",
|
||||
"7D49B6347CBCC8919C7FA96A37A7A215",
|
||||
"900024B29A08C6721B95BA3B753DDB4D",
|
||||
"6D2182FB283B6934D90BA7848CAB5E66",
|
||||
"F73EF01B448D23A4D90DE8B2F9666E7A",
|
||||
"4AD9CDA2418643E9A3D926AF5E6B0412",
|
||||
"7CAEC8E7E5953997D545B033201C8C5B",
|
||||
"3C43CA1F6B6864503E27B48D88230CF5",
|
||||
"44F779B93108FE9FEEC880D79BA74488",
|
||||
"9E50E8D9CFD3A682A78E527C9072A1CF",
|
||||
"68D000CBC838BBE3C505D6F814C01F28",
|
||||
"2CB2A9FEC1ACD1D9B0FA05205E304F57",
|
||||
"01EB2806606E46444520A5CC6180CD4B",
|
||||
"DAA9B25168CC702326F217F1A0C0B162",
|
||||
"3E07E648975D9578D03555B1755807ED",
|
||||
"0B45F52E802C8B8DE09579425B80B711",
|
||||
"659595DA0B68F6DF0DD6CA77202986E1",
|
||||
"05FF42873893536E58C8FA98A45C73C4",
|
||||
"B5B03421DE8BBFFC4EADEC767339A9BD",
|
||||
"788BCD111ECF73D4E78D2E21BEF55460",
|
||||
"909CD9EC6790359F982DC6F2393D5315",
|
||||
"332950F361535FF24EFAC8C76293F12C",
|
||||
"A68CCD4E330FFDA9D576DA436DB53D75",
|
||||
"27C8A1CCFDB0B015D1ED5B3E77143791",
|
||||
"D76A4B95887A77DF610DD3E1D3B20325",
|
||||
"C068AB0DE71C66DAE83C361EF4B2D989",
|
||||
"C2120BCD49EDA9A288B3B4BE79AC8158",
|
||||
"0C546F62BF2773CD0F564FCECA7BA688",
|
||||
"18F3462BEDE4920213CCB66DAB1640AA",
|
||||
"FE42F245EDD0E24B216AEBD8B392D690",
|
||||
"3D3EEBC8D3D1558A194C2D00C337FF2B",
|
||||
"29AAEDF043E785DB42836F79BE6CBA28",
|
||||
"215F90C6744E2944358E78619159A611",
|
||||
"8606B1AA9E1D548E5442B06551E2C6DC",
|
||||
"987BB4B8740EC0EDE7FEA97DF033B5B1",
|
||||
"C0A3500DA5B0AE07D2F450930BEEDF1B",
|
||||
"525FDF8312FE8F32C781481A8DAAAE37",
|
||||
"BFD2C56AE5FB9C9DE33A6944572A6487",
|
||||
"7975A57A425CDF5AA1FA929101F650B0",
|
||||
"BF174BC49609A8709B2CD8366DAA79FE",
|
||||
"06C50C43222F56C874B1704E9F44BF7D",
|
||||
"0CEC48CD34043EA29CA3B8ED5278721E",
|
||||
"9548EA34A1560197B304D0ACB8A1698D",
|
||||
"22F9E9B1BD73B6B5B7D3062C986272F3",
|
||||
"FEE8E934BD0873295059002230E298D4",
|
||||
"1B08E2E3EB820D139CB4ABBDBE81D00D",
|
||||
"0021177681E4D90CEAF69DCED0145125",
|
||||
"4A8E314452CA8A8A3619FC54BC423643",
|
||||
"65047474F7222C94C6965425FF1BFD0A",
|
||||
"E123F551A9C4A8489622B16F961A9AA4",
|
||||
"EF05530948B80915028BB2B6FE429380",
|
||||
"72535B7FE0F0F777CEDCD55CD77E2DDF",
|
||||
"3423D8EFC31FA2F4C365C77D8F3B5C63",
|
||||
"DE0E51C264663F3C5DBC59580A98D8E4",
|
||||
"B2D9391166680947AB09264156719679",
|
||||
"10DB79F23B06D263835C424AF749ADB7",
|
||||
"DDF72D27E6B01EC107EA3E005B59563B",
|
||||
"8266B57485A5954A4236751DE07F6694",
|
||||
"669A501E1F1ADE6E5523DE01D6DBC987",
|
||||
"C20C48F2989725D461D1DB589DC0896E",
|
||||
"DE35158E7810ED1191825D2AA98FA97D",
|
||||
"4FE294F2C0F34D0671B693A237EBDDC8",
|
||||
"087AE74B10CCBFDF6739FEB9559C01A4",
|
||||
"5DC278970B7DEF77A5536C77AB59C207",
|
||||
"7607F078C77085184EAA9B060C1FBFFF",
|
||||
"9DB841531BCBE7998DAD19993FB3CC00",
|
||||
"D6A089B654854A94560BAE13298835B8",
|
||||
"E1E223C4CF90CC5D195B370D65114622",
|
||||
"1CBED73C50D053BDAD372CEEE54836A1",
|
||||
"D309E69376D257ADF2BFDA152B26555F",
|
||||
"740F7649117F0DEE6EAA7789A9994C36",
|
||||
"76AE64417C297184D668C5FD908B3CE5",
|
||||
"6095FEA4AA8035591F1787A819C48787",
|
||||
"D1FF4E7ACD1C79967FEBAB0F7465D450",
|
||||
"5F5AD3C42B9489557BB63BF49ECF5F8A",
|
||||
"FB56CC09B680B1D07C5A52149E29F07C",
|
||||
"FF49B8DF4A97CBE03833E66197620DAD",
|
||||
"5E070ADE533D2E090ED0F5BE13BC0983",
|
||||
"3AB4FB1D2B7BA376590A2C241D1F508D",
|
||||
"58B2431BC0BEDE02550F40238969EC78",
|
||||
"0253786E126504F0DAB90C48A30321DE",
|
||||
"200211214E7394DA2089B6ACD093ABE0",
|
||||
"0388DACE60B6A392F328C2B971B2FE78",
|
||||
"58E2FCCEFA7E3061367F1D57A4E7455A"
|
||||
},
|
||||
// Cipher Texts for 192-bit key
|
||||
{
|
||||
"6CD02513E8D4DC986B4AFE087A60BD0C",
|
||||
"423D2772A0CA56DAABB48D2129062987",
|
||||
"1021F2A8DA70EB2219DC16804445FF98",
|
||||
"C636E35B402577F96974D8804295EBB8",
|
||||
"1566D2E57E8393C19E29F892EA28A9A7",
|
||||
"883C878FED70B36CC09D040F9619DD19",
|
||||
"06734593A974965790E715594FC34AA9",
|
||||
"F19B389948D9A45534E5BD36C984134A",
|
||||
"D8410DFC14FA6D175EC968EA8CAC514C",
|
||||
"7E6C6EBB4029A177CF7B2FDD9AC6BB7A",
|
||||
"4B51DD4850DC0A6C3A46D924003D2C27",
|
||||
"2E510A9D917B15BE32A192B12A668F23",
|
||||
"88F6F79962B0FB77FEA8E7C632D3108E",
|
||||
"A3A35AB1D88DAF07B52794A0F065383A",
|
||||
"DC6CC878433E2B3BB193049A4ECBFC53",
|
||||
"EFCD3763EB7B1A415938248A9A5B4FD5",
|
||||
"AB7E9FB9A66DBE5BB44854F07D9015EE",
|
||||
"8B8E9D3365F8F6743ECF7E33E99255A4",
|
||||
"54D37B4F176FF3D8F6AFC866066D8572",
|
||||
"E83310889480FBF3C00342E3126D0D02",
|
||||
"D321AB2511F92F098174AA2DE6E85DA2",
|
||||
"D8E3F40B1112D5149D58C481DFA9983F",
|
||||
"2454C4E0806639DDF19854D6C68054AD",
|
||||
"A5506D410F7CA32F3955DD79D9D09418",
|
||||
"7908EE40677699568A7DC1AA317C7E4E",
|
||||
"B4B7B29DD43B2F5CF765E25192273982",
|
||||
"92AFE9668159BEFFE2A86F8503260164",
|
||||
"5C36A232FBA6D187A84657AD4028B18F",
|
||||
"A2E994DFAB3A798DF8F54F6DA87E58E2",
|
||||
"6CDAB10A72ADF77D71D0765BAAE95631",
|
||||
"9FE3C801BCAAF7BB800F2E6BF3278E21",
|
||||
"B459D90D9A6C392E5493BC91CF5A0863",
|
||||
"0518A9FA5007F6787E0FB4E5AC27D758",
|
||||
"BED9795415D28599700ED7952384A963",
|
||||
"F0140421173D60251EF6CAB0229B1B50",
|
||||
"460EB4652B3F6779EA28CB11B37529ED",
|
||||
"C4283D351C960A6AC13CD19CCF03AE38",
|
||||
"6815A10047B2C834A798EBDCC6786C75",
|
||||
"99BA19F0CDD5990D0386B32CE56C9C4C",
|
||||
"DE76F62C61E07915162DA13E79679DEC",
|
||||
"DD0325D6854803D06D1D2277D5FB8D67",
|
||||
"580B71A41DE37D6FAC83CCB0B3BB1C97",
|
||||
"E9B1AB470A1B02EF0FF5E6754A092C96",
|
||||
"8590620F5AF5993B7410282F4126BC1F",
|
||||
"8D4914D2F1B22B2E268E66E532D29D7C",
|
||||
"FD826CE48E62C5E30867044B86BA4B56",
|
||||
"100E7B831C9F35FA1271F5F1316C6FCF",
|
||||
"0A2DD0C17F68B996AA96C007003D0B31",
|
||||
"C95F68C57E06B0A2E1F623C83C5D80BF",
|
||||
"571CAFC92C7C8A5EC54C0741E186905C",
|
||||
"22514353E95312C112255E1EED0B2DF6",
|
||||
"791A8BF462BD17580BD9152C6D11C6C5",
|
||||
"5882A0178D548F84A165DB809C60DC28",
|
||||
"3CE4A90EED4458CA6039E42DDADB71C3",
|
||||
"D3CBAB261207A16BE2751E77044FD7C9",
|
||||
"24E32B698A7B32217093628B01F424AB",
|
||||
"9F6AFC0AF27CF565110C77E3C24F4F5B",
|
||||
"E088AA5CDA20EF267BB039B00C72C45B",
|
||||
"5CF1018B7E0BA1775601C2E279900360",
|
||||
"3B1A7388B89FB9416AD8753CF5AF35D2",
|
||||
"137FA4ED00AFCD9F5D8BC0D14BD5837A",
|
||||
"806F5C9B663559BB56F234881E4A3E60",
|
||||
"8069A449152292DF2DE8642992C632B6",
|
||||
"37C6CF2A1ABD1B1F1922B46C7B4A280D",
|
||||
"7A2835260E5A0AA2B5DC301800EC8438",
|
||||
"EE81FAF2F9058213FFCACF281CB8509E",
|
||||
"57F22D93C37129BA331FDBA38E005A1E",
|
||||
"EC798782E87B7D9F780CC3C3A46519B5",
|
||||
"43EA28497F5D40E3A4744FA2EDAA42DE",
|
||||
"91F004E7DEBF41B3414DD8C5C317372C",
|
||||
"C249EAE54E7B4DF43B938C1B4CC28314",
|
||||
"32C289D7EEFB99D2F17AD7B7D45FE1EC",
|
||||
"A675FB2E8DDBF810CEF01CF2B728CD2B",
|
||||
"A418AAAB6E6921CC731AA8A349386080",
|
||||
"2E2B0F44863E67D9B0215C4ABD60417F",
|
||||
"F0AF7CB19E911D481F6426DAEFDD2240",
|
||||
"CB1304DAAA2DF6878F56AC2E0F887E04",
|
||||
"B1B70A7E6A0CD1916D9B78BEA19084AE",
|
||||
"0CDE9F9BE646A5FCE3436B794A9CFC65",
|
||||
"68C7946D476A0A36674B36AFD7E5DF33",
|
||||
"48770159A07DD8DFFF06C80105F8D57C",
|
||||
"665E62801B3260E3C45BD3BE34DFDEBE",
|
||||
"4159C1F686BFBE5B0E50BDB0DA532B69",
|
||||
"6333100A5A4AD917DC2D4E78A04869A3",
|
||||
"866A4519AB1D199F25886B89D0539ACC",
|
||||
"EC0CFD37E4CBC7E8BE385283F7AEA75A",
|
||||
"CA2F383AACCA0810AA13F3E710621422",
|
||||
"1D0EEF6870444F950937831EC0A55D98",
|
||||
"37839B35ED6801E7670496D479A95017",
|
||||
"02317C8C7098C4F94AB867AC7A49DD8D",
|
||||
"FFB4CB4E3F7F8BF3367EBD43236518B4",
|
||||
"36BEDEF1E4AA3E4A40A305741713FCBF",
|
||||
"B2DFE3C4870269C1E3FEEC39161540D9",
|
||||
"147EF2518AD45DA0026056ECBF6A3DFA",
|
||||
"027A75E4DE635790E47ACE90D7928804",
|
||||
"C4CF3CCB59BF87D0AFBD629F48CFBB7B",
|
||||
"35165C93F564C97E1C32EF97E8151A87",
|
||||
"449DE37F7D5A1BBD628ABBE7E061701D",
|
||||
"B1D45EAF218F1799B149BAD677FE129F",
|
||||
"BE08AC6DB6BD0583AA9D2ABC71C73DCD",
|
||||
"BCC835BD3DF1A79E4C7C145B899A5C25",
|
||||
"3D311EA611FF5AF371301C58A8E9912D",
|
||||
"A5A1BEA594ACC7CA80F09EA5ADDB5C71",
|
||||
"0F09492429FE7222D6CD8190D9F2FFBF",
|
||||
"816D2220A16B8AAEE71364FD43636C6F",
|
||||
"D7E8702408419ED73191B107EAF75A0B",
|
||||
"9B170EFB1E235B433C78E276BEA082F0",
|
||||
"03BBECC5598AE974430F29395522F096",
|
||||
"DB53517766C0E8CF42059607CBA89380",
|
||||
"2E2AF4B7931F0AEFFAC5471148A5BB97",
|
||||
"C872C0408266403B984F635FF5683DE4",
|
||||
"15DCF750B0E3A68AD1F4EFD07E8967B4",
|
||||
"B41092048E9E6A749F6FD8CE515A23A3",
|
||||
"4DA9267D62507994312BD5C99ADDE730",
|
||||
"9E2FCA6D1D626E9C6A924EBF7DBF618A",
|
||||
"E092E8D7EF2C2465AEFB2493C3063590",
|
||||
"1C0E58DA37D1068378A88DBE2EDE4E10",
|
||||
"19063F854232B8509A6A3A6D46809959",
|
||||
"447FB09E54EFA285F7530F25C4EA0022",
|
||||
"F6ABE86321BE40E1FBFDAFED37CC1D9B",
|
||||
"4E8506CD006666341D6CF51F98B41F35",
|
||||
"53995DE0009CA18BECAFB8307C54C14C",
|
||||
"2006BF99F4C58B6CC2627856593FAEEA",
|
||||
"2DA697D2737CB30B744A4644FA1CBC6E",
|
||||
"47A22ACDB60C3A986A8F76ECD0EA3433",
|
||||
"FDAA17C2CDE20268FE36E164EA532151",
|
||||
"98E7247C07F0FE411C267E4384B0F600",
|
||||
"CD33B28AC773F74BA00ED1F312572435"
|
||||
},
|
||||
// Cipher Texts for 256-bit key
|
||||
{
|
||||
"DDC6BF790C15760D8D9AEB6F9A75FD4E",
|
||||
"C7098C217C334D0C9BDF37EA13B0822C",
|
||||
"60F0FB0D4C56A8D4EEFEC5264204042D",
|
||||
"73376FBBF654D0686E0E84001477106B",
|
||||
"2F443B52BA5F0C6EA0602C7C4FD259B6",
|
||||
"75D11B0E3A68C4223D88DBF017977DD7",
|
||||
"779B38D15BFFB63D8D609D551A5CC98E",
|
||||
"5275F3D86B4FB8684593133EBFA53CD3",
|
||||
"1CEF2074B336CEC62F12DEA2F6AB1481",
|
||||
"1AEF5ABBAD9D7160874578DCD8BAE172",
|
||||
"46C525DB17E72F26BF03216846B6F609",
|
||||
"E24411F941BBE08788781E3EC52CBAA4",
|
||||
"83A3DEDD1DD27018F6A6477E40527581",
|
||||
"B68F8A2CDBAB0C923C67FC8F0F1087DE",
|
||||
"649944A70C32BF87A7409E7AE128FDE8",
|
||||
"2846526D67387539C89314DE9E0C2D02",
|
||||
"A9A0B8402E53C70DD1688054BA58DDFD",
|
||||
"4A72E6E1B79C83AC4BE3EBA5699EED48",
|
||||
"B0E36B867BA4FF2B77D0614B0E364E4C",
|
||||
"49B57DE141F6418E3090F24DDD4014B6",
|
||||
"A6C0D5B9797258E1987AC5F6CD20146D",
|
||||
"426CF4BDCAA369175965D26E7C71EEA2",
|
||||
"E27F484CE54BC99BC1A52BDA3B518A26",
|
||||
"D16D186284C7E6EE64B8104E0EF20BA5",
|
||||
"6431F8538AD54E1E044A9F71F8EF556B",
|
||||
"ECD57CEB451D27EB96C55B2042257E8E",
|
||||
"4F0F188DC911B1954AFBC734C9F68872",
|
||||
"B54DEF0337626B65614E81EDFDE620F3",
|
||||
"6655D8074CAE0B90B0D3A3FE72D4D9DB",
|
||||
"C6B74B6B9EB4FC0C9A237DB1B616D09A",
|
||||
"D7B5D076EA56EC2B20791D7AD51CCF8F",
|
||||
"FE160C224BF003CE3BDDC90CB52ED22C",
|
||||
"5E00DA9BA94B5EC0D258D8A8002E0F6A",
|
||||
"09AC6DCFF4DACFF1651E2BA212A292A3",
|
||||
"B283617E318D99AF83A05D9810BA89F7",
|
||||
"0B5F70CCB40B0EF2538AE9B4A9770B35",
|
||||
"43282BF180248FB517839B37F4DDAAE4",
|
||||
"DDBD534C8B2E6D30A268F88C55AD765B",
|
||||
"A41A164E50EC2D9F175E752B755E0B5C",
|
||||
"37BFF99FF2F7AA97779E4ADF6F13FB10",
|
||||
"9BA4F7BD298152903A683C4CEC669216",
|
||||
"5FB750C7CE10DE7B4504248914D0DA06",
|
||||
"3E748BFA108E086F51D56EC74A9E0FB9",
|
||||
"31D4E56B99F5B73C1B8437DF332AFB98",
|
||||
"9DC6717B84FC55D266E7B1D9B5C52A5F",
|
||||
"8EF8BA007F23C0A50FC120E07041BCCD",
|
||||
"C58F38E1839FC1918A12B8C9E88C66B6",
|
||||
"B695D72A3FCF508C4050E12E40061C2D",
|
||||
"5D2736AD478A50583BC8C11BEFF16D7A",
|
||||
"DF0EACA8F17847AD41F9578F14C7B56B",
|
||||
"E5AA14AD48AD0A3C47CC35D5F8020E51",
|
||||
"11BE6C8F58EBD8CEF1A53F591A68E8CE",
|
||||
"ECFE7BAFCBF42C1FEE015488770B3053",
|
||||
"E552649F8D8EC4A1E1CD6DF50B6E6777",
|
||||
"521C0629DE93B9119CDB1DDC5809DDEA",
|
||||
"CB38A62A0BAB1784156BA038CBA99BF6",
|
||||
"76CCEE8AAACD394DE1EEF3DDA10CB54B",
|
||||
"6AFF910FA1D5673140E2DB59B8416049",
|
||||
"064A12C0EF73FB386801BF4F35F3120D",
|
||||
"2240E374929D5B1BB8FF0FFDDDF640EC",
|
||||
"D4BA15C904C7692185DE85C02052E180",
|
||||
"1714A315AB0166728A44CD91D4AE9018",
|
||||
"6C970BDD9F0E222722EA31A1D12DD0AD",
|
||||
"F5956EDF02BD36A401BBB6CE77C3D3FB",
|
||||
"0CA11F122CCD7C259DC597EED3DF9BC4",
|
||||
"50109AB4912AD2560B206F331B62EB6C",
|
||||
"DBE7C91A4175614889A2D4BEFD64845E",
|
||||
"0D3322853A571A6B46B79C0228E0DD25",
|
||||
"96E4EE0BB9A11C6FB8522F285BADDEB6",
|
||||
"96705C52D2CFCE82E630C93477C79C49",
|
||||
"C50130AED6A126149D71F3888C83C232",
|
||||
"4816EFE3DEB380566EBA0C17BF582090",
|
||||
"0390857B4C8C98E4CF7A2B6F3394C507",
|
||||
"422E73A02025EBE8B8B5D6E0FA24FCB2",
|
||||
"3271AA7F4BF1D7C38050A43076D4FF76",
|
||||
"D2074946F0D37B8975607BFC2E70234C",
|
||||
"1A509194C1270AB92E5A42D3A9F8D98B",
|
||||
"512438946360CCC4A5C6D73F6EED7130",
|
||||
"98CFCDEC46EBEA1A286B3004F2746A0D",
|
||||
"A1CF369949677A3AF3D58E3EABF2741B",
|
||||
"D84C2E1A0E4A52166FA8FF6889D1E5E2",
|
||||
"4AD91CCEEF60119B5078FD162D2735DE",
|
||||
"2860793D818E97AAFF1D339D7702438D",
|
||||
"6F9068BE73364AE250D89D78A6C9CE6F",
|
||||
"024FC3FEF4883FEB1A8DD005305FECCE",
|
||||
"08A61FE0816D75EA15EB3C9FB9CCDED6",
|
||||
"449C86DFA13F260175CE39797686FFA4",
|
||||
"4FFFFC29A59858E1133F2BFB1A8A4817",
|
||||
"19425D1F6480B25096561295697DC2B7",
|
||||
"31974727ECDD2C77C3A428FC3A8CB3FC",
|
||||
"A57CD704B3C95E744D08DF443458F2F5",
|
||||
"486D8C193DB1ED73ACB17990442FC40B",
|
||||
"5E4DBF4E83AB3BC055B9FCC7A6B3A763",
|
||||
"ACF2E0A693FBBCBA4D41B861E0D89E37",
|
||||
"32A7CB2AE066A51D2B78FC4B4CFCB608",
|
||||
"677D494DBB73CAF55C1990158DA12F14",
|
||||
"082A0D2367512ADF0D75A151BFBE0A17",
|
||||
"5E5BB7337923C482CE8CBA249E6A8C7D",
|
||||
"D3001BA7C7026EE3E5003179530AFCFC",
|
||||
"46EC44F8931E629FE8FD8961312EDDE1",
|
||||
"C5F8ECD79C7B30E81D17E32079969310",
|
||||
"5B8AD6919E24CAEBCC55401AEE0C9802",
|
||||
"C2302B7E701B5CC7F8B29E3516DBBFA6",
|
||||
"A1D04D6A76F9F7A94D49FAA64A87F244",
|
||||
"7FB6F92D35B5CB6C631600EDB9E860BA",
|
||||
"B2EF7078BCFACE07AEEC3F9B48830EB3",
|
||||
"F475A7493D24C7036E53390374C378B3",
|
||||
"B36802AC987377A37BD8EADC97C57D60",
|
||||
"ADDCD3D19689C4DDC738CE5F69DC9505",
|
||||
"0DAF8CA22884915403C0F0BB1F4BD74F",
|
||||
"4AF36BAE2660503B3248E4685059FD05",
|
||||
"7D5631814DD8E917D97A0D514C743971",
|
||||
"BC3352500FC0CBB9DB5B5F6B491C1BE8",
|
||||
"6A4A30BA87E87AF65C90AEB7AFEDC76B",
|
||||
"77E6125897668AC8E73E8C79A6FF8336",
|
||||
"3FA9D39104EBB323C7AAAA248960DD1E",
|
||||
"FAD75AD76AB10ADC49036B250E229D39",
|
||||
"2FACAA5FE35B228A16AC74088D702EC4",
|
||||
"88B6CBCFDFEF8AD91720A1BB69A1F33E",
|
||||
"C7E9D250998632D444356242EF04058D",
|
||||
"B14DAD8D3D9153F46C0D3A1AD63C7A05",
|
||||
"60ABA678A506608D0845966D29B5F790",
|
||||
"482DC43F2388EF25D24144E144BD834E",
|
||||
"1490A05A7CEE43BDE98B56E309DC0126",
|
||||
"ABFA77CD6E85DA245FB0BDC5E52CFC29",
|
||||
"DD4AB1284D4AE17B41E85924470C36F7",
|
||||
"CEA7403D4D606B6E074EC5D3BAF39D18",
|
||||
"530F8AFBC74536B9A963B4F1C4CB738B"
|
||||
}
|
||||
};
|
||||
|
||||
private static int[] KEY_SIZES = {
|
||||
16, 24, 32
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs an AES Key according to the specified key size.
|
||||
* @param len key size in bytes, i.e. 16, 24, or 32
|
||||
*/
|
||||
private static SecretKey constructAESKey(int len)
|
||||
throws IllegalArgumentException {
|
||||
if ((len != 16) && (len != 24) && (len != 32)) {
|
||||
throw new IllegalArgumentException("Wrong Key Length: " + len);
|
||||
}
|
||||
byte[] keyval = new byte[len];
|
||||
return new SecretKeySpec(keyval, "AES");
|
||||
}
|
||||
/**
|
||||
* Constructs plain text byte array according to the specified round
|
||||
* number.
|
||||
* @param rounds round number starting from 0, i.e. valid from 0
|
||||
* to 127.
|
||||
*/
|
||||
private static byte[] constructPT(int rounds) {
|
||||
byte[] tempValue = new byte[16];
|
||||
Arrays.fill(tempValue, (byte)0);
|
||||
|
||||
int whichByte = rounds/8;
|
||||
int whichDigit = rounds % 8;
|
||||
if ((whichByte >= 16) || (whichDigit < 0) ||
|
||||
(whichDigit > 8)) {
|
||||
throw new IllegalArgumentException("Invalid rounds: " +
|
||||
rounds);
|
||||
}
|
||||
switch (whichDigit) {
|
||||
case 0:
|
||||
tempValue[whichByte] = (byte)0x80;
|
||||
break;
|
||||
case 1:
|
||||
tempValue[whichByte] = (byte)0x40;
|
||||
break;
|
||||
case 2:
|
||||
tempValue[whichByte] = (byte)0x20;
|
||||
break;
|
||||
case 3:
|
||||
tempValue[whichByte] = (byte)0x10;
|
||||
break;
|
||||
case 4:
|
||||
tempValue[whichByte] = (byte)0x08;
|
||||
break;
|
||||
case 5:
|
||||
tempValue[whichByte] = (byte)0x04;
|
||||
break;
|
||||
case 6:
|
||||
tempValue[whichByte] = (byte)0x02;
|
||||
break;
|
||||
case 7:
|
||||
tempValue[whichByte] = (byte)0x01;
|
||||
break;
|
||||
}
|
||||
return tempValue;
|
||||
}
|
||||
|
||||
private static byte[] constructByteArray(String s) {
|
||||
int len = s.length()/2;
|
||||
byte[] tempValue = new byte[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
tempValue[i] = Integer.valueOf(s.substring(2*i, 2*i+2),
|
||||
16).byteValue();
|
||||
}
|
||||
return tempValue;
|
||||
}
|
||||
|
||||
public boolean execute() throws Exception {
|
||||
String transformation = ALGO+"/"+MODE+"/"+PADDING;
|
||||
Cipher c = Cipher.getInstance(transformation,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
|
||||
for (int i=0; i<KEY_SIZES.length; i++) {
|
||||
if (KEY_SIZES[i]*8 >
|
||||
Cipher.getMaxAllowedKeyLength(transformation)) {
|
||||
// skip if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
continue;
|
||||
}
|
||||
SecretKey aesKey = constructAESKey(KEY_SIZES[i]);
|
||||
byte[] plainText = null;
|
||||
byte[] cipherText = null;
|
||||
try {
|
||||
for (int j=0; j < 128; j++) {
|
||||
plainText = constructPT(j);
|
||||
c.init(Cipher.ENCRYPT_MODE, aesKey);
|
||||
cipherText = c.doFinal(plainText);
|
||||
byte[] answer = constructByteArray(CTS[i][j]);
|
||||
if (!Arrays.equals(cipherText, answer)) {
|
||||
throw new Exception((i+1) +
|
||||
"th known answer test failed for encryption");
|
||||
}
|
||||
c.init(Cipher.DECRYPT_MODE, aesKey);
|
||||
byte[] restored = c.doFinal(cipherText);
|
||||
if (!Arrays.equals(plainText, restored)) {
|
||||
throw new Exception((i+1) +
|
||||
"th known answer test failed for decryption");
|
||||
}
|
||||
}
|
||||
System.out.println(
|
||||
"Finished KAT for " + KEY_SIZES[i] + "-byte key");
|
||||
} catch (SecurityException se) {
|
||||
TestUtil.handleSE(se);
|
||||
}
|
||||
}
|
||||
|
||||
// passed all tests...hooray!
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
TestKATForECB_VT test = new TestKATForECB_VT();
|
||||
String testName = test.getClass().getName() + "[" + ALGO +
|
||||
"/" + MODE + "/" + PADDING + "]";
|
||||
if (test.execute()) {
|
||||
System.out.println(testName + ": Passed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
418
test/jdk/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java
Normal file
418
test/jdk/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java
Normal file
|
|
@ -0,0 +1,418 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6996769
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main TestKATForGCM
|
||||
* @summary Known Answer Test for AES cipher with GCM mode support in
|
||||
* SunJCE provider.
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.math.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TestKATForGCM {
|
||||
|
||||
// Utility methods
|
||||
private static byte[] HexToBytes(String hexVal) {
|
||||
if (hexVal == null) return new byte[0];
|
||||
byte[] result = new byte[hexVal.length()/2];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
// 2 characters at a time
|
||||
String byteVal = hexVal.substring(2*i, 2*i +2);
|
||||
result[i] = Integer.valueOf(byteVal, 16).byteValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class TestVector {
|
||||
int id;
|
||||
SecretKey key;
|
||||
byte[] plainText;
|
||||
byte[] aad;
|
||||
byte[] cipherText;
|
||||
byte[] tag;
|
||||
GCMParameterSpec spec;
|
||||
String info;
|
||||
|
||||
TestVector(int id, String key, String iv, String pt, String aad,
|
||||
String ct, String tag) {
|
||||
this.id = id;
|
||||
this.key = new SecretKeySpec(HexToBytes(key), "AES");
|
||||
this.plainText = HexToBytes(pt);
|
||||
this.aad = HexToBytes(aad);
|
||||
this.cipherText = HexToBytes(ct);
|
||||
this.tag = HexToBytes(tag);
|
||||
this.spec = new GCMParameterSpec(this.tag.length * 8, HexToBytes(iv));
|
||||
this.info = "id = " + id + ", key=" + key + ", iv=" + iv + ", pt=" + pt +
|
||||
",aad=" + aad + ", ct=" + ct + ", tag=" + tag;
|
||||
}
|
||||
|
||||
TestVector() {};
|
||||
|
||||
TestVector duplicate() {
|
||||
TestVector t = new TestVector();
|
||||
t.id = id;
|
||||
t.key = key;
|
||||
t.plainText = plainText;
|
||||
t.cipherText = cipherText;
|
||||
t.aad = aad;
|
||||
t.tag = tag;
|
||||
t.spec = spec;
|
||||
t.info = info;
|
||||
return t;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean testFailed = false;
|
||||
|
||||
// These test vectors are found off NIST's CAVP page
|
||||
// http://csrc.nist.gov/groups/STM/cavp/index.html
|
||||
// inside the link named "GCM Test Vectors", i.e.
|
||||
// http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
|
||||
// CAVS 14.0, set of test vectors w/ count = 0, keysize = 128
|
||||
private static TestVector[] testValues = {
|
||||
// 96-bit iv w/ 128/120/112/104/96-bit tags
|
||||
// no plain text, no aad
|
||||
new TestVector(1, "11754cd72aec309bf52f7687212e8957",
|
||||
"3c819d9a9bed087615030b65",
|
||||
null, null, null,
|
||||
"250327c674aaf477aef2675748cf6971"),
|
||||
new TestVector(2, "272f16edb81a7abbea887357a58c1917",
|
||||
"794ec588176c703d3d2a7a07",
|
||||
null, null, null,
|
||||
"b6e6f197168f5049aeda32dafbdaeb"),
|
||||
new TestVector(3, "81b6844aab6a568c4556a2eb7eae752f",
|
||||
"ce600f59618315a6829bef4d",
|
||||
null, null, null,
|
||||
"89b43e9dbc1b4f597dbbc7655bb5"),
|
||||
new TestVector(4, "cde2f9a9b1a004165ef9dc981f18651b",
|
||||
"29512c29566c7322e1e33e8e",
|
||||
null, null, null,
|
||||
"2e58ce7dabd107c82759c66a75"),
|
||||
new TestVector(5, "b01e45cc3088aaba9fa43d81d481823f",
|
||||
"5a2c4a66468713456a4bd5e1",
|
||||
null, null, null,
|
||||
"014280f944f53c681164b2ff"),
|
||||
// 96-bit iv w/ 128/120/112/104/96-bit tags
|
||||
// no plain text, 16-byte aad
|
||||
new TestVector(6, "77be63708971c4e240d1cb79e8d77feb",
|
||||
"e0e00f19fed7ba0136a797f3",
|
||||
null,
|
||||
"7a43ec1d9c0a5a78a0b16533a6213cab",
|
||||
null,
|
||||
"209fcc8d3675ed938e9c7166709dd946"),
|
||||
new TestVector(7, "da0b615656135194ba6d3c851099bc48",
|
||||
"d39d4b4d3cc927885090e6c3",
|
||||
null,
|
||||
"e7e5e6f8dac913036cb2ff29e8625e0e",
|
||||
null,
|
||||
"ab967711a5770461724460b07237e2"),
|
||||
new TestVector(8, "7e0986937a88eef894235aba4a2f43b2",
|
||||
"92c4a631695907166b422d60",
|
||||
null,
|
||||
"85c185f8518f9f2cd597a8f9208fc76b",
|
||||
null,
|
||||
"3bb916b728df94fe9d1916736be1"),
|
||||
new TestVector(9, "c3db570d7f0c21e86b028f11465d1dc9",
|
||||
"f86970f58ceef89fc7cb679e",
|
||||
null,
|
||||
"c095240708c0f57c288d86090ae34ee1",
|
||||
null,
|
||||
"e043c52160d652e82c7262fcf4"),
|
||||
new TestVector(10, "bea48ae4980d27f357611014d4486625",
|
||||
"32bddb5c3aa998a08556454c",
|
||||
null,
|
||||
"8a50b0b8c7654bced884f7f3afda2ead",
|
||||
null,
|
||||
"8e0f6d8bf05ffebe6f500eb1"),
|
||||
// 96-bit iv w/ 128/120/112/104/96-bit tags
|
||||
// no plain text, 20-byte aad
|
||||
new TestVector(11, "2fb45e5b8f993a2bfebc4b15b533e0b4",
|
||||
"5b05755f984d2b90f94b8027",
|
||||
null,
|
||||
"e85491b2202caf1d7dce03b97e09331c32473941",
|
||||
null,
|
||||
"c75b7832b2a2d9bd827412b6ef5769db"),
|
||||
new TestVector(12, "9bf406339fcef9675bbcf156aa1a0661",
|
||||
"8be4a9543d40f542abacac95",
|
||||
null,
|
||||
"7167cbf56971793186333a6685bbd58d47d379b3",
|
||||
null,
|
||||
"5e7968d7bbd5ba58cfcc750e2ef8f1"),
|
||||
new TestVector(13, "a2e962fff70fd0f4d63be728b80556fc",
|
||||
"1fa7103483de43d09bc23db4",
|
||||
null,
|
||||
"2a58edf1d53f46e4e7ee5e77ee7aeb60fc360658",
|
||||
null,
|
||||
"fa37f2dbbefab1451eae1d0d74ca"),
|
||||
new TestVector(14, "6bf4fdce82926dcdfc52616ed5f23695",
|
||||
"cc0f5899a10615567e1193ed",
|
||||
null,
|
||||
"3340655592374c1da2f05aac3ee111014986107f",
|
||||
null,
|
||||
"8ad3385cce3b5e7c985908192c"),
|
||||
new TestVector(15, "4df7a13e43c3d7b66b1a72fac5ba398e",
|
||||
"97179a3a2d417908dcf0fb28",
|
||||
null,
|
||||
"cbb7fc0010c255661e23b07dbd804b1e06ae70ac",
|
||||
null,
|
||||
"37791edae6c137ea946cfb40"),
|
||||
// 96-bit iv w/ 128-bit tags, 13/16/32/51-byte plain text, no aad
|
||||
new TestVector(16, "fe9bb47deb3a61e423c2231841cfd1fb",
|
||||
"4d328eb776f500a2f7fb47aa",
|
||||
"f1cc3818e421876bb6b8bbd6c9",
|
||||
null,
|
||||
"b88c5c1977b35b517b0aeae967",
|
||||
"43fd4727fe5cdb4b5b42818dea7ef8c9"),
|
||||
new TestVector(17, "7fddb57453c241d03efbed3ac44e371c",
|
||||
"ee283a3fc75575e33efd4887",
|
||||
"d5de42b461646c255c87bd2962d3b9a2",
|
||||
null,
|
||||
"2ccda4a5415cb91e135c2a0f78c9b2fd",
|
||||
"b36d1df9b9d5e596f83e8b7f52971cb3"),
|
||||
new TestVector(18, "9971071059abc009e4f2bd69869db338",
|
||||
"07a9a95ea3821e9c13c63251",
|
||||
"f54bc3501fed4f6f6dfb5ea80106df0bd836e6826225b75c0222f6e859b35983",
|
||||
null,
|
||||
"0556c159f84ef36cb1602b4526b12009c775611bffb64dc0d9ca9297cd2c6a01",
|
||||
"7870d9117f54811a346970f1de090c41"),
|
||||
new TestVector(19, "594157ec4693202b030f33798b07176d",
|
||||
"49b12054082660803a1df3df",
|
||||
|
||||
"3feef98a976a1bd634f364ac428bb59cd51fb159ec1789946918dbd50ea6c9d594a3a31a5269b0da6936c29d063a5fa2cc8a1c",
|
||||
null,
|
||||
|
||||
"c1b7a46a335f23d65b8db4008a49796906e225474f4fe7d39e55bf2efd97fd82d4167de082ae30fa01e465a601235d8d68bc69",
|
||||
"ba92d3661ce8b04687e8788d55417dc2"),
|
||||
// 96-bit iv w/ 128-bit tags, 16-byte plain text, 16/20/48/90-byte aad
|
||||
new TestVector(20, "c939cc13397c1d37de6ae0e1cb7c423c",
|
||||
"b3d8cc017cbb89b39e0f67e2",
|
||||
"c3b3c41f113a31b73d9a5cd432103069",
|
||||
"24825602bd12a984e0092d3e448eda5f",
|
||||
"93fe7d9e9bfd10348a5606e5cafa7354",
|
||||
"0032a1dc85f1c9786925a2e71d8272dd"),
|
||||
new TestVector(21, "d4a22488f8dd1d5c6c19a7d6ca17964c",
|
||||
"f3d5837f22ac1a0425e0d1d5",
|
||||
"7b43016a16896497fb457be6d2a54122",
|
||||
"f1c5d424b83f96c6ad8cb28ca0d20e475e023b5a",
|
||||
"c2bd67eef5e95cac27e3b06e3031d0a8",
|
||||
"f23eacf9d1cdf8737726c58648826e9c"),
|
||||
new TestVector(22, "89850dd398e1f1e28443a33d40162664",
|
||||
"e462c58482fe8264aeeb7231",
|
||||
"2805cdefb3ef6cc35cd1f169f98da81a",
|
||||
|
||||
"d74e99d1bdaa712864eec422ac507bddbe2b0d4633cd3dff29ce5059b49fe868526c59a2a3a604457bc2afea866e7606",
|
||||
"ba80e244b7fc9025cd031d0f63677e06",
|
||||
"d84a8c3eac57d1bb0e890a8f461d1065"),
|
||||
new TestVector(23, "bd7c5c63b7542b56a00ebe71336a1588",
|
||||
"87721f23ba9c3c8ea5571abc",
|
||||
"de15ddbb1e202161e8a79af6a55ac6f3",
|
||||
|
||||
"a6ec8075a0d3370eb7598918f3b93e48444751624997b899a87fa6a9939f844e008aa8b70e9f4c3b1a19d3286bf543e7127bfecba1ad17a5ec53fccc26faecacc4c75369498eaa7d706aef634d0009279b11e4ba6c993e5e9ed9",
|
||||
"41eb28c0fee4d762de972361c863bc80",
|
||||
"9cb567220d0b252eb97bff46e4b00ff8"),
|
||||
// 8/1024-bit iv w/ 128-bit tag, no plain text, no aad
|
||||
new TestVector(24, "1672c3537afa82004c6b8a46f6f0d026",
|
||||
"05",
|
||||
null, null, null,
|
||||
"8e2ad721f9455f74d8b53d3141f27e8e"),
|
||||
new TestVector(25, "d0f1f4defa1e8c08b4b26d576392027c",
|
||||
|
||||
"42b4f01eb9f5a1ea5b1eb73b0fb0baed54f387ecaa0393c7d7dffc6af50146ecc021abf7eb9038d4303d91f8d741a11743166c0860208bcc02c6258fd9511a2fa626f96d60b72fcff773af4e88e7a923506e4916ecbd814651e9f445adef4ad6a6b6c7290cc13b956130eef5b837c939fcac0cbbcc9656cd75b13823ee5acdac",
|
||||
null, null, null,
|
||||
"7ab49b57ddf5f62c427950111c5c4f0d"),
|
||||
// 8-bit iv w/ 128-bit tag, 13-byte plain text, 90-byte aad
|
||||
new TestVector(26, "9f79239f0904eace50784b863e723f6b",
|
||||
"d9",
|
||||
"bdb0bb10c87965acd34d146171",
|
||||
|
||||
"44db436089327726c5f01139e1f339735c9e85514ccc2f167bad728010fb34a9072a9794c8a5e7361b1d0dbcdc9ac4091e354bb2896561f0486645252e9c78c86beece91bfa4f7cc4a8794ce1f305b1b735efdbf1ed1563c0be0",
|
||||
"7e5a7c8dadb3f0c7335b4d9d8d",
|
||||
"6b6ef1f53723a89f3bb7c6d043840717"),
|
||||
// 1024-bit iv w/ 128-bit tag, 51-byte plain text, 48-byte aad
|
||||
new TestVector(27, "141f1ce91989b07e7eb6ae1dbd81ea5e",
|
||||
|
||||
"49451da24bd6074509d3cebc2c0394c972e6934b45a1d91f3ce1d3ca69e194aa1958a7c21b6f21d530ce6d2cc5256a3f846b6f9d2f38df0102c4791e57df038f6e69085646007df999751e248e06c47245f4cd3b8004585a7470dee1690e9d2d63169a58d243c0b57b3e5b4a481a3e4e8c60007094ef3adea2e8f05dd3a1396f",
|
||||
|
||||
"d384305af2388699aa302f510913fed0f2cb63ba42efa8c5c9de2922a2ec2fe87719dadf1eb0aef212b51e74c9c5b934104a43",
|
||||
|
||||
"630cf18a91cc5a6481ac9eefd65c24b1a3c93396bd7294d6b8ba323951727666c947a21894a079ef061ee159c05beeb4",
|
||||
|
||||
"f4c34e5fbe74c0297313268296cd561d59ccc95bbfcdfcdc71b0097dbd83240446b28dc088abd42b0fc687f208190ff24c0548",
|
||||
"dbb93bbb56d0439cd09f620a57687f5d"),
|
||||
};
|
||||
|
||||
void executeArray(TestVector tv) throws Exception {
|
||||
Cipher c = Cipher.getInstance("AES/GCM/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
try {
|
||||
System.out.println("Test #" + tv.id + ": byte[].");
|
||||
|
||||
c.init(Cipher.ENCRYPT_MODE, tv.key, tv.spec);
|
||||
c.updateAAD(tv.aad);
|
||||
byte[] ctPlusTag = c.doFinal(tv.plainText);
|
||||
|
||||
c.init(Cipher.DECRYPT_MODE, tv.key, tv.spec);
|
||||
c.updateAAD(tv.aad);
|
||||
byte[] pt = c.doFinal(ctPlusTag); // should fail if tag mismatched
|
||||
|
||||
// check encryption/decryption results just to be sure
|
||||
if (!Arrays.equals(tv.plainText, pt)) {
|
||||
System.out.println("PlainText diff failed for test# " + tv.id);
|
||||
testFailed = true;
|
||||
}
|
||||
int ctLen = tv.cipherText.length;
|
||||
if (!Arrays.equals(tv.cipherText,
|
||||
Arrays.copyOf(ctPlusTag, ctLen))) {
|
||||
System.out.println("CipherText diff failed for test# " + tv.id);
|
||||
testFailed = true;
|
||||
}
|
||||
int tagLen = tv.tag.length;
|
||||
if (!Arrays.equals
|
||||
(tv.tag,
|
||||
Arrays.copyOfRange(ctPlusTag, ctLen, ctLen+tagLen))) {
|
||||
System.out.println("Tag diff failed for test# " + tv.id);
|
||||
testFailed = true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// continue testing other test vectors
|
||||
System.out.println("Failed Test Vector: " + tv);
|
||||
ex.printStackTrace();
|
||||
testFailed = true;
|
||||
}
|
||||
if (testFailed) {
|
||||
throw new Exception("Test Failed");
|
||||
}
|
||||
}
|
||||
|
||||
void executeByteBuffer(TestVector tv, boolean direct, int offset) throws Exception {
|
||||
Cipher c = Cipher.getInstance("AES/GCM/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
|
||||
ByteBuffer src;
|
||||
ByteBuffer ctdst;
|
||||
ByteBuffer ptdst;
|
||||
|
||||
if (direct) {
|
||||
System.out.print("Test #" + tv.id + ": ByteBuffer Direct.");
|
||||
src = ByteBuffer.allocateDirect(tv.plainText.length + offset);
|
||||
ctdst = ByteBuffer.allocateDirect(tv.cipherText.length + tv.tag.length + offset);
|
||||
ptdst = ByteBuffer.allocateDirect(tv.plainText.length + offset);
|
||||
} else {
|
||||
System.out.print("Test #" + tv.id + ": ByteBuffer Heap.");
|
||||
src = ByteBuffer.allocate(tv.plainText.length + offset);
|
||||
ctdst = ByteBuffer.allocate(tv.cipherText.length + tv.tag.length + offset);
|
||||
ptdst = ByteBuffer.allocate(tv.plainText.length + offset);
|
||||
}
|
||||
|
||||
byte[] plainText;
|
||||
|
||||
if (offset > 0) {
|
||||
System.out.println(" offset = " + offset);
|
||||
plainText = new byte[tv.plainText.length + offset];
|
||||
System.arraycopy(tv.plainText, 0, plainText, offset,
|
||||
tv.plainText.length);
|
||||
} else {
|
||||
System.out.println();
|
||||
plainText = tv.plainText;
|
||||
}
|
||||
|
||||
src.put(plainText);
|
||||
src.position(offset);
|
||||
ctdst.position(offset);
|
||||
ctdst.mark();
|
||||
ptdst.position(offset);
|
||||
ptdst.mark();
|
||||
|
||||
try {
|
||||
c.init(Cipher.ENCRYPT_MODE, tv.key, tv.spec);
|
||||
c.updateAAD(tv.aad);
|
||||
c.doFinal(src, ctdst);
|
||||
|
||||
ctdst.reset();
|
||||
ByteBuffer tag = ctdst.duplicate();
|
||||
tag.position(tag.limit() - tv.tag.length);
|
||||
|
||||
c.init(Cipher.DECRYPT_MODE, tv.key, tv.spec);
|
||||
c.updateAAD(tv.aad);
|
||||
c.doFinal(ctdst, ptdst); // should fail if tag mismatched
|
||||
|
||||
ptdst.reset();
|
||||
// check encryption/decryption results just to be sure
|
||||
if (ptdst.compareTo(ByteBuffer.wrap(tv.plainText)) != 0) {
|
||||
System.out.println("\t PlainText diff failed for test# " + tv.id);
|
||||
testFailed = true;
|
||||
}
|
||||
|
||||
ctdst.reset();
|
||||
ctdst.limit(ctdst.limit() - tv.tag.length);
|
||||
if (ctdst.compareTo(ByteBuffer.wrap(tv.cipherText)) != 0) {
|
||||
System.out.println("\t CipherText diff failed for test# " + tv.id);
|
||||
testFailed = true;
|
||||
}
|
||||
|
||||
int mismatch = 0;
|
||||
for (int i = 0; i < tv.tag.length; i++) {
|
||||
mismatch |= tag.get() ^ tv.tag[i];
|
||||
}
|
||||
if (mismatch != 0) {
|
||||
System.out.println("\t Tag diff failed for test# " + tv.id);
|
||||
testFailed = true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// continue testing other test vectors
|
||||
System.out.println("\t Failed Test Vector ( #" + tv.id + ") : " + tv);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
TestKATForGCM test = new TestKATForGCM();
|
||||
for (TestVector tv : testValues) {
|
||||
test.executeArray(tv);
|
||||
test.executeByteBuffer(tv, false, 0);
|
||||
test.executeByteBuffer(tv, true, 0);
|
||||
test.executeByteBuffer(tv, false, 2);
|
||||
test.executeByteBuffer(tv, true, 2);
|
||||
}
|
||||
if (!testFailed) {
|
||||
System.out.println("Tests passed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8180392
|
||||
* @summary Ensure SunJCE provider throws exception for unsupported modes
|
||||
* and padding combinations
|
||||
*/
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import javax.crypto.*;
|
||||
|
||||
public class TestNoPaddingModes {
|
||||
|
||||
// SunJCE only supports NoPadding with following modes
|
||||
private static final String[] MODES = {
|
||||
"CTR", "CTS", "GCM"
|
||||
};
|
||||
private static final String[] PADDINGS = {
|
||||
"PKCS5Padding", "ISO10126Padding"
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Provider p = Security.getProvider(
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
String transformation;
|
||||
for (String mode : MODES) {
|
||||
for (String padding : PADDINGS) {
|
||||
transformation = "AES/" + mode + "/" + padding;
|
||||
|
||||
System.out.println("Test using " + transformation);
|
||||
try {
|
||||
Cipher c = Cipher.getInstance(transformation,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
throw new RuntimeException("=> Fail, no exception thrown");
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException ex) {
|
||||
System.out.println("=> Expected ex: " + ex);
|
||||
}
|
||||
try {
|
||||
Cipher c = Cipher.getInstance(transformation, p);
|
||||
throw new RuntimeException("=> Fail, no exception thrown");
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException ex) {
|
||||
System.out.println("=> Expected ex: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Test Passed");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2024, 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 java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.util.Random;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.ShortBufferException;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8043836
|
||||
* @summary Test AES encryption with no padding. Expect the original data length
|
||||
* is the same as the encrypted data.
|
||||
* @key randomness
|
||||
*/
|
||||
public class TestNonexpanding {
|
||||
|
||||
private static final String ALGORITHM = "AES";
|
||||
private static final String PROVIDER =
|
||||
System.getProperty("test.provider.name", "SunJCE");
|
||||
private static final String[] MODES = { "ECb", "CbC", "OFB", "OFB150",
|
||||
"cFB", "CFB7", "cFB8", "cFB16", "cFB24", "cFB32", "Cfb40", "cfB48",
|
||||
"cfB56", "cfB64", "cfB72", "cfB80", "cfB88", "cfB96", "cfb104",
|
||||
"cfB112", "cfB120", "GCM" };
|
||||
private static final String PADDING = "NoPadding";
|
||||
private static final int KEY_LENGTH = 128;
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
TestNonexpanding test = new TestNonexpanding();
|
||||
for (String mode : MODES) {
|
||||
test.runTest(ALGORITHM, mode, PADDING);
|
||||
}
|
||||
}
|
||||
|
||||
public void runTest(String algo, String mo, String pad) throws Exception {
|
||||
Cipher ci = null;
|
||||
SecretKey key = null;
|
||||
try {
|
||||
// Initialization
|
||||
Random rdm = new Random();
|
||||
byte[] plainText = new byte[128];
|
||||
rdm.nextBytes(plainText);
|
||||
|
||||
ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
|
||||
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER);
|
||||
kg.init(KEY_LENGTH);
|
||||
key = kg.generateKey();
|
||||
|
||||
// encrypt
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = ci.update(plainText, 0, plainText.length, cipherText,
|
||||
0);
|
||||
ci.doFinal(cipherText, offset);
|
||||
|
||||
// Comparison
|
||||
if (!(plainText.length == cipherText.length)) {
|
||||
// The result of encryption in GCM is a combination of an
|
||||
// authentication tag and cipher text.
|
||||
if (mo.equalsIgnoreCase("GCM")) {
|
||||
GCMParameterSpec spec = ci.getParameters().getParameterSpec(GCMParameterSpec.class);
|
||||
int cipherTextLength = cipherText.length - spec.getTLen()
|
||||
/ 8;
|
||||
if (plainText.length == cipherTextLength) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
System.out.println("Original length: " + plainText.length);
|
||||
System.out.println("Cipher text length: " + cipherText.length);
|
||||
throw new RuntimeException("Test failed!");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
//CFB7 and OFB150 are for negative testing
|
||||
if (!mo.equalsIgnoreCase("CFB7") && !mo.equalsIgnoreCase("OFB150")) {
|
||||
System.out.println("Unexpected NoSuchAlgorithmException with mode: "
|
||||
+ mo);
|
||||
throw new RuntimeException("Test failed!");
|
||||
}
|
||||
} catch ( NoSuchProviderException | NoSuchPaddingException
|
||||
| InvalidKeyException | InvalidParameterSpecException
|
||||
| ShortBufferException | IllegalBlockSizeException
|
||||
| BadPaddingException e) {
|
||||
System.out.println("Test failed!");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
140
test/jdk/com/sun/crypto/provider/Cipher/AES/TestSameBuffer.java
Normal file
140
test/jdk/com/sun/crypto/provider/Cipher/AES/TestSameBuffer.java
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2024, 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 java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Random;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.ShortBufferException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8043836
|
||||
* @summary Test AES ciphers with different modes and padding schemes (ECB mode
|
||||
* doesn't use IV). The test tries 3 different read methods of
|
||||
* CipherInputStream.
|
||||
* @key randomness
|
||||
*/
|
||||
public class TestSameBuffer {
|
||||
|
||||
private static final String ALGORITHM = "AES";
|
||||
private static final String PROVIDER =
|
||||
System.getProperty("test.provider.name", "SunJCE");
|
||||
private static final String[] MODES = { "ECb", "CbC", "OFB", "CFB150",
|
||||
"cFB", "CFB7", " cFB8", "cFB16", "cFB24", "cFB32", "Cfb40",
|
||||
"cfB48", " cfB56", "cfB64", "cfB72", "cfB80", "cfB88", "cfB96",
|
||||
"cfb104", "cfB112", "cfB120" };
|
||||
private static final String PADDING = "NoPadding";
|
||||
private static final int KEY_LENGTH = 128;
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
TestSameBuffer test = new TestSameBuffer();
|
||||
for (String mode : MODES) {
|
||||
test.runTest(ALGORITHM, mode, PADDING);
|
||||
}
|
||||
}
|
||||
|
||||
public void runTest(String algo, String mo, String pad) throws Exception {
|
||||
Cipher ci = null;
|
||||
byte[] iv = null;
|
||||
AlgorithmParameterSpec aps = null;
|
||||
SecretKey key = null;
|
||||
try {
|
||||
// Initialization
|
||||
Random rdm = new Random();
|
||||
byte[] plainText = new byte[128];
|
||||
rdm.nextBytes(plainText);
|
||||
|
||||
// keep the plain text
|
||||
byte[] tmpText = new byte[plainText.length];
|
||||
for (int i = 0; i < plainText.length; i++) {
|
||||
tmpText[i] = plainText[i];
|
||||
}
|
||||
|
||||
ci = Cipher.getInstance(algo + "/" + mo + "/" + pad, PROVIDER);
|
||||
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algo, PROVIDER);
|
||||
kg.init(KEY_LENGTH);
|
||||
key = kg.generateKey();
|
||||
|
||||
// encrypt
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
int offset = ci
|
||||
.update(plainText, 0, plainText.length, plainText, 0);
|
||||
ci.doFinal(plainText, offset);
|
||||
|
||||
if (!mo.equalsIgnoreCase("ECB")) {
|
||||
iv = ci.getIV();
|
||||
aps = new IvParameterSpec(iv);
|
||||
} else {
|
||||
aps = null;
|
||||
}
|
||||
|
||||
ci.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
byte[] recoveredText = new byte[ci.getOutputSize(plainText.length)];
|
||||
ci.doFinal(plainText, 0, plainText.length, recoveredText);
|
||||
|
||||
// Comparison
|
||||
if (!java.util.Arrays.equals(tmpText, recoveredText)) {
|
||||
System.out.println("Original: ");
|
||||
dumpBytes(plainText);
|
||||
System.out.println("Recovered: ");
|
||||
dumpBytes(recoveredText);
|
||||
throw new RuntimeException(
|
||||
"Original text is not equal with recovered text, with mode:"
|
||||
+ mo);
|
||||
}
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
//CFB7 and CFB150 are for negative testing
|
||||
if (!mo.equalsIgnoreCase("CFB7") && !mo.equalsIgnoreCase("CFB150")) {
|
||||
System.out.println("Unexpected NoSuchAlgorithmException with mode: "
|
||||
+ mo);
|
||||
throw new RuntimeException("Test failed!");
|
||||
}
|
||||
} catch (NoSuchProviderException | NoSuchPaddingException
|
||||
| InvalidKeyException | InvalidAlgorithmParameterException
|
||||
| ShortBufferException | IllegalBlockSizeException
|
||||
| BadPaddingException e) {
|
||||
System.out.println("Test failed!");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpBytes(byte[] bytes) {
|
||||
for (byte b : bytes) {
|
||||
System.out.print(Integer.toHexString(b));
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
197
test/jdk/com/sun/crypto/provider/Cipher/AES/TestShortBuffer.java
Normal file
197
test/jdk/com/sun/crypto/provider/Cipher/AES/TestShortBuffer.java
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4979126
|
||||
* @summary Ensure update()/doFinal() matches javadoc description
|
||||
* when ShortBufferException is thrown.
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
import java.util.Arrays;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import java.math.BigInteger;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
import java.security.Provider;
|
||||
|
||||
public class TestShortBuffer {
|
||||
private static final String ALGO = "AES";
|
||||
private static final String[] MODES = {
|
||||
"ECB", "CBC", "PCBC", "CFB16", "OFB8"
|
||||
};
|
||||
private static final SecretKey KEY =
|
||||
new SecretKeySpec(new byte[16], ALGO);
|
||||
private static byte[] SHORTBUFFER = new byte[1];
|
||||
|
||||
private static final byte[] PLAINTEXT = new byte[30];
|
||||
static {
|
||||
PLAINTEXT[0] = (byte)0x15;
|
||||
};
|
||||
private Cipher ci = null;
|
||||
private byte[] in = null;
|
||||
private byte[] expected = null;
|
||||
private byte[] out = null;
|
||||
private int outOffset = 0;
|
||||
|
||||
private TestShortBuffer(Cipher ci) {
|
||||
this.ci = ci;
|
||||
}
|
||||
|
||||
private void init(byte[] in, byte[] expected) {
|
||||
this.in = (byte[]) in.clone();
|
||||
this.expected = (byte[]) expected.clone();
|
||||
this.out = new byte[expected.length];
|
||||
this.outOffset = 0;
|
||||
}
|
||||
|
||||
private static void runTest() throws Exception {
|
||||
// Initialization
|
||||
for (int i = 0; i < MODES.length; i++) {
|
||||
System.out.println("===== TESTING MODE " + MODES[i] + " =====");
|
||||
Cipher ci = Cipher.getInstance(ALGO+"/"+MODES[i]+"/PKCS5Padding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
TestShortBuffer test = null;
|
||||
int stored = 0;
|
||||
AlgorithmParameters params = null;
|
||||
byte[] cipherText = null;
|
||||
byte[] shortBuffer = new byte[8];
|
||||
for (int k = 0; k < 2; k++) {
|
||||
byte[] expected = null;
|
||||
switch (k) {
|
||||
case 0: // Encryption
|
||||
System.out.println("Testing with Cipher.ENCRYPT_MODE");
|
||||
ci.init(Cipher.ENCRYPT_MODE, KEY);
|
||||
cipherText = ci.doFinal(PLAINTEXT);
|
||||
test = new TestShortBuffer(ci);
|
||||
test.init(PLAINTEXT, cipherText);
|
||||
params = ci.getParameters();
|
||||
break;
|
||||
case 1: // Decryption
|
||||
System.out.println("Testing with Cipher.DECRYPT_MODE");
|
||||
ci.init(Cipher.DECRYPT_MODE, KEY, params);
|
||||
test = new TestShortBuffer(ci);
|
||||
test.init(cipherText, PLAINTEXT);
|
||||
break;
|
||||
}
|
||||
int offset = 2 + i*5;
|
||||
test.testUpdate();
|
||||
test.testUpdateWithUpdate(offset);
|
||||
test.testDoFinal();
|
||||
test.testDoFinalWithUpdate(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkOutput() throws Exception {
|
||||
if (!Arrays.equals(out, expected)) {
|
||||
System.out.println("got: " + new BigInteger(out));
|
||||
System.out.println("expect: " + new BigInteger(expected));
|
||||
throw new Exception("Generated different outputs");
|
||||
}
|
||||
}
|
||||
private void testUpdate() throws Exception {
|
||||
outOffset = 0;
|
||||
int stored = 0;
|
||||
try {
|
||||
stored = ci.update(in, 0, in.length, SHORTBUFFER);
|
||||
throw new Exception("Should throw ShortBufferException!");
|
||||
} catch (ShortBufferException sbe) {
|
||||
System.out.println("Expected SBE thrown....");
|
||||
// retry with a large-enough buffer according to javadoc
|
||||
stored = ci.update(in, 0, in.length, out);
|
||||
stored = ci.doFinal(out, outOffset += stored);
|
||||
if (out.length != (stored + outOffset)) {
|
||||
throw new Exception("Wrong number of output bytes");
|
||||
}
|
||||
}
|
||||
checkOutput();
|
||||
}
|
||||
private void testUpdateWithUpdate(int offset) throws Exception {
|
||||
outOffset = 0;
|
||||
int stored = 0;
|
||||
byte[] out1 = ci.update(in, 0, offset);
|
||||
if (out1 != null) {
|
||||
System.arraycopy(out1, 0, out, 0, out1.length);
|
||||
outOffset += out1.length;
|
||||
}
|
||||
try {
|
||||
stored = ci.update(in, offset, in.length-offset, SHORTBUFFER);
|
||||
throw new Exception("Should throw ShortBufferException!");
|
||||
} catch (ShortBufferException sbe) {
|
||||
System.out.println("Expected SBE thrown....");
|
||||
// retry with a large-enough buffer according to javadoc
|
||||
stored = ci.update(in, offset, in.length-offset,
|
||||
out, outOffset);
|
||||
stored = ci.doFinal(out, outOffset+=stored);
|
||||
if (out.length != (stored + outOffset)) {
|
||||
throw new Exception("Wrong number of output bytes");
|
||||
}
|
||||
}
|
||||
checkOutput();
|
||||
}
|
||||
private void testDoFinal() throws Exception {
|
||||
outOffset = 0;
|
||||
int stored = 0;
|
||||
try {
|
||||
stored = ci.doFinal(in, 0, in.length, SHORTBUFFER);
|
||||
throw new Exception("Should throw ShortBufferException!");
|
||||
} catch (ShortBufferException sbe) {
|
||||
System.out.println("Expected SBE thrown....");
|
||||
// retry with a large-enough buffer according to javadoc
|
||||
stored = ci.doFinal(in, 0, in.length, out, 0);
|
||||
if (out.length != stored) {
|
||||
throw new Exception("Wrong number of output bytes");
|
||||
}
|
||||
}
|
||||
checkOutput();
|
||||
}
|
||||
|
||||
private void testDoFinalWithUpdate(int offset) throws Exception {
|
||||
outOffset = 0;
|
||||
int stored = 0;
|
||||
byte[] out1 = ci.update(in, 0, offset);
|
||||
if (out1 != null) {
|
||||
System.arraycopy(out1, 0, out, 0, out1.length);
|
||||
outOffset += out1.length;
|
||||
}
|
||||
try {
|
||||
stored = ci.doFinal(in, offset, in.length-offset, SHORTBUFFER);
|
||||
throw new Exception("Should throw ShortBufferException!");
|
||||
} catch (ShortBufferException sbe) {
|
||||
System.out.println("Expected SBE thrown....");
|
||||
// retry with a large-enough buffer according to javadoc
|
||||
stored = ci.doFinal(in, offset, in.length-offset,
|
||||
out, outOffset);
|
||||
if (out.length != (stored + outOffset)) {
|
||||
throw new Exception("Wrong number of output bytes");
|
||||
}
|
||||
}
|
||||
checkOutput();
|
||||
}
|
||||
public static void main(String[] argv) throws Exception {
|
||||
runTest();
|
||||
System.out.println("Test Passed");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2021, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 0000000
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main BlowfishTestVector
|
||||
* @summary Known Answer Test for Blowfish cipher with ECB mode
|
||||
* @author Jan Luehe
|
||||
*/
|
||||
|
||||
import java.security.*;
|
||||
import java.util.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
public class BlowfishTestVector {
|
||||
|
||||
// test vector #1 (checking for the "signed" bug)
|
||||
// (ECB mode)
|
||||
private static final byte[] TEST_KEY_1 = new byte[] {
|
||||
(byte)0x1c, (byte)0x58, (byte)0x7f, (byte)0x1c,
|
||||
(byte)0x13, (byte)0x92, (byte)0x4f, (byte)0xef
|
||||
};
|
||||
private static final byte[] TV_P1 = new byte[] {
|
||||
(byte)0x30, (byte)0x55, (byte)0x32, (byte)0x28,
|
||||
(byte)0x6d, (byte)0x6f, (byte)0x29, (byte)0x5a
|
||||
};
|
||||
private static final byte[] TV_C1 = new byte[] {
|
||||
(byte)0x55, (byte)0xcb, (byte)0x37, (byte)0x74,
|
||||
(byte)0xd1, (byte)0x3e, (byte)0xf2, (byte)0x01
|
||||
};
|
||||
|
||||
// test vector #2 (offical vector by Bruce Schneier)
|
||||
// (ECB mode)
|
||||
private static final String S_TEST_KEY_2 = "Who is John Galt?";
|
||||
|
||||
private static final byte[] TV_P2 = new byte[] {
|
||||
(byte)0xfe, (byte)0xdc, (byte)0xba, (byte)0x98,
|
||||
(byte)0x76, (byte)0x54, (byte)0x32, (byte)0x10
|
||||
};
|
||||
private static final byte[] TV_C2 = new byte[] {
|
||||
(byte)0xcc, (byte)0x91, (byte)0x73, (byte)0x2b,
|
||||
(byte)0x80, (byte)0x22, (byte)0xf6, (byte)0x84
|
||||
};
|
||||
|
||||
public static void main(String[] argv) throws Exception {
|
||||
|
||||
String transformation = "Blowfish/ECB/NoPadding";
|
||||
Cipher cipher = Cipher.getInstance(transformation, "SunJCE");
|
||||
int MAX_KEY_SIZE = Cipher.getMaxAllowedKeyLength(transformation);
|
||||
//
|
||||
// test 1
|
||||
//
|
||||
if (TEST_KEY_1.length*8 <= MAX_KEY_SIZE) {
|
||||
SecretKey sKey = new SecretKeySpec(TEST_KEY_1, "Blowfish");
|
||||
try {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, sKey);
|
||||
byte[] c1 = cipher.doFinal(TV_P1);
|
||||
if (!Arrays.equals(c1, TV_C1))
|
||||
throw new Exception("Encryption (Test vector 1) failed");
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, sKey);
|
||||
byte[] p1 = cipher.doFinal(c1);
|
||||
if (!Arrays.equals(p1, TV_P1))
|
||||
throw new Exception("Decryption (Test vector 1) failed");
|
||||
} catch (SecurityException se) {
|
||||
TestUtil.handleSE(se);
|
||||
}
|
||||
}
|
||||
//
|
||||
// test 2
|
||||
//
|
||||
byte[] testKey2 = S_TEST_KEY_2.getBytes();
|
||||
if (testKey2.length*8 <= MAX_KEY_SIZE) {
|
||||
SecretKey sKey = new SecretKeySpec(testKey2, "Blowfish");
|
||||
try {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, sKey);
|
||||
byte[] c2 = cipher.doFinal(TV_P2);
|
||||
if (!Arrays.equals(c2, TV_C2))
|
||||
throw new Exception("Encryption (Test vector 2) failed");
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, sKey);
|
||||
byte[] p2 = cipher.doFinal(c2);
|
||||
if (!Arrays.equals(p2, TV_P2))
|
||||
throw new Exception("Decryption (Test vector 2) failed");
|
||||
} catch (SecurityException se) {
|
||||
TestUtil.handleSE(se);
|
||||
}
|
||||
}
|
||||
System.out.println("Test passed");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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 java.security.NoSuchAlgorithmException;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048601
|
||||
* @library ../
|
||||
* @summary Test Blowfish cipher with different MODES and padding
|
||||
*/
|
||||
|
||||
public class TestCipherBlowfish extends TestCipher {
|
||||
|
||||
TestCipherBlowfish(String[] modes, String[] paddings) throws NoSuchAlgorithmException {
|
||||
super("Blowfish", modes, paddings, 32, 448);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new TestCipherBlowfish(new String[]{ "CBC", "ECB", "PCBC",
|
||||
//CFBx
|
||||
"CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40",
|
||||
"CFB48", "CFB56", "CFB64",
|
||||
//OFBx
|
||||
"OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40",
|
||||
"OFB48", "OFB56", "OFB64"},
|
||||
new String[]{ "NoPaDDing", "PKCS5Padding"}).runAll();
|
||||
new TestCipherBlowfish(new String[]{ "CTR", "CTS" },
|
||||
new String[]{ "NoPaDDing" }).runAll();
|
||||
}
|
||||
}
|
||||
190
test/jdk/com/sun/crypto/provider/Cipher/CTR/CounterMode.java
Normal file
190
test/jdk/com/sun/crypto/provider/Cipher/CTR/CounterMode.java
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4688768
|
||||
* @library ../UTIL
|
||||
* @build TestUtil
|
||||
* @run main CounterMode
|
||||
* @summary Verify that CTR mode works as expected
|
||||
* @author Andreas Sterbenz
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
public class CounterMode {
|
||||
|
||||
private final static byte[] toByteArray(String s) {
|
||||
char[] c = s.toCharArray();
|
||||
byte[] t = new byte[c.length / 2];
|
||||
int n = 0;
|
||||
int d1 = -1;
|
||||
int d2 = -1;
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
char ch = c[i];
|
||||
if (d1 == -1) {
|
||||
d1 = Character.digit(ch, 16);
|
||||
} else {
|
||||
d2 = Character.digit(ch, 16);
|
||||
if (d2 != -1) {
|
||||
t[n++] = (byte)((d1 << 4) | d2);
|
||||
d1 = -1;
|
||||
d2 = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d1 != -1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (n == t.length) {
|
||||
return t;
|
||||
}
|
||||
byte[] b = new byte[n];
|
||||
System.arraycopy(t, 0, b, 0, n);
|
||||
return b;
|
||||
}
|
||||
|
||||
private final static String[] ALGORITHM = {
|
||||
"AES",
|
||||
"AES",
|
||||
"AES",
|
||||
"AES",
|
||||
"AES",
|
||||
"DES",
|
||||
"DES",
|
||||
"DESede",
|
||||
"DESede",
|
||||
"Blowfish",
|
||||
"Blowfish",
|
||||
};
|
||||
|
||||
private final static byte[][] KEYS = {
|
||||
toByteArray("2b7e151628aed2a6abf7158809cf4f3c"),
|
||||
toByteArray("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
|
||||
toByteArray("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
|
||||
toByteArray("2b7e151628aed2a6abf7158809cf4f3c"),
|
||||
toByteArray("2b7e151628aed2a6abf7158809cf4f3c"),
|
||||
toByteArray("2b7e151628aed2a6"),
|
||||
toByteArray("874d6191b620e326"),
|
||||
toByteArray("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
|
||||
toByteArray("874d6191b620e3261bef6864990db6ce9806f66b7970fdff"),
|
||||
toByteArray("2b7e151628aed2a6abf7158809cf4f3c"),
|
||||
toByteArray("874d6191b620e3261bef6864990db6ce"),
|
||||
};
|
||||
|
||||
private final static byte[][] IVS = {
|
||||
toByteArray("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
|
||||
toByteArray("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
|
||||
toByteArray("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
|
||||
toByteArray("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
|
||||
toByteArray("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
|
||||
toByteArray("fffffffffffffffd"),
|
||||
toByteArray("f0f1f2f3f4f5f6f7"),
|
||||
toByteArray("f0f1f2f3f4f5f6f7"),
|
||||
toByteArray("f0f1f2f3f4f5f6ff"),
|
||||
toByteArray("f0f1f2f3f4f5f6f7"),
|
||||
toByteArray("f0f1f2f3f4f5f6ff"),
|
||||
};
|
||||
|
||||
private final static byte[][] PLAIN = {
|
||||
toByteArray("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"),
|
||||
toByteArray("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"),
|
||||
toByteArray("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"),
|
||||
toByteArray("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c37"),
|
||||
toByteArray(""),
|
||||
toByteArray("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"),
|
||||
toByteArray("6bc1bee22e409f96"),
|
||||
toByteArray("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"),
|
||||
toByteArray("6bc1bee22e409f96e9"),
|
||||
toByteArray("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"),
|
||||
toByteArray("6bc1bee22e409f"),
|
||||
};
|
||||
|
||||
private final static byte[][] CIPHER = {
|
||||
toByteArray("874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee"),
|
||||
toByteArray("1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050"),
|
||||
toByteArray("601ec313775789a5b7a7f504bbf3d228f443e3ca4d62b59aca84e990cacaf5c52b0930daa23de94ce87017ba2d84988ddfc9c58db67aada613c2dd08457941a6"),
|
||||
toByteArray("874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009c"),
|
||||
toByteArray(""),
|
||||
toByteArray("79:62:2c:42:59:8e:9a:1a:e3:da:3d:7c:88:4f:0a:d2:eb:1a:e2:27:b0:d7:16:f6:6d:8d:50:fe:8b:9f:87:a7:ba:83:65:48:5b:87:12:07:d0:3f:3d:f0:b2:c8:98:e9:bb:a0:ad:35:98:e8:4f:d8:ef:91:85:2c:55:c0:b0:b9"),
|
||||
toByteArray("79:5e:90:a6:35:9d:1e:b2"),
|
||||
toByteArray("0a:ce:b5:1e:20:74:2e:29:17:28:55:d6:c9:28:62:c3:43:a5:da:30:90:9f:8f:46:60:3d:b6:5c:b6:bc:21:52:06:2f:6f:b4:14:0d:ef:23:e2:99:fd:4b:dc:65:ee:6a:50:76:5b:86:43:65:56:ee:1a:7a:25:07:43:b4:f0:88"),
|
||||
toByteArray("12:06:8f:ae:bb:47:a7:68:8b"),
|
||||
toByteArray("ac:92:83:dd:79:f3:c2:36:0c:da:06:bd:ed:69:ca:47:42:2e:68:11:5e:6b:63:56:3e:87:b0:be:98:17:42:7d:8b:4a:5b:be:af:0c:2b:f0:1c:1c:62:60:b9:2c:69:04:ca:c9:23:d2:08:9d:8d:57:7f:61:f7:e6:79:83:ae:89"),
|
||||
toByteArray("65:ff:ee:6b:64:9e:a0"),
|
||||
};
|
||||
|
||||
private static String toString(byte[] b) {
|
||||
StringBuffer sb = new StringBuffer(b.length * 3);
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
int k = b[i] & 0xff;
|
||||
if (i != 0) {
|
||||
sb.append(':');
|
||||
}
|
||||
sb.append(Character.forDigit(k >> 4, 16));
|
||||
sb.append(Character.forDigit(k & 0xf, 16));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (int i = 0; i < KEYS.length; i++) {
|
||||
try {
|
||||
String alg = ALGORITHM[i];
|
||||
int MAX_KEYSIZE = Cipher.getMaxAllowedKeyLength(alg);
|
||||
if (KEYS[i].length*8 > MAX_KEYSIZE) {
|
||||
// skip tests using keys whose length exceeds
|
||||
// what's configured in jce jurisdiction policy files.
|
||||
continue;
|
||||
}
|
||||
System.out.println("Running test " + i + " (" + alg + ")");
|
||||
Cipher cipher = Cipher.getInstance(alg + "/CTR/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
SecretKeySpec key = new SecretKeySpec(KEYS[i], alg);
|
||||
IvParameterSpec iv = new IvParameterSpec(IVS[i]);
|
||||
byte[] plainText = PLAIN[i];
|
||||
byte[] cipherText = CIPHER[i];
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
|
||||
byte[] enc = cipher.doFinal(plainText);
|
||||
if (Arrays.equals(cipherText, enc) == false) {
|
||||
System.out.println("plain: " + toString(PLAIN[i]));
|
||||
System.out.println("cipher: " + toString(CIPHER[i]));
|
||||
System.out.println("actual: " + toString(enc));
|
||||
throw new RuntimeException("Encryption failure for test " + i);
|
||||
}
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, iv);
|
||||
byte[] dec = cipher.doFinal(cipherText);
|
||||
if (Arrays.equals(plainText, dec) == false) {
|
||||
throw new RuntimeException("Decryption failure for test " + i);
|
||||
}
|
||||
} catch (SecurityException ex) {
|
||||
TestUtil.handleSE(ex);
|
||||
}
|
||||
}
|
||||
System.out.println("Done");
|
||||
}
|
||||
}
|
||||
367
test/jdk/com/sun/crypto/provider/Cipher/CTS/CTSMode.java
Normal file
367
test/jdk/com/sun/crypto/provider/Cipher/CTS/CTSMode.java
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 5083253
|
||||
* @run main CTSMode
|
||||
* @summary Verify that CTR mode works as expected
|
||||
* @author Valerie Peng
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.security.AlgorithmParameters;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
public class CTSMode {
|
||||
|
||||
private final static byte[] toByteArray(String s) {
|
||||
char[] c = s.toCharArray();
|
||||
byte[] t = new byte[c.length / 2];
|
||||
int n = 0;
|
||||
int d1 = -1;
|
||||
int d2 = -1;
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
char ch = c[i];
|
||||
if (d1 == -1) {
|
||||
d1 = Character.digit(ch, 16);
|
||||
} else {
|
||||
d2 = Character.digit(ch, 16);
|
||||
if (d2 != -1) {
|
||||
t[n++] = (byte)((d1 << 4) | d2);
|
||||
d1 = -1;
|
||||
d2 = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d1 != -1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (n == t.length) {
|
||||
return t;
|
||||
}
|
||||
byte[] b = new byte[n];
|
||||
System.arraycopy(t, 0, b, 0, n);
|
||||
return b;
|
||||
}
|
||||
|
||||
private final static SecretKey KEY1 =
|
||||
new SecretKeySpec(toByteArray("636869636b656e207465726979616b69"),
|
||||
"AES");
|
||||
|
||||
private final static IvParameterSpec IV1 =
|
||||
new IvParameterSpec(new byte[16]);
|
||||
|
||||
/*
|
||||
* Use test vectors, i.e. PLAIN1 and CIPHER1, from the appendix B
|
||||
* of RFC 3962 "Advanced Encryption Standard (AES) Encryption for
|
||||
* Kerberos 5".
|
||||
*/
|
||||
private final static byte[][] PLAIN1 = {
|
||||
toByteArray("4920776f756c64206c696b652074686520"),
|
||||
toByteArray("4920776f756c64206c696b6520746865" +
|
||||
"2047656e6572616c20476175277320"),
|
||||
toByteArray("4920776f756c64206c696b6520746865" +
|
||||
"2047656e6572616c2047617527732043"),
|
||||
toByteArray("4920776f756c64206c696b6520746865" +
|
||||
"2047656e6572616c2047617527732043" +
|
||||
"6869636b656e2c20706c656173652c"),
|
||||
toByteArray("4920776f756c64206c696b6520746865" +
|
||||
"2047656e6572616c2047617527732043" +
|
||||
"6869636b656e2c20706c656173652c20"),
|
||||
toByteArray("4920776f756c64206c696b6520746865" +
|
||||
"2047656e6572616c2047617527732043" +
|
||||
"6869636b656e2c20706c656173652c20" +
|
||||
"616e6420776f6e746f6e20736f75702e")
|
||||
};
|
||||
private final static byte[][] CIPHER1 = {
|
||||
toByteArray("c6353568f2bf8cb4d8a580362da7ff7f97"),
|
||||
toByteArray("fc00783e0efdb2c1d445d4c8eff7ed22" +
|
||||
"97687268d6ecccc0c07b25e25ecfe5"),
|
||||
toByteArray("39312523a78662d5be7fcbcc98ebf5a8" +
|
||||
"97687268d6ecccc0c07b25e25ecfe584"),
|
||||
toByteArray("97687268d6ecccc0c07b25e25ecfe584" +
|
||||
"b3fffd940c16a18c1b5549d2f838029e" +
|
||||
"39312523a78662d5be7fcbcc98ebf5"),
|
||||
toByteArray("97687268d6ecccc0c07b25e25ecfe584" +
|
||||
"9dad8bbb96c4cdc03bc103e1a194bbd8" +
|
||||
"39312523a78662d5be7fcbcc98ebf5a8"),
|
||||
toByteArray("97687268d6ecccc0c07b25e25ecfe584" +
|
||||
"39312523a78662d5be7fcbcc98ebf5a8" +
|
||||
"4807efe836ee89a526730dbc2f7bc840" +
|
||||
"9dad8bbb96c4cdc03bc103e1a194bbd8"),
|
||||
};
|
||||
|
||||
private final static byte[] IV2_SRC =
|
||||
toByteArray("11223344556677880011223344556677");
|
||||
|
||||
private final static String[] ALGORITHMS2 = {
|
||||
"DES", "DESede", "Blowfish", "AES"
|
||||
};
|
||||
private final static int[] KEYSIZES2 = {
|
||||
8, 24, 16, 16
|
||||
};
|
||||
|
||||
private static String toString(byte[] b) {
|
||||
StringBuffer sb = new StringBuffer(b.length * 3);
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
int k = b[i] & 0xff;
|
||||
if (i != 0) {
|
||||
sb.append(':');
|
||||
}
|
||||
sb.append(Character.forDigit(k >> 4, 16));
|
||||
sb.append(Character.forDigit(k & 0xf, 16));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with the test vectors and see if results match.
|
||||
*/
|
||||
private static void test1() throws Exception {
|
||||
for (int i = 0; i < PLAIN1.length; i++) {
|
||||
String algo = KEY1.getAlgorithm();
|
||||
int MAX_KEYSIZE = Cipher.getMaxAllowedKeyLength(algo);
|
||||
if (KEY1.getEncoded().length > MAX_KEYSIZE) {
|
||||
// skip tests using keys whose length exceeds
|
||||
// what's configured in jce jurisdiction policy files.
|
||||
continue;
|
||||
}
|
||||
System.out.println("Running test1_" + i + " (" + algo + ")");
|
||||
Cipher cipher = Cipher.getInstance(algo+ "/CTS/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
byte[] plainText = PLAIN1[i];
|
||||
byte[] cipherText = CIPHER1[i];
|
||||
cipher.init(Cipher.ENCRYPT_MODE, KEY1, IV1);
|
||||
byte[] enc = cipher.doFinal(plainText);
|
||||
if (Arrays.equals(cipherText, enc) == false) {
|
||||
System.out.println("plain: " + toString(plainText));
|
||||
System.out.println("cipher: " + toString(cipherText));
|
||||
System.out.println("actual: " + toString(enc));
|
||||
throw new RuntimeException("Encryption failure for test " + i);
|
||||
}
|
||||
cipher.init(Cipher.DECRYPT_MODE, KEY1, IV1);
|
||||
byte[] dec = cipher.doFinal(cipherText);
|
||||
if (Arrays.equals(plainText, dec) == false) {
|
||||
System.out.println("cipher: " + toString(cipherText));
|
||||
System.out.println("plain: " + toString(plainText));
|
||||
System.out.println("actual: " + toString(enc));
|
||||
throw new RuntimeException("Decryption failure for test " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with a combination of update/doFinal calls and make
|
||||
* sure that same data is recovered after decryption.
|
||||
*/
|
||||
private static void test2() throws Exception {
|
||||
for (int i = 0; i < ALGORITHMS2.length; i++) {
|
||||
String algo = ALGORITHMS2[i];
|
||||
System.out.println("Running test2_" + i + " (" + algo + ")");
|
||||
int keySize = KEYSIZES2[i];
|
||||
int MAX_KEYSIZE = Cipher.getMaxAllowedKeyLength(algo);
|
||||
if (keySize > MAX_KEYSIZE) {
|
||||
// skip tests using keys whose length exceeds
|
||||
// what's configured in jce jurisdiction policy files.
|
||||
continue;
|
||||
}
|
||||
Cipher cipher =
|
||||
Cipher.getInstance(algo+"/CTS/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
int blockSize = cipher.getBlockSize();
|
||||
SecretKeySpec key = new SecretKeySpec(new byte[keySize], algo);
|
||||
// Make sure encryption works for inputs with valid length
|
||||
byte[] plainText = PLAIN1[3];
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
byte[] cipherText = new byte[plainText.length];
|
||||
int firstPartLen = blockSize + 1;
|
||||
int processed1 = cipher.update(plainText, 0, firstPartLen,
|
||||
cipherText, 0);
|
||||
int processed2 = cipher.doFinal(plainText, firstPartLen,
|
||||
plainText.length-firstPartLen,
|
||||
cipherText, processed1);
|
||||
AlgorithmParameters params = cipher.getParameters();
|
||||
if ((processed1 + processed2) != plainText.length) {
|
||||
System.out.println("processed1 = " + processed1);
|
||||
System.out.println("processed2 = " + processed2);
|
||||
System.out.println("total length = " + plainText.length);
|
||||
throw new RuntimeException("Encryption failure for test " + i);
|
||||
}
|
||||
// Make sure IllegalBlockSizeException is thrown for inputs
|
||||
// with less-than-a-block length
|
||||
try {
|
||||
cipher.doFinal(new byte[blockSize-1]);
|
||||
throw new RuntimeException("Expected IBSE is not thrown");
|
||||
} catch (IllegalBlockSizeException ibse) {
|
||||
}
|
||||
// Make sure data is encrypted as in CBC mode for inputs
|
||||
// which is exactly one block long
|
||||
IvParameterSpec iv2 = new IvParameterSpec(IV2_SRC, 0, blockSize);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, iv2);
|
||||
Cipher cipher2 =
|
||||
Cipher.getInstance(algo+"/CBC/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
cipher2.init(Cipher.ENCRYPT_MODE, key, iv2);
|
||||
|
||||
byte[] eout = cipher.doFinal(IV2_SRC, 0, blockSize);
|
||||
byte[] eout2 = cipher2.doFinal(IV2_SRC, 0, blockSize);
|
||||
if (!Arrays.equals(eout, eout2)) {
|
||||
throw new RuntimeException("Different encryption output " +
|
||||
"for CBC and CTS");
|
||||
}
|
||||
// Make sure decryption works for inputs with valid length
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, params);
|
||||
byte[] recoveredText =
|
||||
new byte[cipher.getOutputSize(cipherText.length)];
|
||||
processed1 = cipher.update(cipherText, 0, firstPartLen,
|
||||
recoveredText, 0);
|
||||
processed2 = cipher.update(cipherText, firstPartLen,
|
||||
cipherText.length-firstPartLen,
|
||||
recoveredText, processed1);
|
||||
int processed3 =
|
||||
cipher.doFinal(recoveredText, processed1+processed2);
|
||||
if ((processed1 + processed2 + processed3) != plainText.length) {
|
||||
System.out.println("processed1 = " + processed1);
|
||||
System.out.println("processed2 = " + processed2);
|
||||
System.out.println("processed3 = " + processed3);
|
||||
System.out.println("total length = " + plainText.length);
|
||||
throw new RuntimeException("Decryption failure for test " + i);
|
||||
}
|
||||
if (Arrays.equals(plainText, recoveredText) == false) {
|
||||
System.out.println("plain: " + toString(plainText));
|
||||
System.out.println("recovered: " + toString(recoveredText));
|
||||
throw new RuntimeException("Decryption failure for test " + i);
|
||||
}
|
||||
// Make sure IllegalBlockSizeException is thrown for inputs
|
||||
// with less-than-a-block length
|
||||
try {
|
||||
cipher.doFinal(new byte[blockSize-1]);
|
||||
throw new RuntimeException("Expected IBSE is not thrown");
|
||||
} catch (IllegalBlockSizeException ibse) {
|
||||
}
|
||||
// Make sure data is decrypted as in CBC mode for inputs
|
||||
// which is exactly one block long
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, iv2);
|
||||
cipher2.init(Cipher.DECRYPT_MODE, key, iv2);
|
||||
byte[] dout = cipher.doFinal(eout);
|
||||
byte[] dout2 = cipher2.doFinal(eout2);
|
||||
if (!Arrays.equals(dout, dout2)) {
|
||||
throw new RuntimeException("Different decryption output " +
|
||||
"for CBC and CTS");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with a shortBuffer and see if encryption/decryption
|
||||
* still works correctly afterwards.
|
||||
*/
|
||||
private static void test3() throws Exception {
|
||||
// Skip PLAIN1[0, 1, 2] due to their lengths
|
||||
for (int i = 3; i < PLAIN1.length; i++) {
|
||||
String algo = KEY1.getAlgorithm();
|
||||
System.out.println("Running test3_" + i + " (" + algo + ")");
|
||||
int MAX_KEYSIZE = Cipher.getMaxAllowedKeyLength(algo);
|
||||
if (KEY1.getEncoded().length > MAX_KEYSIZE) {
|
||||
// skip tests using keys whose length exceeds
|
||||
// what's configured in jce jurisdiction policy files.
|
||||
continue;
|
||||
}
|
||||
Cipher cipher =
|
||||
Cipher.getInstance(algo+ "/CTS/NoPadding",
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
byte[] plainText = PLAIN1[i];
|
||||
byte[] cipherText = CIPHER1[i];
|
||||
byte[] enc = new byte[plainText.length];
|
||||
cipher.init(Cipher.ENCRYPT_MODE, KEY1, IV1);
|
||||
int halfInput = plainText.length/2;
|
||||
int processed1 = cipher.update(plainText, 0, halfInput,
|
||||
enc, 0);
|
||||
try {
|
||||
cipher.doFinal(plainText, halfInput,
|
||||
plainText.length-halfInput,
|
||||
new byte[1], 0);
|
||||
throw new RuntimeException("Expected Exception is not thrown");
|
||||
} catch (ShortBufferException sbe) {
|
||||
// expected exception thrown; retry
|
||||
int processed2 =
|
||||
cipher.doFinal(plainText, halfInput,
|
||||
plainText.length-halfInput,
|
||||
enc, processed1);
|
||||
if ((processed1 + processed2) != enc.length) {
|
||||
System.out.println("processed1 = " + processed1);
|
||||
System.out.println("processed2 = " + processed2);
|
||||
System.out.println("total length = " + enc.length);
|
||||
throw new RuntimeException("Encryption length check " +
|
||||
"failed");
|
||||
}
|
||||
}
|
||||
if (Arrays.equals(cipherText, enc) == false) {
|
||||
System.out.println("plain: " + toString(plainText));
|
||||
System.out.println("cipher: " + toString(cipherText));
|
||||
System.out.println("actual: " + toString(enc));
|
||||
throw new RuntimeException("Encryption failure for test " + i);
|
||||
}
|
||||
cipher.init(Cipher.DECRYPT_MODE, KEY1, IV1);
|
||||
byte[] dec =
|
||||
new byte[cipher.getOutputSize(cipherText.length)];
|
||||
processed1 = cipher.update(cipherText, 0, halfInput,
|
||||
dec, 0);
|
||||
try {
|
||||
cipher.update(cipherText, halfInput,
|
||||
cipherText.length-halfInput,
|
||||
new byte[1], 0);
|
||||
throw new RuntimeException("Expected Exception is not thrown");
|
||||
} catch (ShortBufferException sbe) {
|
||||
// expected exception thrown; retry
|
||||
int processed2 = cipher.update(cipherText, halfInput,
|
||||
cipherText.length-halfInput,
|
||||
dec, processed1);
|
||||
int processed3 =
|
||||
cipher.doFinal(dec, processed1+processed2);
|
||||
if ((processed1 + processed2 + processed3) != dec.length) {
|
||||
System.out.println("processed1 = " + processed1);
|
||||
System.out.println("processed2 = " + processed2);
|
||||
System.out.println("processed3 = " + processed3);
|
||||
System.out.println("total length = " + dec.length);
|
||||
throw new RuntimeException("Decryption length check " +
|
||||
"failed");
|
||||
}
|
||||
}
|
||||
if (Arrays.equals(plainText, dec) == false) {
|
||||
System.out.println("cipher: " + toString(cipherText));
|
||||
System.out.println("plain: " + toString(plainText));
|
||||
System.out.println("actualD: " + toString(dec));
|
||||
throw new RuntimeException("Decryption failure for test " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,495 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2021, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8153029
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.Convert
|
||||
* @run main ChaCha20KAT
|
||||
* @summary ChaCha20 Cipher Implementation (KAT)
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.ChaCha20ParameterSpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.crypto.AEADBadTagException;
|
||||
import java.nio.ByteBuffer;
|
||||
import jdk.test.lib.Convert;
|
||||
|
||||
public class ChaCha20KAT {
|
||||
public static class TestData {
|
||||
public TestData(String name, String keyStr, String nonceStr, int ctr,
|
||||
int dir, String inputStr, String aadStr, String outStr) {
|
||||
testName = Objects.requireNonNull(name);
|
||||
HexFormat hex = HexFormat.of();
|
||||
key = hex.parseHex(Objects.requireNonNull(keyStr));
|
||||
nonce = hex.parseHex(Objects.requireNonNull(nonceStr));
|
||||
if ((counter = ctr) < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"counter must be 0 or greater");
|
||||
}
|
||||
direction = dir;
|
||||
if ((direction != Cipher.ENCRYPT_MODE) &&
|
||||
(direction != Cipher.DECRYPT_MODE)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Direction must be ENCRYPT_MODE or DECRYPT_MODE");
|
||||
}
|
||||
input = hex.parseHex(Objects.requireNonNull(inputStr));
|
||||
aad = (aadStr != null) ? hex.parseHex(aadStr) : null;
|
||||
expOutput = hex.parseHex(Objects.requireNonNull(outStr));
|
||||
}
|
||||
|
||||
public final String testName;
|
||||
public final byte[] key;
|
||||
public final byte[] nonce;
|
||||
public final int counter;
|
||||
public final int direction;
|
||||
public final byte[] input;
|
||||
public final byte[] aad;
|
||||
public final byte[] expOutput;
|
||||
}
|
||||
|
||||
public static final List<TestData> testList = new LinkedList<TestData>() {{
|
||||
add(new TestData("RFC 7539 Sample Test Vector",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
|
||||
"000000000000004a00000000",
|
||||
1, Cipher.ENCRYPT_MODE,
|
||||
"4c616469657320616e642047656e746c656d656e206f662074686520636c6173" +
|
||||
"73206f66202739393a204966204920636f756c64206f6666657220796f75206f" +
|
||||
"6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" +
|
||||
"637265656e20776f756c642062652069742e",
|
||||
null,
|
||||
"6e2e359a2568f98041ba0728dd0d6981e97e7aec1d4360c20a27afccfd9fae0b" +
|
||||
"f91b65c5524733ab8f593dabcd62b3571639d624e65152ab8f530c359f0861d8" +
|
||||
"07ca0dbf500d6a6156a38e088a22b65e52bc514d16ccf806818ce91ab7793736" +
|
||||
"5af90bbf74a35be6b40b8eedf2785e42874d"));
|
||||
add(new TestData("RFC 7539 Test Vector 1 (all zeroes)",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"000000000000000000000000",
|
||||
0, Cipher.ENCRYPT_MODE,
|
||||
"0000000000000000000000000000000000000000000000000000000000000000" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
null,
|
||||
"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7" +
|
||||
"da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586"));
|
||||
add(new TestData("RFC 7539 Test Vector 2",
|
||||
"0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"000000000000000000000002",
|
||||
1, Cipher.ENCRYPT_MODE,
|
||||
"416e79207375626d697373696f6e20746f20746865204945544620696e74656e" +
|
||||
"6465642062792074686520436f6e7472696275746f7220666f72207075626c69" +
|
||||
"636174696f6e20617320616c6c206f722070617274206f6620616e2049455446" +
|
||||
"20496e7465726e65742d4472616674206f722052464320616e6420616e792073" +
|
||||
"746174656d656e74206d6164652077697468696e2074686520636f6e74657874" +
|
||||
"206f6620616e204945544620616374697669747920697320636f6e7369646572" +
|
||||
"656420616e20224945544620436f6e747269627574696f6e222e205375636820" +
|
||||
"73746174656d656e747320696e636c756465206f72616c2073746174656d656e" +
|
||||
"747320696e20494554462073657373696f6e732c2061732077656c6c20617320" +
|
||||
"7772697474656e20616e6420656c656374726f6e696320636f6d6d756e696361" +
|
||||
"74696f6e73206d61646520617420616e792074696d65206f7220706c6163652c" +
|
||||
"207768696368206172652061646472657373656420746f",
|
||||
null,
|
||||
"a3fbf07df3fa2fde4f376ca23e82737041605d9f4f4f57bd8cff2c1d4b7955ec" +
|
||||
"2a97948bd3722915c8f3d337f7d370050e9e96d647b7c39f56e031ca5eb6250d" +
|
||||
"4042e02785ececfa4b4bb5e8ead0440e20b6e8db09d881a7c6132f420e527950" +
|
||||
"42bdfa7773d8a9051447b3291ce1411c680465552aa6c405b7764d5e87bea85a" +
|
||||
"d00f8449ed8f72d0d662ab052691ca66424bc86d2df80ea41f43abf937d3259d" +
|
||||
"c4b2d0dfb48a6c9139ddd7f76966e928e635553ba76c5c879d7b35d49eb2e62b" +
|
||||
"0871cdac638939e25e8a1e0ef9d5280fa8ca328b351c3c765989cbcf3daa8b6c" +
|
||||
"cc3aaf9f3979c92b3720fc88dc95ed84a1be059c6499b9fda236e7e818b04b0b" +
|
||||
"c39c1e876b193bfe5569753f88128cc08aaa9b63d1a16f80ef2554d7189c411f" +
|
||||
"5869ca52c5b83fa36ff216b9c1d30062bebcfd2dc5bce0911934fda79a86f6e6" +
|
||||
"98ced759c3ff9b6477338f3da4f9cd8514ea9982ccafb341b2384dd902f3d1ab" +
|
||||
"7ac61dd29c6f21ba5b862f3730e37cfdc4fd806c22f221"));
|
||||
add(new TestData("RFC 7539 Test Vector 3",
|
||||
"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0",
|
||||
"000000000000000000000002",
|
||||
42, Cipher.ENCRYPT_MODE,
|
||||
"2754776173206272696c6c69672c20616e642074686520736c6974687920746f" +
|
||||
"7665730a446964206779726520616e642067696d626c6520696e207468652077" +
|
||||
"6162653a0a416c6c206d696d737920776572652074686520626f726f676f7665" +
|
||||
"732c0a416e6420746865206d6f6d65207261746873206f757467726162652e",
|
||||
null,
|
||||
"62e6347f95ed87a45ffae7426f27a1df5fb69110044c0d73118effa95b01e5cf" +
|
||||
"166d3df2d721caf9b21e5fb14c616871fd84c54f9d65b283196c7fe4f60553eb" +
|
||||
"f39c6402c42234e32a356b3e764312a61a5532055716ead6962568f87d3f3f77" +
|
||||
"04c6a8d1bcd1bf4d50d6154b6da731b187b58dfd728afa36757a797ac188d1"));
|
||||
}};
|
||||
|
||||
public static final List<TestData> aeadTestList =
|
||||
new LinkedList<TestData>() {{
|
||||
add(new TestData("RFC 7539 Sample AEAD Test Vector",
|
||||
"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
|
||||
"070000004041424344454647",
|
||||
1, Cipher.ENCRYPT_MODE,
|
||||
"4c616469657320616e642047656e746c656d656e206f662074686520636c6173" +
|
||||
"73206f66202739393a204966204920636f756c64206f6666657220796f75206f" +
|
||||
"6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" +
|
||||
"637265656e20776f756c642062652069742e",
|
||||
"50515253c0c1c2c3c4c5c6c7",
|
||||
"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d6" +
|
||||
"3dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b36" +
|
||||
"92ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc" +
|
||||
"3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd060" +
|
||||
"0691"));
|
||||
add(new TestData("RFC 7539 A.5 Sample Decryption",
|
||||
"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0",
|
||||
"000000000102030405060708",
|
||||
1, Cipher.DECRYPT_MODE,
|
||||
"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb2" +
|
||||
"4c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf" +
|
||||
"332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c855" +
|
||||
"9797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4" +
|
||||
"b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523e" +
|
||||
"af4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a" +
|
||||
"0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a10" +
|
||||
"49e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29" +
|
||||
"a6ad5cb4022b02709beead9d67890cbb22392336fea1851f38",
|
||||
"f33388860000000000004e91",
|
||||
"496e7465726e65742d4472616674732061726520647261667420646f63756d65" +
|
||||
"6e74732076616c696420666f722061206d6178696d756d206f6620736978206d" +
|
||||
"6f6e74687320616e64206d617920626520757064617465642c207265706c6163" +
|
||||
"65642c206f72206f62736f6c65746564206279206f7468657220646f63756d65" +
|
||||
"6e747320617420616e792074696d652e20497420697320696e617070726f7072" +
|
||||
"6961746520746f2075736520496e7465726e65742d4472616674732061732072" +
|
||||
"65666572656e6365206d6174657269616c206f7220746f206369746520746865" +
|
||||
"6d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67" +
|
||||
"726573732e2fe2809d"));
|
||||
}};
|
||||
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
int testsPassed = 0;
|
||||
int testNumber = 0;
|
||||
|
||||
System.out.println("----- Single-part (byte[]) Tests -----");
|
||||
for (TestData test : testList) {
|
||||
System.out.println("*** Test " + ++testNumber + ": " +
|
||||
test.testName);
|
||||
if (runSinglePartTest(test)) {
|
||||
testsPassed++;
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
System.out.println("----- Single-part (ByteBuffer) Tests -----");
|
||||
for (TestData test : testList) {
|
||||
System.out.println("*** Test " + ++testNumber + ": " +
|
||||
test.testName);
|
||||
if (runByteBuffer(test)) {
|
||||
testsPassed++;
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
System.out.println("----- Multi-part Tests -----");
|
||||
for (TestData test : testList) {
|
||||
System.out.println("*** Test " + ++testNumber + ": " +
|
||||
test.testName);
|
||||
if (runMultiPartTest(test)) {
|
||||
testsPassed++;
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
System.out.println("----- AEAD Tests -----");
|
||||
for (TestData test : aeadTestList) {
|
||||
System.out.println("*** Test " + ++testNumber + ": " +
|
||||
test.testName);
|
||||
if (runAEADTest(test)) {
|
||||
testsPassed++;
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
System.out.println("Total tests: " + testNumber +
|
||||
", Passed: " + testsPassed + ", Failed: " +
|
||||
(testNumber - testsPassed));
|
||||
if (testsPassed != testNumber) {
|
||||
throw new RuntimeException("One or more tests failed. " +
|
||||
"Check output for details");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean runSinglePartTest(TestData testData)
|
||||
throws GeneralSecurityException {
|
||||
boolean encRes = false;
|
||||
boolean decRes = false;
|
||||
byte[] encryptedResult;
|
||||
byte[] decryptedResult;
|
||||
|
||||
// Get a Cipher instance and set up the parameters
|
||||
Cipher mambo = Cipher.getInstance("ChaCha20");
|
||||
SecretKeySpec mamboKey = new SecretKeySpec(testData.key, "ChaCha20");
|
||||
ChaCha20ParameterSpec mamboSpec = new ChaCha20ParameterSpec(
|
||||
testData.nonce, testData.counter);
|
||||
|
||||
// Encrypt our input
|
||||
mambo.init(Cipher.ENCRYPT_MODE, mamboKey, mamboSpec);
|
||||
encryptedResult = mambo.doFinal(testData.input);
|
||||
|
||||
if (!Arrays.equals(encryptedResult, testData.expOutput)) {
|
||||
System.out.println("ERROR - Output Mismatch!");
|
||||
System.out.println("Expected:\n" +
|
||||
dumpHexBytes(testData.expOutput, 16, "\n", " "));
|
||||
System.out.println("Actual:\n" +
|
||||
dumpHexBytes(encryptedResult, 16, "\n", " "));
|
||||
System.out.println();
|
||||
} else {
|
||||
encRes = true;
|
||||
}
|
||||
|
||||
// Decrypt the result of the encryption operation
|
||||
mambo = Cipher.getInstance("ChaCha20");
|
||||
mambo.init(Cipher.DECRYPT_MODE, mamboKey, mamboSpec);
|
||||
decryptedResult = mambo.doFinal(encryptedResult);
|
||||
|
||||
if (!Arrays.equals(decryptedResult, testData.input)) {
|
||||
System.out.println("ERROR - Output Mismatch!");
|
||||
System.out.println("Expected:\n" +
|
||||
dumpHexBytes(testData.input, 16, "\n", " "));
|
||||
System.out.println("Actual:\n" +
|
||||
dumpHexBytes(decryptedResult, 16, "\n", " "));
|
||||
System.out.println();
|
||||
} else {
|
||||
decRes = true;
|
||||
}
|
||||
|
||||
return (encRes && decRes);
|
||||
}
|
||||
|
||||
private static boolean runMultiPartTest(TestData testData)
|
||||
throws GeneralSecurityException {
|
||||
boolean encRes = false;
|
||||
boolean decRes = false;
|
||||
|
||||
// Get a cipher instance and initialize it
|
||||
Cipher mambo = Cipher.getInstance("ChaCha20");
|
||||
SecretKeySpec mamboKey = new SecretKeySpec(testData.key, "ChaCha20");
|
||||
ChaCha20ParameterSpec mamboSpec = new ChaCha20ParameterSpec(
|
||||
testData.nonce, testData.counter);
|
||||
|
||||
byte[] encryptedResult = new byte[testData.input.length];
|
||||
mambo.init(Cipher.ENCRYPT_MODE, mamboKey, mamboSpec);
|
||||
System.out.print("Encrypt - ");
|
||||
doMulti(mambo, testData.input, encryptedResult);
|
||||
|
||||
if (!Arrays.equals(encryptedResult, testData.expOutput)) {
|
||||
System.out.println("ERROR - Output Mismatch!");
|
||||
System.out.println("Expected:\n" +
|
||||
dumpHexBytes(testData.expOutput, 16, "\n", " "));
|
||||
System.out.println("Actual:\n" +
|
||||
dumpHexBytes(encryptedResult, 16, "\n", " "));
|
||||
System.out.println();
|
||||
} else {
|
||||
encRes = true;
|
||||
}
|
||||
|
||||
// Decrypt the result of the encryption operation
|
||||
mambo = Cipher.getInstance("ChaCha20");
|
||||
byte[] decryptedResult = new byte[encryptedResult.length];
|
||||
mambo.init(Cipher.DECRYPT_MODE, mamboKey, mamboSpec);
|
||||
System.out.print("Decrypt - ");
|
||||
doMulti(mambo, encryptedResult, decryptedResult);
|
||||
|
||||
if (!Arrays.equals(decryptedResult, testData.input)) {
|
||||
System.out.println("ERROR - Output Mismatch!");
|
||||
System.out.println("Expected:\n" +
|
||||
dumpHexBytes(testData.input, 16, "\n", " "));
|
||||
System.out.println("Actual:\n" +
|
||||
dumpHexBytes(decryptedResult, 16, "\n", " "));
|
||||
System.out.println();
|
||||
} else {
|
||||
decRes = true;
|
||||
}
|
||||
|
||||
return (encRes && decRes);
|
||||
}
|
||||
|
||||
private static void doMulti(Cipher c, byte[] input, byte[] output)
|
||||
throws GeneralSecurityException {
|
||||
int offset = 0;
|
||||
boolean done = false;
|
||||
Random randIn = new Random(System.currentTimeMillis());
|
||||
|
||||
// Send small updates between 1 - 8 bytes in length until we get
|
||||
// 8 or less bytes from the end of the input, then finalize.
|
||||
System.out.println("Input length: " + input.length);
|
||||
System.out.print("Multipart (bytes in/out): ");
|
||||
while (!done) {
|
||||
int mPartLen = randIn.nextInt(8) + 1;
|
||||
int bytesLeft = input.length - offset;
|
||||
int processed;
|
||||
if (mPartLen < bytesLeft) {
|
||||
System.out.print(mPartLen + "/");
|
||||
processed = c.update(input, offset, mPartLen,
|
||||
output, offset);
|
||||
offset += processed;
|
||||
System.out.print(processed + " ");
|
||||
} else {
|
||||
processed = c.doFinal(input, offset, bytesLeft,
|
||||
output, offset);
|
||||
System.out.print(bytesLeft + "/" + processed + " ");
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private static boolean runByteBuffer(TestData testData)
|
||||
throws GeneralSecurityException {
|
||||
boolean encRes = false;
|
||||
boolean decRes = false;
|
||||
|
||||
// Get a cipher instance and initialize it
|
||||
Cipher mambo = Cipher.getInstance("ChaCha20");
|
||||
SecretKeySpec mamboKey = new SecretKeySpec(testData.key, "ChaCha20");
|
||||
ChaCha20ParameterSpec mamboSpec = new ChaCha20ParameterSpec(
|
||||
testData.nonce, testData.counter);
|
||||
mambo.init(Cipher.ENCRYPT_MODE, mamboKey, mamboSpec);
|
||||
|
||||
ByteBuffer bbIn = ByteBuffer.wrap(testData.input);
|
||||
ByteBuffer bbEncOut = ByteBuffer.allocate(
|
||||
mambo.getOutputSize(testData.input.length));
|
||||
ByteBuffer bbExpOut = ByteBuffer.wrap(testData.expOutput);
|
||||
|
||||
mambo.doFinal(bbIn, bbEncOut);
|
||||
bbIn.rewind();
|
||||
bbEncOut.rewind();
|
||||
|
||||
if (bbEncOut.compareTo(bbExpOut) != 0) {
|
||||
System.out.println("ERROR - Output Mismatch!");
|
||||
System.out.println("Expected:\n" +
|
||||
dumpHexBytes(bbExpOut, 16, "\n", " "));
|
||||
System.out.println("Actual:\n" +
|
||||
dumpHexBytes(bbEncOut, 16, "\n", " "));
|
||||
System.out.println();
|
||||
} else {
|
||||
encRes = true;
|
||||
}
|
||||
|
||||
// Decrypt the result of the encryption operation
|
||||
mambo = Cipher.getInstance("ChaCha20");
|
||||
mambo.init(Cipher.DECRYPT_MODE, mamboKey, mamboSpec);
|
||||
System.out.print("Decrypt - ");
|
||||
ByteBuffer bbDecOut = ByteBuffer.allocate(
|
||||
mambo.getOutputSize(bbEncOut.remaining()));
|
||||
|
||||
mambo.doFinal(bbEncOut, bbDecOut);
|
||||
bbEncOut.rewind();
|
||||
bbDecOut.rewind();
|
||||
|
||||
if (bbDecOut.compareTo(bbIn) != 0) {
|
||||
System.out.println("ERROR - Output Mismatch!");
|
||||
System.out.println("Expected:\n" +
|
||||
dumpHexBytes(bbIn, 16, "\n", " "));
|
||||
System.out.println("Actual:\n" +
|
||||
dumpHexBytes(bbDecOut, 16, "\n", " "));
|
||||
System.out.println();
|
||||
} else {
|
||||
decRes = true;
|
||||
}
|
||||
|
||||
return (encRes && decRes);
|
||||
}
|
||||
|
||||
private static boolean runAEADTest(TestData testData)
|
||||
throws GeneralSecurityException {
|
||||
boolean result = false;
|
||||
|
||||
Cipher mambo = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
SecretKeySpec mamboKey = new SecretKeySpec(testData.key, "ChaCha20");
|
||||
IvParameterSpec mamboSpec = new IvParameterSpec(testData.nonce);
|
||||
|
||||
mambo.init(testData.direction, mamboKey, mamboSpec);
|
||||
|
||||
byte[] out = new byte[mambo.getOutputSize(testData.input.length)];
|
||||
int outOff = 0;
|
||||
try {
|
||||
mambo.updateAAD(testData.aad);
|
||||
outOff += mambo.update(testData.input, 0, testData.input.length,
|
||||
out, outOff);
|
||||
outOff += mambo.doFinal(out, outOff);
|
||||
} catch (AEADBadTagException abte) {
|
||||
// If we get a bad tag or derive a tag mismatch, log it
|
||||
// and register it as a failure
|
||||
System.out.println("FAIL: " + abte);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Arrays.equals(out, testData.expOutput)) {
|
||||
System.out.println("ERROR - Output Mismatch!");
|
||||
System.out.println("Expected:\n" +
|
||||
dumpHexBytes(testData.expOutput, 16, "\n", " "));
|
||||
System.out.println("Actual:\n" +
|
||||
dumpHexBytes(out, 16, "\n", " "));
|
||||
System.out.println();
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the hex bytes of a buffer into string form.
|
||||
*
|
||||
* @param data The array of bytes to dump to stdout.
|
||||
* @param itemsPerLine The number of bytes to display per line
|
||||
* if the {@code lineDelim} character is blank then all bytes
|
||||
* will be printed on a single line.
|
||||
* @param lineDelim The delimiter between lines
|
||||
* @param itemDelim The delimiter between bytes
|
||||
*
|
||||
* @return The hexdump of the byte array
|
||||
*/
|
||||
private static String dumpHexBytes(byte[] data, int itemsPerLine,
|
||||
String lineDelim, String itemDelim) {
|
||||
return dumpHexBytes(ByteBuffer.wrap(data), itemsPerLine, lineDelim,
|
||||
itemDelim);
|
||||
}
|
||||
|
||||
private static String dumpHexBytes(ByteBuffer data, int itemsPerLine,
|
||||
String lineDelim, String itemDelim) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (data != null) {
|
||||
data.mark();
|
||||
int i = 0;
|
||||
while (data.remaining() > 0) {
|
||||
if (i % itemsPerLine == 0 && i != 0) {
|
||||
sb.append(lineDelim);
|
||||
}
|
||||
sb.append(String.format("%02X", data.get())).append(itemDelim);
|
||||
i++;
|
||||
}
|
||||
data.reset();
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2021, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8153029
|
||||
* @summary ChaCha20 key generator test.
|
||||
* @library /test/lib
|
||||
*/
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.HexFormat;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.ChaCha20ParameterSpec;
|
||||
|
||||
public class ChaCha20KeyGeneratorTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
KeyGenerator generator = KeyGenerator.getInstance("ChaCha20");
|
||||
|
||||
try {
|
||||
generator.init(new ChaCha20ParameterSpec(
|
||||
HexFormat.of().parseHex("100000000000000000000000"), 0));
|
||||
throw new RuntimeException(
|
||||
"ChaCha20 key generation should not consume AlgorithmParameterSpec");
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
System.out.println("Expected InvalidAlgorithmParameterException: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
|
||||
for (int keySize : new int[] { 32, 64, 128, 512, 1024 }) {
|
||||
try {
|
||||
generator.init(keySize);
|
||||
throw new RuntimeException("The key size for ChaCha20 must be 256");
|
||||
} catch (InvalidParameterException e) {
|
||||
System.out.println(
|
||||
"Expected InvalidParameterException: " + keySize);
|
||||
}
|
||||
}
|
||||
|
||||
generator.init(256);
|
||||
SecretKey key = generator.generateKey();
|
||||
byte[] keyValue = key.getEncoded();
|
||||
System.out.println("Key: " + HexFormat.of().formatHex(keyValue));
|
||||
if (keyValue.length != 32) {
|
||||
throw new RuntimeException("The size of generated key must be 256");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,614 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2023, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8153029 8305091
|
||||
* @library /test/lib
|
||||
* @run main ChaCha20NoReuse
|
||||
* @summary ChaCha20 Cipher Implementation (key/nonce reuse protection)
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import javax.crypto.Cipher;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import javax.crypto.spec.ChaCha20ParameterSpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.crypto.AEADBadTagException;
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
public class ChaCha20NoReuse {
|
||||
|
||||
private static final String ALG_CC20 = "ChaCha20";
|
||||
private static final String ALG_CC20_P1305 = "ChaCha20-Poly1305";
|
||||
|
||||
/**
|
||||
* Basic TestMethod interface definition.
|
||||
*/
|
||||
public interface TestMethod {
|
||||
/**
|
||||
* Runs the actual test case
|
||||
*
|
||||
* @param algorithm the algorithm to use (e.g. ChaCha20, etc.)
|
||||
*
|
||||
* @return true if the test passes, false otherwise.
|
||||
*/
|
||||
boolean run(String algorithm);
|
||||
|
||||
/**
|
||||
* Check if this TestMethod can be run for this algorithm. Some tests
|
||||
* are specific to ChaCha20 or ChaCha20-Poly1305, so this method
|
||||
* can be used to determine if a given Cipher type is appropriate.
|
||||
*
|
||||
* @param algorithm the algorithm to use.
|
||||
*
|
||||
* @return true if this test can be run on this algorithm,
|
||||
* false otherwise.
|
||||
*/
|
||||
boolean isValid(String algorithm);
|
||||
}
|
||||
|
||||
public static class TestData {
|
||||
public TestData(String name, String keyStr, String nonceStr, int ctr,
|
||||
int dir, String inputStr, String aadStr, String outStr) {
|
||||
testName = Objects.requireNonNull(name);
|
||||
HexFormat hex = HexFormat.of();
|
||||
key = hex.parseHex(keyStr);
|
||||
nonce = hex.parseHex(nonceStr);
|
||||
if ((counter = ctr) < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"counter must be 0 or greater");
|
||||
}
|
||||
direction = dir;
|
||||
if ((direction != Cipher.ENCRYPT_MODE) &&
|
||||
(direction != Cipher.DECRYPT_MODE)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Direction must be ENCRYPT_MODE or DECRYPT_MODE");
|
||||
}
|
||||
input = hex.parseHex(inputStr);
|
||||
aad = (aadStr != null) ? hex.parseHex(aadStr) : null;
|
||||
expOutput = hex.parseHex(outStr);
|
||||
}
|
||||
|
||||
public final String testName;
|
||||
public final byte[] key;
|
||||
public final byte[] nonce;
|
||||
public final int counter;
|
||||
public final int direction;
|
||||
public final byte[] input;
|
||||
public final byte[] aad;
|
||||
public final byte[] expOutput;
|
||||
}
|
||||
|
||||
public static final List<TestData> testList = new LinkedList<TestData>() {{
|
||||
add(new TestData("RFC 7539 Sample Test Vector [ENCRYPT]",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
|
||||
"000000000000004a00000000",
|
||||
1, Cipher.ENCRYPT_MODE,
|
||||
"4c616469657320616e642047656e746c656d656e206f662074686520636c6173" +
|
||||
"73206f66202739393a204966204920636f756c64206f6666657220796f75206f" +
|
||||
"6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" +
|
||||
"637265656e20776f756c642062652069742e",
|
||||
null,
|
||||
"6e2e359a2568f98041ba0728dd0d6981e97e7aec1d4360c20a27afccfd9fae0b" +
|
||||
"f91b65c5524733ab8f593dabcd62b3571639d624e65152ab8f530c359f0861d8" +
|
||||
"07ca0dbf500d6a6156a38e088a22b65e52bc514d16ccf806818ce91ab7793736" +
|
||||
"5af90bbf74a35be6b40b8eedf2785e42874d"));
|
||||
add(new TestData("RFC 7539 Sample Test Vector [DECRYPT]",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
|
||||
"000000000000004a00000000",
|
||||
1, Cipher.DECRYPT_MODE,
|
||||
"6e2e359a2568f98041ba0728dd0d6981e97e7aec1d4360c20a27afccfd9fae0b" +
|
||||
"f91b65c5524733ab8f593dabcd62b3571639d624e65152ab8f530c359f0861d8" +
|
||||
"07ca0dbf500d6a6156a38e088a22b65e52bc514d16ccf806818ce91ab7793736" +
|
||||
"5af90bbf74a35be6b40b8eedf2785e42874d",
|
||||
null,
|
||||
"4c616469657320616e642047656e746c656d656e206f662074686520636c6173" +
|
||||
"73206f66202739393a204966204920636f756c64206f6666657220796f75206f" +
|
||||
"6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" +
|
||||
"637265656e20776f756c642062652069742e"));
|
||||
}};
|
||||
|
||||
public static final List<TestData> aeadTestList =
|
||||
new LinkedList<TestData>() {{
|
||||
add(new TestData("RFC 7539 Sample AEAD Test Vector",
|
||||
"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
|
||||
"070000004041424344454647",
|
||||
1, Cipher.ENCRYPT_MODE,
|
||||
"4c616469657320616e642047656e746c656d656e206f662074686520636c6173" +
|
||||
"73206f66202739393a204966204920636f756c64206f6666657220796f75206f" +
|
||||
"6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" +
|
||||
"637265656e20776f756c642062652069742e",
|
||||
"50515253c0c1c2c3c4c5c6c7",
|
||||
"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d6" +
|
||||
"3dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b36" +
|
||||
"92ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc" +
|
||||
"3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd060" +
|
||||
"0691"));
|
||||
add(new TestData("RFC 7539 A.5 Sample Decryption",
|
||||
"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0",
|
||||
"000000000102030405060708",
|
||||
1, Cipher.DECRYPT_MODE,
|
||||
"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb2" +
|
||||
"4c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf" +
|
||||
"332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c855" +
|
||||
"9797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4" +
|
||||
"b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523e" +
|
||||
"af4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a" +
|
||||
"0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a10" +
|
||||
"49e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29" +
|
||||
"a6ad5cb4022b02709beead9d67890cbb22392336fea1851f38",
|
||||
"f33388860000000000004e91",
|
||||
"496e7465726e65742d4472616674732061726520647261667420646f63756d65" +
|
||||
"6e74732076616c696420666f722061206d6178696d756d206f6620736978206d" +
|
||||
"6f6e74687320616e64206d617920626520757064617465642c207265706c6163" +
|
||||
"65642c206f72206f62736f6c65746564206279206f7468657220646f63756d65" +
|
||||
"6e747320617420616e792074696d652e20497420697320696e617070726f7072" +
|
||||
"6961746520746f2075736520496e7465726e65742d4472616674732061732072" +
|
||||
"65666572656e6365206d6174657269616c206f7220746f206369746520746865" +
|
||||
"6d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67" +
|
||||
"726573732e2fe2809d"));
|
||||
}};
|
||||
|
||||
/**
|
||||
* Make sure we do not use this Cipher object without initializing it
|
||||
* at all
|
||||
*/
|
||||
public static final TestMethod noInitTest = new TestMethod() {
|
||||
@Override
|
||||
public boolean isValid(String algorithm) {
|
||||
return true; // Valid for all algs
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(String algorithm) {
|
||||
System.out.println("----- No Init Test [" + algorithm +
|
||||
"] -----");
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
TestData testData;
|
||||
switch (algorithm) {
|
||||
case ALG_CC20:
|
||||
testData = testList.get(0);
|
||||
break;
|
||||
case ALG_CC20_P1305:
|
||||
testData = aeadTestList.get(0);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported cipher type: " + algorithm);
|
||||
}
|
||||
|
||||
// Attempting to use the cipher without initializing it
|
||||
// should throw an IllegalStateException
|
||||
try {
|
||||
if (algorithm.equals(ALG_CC20_P1305)) {
|
||||
cipher.updateAAD(testData.aad);
|
||||
}
|
||||
cipher.doFinal(testData.input);
|
||||
throw new RuntimeException(
|
||||
"Expected IllegalStateException not thrown");
|
||||
} catch (IllegalStateException ise) {
|
||||
// Do nothing, this is what we expected to happen
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
System.out.println("Unexpected exception: " + exc);
|
||||
exc.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Make sure we don't allow a double init using the same parameters
|
||||
*/
|
||||
public static final TestMethod doubleInitTest = new TestMethod() {
|
||||
@Override
|
||||
public boolean isValid(String algorithm) {
|
||||
return true; // Valid for all algs
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(String algorithm) {
|
||||
System.out.println("----- Double Init Test [" + algorithm +
|
||||
"] -----");
|
||||
try {
|
||||
AlgorithmParameterSpec spec;
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
TestData testData;
|
||||
switch (algorithm) {
|
||||
case ALG_CC20:
|
||||
testData = testList.get(0);
|
||||
spec = new ChaCha20ParameterSpec(testData.nonce,
|
||||
testData.counter);
|
||||
break;
|
||||
case ALG_CC20_P1305:
|
||||
testData = aeadTestList.get(0);
|
||||
spec = new IvParameterSpec(testData.nonce);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported cipher type: " + algorithm);
|
||||
}
|
||||
SecretKey key = new SecretKeySpec(testData.key, ALG_CC20);
|
||||
|
||||
// Initialize the first time, this should work.
|
||||
cipher.init(testData.direction, key, spec);
|
||||
|
||||
// Immediately initializing a second time with the same
|
||||
// parameters should fail
|
||||
try {
|
||||
cipher.init(testData.direction, key, spec);
|
||||
throw new RuntimeException(
|
||||
"Expected InvalidKeyException not thrown");
|
||||
} catch (InvalidKeyException ike) {
|
||||
// Do nothing, this is what we expected to happen
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
System.out.println("Unexpected exception: " + exc);
|
||||
exc.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempt to run two full encryption operations without an init in
|
||||
* between.
|
||||
*/
|
||||
public static final TestMethod encTwiceNoInit = new TestMethod() {
|
||||
@Override
|
||||
public boolean isValid(String algorithm) {
|
||||
return true; // Valid for all algs
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(String algorithm) {
|
||||
System.out.println("----- Encrypt second time without init [" +
|
||||
algorithm + "] -----");
|
||||
try {
|
||||
AlgorithmParameterSpec spec;
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
TestData testData;
|
||||
switch (algorithm) {
|
||||
case ALG_CC20:
|
||||
testData = testList.get(0);
|
||||
spec = new ChaCha20ParameterSpec(testData.nonce,
|
||||
testData.counter);
|
||||
break;
|
||||
case ALG_CC20_P1305:
|
||||
testData = aeadTestList.get(0);
|
||||
spec = new IvParameterSpec(testData.nonce);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported cipher type: " + algorithm);
|
||||
}
|
||||
SecretKey key = new SecretKeySpec(testData.key, ALG_CC20);
|
||||
|
||||
// Initialize and encrypt
|
||||
cipher.init(testData.direction, key, spec);
|
||||
if (algorithm.equals(ALG_CC20_P1305)) {
|
||||
cipher.updateAAD(testData.aad);
|
||||
}
|
||||
cipher.doFinal(testData.input);
|
||||
System.out.println("First encryption complete");
|
||||
|
||||
// Now attempt to encrypt again without changing the key/IV
|
||||
// This should fail.
|
||||
try {
|
||||
if (algorithm.equals(ALG_CC20_P1305)) {
|
||||
cipher.updateAAD(testData.aad);
|
||||
}
|
||||
cipher.doFinal(testData.input);
|
||||
throw new RuntimeException(
|
||||
"Expected IllegalStateException not thrown");
|
||||
} catch (IllegalStateException ise) {
|
||||
// Do nothing, this is what we expected to happen
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
System.out.println("Unexpected exception: " + exc);
|
||||
exc.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempt to run two full decryption operations without an init in
|
||||
* between.
|
||||
*/
|
||||
public static final TestMethod decTwiceNoInit = new TestMethod() {
|
||||
@Override
|
||||
public boolean isValid(String algorithm) {
|
||||
return true; // Valid for all algs
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(String algorithm) {
|
||||
System.out.println("----- Decrypt second time without init [" +
|
||||
algorithm + "] -----");
|
||||
try {
|
||||
AlgorithmParameterSpec spec;
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
TestData testData;
|
||||
switch (algorithm) {
|
||||
case ALG_CC20:
|
||||
testData = testList.get(1);
|
||||
spec = new ChaCha20ParameterSpec(testData.nonce,
|
||||
testData.counter);
|
||||
break;
|
||||
case ALG_CC20_P1305:
|
||||
testData = aeadTestList.get(1);
|
||||
spec = new IvParameterSpec(testData.nonce);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported cipher type: " + algorithm);
|
||||
}
|
||||
SecretKey key = new SecretKeySpec(testData.key, ALG_CC20);
|
||||
|
||||
// Initialize and decrypt
|
||||
cipher.init(testData.direction, key, spec);
|
||||
if (algorithm.equals(ALG_CC20_P1305)) {
|
||||
cipher.updateAAD(testData.aad);
|
||||
}
|
||||
cipher.doFinal(testData.input);
|
||||
System.out.println("First decryption complete");
|
||||
|
||||
// Now attempt to decrypt again without changing the key/IV
|
||||
// We allow this scenario.
|
||||
if (algorithm.equals(ALG_CC20_P1305)) {
|
||||
cipher.updateAAD(testData.aad);
|
||||
}
|
||||
cipher.doFinal(testData.input);
|
||||
} catch (Exception exc) {
|
||||
System.out.println("Unexpected exception: " + exc);
|
||||
exc.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform an AEAD decryption with corrupted data so the tag does not
|
||||
* match. Then use the uncorrupted test vector input and attempt to
|
||||
* reuse the cipher without initialization.
|
||||
*/
|
||||
public static final TestMethod decFailNoInit = new TestMethod() {
|
||||
@Override
|
||||
public boolean isValid(String algorithm) {
|
||||
return algorithm.equals(ALG_CC20_P1305);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(String algorithm) {
|
||||
System.out.println(
|
||||
"----- Fail decryption, try again with no init [" +
|
||||
algorithm + "] -----");
|
||||
try {
|
||||
TestData testData = aeadTestList.get(1);
|
||||
AlgorithmParameterSpec spec =
|
||||
new IvParameterSpec(testData.nonce);
|
||||
byte[] corruptInput = testData.input.clone();
|
||||
corruptInput[0]++; // Corrupt the ciphertext
|
||||
SecretKey key = new SecretKeySpec(testData.key, ALG_CC20);
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
|
||||
try {
|
||||
// Initialize and encrypt
|
||||
cipher.init(testData.direction, key, spec);
|
||||
cipher.updateAAD(testData.aad);
|
||||
cipher.doFinal(corruptInput);
|
||||
throw new RuntimeException(
|
||||
"Expected AEADBadTagException not thrown");
|
||||
} catch (AEADBadTagException abte) {
|
||||
System.out.println("Expected decryption failure occurred");
|
||||
}
|
||||
|
||||
// Even though an exception occurred during decryption, the
|
||||
// Cipher object should be returned to its post-init state.
|
||||
// Since this is a decryption operation, we should allow
|
||||
// key/nonce reuse. It should properly decrypt the uncorrupted
|
||||
// input.
|
||||
cipher.updateAAD(testData.aad);
|
||||
byte[] pText = cipher.doFinal(testData.input);
|
||||
if (!Arrays.equals(pText, testData.expOutput)) {
|
||||
throw new RuntimeException("FAIL: Attempted decryption " +
|
||||
"did not match expected plaintext");
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
System.out.println("Unexpected exception: " + exc);
|
||||
exc.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Encrypt once successfully, then attempt to init with the same
|
||||
* key and nonce.
|
||||
*/
|
||||
public static final TestMethod encTwiceInitSameParams = new TestMethod() {
|
||||
@Override
|
||||
public boolean isValid(String algorithm) {
|
||||
return true; // Valid for all algs
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(String algorithm) {
|
||||
System.out.println("----- Encrypt, then init with same params [" +
|
||||
algorithm + "] -----");
|
||||
try {
|
||||
AlgorithmParameterSpec spec;
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
TestData testData;
|
||||
switch (algorithm) {
|
||||
case ALG_CC20:
|
||||
testData = testList.get(0);
|
||||
spec = new ChaCha20ParameterSpec(testData.nonce,
|
||||
testData.counter);
|
||||
break;
|
||||
case ALG_CC20_P1305:
|
||||
testData = aeadTestList.get(0);
|
||||
spec = new IvParameterSpec(testData.nonce);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported cipher type: " + algorithm);
|
||||
}
|
||||
SecretKey key = new SecretKeySpec(testData.key, ALG_CC20);
|
||||
|
||||
// Initialize then encrypt
|
||||
cipher.init(testData.direction, key, spec);
|
||||
if (algorithm.equals(ALG_CC20_P1305)) {
|
||||
cipher.updateAAD(testData.aad);
|
||||
}
|
||||
cipher.doFinal(testData.input);
|
||||
System.out.println("First encryption complete");
|
||||
|
||||
// Initializing after the completed encryption with
|
||||
// the same key and nonce should fail.
|
||||
try {
|
||||
cipher.init(testData.direction, key, spec);
|
||||
throw new RuntimeException(
|
||||
"Expected InvalidKeyException not thrown");
|
||||
} catch (InvalidKeyException ike) {
|
||||
// Do nothing, this is what we expected to happen
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
System.out.println("Unexpected exception: " + exc);
|
||||
exc.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrypt once successfully, then attempt to init with the same
|
||||
* key and nonce.
|
||||
*/
|
||||
public static final TestMethod decTwiceInitSameParams = new TestMethod() {
|
||||
@Override
|
||||
public boolean isValid(String algorithm) {
|
||||
return true; // Valid for all algs
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run(String algorithm) {
|
||||
System.out.println("----- Decrypt, then init with same params [" +
|
||||
algorithm + "] -----");
|
||||
try {
|
||||
AlgorithmParameterSpec spec;
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
TestData testData;
|
||||
switch (algorithm) {
|
||||
case ALG_CC20:
|
||||
testData = testList.get(1);
|
||||
spec = new ChaCha20ParameterSpec(testData.nonce,
|
||||
testData.counter);
|
||||
break;
|
||||
case ALG_CC20_P1305:
|
||||
testData = aeadTestList.get(1);
|
||||
spec = new IvParameterSpec(testData.nonce);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported cipher type: " + algorithm);
|
||||
}
|
||||
SecretKey key = new SecretKeySpec(testData.key, ALG_CC20);
|
||||
|
||||
// Initialize then decrypt
|
||||
cipher.init(testData.direction, key, spec);
|
||||
if (algorithm.equals(ALG_CC20_P1305)) {
|
||||
cipher.updateAAD(testData.aad);
|
||||
}
|
||||
byte[] pText = cipher.doFinal(testData.input);
|
||||
if (!Arrays.equals(pText, testData.expOutput)) {
|
||||
throw new RuntimeException("FAIL: Attempted decryption " +
|
||||
"did not match expected plaintext");
|
||||
}
|
||||
System.out.println("First decryption complete");
|
||||
|
||||
// Initializing after the completed decryption with
|
||||
// the same key and nonce is allowed.
|
||||
cipher.init(testData.direction, key, spec);
|
||||
System.out.println("Successful reinit in DECRYPT_MODE");
|
||||
} catch (Exception exc) {
|
||||
System.out.println("Unexpected exception: " + exc);
|
||||
exc.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public static final List<String> algList =
|
||||
Arrays.asList(ALG_CC20, ALG_CC20_P1305);
|
||||
|
||||
public static final List<TestMethod> testMethodList =
|
||||
Arrays.asList(noInitTest, doubleInitTest, encTwiceNoInit,
|
||||
decTwiceNoInit, decFailNoInit, encTwiceInitSameParams,
|
||||
decTwiceInitSameParams);
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
int testsPassed = 0;
|
||||
int testNumber = 0;
|
||||
|
||||
for (TestMethod tm : testMethodList) {
|
||||
for (String alg : algList) {
|
||||
if (tm.isValid(alg)) {
|
||||
testNumber++;
|
||||
boolean result = tm.run(alg);
|
||||
System.out.println("Result: " + (result ? "PASS" : "FAIL"));
|
||||
if (result) {
|
||||
testsPassed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Total Tests: " + testNumber +
|
||||
", Tests passed: " + testsPassed);
|
||||
if (testsPassed < testNumber) {
|
||||
throw new RuntimeException(
|
||||
"Not all tests passed. See output for failure info");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,524 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2021, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8153029 8257769
|
||||
* @library /test/lib
|
||||
* @run main ChaCha20Poly1305ParamTest
|
||||
* @summary ChaCha20 Cipher Implementation (parameters)
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.ChaCha20ParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.crypto.AEADBadTagException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import jdk.test.lib.Convert;
|
||||
|
||||
public class ChaCha20Poly1305ParamTest {
|
||||
public static class TestData {
|
||||
public TestData(String name, String keyStr, String nonceStr, int ctr,
|
||||
int dir, String inputStr, String aadStr, String outStr) {
|
||||
testName = Objects.requireNonNull(name);
|
||||
HexFormat hex = HexFormat.of();
|
||||
key = hex.parseHex(keyStr);
|
||||
nonce = hex.parseHex(nonceStr);
|
||||
if ((counter = ctr) < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"counter must be 0 or greater");
|
||||
}
|
||||
direction = dir;
|
||||
if ((direction != Cipher.ENCRYPT_MODE) &&
|
||||
(direction != Cipher.DECRYPT_MODE)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Direction must be ENCRYPT_MODE or DECRYPT_MODE");
|
||||
}
|
||||
input = hex.parseHex(inputStr);
|
||||
aad = (aadStr != null) ? hex.parseHex(aadStr) : null;
|
||||
expOutput = hex.parseHex(outStr);
|
||||
}
|
||||
|
||||
public final String testName;
|
||||
public final byte[] key;
|
||||
public final byte[] nonce;
|
||||
public final int counter;
|
||||
public final int direction;
|
||||
public final byte[] input;
|
||||
public final byte[] aad;
|
||||
public final byte[] expOutput;
|
||||
}
|
||||
|
||||
public static final List<TestData> aeadTestList =
|
||||
new LinkedList<TestData>() {{
|
||||
add(new TestData("RFC 7539 Sample AEAD Test Vector",
|
||||
"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
|
||||
"070000004041424344454647",
|
||||
1, Cipher.ENCRYPT_MODE,
|
||||
"4c616469657320616e642047656e746c656d656e206f662074686520636c6173" +
|
||||
"73206f66202739393a204966204920636f756c64206f6666657220796f75206f" +
|
||||
"6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73" +
|
||||
"637265656e20776f756c642062652069742e",
|
||||
"50515253c0c1c2c3c4c5c6c7",
|
||||
"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d6" +
|
||||
"3dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b36" +
|
||||
"92ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc" +
|
||||
"3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd060" +
|
||||
"0691"));
|
||||
add(new TestData("RFC 7539 A.5 Sample Decryption",
|
||||
"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0",
|
||||
"000000000102030405060708",
|
||||
1, Cipher.DECRYPT_MODE,
|
||||
"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb2" +
|
||||
"4c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf" +
|
||||
"332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c855" +
|
||||
"9797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4" +
|
||||
"b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523e" +
|
||||
"af4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a" +
|
||||
"0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a10" +
|
||||
"49e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29" +
|
||||
"a6ad5cb4022b02709beead9d67890cbb22392336fea1851f38",
|
||||
"f33388860000000000004e91",
|
||||
"496e7465726e65742d4472616674732061726520647261667420646f63756d65" +
|
||||
"6e74732076616c696420666f722061206d6178696d756d206f6620736978206d" +
|
||||
"6f6e74687320616e64206d617920626520757064617465642c207265706c6163" +
|
||||
"65642c206f72206f62736f6c65746564206279206f7468657220646f63756d65" +
|
||||
"6e747320617420616e792074696d652e20497420697320696e617070726f7072" +
|
||||
"6961746520746f2075736520496e7465726e65742d4472616674732061732072" +
|
||||
"65666572656e6365206d6174657269616c206f7220746f206369746520746865" +
|
||||
"6d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67" +
|
||||
"726573732e2fe2809d"));
|
||||
}};
|
||||
|
||||
// 12-byte nonce DER-encoded as an OCTET_STRING
|
||||
public static final byte[] NONCE_OCTET_STR_12 = {
|
||||
4, 12, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8
|
||||
};
|
||||
|
||||
// Invalid 16-byte nonce DER-encoded as an OCTET_STRING
|
||||
public static final byte[] NONCE_OCTET_STR_16 = {
|
||||
4, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
|
||||
// Throwaway key for default init tests
|
||||
public static final SecretKey DEF_KEY = new SecretKeySpec(new byte[]
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
|
||||
}, "ChaCha20");
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
int testsPassed = 0;
|
||||
int testNumber = 0;
|
||||
|
||||
// Try some default initializations
|
||||
testDefaultAlgParams("ChaCha20", Cipher.ENCRYPT_MODE, true);
|
||||
testDefaultAlgParams("ChaCha20-Poly1305", Cipher.ENCRYPT_MODE, true);
|
||||
testDefaultAlgParamSpec("ChaCha20", Cipher.ENCRYPT_MODE, true);
|
||||
testDefaultAlgParamSpec("ChaCha20-Poly1305", Cipher.ENCRYPT_MODE, true);
|
||||
testDefaultAlgParams("ChaCha20", Cipher.DECRYPT_MODE, false);
|
||||
testDefaultAlgParams("ChaCha20-Poly1305", Cipher.DECRYPT_MODE, false);
|
||||
testDefaultAlgParamSpec("ChaCha20", Cipher.DECRYPT_MODE, false);
|
||||
testDefaultAlgParamSpec("ChaCha20-Poly1305", Cipher.DECRYPT_MODE,
|
||||
false);
|
||||
|
||||
// Try (and hopefully fail) to create a ChaCha20 AlgorithmParameterSpec
|
||||
System.out.println(
|
||||
"*** Test: Try to make ChaCha20 AlgorithmParameterSpec");
|
||||
try {
|
||||
ChaCha20ParameterSpec badChaCha20Spec =
|
||||
new ChaCha20ParameterSpec(NONCE_OCTET_STR_16, 1);
|
||||
throw new RuntimeException("ChaCha20 AlgorithmParameterSpec " +
|
||||
"with 16 byte nonce should fail");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
System.out.println("Caught expected exception: " + iae);
|
||||
}
|
||||
|
||||
// Try (and hopefully fail) to create a ChaCha20 AlgorithmParameters
|
||||
System.out.println(
|
||||
"*** Test: Try to make ChaCha20 AlgorithmParameters");
|
||||
try {
|
||||
AlgorithmParameters apsNoChaCha20 =
|
||||
AlgorithmParameters.getInstance("ChaCha20");
|
||||
throw new RuntimeException(
|
||||
"ChaCha20 AlgorithmParameters should fail");
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
System.out.println("Caught expected exception: " + nsae);
|
||||
}
|
||||
|
||||
// Create the AlgorithmParameters object from a valid encoding
|
||||
System.out.println("*** Test: Create and init ChaCha20-Poly1305 APS");
|
||||
AlgorithmParameters apsGood =
|
||||
AlgorithmParameters.getInstance("ChaCha20-Poly1305");
|
||||
apsGood.init(NONCE_OCTET_STR_12);
|
||||
System.out.println("Test Passed");
|
||||
|
||||
// Pull an AlgorithmParameters object out of the initialized cipher
|
||||
// and compare its value against the original.
|
||||
System.out.println("*** Test: Init ChaCha20-Poly1305 Cipher using " +
|
||||
"AP, retrieve AP and compare");
|
||||
Cipher cc20p1305 = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
cc20p1305.init(Cipher.ENCRYPT_MODE, DEF_KEY, apsGood);
|
||||
AlgorithmParameters pulledParams = cc20p1305.getParameters();
|
||||
byte[] apsGoodData = apsGood.getEncoded();
|
||||
byte[] pulledParamsData = pulledParams.getEncoded();
|
||||
if (!Arrays.equals(apsGoodData, pulledParamsData)) {
|
||||
throw new RuntimeException(
|
||||
"Retrieved parameters do not match those used to init cipher");
|
||||
}
|
||||
System.out.println("Test Passed");
|
||||
|
||||
// Try the same test with ChaCha20. It should always be null.
|
||||
System.out.println("*** Test: Init ChaCha20 Cipher using " +
|
||||
"AP, retrieve AP and compare");
|
||||
Cipher cc20 = Cipher.getInstance("ChaCha20");
|
||||
cc20.init(Cipher.ENCRYPT_MODE, DEF_KEY);
|
||||
pulledParams = cc20.getParameters();
|
||||
if (pulledParams != null) {
|
||||
throw new RuntimeException("Unexpected non-null " +
|
||||
"AlgorithmParameters from ChaCha20 cipiher");
|
||||
}
|
||||
System.out.println("Test Passed");
|
||||
|
||||
// Create and try to init using invalid encoding
|
||||
AlgorithmParameters apsBad =
|
||||
AlgorithmParameters.getInstance("ChaCha20-Poly1305");
|
||||
System.out.println("*** Test: Use invalid encoding scheme");
|
||||
try {
|
||||
apsBad.init(NONCE_OCTET_STR_12, "OraclePrivate");
|
||||
throw new RuntimeException("Allowed unsupported encoding scheme: " +
|
||||
apsBad.getAlgorithm());
|
||||
} catch (IOException iae) {
|
||||
System.out.println("Caught expected exception: " + iae);
|
||||
}
|
||||
|
||||
// Try to init using supported scheme but invalid length
|
||||
System.out.println("*** Test: Use supported scheme, nonce too large");
|
||||
try {
|
||||
apsBad.init(NONCE_OCTET_STR_16, "ASN.1");
|
||||
throw new RuntimeException("Allowed invalid encoded length");
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Caught expected exception: " + ioe);
|
||||
}
|
||||
|
||||
// The next set of tests cover cases where ChaCha20-Poly1305 cipher
|
||||
// objects have the getParameters() call executed after instantiation
|
||||
// but before initialization.
|
||||
System.out.println("*** Test: getParameters before init");
|
||||
cc20p1305 = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
AlgorithmParameters algParams = cc20p1305.getParameters();
|
||||
byte[] preInitNonce = getNonceFromParams(algParams);
|
||||
// A second pre-init getParameters() call should return a new set of
|
||||
// random parameters.
|
||||
AlgorithmParameters algParamsTwo = cc20p1305.getParameters();
|
||||
byte[] secondNonce = getNonceFromParams(algParamsTwo);
|
||||
if (MessageDigest.isEqual(preInitNonce, secondNonce)) {
|
||||
throw new RuntimeException("Unexpected nonce match between " +
|
||||
"two pre-init getParameters() calls");
|
||||
}
|
||||
|
||||
// Next we will initialize the Cipher object using a form of init
|
||||
// that doesn't take AlgorithmParameters or AlgorithmParameterSpec.
|
||||
// The nonce created using the pre-init getParameters() call should
|
||||
// be overwritten by a freshly generated set of random parameters.
|
||||
cc20p1305.init(Cipher.ENCRYPT_MODE, DEF_KEY);
|
||||
AlgorithmParameters postInitAps = cc20p1305.getParameters();
|
||||
byte[] postInitNonce = getNonceFromParams(postInitAps);
|
||||
if (MessageDigest.isEqual(preInitNonce, postInitNonce)) {
|
||||
throw new RuntimeException("Unexpected nonce match between " +
|
||||
"pre and post-init getParameters() calls");
|
||||
}
|
||||
System.out.println("Test Passed");
|
||||
|
||||
// After an initialization, subsequent calls to getParameters() should
|
||||
// return the same parameter value until the next initialization takes
|
||||
// place.
|
||||
System.out.println("*** Test: getParameters after init");
|
||||
AlgorithmParameters postInitApsTwo = cc20p1305.getParameters();
|
||||
byte[] postInitNonceTwo = getNonceFromParams(postInitApsTwo);
|
||||
if (!MessageDigest.isEqual(postInitNonce, postInitNonceTwo)) {
|
||||
throw new RuntimeException("Unexpected nonce mismatch between " +
|
||||
"two post-init getParameters() calls");
|
||||
}
|
||||
System.out.println("Test Passed");
|
||||
|
||||
// Test reinitialization use cases.
|
||||
// First test: instantiate, init(no param), encrypt. Get params
|
||||
// and attempt to reinit with same parameters. Should fail.
|
||||
System.out.println("*** Test: Init w/ random nonce, init 2nd time");
|
||||
cc20p1305 = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
cc20p1305.init(Cipher.ENCRYPT_MODE, DEF_KEY);
|
||||
algParams = cc20p1305.getParameters();
|
||||
preInitNonce = getNonceFromParams(algParams);
|
||||
// Perform a simple encryption operation
|
||||
cc20p1305.doFinal(aeadTestList.get(0).input);
|
||||
try {
|
||||
// Now try to reinitialize using the same parameters
|
||||
cc20p1305.init(Cipher.ENCRYPT_MODE, DEF_KEY, algParams);
|
||||
throw new RuntimeException("Illegal key/nonce reuse");
|
||||
} catch (InvalidKeyException ike) {
|
||||
System.out.println("Caught expected exception: " + ike);
|
||||
}
|
||||
|
||||
// Test the reinit guard using an AlgorithmParameterSpec with the
|
||||
// Same nonce value. This should also be a failure.
|
||||
try {
|
||||
cc20p1305.init(Cipher.ENCRYPT_MODE, DEF_KEY,
|
||||
new IvParameterSpec(preInitNonce));
|
||||
throw new RuntimeException("Illegal key/nonce reuse");
|
||||
} catch (InvalidKeyException ike) {
|
||||
System.out.println("Caught expected exception: " + ike);
|
||||
}
|
||||
|
||||
// Try one more time, this time providing a new 12-byte nonce, which
|
||||
// should be allowed even if the key is the same.
|
||||
cc20p1305.init(Cipher.ENCRYPT_MODE, DEF_KEY,
|
||||
new IvParameterSpec(NONCE_OCTET_STR_12, 2, 12));
|
||||
System.out.println("Test Passed");
|
||||
|
||||
// Reinit test: instantiate, init(no param), getParam, encrypt,
|
||||
// then init(no param). Should work and the parameters should be
|
||||
// different after each init.
|
||||
cc20p1305 = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
cc20p1305.init(Cipher.ENCRYPT_MODE, DEF_KEY);
|
||||
byte[] paramInitOne = getNonceFromParams(cc20p1305.getParameters());
|
||||
// Perform a simple encryption operation
|
||||
cc20p1305.doFinal(aeadTestList.get(0).input);
|
||||
// reinit (no params)
|
||||
cc20p1305.init(Cipher.ENCRYPT_MODE, DEF_KEY);
|
||||
byte[] paramInitTwo = getNonceFromParams(cc20p1305.getParameters());
|
||||
if (MessageDigest.isEqual(paramInitOne, paramInitTwo)) {
|
||||
throw new RuntimeException("Unexpected nonce match between " +
|
||||
"pre and post-init getParameters() calls");
|
||||
}
|
||||
System.out.println("Test Passed");
|
||||
|
||||
// Reinit test: instantiate, init(no param), doFinal, then doFinal
|
||||
// again without intervening init. Should fail due to no-reuse
|
||||
// protections.
|
||||
try {
|
||||
cc20p1305 = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
cc20p1305.init(Cipher.ENCRYPT_MODE, DEF_KEY);
|
||||
cc20p1305.doFinal(aeadTestList.get(0).input);
|
||||
cc20p1305.doFinal(aeadTestList.get(0).input);
|
||||
throw new RuntimeException("Illegal key/nonce reuse");
|
||||
} catch (IllegalStateException ise) {
|
||||
System.out.println("Caught expected exception: " + ise);
|
||||
}
|
||||
|
||||
System.out.println("----- AEAD Tests -----");
|
||||
for (TestData test : aeadTestList) {
|
||||
System.out.println("*** Test " + ++testNumber + ": " +
|
||||
test.testName);
|
||||
if (runAEADTest(test)) {
|
||||
testsPassed++;
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
System.out.println("Total tests: " + testNumber +
|
||||
", Passed: " + testsPassed + ", Failed: " +
|
||||
(testNumber - testsPassed));
|
||||
if (testsPassed != testNumber) {
|
||||
throw new RuntimeException("One or more tests failed. " +
|
||||
"Check output for details");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt default inits with null AlgorithmParameters
|
||||
*
|
||||
* @param alg the algorithm (ChaCha20, ChaCha20-Poly1305)
|
||||
* @param mode the Cipher mode (ENCRYPT_MODE, etc.)
|
||||
*/
|
||||
private static void testDefaultAlgParams(String alg, int mode,
|
||||
boolean shouldPass) {
|
||||
byte[] ivOne = null, ivTwo = null;
|
||||
System.out.println("Test default AlgorithmParameters: Cipher = " +
|
||||
alg + ", mode = " + mode);
|
||||
try {
|
||||
AlgorithmParameters params = null;
|
||||
Cipher cipher = Cipher.getInstance(alg);
|
||||
cipher.init(mode, DEF_KEY, params, null);
|
||||
ivOne = cipher.getIV();
|
||||
cipher.init(mode, DEF_KEY, params, null);
|
||||
ivTwo = cipher.getIV();
|
||||
if (!shouldPass) {
|
||||
throw new RuntimeException(
|
||||
"Did not receive expected exception");
|
||||
}
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (shouldPass) {
|
||||
throw new RuntimeException(gse);
|
||||
}
|
||||
System.out.println("Caught expected exception: " + gse);
|
||||
return;
|
||||
}
|
||||
if (Arrays.equals(ivOne, ivTwo)) {
|
||||
throw new RuntimeException(
|
||||
"FAIL! Two inits generated same nonces");
|
||||
} else {
|
||||
System.out.println("IV 1:\n" + dumpHexBytes(ivOne, 16, "\n", " "));
|
||||
System.out.println("IV 1:\n" + dumpHexBytes(ivTwo, 16, "\n", " "));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt default inits with null AlgorithmParameters
|
||||
*
|
||||
* @param alg the algorithm (ChaCha20, ChaCha20-Poly1305)
|
||||
* @param mode the Cipher mode (ENCRYPT_MODE, etc.)
|
||||
*/
|
||||
private static void testDefaultAlgParamSpec(String alg, int mode,
|
||||
boolean shouldPass) {
|
||||
byte[] ivOne = null, ivTwo = null;
|
||||
System.out.println("Test default AlgorithmParameterSpec: Cipher = " +
|
||||
alg + ", mode = " + mode);
|
||||
try {
|
||||
AlgorithmParameterSpec params = null;
|
||||
Cipher cipher = Cipher.getInstance(alg);
|
||||
cipher.init(mode, DEF_KEY, params, null);
|
||||
ivOne = cipher.getIV();
|
||||
cipher.init(mode, DEF_KEY, params, null);
|
||||
ivTwo = cipher.getIV();
|
||||
if (!shouldPass) {
|
||||
throw new RuntimeException(
|
||||
"Did not receive expected exception");
|
||||
}
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (shouldPass) {
|
||||
throw new RuntimeException(gse);
|
||||
}
|
||||
System.out.println("Caught expected exception: " + gse);
|
||||
return;
|
||||
}
|
||||
if (Arrays.equals(ivOne, ivTwo)) {
|
||||
throw new RuntimeException(
|
||||
"FAIL! Two inits generated same nonces");
|
||||
} else {
|
||||
System.out.println("IV 1:\n" + dumpHexBytes(ivOne, 16, "\n", " "));
|
||||
System.out.println("IV 2:\n" + dumpHexBytes(ivTwo, 16, "\n", " "));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean runAEADTest(TestData testData)
|
||||
throws GeneralSecurityException, IOException {
|
||||
boolean result = false;
|
||||
|
||||
Cipher mambo = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
SecretKeySpec mamboKey = new SecretKeySpec(testData.key, "ChaCha20");
|
||||
AlgorithmParameters mamboParams =
|
||||
AlgorithmParameters.getInstance("ChaCha20-Poly1305");
|
||||
|
||||
// Put the nonce into ASN.1 ChaCha20-Poly1305 parameter format
|
||||
byte[] derNonce = new byte[testData.nonce.length + 2];
|
||||
derNonce[0] = 0x04;
|
||||
derNonce[1] = (byte)testData.nonce.length;
|
||||
System.arraycopy(testData.nonce, 0, derNonce, 2,
|
||||
testData.nonce.length);
|
||||
mamboParams.init(derNonce);
|
||||
|
||||
mambo.init(testData.direction, mamboKey, mamboParams);
|
||||
|
||||
byte[] out = new byte[mambo.getOutputSize(testData.input.length)];
|
||||
int outOff = 0;
|
||||
try {
|
||||
mambo.updateAAD(testData.aad);
|
||||
outOff += mambo.update(testData.input, 0, testData.input.length,
|
||||
out, outOff);
|
||||
outOff += mambo.doFinal(out, outOff);
|
||||
} catch (AEADBadTagException abte) {
|
||||
// If we get a bad tag or derive a tag mismatch, log it
|
||||
// and register it as a failure
|
||||
System.out.println("FAIL: " + abte);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Arrays.equals(out, testData.expOutput)) {
|
||||
System.out.println("ERROR - Output Mismatch!");
|
||||
System.out.println("Expected:\n" +
|
||||
dumpHexBytes(testData.expOutput, 16, "\n", " "));
|
||||
System.out.println("Actual:\n" +
|
||||
dumpHexBytes(out, 16, "\n", " "));
|
||||
System.out.println();
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] getNonceFromParams(AlgorithmParameters params)
|
||||
throws InvalidParameterSpecException {
|
||||
return params.getParameterSpec(IvParameterSpec.class).getIV();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the hex bytes of a buffer into string form.
|
||||
*
|
||||
* @param data The array of bytes to dump to stdout.
|
||||
* @param itemsPerLine The number of bytes to display per line
|
||||
* if the {@code lineDelim} character is blank then all bytes
|
||||
* will be printed on a single line.
|
||||
* @param lineDelim The delimiter between lines
|
||||
* @param itemDelim The delimiter between bytes
|
||||
*
|
||||
* @return The hexdump of the byte array
|
||||
*/
|
||||
private static String dumpHexBytes(byte[] data, int itemsPerLine,
|
||||
String lineDelim, String itemDelim) {
|
||||
return dumpHexBytes(ByteBuffer.wrap(data), itemsPerLine, lineDelim,
|
||||
itemDelim);
|
||||
}
|
||||
|
||||
private static String dumpHexBytes(ByteBuffer data, int itemsPerLine,
|
||||
String lineDelim, String itemDelim) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (data != null) {
|
||||
data.mark();
|
||||
int i = 0;
|
||||
while (data.remaining() > 0) {
|
||||
if (i % itemsPerLine == 0 && i != 0) {
|
||||
sb.append(lineDelim);
|
||||
}
|
||||
sb.append(String.format("%02X", data.get())).append(itemDelim);
|
||||
i++;
|
||||
}
|
||||
data.reset();
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2022, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8224997
|
||||
* @summary ChaCha20-Poly1305 TLS cipher suite decryption throws ShortBufferException
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.Convert
|
||||
* @run main OutputSizeTest
|
||||
*/
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Key;
|
||||
import java.security.SecureRandom;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.spec.ChaCha20ParameterSpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
public class OutputSizeTest {
|
||||
|
||||
private static final SecureRandom SR = new SecureRandom();
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
testCC20GetOutSize();
|
||||
testCC20P1305GetOutSize();
|
||||
testMultiPartAEADDec();
|
||||
}
|
||||
|
||||
private static void testCC20GetOutSize()
|
||||
throws GeneralSecurityException {
|
||||
boolean result = true;
|
||||
KeyGenerator kg = KeyGenerator.getInstance("ChaCha20", "SunJCE");
|
||||
kg.init(256);
|
||||
|
||||
// ChaCha20 encrypt
|
||||
Cipher cc20 = Cipher.getInstance("ChaCha20", "SunJCE");
|
||||
cc20.init(Cipher.ENCRYPT_MODE, kg.generateKey(),
|
||||
new ChaCha20ParameterSpec(getRandBuf(12), 10));
|
||||
|
||||
testOutLen(cc20, 0, 0);
|
||||
testOutLen(cc20, 5, 5);
|
||||
testOutLen(cc20, 5120, 5120);
|
||||
// perform an update, then test with a final block
|
||||
byte[] input = new byte[5120];
|
||||
SR.nextBytes(input);
|
||||
cc20.update(input);
|
||||
testOutLen(cc20, 1024, 1024);
|
||||
|
||||
// Decryption lengths should be calculated the same way as encryption
|
||||
cc20.init(Cipher.DECRYPT_MODE, kg.generateKey(),
|
||||
new ChaCha20ParameterSpec(getRandBuf(12), 10));
|
||||
testOutLen(cc20, 0, 0);
|
||||
testOutLen(cc20, 5, 5);
|
||||
testOutLen(cc20, 5120, 5120);
|
||||
// perform an update, then test with a final block
|
||||
cc20.update(input);
|
||||
testOutLen(cc20, 1024, 1024);
|
||||
}
|
||||
|
||||
private static void testCC20P1305GetOutSize()
|
||||
throws GeneralSecurityException {
|
||||
KeyGenerator kg = KeyGenerator.getInstance("ChaCha20", "SunJCE");
|
||||
kg.init(256);
|
||||
|
||||
// ChaCha20 encrypt
|
||||
Cipher cc20 = Cipher.getInstance("ChaCha20-Poly1305", "SunJCE");
|
||||
cc20.init(Cipher.ENCRYPT_MODE, kg.generateKey(),
|
||||
new IvParameterSpec(getRandBuf(12)));
|
||||
|
||||
// Encryption lengths are calculated as the input length plus the tag
|
||||
// length (16).
|
||||
testOutLen(cc20, 0, 16);
|
||||
testOutLen(cc20, 5, 21);
|
||||
testOutLen(cc20, 5120, 5136);
|
||||
// perform an update, then test with a final block
|
||||
byte[] input = new byte[5120];
|
||||
SR.nextBytes(input);
|
||||
cc20.update(input);
|
||||
testOutLen(cc20, 1024, 1040);
|
||||
|
||||
// Decryption lengths are handled differently for AEAD mode. The length
|
||||
// should be zero for anything up to and including the first 16 bytes
|
||||
// (since that's the tag). Anything above that should be the input
|
||||
// length plus any unprocessed input (via update calls), minus the
|
||||
// 16 byte tag.
|
||||
cc20.init(Cipher.DECRYPT_MODE, kg.generateKey(),
|
||||
new IvParameterSpec(getRandBuf(12)));
|
||||
testOutLen(cc20, 0, 0);
|
||||
testOutLen(cc20, 5, 0);
|
||||
testOutLen(cc20, 16, 0);
|
||||
testOutLen(cc20, 5120, 5104);
|
||||
// Perform an update, then test with the length of a final chunk
|
||||
// of data.
|
||||
cc20.update(input);
|
||||
testOutLen(cc20, 1024, 6128);
|
||||
}
|
||||
|
||||
private static void testMultiPartAEADDec() throws GeneralSecurityException {
|
||||
KeyGenerator kg = KeyGenerator.getInstance("ChaCha20", "SunJCE");
|
||||
kg.init(256);
|
||||
Key key = kg.generateKey();
|
||||
IvParameterSpec ivps = new IvParameterSpec(getRandBuf(12));
|
||||
|
||||
// Encrypt some data so we can test decryption.
|
||||
byte[] pText = getRandBuf(2048);
|
||||
ByteBuffer pTextBase = ByteBuffer.wrap(pText);
|
||||
|
||||
Cipher enc = Cipher.getInstance("ChaCha20-Poly1305", "SunJCE");
|
||||
enc.init(Cipher.ENCRYPT_MODE, key, ivps);
|
||||
ByteBuffer ctBuf = ByteBuffer.allocateDirect(
|
||||
enc.getOutputSize(pText.length));
|
||||
enc.doFinal(pTextBase, ctBuf);
|
||||
|
||||
// Create a new direct plain text ByteBuffer which will catch the
|
||||
// decrypted data.
|
||||
ByteBuffer ptBuf = ByteBuffer.allocateDirect(pText.length);
|
||||
|
||||
// Set the cipher text buffer limit to roughly half the data so we can
|
||||
// do an update/final sequence.
|
||||
ctBuf.position(0).limit(1024);
|
||||
|
||||
Cipher dec = Cipher.getInstance("ChaCha20-Poly1305", "SunJCE");
|
||||
dec.init(Cipher.DECRYPT_MODE, key, ivps);
|
||||
dec.update(ctBuf, ptBuf);
|
||||
System.out.println("CTBuf: " + ctBuf);
|
||||
System.out.println("PTBuf: " + ptBuf);
|
||||
ctBuf.limit(ctBuf.capacity());
|
||||
dec.doFinal(ctBuf, ptBuf);
|
||||
|
||||
ptBuf.flip();
|
||||
pTextBase.flip();
|
||||
System.out.println("PT Base:" + pTextBase);
|
||||
System.out.println("PT Actual:" + ptBuf);
|
||||
|
||||
if (pTextBase.compareTo(ptBuf) != 0) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Plaintext mismatch: Original: ").
|
||||
append(pTextBase.toString()).append("\nActual :").
|
||||
append(ptBuf);
|
||||
throw new RuntimeException(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static void testOutLen(Cipher c, int inLen, int expOut) {
|
||||
int actualOut = c.getOutputSize(inLen);
|
||||
if (actualOut != expOut) {
|
||||
throw new RuntimeException("Cipher " + c + ", in: " + inLen +
|
||||
", expOut: " + expOut + ", actual: " + actualOut);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] getRandBuf(int len) {
|
||||
byte[] buf = new byte[len];
|
||||
SR.nextBytes(buf);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8366833
|
||||
* @summary Poly1305 does not always correctly update position for array-backed
|
||||
* ByteBuffers after processMultipleBlocks
|
||||
* @run main UpdateAADTest
|
||||
*/
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HexFormat;
|
||||
|
||||
public class UpdateAADTest {
|
||||
private static final SecureRandom RAND;
|
||||
private static final KeyGenerator CC20GEN;
|
||||
private static final HexFormat HEX = HexFormat.of();
|
||||
|
||||
private static final byte[] TEST_KEY_BYTES = HEX.parseHex(
|
||||
"3cb1283912536e4108c3094dc2940d0d020afbd7701de267bbfb359bc7d54dd7");
|
||||
private static final byte[] TEST_NONCE_BYTES = HEX.parseHex(
|
||||
"9bd647a43b6fa7826e2cc26d");
|
||||
private static final byte[] TEST_AAD_BYTES =
|
||||
"This is a bunch of additional data to throw into the mix.".
|
||||
getBytes(StandardCharsets.UTF_8);
|
||||
private static final byte[] TEST_INPUT_BYTES =
|
||||
"This is a plaintext message".getBytes(StandardCharsets.UTF_8);
|
||||
private static final byte[] TEST_CT_BYTES = HEX.parseHex(
|
||||
"8536c999809f4b9d6a1594ee1084c751d1bd8a991e6a4b4ac26386f04b9a1303" +
|
||||
"f40cbe6788d72af2d0c617");
|
||||
private static final ByteBuffer EXPOUTBUF = ByteBuffer.wrap(TEST_CT_BYTES);
|
||||
|
||||
static {
|
||||
try {
|
||||
RAND = new SecureRandom();
|
||||
CC20GEN = KeyGenerator.getInstance("ChaCha20");
|
||||
} catch (GeneralSecurityException gse) {
|
||||
throw new RuntimeException("Failed to init static JCE components",
|
||||
gse);
|
||||
}
|
||||
}
|
||||
|
||||
public interface TestAction {
|
||||
void runTest(ByteBuffer buffer) throws Exception;
|
||||
}
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
ByteBuffer twoKBuf = ByteBuffer.allocate(2048);
|
||||
ByteBuffer nonBABuf = ByteBuffer.allocate(1329);
|
||||
|
||||
System.out.println("----- Test 1: Baseline test -----");
|
||||
System.out.println("Make an array backed buffer that is 16-byte " +
|
||||
"aligned, treat all data as AAD and feed it to " +
|
||||
" updateAAD.");
|
||||
aadUpdateTest.runTest(twoKBuf);
|
||||
|
||||
System.out.println("----- Test 2: Non Block Aligned Offset -----");
|
||||
System.out.println("Use the same buffer, but place the offset such " +
|
||||
"that the remaining data is not block aligned.");
|
||||
aadUpdateTest.runTest(twoKBuf.position(395));
|
||||
|
||||
System.out.println("----- Test 3: Non Block Aligned Buf/Off -----");
|
||||
System.out.println("Make a buffer of non-block aligned size with an " +
|
||||
"offset that keeps the remaining data non-block " +
|
||||
"aligned.");
|
||||
aadUpdateTest.runTest(nonBABuf.position(602));
|
||||
|
||||
System.out.println("----- Test 4: Aligned Buffer Slice -----");
|
||||
System.out.println("Use a buffer of block aligned size, but slice " +
|
||||
"the buffer such that the slice offset is part " +
|
||||
"way into the original buffer.");
|
||||
aadUpdateTest.runTest(twoKBuf.rewind().slice(1024,1024).position(42));
|
||||
|
||||
System.out.println("----- Test 5: Non-Aligned Buffer Slice -----");
|
||||
System.out.println("Try the same test as #4, this time with " +
|
||||
"non-block aligned buffers/slices.");
|
||||
aadUpdateTest.runTest(nonBABuf.rewind().slice(347, 347).position(86));
|
||||
|
||||
System.out.println("----- Test 6: MemorySegment Buffer -----");
|
||||
System.out.println("Make a ByteBuffer from an array-backed " +
|
||||
"MemorySegment, and try updating");
|
||||
MemorySegment mseg = MemorySegment.ofArray(new byte[2048]);
|
||||
ByteBuffer msegBuf = mseg.asByteBuffer();
|
||||
aadUpdateTest.runTest(msegBuf.position(55));
|
||||
|
||||
System.out.println("----- Test 7: Buffer of MemorySegment Slice -----");
|
||||
System.out.println("Use a slice from the MemorySegment and create a " +
|
||||
"buffer from that for testing");
|
||||
MemorySegment msegSlice = mseg.asSlice(1024);
|
||||
aadUpdateTest.runTest(msegSlice.asByteBuffer().position(55));
|
||||
|
||||
System.out.println("----- Test 8: MemorySegment Buffer Slice -----");
|
||||
System.out.println("Create a slice from the ByteBuffer from the " +
|
||||
"original MemorySegment.");
|
||||
aadUpdateTest.runTest(msegBuf.rewind().slice(1024, 1024));
|
||||
|
||||
System.out.println("Test vector processing");
|
||||
System.out.println("----------------------");
|
||||
System.out.println("----- Test 9: AAD + Plaintext on buffer ------");
|
||||
System.out.println("Place the AAD, followed by plaintext and verify " +
|
||||
"the ciphertext");
|
||||
// Create a ByteBuffer where the AAD and plaintext actually sit
|
||||
// somewhere in the middle of the underlying array, with non-test-vector
|
||||
// memory on either side of the data.
|
||||
ByteBuffer vectorBuf = ByteBuffer.allocate(1024).position(600).
|
||||
put(TEST_AAD_BYTES).put(TEST_INPUT_BYTES).flip().position(600);
|
||||
vectorTest.runTest(vectorBuf);
|
||||
|
||||
System.out.println("----- Test 10: AAD + Plaintext on slice -----");
|
||||
System.out.println("Perform the same test, this time on a slice" +
|
||||
"of the test vector buffer");
|
||||
ByteBuffer vectorSlice = vectorBuf.slice(600,
|
||||
TEST_AAD_BYTES.length + TEST_INPUT_BYTES.length);
|
||||
vectorTest.runTest(vectorSlice);
|
||||
}
|
||||
|
||||
// Simple test callback for taking a ByteBuffer and throwing all
|
||||
// remaining bytes into an updateAAD call.
|
||||
public static TestAction aadUpdateTest = buffer -> {
|
||||
SecretKey key = CC20GEN.generateKey();
|
||||
byte[] nonce = new byte[12];
|
||||
RAND.nextBytes(nonce);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(nonce));
|
||||
|
||||
cipher.updateAAD(buffer);
|
||||
// Per the API the buffer's position and limit should be equal
|
||||
if (buffer.position() != buffer.limit()) {
|
||||
throw new RuntimeException("Buffer position and limit " +
|
||||
"should be equal but are not: p = " +
|
||||
buffer.position() + ", l = " + buffer.limit());
|
||||
}
|
||||
};
|
||||
|
||||
// Test callback for making sure that the updateAAD method, when
|
||||
// put in with a complete encryption operation still gets the
|
||||
// expected answer.
|
||||
public static TestAction vectorTest = buffer -> {
|
||||
Cipher cipher = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
cipher.init(Cipher.ENCRYPT_MODE,
|
||||
new SecretKeySpec(TEST_KEY_BYTES, "ChaCha20"),
|
||||
new IvParameterSpec(TEST_NONCE_BYTES));
|
||||
ByteBuffer outbuf = ByteBuffer.allocate(cipher.getOutputSize(
|
||||
TEST_INPUT_BYTES.length));
|
||||
|
||||
// Adjust the limit to be the end of the aad
|
||||
int origLim = buffer.limit();
|
||||
buffer.limit(buffer.position() + TEST_AAD_BYTES.length);
|
||||
cipher.updateAAD(buffer);
|
||||
buffer.limit(origLim);
|
||||
cipher.doFinal(buffer, outbuf);
|
||||
if (!outbuf.flip().equals(EXPOUTBUF)) {
|
||||
throw new RuntimeException("Output data mismatch");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8153029 8360463 8368984
|
||||
* @library /test/lib
|
||||
* @run main ChaCha20CipherUnitTest
|
||||
* @summary Unit test for com.sun.crypto.provider.ChaCha20Cipher.
|
||||
*/
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.HexFormat;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.ChaCha20ParameterSpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
public class ChaCha20CipherUnitTest {
|
||||
|
||||
private static final byte[] NONCE
|
||||
= HexFormat.of().parseHex("012345670123456701234567");
|
||||
private static final SecretKeySpec KEY = new SecretKeySpec(
|
||||
HexFormat.of().parseHex("0123456701234567012345670123456701234567012345670123456701234567"),
|
||||
"ChaCha20");
|
||||
private static final ChaCha20ParameterSpec CHACHA20_PARAM_SPEC
|
||||
= new ChaCha20ParameterSpec(NONCE, 0);
|
||||
private static final IvParameterSpec IV_PARAM_SPEC
|
||||
= new IvParameterSpec(NONCE);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
testTransformations();
|
||||
testInit();
|
||||
testAEAD();
|
||||
testGetBlockSize();
|
||||
}
|
||||
|
||||
private static void testTransformations() throws Exception {
|
||||
System.out.println("== transformations ==");
|
||||
|
||||
Class NSAE = NoSuchAlgorithmException.class;
|
||||
Class NSPE = NoSuchPaddingException.class;
|
||||
|
||||
checkTransformation("ChaCha20", null);
|
||||
checkTransformation("ChaCha20/None/NoPadding", null);
|
||||
checkTransformation("ChaCha20/None//", NSAE);
|
||||
checkTransformation("ChaCha20/ECB/NoPadding", NSAE);
|
||||
checkTransformation("ChaCha20/None/PKCS5Padding", NSPE);
|
||||
checkTransformation("ChaCha20-Poly1305", null);
|
||||
checkTransformation("ChaCha20-Poly1305/None/NoPadding", null);
|
||||
checkTransformation("ChaCha20-Poly1305/None//", NSAE);
|
||||
checkTransformation("ChaCha20-Poly1305/ECB/NoPadding", NSAE);
|
||||
checkTransformation("ChaCha20-Poly1305/None/PKCS5Padding", NSPE);
|
||||
}
|
||||
|
||||
private static void checkTransformation(String transformation, Class exCls)
|
||||
throws Exception {
|
||||
try {
|
||||
Cipher.getInstance(transformation,
|
||||
System.getProperty("test.provider.name", "SunJCE"));
|
||||
if (exCls != null) {
|
||||
throw new RuntimeException("Expected Exception not thrown: " +
|
||||
exCls);
|
||||
} else {
|
||||
System.out.println(transformation + ": pass");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
|
||||
if (e.getClass() != exCls) {
|
||||
throw new RuntimeException("Unexpected Exception", e);
|
||||
} else {
|
||||
System.out.println(transformation + ": got expected " +
|
||||
exCls.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testInit() throws Exception {
|
||||
testInitOnCrypt(Cipher.ENCRYPT_MODE);
|
||||
testInitOnCrypt(Cipher.DECRYPT_MODE);
|
||||
testInitOnWrap(Cipher.WRAP_MODE);
|
||||
testInitOnWrap(Cipher.UNWRAP_MODE);
|
||||
}
|
||||
|
||||
private static void testInitOnCrypt(int opMode) throws Exception {
|
||||
System.out.println("== init (" + getOpModeName(opMode) + ") ==");
|
||||
|
||||
Cipher.getInstance("ChaCha20").init(opMode, KEY, CHACHA20_PARAM_SPEC);
|
||||
Cipher.getInstance("ChaCha20").init(opMode, KEY,
|
||||
CHACHA20_PARAM_SPEC, new SecureRandom());
|
||||
|
||||
try {
|
||||
Cipher.getInstance("ChaCha20").init(opMode, KEY, IV_PARAM_SPEC);
|
||||
throw new RuntimeException("ChaCha20ParameterSpec is needed");
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
|
||||
Cipher.getInstance("ChaCha20-Poly1305").init(opMode, KEY,
|
||||
IV_PARAM_SPEC);
|
||||
Cipher.getInstance("ChaCha20-Poly1305").init(opMode, KEY,
|
||||
IV_PARAM_SPEC, new SecureRandom());
|
||||
|
||||
try {
|
||||
Cipher.getInstance("ChaCha20-Poly1305").init(opMode, KEY,
|
||||
CHACHA20_PARAM_SPEC);
|
||||
throw new RuntimeException("IvParameterSpec is needed");
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
|
||||
AlgorithmParameters algorithmParameters =
|
||||
AlgorithmParameters.getInstance("ChaCha20-Poly1305");
|
||||
algorithmParameters.init(
|
||||
new byte[] { 4, 12, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8 });
|
||||
try {
|
||||
Cipher.getInstance("ChaCha20").init(opMode, KEY,
|
||||
algorithmParameters, new SecureRandom());
|
||||
throw new RuntimeException(
|
||||
"ChaCha20 cipher doesn't accept AlgorithmParameters");
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
Cipher.getInstance("ChaCha20-Poly1305").init(opMode, KEY,
|
||||
algorithmParameters, new SecureRandom());
|
||||
}
|
||||
|
||||
private static void testInitOnWrap(int opMode) throws Exception {
|
||||
String opModeName = getOpModeName(opMode);
|
||||
System.out.println("== init (" + opModeName + ") ==");
|
||||
|
||||
Cipher chacha20Cipher = Cipher.getInstance("ChaCha20");
|
||||
try {
|
||||
chacha20Cipher.init(opMode, KEY, new SecureRandom());
|
||||
throw new RuntimeException(
|
||||
"Unexpected opration mode: " + opModeName);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof UnsupportedOperationException) {
|
||||
System.out.println("Expected " + e);
|
||||
} else {
|
||||
throw new RuntimeException("Unexpected exception: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testAEAD() throws Exception {
|
||||
byte[] expectedPlainttext = HexFormat.of().parseHex("01234567");
|
||||
byte[] ciphertext = testUpdateAAD(Cipher.ENCRYPT_MODE, expectedPlainttext);
|
||||
byte[] plaintext = testUpdateAAD(Cipher.DECRYPT_MODE, ciphertext);
|
||||
if (!Arrays.equals(plaintext, expectedPlainttext)) {
|
||||
System.out.println("ciphertext: " + Arrays.toString(ciphertext));
|
||||
System.out.println("plaintext: " + Arrays.toString(plaintext));
|
||||
throw new RuntimeException("AEAD failed");
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] testUpdateAAD(int opMode, byte[] input)
|
||||
throws Exception {
|
||||
String opModeName = getOpModeName(opMode);
|
||||
System.out.println("== updateAAD (" + opModeName + ") ==");
|
||||
|
||||
byte[] aad = HexFormat.of().parseHex("0000");
|
||||
ByteBuffer aadBuf = ByteBuffer.wrap(aad);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("ChaCha20");
|
||||
cipher.init(opMode, KEY, CHACHA20_PARAM_SPEC);
|
||||
try {
|
||||
cipher.updateAAD(aadBuf);
|
||||
throw new RuntimeException("ChaCha20 cipher cannot apply AAD");
|
||||
} catch (IllegalStateException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
|
||||
Cipher aeadCipher = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
try {
|
||||
aeadCipher.updateAAD(aadBuf);
|
||||
throw new RuntimeException(
|
||||
"Cannot update AAD on uninitialized Cipher");
|
||||
} catch (IllegalStateException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
aeadCipher.init(opMode, KEY, IV_PARAM_SPEC);
|
||||
aeadCipher.update(input);
|
||||
try {
|
||||
aeadCipher.updateAAD(aad);
|
||||
throw new RuntimeException(
|
||||
"Cannot update AAD after plaintext/cipertext update");
|
||||
} catch (IllegalStateException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
|
||||
aeadCipher = Cipher.getInstance("ChaCha20-Poly1305");
|
||||
aeadCipher.init(opMode, KEY, IV_PARAM_SPEC);
|
||||
aeadCipher.updateAAD(aadBuf);
|
||||
return aeadCipher.doFinal(input);
|
||||
}
|
||||
|
||||
private static void testGetBlockSize() throws Exception {
|
||||
testGetBlockSize(Cipher.ENCRYPT_MODE);
|
||||
testGetBlockSize(Cipher.DECRYPT_MODE);
|
||||
}
|
||||
|
||||
private static void testGetBlockSize(int opMode) throws Exception {
|
||||
System.out.println("== getBlockSize (" + getOpModeName(opMode) + ") ==");
|
||||
|
||||
Cipher cipher = Cipher.getInstance("ChaCha20");
|
||||
cipher.init(opMode, KEY, CHACHA20_PARAM_SPEC);
|
||||
if (cipher.getBlockSize() != 0) {
|
||||
throw new RuntimeException("Block size must be 0");
|
||||
}
|
||||
}
|
||||
|
||||
private static String getOpModeName(int opMode) {
|
||||
switch (opMode) {
|
||||
case Cipher.ENCRYPT_MODE:
|
||||
return "ENCRYPT";
|
||||
|
||||
case Cipher.DECRYPT_MODE:
|
||||
return "DECRYPT";
|
||||
|
||||
case Cipher.WRAP_MODE:
|
||||
return "WRAP";
|
||||
|
||||
case Cipher.UNWRAP_MODE:
|
||||
return "UNWRAP";
|
||||
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8153029
|
||||
* @library /test/lib
|
||||
* @run main ChaCha20Poly1305ParametersUnitTest
|
||||
* @summary Unit test for com.sun.crypto.provider.ChaCha20Poly1305Parameters.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.spec.ChaCha20ParameterSpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
public class ChaCha20Poly1305ParametersUnitTest {
|
||||
|
||||
private static final String ALGORITHM = "ChaCha20-Poly1305";
|
||||
|
||||
private static final byte[] NONCE = {
|
||||
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
private static final byte[] PARAM = {
|
||||
4, 12, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
|
||||
private static final byte[] BAD_NONCE = {
|
||||
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
private static final byte[] BAD_PARAM = {
|
||||
4, 13, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
testInit();
|
||||
testGetParameterSpec();
|
||||
testGetEncoded();
|
||||
}
|
||||
|
||||
private static void testInit() throws Exception {
|
||||
System.out.println("== init ==");
|
||||
|
||||
AlgorithmParameters ap = AlgorithmParameters.getInstance(ALGORITHM);
|
||||
ap.init(new IvParameterSpec(NONCE));
|
||||
System.out.println("AlgorithmParameters: " + ap);
|
||||
|
||||
ap = AlgorithmParameters.getInstance(ALGORITHM);
|
||||
ap.init(PARAM);
|
||||
|
||||
ap = AlgorithmParameters.getInstance(ALGORITHM);
|
||||
try {
|
||||
ap.init(new ChaCha20ParameterSpec(NONCE, 0));
|
||||
throw new RuntimeException("IvParameterSpec is needed");
|
||||
} catch (InvalidParameterSpecException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
|
||||
ap = AlgorithmParameters.getInstance(ALGORITHM);
|
||||
try {
|
||||
ap.init(new IvParameterSpec(BAD_NONCE));
|
||||
throw new RuntimeException("Nonce must be 96 bits in length");
|
||||
} catch (InvalidParameterSpecException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
|
||||
ap = AlgorithmParameters.getInstance(ALGORITHM);
|
||||
try {
|
||||
ap.init(BAD_PARAM);
|
||||
throw new RuntimeException("Nonce must be 96 bits in length");
|
||||
} catch (IOException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testGetParameterSpec() throws Exception {
|
||||
System.out.println("== getParameterSpec ==");
|
||||
|
||||
AlgorithmParameters ap = AlgorithmParameters.getInstance(ALGORITHM);
|
||||
ap.init(PARAM);
|
||||
|
||||
IvParameterSpec paramSpec = ap.getParameterSpec(IvParameterSpec.class);
|
||||
byte[] nonce = paramSpec.getIV();
|
||||
System.out.println("Nonce: " + Arrays.toString(nonce));
|
||||
Arrays.equals(nonce, NONCE);
|
||||
|
||||
try {
|
||||
ap.getParameterSpec(ChaCha20ParameterSpec.class);
|
||||
throw new RuntimeException("IvParameterSpec is needed");
|
||||
} catch (InvalidParameterSpecException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testGetEncoded() throws Exception {
|
||||
System.out.println("== getEncoded ==");
|
||||
|
||||
AlgorithmParameters ap = AlgorithmParameters.getInstance(ALGORITHM);
|
||||
ap.init(PARAM);
|
||||
|
||||
byte[] defaultFormatEncoded = ap.getEncoded();
|
||||
System.out.println("Default format encoding: "
|
||||
+ Arrays.toString(defaultFormatEncoded));
|
||||
if (!Arrays.equals(defaultFormatEncoded, PARAM)) {
|
||||
throw new RuntimeException("Default format encoding failed");
|
||||
}
|
||||
|
||||
byte[] asn1FormatEncoded = ap.getEncoded("ASN.1");
|
||||
System.out.println("ASN.1 format encoding: "
|
||||
+ Arrays.toString(asn1FormatEncoded));
|
||||
if (!Arrays.equals(asn1FormatEncoded, PARAM)) {
|
||||
throw new RuntimeException("ASN.1 format encoding failed");
|
||||
}
|
||||
|
||||
byte[] nullFormatEncoded = ap.getEncoded(null);
|
||||
System.out.println("Null format encoding: "
|
||||
+ Arrays.toString(nullFormatEncoded));
|
||||
if (!Arrays.equals(nullFormatEncoded, PARAM)) {
|
||||
throw new RuntimeException("Null format encoding failed");
|
||||
}
|
||||
|
||||
try {
|
||||
ap.getEncoded("BAD");
|
||||
throw new RuntimeException("Format must be ASN.1");
|
||||
} catch (IOException e) {
|
||||
System.out.println("Expected " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2022, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8153029
|
||||
* @modules java.base/com.sun.crypto.provider
|
||||
* @run main java.base/com.sun.crypto.provider.Poly1305UnitTest
|
||||
* @summary Unit test for com.sun.crypto.provider.Poly1305.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @key randomness
|
||||
* @modules java.base/com.sun.crypto.provider
|
||||
* @run main java.base/com.sun.crypto.provider.Poly1305IntrinsicFuzzTest
|
||||
* @summary Unit test for com.sun.crypto.provider.Poly1305.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/com.sun.crypto.provider
|
||||
* @run main java.base/com.sun.crypto.provider.Poly1305KAT
|
||||
* @summary Unit test for com.sun.crypto.provider.Poly1305.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @key randomness
|
||||
* @modules java.base/com.sun.crypto.provider
|
||||
* @summary Unit test for IntrinsicCandidate in com.sun.crypto.provider.Poly1305.
|
||||
* @run main/othervm -Xcomp -XX:-TieredCompilation -XX:+UnlockDiagnosticVMOptions -XX:+ForceUnreachable java.base/com.sun.crypto.provider.Poly1305IntrinsicFuzzTest
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/com.sun.crypto.provider
|
||||
* @summary Unit test for IntrinsicCandidate in com.sun.crypto.provider.Poly1305.
|
||||
* @run main/othervm -Xcomp -XX:-TieredCompilation -XX:+UnlockDiagnosticVMOptions -XX:+ForceUnreachable java.base/com.sun.crypto.provider.Poly1305KAT
|
||||
*/
|
||||
|
||||
package com.sun.crypto.provider.Cipher.ChaCha20;
|
||||
|
||||
public class Poly1305UnitTestDriver {
|
||||
static public void main(String[] args) {
|
||||
System.out.println("Passed");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Intel Corporation. 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.
|
||||
*/
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
// This test case relies on the fact that single-byte Poly1305.engineUpdate(byte) does not have an intrinsic
|
||||
// In this way we can compare if the intrinsic and pure java produce same result
|
||||
// This test case is NOT entirely deterministic, it uses a random seed for pseudo-random number generator
|
||||
// If a failure occurs, hardcode the seed to make the test case deterministic
|
||||
public class Poly1305IntrinsicFuzzTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
//Note: it might be useful to increase this number during development of new Poly1305 intrinsics
|
||||
final int repeat = 1000;
|
||||
for (int i = 0; i < repeat; i++) {
|
||||
run();
|
||||
}
|
||||
System.out.println("Fuzz Success");
|
||||
}
|
||||
|
||||
public static void run() throws Exception {
|
||||
Random rnd = new Random();
|
||||
long seed = rnd.nextLong();
|
||||
rnd.setSeed(seed);
|
||||
|
||||
byte[] key = new byte[32];
|
||||
rnd.nextBytes(key);
|
||||
int msgLen = rnd.nextInt(128, 4096); // x86_64 intrinsic requires 256 bytes minimum
|
||||
byte[] message = new byte[msgLen];
|
||||
rnd.nextBytes(message);
|
||||
|
||||
Poly1305 authenticator = new Poly1305();
|
||||
Poly1305 authenticatorSlow = new Poly1305();
|
||||
if (authenticator.engineGetMacLength() != 16) {
|
||||
throw new RuntimeException("The length of Poly1305 MAC must be 16-bytes.");
|
||||
}
|
||||
|
||||
authenticator.engineInit(new SecretKeySpec(key, 0, 32, "Poly1305"), null);
|
||||
authenticatorSlow.engineInit(new SecretKeySpec(key, 0, 32, "Poly1305"), null);
|
||||
|
||||
if (rnd.nextBoolean() && message.length > 16) {
|
||||
// Prime just the buffer and/or accumulator (buffer can keep at most 16 bytes from previous engineUpdate)
|
||||
int initDataLen = rnd.nextInt(1, 16);
|
||||
int initDataOffset = rnd.nextInt(0, message.length - initDataLen);
|
||||
fastUpdate(authenticator, rnd, message, initDataOffset, initDataLen);
|
||||
slowUpdate(authenticatorSlow, message, initDataOffset, initDataLen);
|
||||
}
|
||||
|
||||
if (rnd.nextBoolean()) {
|
||||
// Multiple calls to engineUpdate
|
||||
int initDataOffset = rnd.nextInt(0, message.length);
|
||||
fastUpdate(authenticator, rnd, message, initDataOffset, message.length - initDataOffset);
|
||||
slowUpdate(authenticatorSlow, message, initDataOffset, message.length - initDataOffset);
|
||||
}
|
||||
|
||||
fastUpdate(authenticator, rnd, message, 0, message.length);
|
||||
slowUpdate(authenticatorSlow, message, 0, message.length);
|
||||
|
||||
byte[] tag = authenticator.engineDoFinal();
|
||||
byte[] tagSlow = authenticatorSlow.engineDoFinal();
|
||||
|
||||
if (!Arrays.equals(tag, tagSlow)) {
|
||||
throw new RuntimeException("[Seed "+seed+"] Tag mismatch: " + Arrays.toString(tag) + " != " + Arrays.toString(tagSlow));
|
||||
}
|
||||
}
|
||||
|
||||
static void slowUpdate(Poly1305 authenticator, byte[] message, int offset, int len) {
|
||||
for (int i = offset; i < offset + len; i++) {
|
||||
authenticator.engineUpdate(message[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void fastUpdate(Poly1305 authenticator, Random rnd, byte[] message, int offset, int len) {
|
||||
ByteBuffer buf;
|
||||
switch(rnd.nextInt(4)) {
|
||||
case 0: // byte[]
|
||||
authenticator.engineUpdate(message, offset, len);
|
||||
break;
|
||||
case 1: // ByteArray with backing array
|
||||
buf = ByteBuffer.wrap(message, offset, len);
|
||||
authenticator.engineUpdate(buf);
|
||||
break;
|
||||
case 2: // ByteArray with backing array (non-zero position)
|
||||
buf = ByteBuffer.wrap(message, 0, len+offset)
|
||||
.position(offset);
|
||||
authenticator.engineUpdate(buf);
|
||||
break;
|
||||
case 3: // ByteArray without backing array (wont be sent to intrinsic)
|
||||
buf = ByteBuffer.wrap(message, offset, len)
|
||||
.asReadOnlyBuffer();
|
||||
authenticator.engineUpdate(buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Intel Corporation. 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.
|
||||
*/
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.util.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class Poly1305KAT {
|
||||
public static class TestData {
|
||||
public TestData(String name, String keyStr, String inputStr, String outStr) {
|
||||
HexFormat hex = HexFormat.of();
|
||||
testName = Objects.requireNonNull(name);
|
||||
key = hex.parseHex(Objects.requireNonNull(keyStr));
|
||||
input = hex.parseHex(Objects.requireNonNull(inputStr));
|
||||
expOutput = hex.parseHex(Objects.requireNonNull(outStr));
|
||||
}
|
||||
|
||||
public final String testName;
|
||||
public final byte[] key;
|
||||
public final byte[] input;
|
||||
public final byte[] expOutput;
|
||||
}
|
||||
|
||||
public static final List<TestData> testList = new LinkedList<TestData>() {{
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #1",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"00000000000000000000000000000000"));
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #2",
|
||||
"0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e",
|
||||
"416e79207375626d697373696f6e20746f20746865204945544620696e74656e" +
|
||||
"6465642062792074686520436f6e7472696275746f7220666f72207075626c69" +
|
||||
"636174696f6e20617320616c6c206f722070617274206f6620616e2049455446" +
|
||||
"20496e7465726e65742d4472616674206f722052464320616e6420616e792073" +
|
||||
"746174656d656e74206d6164652077697468696e2074686520636f6e74657874" +
|
||||
"206f6620616e204945544620616374697669747920697320636f6e7369646572" +
|
||||
"656420616e20224945544620436f6e747269627574696f6e222e205375636820" +
|
||||
"73746174656d656e747320696e636c756465206f72616c2073746174656d656e" +
|
||||
"747320696e20494554462073657373696f6e732c2061732077656c6c20617320" +
|
||||
"7772697474656e20616e6420656c656374726f6e696320636f6d6d756e696361" +
|
||||
"74696f6e73206d61646520617420616e792074696d65206f7220706c6163652c" +
|
||||
"207768696368206172652061646472657373656420746f",
|
||||
"36e5f6b5c5e06070f0efca96227a863e"));
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #3",
|
||||
"36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000",
|
||||
"416e79207375626d697373696f6e20746f20746865204945544620696e74656e" +
|
||||
"6465642062792074686520436f6e7472696275746f7220666f72207075626c69" +
|
||||
"636174696f6e20617320616c6c206f722070617274206f6620616e2049455446" +
|
||||
"20496e7465726e65742d4472616674206f722052464320616e6420616e792073" +
|
||||
"746174656d656e74206d6164652077697468696e2074686520636f6e74657874" +
|
||||
"206f6620616e204945544620616374697669747920697320636f6e7369646572" +
|
||||
"656420616e20224945544620436f6e747269627574696f6e222e205375636820" +
|
||||
"73746174656d656e747320696e636c756465206f72616c2073746174656d656e" +
|
||||
"747320696e20494554462073657373696f6e732c2061732077656c6c20617320" +
|
||||
"7772697474656e20616e6420656c656374726f6e696320636f6d6d756e696361" +
|
||||
"74696f6e73206d61646520617420616e792074696d65206f7220706c6163652c" +
|
||||
"207768696368206172652061646472657373656420746f",
|
||||
"f3477e7cd95417af89a6b8794c310cf0"));
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #4",
|
||||
"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0",
|
||||
"2754776173206272696c6c69672c20616e642074686520736c6974687920746f" +
|
||||
"7665730a446964206779726520616e642067696d626c6520696e207468652077" +
|
||||
"6162653a0a416c6c206d696d737920776572652074686520626f726f676f7665" +
|
||||
"732c0a416e6420746865206d6f6d65207261746873206f757467726162652e",
|
||||
"4541669a7eaaee61e708dc7cbcc5eb62"));
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #5: If one uses 130-bit partial reduction, does the code handle the case where partially reducedfinal result is not fully reduced?",
|
||||
"0200000000000000000000000000000000000000000000000000000000000000",
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
"03000000000000000000000000000000"));
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #6: What happens if addition of s overflows modulo 2^128?",
|
||||
"02000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
"02000000000000000000000000000000",
|
||||
"03000000000000000000000000000000"));
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #7: What happens if data limb is all ones and there is carry from lower limb?",
|
||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" +
|
||||
"11000000000000000000000000000000",
|
||||
"05000000000000000000000000000000"));
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #8: What happens if final result from polynomial part is exactly 2^130-5?",
|
||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE" +
|
||||
"01010101010101010101010101010101",
|
||||
"00000000000000000000000000000000"));
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #9: What happens if final result from polynomial part is exactly 2^130-6?",
|
||||
"0200000000000000000000000000000000000000000000000000000000000000",
|
||||
"FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
"FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #10: What happens if 5*H+L-type reduction produces 131-bit intermediate result?",
|
||||
"0100000000000000040000000000000000000000000000000000000000000000",
|
||||
"E33594D7505E43B900000000000000003394D7505E4379CD0100000000000000" +
|
||||
"0000000000000000000000000000000001000000000000000000000000000000",
|
||||
"14000000000000005500000000000000"));
|
||||
add(new TestData("RFC 7539 A.3 Test Vector #11: What happens if 5*H+L-type reduction produces 131-bit final result?",
|
||||
"0100000000000000040000000000000000000000000000000000000000000000",
|
||||
"E33594D7505E43B900000000000000003394D7505E4379CD0100000000000000" +
|
||||
"00000000000000000000000000000000",
|
||||
"13000000000000000000000000000000"));
|
||||
}};
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
int testsPassed = 0;
|
||||
int testNumber = 0;
|
||||
|
||||
for (TestData test : testList) {
|
||||
System.out.println("*** Test " + ++testNumber + ": " +
|
||||
test.testName);
|
||||
if (runSingleTest(test)) {
|
||||
testsPassed++;
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
if (testsPassed != testNumber) {
|
||||
throw new RuntimeException("One or more tests failed. " +
|
||||
"Check output for details");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean runSingleTest(TestData testData) throws Exception {
|
||||
Poly1305 authenticator = new Poly1305(false);
|
||||
authenticator.engineInit(new SecretKeySpec(testData.key, 0, testData.key.length, "Poly1305"), null);
|
||||
authenticator.engineUpdate(testData.input, 0, testData.input.length);
|
||||
byte[] tag = authenticator.engineDoFinal();
|
||||
if (!Arrays.equals(tag, testData.expOutput)) {
|
||||
System.out.println("ERROR - Output Mismatch!");
|
||||
System.out.println("Expected:\n" +
|
||||
dumpHexBytes(testData.expOutput, testData.expOutput.length, "\n", " "));
|
||||
System.out.println("Actual:\n" +
|
||||
dumpHexBytes(tag, tag.length, "\n", " "));
|
||||
System.out.println();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the hex bytes of a buffer into string form.
|
||||
*
|
||||
* @param data The array of bytes to dump to stdout.
|
||||
* @param itemsPerLine The number of bytes to display per line
|
||||
* if the {@code lineDelim} character is blank then all bytes
|
||||
* will be printed on a single line.
|
||||
* @param lineDelim The delimiter between lines
|
||||
* @param itemDelim The delimiter between bytes
|
||||
*
|
||||
* @return The hexdump of the byte array
|
||||
*/
|
||||
private static String dumpHexBytes(byte[] data, int itemsPerLine,
|
||||
String lineDelim, String itemDelim) {
|
||||
return dumpHexBytes(ByteBuffer.wrap(data), itemsPerLine, lineDelim,
|
||||
itemDelim);
|
||||
}
|
||||
|
||||
private static String dumpHexBytes(ByteBuffer data, int itemsPerLine,
|
||||
String lineDelim, String itemDelim) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (data != null) {
|
||||
data.mark();
|
||||
int i = 0;
|
||||
while (data.remaining() > 0) {
|
||||
if (i % itemsPerLine == 0 && i != 0) {
|
||||
sb.append(lineDelim);
|
||||
}
|
||||
sb.append(String.format("%02X", data.get())).append(itemDelim);
|
||||
i++;
|
||||
}
|
||||
data.reset();
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*/
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class Poly1305UnitTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
byte[] key = new byte[] {
|
||||
28, -110, 64, -91, -21, 85, -45, -118,
|
||||
-13, 51, -120, -122, 4, -10, -75, -16,
|
||||
71, 57, 23, -63, 64, 43, -128, 9,
|
||||
-99, -54, 92, -68, 32, 112, 117, -64
|
||||
};
|
||||
|
||||
Poly1305 authenticator = new Poly1305();
|
||||
if (authenticator.engineGetMacLength() != 16) {
|
||||
throw new RuntimeException(
|
||||
"The length of Poly1305 MAC must be 16-bytes.");
|
||||
}
|
||||
|
||||
authenticator.engineInit(new SecretKeySpec(key, 0, 32,
|
||||
"Poly1305"), null);
|
||||
|
||||
byte[] message = new byte[] {
|
||||
39, 84, 119, 97, 115, 32, 98, 114,
|
||||
105, 108, 108, 105, 103, 44, 32, 97,
|
||||
110, 100, 32, 116, 104, 101, 32, 115,
|
||||
108, 105, 116, 104, 121, 32, 116, 111,
|
||||
118, 101, 115, 10, 68, 105, 100, 32,
|
||||
103, 121, 114, 101, 32, 97, 110, 100,
|
||||
32, 103, 105, 109, 98, 108, 101, 32,
|
||||
105, 110, 32, 116, 104, 101, 32, 119,
|
||||
97, 98, 101, 58, 10, 65, 108, 108,
|
||||
32, 109, 105, 109, 115, 121, 32, 119,
|
||||
101, 114, 101, 32, 116, 104, 101, 32,
|
||||
98, 111, 114, 111, 103, 111, 118, 101,
|
||||
115, 44, 10, 65, 110, 100, 32, 116,
|
||||
104, 101, 32, 109, 111, 109, 101, 32,
|
||||
114, 97, 116, 104, 115, 32, 111, 117,
|
||||
116, 103, 114, 97, 98, 101, 46
|
||||
};
|
||||
|
||||
authenticator.engineUpdate(
|
||||
ByteBuffer.wrap(Arrays.copyOfRange(message, 0, 8)));
|
||||
authenticator.engineUpdate(message, 8, 104);
|
||||
authenticator.engineUpdate(message, 112, 7);
|
||||
for (int i = 119; i < message.length; i++) {
|
||||
authenticator.engineUpdate(message[i]);
|
||||
}
|
||||
|
||||
byte[] tag = authenticator.engineDoFinal();
|
||||
byte[] expectedTag = new byte[] {
|
||||
69, 65, 102, -102, 126, -86, -18, 97,
|
||||
-25, 8, -36, 124, -68, -59, -21, 98
|
||||
};
|
||||
if (!Arrays.equals(tag, expectedTag)) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected tag: " + Arrays.toString(tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/com.sun.crypto.provider:+open
|
||||
* @run main/othervm DESKeyCleanupTest
|
||||
* @summary Verify that key storage is cleared
|
||||
*/
|
||||
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
/**
|
||||
* Test that the array holding the key bytes is cleared when it is
|
||||
* no longer referenced by the key.
|
||||
*/
|
||||
|
||||
public class DESKeyCleanupTest {
|
||||
|
||||
private final static String SunJCEProvider = "SunJCE";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
testCleanupSecret("DES");
|
||||
testCleanupSecret("DESede");
|
||||
}
|
||||
|
||||
static void testCleanupSecret(String algorithm) throws Exception {
|
||||
KeyGenerator desGen = KeyGenerator.getInstance(algorithm, SunJCEProvider);
|
||||
SecretKey key = desGen.generateKey();
|
||||
|
||||
// Break into the implementation to observe the key byte array.
|
||||
Class<?> keyClass = key.getClass();
|
||||
Field keyField = keyClass.getDeclaredField("key");
|
||||
keyField.setAccessible(true);
|
||||
byte[] array = (byte[])keyField.get(key);
|
||||
|
||||
byte[] zeros = new byte[array.length];
|
||||
do {
|
||||
// Wait for array to be cleared; if not cleared test will timeout
|
||||
System.out.printf("%s array: %s%n", algorithm, Arrays.toString(array));
|
||||
key = null;
|
||||
System.gc(); // attempt to reclaim the key
|
||||
} while (Arrays.compare(zeros, array) != 0);
|
||||
System.out.printf("%s array: %s%n", algorithm, Arrays.toString(array));
|
||||
|
||||
Reference.reachabilityFence(key); // Keep key alive
|
||||
Reference.reachabilityFence(array); // Keep array alive
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2015, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6755701
|
||||
* @summary Change SecretKeyFactory.generateSecret to allow SecretKeySpec to
|
||||
* be passed and used for creating a DES and DESede keys. This avoids the error
|
||||
* of "InvalidKeySpecException: Inappropriate key specification"
|
||||
* @author Anthony Scarpino
|
||||
*/
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class DESSecretKeySpec {
|
||||
|
||||
public static void main(String arg[]) throws Exception {
|
||||
Cipher c;
|
||||
byte[] key = new byte[]{'1','2','3','4','5','6','7','8',
|
||||
'1','2','3','4','5','6','7','8',
|
||||
'1','2','3','4','5','6','7','8'};
|
||||
|
||||
|
||||
System.out.println("Testing DES key");
|
||||
SecretKeySpec skey = new SecretKeySpec(key, "DES");
|
||||
c = Cipher.getInstance("DES/CBC/PKCS5Padding", "SunJCE");
|
||||
SecretKeyFactory.getInstance("DES", "SunJCE").generateSecret(skey);
|
||||
|
||||
System.out.println("Testing DESede key");
|
||||
skey = new SecretKeySpec(key, "DESede");
|
||||
c = Cipher.getInstance("DESede/CBC/PKCS5Padding", "SunJCE");
|
||||
SecretKeyFactory.getInstance("TripleDES", "SunJCE").generateSecret(skey);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue