com.licel.jcardsim.crypto.MessageDigestImplTest.java Source code

Java tutorial

Introduction

Here is the source code for com.licel.jcardsim.crypto.MessageDigestImplTest.java

Source

/*
 * Copyright 2011 Licel LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.licel.jcardsim.crypto;

import java.security.SecureRandom;

import javacard.security.MessageDigest;
import junit.framework.TestCase;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.encoders.Hex;

/**
 * Test for <code>MessageDigestImpl</code>
 * Test data from NXP JCOP31-36 JavaCard
 */
public class MessageDigestImplTest extends TestCase {

    static final String MESSAGE1 = "F9607F6E66B4162C";
    static final String MESSAGE2 = "26C69FC4C14399A399B5B28AD9CC5B91796BC2565C5580BAC1BE10808F71949D8B";
    // card response with algorithm MD5
    static final String MD_1_NXP_MD5 = "3A43CC845A3DF85404A97407877D3A77";
    static final String MD_2_NXP_MD5 = "5919172BA50F4944339260067E09387A";
    // card response with algorithm SHA1
    static final String MD_1_NXP_SHA1 = "94FF92DC796929290990BA74F4B125F04F9B510A";
    static final String MD_2_NXP_SHA1 = "01793FF98B954C3F60F276B179186C499F619A9D";
    // card response with algorithm SHA256
    static final String MD_1_NXP_SHA256 = "E700E0E6E5A4F3FF05CCBD4DA9CDBBEC712189DE65EF1ED19C351F7966270EF0";
    static final String MD_2_NXP_SHA256 = "17CB067C5E384B85DF370B96A5C91817D908F0C760CB2D7539EF8B9A7C02AB80";
    // NIST SHA-384 SHA ETALON MESSAGES
    static final String MESSAGE_64_NIST_SHA384 = "DE60275BDAFCE4B1";
    static final String MESSAGE_256_NIST_SHA384 = "BE01E520E69F04174CCF95455B1C81445298264D9ADC4958574A52843D95B8BA";
    // NIST SHA-384 ETALON DIGESTS
    static final String MD_64_NIST_SHA384 = "A3D861D866C1362423EB21C6BEC8E44B74CE993C55BAA2B6640567560EBECDAEDA07183DBBBD95E0F522CAEE5DDBDAF0";
    static final String MD_256_NIST_SHA384 = "C5CF54B8E3105B1C7BF7A43754D915B0947F28B6DC94A019182929B5C848E11441C9E4E90C7449F4C3CD12954F0F5D99";
    // NIST SHA-512 ETALON MESSAGES
    static final String MESSAGE_64_NIST_SHA512 = "6F8D58B7CAB1888C";
    static final String MESSAGE_256_NIST_SHA512 = "8CCB08D2A1A282AA8CC99902ECAF0F67A9F21CFFE28005CB27FCF129E963F99D";
    // NIST SHA-512 ETALON DIGESTS
    static final String MD_64_NIST_SHA512 = "A3941DEF2803C8DFC08F20C06BA7E9A332AE0C67E47AE57365C243EF40059B11BE22C91DA6A80C2CFF0742A8F4BCD941BDEE0B861EC872B215433CE8DCF3C031";
    static final String MD_256_NIST_SHA512 = "4551DEF2F9127386EEA8D4DAE1EA8D8E49B2ADD0509F27CCBCE7D9E950AC7DB01D5BCA579C271B9F2D806730D88F58252FD0C2587851C3AC8A0E72B4E1DC0DA6";

    MessageDigestImpl engineMD5 = new MessageDigestImpl(MessageDigest.ALG_MD5);
    MessageDigestImpl engineRIPEMD160 = new MessageDigestImpl(MessageDigest.ALG_RIPEMD160);
    MessageDigestImpl engineSHA1 = new MessageDigestImpl(MessageDigest.ALG_SHA);
    MessageDigestImpl engineSHA256 = new MessageDigestImpl(MessageDigest.ALG_SHA_256);
    MessageDigestImpl engineSHA384 = new MessageDigestImpl(MessageDigest.ALG_SHA_384);
    MessageDigestImpl engineSHA512 = new MessageDigestImpl(MessageDigest.ALG_SHA_512);

    SecureRandom rnd = new SecureRandom();

    public MessageDigestImplTest(String testName) {
        super(testName);
    }

    protected void setUp() throws Exception {
        super.setUp();
    }

    protected void tearDown() throws Exception {
        super.tearDown();
    }

    /**
     * Test of getAlgorithm method, of class MessageDigestImpl.
     */
    public void testGetAlgorithm() {
        System.out.println("getAlgorithm");
        // md5
        byte expResult = MessageDigest.ALG_MD5;
        byte result = engineMD5.getAlgorithm();
        assertEquals(expResult, result);
        // sha1
        expResult = MessageDigest.ALG_SHA;
        result = engineSHA1.getAlgorithm();
        assertEquals(expResult, result);
        // sha256
        expResult = MessageDigest.ALG_SHA_256;
        result = engineSHA256.getAlgorithm();
        assertEquals(expResult, result);
        // sha384
        expResult = MessageDigest.ALG_SHA_384;
        result = engineSHA384.getAlgorithm();
        assertEquals(expResult, result);
        // sha512
        expResult = MessageDigest.ALG_SHA_512;
        result = engineSHA512.getAlgorithm();
        assertEquals(expResult, result);
    }

