/*
* 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.framework.JCSystem;
import javacard.security.AESKey;
import javacard.security.CryptoException;
import javacard.security.DESKey;
import javacard.security.HMACKey;
import javacard.security.KeyBuilder;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.engines.DESEngine;
import org.bouncycastle.crypto.engines.DESedeEngine;
import org.bouncycastle.crypto.params.KeyParameter;
/**
* Implementation of secret key.
* @see DESKey
* @see AESKey
*/
public class SymmetricKeyImpl extends KeyImpl implements DESKey, AESKey, HMACKey {
protected ByteContainer key;
/**
* Create new instance of <code>SymmetricKeyImpl</code>
* @param keyType keyType interface
* @param keySize keySize in bits
* @see KeyBuilder
*/
public SymmetricKeyImpl(byte keyType, short keySize) {
this.size = keySize;
this.type = keyType;
switch (keyType) {
case KeyBuilder.TYPE_DES_TRANSIENT_DESELECT:
case KeyBuilder.TYPE_AES_TRANSIENT_DESELECT:
case KeyBuilder.TYPE_HMAC_TRANSIENT_DESELECT:
key = new ByteContainer(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
break;
case KeyBuilder.TYPE_DES_TRANSIENT_RESET:
case KeyBuilder.TYPE_AES_TRANSIENT_RESET:
case KeyBuilder.TYPE_HMAC_TRANSIENT_RESET:
key = new ByteContainer(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
break;
case KeyBuilder.TYPE_DES:
case KeyBuilder.TYPE_AES:
case KeyBuilder.TYPE_HMAC:
key = new ByteContainer(JCSystem.MEMORY_TYPE_PERSISTENT);
break;
}
}
/**
* Clears the key and sets its initialized state to false.
*/
public void clearKey() {
key.clear();
}
/**
* Sets the <code>Key</code> data.
*/
public void setKey(byte[] keyData, short kOff) throws CryptoException, NullPointerException, ArrayIndexOutOfBoundsException {
key.setBytes(keyData, kOff, (short) (size / 8));
}
/**
* Sets the <code>Key</code> data.
*/
public void setKey(byte[] keyData, short kOff, short kLen) throws CryptoException, NullPointerException, ArrayIndexOutOfBoundsException {
key.setBytes(keyData, kOff, kLen);
}
/**
* Returns the <code>Key</code> data in plain text.
*/
public byte getKey(byte[] keyData, short kOff) {
return (byte) key.getBytes(keyData, kOff);
}
public void setParameters(CipherParameters params){
key.setBytes(((KeyParameter)params).getKey());
}
/**
* Return the BouncyCastle <code>KeyParameter</code> of the key
* @return parameter of the key
* @throws CryptoException if key not initialized
* @see KeyParameter
*/
public CipherParameters getParameters() throws CryptoException {
if (!key.isInitialized()) {
CryptoException.throwIt(CryptoException.UNINITIALIZED_KEY);
}
return new KeyParameter(key.getBytes(JCSystem.CLEAR_ON_RESET));
}
/**
* Return the BouncyCastle <code>BlockCipher</code> for using with this key
* @return <code>BlockCipher</code> for this key, or null for HMACKey
* @throws CryptoException if key not initialized
* @see BlockCipher
*/
public BlockCipher getCipher() throws CryptoException {
if (!key.isInitialized()) {
CryptoException.throwIt(CryptoException.UNINITIALIZED_KEY);
}
BlockCipher cipher = null;
switch (type) {
case KeyBuilder.TYPE_DES:
case KeyBuilder.TYPE_DES_TRANSIENT_DESELECT:
case KeyBuilder.TYPE_DES_TRANSIENT_RESET:
if (size == KeyBuilder.LENGTH_DES) {
cipher = new DESEngine();
}
if (size == KeyBuilder.LENGTH_DES3_2KEY || size == KeyBuilder.LENGTH_DES3_3KEY) {
cipher = new DESedeEngine();
}
break;
case KeyBuilder.TYPE_AES:
case KeyBuilder.TYPE_AES_TRANSIENT_DESELECT:
case KeyBuilder.TYPE_AES_TRANSIENT_RESET:
cipher = new AESEngine();
break;
}
return cipher;
}
public boolean isInitialized() {
return key.isInitialized();
}
public KeyGenerationParameters getKeyGenerationParameters(SecureRandom rnd) {
return null;
}
}