All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javacardx.crypto.Cipher Maven / Gradle / Ivy

The newest version!
/*
 * 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 javacardx.crypto;

import com.licel.jcardsim.crypto.AssymetricCipherImpl;
import com.licel.jcardsim.crypto.SymmetricCipherImpl;
import javacard.security.CryptoException;
import javacard.security.Key;

/**
 * The Cipher class is the abstract base class for Cipher algorithms. Implementations of Cipher
 * algorithms must extend this class and implement all the abstract methods.
 * 

The term "pad" is used in the public key cipher algorithms below to refer to all the * operations specified in the referenced scheme to transform the message block into * the cipher block size. *

The asymmetric key algorithms encrypt using either a public key (to cipher) or a private key (to sign). * In addition they decrypt using the either a private key (to decipher) or a public key (to verify). *

A tear or card reset event resets an initialized * Cipher object to the state it was in when previously initialized * via a call to init(). For algorithms which support keys with transient * key data sets, such as DES, triple DES and AES, * the Cipher object key becomes * uninitialized on clear events associated with the Key * object used to initialize the Cipher object. *

Even if a transaction is in progress, update of intermediate result state in the implementation * instance shall not participate in the transaction.
*

Note: *

    *
  • On a tear or card reset event, the AES, DES, and triple DES algorithms in CBC mode * reset the initial vector(IV) to 0. The initial vector(IV) can be re-initialized using the * init(Key, byte, byte[], short, short) method. *
*/ public abstract class Cipher { /** * Cipher algorithm ALG_DES_CBC_NOPAD provides a cipher using DES in CBC mode * or triple DES in outer CBC mode, and * does not pad input data. If the input data is not (8-byte) block * aligned it throws CryptoException with the reason code ILLEGAL_USE. */ public static final byte ALG_DES_CBC_NOPAD = 1; /** * Cipher algorithm ALG_DES_CBC_ISO9797_M1 provides a cipher using DES * in CBC mode or triple DES in outer CBC mode, and pads * input data according to the ISO 9797 method 1 scheme. */ public static final byte ALG_DES_CBC_ISO9797_M1 = 2; /** * Cipher algorithm ALG_DES_CBC_ISO9797_M2 provides a cipher using DES * in CBC mode or triple DES in outer CBC mode, and pads * input data according to the ISO 9797 method 2 (ISO 7816-4, EMV'96) scheme. */ public static final byte ALG_DES_CBC_ISO9797_M2 = 3; /** * Cipher algorithm ALG_DES_CBC_PKCS5 provides a cipher using DES * in CBC mode or triple DES in outer CBC mode, and pads * input data according to the PKCS#5 scheme. */ public static final byte ALG_DES_CBC_PKCS5 = 4; /** * Cipher algorithm ALG_DES_ECB_NOPAD provides a cipher using DES in ECB mode, * and does not pad input data. If the input data is not (8-byte) block * aligned it throws CryptoException with the reason code ILLEGAL_USE. */ public static final byte ALG_DES_ECB_NOPAD = 5; /** * Cipher algorithm ALG_DES_ECB_ISO9797_M1 provides a cipher using DES * in ECB mode, and pads * input data according to the ISO 9797 method 1 scheme. */ public static final byte ALG_DES_ECB_ISO9797_M1 = 6; /** * Cipher algorithm ALG_DES_ECB_ISO9797_M2 provides a cipher using DES * in ECB mode, and pads * input data according to the ISO 9797 method 2 (ISO 7816-4, EMV'96) scheme. */ public static final byte ALG_DES_ECB_ISO9797_M2 = 7; /** * Cipher algorithm ALG_DES_ECB_PKCS5 provides a cipher using DES * in ECB mode, and pads * input data according to the PKCS#5 scheme. */ public static final byte ALG_DES_ECB_PKCS5 = 8; /** * Cipher algorithm ALG_RSA_ISO14888 provides a cipher using RSA, and pads * input data according to the ISO 14888 scheme. */ public static final byte ALG_RSA_ISO14888 = 9; /** * Cipher algorithm ALG_RSA_PKCS1 provides a cipher using RSA, and pads * input data according to the PKCS#1 (v1.5) scheme. *

Note: *

    *
  • This algorithm is only suitable for messages of limited length. * The total number of input bytes processed may not be more than k-11, * where k is the RSA key's modulus size in bytes. *
  • The encryption block(EB) during encryption with a Public key * is built as follows:
    *   EB = 00 || 02 || PS || 00 || M
    *       :: M (input bytes) is the plaintext message
    *       :: PS is an octet string of length k-3-||M|| of pseudo * random nonzero octets. The length of PS must be at least 8 octets.
    *       :: k is the RSA modulus size.

    *
  • The encryption block(EB) during encryption with a Private key * (used to compute signatures when the message digest is computed off-card) * is built as follows:
    *   EB = 00 || 01 || PS || 00 || D
    *       :: D (input bytes) is the DER encoding of the * hash computed elsewhere with an algorithm ID * prepended if appropriate
    *       :: PS is an octet string of length k-3-||D|| with value * FF. The length of PS must be at least 8 octets.
    *       :: k is the RSA modulus size.

    *
*/ public static final byte ALG_RSA_PKCS1 = 10; /** * This Cipher algorithm ALG_RSA_ISO9796 should not be used. The * ISO 9796-1 algorithm was withdrawn by ISO in July 2000. */ public static final byte ALG_RSA_ISO9796 = 11; /** * Cipher algorithm ALG_RSA_NOPAD provides a cipher using RSA and * does not pad input data. If the input data is bounded by incorrect * padding bytes while using RSAPrivateCrtKey, incorrect output may result. * If the input data is not block aligned it throws CryptoException with * the reason code ILLEGAL_USE. */ public static final byte ALG_RSA_NOPAD = 12; /** * Cipher algorithm ALG_AES_BLOCK_128_CBC_NOPAD provides a cipher using AES with * block size 128 in CBC mode and * does not pad input data. If the input data is not block * aligned it throws CryptoException with the reason code ILLEGAL_USE. */ public static final byte ALG_AES_BLOCK_128_CBC_NOPAD = 13; /** * Cipher algorithm ALG_AES_BLOCK_128_ECB_NOPAD provides a cipher using AES with * block size 128 in ECB mode and * does not pad input data. If the input data is not block * aligned it throws CryptoException with the reason code ILLEGAL_USE. */ public static final byte ALG_AES_BLOCK_128_ECB_NOPAD = 14; /** * Cipher algorithm ALG_RSA_PKCS1_OAEP provides a cipher using RSA, and * pads input data according to the PKCS#1-OAEP scheme (IEEE 1363-2000). */ public static final byte ALG_RSA_PKCS1_OAEP = 15; /** * Cipher algorithm ALG_KOREAN_SEED_ECB_NOPAD provides a cipher using the * Korean SEED algorithm specified in the Korean SEED Algorithm * specification provided by KISA, Korea Information Security Agency in ECB * mode and does not pad input data. If the input data is not block aligned * it throws CryptoException with the reason code ILLEGAL_USE. * * @since 2.2.2 */ public static final byte ALG_KOREAN_SEED_ECB_NOPAD = 16; /** * Cipher algorithm ALG_KOREAN_SEED_CBC_NOPAD provides a cipher using the * Korean SEED algorithm specified in the Korean SEED Algorithm * specification provided by KISA, Korea Information Security Agency in ECB * mode and does not pad input data. If the input data is not block aligned * it throws CryptoException with the reason code ILLEGAL_USE. * * * @since 2.2.2 */ public static final byte ALG_KOREAN_SEED_CBC_NOPAD = 17; /** * Used in init() methods to indicate decryption mode. */ public static final byte MODE_DECRYPT = 1; /** * Used in init() methods to indicate encryption mode. */ public static final byte MODE_ENCRYPT = 2; /** * Protected constructor. */ protected Cipher() { } /** * Creates a Cipher object instance of the selected algorithm. * @param algorithm the desired Cipher algorithm. Valid codes listed in * ALG_ .. constants above, for example, {@link #ALG_DES_CBC_NOPAD} * @param externalAccess indicates that the instance will be shared among * multiple applet instances and that the Cipher instance will also be accessed (via a Shareable * interface) when the owner of the Cipher instance is not the currently selected applet. * If true the implementation must not allocate CLEAR_ON_DESELECT transient space for internal data. * @return the Cipher object instance of the requested algorithm * @throws CryptoException with the following reason codes: *
    *
  • CryptoException.NO_SUCH_ALGORITHM if the requested algorithm is not supported * or shared access mode is not supported. *
*/ public static final Cipher getInstance(byte algorithm, boolean externalAccess) throws CryptoException { Cipher instance = null; if (externalAccess) { CryptoException.throwIt((short) 3); } switch (algorithm) { case ALG_DES_CBC_NOPAD: case ALG_DES_CBC_ISO9797_M1: case ALG_DES_CBC_ISO9797_M2: case ALG_DES_CBC_PKCS5: case ALG_DES_ECB_NOPAD: case ALG_DES_ECB_ISO9797_M1: case ALG_DES_ECB_ISO9797_M2: case ALG_DES_ECB_PKCS5: case ALG_AES_BLOCK_128_CBC_NOPAD: case ALG_AES_BLOCK_128_ECB_NOPAD: instance = new SymmetricCipherImpl(algorithm); break; case ALG_RSA_PKCS1: case ALG_RSA_NOPAD: case ALG_RSA_ISO14888: case ALG_RSA_ISO9796: case ALG_RSA_PKCS1_OAEP: instance = new AssymetricCipherImpl(algorithm); break; default: CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM); break; } return instance; } /** * Initializes the Cipher object with the appropriate Key. * This method should be used * for algorithms which do not need initialization parameters or use default parameter * values. *

init() must be used to update the Cipher object with a new key. * If the Key object is modified after invoking the init() method, * the behavior of the update() and doFinal() * methods is unspecified. *

Note: *

    *
  • AES, DES, and triple DES algorithms in CBC mode will use 0 for initial vector(IV) if this * method is used. *
  • For optimal performance, when the theKey parameter is a transient key, the implementation should, * whenever possible, use transient space for internal storage. *
* @param theKey the key object to use for encrypting or decrypting * @param theMode one of MODE_DECRYPT or MODE_ENCRYPT * @throws CryptoException with the following reason codes: *
    *
  • CryptoException.ILLEGAL_VALUE if theMode option is an undefined value or * if the Key is inconsistent with the Cipher implementation. *
  • CryptoException.UNINITIALIZED_KEY if theKey instance is uninitialized. *
*/ public abstract void init(Key theKey, byte theMode) throws CryptoException; /** * Initializes the Cipher object with the appropriate Key and algorithm specific * parameters. *

init() must be used to update the Cipher object with a new key. * If the Key object is modified after invoking the init() method, * the behavior of the update() and doFinal() * methods is unspecified. *

Note: *

    *
  • DES and triple DES algorithms in CBC mode expect an 8-byte parameter value for * the initial vector(IV) in bArray. *
  • AES algorithms in CBC mode expect a 16-byte parameter value for * the initial vector(IV) in bArray. *
  • AES algorithms in ECB mode, DES algorithms in ECB mode, * RSA and DSA algorithms throw CryptoException.ILLEGAL_VALUE. *
  • For optimal performance, when the theKey parameter is a transient key, the implementation should, * whenever possible, use transient space for internal storage. *
* @param theKey the key object to use for encrypting or decrypting. * @param theMode one of MODE_DECRYPT or MODE_ENCRYPT * @param bArray byte array containing algorithm specific initialization info * @param bOff offset within bArray where the algorithm specific data begins * @param bLen byte length of algorithm specific parameter data * @throws CryptoException with the following reason codes: *
    *
  • CryptoException.ILLEGAL_VALUE if theMode option is an undefined value * or if a byte array parameter option is not supported by the algorithm or if * the bLen is an incorrect byte length for the algorithm specific data or * if the Key is inconsistent with the Cipher implementation. *
  • CryptoException.UNINITIALIZED_KEY if theKey instance is uninitialized. *
*/ public abstract void init(Key theKey, byte theMode, byte[] bArray, short bOff, short bLen) throws CryptoException; /** * Gets the Cipher algorithm. * @return the algorithm code defined above */ public abstract byte getAlgorithm(); /** * Generates encrypted/decrypted output from all/last input data. This method must be invoked * to complete a cipher operation. This method processes any remaining input data buffered by * one or more calls to the update() method as well as input data supplied in the * inBuff parameter. *

A call to this method also resets this Cipher object to the state it was in * when previously initialized via a call to init(). * That is, the object is reset and available to encrypt or decrypt * (depending on the operation mode that was specified in the call to init()) more data. * In addition, note that the initial vector(IV) used in AES and DES algorithms will be reset to 0. *

Notes: *

    *
  • When using block-aligned data (multiple of block size), * if the input buffer, inBuff and the output buffer, * outBuff * are the same array, then the output data area must not partially overlap the input data area such that * the input data is modified before it is used; * if inBuff==outBuff and
    inOffset < outOffset < inOffset+inLength, * incorrect output may result. *
  • When non-block aligned data is presented as input data, no amount of input * and output buffer data overlap is allowed; * if inBuff==outBuff and
    outOffset < inOffset+inLength, * incorrect output may result. *
  • AES, DES, and triple DES algorithms in CBC mode reset the initial vector(IV) * to 0. The initial vector(IV) can be re-initialized using the * init(Key, byte, byte[], short, short) method. *
  • On decryption operations (except when ISO 9797 method 1 padding is used), * the padding bytes are not written to outBuff. *
  • On encryption and decryption operations, the number of bytes output into outBuff * may be larger or smaller than inLength or even 0. *
  • On decryption operations resulting in an ArrayIndexOutOfBoundException, * outBuff may be partially modified. *
* @param inBuff the input buffer of data to be encrypted/decrypted * @param inOffset the offset into the input buffer at which to begin encryption/decryption * @param inLength the byte length to be encrypted/decrypted * @param outBuff the output buffer, may be the same as the input buffer * @param outOffset the offset into the output buffer where the resulting output data begins * @return number of bytes output in outBuff * @throws CryptoException with the following reason codes: *
    *
  • CryptoException.UNINITIALIZED_KEY if key not initialized. *
  • CryptoException.INVALID_INIT if this Cipher object is * not initialized. *
  • CryptoException.ILLEGAL_USE if one of the following conditions is met: *
      *
    • This Cipher algorithm * does not pad the message and the message is not block aligned. *
    • This Cipher algorithm * does not pad the message and no input * data has been provided in inBuff or via the update() method. *
    • The input message length is not supported. *
    • The decrypted data is not bounded by appropriate padding bytes. *
    *
*/ public abstract short doFinal(byte[] inBuff, short inOffset, short inLength, byte[] outBuff, short outOffset) throws CryptoException; /** * Generates encrypted/decrypted output from input data. This method is intended for multiple-part * encryption/decryption operations. *

This method requires temporary storage of * intermediate results. In addition, if the input data length is not block aligned * (multiple of block size) * then additional internal storage may be allocated at this time to store a partial * input data block. * This may result in additional resource consumption and/or slow performance. *

This method should only be used if all the input data required for the cipher * is not available in one byte array. If all the input data required for the cipher * is located in a single byte array, use of the doFinal() method to * process all of the input data is recommended. The doFinal() method * must be invoked to complete processing of any remaining input data buffered by one or more calls * to the update() method. *

Notes:

    *
  • When using block-aligned data (multiple of block size), * if the input buffer, inBuff and the output buffer, * outBuff * are the same array, then the output data area must not partially overlap the input data area such that * the input data is modified before it is used; * if inBuff==outBuff and
    inOffset < outOffset < inOffset+inLength, * incorrect output may result. *
  • When non-block aligned data is presented as input data, no amount of input * and output buffer data overlap is allowed; * if inBuff==outBuff and
    outOffset < inOffset+inLength, * incorrect output may result. *
  • On decryption operations(except when ISO 9797 method 1 padding is used), * the padding bytes are not written to outBuff. *
  • On encryption and decryption operations, * block alignment considerations may require that * the number of bytes output into outBuff be larger or smaller than * inLength or even 0. *
  • If inLength is 0 this method does nothing. *
* @param inBuff the input buffer of data to be encrypted/decrypted * @param inOffset the offset into the input buffer at which to begin encryption/decryption * @param inLength the byte length to be encrypted/decryptedv * @param outBuff the output buffer, may be the same as the input buffer * @param outOffset the offset into the output buffer where the resulting ciphertext/plaintext begins * @return number of bytes output in outBuff * @throws CryptoException with the following reason codes: *
    *
  • CryptoException.UNINITIALIZED_KEY if key not initialized. *
  • CryptoException.INVALID_INIT if this Cipher object is * not initialized. *
  • CryptoException.ILLEGAL_USE if the input message length is not supported. *
*/ public abstract short update(byte[] inBuff, short inOffset, short inLength, byte[] outBuff, short outOffset) throws CryptoException; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy