iaik.security.cipher
Class CAST128KeyWrap

java.lang.Object
  |
  +--javax.crypto.CipherSpi
        |
        +--iaik.security.cipher.BufferedCipher
              |
              +--iaik.security.cipher.CMSKeyWrapCipher
                    |
                    +--iaik.security.cipher.CAST128KeyWrap

public class CAST128KeyWrap
extends iaik.security.cipher.CMSKeyWrapCipher

This class implements the CMS CAST128 Key Wrap key wrap algorithm.

RFC 2984 (Use of the CAST-128 algorithm in CMS) specifies the CAST128 key wrap algorithm for wrapping CAST128 content encryption keys with CAST128 key encryption keys when using the KeyAgreeRecipientInfo or KEKRecipientInfo choice for providing recipient specific information when encrypting data using the EnvelopedData type.

Since this class only can be used for wrapping/unwrapping secret content encryption keys an application only can call methods wrap and unwrap of the corresponding Cipher object. Any attempt to call a update or doFinal method will cause a RuntimeException to be thrown. A CMS key wrap (unwrap) procedure involves two encryption (decryption) operations, both run in CBC mode. The first encryption step uses a random IV and the second encryption step uses a fixed IV of 0x4adda22c79e82105. Correspondingly the first decryption step uses a fixed IV (0x4adda22c79e82105) and the second decryption step uses the random IV recovered from the first decryption. When calling an engineInit method the supplied parameters only may specify the key length to be used by CAST128WrapParameterSpec or CAST128Parameters; this CMS CAST128 key wrap cipher implementation itself takes care for using the right IV for the right en/decryption step. When calling method getIV this class always returns null; when calling method getParameters this class returns the key length to be included in the parameters field of the algorithm id.

When creating a new CMS CAST128 key wrap Cipher object you only may provide the name of the key wrap cipher ("CAST128WrapCAST128"). Any cipher mode (always uses CBC) or padding (does the padding itself) specification is ignored.

For example, wrapping a CAST128 content encryption key using a CAST128 key encryption key typically may be done as follows:

 // the content encryption key to be wrapped:
 SecretKey cek = ...;
 // the key encryption key to be used:
 SecretKey kek = ...;
 // get a CAST128 key wrap cipher:
 Cipher c = Cipher.getInstance("CAST128WrapCAST128");
 // init with the key encryption key
 c.init(Cipher.WRAP_MODE, kek);
 // wrap the content encryption key:
 byte[] wrappedCek = c.wrap(cek);
 // get the parameters:
 CAST128WrapParameters cast128WrapParameters = (CAST128WrapParameters)c.getParameters();
 
For unwrapping the key init the Cipher in unwrap mode:
 Cipher c = Cipher.getInstance("CAST128WrapCAST128");
 // init with the key encryption key
 c.init(Cipher.UNWRAP_MODE, kek, cast128WrapParameters, random);
 // unwrap the wrapped content encryption key:
 Key unwrappedCek = c.unwrap(wrappedCek, "CAST128", Cipher.SECRET_KEY);
 

Version:
File Revision 7

Field Summary
protected  int cipherTextLength
          The expected cipher text length, may be required to be checked.
static byte[] CMS_KEY_WRAP_IV
          The IV for the last encryption step of CMS key wrap.
protected  Key kek
          The key encryption key (used for en/decrypting the content encryption key).
protected  byte[] keyWrapIV
          The IV to be used for the second encryption step. (default 0x4adda22c79e82105)
protected  SecureRandom random
          The SecureRandom.
 
Constructor Summary
CAST128KeyWrap()
          Creates a CAST128KeyWrap object.
 
Method Summary
protected  byte[] computeLCEKPAD(Key contentEncryptionKey)
          Calculates the LCEKPAD value (RFC 2630, Section 12.6.4) from the given content encryption key.
protected  byte[] decomposeLCEKPAD(byte[] LCEKPAD)
          Decomposes the LCEKPAD value (RFC 2630, Section 12.6.5, 8.) into LENGTH CEK and PAD and returns the CEK As last step of the RC2 Key UnWrap algorithm described in RFC2630, the LCEKPAD (composed of cek-length, decrypted content-encryption key and optional padding) has to be decomposed for getting the cek.
 byte[] engineDoFinal(byte[] in, int inOff, int inLen)
          Throws a RuntimeException since not supported by this key wrap cipher.
 int engineDoFinal(byte[] in, int inOff, int inLen, byte[] out, int outOff)
          Throws a RuntimeException since not supported by this key wrap cipher.
 int engineGetBlockSize()
          Returns the block size corresponding to this cipher.
 byte[] engineGetIV()
          Returns null.
