From 7abe5c31d1dd2225bace01876dec6a4676d23d94 Mon Sep 17 00:00:00 2001 From: Jack Tjaden Date: Fri, 7 Feb 2025 16:14:11 -0700 Subject: [PATCH 1/3] JCE: Implements HMAC benchmarks with SHA and MD5 --- examples/provider/CryptoBenchmark.java | 79 +++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/examples/provider/CryptoBenchmark.java b/examples/provider/CryptoBenchmark.java index eab9902..c92dd49 100644 --- a/examples/provider/CryptoBenchmark.java +++ b/examples/provider/CryptoBenchmark.java @@ -1,4 +1,6 @@ import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; @@ -7,10 +9,10 @@ import java.security.SecureRandom; import java.security.Security; import java.security.spec.AlgorithmParameterSpec; -import java.util.*; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.spec.ECGenParameterSpec; +import java.util.*; import com.wolfssl.provider.jce.WolfCryptProvider; import com.wolfssl.wolfcrypt.FeatureDetect; @@ -403,6 +405,55 @@ private static void runECCBenchmark(String providerName, String curveName) throw printKeyGenResults(keyGenOps, elapsedTime, keyGenOp, providerName, "EC"); } + /* HMAC benchmark */ + private static void runHmacBenchmark(String algorithm, String providerName) throws Exception { + Mac mac; + byte[] testData; + double dataSizeMiB; + long startTime; + long endTime; + long elapsedTime; + double throughput; + + /* Generate test data */ + testData = generateTestData(DATA_SIZE); + + /* Initialize Mac with specific provider */ + mac = Mac.getInstance(algorithm, providerName); + + /* Initialize Mac with a random key */ + SecureRandom secureRandom = new SecureRandom(); + byte[] keyBytes = new byte[64]; + secureRandom.nextBytes(keyBytes); + SecretKeySpec key = new SecretKeySpec(keyBytes, algorithm); + mac.init(key); + + /* Warm up phase */ + for (int i = 0; i < WARMUP_ITERATIONS; i++) { + mac.update(testData); + mac.doFinal(); + } + + /* Benchmark */ + startTime = System.nanoTime(); + for (int i = 0; i < TEST_ITERATIONS; i++) { + mac.update(testData); + mac.doFinal(); + } + endTime = System.nanoTime(); + elapsedTime = (endTime - startTime) / TEST_ITERATIONS; + + dataSizeMiB = (DATA_SIZE * TEST_ITERATIONS) / (1024.0 * 1024.0); + throughput = (DATA_SIZE / (elapsedTime / 1000000000.0)) / (1024.0 * 1024.0); + + String testName = String.format("%s (%s)", algorithm, providerName); + System.out.printf(" %-40s %8.3f MiB took %.3f seconds, %8.3f MiB/s%n", + testName, dataSizeMiB, elapsedTime / 1_000_000_000.0, throughput); + + /* Store result */ + results.add(new BenchmarkResult(providerName, algorithm, throughput)); + } + public static void main(String[] args) { try { /* Check if Bouncy Castle is available */ @@ -494,6 +545,32 @@ public static void main(String[] args) { Security.removeProvider(provider.getName()); } + System.out.println("\n-----------------------------------------------------------------------------"); + System.out.println("HMAC Benchmark Results"); + System.out.println("-----------------------------------------------------------------------------"); + + for (int i = 0; i < providers.length; i++) { + Security.insertProviderAt(providers[i], 1); + + if (FeatureDetect.HmacMd5Enabled()) { + runHmacBenchmark("HmacMD5", providerNames[i]); + } + if (FeatureDetect.HmacShaEnabled()) { + runHmacBenchmark("HmacSHA1", providerNames[i]); + } + if (FeatureDetect.HmacSha256Enabled()) { + runHmacBenchmark("HmacSHA256", providerNames[i]); + } + if (FeatureDetect.HmacSha384Enabled()) { + runHmacBenchmark("HmacSHA384", providerNames[i]); + } + if (FeatureDetect.HmacSha512Enabled()) { + runHmacBenchmark("HmacSHA512", providerNames[i]); + } + + Security.removeProvider(providers[i].getName()); + } + System.out.println("-----------------------------------------------------------------------------\n"); /* Print delta table */ From e8c10e404f7644d8a187f4487544fda8dd48f8f6 Mon Sep 17 00:00:00 2001 From: Jack Tjaden Date: Fri, 7 Feb 2025 16:37:40 -0700 Subject: [PATCH 2/3] Removed hard coded key size to key sizes that match HMAC algorithms --- examples/provider/CryptoBenchmark.java | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/examples/provider/CryptoBenchmark.java b/examples/provider/CryptoBenchmark.java index c92dd49..bf54171 100644 --- a/examples/provider/CryptoBenchmark.java +++ b/examples/provider/CryptoBenchmark.java @@ -74,6 +74,24 @@ private static byte[] generateTestData(int size) { return new byte[size]; } + private static int getHmacKeySize(String algorithm) { + // Key sizes in bytes based on hash block sizes + switch (algorithm) { + case "HmacMD5": + return 64; + case "HmacSHA1": + return 64; + case "HmacSHA256": + return 64; + case "HmacSHA384": + return 128; + case "HmacSHA512": + return 128; + default: + throw new IllegalArgumentException("Unsupported HMAC algorithm: " + algorithm); + } + } + private static void printProviderInfo(Provider provider) { System.out.printf("%s version: %.1f%n", provider.getName(), provider.getVersion()); } @@ -421,9 +439,10 @@ private static void runHmacBenchmark(String algorithm, String providerName) thro /* Initialize Mac with specific provider */ mac = Mac.getInstance(algorithm, providerName); - /* Initialize Mac with a random key */ + /* Initialize Mac with a random key of appropriate length */ SecureRandom secureRandom = new SecureRandom(); - byte[] keyBytes = new byte[64]; + int keySize = getHmacKeySize(algorithm); + byte[] keyBytes = new byte[keySize]; secureRandom.nextBytes(keyBytes); SecretKeySpec key = new SecretKeySpec(keyBytes, algorithm); mac.init(key); From 98e85c974263640e17b774c10c9cdb0eeed96f9e Mon Sep 17 00:00:00 2001 From: Jack Tjaden Date: Fri, 14 Feb 2025 15:33:40 -0700 Subject: [PATCH 3/3] Changed fixed length key sizes to match test.c for HMAC test --- examples/provider/CryptoBenchmark.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/provider/CryptoBenchmark.java b/examples/provider/CryptoBenchmark.java index bf54171..01f5875 100644 --- a/examples/provider/CryptoBenchmark.java +++ b/examples/provider/CryptoBenchmark.java @@ -74,19 +74,19 @@ private static byte[] generateTestData(int size) { return new byte[size]; } + /* Bytes sizes from WC_*_DIGEST_SIZE for corresponding algorithm in text.c */ private static int getHmacKeySize(String algorithm) { - // Key sizes in bytes based on hash block sizes switch (algorithm) { case "HmacMD5": - return 64; + return 16; case "HmacSHA1": - return 64; + return 20; case "HmacSHA256": - return 64; + return 32; case "HmacSHA384": - return 128; + return 48; case "HmacSHA512": - return 128; + return 64; default: throw new IllegalArgumentException("Unsupported HMAC algorithm: " + algorithm); } @@ -176,7 +176,7 @@ private static void printDeltaTable() { } } System.out.println("--------------------------------------------------------------------------------"); - System.out.println("* Delta Value: MiB/s for symmetric ciphers, operations/second for RSA"); + System.out.println("* Delta Value: MiB/s for symmetric ciphers, operations/second for RSA and ECC"); } /* Run symmetric encryption/decryption benchmarks */