    /**
     * Test of getLength method, of class MessageDigestImpl.
     */
    public void testGetLength() {
        System.out.println("getLength");
        // md5
        assertEquals(engineMD5.getLength(), MessageDigest.LENGTH_MD5);
        // ripemd160
        assertEquals(engineRIPEMD160.getLength(), MessageDigest.LENGTH_RIPEMD160);
        // sha1
        assertEquals(engineSHA1.getLength(), MessageDigest.LENGTH_SHA);
        // sha256
        assertEquals(engineSHA256.getLength(), MessageDigest.LENGTH_SHA_256);
        // sha384
        assertEquals(engineSHA384.getLength(), MessageDigest.LENGTH_SHA_384);
        // sha512
        assertEquals(engineSHA512.getLength(), MessageDigest.LENGTH_SHA_512);
    }

    /**
     * Test MD5 algorithm with card response
     */
    public void testMD5() {
        System.out.println("test MD5 doFinal()");
        testEngineDoFinal(engineMD5, Hex.decode(MESSAGE1), Hex.decode(MD_1_NXP_MD5));
        System.out.println("test MD5 doUpdate() + doFinal()");
        testEngineDoUpdateFinal(engineMD5, Hex.decode(MESSAGE2), Hex.decode(MD_2_NXP_MD5));
    }

    /**
     * Test SHA1 algorithm with card response
     */
    public void testSHA() {
        System.out.println("test SHA1 doFinal()");
        testEngineDoFinal(engineSHA1, Hex.decode(MESSAGE1), Hex.decode(MD_1_NXP_SHA1));
        System.out.println("test SHA1 doUpdate() + doFinal()");
        testEngineDoUpdateFinal(engineSHA1, Hex.decode(MESSAGE2), Hex.decode(MD_2_NXP_SHA1));
    }

    /**
     * Test SHA256 algorithm with card response
     */
    public void testSHA256() {
        System.out.println("test SHA256 doFinal()");
        testEngineDoFinal(engineSHA256, Hex.decode(MESSAGE1), Hex.decode(MD_1_NXP_SHA256));
        System.out.println("test SHA256 doUpdate() + doFinal()");
        testEngineDoUpdateFinal(engineSHA256, Hex.decode(MESSAGE2), Hex.decode(MD_2_NXP_SHA256));
    }

    /**
     * Test SHA384 algorithm with card response
     */
    public void testSHA384() {
        System.out.println("test SHA384 doFinal()");
        testEngineDoFinal(engineSHA384, Hex.decode(MESSAGE_64_NIST_SHA384), Hex.decode(MD_64_NIST_SHA384));
        System.out.println("test SHA384 doUpdate() + doFinal()");
        testEngineDoUpdateFinal(engineSHA384, Hex.decode(MESSAGE_256_NIST_SHA384), Hex.decode(MD_256_NIST_SHA384));
    }

    /**
     * Test SHA512 algorithm with card response
     */
    public void testSHA512() {
        System.out.println("test SHA512 doFinal()");
        testEngineDoFinal(engineSHA512, Hex.decode(MESSAGE_64_NIST_SHA512), Hex.decode(MD_64_NIST_SHA512));
        System.out.println("test SHA512 doUpdate() + doFinal()");
        testEngineDoUpdateFinal(engineSHA512, Hex.decode(MESSAGE_256_NIST_SHA512), Hex.decode(MD_256_NIST_SHA512));
    }

    /**
     * Test method <code>doFinal</code>
     * @param engine tested engine
     * @param msg byte array contains etalon message
     * @param etalonDigest byte array contains etalon digest
     */
    public void testEngineDoFinal(MessageDigest engine, byte[] msg, byte[] etalonDigest) {
        byte[] digest = new byte[engine.getLength()];
        engine.doFinal(msg, (short) 0, (short) msg.length, digest, (short) 0);
        assertEquals(true, Arrays.areEqual(etalonDigest, digest));
    }

    /**
     * Test sequence method's calls <code>doUpdate();doFinal()</code>
     * @param engine tested engine
     * @param msg byte array contains etalon message
     * @param etalonDigest byte array contains etalon digest
     */
    public void testEngineDoUpdateFinal(MessageDigest engine, byte[] msg, byte[] etalonDigest) {
        byte[] digest = new byte[engine.getLength()];
        engine.update(msg, (short) 0, (short) 7);
        engine.doFinal(msg, (short) 7, (short) (msg.length - 7), digest, (short) 0);
        assertEquals(true, Arrays.areEqual(etalonDigest, digest));
    }

    /**
     * Test of setInitialDigest method, of class MessageDigestImpl.
     */
    public void testSetInitialDigest() {
        byte[] initialDigestBuf = new byte[128];
        byte[] inputData = new byte[254];
        rnd.nextBytes(inputData);

        MessageDigestImpl[] digests = new MessageDigestImpl[] { engineSHA1, engineMD5, engineRIPEMD160,
                engineSHA256, engineSHA384, engineSHA512 };

        for (short i = 0; i < digests.length; i++) {
            System.out.println("testSetInitialDigest() - " + digests[i].getAlgorithm());
            byte[] digest = new byte[digests[i].getLength()];
            byte[] etalonDigest = new byte[digests[i].getLength()];
            // calc first part
            short part = digests[i].getBlockSize();
            digests[i].update(inputData, (short) 0, part);
            short initialDigestOff = (short) rnd.nextInt(initialDigestBuf.length - digests[i].getLength());
            digests[i].getIntermediateDigest(initialDigestBuf, initialDigestOff);
            // doFinal
            digests[i].doFinal(inputData, part, (short) (inputData.length - part), digest, (short) 0);
            // etalon
            digests[i].reset();
            digests[i].update(inputData, (short) 0, part);
            digests[i].doFinal(inputData, part, (short) (inputData.length - part), etalonDigest, (short) 0);
            assertEquals(true, Arrays.areEqual(etalonDigest, digest));
        }
    }

}