protected  int engineGetKeySize(Key key)
          New method in JCE 1.2.1
 int engineGetOutputSize(int inLen)
          Returns the output buffer size necessary for capturing the data resulting from the next update or doFinal operation including any data currently being buffered.
 AlgorithmParameters engineGetParameters()
          Returns the algorithm parameters of this CAST128KeyWrap cipher.
 void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random)
          Initializes this cipher object.
 void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
          Initializes this cipher object.
protected  void engineInit(int opmode, Key key, byte[] iv, SecureRandom random)
          Internal inits the underlying CAST128 cipher for the second en/decryption step.
 void engineInit(int opmode, Key key, SecureRandom random)
          Initializes this cipher object.
 void engineSetMode(String mode)
          Sets the mode of this cipher to "CBC".
 void engineSetPadding(String paddingName)
          Sets the padding scheme of this cipher.
protected  Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)
          Unwraps the given wrapped key to recover the content encryption key.
 byte[] engineUpdate(byte[] in, int inOff, int inLen)
          Throws a RuntimeException since not supported by this key wrap cipher.
 int engineUpdate(byte[] in, int inOff, int inLen, byte[] out, int outOff)
          Throws a RuntimeException since not supported by this key wrap cipher.
protected  byte[] engineWrap(Key key)
          Engine method for key wrapping.
