1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.core; 18 19 import junit.framework.Assert; 20 import junit.framework.TestCase; 21 22 import org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigest; 23 import org.bouncycastle.crypto.Digest; 24 import org.bouncycastle.crypto.ExtendedDigest; 25 import org.bouncycastle.crypto.digests.MD4Digest; 26 import org.bouncycastle.crypto.digests.MD5Digest; 27 import org.bouncycastle.crypto.digests.SHA1Digest; 28 import android.test.suitebuilder.annotation.LargeTest; 29 import android.test.suitebuilder.annotation.MediumTest; 30 31 /** 32 * Implements unit tests for our JNI wrapper around OpenSSL. We use the 33 * existing Bouncy Castle implementation as our test oracle. 34 */ 35 public class CryptoTest extends TestCase { 36 37 /** 38 * Processes the two given message digests for the same data and checks 39 * the results. Requirement is that the results must be equal, the digest 40 * implementations must have the same properties, and the new implementation 41 * must be faster than the old one. 42 * 43 * @param oldDigest The old digest implementation, provided by Bouncy Castle 44 * @param newDigest The new digest implementation, provided by OpenSSL 45 */ doTestMessageDigest(Digest oldDigest, Digest newDigest)46 public void doTestMessageDigest(Digest oldDigest, Digest newDigest) { 47 final int ITERATIONS = 10; 48 49 byte[] data = new byte[1024]; 50 51 byte[] oldHash = new byte[oldDigest.getDigestSize()]; 52 byte[] newHash = new byte[newDigest.getDigestSize()]; 53 54 Assert.assertEquals("Hash names must be equal", oldDigest.getAlgorithmName(), newDigest.getAlgorithmName()); 55 Assert.assertEquals("Hash sizes must be equal", oldHash.length, newHash.length); 56 Assert.assertEquals("Hash block sizes must be equal", ((ExtendedDigest)oldDigest).getByteLength(), ((ExtendedDigest)newDigest).getByteLength()); 57 for (int i = 0; i < data.length; i++) { 58 data[i] = (byte)i; 59 } 60 61 long oldTime = 0; 62 long newTime = 0; 63 64 for (int j = 0; j < ITERATIONS; j++) { 65 long t0 = System.currentTimeMillis(); 66 for (int i = 0; i < 4; i++) { 67 oldDigest.update(data, 0, data.length); 68 } 69 int oldLength = oldDigest.doFinal(oldHash, 0); 70 long t1 = System.currentTimeMillis(); 71 72 oldTime = oldTime + (t1 - t0); 73 74 long t2 = System.currentTimeMillis(); 75 for (int i = 0; i < 4; i++) { 76 newDigest.update(data, 0, data.length); 77 } 78 int newLength = newDigest.doFinal(newHash, 0); 79 long t3 = System.currentTimeMillis(); 80 81 newTime = newTime + (t3 - t2); 82 83 Assert.assertEquals("Hash sizes must be equal", oldLength, newLength); 84 85 for (int i = 0; i < oldLength; i++) { 86 Assert.assertEquals("Hashes[" + i + "] must be equal", oldHash[i], newHash[i]); 87 } 88 } 89 90 android.util.Log.d("CryptoTest", "Time for " + ITERATIONS + " x old hash processing: " + oldTime + " ms"); 91 android.util.Log.d("CryptoTest", "Time for " + ITERATIONS + " x new hash processing: " + newTime + " ms"); 92 93 // Assert.assertTrue("New hash should be faster", newTime < oldTime); 94 } 95 96 /** 97 * Tests the MD4 implementation. 98 */ 99 @MediumTest testMD4()100 public void testMD4() { 101 Digest oldDigest = new MD4Digest(); 102 Digest newDigest = OpenSSLMessageDigest.getInstance("MD4"); 103 doTestMessageDigest(oldDigest, newDigest); 104 } 105 106 /** 107 * Tests the MD5 implementation. 108 */ 109 @MediumTest testMD5()110 public void testMD5() { 111 Digest oldDigest = new MD5Digest(); 112 Digest newDigest = OpenSSLMessageDigest.getInstance("MD5"); 113 doTestMessageDigest(oldDigest, newDigest); 114 } 115 116 /** 117 * Tests the SHA-1 implementation. 118 */ 119 @MediumTest testSHA1()120 public void testSHA1() { 121 Digest oldDigest = new SHA1Digest(); 122 Digest newDigest = OpenSSLMessageDigest.getInstance("SHA-1"); 123 doTestMessageDigest(oldDigest, newDigest); 124 } 125 126 } 127