Page 1 of 1

The ALgorithm of Hash Sample Code

Posted: Sat Jul 09, 2016 6:06 am
by JavaCardOS
The following code is the ALgorithm of Hash Sample Code in JavaCard API Specification.

You can copy and use it directly or you can download the JCIDE project from the attachment and build it.


Code: Select all

/*
 * @file  HashSample.java
 * @version v1.0
 * Package AID: 4A617661436172644F53
 * Applet AID:  4A617661436172644F5305
 * @brief The ALgorithm of Hash Sample Code in JavaCard API Specification
 * @comment The purpose of this example is only used to show the usage of API functions and there is no practical significance.
 * @copyright Copyright(C) 2016 JavaCardOS Technologies Co., Ltd. All rights reserved.
 */
 
package JavaCardOS.Sample.Algorithm;

import javacard.framework.*;
import javacard.security.*;
import javacardx.crypto.*;

public class HashSample extends Applet
{
   private static final byte INS_GEN_HASH = (byte)0x50;

    private byte[] flags;
    private static final short OFF_INS    = (short)0;
    private static final short OFF_P1     = (short)1;
    private static final short OFF_P2     = (short)2;
    private static final short OFF_LEN    = (short)3;
    private static final short FLAGS_SIZE = (short)5;
   
   private InitializedMessageDigest sha1;
    private InitializedMessageDigest sha256;
    private InitializedMessageDigest sha512;
   
    public HashSample()
    {
        flags = JCSystem.makeTransientByteArray(FLAGS_SIZE, JCSystem.CLEAR_ON_DESELECT);
        //Creates a InitializedMessageDigest object instance of the ALG_SHA algorithm.
        sha1 = MessageDigest.getInitializedMessageDigestInstance(MessageDigest.ALG_SHA, false);
        //Creates a InitializedMessageDigest object instance of the ALG_SHA_256 algorithm.
        sha256 = MessageDigest.getInitializedMessageDigestInstance(MessageDigest.ALG_SHA_256, false);
        //Creates a InitializedMessageDigest object instance of the ALG_SHA_512 algorithm.
        sha512 = MessageDigest.getInitializedMessageDigestInstance(MessageDigest.ALG_SHA_512, false);
        JCSystem.requestObjectDeletion();
    }
   public static void install(byte[] bArray, short bOffset, byte bLength)
   {
      new HashSample().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
   }

   public void process(APDU apdu)
   {
      if (selectingApplet())
      {
         return;
      }

      byte[] buf = apdu.getBuffer();
      short len = apdu.setIncomingAndReceive();
      switch (buf[ISO7816.OFFSET_INS])
      {
      case (byte)INS_GEN_HASH:
         generateHash(apdu, len);
         break;
      default:
         ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
      }
   }
   
   //Generate Hash
    private void generateHash(APDU apdu, short len)
    {
        byte[] buffer = apdu.getBuffer();
        boolean hasMoreCmd = (buffer[ISO7816.OFFSET_P1] & 0x80) != 0;
        InitializedMessageDigest hash = null;
        short resultLen = 0;
        short offset = ISO7816.OFFSET_CDATA;
        switch (buffer[ISO7816.OFFSET_P1] & 0x7f)
        {
        case 0:
            hash = sha1;
            resultLen = MessageDigest.LENGTH_SHA;
            break;
        case 1:
            hash = sha256;
            resultLen = MessageDigest.LENGTH_SHA_256;
            break;
        case 2:
            hash = sha512;
            resultLen = MessageDigest.LENGTH_SHA_512;
            if (hash == null)
            {
                ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
            }
            break;
        default:
            ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            break;
        }

        if (buffer[ISO7816.OFFSET_P2] == 0) //first block
        {
           //Reset the MessageDigest object to the initial state.
            hash.reset();
        }

        if (hasMoreCmd)
        {
           //Accumulate a hash of the input data.
            hash.update(buffer, offset, len);
        }
        else
        {
           //Generate a hash of all the input data.
            short ret = hash.doFinal(buffer, offset, len, buffer, (short)0);
            Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
            apdu.setOutgoingAndSend((short)0, ret);
        }
    }

}



Note:
The purpose of this example is only used to show the usage of Hash algorithm .