protected  Key finishUnWrap(byte[] decryptedCek, String wrappedKeyAlgorithm, int wrappedKeyType)
          Finishes the unwrapping process by decomposing the LCEKPAD value (RFC 2630, Section 12.6.5, 8.) into LENGTH CEK and PAD and returns the CEK As last step of CAST128 Key UnWrap algorithm (equivalent to RC2 key unwrapdescribed in RFC2630, the LCEKPAD (composed of cek-length, decrypted content-encryption key and optional padding) has to be decomposed for getting the cek.
 int getModeBlockSize()
          Returns the block size corresponding to the actual cipher mode.
protected  SecureRandom getRandom()
          Gets the SecureRandom.
protected  byte[] prepareWrap(Key contentEncryptionKey)
          Prepares the given content encryption CAST128 key for being wrapped.
 String toString()
          Returns a string representation of this Cipher.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

kek

protected Key kek
The key encryption key (used for en/decrypting the content encryption key). To be supplied when initializing the cipher.

cipherTextLength

protected int cipherTextLength
The expected cipher text length, may be required to be checked.

random

protected SecureRandom random
The SecureRandom.

keyWrapIV

protected byte[] keyWrapIV
The IV to be used for the second encryption step. (default 0x4adda22c79e82105)

CMS_KEY_WRAP_IV

public static final byte[] CMS_KEY_WRAP_IV
The IV for the last encryption step of CMS key wrap. See RFC 2630, section 12.6.2 - 12.6.5:
 IV = 0x4adda22c79e82105.
 
Constructor Detail

CAST128KeyWrap

public CAST128KeyWrap()
Creates a CAST128KeyWrap object. This constructor is only internally used for initializing a CAST128KeyWrap Cipher. Applications should not call this constructor to get a CAST128KeyWrap Cipher; they should call one of the Cipher.getInstance factory methods instead, e.g.:
 Cipher cast128KeyWrap = Cipher.getInstance("CAST128WrapCAST128");
 
Since the CAST128KeyWrap cipher only runs in CBC mode and itself takes care for padding, any mode or padding specification as part of the transformation string supplied when creating the Cipher object is ignored.
Method Detail

engineInit

public void engineInit(int opmode,
                       Key key,
                       AlgorithmParameterSpec params,
                       SecureRandom random)
                throws InvalidKeyException,
                       InvalidAlgorithmParameterException
Initializes this cipher object.

Any parameters to be set have to be supplied as instances of CAST128WrapParameterSpec giving key length.

If the cipher has to be initialized for key wrap, a random IV is used. If the cipher has to be initialized for key unwrap, a fixed CMS key wrap IV is used.

Overrides:
engineInit in class iaik.security.cipher.BufferedCipher
Parameters:
opmode - the operation mode for which this cipher is used (WRAP_MODE or UNWRAP_MODE)
key - the key encryption key to be used
params - the algorithm parameters
random - the random seed
Throws:
InvalidKeyException - if the given key cannot be used for initializing this cipher
InvalidAlgorithmParameterException - if the given algorithm parameters donīt match to this cipher

engineInit

public void engineInit(int opmode,
                       Key key,
                       AlgorithmParameters params,
                       SecureRandom random)
                throws InvalidKeyException,
                       InvalidAlgorithmParameterException
Initializes this cipher object.

Any parameters to be set have to be supplied as instances of CAST128WrapParameters giving the key length.

If the cipher has to be initialized for key wrap, a random IV is used. If the cipher has to be initialized for key unwrap, a fixed CMS key wrap IV is used.

Overrides:
engineInit in class iaik.security.cipher.BufferedCipher
Parameters:
opmode - the operation mode for which this cipher is used (WRAP_MODE or UNWRAP_MODE)
key - the key encryption key
params - the algorithm parameters
random - the random seed
Throws:
InvalidKeyException - if the given key cannot be used for initializing this cipher
InvalidAlgorithmParameterException - if the given algorithm parameters donīt match to this cipher

engineInit

protected void engineInit(int opmode,
                          Key key,
                          byte[] iv,
                          SecureRandom random)
                   throws InvalidKeyException,
                          InvalidAlgorithmParameterException
Internal inits the underlying CAST128 cipher for the second en/decryption step.

A CMS key wrap (unwrap) procedure involves two encryption (decryption) operations, both run in CBC mode. The first encryption step uses a random IV and the second encryption step uses a fixed IV of default 0x4adda22c79e82105. Correspondingly the first decryption step uses a fixed IV (default 0x4adda22c79e82105) and the second decryption step uses the random IV recovered from the first decryption. When calling an This method is called during the wrapping/unwrapping to init the underlying CAST128 cipher for the second en/decryption step. The given iv is used to be included in CAST128 parameters for initializing the underlying cipher.

Overrides:
engineInit in class iaik.security.cipher.CMSKeyWrapCipher
Parameters:
opmode - the operation mode
key - the key encryption key
iv - the initialization vector, either fixed (for second encryption step) or recovered random (for second decryption step)
random - the random seed
Throws:
InvalidKeyException - if something is wrong with the key
InvalidAlgorithmParameterException - if an error occurs when creating the parameters from the iv

engineGetParameters

public AlgorithmParameters engineGetParameters()
Returns the algorithm parameters of this CAST128KeyWrap cipher.

The parameters are returned as CAST128WrapParameters giving the key length:

 cast5CMSkeywrapParameter ::= INTEGER
   -- key length in bits
 
Overrides:
engineGetParameters in class iaik.security.cipher.CMSKeyWrapCipher
Following copied from class: iaik.security.cipher.CMSKeyWrapCipher
Returns:
null

prepareWrap

protected byte[] prepareWrap(Key contentEncryptionKey)
                      throws InvalidKeyException
Prepares the given content encryption CAST128 key for being wrapped.

This method calculates the LCEKPAD value (RFC 2630, Section 12.6.4) from the given content encryption key.

As first step of the CAST128 Key Wrap algorithm (equivalent to RC2 key wrap described in RFC2630), the content-encryption key is concatenated with its length and padded to a multiple of 8, if required:

  1. Let the content-encryption key be called CEK, and let the length of the content-encryption key in octets be called LENGTH. LENGTH is a single octet.
  2. Let LCEK = LENGTH || CEK.
  3. Let LCEKPAD = LCEK || PAD. If the length of LCEK is a multiple of 8, the PAD has a length of zero. If the length of LCEK is not a multiple of 8, then PAD contains the fewest number of random octets to make the length of LCEKPAD a multiple of 8.
  4. ...
The LCEKPAD value subsequently is the input to the wrapping process itself.
Overrides:
prepareWrap in class iaik.security.cipher.CMSKeyWrapCipher
Parameters:
contentEncryptionKey - the content encryption key for which to calculate the LCEKPAD value
Returns:
the LCEKPAD value calculated from the given content encryption key

finishUnWrap

protected Key finishUnWrap(byte[] decryptedCek,
                           String wrappedKeyAlgorithm,
                           int wrappedKeyType)
                    throws InvalidKeyException
Finishes the unwrapping process by decomposing the LCEKPAD value (RFC 2630, Section 12.6.5, 8.) into LENGTH CEK and PAD and returns the CEK

As last step of CAST128 Key UnWrap algorithm (equivalent to RC2 key unwrapdescribed in RFC2630, the LCEKPAD (composed of cek-length, decrypted content-encryption key and optional padding) has to be decomposed for getting the cek.

Overrides:
finishUnWrap in class iaik.security.cipher.CMSKeyWrapCipher
Parameters:
LCEKPAD - the LCEKPAD value (LENGTH || CEK || PAD)
Returns:
the recovered raw content encryption key encoding
Throws:
InvalidKeyException - if the key cannot be unwrapped because the PAD value of the LCEKPAD is invalid (has a length not shorter than 8

engineInit

public void engineInit(int opmode,
                       Key key,
                       SecureRandom random)
                throws InvalidKeyException
Initializes this cipher object.

If the cipher has to be initialized for key wrap, a random IV is used. If the cipher has to be initialized for key unwrap, a fixed CMS key wrap IV is used.

Overrides:
engineInit in class iaik.security.cipher.BufferedCipher
Parameters:
opmode - the operation mode for which this cipher is used (WRAP_MODE or UNWRAP_MODE)
key - the key encryption key to be used
random - the random seed
Throws:
InvalidKeyException - if the given key cannot be used for initializing this cipher

engineSetPadding

public void engineSetPadding(String paddingName)
                      throws NoSuchPaddingException
Sets the padding scheme of this cipher.

This method only overrides engineSetPadding for not allowing an application to request a specific padding scheme (this key wrap cipher itself takes care for padding).

Overrides:
engineSetPadding in class iaik.security.cipher.BufferedCipher
Parameters:
paddingName - the name of the padding scheme; ignored
Throws:
NoSuchPaddingException - if this padding scheme is not supported

engineSetMode

public void engineSetMode(String mode)
                   throws NoSuchAlgorithmException
Sets the mode of this cipher to "CBC".

This method only overrides engineSetMode for not allowing an application to request a specific cipher mode (this key wrap cipher always uses "CBC").

Overrides:
engineSetMode in class iaik.security.cipher.BufferedCipher
Parameters:
mode - the cipher mode
Throws:
NoSuchAlgorithmException - if this cipher mode is not supported

engineUpdate

public byte[] engineUpdate(byte[] in,
                           int inOff,
                           int inLen)
Throws a RuntimeException since not supported by this key wrap cipher. Use method wrap/unwrap for wrapping/unwrapping a key.
Overrides:
engineUpdate in class iaik.security.cipher.BufferedCipher
Following copied from class: iaik.security.cipher.BufferedCipher
Parameters:
in - the input data.
inOff - the offset indicating where the subarray starts in the in array.
inLen - the length of the subarray.
isFinal - true, if this is the last call to update
Returns:
array containing the en/decrypted data
See Also:
BufferedCipher.engineDoFinal(byte[], int, int, byte[], int), Cipher.doFinal(), Cipher.update(byte[]), CipherSpi.engineUpdate(byte[], int, int)

engineUpdate

public int engineUpdate(byte[] in,
                        int inOff,
                        int inLen,
                        byte[] out,
                        int outOff)
                 throws ShortBufferException
Throws a RuntimeException since not supported by this key wrap cipher. Use method wrap/unwrap for wrapping/unwrapping a key.
Overrides:
engineUpdate in class iaik.security.cipher.BufferedCipher
Following copied from class: iaik.security.cipher.BufferedCipher
Parameters:
in - the input data.
inOff - the offset indicating where the subarray starts in the in array.
inLen - the length of the subarray.
out - the output buffer.
outOff - the offset indicating where to start writing the result into the output buffer.
Returns:
number of bytes written to out array.
Throws:
ShoetBufferException - if the buffer size is to short
See Also:
BufferedCipher.engineDoFinal(byte[], int, int, byte[], int), Cipher.doFinal(), Cipher.update(byte[]), CipherSpi.engineUpdate(byte[], int, int)

engineDoFinal

public int engineDoFinal(byte[] in,
                         int inOff,
                         int inLen,
                         byte[] out,
                         int outOff)
                  throws ShortBufferException,
                         IllegalBlockSizeException,
                         BadPaddingException
Throws a RuntimeException since not supported by this key wrap cipher. Use method wrap/unwrap for wrapping/unwrapping a key.
Overrides:
engineDoFinal in class iaik.security.cipher.BufferedCipher
Following copied from class: iaik.security.cipher.BufferedCipher
Parameters:
in - the byte array holding the data to be processed
inOff - the offset indicating the start position within the input byte array
inLen - the number of bytes to be processed
out - the byte array for holding the result
outOff - the offset indicating the start position within the output byte array to which the en/decrypted data is written
Returns:
the number of bytes stored in the output byte array
Throws:
ShortBufferException - if the given output buffer is too small for holding the result
IllegalBlockSizeException - if the total length of the processed data is not a multiple of the block size for a (no padding performing) block cipher
BadPaddingException - if the decrypted data is not bounded by the proper padding bytes after data decryption including (un)padding
See Also:
Cipher.doFinal(), CipherSpi.engineDoFinal(byte[], int, int)

engineDoFinal

public byte[] engineDoFinal(byte[] in,
                            int inOff,
                            int inLen)
                     throws IllegalBlockSizeException,
                            BadPaddingException
Throws a RuntimeException since not supported by this key wrap cipher. Use method wrap/unwrap for wrapping/unwrapping a key.
Overrides:
engineDoFinal in class iaik.security.cipher.BufferedCipher
Following copied from class: iaik.security.cipher.BufferedCipher
Parameters:
in - the byte array holding the data to be processed
inOff - the offset indicating the start position within the input byte array
inLen - the number of bytes to be processed
Returns:
the byte array containing the en/decrypted data
Throws:
IllegalBlockSizeException - if the total length of the processed data is not a multiple of the block size for a (no padding performing) block cipher
BadPaddingException - if the decrypted data is not bounded by the proper padding bytes after data decryption including (un)padding
See Also:
Cipher.doFinal(), CipherSpi.engineDoFinal(byte[], int, int)

engineGetIV

public byte[] engineGetIV()
Returns null. This method always returns null (CMS key wrap uses fixed IVs) and may be overriden if required for a particular key wrap cipher.
Overrides:
engineGetIV in class iaik.security.cipher.BufferedCipher
Returns:
null

toString

public String toString()
Returns a string representation of this Cipher.
Overrides:
toString in class iaik.security.cipher.BufferedCipher
Returns:
a string representation

engineWrap

protected byte[] engineWrap(Key key)
                     throws IllegalBlockSizeException,
                            InvalidKeyException
Description copied from class: CipherSpi
Engine method for key wrapping. Since JCE 1.2.1
Overrides:
engineWrap in class iaik.security.cipher.BufferedCipher

engineUnwrap

protected Key engineUnwrap(byte[] wrappedKey,
                           String wrappedKeyAlgorithm,
                           int wrappedKeyType)
                    throws InvalidKeyException,
                           NoSuchAlgorithmException
Unwraps the given wrapped key to recover the content encryption key.

This method implements the core operations common to the Triple-DES and RC2 Key Wrap algorithms of RFC 2630, in particular the equivalent steps 1 to 7 of Triple-DES Key Unwrap (section 12.6.3 of RFC 2630) respectively steps 1 to 7 of RC2 Key Unwrap (section 12.6.5 of RFC 2630). Any key wrap algorithm specific operations required to finish the unwrap procedure may be done by implementing the abstract method finishUnWrap for the specific key wrap algorithm in mind. Triple-DES Key wrap, for instance, requires the content encryption key to be (odd) parity adjusted before being wrapped. Triple-DES Key Wrap is implemented by class TripleDESKeyWrap which implements method finishUnWrap to check odd parity at the end of the unwrapping procedure.

Overrides:
engineUnwrap in class iaik.security.cipher.BufferedCipher
Parameters:
wrappedKey - the wrapped content encryption key to be unwrapped
wrappedKeyAlgorithm - the content encryption key algorithm
wrappedKeyType - the key type, Cipher.SECRET_KEY
Throws:
InvalidKeyException - if an error occurs while unwrapping the key
NoSuchAlgorithmException - if the algorithm used is not supported by the installed providers

getRandom

protected SecureRandom getRandom()
Gets the SecureRandom.

If no SecureRandom has been set, a new one is created.

Returns:
the SecureRandom

computeLCEKPAD

protected byte[] computeLCEKPAD(Key contentEncryptionKey)
Calculates the LCEKPAD value (RFC 2630, Section 12.6.4) from the given content encryption key.

As first step of the RC2 Key Wrap algorithm described in RFC2630, the content-encryption key is concatenated with its length and padded to a multiple of 8, if required:

  1. Let the content-encryption key be called CEK, and let the length of the content-encryption key in octets be called LENGTH. LENGTH is a single octet.
  2. Let LCEK = LENGTH || CEK.
  3. Let LCEKPAD = LCEK || PAD. If the length of LCEK is a multiple of 8, the PAD has a length of zero. If the length of LCEK is not a multiple of 8, then PAD contains the fewest number of random octets to make the length of LCEKPAD a multiple of 8.
  4. ...
The LCEKPAD value subsequently is the input to the wrapping process itself. Since LCEKPAD also may be required by other key wrap algorithms than RC2 (e.g. CAST-128 Key Wrap; RFC2984) this method may be used for calculating the LCEKPAD value when preparing the content encryption key for the wrapping procedure.
Parameters:
contentEncryptionKey - the content encryption key for which to calculate the LCEKPAD value
Returns:
the LCEKPAD value calculated from the given content encryption key

decomposeLCEKPAD

protected byte[] decomposeLCEKPAD(byte[] LCEKPAD)
                           throws BadPaddingException
Decomposes the LCEKPAD value (RFC 2630, Section 12.6.5, 8.) into LENGTH CEK and PAD and returns the CEK

As last step of the RC2 Key UnWrap algorithm described in RFC2630, the LCEKPAD (composed of cek-length, decrypted content-encryption key and optional padding) has to be decomposed for getting the cek. Since LCEKPAD also may be used by other key wrap algorithms than RC2 (e.g. CAST-128 Key Wrap; RFC2984) this method may be used for decomposing the LCEKPAD value when finishing the unwrapping procedure.

Parameters:
LCEKPAD - the LCEKPAD value (LENGTH || CEK || PAD)
Returns:
the recovered raw content encryption key encoding
Throws:
BadPaddingException - if the PAD value of the LCEKPAD has a length not shorter than 8

engineGetOutputSize

public int engineGetOutputSize(int inLen)
Returns the output buffer size necessary for capturing the data resulting from the next update or doFinal operation including any data currently being buffered.
Overrides:
engineGetOutputSize in class CipherSpi
Parameters:
inLen - the number of bytes to process
Returns:
the size of the output buffer (in bytes)
See Also:
Cipher.getOutputSize(int), CipherSpi.engineGetOutputSize(int)

getModeBlockSize

public int getModeBlockSize()
Returns the block size corresponding to the actual cipher mode. This may differ from the actual block size of the cipher in the OFB, CFB and CTR mode. This is the input size that an application must supply to an update call to get an output.
Returns:
The block size (in bytes) of the current mode. This is always at least one.

engineGetBlockSize

public int engineGetBlockSize()
Returns the block size corresponding to this cipher. The block size is returned in bytes. If the implemented algorithm is not a block cipher, 0 is returned.
Overrides:
engineGetBlockSize in class CipherSpi
Returns:
the block size (in bytes) if this cipher is a block cipher, 0 otherwise.
See Also:
Cipher.getBlockSize(), CipherSpi.engineGetBlockSize()

engineGetKeySize

protected int engineGetKeySize(Key key)
                        throws InvalidKeyException
Description copied from class: CipherSpi
New method in JCE 1.2.1
Overrides:
engineGetKeySize in class CipherSpi

This Javadoc may contain text parts from Internet Standard specifications (RFC 2459, 3280, 3039, 2560, 1521, 821, 822, 2253, 1319, 1321, ,2630, 2631, 2268, 3058, 2984, 2104, 2144, 2040, 2311, 2279, see copyright note) and RSA Data Security Public-Key Cryptography Standards (PKCS#1,3,5,7,8,9,10,12, see copyright note).

IAIK-JCE 3.1 with IAIK-JCE CC Core 3.1, (c) 1997-2004 IAIK