SPI Slave mode and circular DMA with STM32F7 - stm32

I am currently using a peripheral which communicates in SPI (master mode).
This unit sends a 27-bit packet and receives 8 x 27-bit packets each.
With my STM32, I use the SPI protocol in slave mode (full duplex) and I use a 27-bit buffer memory for reception (RxBuffer [26]) and 8 buffers of 27 bits each for transmission. (TxBufferPKG0[27], TxBufferPKG1[27], ... ,TxBufferPKG7[27]).
The receive works very well.
The problem is sending 8 packets one after the other.
I a shift of bit during the transfert. Unfortunately, I don't have a oscilloscope to view the frames.
I don't want to use a 216 bit (8 * 27) buffer.
I am using the void DMA_IRQHandler () function to transfer memory to the SPI. But, I can't seem to use the interrupt flags for the completed send.
I know the flags are DMA_IT_HT and DMA_IT_TC but I don't know how to use them correctly.
I would like to send the 27 bit packets one by one and without lag.
Thanks for your help.
My code :
uint8_t TbufferPKG0[27] = { 0, 0x7F, 0x7F, 0x63, 0x41, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0, 0 };
uint8_t TbufferPKG1[27] = { 24, 0x7E, 0x11, 0x11, 0x11, 0x7E, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0, 0 };
uint8_t TbufferPKG2[27] = { 48, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x3E, 0x41, 0x49, 0x49, 0x3A, 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0, 0 };
uint8_t TbufferPKG3[27] = { 72, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x41, 0x63, 0x7F, 0x7F, 0x00, 0, 0 };
uint8_t TbufferPKG4[27] = { 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t TbufferPKG5[27] = { 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t TbufferPKG6[27] = { 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t TbufferPKG7[27] = { 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0C, 0, 0x20, 0, 0, 0, 0x58, 0, 0, 0 };
uint8_t Tbuffer[27] = { 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0C, 0, 0x20, 0, 0, 0, 0x58, 0, 0, 0 };
uint8_t Rbuffer[27] = {0};
void DMA1_Stream4_IRQHandler(void) {
HAL_DMA_IRQHandler(&hdma_spi2_tx);
if (TxPKG_SPI2 == 0) { memmove(Tbuffer, TbufferPKG0, sizeof(Tbuffer)); }
if (TxPKG_SPI2 == 1) { memmove(Tbuffer, TbufferPKG1, sizeof(Tbuffer)); }
if (TxPKG_SPI2 == 2) { memmove(Tbuffer, TbufferPKG2, sizeof(Tbuffer)); }
if (TxPKG_SPI2 == 3) { memmove(Tbuffer, TbufferPKG3, sizeof(Tbuffer)); }
if (TxPKG_SPI2 == 4) { memmove(Tbuffer, TbufferPKG4, sizeof(Tbuffer)); }
if (TxPKG_SPI2 == 5) { memmove(Tbuffer, TbufferPKG5, sizeof(Tbuffer)); }
if (TxPKG_SPI2 == 6) { memmove(Tbuffer, TbufferPKG6, sizeof(Tbuffer)); }
if (TxPKG_SPI2 == 7) { memmove(Tbuffer, TbufferPKG7, sizeof(Tbuffer)); }
TxPKG_SPI2 += 1;
if (TxPKG_SPI2 >= 8) { TxPKG_SPI2 = 0; }
}
/* SPI2_TX Init */
hdma_spi2_tx.Instance = DMA1_Stream4;
hdma_spi2_tx.Init.Channel = DMA_CHANNEL_0;
hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi2_tx.Init.Mode = DMA_CIRCULAR;
hdma_spi2_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

I solved my problem.
I replace DMA circular by DMA normal and I call the HAL_SPI_TxRxCpltCallback function.

Related

PKCS11Interop Hash with SHA256 and Sign with RSA in two steps

I have two applications, one that calculates the SHA-256 hash of a document and the other which makes the RSA signing.
Trying different things i came to the conclusion that making CKM_SHA256 and then making CKM_RSA_PKCS give a different result than just making the CKM_SHA256_RSA_PKCS of the document itself.
So my question is, what is the difference between this two implementations?
What information is added to the hash in CKM_SHA256_RSA_PKCS mechanism that turns in a complete different signature?
Mechanims CKM_SHA256_RSA_PKCS does following things:
Computes SHA256 hash of the data just like CKM_SHA256 does
Constructs DER encoded DigestInfo structure defined in RFC 8017
Signs DigestInfo structure with private key just like CKM_RSA_PKCS does
Several approaches are possible when it comes to construction of DER encoded DigestInfo structure:
In Pkcs11Admin application I did use BouncyCastle library:
public static byte[] CreateDigestInfo(byte[] hash, string hashOid)
{
DerObjectIdentifier derObjectIdentifier = new DerObjectIdentifier(hashOid);
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(derObjectIdentifier, null);
DigestInfo digestInfo = new DigestInfo(algorithmIdentifier, hash);
return digestInfo.GetDerEncoded();
}
In Pkcs11Interop.X509Store library I did use precomputed arrays:
/// <summary>
/// Creates DER encoded PKCS#1 DigestInfo structure defined in RFC 8017
/// </summary>
/// <param name="hash">Hash value</param>
/// <param name="hashAlgorithm">Hash algorithm</param>
/// <returns>DER encoded PKCS#1 DigestInfo structure or null</returns>
private static byte[] CreatePkcs1DigestInfo(byte[] hash, HashAlgorithmName hashAlgorithm)
{
if (hash == null || hash.Length == 0)
throw new ArgumentNullException(nameof(hash));
byte[] pkcs1DigestInfo = null;
if (hashAlgorithm == HashAlgorithmName.MD5)
{
if (hash.Length != 16)
throw new ArgumentException("Invalid lenght of hash value");
pkcs1DigestInfo = new byte[] { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
}
else if (hashAlgorithm == HashAlgorithmName.SHA1)
{
if (hash.Length != 20)
throw new ArgumentException("Invalid lenght of hash value");
pkcs1DigestInfo = new byte[] { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
}
else if (hashAlgorithm == HashAlgorithmName.SHA256)
{
if (hash.Length != 32)
throw new ArgumentException("Invalid lenght of hash value");
pkcs1DigestInfo = new byte[] { 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
}
else if (hashAlgorithm == HashAlgorithmName.SHA384)
{
if (hash.Length != 48)
throw new ArgumentException("Invalid lenght of hash value");
pkcs1DigestInfo = new byte[] { 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
}
else if (hashAlgorithm == HashAlgorithmName.SHA512)
{
if (hash.Length != 64)
throw new ArgumentException("Invalid lenght of hash value");
pkcs1DigestInfo = new byte[] { 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
}
return pkcs1DigestInfo;
}

PKCS#11 C_CreateObject fails with bad arguments

I have a C_CreateObject PKCS#11 API call to generate a 128 bit AES-key that fails with bad arguments.
Can anyone please help me figuring out what is wrong with the template ?
CK_OBJECT_HANDLE hKey;
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_AES;
CK_BBOOL _true = TRUE;
CK_BBOOL _false = FALSE;
CK_BYTE key_value[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
CK_ATTRIBUTE keyTemplate[] = {
{CKA_CLASS, &keyClass, sizeof(keyClass)},
{CKA_KEY_TYPE, &keyType, sizeof(keyType)},
{CKA_ENCRYPT, &_true, sizeof(_true)},
{CKA_DECRYPT, &_true, sizeof(_true)},
{CKA_TOKEN, &_true, sizeof(_true)}, /* token object */
{CKA_PRIVATE, &_false, sizeof(_false)}, /* public object */
{CKA_VALUE, key_value, sizeof(key_value)},
{CKA_LABEL, CK_VOID_PTR("key"), sizeof("key")}
};
rv = pfunc11->C_CreateObject(session, keyTemplate, sizeof (keyTemplate)/sizeof (CK_ATTRIBUTE), &hKey);
if (rv != CKR_OK) {
printf("ERROR: rv=0x%08X: C_CreateObject:\n", (unsigned int)rv);
return false;
}
Your key value is too short for AES key -- you need to provide 16 bytes (128 bits) or 32 bytes (256 bits) in key_value, e.g.:
CK_BYTE key_value[] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xcd, 0xef, 0x89, 0xab, 0x45, 0x67, 0x01, 0x23,
};
Good luck!

I can't create java card applet. APDU response message is 0x6444, and i don't know what to check

CMD>// Applet Instantiation APDU Script
//
// Package: cryptoPack
// Package AID: //aid/A000000062/03010C01
// Applet: CryptoDES
// Applet AID: //aid/A000000062/03010C0101
//
// Select the installer applet
0x00 0xA4 0x04 0x00 0x09 0xA0 0x00 0x00 0x00 0x62 0x03 0x01 0x08 0x01 0x7F;
APDU|CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 09, a0, 00, 00, 00, 62, 03, 01, 08, 01, Le: 00, SW1: 90, SW2: 00
// Create CryptoDES applet
0x80 0xB8 0x00 0x00 0x0C 0x0A 0xA0 0x00 0x00 0x00 0x62 0x03 0x01 0x0C 0x01 0x01 0x00 0x7F;
APDU|CLA: 80, INS: b8, P1: 00, P2: 00, Lc: 0c, 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, 00, Le: 00, SW1: 64, SW2: 44
I tested this code from Java Card DES generator applet output is different from online-tools output. And my test environment is eclipse and java card platform.
I compiled CryptoDES.java as Java Card Project. And first, I operated cap-cryptoPack script. Next, create-cryptoPack.CryptoDES script.
But, as above console, Sample_Device returned 0x6444. I don't know problem. Please help me.
package cryptoPack;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;
import javacard.security.CryptoException;
import javacard.security.DESKey;
import javacard.security.KeyBuilder;
import javacardx.crypto.Cipher;
public class CryptoDES extends Applet {
// Array for the encryption/decryption key
private byte[] TheDES_Key = { (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00 };
// Defining required Keys
DESKey MyDES1Key = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES,
KeyBuilder.LENGTH_DES, false);
DESKey MyDES2Key = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES,
KeyBuilder.LENGTH_DES3_2KEY, false);
DESKey MyDES3Key = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES,
KeyBuilder.LENGTH_DES3_3KEY, false);
byte ConfiguredKeyLength;
// Defining required cipher
Cipher MyCipher;
// Defining switch case variables for supported instructions = INS in APDU command
final byte SetKey = (byte) 0xC0;
final byte OneKeyDES = (byte) 0xC1;
final byte TwoKeyDES = (byte) 0xC2;
final byte ThreeKeyDES = (byte) 0xC3;
// Defining switch case variables for cipher algorithms = P1 in APDU command
final byte DES_CBC_ISO9797_M1 = (byte) 0x00;
final byte DES_CBC_ISO9797_M2 = (byte) 0x01;
final byte DES_CBC_NOPAD = (byte) 0x02;
final byte DES_CBC_PKCS5 = (byte) 0x03;
final byte DES_ECB_ISO9797_M1 = (byte) 0x04;
final byte DES_ECB_ISO9797_M2 = (byte) 0x05;
final byte DES_ECB_NOPAD = (byte) 0x06;
final byte DES_ECB_PKCS5 = (byte) 0x07;
// Defining Proprietary Status Words
final short KeyInNotSetGood = 0x6440;
// A flag to be sure that the configured key has the same length that the
// algorithm needs.
private CryptoDES() {
}
public static void install(byte bArray[], short bOffset, byte bLength)
throws ISOException {
new CryptoDES().register();
}
public void process(APDU apdu) throws ISOException {
// Assigning 0 to "ConfiguredKeyLength" to force the user to use ...
// ... "SetKey" command, after applet selection.
if (selectingApplet()) {
ConfiguredKeyLength = 0;
return;
}
byte[] buffer = apdu.getBuffer();
// Checking the CLA field in the APDU command.
if (buffer[ISO7816.OFFSET_CLA] != 0) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
// Checking the P1 and P2 fields in the APDU command.
if (buffer[ISO7816.OFFSET_P1] > 7 || buffer[ISO7816.OFFSET_P2] > 1) {
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
// Analyzing the command.
try {
switch (buffer[ISO7816.OFFSET_INS]) {
case SetKey:
SetCryptoKeyAndInitCipher(apdu);
break;
case OneKeyDES:
OneKeyDESCrypto(apdu);
DoEncryptDecrypt(apdu);
break;
case TwoKeyDES:
TwoKeyDESCrypto(apdu);
DoEncryptDecrypt(apdu);
break;
case (byte) ThreeKeyDES:
ThreeKeyDESCrypto(apdu);
DoEncryptDecrypt(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
} catch (CryptoException e) {
ISOException.throwIt(((CryptoException) e).getReason());
}
}
public void SetCryptoKeyAndInitCipher(APDU apdu)
throws ISOException {
byte[] buffer = apdu.getBuffer();
// Key must has a length of 8, 16 or 24 bytes
if (buffer[ISO7816.OFFSET_LC] == 8 || buffer[ISO7816.OFFSET_LC] == 16
|| buffer[ISO7816.OFFSET_LC] == 24) {
Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, TheDES_Key,
(short) 0, buffer[ISO7816.OFFSET_LC]);
ConfiguredKeyLength = buffer[ISO7816.OFFSET_LC];
} else {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
switch (buffer[ISO7816.OFFSET_P1]) {
case DES_CBC_ISO9797_M1:
MyCipher = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M1, false);
break;
case DES_CBC_ISO9797_M2:
MyCipher = Cipher.getInstance(Cipher.ALG_DES_CBC_ISO9797_M2, false);
break;
case DES_CBC_NOPAD:
MyCipher = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
break;
case DES_CBC_PKCS5:
MyCipher = Cipher.getInstance(Cipher.ALG_DES_CBC_PKCS5, false);
break;
case DES_ECB_ISO9797_M1:
MyCipher = Cipher.getInstance(Cipher.ALG_DES_ECB_ISO9797_M1, false);
break;
case DES_ECB_ISO9797_M2:
MyCipher = Cipher.getInstance(Cipher.ALG_DES_ECB_ISO9797_M2, false);
break;
case DES_ECB_NOPAD:
MyCipher = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
break;
case DES_ECB_PKCS5:
MyCipher = Cipher.getInstance(Cipher.ALG_DES_ECB_PKCS5, false);
break;
}
}
public void OneKeyDESCrypto(APDU apdu)
throws ISOException {
byte[] buffer = apdu.getBuffer();
// Check to see if the configured key is the required key for this ...
// ... algorithm or not
if (ConfiguredKeyLength != 8) {
ISOException.throwIt(KeyInNotSetGood);
}
MyDES1Key.setKey(TheDES_Key, (short) 0);
if (buffer[ISO7816.OFFSET_P2] == 1) {
MyCipher.init(MyDES1Key, Cipher.MODE_ENCRYPT);
} else {
MyCipher.init(MyDES1Key, Cipher.MODE_DECRYPT);
}
}
public void TwoKeyDESCrypto(APDU apdu)
throws ISOException {
byte[] buffer = apdu.getBuffer();
// Check to see if the configured key is the required key for this ...
// ... algorithm or not
if (ConfiguredKeyLength != 16) {
ISOException.throwIt(KeyInNotSetGood);
}
MyDES2Key.setKey(TheDES_Key, (short) 0);
if (buffer[ISO7816.OFFSET_P2] == 1) {
MyCipher.init(MyDES2Key, Cipher.MODE_ENCRYPT);
} else {
MyCipher.init(MyDES2Key, Cipher.MODE_DECRYPT);
}
}
public void ThreeKeyDESCrypto(APDU apdu)
throws ISOException {
byte[] buffer = apdu.getBuffer();
// Check to see if the configured key is the required key for this ...
// ... algorithm or not
if (ConfiguredKeyLength != 24) {
ISOException.throwIt(KeyInNotSetGood);
}
MyDES3Key.setKey(TheDES_Key, (short) 0);
if (buffer[ISO7816.OFFSET_P2] == 1) {
MyCipher.init(MyDES3Key, Cipher.MODE_ENCRYPT);
} else {
MyCipher.init(MyDES3Key, Cipher.MODE_DECRYPT);
}
}
public void DoEncryptDecrypt(APDU apdu) {
byte[] buffer = apdu.getBuffer();
byte[] CipheredData = JCSystem.makeTransientByteArray((short) 32,
JCSystem.CLEAR_ON_DESELECT);
short datalen = apdu.setIncomingAndReceive();
if ((datalen % 8) != 0) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
MyCipher.doFinal(buffer, (short) 0, datalen, CipheredData, (short) 0);
Util.arrayCopyNonAtomic(CipheredData, (short) 0, buffer, (short) 0,
datalen);
apdu.setOutgoingAndSend((short) 0, datalen);
}
}

How to create list of 50 different itext colors

I'm creating pdf tables in java. Each cell has itext, portions of which I need to set the font colors depending on a substring in the cell. I know how to do everything except create a set of about 50 colors different enough from one another that all cells with a particular substring are easily spotted by the user.
Is there an a collection of colors I can use, a clever way of generating such a list?
TIA
Ed S
Please take a look inside the WebColors class. This class extends a HashMap<String, int[]> as well as a public static constant that is created like this:
public static final WebColors NAMES = new WebColors();
static {
NAMES.put("aliceblue", new int[] { 0xf0, 0xf8, 0xff, 0xff });
NAMES.put("antiquewhite", new int[] { 0xfa, 0xeb, 0xd7, 0xff });
NAMES.put("aqua", new int[] { 0x00, 0xff, 0xff, 0xff });
NAMES.put("aquamarine", new int[] { 0x7f, 0xff, 0xd4, 0xff });
NAMES.put("azure", new int[] { 0xf0, 0xff, 0xff, 0xff });
NAMES.put("beige", new int[] { 0xf5, 0xf5, 0xdc, 0xff });
NAMES.put("bisque", new int[] { 0xff, 0xe4, 0xc4, 0xff });
NAMES.put("black", new int[] { 0x00, 0x00, 0x00, 0xff });
NAMES.put("blanchedalmond", new int[] { 0xff, 0xeb, 0xcd, 0xff });
NAMES.put("blue", new int[] { 0x00, 0x00, 0xff, 0xff });
NAMES.put("blueviolet", new int[] { 0x8a, 0x2b, 0xe2, 0xff });
NAMES.put("brown", new int[] { 0xa5, 0x2a, 0x2a, 0xff });
NAMES.put("burlywood", new int[] { 0xde, 0xb8, 0x87, 0xff });
NAMES.put("cadetblue", new int[] { 0x5f, 0x9e, 0xa0, 0xff });
NAMES.put("chartreuse", new int[] { 0x7f, 0xff, 0x00, 0xff });
NAMES.put("chocolate", new int[] { 0xd2, 0x69, 0x1e, 0xff });
NAMES.put("coral", new int[] { 0xff, 0x7f, 0x50, 0xff });
NAMES.put("cornflowerblue", new int[] { 0x64, 0x95, 0xed, 0xff });
NAMES.put("cornsilk", new int[] { 0xff, 0xf8, 0xdc, 0xff });
NAMES.put("crimson", new int[] { 0xdc, 0x14, 0x3c, 0xff });
NAMES.put("cyan", new int[] { 0x00, 0xff, 0xff, 0xff });
NAMES.put("darkblue", new int[] { 0x00, 0x00, 0x8b, 0xff });
NAMES.put("darkcyan", new int[] { 0x00, 0x8b, 0x8b, 0xff });
NAMES.put("darkgoldenrod", new int[] { 0xb8, 0x86, 0x0b, 0xff });
NAMES.put("darkgray", new int[] { 0xa9, 0xa9, 0xa9, 0xff });
NAMES.put("darkgreen", new int[] { 0x00, 0x64, 0x00, 0xff });
NAMES.put("darkkhaki", new int[] { 0xbd, 0xb7, 0x6b, 0xff });
NAMES.put("darkmagenta", new int[] { 0x8b, 0x00, 0x8b, 0xff });
NAMES.put("darkolivegreen", new int[] { 0x55, 0x6b, 0x2f, 0xff });
NAMES.put("darkorange", new int[] { 0xff, 0x8c, 0x00, 0xff });
NAMES.put("darkorchid", new int[] { 0x99, 0x32, 0xcc, 0xff });
NAMES.put("darkred", new int[] { 0x8b, 0x00, 0x00, 0xff });
NAMES.put("darksalmon", new int[] { 0xe9, 0x96, 0x7a, 0xff });
NAMES.put("darkseagreen", new int[] { 0x8f, 0xbc, 0x8f, 0xff });
NAMES.put("darkslateblue", new int[] { 0x48, 0x3d, 0x8b, 0xff });
NAMES.put("darkslategray", new int[] { 0x2f, 0x4f, 0x4f, 0xff });
NAMES.put("darkturquoise", new int[] { 0x00, 0xce, 0xd1, 0xff });
NAMES.put("darkviolet", new int[] { 0x94, 0x00, 0xd3, 0xff });
NAMES.put("deeppink", new int[] { 0xff, 0x14, 0x93, 0xff });
NAMES.put("deepskyblue", new int[] { 0x00, 0xbf, 0xff, 0xff });
NAMES.put("dimgray", new int[] { 0x69, 0x69, 0x69, 0xff });
NAMES.put("dodgerblue", new int[] { 0x1e, 0x90, 0xff, 0xff });
NAMES.put("firebrick", new int[] { 0xb2, 0x22, 0x22, 0xff });
NAMES.put("floralwhite", new int[] { 0xff, 0xfa, 0xf0, 0xff });
NAMES.put("forestgreen", new int[] { 0x22, 0x8b, 0x22, 0xff });
NAMES.put("fuchsia", new int[] { 0xff, 0x00, 0xff, 0xff });
NAMES.put("gainsboro", new int[] { 0xdc, 0xdc, 0xdc, 0xff });
NAMES.put("ghostwhite", new int[] { 0xf8, 0xf8, 0xff, 0xff });
NAMES.put("gold", new int[] { 0xff, 0xd7, 0x00, 0xff });
NAMES.put("goldenrod", new int[] { 0xda, 0xa5, 0x20, 0xff });
NAMES.put("gray", new int[] { 0x80, 0x80, 0x80, 0xff });
NAMES.put("green", new int[] { 0x00, 0x80, 0x00, 0xff });
NAMES.put("greenyellow", new int[] { 0xad, 0xff, 0x2f, 0xff });
NAMES.put("honeydew", new int[] { 0xf0, 0xff, 0xf0, 0xff });
NAMES.put("hotpink", new int[] { 0xff, 0x69, 0xb4, 0xff });
NAMES.put("indianred", new int[] { 0xcd, 0x5c, 0x5c, 0xff });
NAMES.put("indigo", new int[] { 0x4b, 0x00, 0x82, 0xff });
NAMES.put("ivory", new int[] { 0xff, 0xff, 0xf0, 0xff });
NAMES.put("khaki", new int[] { 0xf0, 0xe6, 0x8c, 0xff });
NAMES.put("lavender", new int[] { 0xe6, 0xe6, 0xfa, 0xff });
NAMES.put("lavenderblush", new int[] { 0xff, 0xf0, 0xf5, 0xff });
NAMES.put("lawngreen", new int[] { 0x7c, 0xfc, 0x00, 0xff });
NAMES.put("lemonchiffon", new int[] { 0xff, 0xfa, 0xcd, 0xff });
NAMES.put("lightblue", new int[] { 0xad, 0xd8, 0xe6, 0xff });
NAMES.put("lightcoral", new int[] { 0xf0, 0x80, 0x80, 0xff });
NAMES.put("lightcyan", new int[] { 0xe0, 0xff, 0xff, 0xff });
NAMES.put("lightgoldenrodyellow", new int[] { 0xfa, 0xfa, 0xd2, 0xff });
NAMES.put("lightgreen", new int[] { 0x90, 0xee, 0x90, 0xff });
NAMES.put("lightgrey", new int[] { 0xd3, 0xd3, 0xd3, 0xff });
NAMES.put("lightpink", new int[] { 0xff, 0xb6, 0xc1, 0xff });
NAMES.put("lightsalmon", new int[] { 0xff, 0xa0, 0x7a, 0xff });
NAMES.put("lightseagreen", new int[] { 0x20, 0xb2, 0xaa, 0xff });
NAMES.put("lightskyblue", new int[] { 0x87, 0xce, 0xfa, 0xff });
NAMES.put("lightslategray", new int[] { 0x77, 0x88, 0x99, 0xff });
NAMES.put("lightsteelblue", new int[] { 0xb0, 0xc4, 0xde, 0xff });
NAMES.put("lightyellow", new int[] { 0xff, 0xff, 0xe0, 0xff });
NAMES.put("lime", new int[] { 0x00, 0xff, 0x00, 0xff });
NAMES.put("limegreen", new int[] { 0x32, 0xcd, 0x32, 0xff });
NAMES.put("linen", new int[] { 0xfa, 0xf0, 0xe6, 0xff });
NAMES.put("magenta", new int[] { 0xff, 0x00, 0xff, 0xff });
NAMES.put("maroon", new int[] { 0x80, 0x00, 0x00, 0xff });
NAMES.put("mediumaquamarine", new int[] { 0x66, 0xcd, 0xaa, 0xff });
NAMES.put("mediumblue", new int[] { 0x00, 0x00, 0xcd, 0xff });
NAMES.put("mediumorchid", new int[] { 0xba, 0x55, 0xd3, 0xff });
NAMES.put("mediumpurple", new int[] { 0x93, 0x70, 0xdb, 0xff });
NAMES.put("mediumseagreen", new int[] { 0x3c, 0xb3, 0x71, 0xff });
NAMES.put("mediumslateblue", new int[] { 0x7b, 0x68, 0xee, 0xff });
NAMES.put("mediumspringgreen", new int[] { 0x00, 0xfa, 0x9a, 0xff });
NAMES.put("mediumturquoise", new int[] { 0x48, 0xd1, 0xcc, 0xff });
NAMES.put("mediumvioletred", new int[] { 0xc7, 0x15, 0x85, 0xff });
NAMES.put("midnightblue", new int[] { 0x19, 0x19, 0x70, 0xff });
NAMES.put("mintcream", new int[] { 0xf5, 0xff, 0xfa, 0xff });
NAMES.put("mistyrose", new int[] { 0xff, 0xe4, 0xe1, 0xff });
NAMES.put("moccasin", new int[] { 0xff, 0xe4, 0xb5, 0xff });
NAMES.put("navajowhite", new int[] { 0xff, 0xde, 0xad, 0xff });
NAMES.put("navy", new int[] { 0x00, 0x00, 0x80, 0xff });
NAMES.put("oldlace", new int[] { 0xfd, 0xf5, 0xe6, 0xff });
NAMES.put("olive", new int[] { 0x80, 0x80, 0x00, 0xff });
NAMES.put("olivedrab", new int[] { 0x6b, 0x8e, 0x23, 0xff });
NAMES.put("orange", new int[] { 0xff, 0xa5, 0x00, 0xff });
NAMES.put("orangered", new int[] { 0xff, 0x45, 0x00, 0xff });
NAMES.put("orchid", new int[] { 0xda, 0x70, 0xd6, 0xff });
NAMES.put("palegoldenrod", new int[] { 0xee, 0xe8, 0xaa, 0xff });
NAMES.put("palegreen", new int[] { 0x98, 0xfb, 0x98, 0xff });
NAMES.put("paleturquoise", new int[] { 0xaf, 0xee, 0xee, 0xff });
NAMES.put("palevioletred", new int[] { 0xdb, 0x70, 0x93, 0xff });
NAMES.put("papayawhip", new int[] { 0xff, 0xef, 0xd5, 0xff });
NAMES.put("peachpuff", new int[] { 0xff, 0xda, 0xb9, 0xff });
NAMES.put("peru", new int[] { 0xcd, 0x85, 0x3f, 0xff });
NAMES.put("pink", new int[] { 0xff, 0xc0, 0xcb, 0xff });
NAMES.put("plum", new int[] { 0xdd, 0xa0, 0xdd, 0xff });
NAMES.put("powderblue", new int[] { 0xb0, 0xe0, 0xe6, 0xff });
NAMES.put("purple", new int[] { 0x80, 0x00, 0x80, 0xff });
NAMES.put("red", new int[] { 0xff, 0x00, 0x00, 0xff });
NAMES.put("rosybrown", new int[] { 0xbc, 0x8f, 0x8f, 0xff });
NAMES.put("royalblue", new int[] { 0x41, 0x69, 0xe1, 0xff });
NAMES.put("saddlebrown", new int[] { 0x8b, 0x45, 0x13, 0xff });
NAMES.put("salmon", new int[] { 0xfa, 0x80, 0x72, 0xff });
NAMES.put("sandybrown", new int[] { 0xf4, 0xa4, 0x60, 0xff });
NAMES.put("seagreen", new int[] { 0x2e, 0x8b, 0x57, 0xff });
NAMES.put("seashell", new int[] { 0xff, 0xf5, 0xee, 0xff });
NAMES.put("sienna", new int[] { 0xa0, 0x52, 0x2d, 0xff });
NAMES.put("silver", new int[] { 0xc0, 0xc0, 0xc0, 0xff });
NAMES.put("skyblue", new int[] { 0x87, 0xce, 0xeb, 0xff });
NAMES.put("slateblue", new int[] { 0x6a, 0x5a, 0xcd, 0xff });
NAMES.put("slategray", new int[] { 0x70, 0x80, 0x90, 0xff });
NAMES.put("snow", new int[] { 0xff, 0xfa, 0xfa, 0xff });
NAMES.put("springgreen", new int[] { 0x00, 0xff, 0x7f, 0xff });
NAMES.put("steelblue", new int[] { 0x46, 0x82, 0xb4, 0xff });
NAMES.put("tan", new int[] { 0xd2, 0xb4, 0x8c, 0xff });
NAMES.put("teal", new int[] { 0x00, 0x80, 0x80, 0xff });
NAMES.put("thistle", new int[] { 0xd8, 0xbf, 0xd8, 0xff });
NAMES.put("tomato", new int[] { 0xff, 0x63, 0x47, 0xff });
NAMES.put("transparent", new int[] { 0xff, 0xff, 0xff, 0x00 });
NAMES.put("turquoise", new int[] { 0x40, 0xe0, 0xd0, 0xff });
NAMES.put("violet", new int[] { 0xee, 0x82, 0xee, 0xff });
NAMES.put("wheat", new int[] { 0xf5, 0xde, 0xb3, 0xff });
NAMES.put("white", new int[] { 0xff, 0xff, 0xff, 0xff });
NAMES.put("whitesmoke", new int[] { 0xf5, 0xf5, 0xf5, 0xff });
NAMES.put("yellow", new int[] { 0xff, 0xff, 0x00, 0xff });
NAMES.put("yellowgreen", new int[] { 0x9a, 0xcd, 0x32, 0xff });
}
You can use any of these names like this:
BaseColor color = WebColors.getRGBColor(name);
where name is one of the values of the keys available in NAMES, such as "aliceblue", "antiquewhite", and so on. The colors were harvested from http://en.wikipedia.org/wiki/Web_colors

Java Card - Applet selection failed

Below is DES encryption code. I am getting error 0x6999: "Applet selection failed".
package JCardDES;
import javacard.framework.*;
import javacard.security.*;
import javacardx.crypto.*;
public class JCard_DES extends Applet
{
// globals
DESKey deskey;
Cipher cipherCBC;
final short dataOffset = (short) ISO7816.OFFSET_CDATA;
static byte[] TrippleDESKey = {(byte) 0x38, (byte) 0x12, (byte) 0xA4,
(byte) 0x19, (byte) 0xC6, (byte) 0x3B, (byte) 0xE7, (byte) 0x71, (byte) 0x00, (byte) 0x12, (byte) 0x00,
(byte) 0x19, (byte) 0x80, (byte) 0x3B, (byte) 0xE7, (byte) 0x71, (byte) 0x01, (byte) 0x12, (byte) 0x01,
(byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0xE7, (byte) 0x71};
// constructor,
// initialization
private JCard_DES(byte bArray[], short bOffset, byte bLength)
{
try {
deskey = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_3KEY, false);
cipherCBC = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
}
catch (CryptoException e) {
ISOException.throwIt((short) ((short) 0x9000 + e.getReason()));
}
if (bArray[bOffset] == 0)
{
register();
}
else
{
register(bArray, (short)(bOffset+1), bArray[bOffset]);
}
}
// install
public static void install(byte bArray[], short bOffset, byte bLength)
{
new JCard_DES(bArray, bOffset, bLength);
}
public void process(APDU apdu)
{
byte[] buf = apdu.getBuffer();
if (selectingApplet())
{
return;
}
doTrippeDES(apdu);
}
// DES encryption
private void doTrippeDES(APDU apdu)
{
byte a[] = apdu.getBuffer();
short incomingLength = (short) (apdu.setIncomingAndReceive());
if (incomingLength != 24) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
deskey.setKey(TrippleDESKey, (short)0);
cipherCBC.init(deskey, Cipher.MODE_ENCRYPT,new byte[]{0,0,0,0,0,0,0,0},(short)0,(short)8);
cipherCBC.doFinal(a, (short) dataOffset, incomingLength, a, (short) (dataOffset + 24));
cipherCBC.init(deskey, Cipher.MODE_DECRYPT,new byte[]{0,0,0,0,0,0,0,0},(short)0,(short)8);
cipherCBC.doFinal(a, (short) (dataOffset + 24), incomingLength, a, (short) (dataOffset + 48));
// send results
apdu.setOutgoing();
apdu.setOutgoingLength((short) 72);
apdu.sendBytesLong(a, (short) dataOffset, (short) 72);
}
}
That's strange, because without the initialization codes in try/catch block, there is no problem to select the applet.
My script file (APDU script) is
powerup;
// Select JCard_DES
0x00 0xA4 0x04 0x00 0X06 0XFC 0X74 0X41 0XA1 0X9B 0X63 0x7F;
Please guide me where i'm going wrong since i'm new to Java Card Programming
Thanks
Your command length (Lc) is incorrect. It should be 0x07 instead of 0x06.
0x00 0xA4 0x04 0x00 0X07 0XFC 0X74 0X41 0XA1 0X9B 0X63 0x7F
error code 0x6999 means applet selection failed.To determine the correctness of your aid and uniqueness.Pay attention to rules inside sometimes choose aid will appear automatically when the concept of completion.