Java Code Examples for javacard.framework.ISO7816#OFFSET_P1
The following examples show how to use
javacard.framework.ISO7816#OFFSET_P1 .
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: OCUnitTests.java From JCMathLib with MIT License | 6 votes |
void test_INT_ADD(APDU apdu, short dataLen) { byte[] apdubuf = apdu.getBuffer(); short p1 = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF); PM.check(PM.TRAP_INT_ADD_1); //Integer num_add_1 = new Integer(dataLen, (short) 0, apdubuf, ISO7816.OFFSET_CDATA); Integer num_add_1 = m_testINT1; num_add_1.fromByteArray(apdubuf, ISO7816.OFFSET_CDATA, p1); PM.check(PM.TRAP_INT_ADD_2); //Integer num_add_2 = new Integer((short) (dataLen - p1), (short) 0, apdubuf, (short) (ISO7816.OFFSET_CDATA + p1)); Integer num_add_2 = m_testINT2; num_add_2.fromByteArray(apdubuf, (short) (ISO7816.OFFSET_CDATA + p1), p1); PM.check(PM.TRAP_INT_ADD_3); num_add_1.add(num_add_2); PM.check(PM.TRAP_INT_ADD_4); short len = num_add_1.toByteArray(apdubuf, (short) 0); apdu.setOutgoingAndSend((short) 0, len); }
Example 2
Source File: OCUnitTests.java From JCMathLib with MIT License | 6 votes |
void test_BN_SUB(APDU apdu, short dataLen) { byte[] apdubuf = apdu.getBuffer(); short p1 = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF); PM.check(PM.TRAP_BN_SUB_1); Bignat sub1 = m_testBN1; sub1.set_size(p1); PM.check(PM.TRAP_BN_SUB_2); Bignat sub2 = m_testBN2; sub2.set_size((short) (dataLen - p1)); PM.check(PM.TRAP_BN_SUB_3); Bignat result = m_testBN3; result.set_size((short) (p1 + 1)); PM.check(PM.TRAP_BN_SUB_4); sub1.from_byte_array(dataLen, (short)0, apdubuf, ISO7816.OFFSET_CDATA); sub2.from_byte_array(dataLen, (short)0, apdubuf, (short)(ISO7816.OFFSET_CDATA+p1)); PM.check(PM.TRAP_BN_SUB_5); result.copy(sub1); PM.check(PM.TRAP_BN_SUB_6); result.subtract(sub2); PM.check(PM.TRAP_BN_SUB_7); short len = result.copy_to_buffer(apdubuf, (short) 0); apdu.setOutgoingAndSend((short) 0, len); }
Example 3
Source File: IsoApplet.java From IsoApplet with GNU General Public License v3.0 | 6 votes |
/** * \brief Process the PUT DATA apdu (INS=DB). * * PUT DATA is currently used for private key import. * * \throw ISOException SW_SECURITY_STATUS_NOT_SATISFIED, SW_INCORRECT_P1P2 */ private void processPutData(APDU apdu) throws ISOException { byte[] buf = apdu.getBuffer(); byte p1 = buf[ISO7816.OFFSET_P1]; byte p2 = buf[ISO7816.OFFSET_P2]; if( ! pin.isValidated() ) { ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED); } if(p1 == (byte) 0x3F && p2 == (byte) 0xFF) { if( ! DEF_PRIVATE_KEY_IMPORT_ALLOWED) { ISOException.throwIt(SW_COMMAND_NOT_ALLOWED_GENERAL); } importPrivateKey(apdu); } else { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } }
Example 4
Source File: OCUnitTests.java From JCMathLib with MIT License | 6 votes |
void test_BN_MUL_MOD(APDU apdu, short dataLen) { byte[] apdubuf = apdu.getBuffer(); short p1 = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF); short p2 = (short) (apdubuf[ISO7816.OFFSET_P2] & 0x00FF); PM.check(PM.TRAP_BN_MUL_MOD_1); Bignat num1 = m_testBN1; num1.set_size(p1); PM.check(PM.TRAP_BN_MUL_MOD_2); Bignat num2 = m_testBN2; num2.set_size(p2); PM.check(PM.TRAP_BN_MUL_MOD_3); Bignat mod = m_testBN3; mod.set_size((short) (dataLen - p1 - p2)); PM.check(PM.TRAP_BN_MUL_MOD_4); num1.from_byte_array(p1, (short)0, apdubuf, ISO7816.OFFSET_CDATA); num2.from_byte_array(p2, (short)0, apdubuf, (short)(ISO7816.OFFSET_CDATA+p1)); mod.from_byte_array((short)(dataLen-p1-p2), (short)0, apdubuf, (short)(ISO7816.OFFSET_CDATA+p1+p2)); PM.check(PM.TRAP_BN_MUL_MOD_5); num1.mod_mult(num1, num2, mod); PM.check(PM.TRAP_BN_MUL_MOD_6); short len = num1.copy_to_buffer(apdubuf, (short) 0); apdu.setOutgoingAndSend((short) 0, len); }
Example 5
Source File: Gpg.java From OpenPGP-Card with GNU General Public License v3.0 | 5 votes |
/** * RESET RETRY COUNTER ADPU implementation. */ private void resetRetryCounter(APDU apdu) { byte buffer[] = apdu.getBuffer(); short length = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF); if (apdu.setIncomingAndReceive() != length) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (buffer[ISO7816.OFFSET_P2] != (byte) 0x81) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } if (buffer[ISO7816.OFFSET_P1] == (byte) 0) { // We need to check RC then update P1 (if RC is set). byte rcLength = pinLength[PIN_INDEX_RC]; if (pins[PIN_INDEX_RC].getTriesRemaining() == 0 || rcLength == 0) { ISOException.throwIt(SW_PIN_BLOCKED); } if (length < rcLength + MIN_PIN1_LENGTH || length > rcLength + MAX_PIN_LENGTH) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (pins[PIN_INDEX_RC].check(buffer, ISO7816.OFFSET_CDATA, rcLength)) { updatePIN(PIN_INDEX_PW1, buffer, (short) (ISO7816.OFFSET_CDATA + rcLength), (byte) (length - rcLength)); } else { ISOException.throwIt((short) (SW_PIN_FAILED_00 + pins[PIN_INDEX_RC].getTriesRemaining())); } } else if (buffer[ISO7816.OFFSET_P1] == (byte) 2) { // Resetting by assuming that PW3 was submitted. if (!pins[PIN_INDEX_PW3].isValidated()) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (length < MIN_PIN1_LENGTH || length > MAX_PIN_LENGTH) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } updatePIN(PIN_INDEX_PW1, buffer, ISO7816.OFFSET_CDATA, (byte) length); } else { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } }
Example 6
Source File: NdefApplet.java From openjavacard-ndef with GNU General Public License v3.0 | 5 votes |
/** * Process a SELECT command * * This handles only the one case mandated by the NDEF * specification: SELECT FIRST-OR-ONLY BY-FILE-ID. * * The file ID is specified in the APDU contents. It * must be exactly two bytes long and also valid. * * @param apdu to process * @throws ISOException on error */ private void processSelect(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); byte p1 = buffer[ISO7816.OFFSET_P1]; byte p2 = buffer[ISO7816.OFFSET_P2]; // we only support what the NDEF spec prescribes if(p1 != SELECT_P1_BY_FILEID || p2 != SELECT_P2_FIRST_OR_ONLY) { ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } // receive data short lc = apdu.setIncomingAndReceive(); // check length, must be for a file ID if(lc != 2) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // retrieve the file ID short fileId = Util.getShort(buffer, ISO7816.OFFSET_CDATA); // perform selection if the ID is valid if(fileId == FILEID_NDEF_CAPABILITIES || fileId == FILEID_NDEF_DATA) { vars[VAR_SELECTED_FILE] = fileId; } else { ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND); } }
Example 7
Source File: OCUnitTests.java From JCMathLib with MIT License | 5 votes |
void test_INT_STR(APDU apdu, short dataLen) { byte[] apdubuf = apdu.getBuffer(); short p1 = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF); PM.check(PM.TRAP_INT_STR_1); //Integer num_int = new Integer(dataLen, (short) 0, apdubuf, ISO7816.OFFSET_CDATA); Integer num_int = m_testINT1; num_int.fromByteArray(apdubuf, ISO7816.OFFSET_CDATA, dataLen); PM.check(PM.TRAP_INT_STR_2); short len = num_int.toByteArray(apdubuf, (short) 0); apdu.setOutgoingAndSend((short) 0, len); }
Example 8
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void handleGetOperationMode(APDU apdu) throws ISOException { byte[] buffer = apdu.getBuffer(); if (buffer[ISO7816.OFFSET_P1] == P1_GET_OPERATION_MODE) { buffer[0] = currentMode; } else if (buffer[ISO7816.OFFSET_P1] == P1_GET_OPERATION_MODE_2FA) { buffer[0] = SFA_NFC; } apdu.setOutgoingAndSend((short)0, (short)1); }
Example 9
Source File: Gpg.java From OpenPGP-Card with GNU General Public License v3.0 | 5 votes |
/** * CHANGE REFERENCE DATA APDU implementation. */ private void changeReferenceData(APDU apdu) { byte buffer[] = apdu.getBuffer(); if (buffer[ISO7816.OFFSET_P1] != (byte) 0) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } byte pinOffset = PIN_INDEX_PW1; byte minLength = MIN_PIN1_LENGTH; byte type = buffer[ISO7816.OFFSET_P2]; if (type == (byte) 0x83) { pinOffset = PIN_INDEX_PW3; minLength = MIN_PIN3_LENGTH; } else if (type != (byte) 0x81) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } byte currentLength = pinLength[pinOffset]; short length = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF); if (apdu.setIncomingAndReceive() != length || length > currentLength + MAX_PIN_LENGTH || length < currentLength + minLength) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (pins[pinOffset].getTriesRemaining() == 0) { ISOException.throwIt(SW_PIN_BLOCKED); } if (!pins[pinOffset].check(buffer, ISO7816.OFFSET_CDATA, currentLength)) { pinSubmitted[0] = false; ISOException.throwIt((short) (SW_PIN_FAILED_00 + pins[pinOffset].getTriesRemaining())); } updatePIN(pinOffset, buffer, (short) (ISO7816.OFFSET_CDATA + currentLength), (byte) (length - currentLength)); }
Example 10
Source File: OCUnitTests.java From JCMathLib with MIT License | 5 votes |
void test_BN_MUL(APDU apdu, short dataLen, boolean bFastEngine) { byte[] apdubuf = apdu.getBuffer(); short p1 = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF); PM.check(PM.TRAP_BN_MUL_1); Bignat mul1 = m_testBN1; mul1.set_size(p1); PM.check(PM.TRAP_BN_MUL_2); Bignat mul2 = m_testBN2; mul2.set_size((short) (dataLen - p1)); PM.check(PM.TRAP_BN_MUL_3); Bignat product = m_testBN3; product.set_size(dataLen); PM.check(PM.TRAP_BN_MUL_4); mul1.from_byte_array(p1, (short)0, apdubuf, ISO7816.OFFSET_CDATA); mul2.from_byte_array((short)(dataLen-p1), (short)0, apdubuf, (short)(ISO7816.OFFSET_CDATA+p1)); PM.check(PM.TRAP_BN_MUL_5); if (bFastEngine && !bIsSimulator) { product.mult_rsa_trick(mul1, mul2, null, null); } else { product.mult_schoolbook(mul1, mul2); } PM.check(PM.TRAP_BN_MUL_6); short len = product.copy_to_buffer(apdubuf, (short) 0); apdu.setOutgoingAndSend((short) 0, len); }
Example 11
Source File: OCUnitTests.java From JCMathLib with MIT License | 5 votes |
void test_EC_COMPARE(APDU apdu) { byte[] apdubuf = apdu.getBuffer(); short p1_len = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF); short p2_len = (short) (apdubuf[ISO7816.OFFSET_P1] & 0x00FF); m_testPoint1.setW(apdubuf, (short) ISO7816.OFFSET_CDATA, p1_len); m_testPoint2.setW(apdubuf, (short) (ISO7816.OFFSET_CDATA + p1_len), p2_len); apdubuf[0] = 0; apdubuf[1] = 0; apdubuf[2] = 0; apdubuf[3] = 0; // Tests expects big integer apdubuf[4] = m_testPoint1.isEqual(m_testPoint2) ? (byte) 1 : (byte) 0; apdu.setOutgoingAndSend((short) 0, (short) 5); }
Example 12
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 5 votes |
/** * This function creates a PIN with parameters specified by the P1, P2 and DATA * values. P2 specifies the maximum number of consecutive unsuccessful * verifications before the PIN blocks. PIN can be created only if one of the logged identities * allows it. * * ins: 0x40 * p1: PIN number (0x00-0x07) * p2: max attempt number * data: [PIN_size(1b) | PIN | UBLK_size(1b) | UBLK] * return: none */ private short CreatePIN(APDU apdu, byte[] buffer) { // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); byte pin_nb = buffer[ISO7816.OFFSET_P1]; byte num_tries = buffer[ISO7816.OFFSET_P2]; if ((pin_nb < 0) || (pin_nb >= MAX_NUM_PINS) || (pins[pin_nb] != null)) ISOException.throwIt(SW_INCORRECT_P1); /* Allow pin lengths > 127 (useful at all ?) */ short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); // At least 1 character for PIN and 1 for unblock code (+ lengths) if (bytesLeft < 4) ISOException.throwIt(SW_INVALID_PARAMETER); byte pin_size = buffer[ISO7816.OFFSET_CDATA]; if (bytesLeft < (short) (1 + pin_size + 1)) ISOException.throwIt(SW_INVALID_PARAMETER); if (!CheckPINPolicy(buffer, (short) (ISO7816.OFFSET_CDATA + 1), pin_size)) ISOException.throwIt(SW_INVALID_PARAMETER); byte ucode_size = buffer[(short) (ISO7816.OFFSET_CDATA + 1 + pin_size)]; if (bytesLeft != (short) (1 + pin_size + 1 + ucode_size)) ISOException.throwIt(SW_INVALID_PARAMETER); if (!CheckPINPolicy(buffer, (short) (ISO7816.OFFSET_CDATA + 1 + pin_size + 1), ucode_size)) ISOException.throwIt(SW_INVALID_PARAMETER); pins[pin_nb] = new OwnerPIN(num_tries, PIN_MAX_SIZE); pins[pin_nb].update(buffer, (short) (ISO7816.OFFSET_CDATA + 1), pin_size); ublk_pins[pin_nb] = new OwnerPIN((byte) 3, PIN_MAX_SIZE); // Recycle variable pin_size pin_size = (byte) (ISO7816.OFFSET_CDATA + 1 + pin_size + 1); ublk_pins[pin_nb].update(buffer, pin_size, ucode_size); return (short)0; }
Example 13
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function signs a given transaction hash with a std or the last extended key * If 2FA is enabled, a HMAC must be provided as an additional security layer. * * ins: 0x7A * p1: key number or 0xFF for the last derived Bip32 extended key * p2: 0x00 * data: [hash(32b) | option: 2FA-flag(2b)|hmac(20b)] * * return: [sig ] * */ private short SignTransactionHash(APDU apdu, byte[] buffer){ // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); byte key_nb = buffer[ISO7816.OFFSET_P1]; if ( (key_nb!=(byte)0xFF) && ((key_nb < 0) || (key_nb >= MAX_NUM_KEYS)) ) ISOException.throwIt(SW_INCORRECT_P1); short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); if (bytesLeft<MessageDigest.LENGTH_SHA_256) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // check whether the seed is initialized if (key_nb==(byte)0xFF && !bip32_seeded) ISOException.throwIt(SW_BIP32_UNINITIALIZED_SEED); // check 2FA if required if(needs_2FA){ // check data length if (bytesLeft<MessageDigest.LENGTH_SHA_256+MessageDigest.LENGTH_SHA+(short)2) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // check flag for 2fa_hmac_chalresp short hmac_flags= Util.getShort(buffer, (short)(ISO7816.OFFSET_CDATA+32)); if (hmac_flags!=HMAC_CHALRESP_2FA) ISOException.throwIt(SW_INCORRECT_ALG); // hmac of 64-bytes msg: ( 32bytes tx_hash | 32bytes 0xCC-padding) Util.arrayCopyNonAtomic(buffer, (short)ISO7816.OFFSET_CDATA, recvBuffer, (short)0, (short)32); Util.arrayFillNonAtomic(recvBuffer, (short)32, (short)32, (byte)0xCC); HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, recvBuffer, (short)0, (short)64, recvBuffer, (short)64); if (Util.arrayCompare(buffer, (short)(ISO7816.OFFSET_CDATA+32+2), recvBuffer, (short)64, (short)20)!=0) ISOException.throwIt(SW_SIGNATURE_INVALID); } // hash+sign singlehash if (key_nb==(byte)0xFF) sigECDSA.init(bip32_extendedkey, Signature.MODE_SIGN); else{ Key key= eckeys[key_nb]; // check type and size if ((key == null) || !key.isInitialized()) ISOException.throwIt(SW_INCORRECT_P1); if (key.getType() != KeyBuilder.TYPE_EC_FP_PRIVATE) ISOException.throwIt(SW_INCORRECT_ALG); if (key.getSize()!= LENGTH_EC_FP_256) ISOException.throwIt(SW_INCORRECT_ALG); sigECDSA.init(key, Signature.MODE_SIGN); } short sign_size= sigECDSA.signPreComputedHash(buffer, ISO7816.OFFSET_CDATA, MessageDigest.LENGTH_SHA_256, buffer, (short)0); return sign_size; }
Example 14
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function signs the current hash transaction with a std or the last extended key * The hash provided in the APDU is compared to the version stored inside the chip. * Depending of the total amount in the transaction and the predefined limit, * a HMAC must be provided as an additional security layer. * * ins: 0x6F * p1: key number or 0xFF for the last derived Bip32 extended key * p2: 0x00 * data: [hash(32b) | option: 2FA-flag(2b)|hmac(20b)] * * return: [sig ] * */ private short SignTransaction(APDU apdu, byte[] buffer){ // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); byte key_nb = buffer[ISO7816.OFFSET_P1]; if ( (key_nb!=(byte)0xFF) && ((key_nb < 0) || (key_nb >= MAX_NUM_KEYS)) ) ISOException.throwIt(SW_INCORRECT_P1); short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); if (bytesLeft<MessageDigest.LENGTH_SHA_256) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // check whether the seed is initialized if (key_nb==(byte)0xFF && !bip32_seeded) ISOException.throwIt(SW_BIP32_UNINITIALIZED_SEED); // check doublehash value in buffer with cached singlehash value sha256.reset(); sha256.doFinal(transactionData, OFFSET_TRANSACTION_HASH, MessageDigest.LENGTH_SHA_256, recvBuffer, (short)0); if ((byte)0 != Util.arrayCompare(buffer, ISO7816.OFFSET_CDATA, recvBuffer, (short)0, MessageDigest.LENGTH_SHA_256)) ISOException.throwIt(SW_INCORRECT_TXHASH); // check challenge-response answer if necessary if(needs_2FA){ if( Biginteger.lessThan(data2FA, OFFSET_2FA_LIMIT, transactionData, OFFSET_TRANSACTION_AMOUNT, (short)8)){ if (bytesLeft<MessageDigest.LENGTH_SHA_256+MessageDigest.LENGTH_SHA+(short)2) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // check flag for 2fa_hmac_chalresp short hmac_flags= Util.getShort(buffer, (short)(ISO7816.OFFSET_CDATA+32)); if (hmac_flags!=HMAC_CHALRESP_2FA) ISOException.throwIt(SW_INCORRECT_ALG); // hmac of 64-bytes msg: (doublesha256(raw_tx) | 32bytes zero-padding) Util.arrayFillNonAtomic(recvBuffer, (short)32, (short)32, (byte)0x00); HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, recvBuffer, (short)0, (short)64, recvBuffer, (short)64); if (Util.arrayCompare(buffer, (short)(ISO7816.OFFSET_CDATA+32+2), recvBuffer, (short)64, (short)20)!=0) ISOException.throwIt(SW_SIGNATURE_INVALID); // reset total amount Util.arrayFillNonAtomic(transactionData, OFFSET_TRANSACTION_TOTAL, (short)8, (byte)0x00); } else{ //update total amount Util.arrayCopyNonAtomic(transactionData, OFFSET_TRANSACTION_AMOUNT, transactionData, OFFSET_TRANSACTION_TOTAL, (short)8); } } // hash+sign singlehash if (key_nb==(byte)0xFF) sigECDSA.init(bip32_extendedkey, Signature.MODE_SIGN); else{ Key key= eckeys[key_nb]; // check type and size if ((key == null) || !key.isInitialized()) ISOException.throwIt(SW_INCORRECT_P1); if (key.getType() != KeyBuilder.TYPE_EC_FP_PRIVATE) ISOException.throwIt(SW_INCORRECT_ALG); if (key.getSize()!= LENGTH_EC_FP_256) ISOException.throwIt(SW_INCORRECT_ALG); sigECDSA.init(key, Signature.MODE_SIGN); } short sign_size= sigECDSA.sign(transactionData, OFFSET_TRANSACTION_HASH, (short)32, buffer, (short)0); return sign_size; }
Example 15
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function returns the public key associated with a particular private key stored * in the applet. The exact key blob contents depend on the key�s algorithm and type. * * ins: 0x35 * p1: private key number (0x00-0x0F) * p2: 0x00 * data: none * return(SECP256K1): [coordx_size(2b) | pubkey_coordx | sig_size(2b) | sig] */ private short getPublicKeyFromPrivate(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); byte key_nb = buffer[ISO7816.OFFSET_P1]; if ((key_nb < 0) || (key_nb >= MAX_NUM_KEYS)) ISOException.throwIt(SW_INCORRECT_P1); Key key = eckeys[key_nb]; // check type and size if ((key == null) || !key.isInitialized()) ISOException.throwIt(SW_INCORRECT_P1); if (key.getType() != KeyBuilder.TYPE_EC_FP_PRIVATE) ISOException.throwIt(SW_INCORRECT_ALG); if (key.getSize()!= LENGTH_EC_FP_256) ISOException.throwIt(SW_INCORRECT_ALG); // check the curve param if(!Secp256k1.checkCurveParameters((ECPrivateKey)key, recvBuffer, (short)0)) ISOException.throwIt(SW_INCORRECT_ALG); // compute the corresponding partial public key... keyAgreement.init((ECPrivateKey)key); short coordx_size=(short)32; keyAgreement.generateSecret(Secp256k1.SECP256K1, Secp256k1.OFFSET_SECP256K1_G, (short) 65, buffer, (short)1); //pubkey in uncompressed form Util.setShort(buffer, (short)0, coordx_size); // sign fixed message sigECDSA.init(key, Signature.MODE_SIGN); short sign_size= sigECDSA.sign(buffer, (short)0, (short)(coordx_size+2), buffer, (short)(coordx_size+4)); Util.setShort(buffer, (short)(coordx_size+2), 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... return (short)(2+coordx_size+2+sign_size); }
Example 16
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function allows to reset a private ECkey stored in the card. * If 2FA is enabled, a hmac code must be provided to reset the key. * * ins: 0x33 * p1: private key number (0x00-0x0F) * p2: 0x00 * data: [ (option)HMAC-2FA(20b)] * return: none */ private short ResetKey(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); byte key_nb = buffer[ISO7816.OFFSET_P1]; if ((key_nb < 0) || (key_nb >= MAX_NUM_KEYS)) ISOException.throwIt(SW_INCORRECT_P1); Key key = eckeys[key_nb]; // check type and size if ((key == null) || !key.isInitialized()) ISOException.throwIt(SW_INCORRECT_P1); // check 2FA if required if (needs_2FA){ short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); if (bytesLeft < (short)20) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // compute the corresponding partial public key... keyAgreement.init((ECPrivateKey)key); keyAgreement.generateSecret(Secp256k1.SECP256K1, Secp256k1.OFFSET_SECP256K1_G, (short) 65, tmpBuffer, (short)0); //pubkey in uncompressed form Util.arrayCopy(tmpBuffer, (short)1, recvBuffer, (short)0, (short)32); // hmac of 64-bytes msg: (pubkey-x | 32bytes (0x20^key_nb)-padding) Util.arrayFillNonAtomic(recvBuffer, (short)32, (short)32, (byte) (0x20^key_nb)); HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, recvBuffer, (short)0, (short)64, recvBuffer, (short)64); if (Util.arrayCompare(buffer, ISO7816.OFFSET_CDATA, recvBuffer, (short)64, (short)20)!=0) ISOException.throwIt(SW_SIGNATURE_INVALID); } // clear key & reset flag key.clearKey(); eckeys_flag &= (short) ~(0x0001 << key_nb);// reset corresponding bit flag; return (short)0; }
Example 17
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
private static void handleSetUserKeycard(APDU apdu, boolean airgap) throws ISOException { byte[] buffer = apdu.getBuffer(); short offset = ISO7816.OFFSET_CDATA; apdu.setIncomingAndReceive(); if ((setup == TC.FALSE) || (setup != TC.TRUE)) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (Keycard.issuerKeycardSize == (byte)0) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } if (buffer[ISO7816.OFFSET_P1] == P1_SET_KEYCARD) { if (buffer[ISO7816.OFFSET_LC] != (byte)(KEYCARD_KEY_LENGTH + 1)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Keycard.setPairingData(buffer, ISO7816.OFFSET_CDATA); Keycard.generateRandomIndexes(Keycard.challenge, (short)0, KEYCARD_CHALLENGE_LENGTH); buffer[0] = CONFIRM_PREVIOUS_KEYCARD; Util.arrayCopyNonAtomic(Keycard.challenge, (short)0, buffer, (short)1, KEYCARD_CHALLENGE_LENGTH); apdu.setOutgoingAndSend((short)0, (short)(KEYCARD_CHALLENGE_LENGTH + 1)); } else if (buffer[ISO7816.OFFSET_P1] == P1_CONFIRM_KEYCARD) { if (buffer[ISO7816.OFFSET_LC] != KEYCARD_CHALLENGE_LENGTH) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (!Keycard.check(null, (short)0, (byte)0, buffer, ISO7816.OFFSET_CDATA, (byte)4, Keycard.challenge, (short)0, scratch256, (short)150)) { Keycard.clearPairingData(); ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED); } else { Keycard.getPairingData(scratch256, (short)0); if (!airgap) { Keycard.setUser(scratch256[0], scratch256, (short)1); } else { Crypto.initCipherAES(pairingKey, false); Crypto.blobEncryptDecryptAES.doFinal(scratch256, (short)1, (short)16, scratch256, (short)100); Keycard.setUser(scratch256[0], scratch256, (short)100); } } } else { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } }
Example 18
Source File: IsoApplet.java From IsoApplet with GNU General Public License v3.0 | 4 votes |
/** * \brief Process the VERIFY apdu (INS = 20). * * This apdu is used to verify a PIN and authenticate the user. A counter is used * to limit unsuccessful tries (i.e. brute force attacks). * * \param apdu The apdu. * * \throw ISOException SW_INCORRECT_P1P2, ISO7816.SW_WRONG_LENGTH, SW_PIN_TRIES_REMAINING. */ private void processVerify(APDU apdu) throws ISOException { byte[] buf = apdu.getBuffer(); short offset_cdata; short lc; // P1P2 0001 only at the moment. (key-reference 01 = PIN) if(buf[ISO7816.OFFSET_P1] != 0x00 || buf[ISO7816.OFFSET_P2] != 0x01) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } // Bytes received must be Lc. lc = apdu.setIncomingAndReceive(); if(lc != apdu.getIncomingLength()) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } offset_cdata = apdu.getOffsetCdata(); // Lc might be 0, in this case the caller checks if verification is required. if((lc > 0 && (lc < PIN_MIN_LENGTH) || lc > PIN_MAX_LENGTH)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Caller asks if verification is needed. if(lc == 0 && state != STATE_CREATION && state != STATE_INITIALISATION) { // Verification required, return remaining tries. ISOException.throwIt((short)(SW_PIN_TRIES_REMAINING | pin.getTriesRemaining())); } else if(lc == 0 && (state == STATE_CREATION || state == STATE_INITIALISATION)) { // No verification required. ISOException.throwIt(ISO7816.SW_NO_ERROR); } // Pad the PIN if not done by caller, so no garbage from the APDU will be part of the PIN. Util.arrayFillNonAtomic(buf, (short)(offset_cdata + lc), (short)(PIN_MAX_LENGTH - lc), (byte) 0x00); // Check the PIN. if(!pin.check(buf, offset_cdata, PIN_MAX_LENGTH)) { fs.setUserAuthenticated(false); ISOException.throwIt((short)(SW_PIN_TRIES_REMAINING | pin.getTriesRemaining())); } else { fs.setUserAuthenticated(true); } }
Example 19
Source File: Gpg.java From OpenPGP-Card with GNU General Public License v3.0 | 4 votes |
/** * GENERATE KEY APDU implementation. */ private void generateAsymetricKey(APDU apdu) { byte[] buffer = apdu.getBuffer(); if (apdu.setIncomingAndReceive() != 2) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } KeyPair key = getKey(buffer[ISO7816.OFFSET_CDATA]); if (buffer[ISO7816.OFFSET_P1] == (byte) 0x81) { if (!(key.getPublic()).isInitialized()) { ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND); } } else { if (!pins[PIN_INDEX_PW3].isValidated()) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } JCSystem.beginTransaction(); key.genKeyPair(); if (buffer[ISO7816.OFFSET_CDATA] == (byte)0xB6) { signatureCounter[0] = 0; signatureCounter[1] = 0; signatureCounter[2] = 0; } JCSystem.commitTransaction(); } // Send the TLV data and public exponent using the APDU buffer. buffer[ISO7816.OFFSET_CDATA] = 0x7F; buffer[(short) (ISO7816.OFFSET_CDATA + 1)] = 0x49; buffer[(short) (ISO7816.OFFSET_CDATA + 2)] = (byte) 0x82; buffer[(short) (ISO7816.OFFSET_CDATA + 5)] = (byte) 0x82; short length = ((RSAPublicKey) key.getPublic()).getExponent( buffer, (short) (ISO7816.OFFSET_CDATA + 7)); buffer[(short) (ISO7816.OFFSET_CDATA + 6)] = (byte) length; short pos = (short) (ISO7816.OFFSET_CDATA + 7 + length); buffer[pos] = (byte) 0x81; buffer[(short) (pos + 1)] = (byte) 0x82; Util.setShort(buffer, (short) (pos + 2), RSA_KEY_LENGTH_BYTES); Util.setShort(buffer, (short) (ISO7816.OFFSET_CDATA + 3), (short) (pos + RSA_KEY_LENGTH_BYTES - ISO7816.OFFSET_CDATA - 1)); apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, (short) (length + 11)); // And the modulus using get response. Util.setShort(commandChainingBuffer, TEMP_GET_RESPONSE_LENGTH, RSA_KEY_LENGTH_BYTES); ((RSAPublicKey) key.getPublic()).getModulus(commandChainingBuffer, TEMP_GET_RESPONSE_DATA); // Skip leading zero byte. if (commandChainingBuffer[TEMP_GET_RESPONSE_DATA] == 0) { Util.setShort(commandChainingBuffer, TEMP_GET_RESPONSE_OFFSET, (short) (TEMP_GET_RESPONSE_DATA + 1)); } else { Util.setShort(commandChainingBuffer, TEMP_GET_RESPONSE_OFFSET, TEMP_GET_RESPONSE_DATA); } commandChainingBuffer[TEMP_INS] = buffer[ISO7816.OFFSET_INS]; ISOException.throwIt(ISO7816.SW_BYTES_REMAINING_00); }
Example 20
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function changes a PIN code. The DATA portion contains both the old and * the new PIN codes. * * ins: 0x44 * p1: PIN number (0x00-0x07) * p2: 0x00 * data: [PIN_size(1b) | old_PIN | PIN_size(1b) | new_PIN ] * return: none (throws an exception in case of wrong PIN) */ private short ChangePIN(APDU apdu, byte[] buffer) { /* * Here I suppose the PIN code is small enough that 2 of them enter in * the buffer TODO: Verify the assumption and eventually adjust code to * support reading PINs in multiple read()s */ byte pin_nb = buffer[ISO7816.OFFSET_P1]; if ((pin_nb < 0) || (pin_nb >= MAX_NUM_PINS)) ISOException.throwIt(SW_INCORRECT_P1); OwnerPIN pin = pins[pin_nb]; if (pin == null) ISOException.throwIt(SW_INCORRECT_P1); if (buffer[ISO7816.OFFSET_P2] != (byte) 0x00) ISOException.throwIt(SW_INCORRECT_P2); short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); // At least 1 character for each PIN code if (bytesLeft < 4) ISOException.throwIt(SW_INVALID_PARAMETER); byte pin_size = buffer[ISO7816.OFFSET_CDATA]; if (bytesLeft < (short) (1 + pin_size + 1)) ISOException.throwIt(SW_INVALID_PARAMETER); if (!CheckPINPolicy(buffer, (short) (ISO7816.OFFSET_CDATA + 1), pin_size)) ISOException.throwIt(SW_INVALID_PARAMETER); byte new_pin_size = buffer[(short) (ISO7816.OFFSET_CDATA + 1 + pin_size)]; if (bytesLeft < (short) (1 + pin_size + 1 + new_pin_size)) ISOException.throwIt(SW_INVALID_PARAMETER); if (!CheckPINPolicy(buffer, (short) (ISO7816.OFFSET_CDATA + 1 + pin_size + 1), new_pin_size)) ISOException.throwIt(SW_INVALID_PARAMETER); byte triesRemaining = pin.getTriesRemaining(); if (triesRemaining == (byte) 0x00) ISOException.throwIt(SW_IDENTITY_BLOCKED); if (!pin.check(buffer, (short) (ISO7816.OFFSET_CDATA + 1), pin_size)) { LogoutIdentity(pin_nb); ISOException.throwIt((short)(SW_PIN_FAILED + triesRemaining - 1)); } pin.update(buffer, (short) (ISO7816.OFFSET_CDATA + 1 + pin_size + 1), new_pin_size); // JC specifies this resets the validated flag. So we do. logged_ids &= (short) ((short) 0xFFFF ^ (0x01 << pin_nb)); return (short)0; }