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.
212 lines
7.7 KiB
Java
212 lines
7.7 KiB
Java
/*
|
|
* Copyright (c) 2024, 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 jdk.test.lib.artifacts.Artifact;
|
|
import jdk.test.lib.artifacts.ArtifactResolver;
|
|
import jdk.test.lib.json.JSONValue;
|
|
import jtreg.SkippedException;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.nio.file.Path;
|
|
import java.security.Provider;
|
|
import java.security.Security;
|
|
import java.util.zip.ZipEntry;
|
|
import java.util.zip.ZipFile;
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8342442 8345057
|
|
* @summary Test default implementation. Use othervm because
|
|
* ML_DSA_Impls.version might be modified
|
|
* @library /test/lib
|
|
* @modules java.base/sun.security.provider
|
|
* java.base/sun.security.util
|
|
* java.base/com.sun.crypto.provider
|
|
* @run main/othervm/timeout=480 Launcher
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8342442 8345057
|
|
* @summary Test verifying the intrinsic implementation.
|
|
* @library /test/lib
|
|
* @modules java.base/sun.security.provider
|
|
* java.base/sun.security.util
|
|
* java.base/com.sun.crypto.provider
|
|
* @run main/othervm/timeout=480 -Xcomp Launcher
|
|
*/
|
|
|
|
/// This test runs on `internalProjection.json`-style files generated by NIST's
|
|
/// ACVP Server ([GitHub repository](https://github.com/usnistgov/ACVP-Server)).
|
|
/// These files are included in ZIP archives available under the
|
|
/// [tags section](https://github.com/usnistgov/ACVP-Server/tags)
|
|
/// of the repository.
|
|
///
|
|
/// The zip archive is either hosted on artifactory server or
|
|
/// specified with local path to the test.
|
|
/// The test looks for test data files in the archive listed with `TEST_FILES`.
|
|
///
|
|
/// These tests are currently compatible with ACVP version 1.1.0.38.
|
|
///
|
|
/// By default, the test uses system-preferred implementations.
|
|
/// If you want to test a specific provider, set the
|
|
/// `test.acvp.provider` test property. The provider must be
|
|
/// registered.
|
|
///
|
|
/// Tests for each algorithm must be compliant to its specification linked from
|
|
/// [https://github.com/usnistgov/ACVP?tab=readme-ov-file#supported-algorithms].
|
|
///
|
|
/// Example:
|
|
///
|
|
/// Run locally with ArtifactResolver
|
|
/// ```
|
|
/// jtreg -Djdk.test.lib.artifacts.ACVP-Server=<path-to-archive-file>
|
|
/// ```
|
|
/// OR host the zip archive on artifactory server.
|
|
///
|
|
|
|
public class Launcher {
|
|
|
|
private static final Provider PROVIDER;
|
|
|
|
private static final String ACVP_BUNDLE_LOC = "jpg.tests.jdk";
|
|
private static final String ACVP_BUNDLE_NAME = "ACVP-Server";
|
|
private static final String ACVP_BUNDLE_VERSION = "1.1.0.38";
|
|
// Zip archive entry name, do not update to use File.separator
|
|
private static final String[] TEST_FILES = {
|
|
"gen-val/json-files/ML-DSA-keyGen-FIPS204/internalProjection.json",
|
|
"gen-val/json-files/ML-DSA-sigGen-FIPS204/internalProjection.json",
|
|
"gen-val/json-files/ML-DSA-sigVer-FIPS204/internalProjection.json",
|
|
"gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json",
|
|
"gen-val/json-files/ML-KEM-keyGen-FIPS203/internalProjection.json"
|
|
};
|
|
|
|
private static int count = 0;
|
|
private static int invalidTest = 0;
|
|
private static int unsupportedTest = 0;
|
|
|
|
static {
|
|
var provProp = System.getProperty("test.acvp.provider");
|
|
if (provProp != null) {
|
|
var p = Security.getProvider(provProp);
|
|
if (p == null) {
|
|
System.err.println(provProp + " is not a registered provider name");
|
|
throw new RuntimeException(provProp + " is not a registered provider name");
|
|
}
|
|
PROVIDER = p;
|
|
} else {
|
|
PROVIDER = null;
|
|
}
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
|
|
Path archivePath = null;
|
|
try {
|
|
archivePath = ArtifactResolver.fetchOne(ACVP_SERVER_TESTS.class);
|
|
} catch (IOException e) {
|
|
if (e.getMessage().contains("Cannot find the artifact ACVP-Server")) {
|
|
throw new SkippedException("ACVP-Server not available.");
|
|
}
|
|
}
|
|
System.out.println("Data path: " + archivePath);
|
|
|
|
if (PROVIDER != null) {
|
|
System.out.println("Provider: " + PROVIDER.getName());
|
|
}
|
|
|
|
// Read test data files from zip archive
|
|
try (ZipFile zf = new ZipFile(archivePath.toFile())) {
|
|
for (String testFile : TEST_FILES) {
|
|
// Zip archive entry name, do not update to use File.separator
|
|
String fullEntryName = ACVP_BUNDLE_NAME + "-" + ACVP_BUNDLE_VERSION + "/" + testFile;
|
|
System.out.println("Find and test with: " + fullEntryName);
|
|
ZipEntry ze = zf.getEntry(fullEntryName);
|
|
if (ze != null) {
|
|
run(zf.getInputStream(ze));
|
|
} else {
|
|
throw new RuntimeException("Entry not found: " + fullEntryName);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count > 0) {
|
|
System.out.println();
|
|
System.out.println("Test completed: " + count);
|
|
System.out.println("Invalid tests: " + invalidTest);
|
|
System.out.println("Unsupported tests: " + unsupportedTest);
|
|
} else {
|
|
throw new RuntimeException("No supported test found");
|
|
}
|
|
|
|
if (invalidTest != 0 || unsupportedTest != 0){
|
|
throw new RuntimeException("Invalid or Unsupported tests found");
|
|
}
|
|
}
|
|
|
|
static void run(InputStream test) {
|
|
try {
|
|
JSONValue kat;
|
|
try (test) {
|
|
kat = JSONValue.parse(new String(test.readAllBytes()));
|
|
} catch (Exception e) {
|
|
System.out.println("Warning: cannot parse " + test + ". Skipped");
|
|
invalidTest++;
|
|
return;
|
|
}
|
|
var alg = kat.get("algorithm").asString();
|
|
switch (alg) {
|
|
case "ML-DSA" -> {
|
|
ML_DSA_Test.run(kat, PROVIDER);
|
|
count++;
|
|
}
|
|
case "ML-KEM" -> {
|
|
ML_KEM_Test.run(kat, PROVIDER);
|
|
count++;
|
|
}
|
|
case "SHA2-256", "SHA2-224", "SHA3-256", "SHA3-224" -> {
|
|
SHA_Test.run(kat, PROVIDER);
|
|
count++;
|
|
}
|
|
default -> {
|
|
System.out.println("Skipped unsupported algorithm: " + alg);
|
|
unsupportedTest++;
|
|
}
|
|
}
|
|
} catch (RuntimeException re) {
|
|
throw re;
|
|
} catch (Exception e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@Artifact(
|
|
organization = ACVP_BUNDLE_LOC,
|
|
name = ACVP_BUNDLE_NAME,
|
|
revision = ACVP_BUNDLE_VERSION,
|
|
extension = "zip",
|
|
unpack = false)
|
|
private static class ACVP_SERVER_TESTS {
|
|
}
|
|
}
|