package edu.washington.cs.oneswarm.f2f.datagram; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import org.gudy.azureus2.core3.util.SHA1Hasher; public abstract class DatagramEncrytionBase { public final static String ENCR_STD = "AES"; public final static String ENCR_ALGO = "AES/CTR/PKCS5Padding"; // public final static String HMAC_ALGO = "HmacSHA1"; public static final int HMAC_SIZE = 20; // Using sha1 instead of hmac-sha1. public final static int HMAC_KEY_LENGTH = 20; public final static int AES_KEY_LENGTH = 128; public final static int BLOCK_SIZE = AES_KEY_LENGTH / 8; public final static int SEQUENCE_NUMBER_BYTES = 8; public static int TYPE_AES_CRT_128__SHA1 = 0; protected final SHA1Hasher sha1; public DatagramEncrytionBase() { sha1 = new SHA1Hasher(); } public int getCryptoAlgo() { return TYPE_AES_CRT_128__SHA1; } protected byte[] hmac_key; protected IvParameterSpec ivSpec; protected Key key; protected Cipher cipher; protected static SecretKey createKeyForAES(int bitLength, SecureRandom random) throws NoSuchAlgorithmException, NoSuchProviderException { KeyGenerator generator = KeyGenerator.getInstance(ENCR_STD); generator.init(AES_KEY_LENGTH, random); return generator.generateKey(); } protected static IvParameterSpec createCtrIvForAES(long sequenceNumber, SecureRandom random) { byte[] ivBytes = new byte[16]; random.nextBytes(ivBytes); return setSequenceNumber(sequenceNumber, ivBytes); } protected static IvParameterSpec setSequenceNumber(long sequenceNumber, byte[] ivBytes) { ByteBuffer buf = ByteBuffer.wrap(ivBytes); buf.order(ByteOrder.BIG_ENDIAN); // Sun implements counter as // big-endian buf.position(8); // Counter is the last 8 bytes buf.putLong(sequenceNumber); return new IvParameterSpec(ivBytes); } protected static long getSequenceNumber(IvParameterSpec ivSpec) { ByteBuffer buf = ByteBuffer.wrap(ivSpec.getIV()); buf.order(ByteOrder.BIG_ENDIAN); // Sun implements counter as // big-endian buf.position(8); // Counter is the last 8 bytes return buf.getLong(); } }