Commit 302e91da authored by chiaming2000's avatar chiaming2000
Browse files

Java API/Simulator: support CRC32 algorithm for tag

calculation/validation.
parent 63467900
Loading
Loading
Loading
Loading
+76 −0
Original line number Diff line number Diff line
/**
 * Copyright (C) 2014 Seagate Technology.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package com.seagate.kinetic.common.lib;

import java.nio.ByteBuffer;
import java.util.logging.Logger;
import java.util.zip.CRC32;
import java.util.zip.Checksum;

import com.google.protobuf.ByteString;

/**
 * Kinetic tag calculation with CRC32 checksum algorithm utils.
 * 
 * @author chiaming
 *
 */
public class Crc32TagCalc implements KineticTagCalc {

    private final static Logger logger = Logger.getLogger(Crc32TagCalc.class
            .getName());

    private static String myName = "CRC32";

    private Checksum crc32 = null;

    public Crc32TagCalc() {

        logger.info(myName + " checksum isntance instantiated ...");

        crc32 = new CRC32();
    }

    @Override
    public synchronized ByteString calculateTag(byte[] value) {

        try {
            // do update
            crc32.update(value, 0, value.length);

            // get checksum value
            long cval = crc32.getValue();

            // convert to byte[]
            byte[] checkSum = ByteBuffer.allocate(8).putLong(cval).array();

            // convert to bytestring and return
            return ByteString.copyFrom(checkSum);

        } finally {
            // reset crc32 instance
            crc32.reset();
        }
    }

    @Override
    public String getAlgoName() {
        return myName;
    }

}
+11 −0
Original line number Diff line number Diff line
package com.seagate.kinetic.common.lib;

import com.google.protobuf.ByteString;

public interface KineticTagCalc {

    public ByteString calculateTag(byte[] value);

    public String getAlgoName();

}
+88 −0
Original line number Diff line number Diff line
/**
 * Copyright (C) 2014 Seagate Technology.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package com.seagate.kinetic.common.lib;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.protobuf.ByteString;

/**
 * Kinetic tag calculation with Message digest algorithm utils.
 * 
 * @author chiaming
 *
 */
public class MessageDigestTagCalc implements KineticTagCalc {

    public static final String SHA1 = "SHA-1";

    public static final String SHA2 = "SHA-256";

    private final static Logger logger = Logger.getLogger(MessageDigestTagCalc.class
            .getName());

    private MessageDigest md = null;

    private String algoName = null;

    public MessageDigestTagCalc(String algoName) {

        this.algoName = algoName;
        this.init();
    }

    @Override
    public synchronized ByteString calculateTag(byte[] value) {

        // init to empty byte if null
        if (value == null) {
            value = new byte[0];
        }

        byte[] digest = null;
        ByteString tag = null;

        try {
            // calculate
            digest = md.digest(value);
            // to byte string
            tag = ByteString.copyFrom(digest);
        } finally {
            // reset for further use
            md.reset();
        }

        return tag;
    }

    private void init() {
        try {
            md = MessageDigest.getInstance(algoName);
        } catch (NoSuchAlgorithmException e) {
            logger.log(Level.WARNING, e.getMessage(), e);
        }
    }

    @Override
    public String getAlgoName() {
        return this.algoName;
    }
}
+110 −9
Original line number Diff line number Diff line
@@ -17,10 +17,13 @@
 */
package com.seagate.kinetic.common.lib;

import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.CRC32;
import java.util.zip.Checksum;

import com.google.protobuf.ByteString;
import com.seagate.kinetic.proto.Kinetic.Command.Algorithm;
@@ -35,43 +38,126 @@ public class MessageDigestUtil {
    private final static Logger logger = Logger
            .getLogger(MessageDigestUtil.class.getName());

    // SHA1 tag calc instance
    private static KineticTagCalc sha1Algo = null;

    // SHA2 tag calc instance
    private static KineticTagCalc sha2Algo = null;

    // CRC32 checksum instance
    private static KineticTagCalc crc32 = null;

    public static ByteString calculateTag(Algorithm algo, byte[] value) {

        byte[] digest = null;
        ByteString tag = null;

        // get md instance
        MessageDigest md = getInstance(algo);
        KineticTagCalc tagCalc = getInstance(algo);

        if (value == null) {
            value = new byte[0];
        }

        // calculate and return digest
        digest = md.digest(value);

        return ByteString.copyFrom(digest);
        tag = tagCalc.calculateTag(value);

        return tag;
    }

    public static boolean isSupportedForKineticJava(Algorithm algo) {

        switch (algo) {
        case SHA1:
            return true;
        case SHA2:
        case CRC32:
            return true;
        default:
            return false;
        }
    }

    public static MessageDigest getInstance(Algorithm algo) {
    /**
     * Get SHA1 instance.
     * 
     * @return SHA1 instance.
     */
    public static KineticTagCalc getSha1Instance() {

        // check if constructed
        if (sha1Algo != null) {
            return sha1Algo;
        }

        // sync
        synchronized (MessageDigestUtil.class) {

            // check if alread constructed
            if (sha1Algo == null) {
                sha1Algo = new MessageDigestTagCalc("SHA-1");
            }
        }

        return sha1Algo;
    }

    /**
     * Get SHA2 instance.
     * 
     * @return SHA2 instance.
     */
    public static KineticTagCalc getSha2Instance() {

        // check if constructed
        if (sha2Algo != null) {
            return sha2Algo;
        }

        // sync
        synchronized (MessageDigestUtil.class) {

            // check if already constructed
            if (sha2Algo == null) {
                sha2Algo = new MessageDigestTagCalc("SHA-256");
            }
        }

        return sha2Algo;
    }

    /**
     * Get SHA2 instance.
     * 
     * @return SHA2 instance.
     */
    public static KineticTagCalc getCrc32Instance() {

        // check if constructed
        if (crc32 != null) {
            return crc32;
        }

        // sync
        synchronized (MessageDigestUtil.class) {

            // check if already constructed
            if (crc32 == null) {
                crc32 = new Crc32TagCalc();
            }
        }

        return crc32;
    }


    public static KineticTagCalc getInstance(Algorithm algo) {

        switch (algo) {
        case SHA1:
            return getDigestInstance("SHA-1");
            return getSha1Instance();
        case SHA2:
            return getDigestInstance("SHA-256");
            return getSha2Instance();
        case CRC32:
            return getCrc32Instance();
        default:
            throw new java.lang.UnsupportedOperationException(
                    "unsupported algorithm., name = " + algo.name());
@@ -91,4 +177,19 @@ public class MessageDigestUtil {
        return md;
    }

    public static Checksum getCrc32ChecksumInstance() {
        return new CRC32();
    }

    public ByteString calculateTag(Checksum crc, byte[] value) {

        crc.update(value, 0, value.length);

        long csum = crc.getValue();

        ByteBuffer buffer = ByteBuffer.allocate(8);

        return ByteString.copyFrom(buffer.putLong(csum).array());
    }

}