summaryrefslogtreecommitdiffstats
path: root/support/src
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2011-02-01 15:57:13 -0800
committerBrian Carlstrom <bdc@google.com>2011-02-01 20:58:35 -0800
commit4155a2498a57fb09e92815f8993a70c216ddc5ec (patch)
tree18508b14968d422c1d766ee8bf80b70c3b36c47d /support/src
parent54db500a1f77652e25d2789eb40dc46abc8ea8ea (diff)
downloadlibcore-4155a2498a57fb09e92815f8993a70c216ddc5ec.zip
libcore-4155a2498a57fb09e92815f8993a70c216ddc5ec.tar.gz
libcore-4155a2498a57fb09e92815f8993a70c216ddc5ec.tar.bz2
Performance improvements to NativeCrypto based MessageDigest API
NativeCrypto API improvements: - Move to using EVP_MD related native methods, some of which are derived from the EVP_MD_CTX versions with similar name. The new EVP_get_digestbyname allows one time lookup of the EVP_MD from the string name, avoiding doing it on every call to EVP_DigestInit. - EVP_MD_CTX_create is now removed, it is just done as part of EVP_DigestInit and EVP_VerifyInit to an extra JNI call. - EVP_DigestFinal now destroys the EVP_MD_CTX to avoid needing to make another call JNI call to EVP_MD_CTX_destroy. EVP_MD_CTX_destroy is kept for cases when EVP_DigestFinal is never called. luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java In addition to the improved NativeCrypto API to allow better performance for callers, the implementations use of throwExceptionIfNecessary was made conditional based on the status code from various operations, which had a noticeable impact on performance compared to android.security.MessageDigest luni/src/main/native/NativeCrypto.cpp Updated MessageDigest.getInstance default implementation to use new NativeCrypto API. An EVP_MD instance is looked up at class load time for a specific digest type and then used to call NativeCrypto.EVP_DigestInit as needed, avoiding a lookup of EVP_MD for each new digest. The EVP_MD is also for a one-time lookup the digest output size in bytes, to avoid native calls for engineGetDigestLength. Finally, the creation of the EVP_MD_CTX is now lazy, only created when needed, avoiding unnecessarily create/free in reset cases such as engineDigest. See also external/bouncycastle's OpenSSLDigest implementation which had similar optimizations. luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java OpenSSLSignature also used EVP_MD_CTX_create, and its EVP_VerifyInit was changed similar to EVP_DigestInit to internally allocate the EVP_MD_CTX on the call to init. luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSignature.java Fix test to work with arbitrary provider order luni/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java Fix CloseGuard warnings luni/src/test/java/tests/security/MessageDigestTest.java Bug: 3392028 Change-Id: Idb266ebc0918ffd5550e0f457784256400cd2ff0
Diffstat (limited to 'support/src')
-rw-r--r--support/src/test/java/tests/security/MessageDigestTest.java182
1 files changed, 39 insertions, 143 deletions
diff --git a/support/src/test/java/tests/security/MessageDigestTest.java b/support/src/test/java/tests/security/MessageDigestTest.java
index 9ae4881..5457688 100644
--- a/support/src/test/java/tests/security/MessageDigestTest.java
+++ b/support/src/test/java/tests/security/MessageDigestTest.java
@@ -15,16 +15,12 @@
*/
package tests.security;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-
-import junit.framework.TestCase;
-
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import junit.framework.TestCase;
+
public abstract class MessageDigestTest extends TestCase {
private String digestAlgorithmName;
@@ -65,14 +61,14 @@ public abstract class MessageDigestTest extends TestCase {
expected3 = null;
digest = null;
+ sourceData.close();
sourceData = null;
checkDigest = null;
System.gc();
}
- MessageDigest getMessageDigest()
- {
+ MessageDigest getMessageDigest() {
try {
return MessageDigest.getInstance(digestAlgorithmName);
} catch (NoSuchAlgorithmException e) {
@@ -81,59 +77,37 @@ public abstract class MessageDigestTest extends TestCase {
}
}
- InputStream getSourceData()
- {
- InputStream sourceStream = getClass().getResourceAsStream(
- digestAlgorithmName + ".data");
- assertNotNull("digest source data not found: " + digestAlgorithmName,
- sourceStream);
+ InputStream getSourceData() {
+ InputStream sourceStream = getClass().getResourceAsStream(digestAlgorithmName + ".data");
+ assertNotNull("digest source data not found: " + digestAlgorithmName, sourceStream);
return sourceStream;
}
- byte[] getCheckDigest()
- {
- InputStream checkDigestStream = getClass().getResourceAsStream(
- digestAlgorithmName + ".check");
+ byte[] getCheckDigest() {
+ InputStream checkDigestStream =
+ getClass().getResourceAsStream(digestAlgorithmName + ".check");
byte[] checkDigest = new byte[digest.getDigestLength()];
int read = 0;
int index = 0;
try {
- while ((read = checkDigestStream.read()) != -1)
- {
+ while ((read = checkDigestStream.read()) != -1) {
checkDigest[index++] = (byte)read;
}
+ checkDigestStream.close();
} catch (IOException e) {
fail("failed to read digest golden data: " + digestAlgorithmName);
}
return checkDigest;
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "update",
- args = {byte[].class,int.class,int.class}
- ),
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "digest",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "method",
- args = {}
- )
- })
- public void testMessageDigest1()
- {
+ public void testMessageDigest1() {
byte[] buf = new byte[128];
int read = 0;
try {
- while ((read = sourceData.read(buf)) != -1)
- {
+ while ((read = sourceData.read(buf)) != -1) {
digest.update(buf, 0, read);
}
+ sourceData.close();
} catch (IOException e) {
fail("failed to read digest data");
}
@@ -141,42 +115,22 @@ public abstract class MessageDigestTest extends TestCase {
byte[] computedDigest = digest.digest();
assertNotNull("computed digest is is null", computedDigest);
- assertEquals("digest length mismatch", checkDigest.length,
- computedDigest.length);
+ assertEquals("digest length mismatch", checkDigest.length, computedDigest.length);
- for (int i = 0; i < checkDigest.length; i++)
- {
+ for (int i = 0; i < checkDigest.length; i++) {
assertEquals("byte " + i + " of computed and check digest differ",
- checkDigest[i], computedDigest[i]);
+ checkDigest[i], computedDigest[i]);
}
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "update",
- args = {byte.class}
- ),
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "digest",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "method",
- args = {}
- )
- })
- public void testMessageDigest2()
- {
+ public void testMessageDigest2() {
int val;
try {
- while ((val = sourceData.read()) != -1)
- {
+ while ((val = sourceData.read()) != -1) {
digest.update((byte)val);
}
+ sourceData.close();
} catch (IOException e) {
fail("failed to read digest data");
}
@@ -184,12 +138,10 @@ public abstract class MessageDigestTest extends TestCase {
byte[] computedDigest = digest.digest();
assertNotNull("computed digest is is null", computedDigest);
- assertEquals("digest length mismatch", checkDigest.length,
- computedDigest.length);
- for (int i = 0; i < checkDigest.length; i++)
- {
+ assertEquals("digest length mismatch", checkDigest.length, computedDigest.length);
+ for (int i = 0; i < checkDigest.length; i++) {
assertEquals("byte " + i + " of computed and check digest differ",
- checkDigest[i], computedDigest[i]);
+ checkDigest[i], computedDigest[i]);
}
}
@@ -199,8 +151,12 @@ public abstract class MessageDigestTest extends TestCase {
* Official FIPS180-2 testcases
*/
- protected String source1, source2, source3;
- protected String expected1, expected2, expected3;
+ protected String source1;
+ protected String source2;
+ protected String source3;
+ protected String expected1;
+ protected String expected2;
+ protected String expected3;
String getLongMessage(int length) {
StringBuilder sourceBuilder = new StringBuilder(length);
@@ -210,23 +166,6 @@ public abstract class MessageDigestTest extends TestCase {
return sourceBuilder.toString();
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "update",
- args = {byte.class}
- ),
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "digest",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "method",
- args = {}
- )
- })
public void testfips180_2_singleblock() {
digest.update(source1.getBytes(), 0, source1.length());
@@ -236,33 +175,13 @@ public abstract class MessageDigestTest extends TestCase {
assertNotNull("computed digest is null", computedDigest);
StringBuilder sb = new StringBuilder();
- String res;
- for (int i = 0; i < computedDigest.length; i++)
- {
- res = Integer.toHexString(computedDigest[i] & 0xFF);
+ for (int i = 0; i < computedDigest.length; i++) {
+ String res = Integer.toHexString(computedDigest[i] & 0xFF);
sb.append((res.length() == 1 ? "0" : "") + res);
}
- assertEquals("computed and check digest differ", expected1,
- sb.toString());
+ assertEquals("computed and check digest differ", expected1, sb.toString());
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "update",
- args = {byte.class}
- ),
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "digest",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "method",
- args = {}
- )
- })
public void testfips180_2_multiblock() {
digest.update(source2.getBytes(), 0, source2.length());
@@ -272,33 +191,13 @@ public abstract class MessageDigestTest extends TestCase {
assertNotNull("computed digest is null", computedDigest);
StringBuilder sb = new StringBuilder();
- String res;
- for (int i = 0; i < computedDigest.length; i++)
- {
- res = Integer.toHexString(computedDigest[i] & 0xFF);
+ for (int i = 0; i < computedDigest.length; i++) {
+ String res = Integer.toHexString(computedDigest[i] & 0xFF);
sb.append((res.length() == 1 ? "0" : "") + res);
}
- assertEquals("computed and check digest differ", expected2,
- sb.toString());
+ assertEquals("computed and check digest differ", expected2, sb.toString());
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "update",
- args = {byte.class}
- ),
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "digest",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "method",
- args = {}
- )
- })
public void testfips180_2_longMessage() {
digest.update(source3.getBytes(), 0, source3.length());
@@ -308,13 +207,10 @@ public abstract class MessageDigestTest extends TestCase {
assertNotNull("computed digest is null", computedDigest);
StringBuilder sb = new StringBuilder();
- String res;
- for (int i = 0; i < computedDigest.length; i++)
- {
- res = Integer.toHexString(computedDigest[i] & 0xFF);
+ for (int i = 0; i < computedDigest.length; i++) {
+ String res = Integer.toHexString(computedDigest[i] & 0xFF);
sb.append((res.length() == 1 ? "0" : "") + res);
}
- assertEquals("computed and check digest differ", expected3,
- sb.toString());
+ assertEquals("computed and check digest differ", expected3, sb.toString());
}
}