Java Code Examples for javacard.framework.Util#arrayCopyNonAtomic()
The following examples show how to use
javacard.framework.Util#arrayCopyNonAtomic() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Records.java From CardExamples with The Unlicense | 6 votes |
/** * Constructor for SFI Record object. * * @param sfi * @param recordNumber * @param data * @param dataOffset * @param dataLength */ private Record(byte sfi, byte recordNumber, byte[] data, short dataOffset, short dataLength) { this.sfi = sfi; this.recordNumber = recordNumber; // Add tag and length to record data. short recordLength = (short) (dataLength + (byte) 2); if (dataLength > (short) 127) { recordLength++; } this.data = new byte[recordLength]; // Reuse 'recordLength' to track offset. recordLength = (short) 0; this.data[recordLength++] = Constants.TAG_READ_RECORD_RESPONSE_MESSAGE_TEMPLATE; if (dataLength > (short) 127) { this.data[recordLength++] = (byte) 0x81; } this.data[recordLength++] = (byte) dataLength; this.dataLength = Util.arrayCopyNonAtomic(data, dataOffset, this.data, recordLength, dataLength); }
Example 2
Source File: Bip32ObjectManager.java From SatochipApplet with GNU Affero General Public License v3.0 | 6 votes |
/** * Creates an object by reserving a fixed memory size for it. * Throws a SW_NO_MEMORY_LEFT exception if cannot allocate the memory. * * @param src * the source array to copy from * @param srcOff * the offset for the source array * * @return The memory base address for the object. */ public short createObject(byte[] src, short srcOff) { if (nb_elem_free == 0) ISOException.throwIt(SW_NO_MEMORY_LEFT); short base=0; while (base<this.size) { if (Util.arrayCompare(this.ptr, base, this.empty, (short)0, this.size_id)==0){ Util.arrayCopyNonAtomic(src, srcOff, this.ptr, base, this.size_elem); this.nb_elem_free--; this.nb_elem_used++; return base; } base+=this.size_elem; } return NULL_OFFSET;//should not happen }
Example 3
Source File: ECPoint.java From JCMathLib with MIT License | 5 votes |
/** * Returns the Y coordinate of this point in uncompressed form. * * @param buffer output array for Y coordinate * @param offset start offset within output array * @return length of Y coordinate (in bytes) */ public short getY(byte[] buffer, short offset) { ech.lock(ech.uncompressed_point_arr1); thePoint.getW(ech.uncompressed_point_arr1, (short) 0); Util.arrayCopyNonAtomic(ech.uncompressed_point_arr1, (short)(1 + this.theCurve.COORD_SIZE), buffer, offset, this.theCurve.COORD_SIZE); ech.unlock(ech.uncompressed_point_arr1); return this.theCurve.COORD_SIZE; }
Example 4
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void handleGetHalfPublicKey(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); apdu.setIncomingAndReceive(); short offset = ISO7816.OFFSET_CDATA; byte derivationSize = buffer[offset++]; byte i; if (Crypto.keyAgreement == null) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (derivationSize > MAX_DERIVATION_PATH) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } Crypto.initCipher(chipKey, false); Crypto.blobEncryptDecrypt.doFinal(masterDerived, (short)0, (short)DEFAULT_SEED_LENGTH, scratch256, (short)0); i = Bip32Cache.copyPrivateBest(buffer, (short)(ISO7816.OFFSET_CDATA + 1), derivationSize, scratch256, (short)0); for (; i<derivationSize; i++) { Util.arrayCopyNonAtomic(buffer, (short)(offset + 4 * i), scratch256, Bip32.OFFSET_DERIVATION_INDEX, (short)4); if ((proprietaryAPI == null) && ((scratch256[Bip32.OFFSET_DERIVATION_INDEX] & (byte)0x80) == 0)) { if (!Bip32Cache.setPublicIndex(buffer, (short)(ISO7816.OFFSET_CDATA + 1), i)) { ISOException.throwIt(SW_PUBLIC_POINT_NOT_AVAILABLE); } } if (!Bip32.derive(buffer)) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } Bip32Cache.storePrivate(buffer, (short)(ISO7816.OFFSET_CDATA + 1), (byte)(i + 1), scratch256); } Crypto.initTransientPrivate(scratch256, (short)0); Crypto.keyAgreement.init(Crypto.transientPrivate); Crypto.keyAgreement.generateSecret(Secp256k1.SECP256K1_G, (short)0, (short)Secp256k1.SECP256K1_G.length, scratch256, (short)32); offset = 0; Crypto.random.generateData(buffer, (short)offset, (short)32); offset += 32; Util.arrayCopyNonAtomic(scratch256, (short)32, buffer, offset, (short)32); offset += 32; signTransientPrivate(scratch256, (short)0, buffer, (short)0, buffer, offset); offset += buffer[(short)(offset + 1)] + 2; Crypto.digestScratch.doFinal(buffer, (short)0, (short)32, buffer, (short)0); apdu.setOutgoingAndSend((short)0, offset); }
Example 5
Source File: FIDOCCImplementation.java From CCU2F with Apache License 2.0 | 5 votes |
private short computeHmacSha256(byte[] key, short key_offset, short key_length, byte[] message, short message_offset, short message_length, byte[] mac, short mac_offset){ byte[] hmacBuffer = JCSystem.makeTransientByteArray((short) 128, JCSystem.CLEAR_ON_DESELECT); short BLOCKSIZE=64; short HASHSIZE=32; // compute inner hash for (short i=0; i<key_length; i++){ hmacBuffer[i]= (byte) (key[(short)(key_offset+i)] ^ (0x36)); } Util.arrayFillNonAtomic(hmacBuffer, key_length, (short)(BLOCKSIZE-key_length), (byte)0); Util.arrayCopyNonAtomic(message, message_offset, hmacBuffer, BLOCKSIZE, message_length); sha256.reset(); sha256.doFinal(hmacBuffer, (short)0, (short)(BLOCKSIZE+message_length), hmacBuffer, BLOCKSIZE); // copy hash result to data buffer! // compute outer hash for (short i=0; i<key_length; i++){ hmacBuffer[i]= (byte) (key[(short)(key_offset+i)] ^ (0x5c)); } Util.arrayFillNonAtomic(hmacBuffer, key_length, (short)(BLOCKSIZE-key_length), (byte)0); // previous hash already copied to correct offset in scratch sha256.reset(); sha256.doFinal(hmacBuffer, (short)0, (short)(BLOCKSIZE+HASHSIZE), mac, mac_offset); return HASHSIZE; }
Example 6
Source File: Bignat.java From JCMathLib with MIT License | 5 votes |
/** * Shifts stored value to right by specified number of bytes. This operation equals to multiplication by value numBytes * 256. * @param numBytes number of bytes to shift */ public void shift_bytes_right(short numBytes) { // Move whole content by numBytes offset bnh.lock(bnh.fnc_shift_bytes_right_tmp); Util.arrayCopyNonAtomic(this.value, (short) 0, bnh.fnc_shift_bytes_right_tmp, (short) 0, (short) (this.value.length)); Util.arrayCopyNonAtomic(bnh.fnc_shift_bytes_right_tmp, (short) 0, this.value, numBytes, (short) ((short) (this.value.length) - numBytes)); Util.arrayFillNonAtomic(this.value, (short) 0, numBytes, (byte) 0); bnh.unlock(bnh.fnc_shift_bytes_right_tmp); }
Example 7
Source File: PasswordManagerApplet.java From sim-password-manager with Apache License 2.0 | 5 votes |
private void initAes() { Util.arrayCopyNonAtomic(iv, OFFSET_ZERO, cbcV, OFFSET_ZERO, (short) iv.length); Util.arrayFillNonAtomic(cbcNextV, OFFSET_ZERO, (short) cbcNextV.length, (byte) 0); Util.arrayFillNonAtomic(roundKeysBuff, OFFSET_ZERO, (short) roundKeysBuff.length, (byte) 0); }
Example 8
Source File: Records.java From CardExamples with The Unlicense | 5 votes |
/** * Find record, retrieve record data, return record data. * * @param sfi * @param recordNumber * @param dataBuffer * @return */ short getRecordData(byte sfi, short recordNumber, byte[] dataBuffer) { byte result = findSFIRecord(sfi, recordNumber); if (result == RECORD_FOUND) { return Util.arrayCopyNonAtomic(this.foundRecord.data, (short) 0, dataBuffer, (short) 0, this.foundRecord.dataLength); } // Use offset 1 to indicate error type. dataBuffer[(byte) 1] = result; // Record not found. // dataBuffer[1] = 0x00 if SFI not found. // 0x01 if SFI found, record number not found. return (short) -1; }
Example 9
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function imports a Bip32 seed to the applet and derives the master key and chain code. * It also derives a second ECC that uniquely authenticates the HDwallet: the authentikey. * Lastly, it derives a 32-bit AES key that is used to encrypt/decrypt Bip32 object stored in secure memory * If the seed already exists, it is reset if the logged identities allow it. * * The function returns the x-coordinate of the authentikey, self-signed. * The authentikey full public key can be recovered from the signature. * * ins: 0x6C * p1: seed_size(1b) * p2: 0x00 * data: [seed_data (seed_size)] * return: [coordx_size(2b) | coordx | sig_size(2b) | sig] */ private short importBIP32Seed(APDU apdu, byte[] buffer){ // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); if (buffer[ISO7816.OFFSET_P2] != (byte) 0x00) ISOException.throwIt(SW_INCORRECT_P2); // if already seeded, must call resetBIP32Seed first! if (bip32_seeded) ISOException.throwIt(SW_BIP32_INITIALIZED_SEED); short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); // get seed bytesize (max 64 bytes) byte bip32_seedsize = buffer[ISO7816.OFFSET_P1]; if (bip32_seedsize <0 || bip32_seedsize>64) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); short offset= (short)ISO7816.OFFSET_CDATA; // derive master key! HmacSha512.computeHmacSha512(BITCOIN_SEED, (short)0, (short)BITCOIN_SEED.length, buffer, offset, (short)bip32_seedsize, recvBuffer, (short)0); bip32_masterkey.setKey(recvBuffer, (short)0); // data must be exactly 32 bytes long bip32_masterchaincode.setKey(recvBuffer, (short)32); // data must be exactly 32 bytes long // derive 2 more keys from seed: // - AES encryption key for secure storage of extended keys in object // - ECC key for authentication of sensitive data returned by the applet (hash, pubkeys) HmacSha512.computeHmacSha512(BITCOIN_SEED2, (short)0, (short)BITCOIN_SEED2.length, buffer, offset, (short)bip32_seedsize, recvBuffer, (short)64); bip32_authentikey.setS(recvBuffer, (short)64, BIP32_KEY_SIZE); bip32_encryptkey.setKey(recvBuffer, (short)96); // AES-128: 16-bytes key!! // bip32 is now seeded bip32_seeded= true; // clear recvBuffer Util.arrayFillNonAtomic(recvBuffer, (short)0, (short)128, (byte)0); // compute the partial authentikey public key... keyAgreement.init(bip32_authentikey); short coordx_size= (short)32; keyAgreement.generateSecret(Secp256k1.SECP256K1, Secp256k1.OFFSET_SECP256K1_G, (short) 65, authentikey_pubkey, (short)0); //pubkey in uncompressed form Util.setShort(buffer, (short)0, coordx_size); Util.arrayCopyNonAtomic(authentikey_pubkey, (short)1, buffer, (short)2, coordx_size); // self signed public key sigECDSA.init(bip32_authentikey, Signature.MODE_SIGN); short sign_size= sigECDSA.sign(buffer, (short)0, (short)(coordx_size+2), buffer, (short)(coordx_size+4)); Util.setShort(buffer, (short)(2+coordx_size), sign_size); // return x-coordinate of public key+signature // the client can recover full public-key from the signature or // by guessing the compression value () and verifying the signature... // buffer= [coordx_size(2) | coordx | sigsize(2) | sig] return (short)(2+coordx_size+2+sign_size); }
Example 10
Source File: Bignat.java From JCMathLib with MIT License | 4 votes |
/** * One digit left shift. * <P> * Asserts that the first digit is zero. */ public void shift_left() { // NOTE: assumes that overlapping src and dest arrays are properly handled by Util.arrayCopyNonAtomic Util.arrayCopyNonAtomic(this.value, (short) 1, this.value, (short) 0, (short) (size - 1)); value[(short) (size - 1)] = 0; }
Example 11
Source File: Bip32.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
public static boolean derive(byte[] apduBuffer) { boolean isZero = true; byte i; if ((LedgerWalletApplet.scratch256[OFFSET_DERIVATION_INDEX] & (byte)0x80) == 0) { if (LedgerWalletApplet.proprietaryAPI != null) { LedgerWalletApplet.proprietaryAPI.getUncompressedPublicPoint(LedgerWalletApplet.scratch256, (short)0, LedgerWalletApplet.scratch256, OFFSET_TMP); } else { if (!Bip32Cache.copyLastPublic(LedgerWalletApplet.scratch256, OFFSET_TMP)) { return false; } } AddressUtils.compressPublicKey(LedgerWalletApplet.scratch256, OFFSET_TMP); } else { LedgerWalletApplet.scratch256[OFFSET_TMP] = 0; Util.arrayCopyNonAtomic(LedgerWalletApplet.scratch256, (short)0, LedgerWalletApplet.scratch256, (short)(OFFSET_TMP + 1), (short)32); } Util.arrayCopyNonAtomic(LedgerWalletApplet.scratch256, OFFSET_DERIVATION_INDEX, LedgerWalletApplet.scratch256, (short)(OFFSET_TMP + 33), (short)4); if (Crypto.signatureHmac != null) { Crypto.keyHmac.setKey(LedgerWalletApplet.scratch256, (short)32, (short)32); if ((LedgerWalletApplet.proprietaryAPI != null) && (LedgerWalletApplet.proprietaryAPI.hasHmacSHA512())) { LedgerWalletApplet.proprietaryAPI.hmacSHA512(Crypto.keyHmac, LedgerWalletApplet.scratch256, OFFSET_TMP, (short)37, LedgerWalletApplet.scratch256, OFFSET_TMP); } else { Crypto.signatureHmac.init(Crypto.keyHmac, Signature.MODE_SIGN); Crypto.signatureHmac.sign(LedgerWalletApplet.scratch256, OFFSET_TMP, (short)37, LedgerWalletApplet.scratch256, OFFSET_TMP); } } else { HmacSha512.hmac(LedgerWalletApplet.scratch256, (short)32, (short)32, LedgerWalletApplet.scratch256, OFFSET_TMP, (short)37, LedgerWalletApplet.scratch256, OFFSET_TMP, apduBuffer, OFFSET_BLOCK); } if (MathMod256.ucmp(LedgerWalletApplet.scratch256, OFFSET_TMP, Secp256k1.SECP256K1_R, (short)0) >= 0) { return false; } MathMod256.addm(LedgerWalletApplet.scratch256, (short)0, LedgerWalletApplet.scratch256, OFFSET_TMP, LedgerWalletApplet.scratch256, (short)0, Secp256k1.SECP256K1_R, (short)0); for (i=0; i<(byte)32; i++) { if (LedgerWalletApplet.scratch256[i] != 0) { isZero = false; break; } } if (isZero) { return false; } Util.arrayCopyNonAtomic(LedgerWalletApplet.scratch256, (short)(OFFSET_TMP + 32), LedgerWalletApplet.scratch256, (short)32, (short)32); return true; }
Example 12
Source File: Keycard.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
public static void setPairingData(byte[] data, short offset) { pairingData[0] = (byte)0x01; Util.arrayCopyNonAtomic(data, offset, pairingData, (short)1, PAIRING_DATA_SIZE); }
Example 13
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
private static void handleSignMessage(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); short offset = ISO7816.OFFSET_CDATA; if (buffer[ISO7816.OFFSET_P1] == P1_PREPARE_MESSAGE) { byte derivationSize = buffer[offset++]; boolean addressVerified = false; if (Util.arrayCompare(buffer, offset, SLIP13_HEAD, (short)0, (short)SLIP13_HEAD.length) == (short)0) { addressVerified = true; } else { for (byte i=0; i<derivationSize; i++) { if ((Util.arrayCompare(buffer, (short)(offset + 2), BITID_DERIVE, (short)0, (short)BITID_DERIVE.length) == (short)0) || (Util.arrayCompare(buffer, (short)(offset + 2), BITID_DERIVE_MULTIPLE, (short)0, (short)BITID_DERIVE_MULTIPLE.length) == (short)0)) { addressVerified = true; break; } offset += 4; } } if (!addressVerified) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } offset = (short)(ISO7816.OFFSET_CDATA + 1 + 4 * derivationSize); short messageLength = (short)(buffer[offset++] & 0xff); Crypto.digestFull.reset(); Crypto.digestFull.update(SIGNMAGIC, (short)0, (short)SIGNMAGIC.length); scratch256[(short)100] = (byte)messageLength; Crypto.digestFull.update(scratch256, (short)100, (short)1); Crypto.digestFull.doFinal(buffer, offset, messageLength, scratch256, (short)32); signTransientPrivate(scratch256, (short)0, scratch256, (short)32, scratch256, (short)100); Util.arrayFillNonAtomic(scratch256, (short)0, (short)64, (byte)0x00); buffer[(short)0] = (byte)0x00; TC.ctx[TC.TX_B_MESSAGE_SIGN_READY] = (byte)0x01; apdu.setOutgoingAndSend((short)0, (short)1); } else if (buffer[ISO7816.OFFSET_P1] == P1_SIGN_MESSAGE) { if (TC.ctx[TC.TX_B_MESSAGE_SIGN_READY] != (byte)0x01) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } TC.ctx[TC.TX_B_MESSAGE_SIGN_READY] = (byte)0x00; short signatureSize = (short)((short)(scratch256[(short)101] & 0xff) + 2); Util.arrayCopyNonAtomic(scratch256, (short)100, buffer, (short)0, signatureSize); apdu.setOutgoingAndSend((short)0, signatureSize); } else { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } }
Example 14
Source File: JavaCardAES.java From sim-password-manager with Apache License 2.0 | 4 votes |
/** * Sechedule AES round keys fro given key material * @param key ... key array * @param keyOffset ... start offset in key array * @param aesRoundKeys ... array to hold scheduled keys */ public void RoundKeysSchedule(byte key[], short keyOffset, byte aesRoundKeys[]) { byte i; byte j; byte round; byte rconpointer = 0; short sourceOffset = 0; short targetOffset = 0; // hlp CONTAINS PRECALCULATED EXPRESSION (round * (4 * KEYN)) short hlp = 0; // FIRST KEY (SAME AS INPUT KEY) Util.arrayCopyNonAtomic(key, keyOffset, aesRoundKeys, (short) 0, STATELEN); // 10 ROUNDS KEYS for (round = 1; round <= N_ROUNDS; round++) { // TIME REDUCING PRECALCULATION hlp += STATELEN; // COPY KEY FOR round - 1 TO BUFFER FOR round Util.arrayCopyNonAtomic(aesRoundKeys, (short) ((round - 1) * STATELEN), aesRoundKeys, hlp, STATELEN); rconpointer = (byte) (round - 1); for (i = 0; i < 4; i++) { sourceOffset = (short) ( ((i + 1) % 4) + ((KEYN-1) * 4) + hlp ); targetOffset = (short) ( i + (0 * 4) + hlp ); aesRoundKeys[targetOffset] ^= SBox[(aesRoundKeys[sourceOffset] >= 0) ? aesRoundKeys[sourceOffset] : (short) (256 + aesRoundKeys[sourceOffset])]; } aesRoundKeys[hlp] ^= rcon[rconpointer]; for (j = 1; j < KEYN; j++) { for (i = 0; i < 4; i++) { sourceOffset = (short) (i + ((j - 1) * 4) + hlp); targetOffset = (short) ((i + (j * 4)) + hlp); aesRoundKeys[targetOffset] ^= aesRoundKeys[sourceOffset]; } } } }
Example 15
Source File: Base58.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
public static short decode(byte[] in, short inOffset, short inLength, byte[] out, short outOffset, byte[] scratch, short scratchOffset) { try { short zeroCount = (short)0, j, startAt; for (short i=0; i<inLength; i++) { short value = (short)(in[(short)(inOffset + i)] & 0xff); if (value > 128) { return (short)-1; } byte base58Value = BASE58TABLE[value]; if (base58Value == (byte)0xff) { return (short)-1; } scratch[(short)(scratchOffset + i)] = base58Value; } while ((zeroCount < inLength) && (scratch[(short)(scratchOffset + zeroCount)] == 0)) { ++zeroCount; } j = inLength; startAt = zeroCount; while (startAt < inLength) { short remainder = 0; short divLoop; for (divLoop = startAt ; divLoop < inLength; divLoop++) { short digit256 = (short)(scratch[(short)(scratchOffset + divLoop)] & 0xff); short tmpDiv = (short)(remainder * 58 + digit256); scratch[(short)(scratchOffset + divLoop)] = (byte)(tmpDiv / 256); remainder = (short)(tmpDiv % 256); } if (scratch[(short)(scratchOffset + startAt)] == 0) { ++startAt; } out[(short)(outOffset + --j)] = (byte)remainder; } while ((j < inLength) && (out[(short)(outOffset + j)] == 0)) { j++; } short resultLength = (short)(inLength - (j - zeroCount)); Util.arrayCopyNonAtomic(out, (short)(outOffset + j - zeroCount), out, outOffset, resultLength); return resultLength; } catch(Throwable t) { return (short)-1; } }
Example 16
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
private static void handleTrustedInput(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); byte p1 = buffer[ISO7816.OFFSET_P1]; byte dataOffset = (short)0; apdu.setIncomingAndReceive(); if (p1 == P1_TRUSTED_INPUT_FIRST) { Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, TC.ctx, TC.TX_I_TRANSACTION_TARGET_INPUT, TC.SIZEOF_U32); TC.ctx[TC.TX_B_TRANSACTION_STATE] = Transaction.STATE_NONE; TC.ctx[TC.TX_B_TRUSTED_INPUT_PROCESSED] = (byte)0x00; TC.ctx[TC.TX_B_HASH_OPTION] = Transaction.HASH_FULL; dataOffset = (short)4; } else if (p1 != P1_TRUSTED_INPUT_NEXT) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } short remainingData = (short)((short)(buffer[ISO7816.OFFSET_LC] & 0xff) - dataOffset); byte result = Transaction.parseTransaction(Transaction.PARSE_TRUSTED_INPUT, buffer, (short)(ISO7816.OFFSET_CDATA + dataOffset), remainingData); if (result == Transaction.RESULT_ERROR) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } else if (result == Transaction.RESULT_MORE) { return; } else if (result == Transaction.RESULT_FINISHED) { short offset = 0; buffer[offset++] = BLOB_MAGIC_TRUSTED_INPUT; Crypto.random.generateData(buffer, offset, (short)3); offset += 3; Crypto.digestFull.doFinal(scratch256, (short)0, (short)0, scratch256, (short)0); Crypto.digestFull.doFinal(scratch256, (short)0, (short)32, buffer, offset); offset += 32; GenericBEHelper.swap(TC.SIZEOF_U32, buffer, offset, TC.ctx, TC.TX_I_TRANSACTION_TARGET_INPUT); offset += 4; Util.arrayCopyNonAtomic(TC.ctx, TC.TX_A_TRANSACTION_AMOUNT, buffer, offset, TC.SIZEOF_AMOUNT); offset += TC.SIZEOF_AMOUNT; Crypto.initCipher(trustedInputKey, true); Crypto.blobEncryptDecrypt.doFinal(buffer, (short)0, offset, scratch256, (short)0); Util.arrayCopyNonAtomic(scratch256, (short)(offset - 8), buffer, offset, (short)8); offset += 8; apdu.setOutgoingAndSend((short)0, offset); } }
Example 17
Source File: TransitApplet.java From JCMathLib with MIT License | 4 votes |
/** * Initializes a CAD/card interaction session. This is the first step of * mutual authentication. A new card challenge is generated and used along * with the passed-in host challenge to generate the derivation data from * which a new session key is derived. The card challenge is appended to the * response message. The response message is signed using the newly * generated session key then sent back. Note that mutual authentication is * subsequently completed upon succesful verification of the signature of * the first request received. * * @param apdu * The APDU */ private void initializeSession(APDU apdu) { // C-APDU: [CLA, INS, P1, P2, LC, [4-bytes Host Challenge]] byte[] buffer = apdu.getBuffer(); if ((buffer[ISO7816.OFFSET_P1] != 0) || (buffer[ISO7816.OFFSET_P2] != 0)) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } byte numBytes = buffer[ISO7816.OFFSET_LC]; byte count = (byte) apdu.setIncomingAndReceive(); if (numBytes != CHALLENGE_LENGTH || count != CHALLENGE_LENGTH) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Generate card challenge generateCardChallenge(); // Generate key derivation data from host challenge and card challenge generateKeyDerivationData(buffer); // Generate session key from derivation data generateSessionKey(); // R-APDU: [[4-bytes Card Challenge], [2-bytes Status Word], [8-bytes // MAC]] short offset = 0; // Append card challenge to response message offset = Util.arrayCopyNonAtomic(cardChallenge, (short) 0, buffer, offset, CHALLENGE_LENGTH); // Append status word to response message offset = Util.setShort(buffer, offset, SW_SUCCESS); // Sign response message and append MAC to response message offset = generateMAC(buffer, offset); // Send R-APDU apdu.setOutgoingAndSend((short) 0, offset); }
Example 18
Source File: U2FApplet.java From CCU2F with Apache License 2.0 | 4 votes |
private void handleSign(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); short len = apdu.setIncomingAndReceive(); short dataOffset = apdu.getOffsetCdata(); byte p1 = buffer[ISO7816.OFFSET_P1]; boolean sign = false; boolean counterOverflow = true; short keyHandleLength; boolean extendedLength = (dataOffset != ISO7816.OFFSET_CDATA); short outOffset = SCRATCH_PAD; if (len < 65) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } switch(p1) { case P1_SIGN_OPERATION: sign = true; break; case P1_SIGN_CHECK_ONLY: break; default: ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } // Check if the counter overflowed if (counterOverflowed) { ISOException.throwIt(ISO7816.SW_FILE_FULL); } // Verify key handle if (localPrivateTransient) { Secp256r1.setCommonCurveParameters(localPrivateKey); } keyHandleLength = (short)(buffer[(short)(dataOffset + 64)] & 0xff); if (!fidoImpl.unwrap(buffer, (short)(dataOffset + 65), keyHandleLength, buffer, (short)(dataOffset + APDU_APPLICATION_PARAMETER_OFFSET), (sign ? localPrivateKey : null))) { ISOException.throwIt(FIDO_SW_INVALID_KEY_HANDLE); } // If not signing, return with the "correct" exception if (!sign) { ISOException.throwIt(FIDO_SW_TEST_OF_PRESENCE_REQUIRED); } // If signing, only proceed if user presence can be validated if ((flags & INSTALL_FLAG_DISABLE_USER_PRESENCE) == 0) { if (scratchPersistent[0] != 0) { ISOException.throwIt(FIDO_SW_TEST_OF_PRESENCE_REQUIRED); } } scratchPersistent[0] = (byte)1; // Increase the counter boolean carry = false; JCSystem.beginTransaction(); for (byte i=0; i<4; i++) { short addValue = (i == 0 ? (short)1 : (short)0); short val = (short)((short)(counter[(short)(4 - 1 - i)] & 0xff) + addValue); if (carry) { val++; } carry = (val > 255); counter[(short)(4 - 1 - i)] = (byte)val; } JCSystem.commitTransaction(); if (carry) { // Game over counterOverflowed = true; ISOException.throwIt(ISO7816.SW_FILE_FULL); } // Prepare reply scratch[outOffset++] = FLAG_USER_PRESENCE_VERIFIED; outOffset = Util.arrayCopyNonAtomic(counter, (short)0, scratch, outOffset, (short)4); localSignature.init(localPrivateKey, Signature.MODE_SIGN); localSignature.update(buffer, (short)(dataOffset + APDU_APPLICATION_PARAMETER_OFFSET), (short)32); localSignature.update(scratch, SCRATCH_PAD, (short)5); outOffset += localSignature.sign(buffer, (short)(dataOffset + APDU_CHALLENGE_OFFSET), (short)32, scratch, outOffset); if (extendedLength) { // If using extended length, the message can be completed and sent immediately scratch[SCRATCH_TRANSPORT_STATE] = TRANSPORT_EXTENDED; Util.arrayCopyNonAtomic(scratch, SCRATCH_PAD, buffer, (short)0, outOffset); apdu.setOutgoingAndSend((short)0, (short)(outOffset - SCRATCH_PAD)); } else { // Otherwise send the first chunk scratch[SCRATCH_TRANSPORT_STATE] = TRANSPORT_NOT_EXTENDED; Util.setShort(scratch, SCRATCH_CURRENT_OFFSET, (short)0); Util.setShort(scratch, SCRATCH_SIGNATURE_LENGTH, (short)0); Util.setShort(scratch, SCRATCH_NONCERT_LENGTH, (short)(outOffset - SCRATCH_PAD)); Util.setShort(scratch, SCRATCH_FULL_LENGTH, (short)(outOffset - SCRATCH_PAD)); scratch[SCRATCH_INCLUDE_CERT] = (byte)0; handleGetData(apdu); } }
Example 19
Source File: Gpg.java From OpenPGP-Card with GNU General Public License v3.0 | 4 votes |
private void decrypt(APDU apdu) { byte[] buffer = apdu.getBuffer(); // PW1 with 0x82 if (!pins[PIN_INDEX_PW1].isValidated() || !pinSubmitted[1]) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (!confidentialityKey.getPrivate().isInitialized()) { ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND); } boolean firstCommand = (commandChainingBuffer[TEMP_INS] != buffer[ISO7816.OFFSET_INS]); // Mark the command chain as bad so it stays in this state in case of exception. short len = apdu.setIncomingAndReceive(); if (len < 1) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (firstCommand) { Util.arrayCopyNonAtomic(buffer, (short) (ISO7816.OFFSET_CDATA + 1), commandChainingBuffer, TEMP_GET_RESPONSE_DATA, (short) (len - 1)); len = (short) (len - 1); } else { short existing = Util.getShort(commandChainingBuffer, TEMP_GET_RESPONSE_LENGTH); if ((short) (len + existing) > RSA_KEY_LENGTH_BYTES) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, commandChainingBuffer, (short) (TEMP_GET_RESPONSE_DATA + existing), len); len += existing; } if (len < RSA_KEY_LENGTH_BYTES) { commandChainingBuffer[TEMP_INS] = CMD_COMPUTE_PSO; Util.setShort(commandChainingBuffer, TEMP_GET_RESPONSE_LENGTH, len); return; // For compatibily with GPG } // We have enough bytes to decrypt. cipherRSA.init(confidentialityKey.getPrivate(), Cipher.MODE_DECRYPT); len = cipherRSA.doFinal(commandChainingBuffer, TEMP_GET_RESPONSE_DATA, RSA_KEY_LENGTH_BYTES, buffer, (short) 0); // Clear command chaining buffer to make ready for next operation. Util.arrayFillNonAtomic(commandChainingBuffer, (short) 0, (short) commandChainingBuffer.length, (byte) 0); apdu.setOutgoingAndSend((short) 0, len); }
Example 20
Source File: Bignat.java From JCMathLib with MIT License | 2 votes |
/** * Serialize this Bignat value into a provided buffer * @param buffer target buffer * @param bufferOffset start offset in buffer * @return number of bytes copied */ public short copy_to_buffer(byte[] buffer, short bufferOffset) { Util.arrayCopyNonAtomic(value, (short) 0, buffer, bufferOffset, size); return size; }