javacard.security.Signature Java Examples
The following examples show how to use
javacard.security.Signature.
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: SigMsgRecApplet.java From JCMathLib with MIT License | 6 votes |
/** * Only this class's install method should create the applet object. */ protected SigMsgRecApplet(byte[] bArray, short bOffset, byte bLength){ byte aidLen = bArray[bOffset]; if (aidLen== (byte)0){ //System.out.println("using dfault"); register(); } else { //System.out.println("using provided"); register(bArray, (short)(bOffset+1), aidLen); } pubKey = (RSAPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC,KeyBuilder.LENGTH_RSA_512,false); privKey = (RSAPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE,KeyBuilder.LENGTH_RSA_512,false); privKey.setExponent(RSA_PRIV_KEY_EXP,(short)0,(short)RSA_PRIV_KEY_EXP.length); privKey.setModulus(RSA_PUB_PRIV_KEY_MOD,(short)0,(short)RSA_PUB_PRIV_KEY_MOD.length); pubKey.setExponent(RSA_PUB_KEY_EXP,(short)0,(short)RSA_PUB_KEY_EXP.length); pubKey.setModulus(RSA_PUB_PRIV_KEY_MOD,(short)0,(short)RSA_PUB_PRIV_KEY_MOD.length); sigBuff = JCSystem.makeTransientByteArray((short)(SIG_LENGTH+2),JCSystem.CLEAR_ON_DESELECT); sig = (SignatureMessageRecovery)Signature.getInstance(Signature.ALG_RSA_SHA_ISO9796_MR,false); recState = (byte)0; }
Example #2
Source File: SigMsgRecApplet.java From JCMathLib with MIT License | 6 votes |
/** * For the purposes of this sample, Assumed that all the data to be * signed fits into one APDU buffer **/ private void testCryptoSign(APDU apdu){ byte []buffer = apdu.getBuffer(); short bytesRead = apdu.setIncomingAndReceive(); short []m1Data = JCSystem.makeTransientShortArray((short)1,JCSystem.CLEAR_ON_DESELECT); sig.init(privKey,Signature.MODE_SIGN); sigLen=sig.sign(buffer,ISO7816.OFFSET_CDATA,bytesRead,sigBuff,(short)0,m1Data,(short)0); //set m1Length into sigBuff array sigBuff[sigLen] = (byte)((short)(m1Data[(short)0] & ((short)0xFF00)) >> ((short)8)); sigBuff[(short)(sigLen+1)] = (byte)(m1Data[(short)0] & ((short)0x00FF)); apdu.setOutgoing(); apdu.setOutgoingLength((short)(sigLen+2));//The extra 2 bytes for m1Length apdu.sendBytesLong(sigBuff,(short)0,(short)(sigLen+2)); }
Example #3
Source File: SigMsgRecApplet.java From JCMathLib with MIT License | 6 votes |
/** * in this case, all the message is inside the signature. * We only expect one APDU with signature **/ private void testCryptoVerifyFullMsgRecovery(APDU apdu){ sig.init(pubKey,Signature.MODE_VERIFY); boolean verified=false; byte []buffer = apdu.getBuffer(); short dataLength = (short)(buffer[ISO7816.OFFSET_LC] & (short)0xFF); //get the signature from APDU short bytesRead = apdu.setIncomingAndReceive(); Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, sigBuff, (short)0,bytesRead); short m1Length = sig.beginVerify(sigBuff,(short)0,bytesRead); verified = sig.verify(sigBuff,(short)0,(short)0); //In either case m1 is consumed by this applet if(!verified){ ISOException.throwIt(ERROR_VERIFICATION_FAILED); } }
Example #4
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 6 votes |
/** * This function returns the authentikey public key (uniquely derived from the Bip32 seed). * The function returns the x-coordinate of the authentikey, self-signed. * The authentikey full public key can be recovered from the signature. * * ins: 0x73 * p1: 0x00 * p2: 0x00 * data: none * return: [coordx_size(2b) | coordx | sig_size(2b) | sig] */ private short getBIP32AuthentiKey(APDU apdu, byte[] buffer){ // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); // check whether the seed is initialized if (!bip32_seeded) ISOException.throwIt(SW_BIP32_UNINITIALIZED_SEED); // 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, buffer, (short)1); //pubkey in uncompressed form Util.setShort(buffer, (short)0, 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)(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... // buffer= [coordx_size(2) | coordx | sigsize(2) | sig] return (short)(coordx_size+sign_size+4); }
Example #5
Source File: TransitApplet.java From JCMathLib with MIT License | 6 votes |
/** * Checks the request message signature. * * @param buffer * The APDU buffer * @return true if the message signature is correct; false otherwise */ private boolean checkMAC(byte[] buffer) { byte numBytes = buffer[ISO7816.OFFSET_LC]; if (numBytes <= MAC_LENGTH) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Initialize signature with current session key for verification signature.init(sessionKey, Signature.MODE_VERIFY); // Verify request message signature return signature.verify(buffer, ISO7816.OFFSET_CDATA, (short) (numBytes - MAC_LENGTH), buffer, (short) (ISO7816.OFFSET_CDATA + numBytes - MAC_LENGTH), MAC_LENGTH); }
Example #6
Source File: OpenPGPSecureMessaging.java From javacard-openpgpcard with GNU General Public License v2.0 | 6 votes |
/** * Construct a new secure messaging wrapper. */ public OpenPGPSecureMessaging() { ssc = JCSystem.makeTransientByteArray(SSC_SIZE, JCSystem.CLEAR_ON_DESELECT); tmp = JCSystem.makeTransientByteArray(TMP_SIZE, JCSystem.CLEAR_ON_DESELECT); signer = Signature.getInstance( Signature.ALG_DES_MAC8_ISO9797_1_M2_ALG3, false); verifier = Signature.getInstance( Signature.ALG_DES_MAC8_ISO9797_1_M2_ALG3, false); cipher = Cipher.getInstance( Cipher.ALG_DES_CBC_ISO9797_M2, false); decipher = Cipher.getInstance( Cipher.ALG_DES_CBC_ISO9797_M2, false); keyMAC = (DESKey) KeyBuilder.buildKey( KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_DES3_2KEY, false); keyENC = (DESKey) KeyBuilder.buildKey( KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_DES3_2KEY, false); ssc_set = JCSystem.makeTransientBooleanArray((short)1, JCSystem.CLEAR_ON_DESELECT); ssc_set[0] = false; }
Example #7
Source File: OpenPGPSecureMessaging.java From javacard-openpgpcard with GNU General Public License v2.0 | 6 votes |
/** * Set the MAC and encryption (and decryption) session keys. Each key is a * 16 byte 3DES EDE key. This method may be called at any time and will * immediately replace the session key. * * @param buffer byte array containing the session keys. * @param offset location of the session keys in the buffer. */ public void setSessionKeys(byte[] buffer, short offset) { // Check for empty keys if(Util.arrayCompare(buffer, (short)0, EMPTY_KEY, (short)0, KEY_SIZE) == 0 || Util.arrayCompare(buffer, KEY_SIZE, EMPTY_KEY, (short)0, KEY_SIZE) == 0) { keyMAC.clearKey(); keyENC.clearKey(); } else { keyMAC.setKey(buffer, offset); keyENC.setKey(buffer, (short) (offset + KEY_SIZE)); signer.init(keyMAC, Signature.MODE_SIGN); verifier.init(keyMAC, Signature.MODE_VERIFY); cipher.init(keyENC, Cipher.MODE_ENCRYPT); decipher.init(keyENC, Cipher.MODE_DECRYPT); } }
Example #8
Source File: ECPoint_Helper.java From JCMathLib with MIT License | 5 votes |
public ECPoint_Helper(ResourceManager rm) { super(rm); FLAG_FAST_EC_MULT_VIA_KA = false; // set true only if succesfully allocated and tested below try { //fnc_multiplication_x_keyAgreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DHC, false); //fnc_SignVerifyECDSA_signEngine = Signature.getInstance(Signature.ALG_ECDSA_SHA, false); //fnc_multiplication_x_keyAgreement = KeyAgreement.getInstance(Consts.KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY, false); fnc_multiplication_x_keyAgreement = KeyAgreement.getInstance(KeyAgreement_ALG_EC_SVDP_DH_PLAIN, false); fnc_SignVerifyECDSA_signEngine = Signature.getInstance(Signature_ALG_ECDSA_SHA_256, false); FLAG_FAST_EC_MULT_VIA_KA = true; } catch (Exception ignored) { } // Discard any exception }
Example #9
Source File: Bip32.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
public static void deriveSeed(byte seedLength) { if (Crypto.signatureHmac != null) { Crypto.keyHmac2.setKey(BITCOIN_SEED, (short)0, (short)BITCOIN_SEED.length); if ((LedgerWalletApplet.proprietaryAPI != null) && (LedgerWalletApplet.proprietaryAPI.hasHmacSHA512())) { LedgerWalletApplet.proprietaryAPI.hmacSHA512(Crypto.keyHmac2, LedgerWalletApplet.scratch256, (short)0, seedLength, LedgerWalletApplet.masterDerived, (short)0); } else { Crypto.signatureHmac.init(Crypto.keyHmac2, Signature.MODE_SIGN); Crypto.signatureHmac.sign(LedgerWalletApplet.scratch256, (short)0, seedLength, LedgerWalletApplet.masterDerived, (short)0); } } else { HmacSha512.hmac(BITCOIN_SEED, (short)0, (short)BITCOIN_SEED.length, LedgerWalletApplet.scratch256, (short)0, seedLength, LedgerWalletApplet.masterDerived, (short)0, LedgerWalletApplet.scratch256, (short)64); } }
Example #10
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void handleAirgapKeyAgreement(APDU apdu) throws ISOException { short offset = (short)0; byte[] buffer = apdu.getBuffer(); apdu.setIncomingAndReceive(); checkAirgapPersonalizationAvailable(); if (buffer[ISO7816.OFFSET_P1] == P1_INITIATE_PAIRING) { if (buffer[ISO7816.OFFSET_LC] != (byte)65) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } pairingDone = false; Crypto.keyPair.genKeyPair(); Crypto.keyAgreement.init((ECPrivateKey)Crypto.keyPair.getPrivate()); Crypto.keyAgreement.generateSecret(buffer, ISO7816.OFFSET_CDATA, (short)65, scratch256, (short)0); pairingKey.setKey(scratch256, (short)0); ((ECPublicKey)Crypto.keyPair.getPublic()).getW(buffer, offset); offset += (short)65; Crypto.signature.init(attestationPrivate, Signature.MODE_SIGN); Crypto.signature.sign(buffer, (short)0, (short)65, buffer, offset); offset += (short)(buffer[(short)(offset + 1)] + 2); apdu.setOutgoingAndSend((short)0, offset); } else if (buffer[ISO7816.OFFSET_P1] == P1_CONFIRM_PAIRING) { if (buffer[ISO7816.OFFSET_LC] != (byte)32) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Crypto.initCipherAES(pairingKey, false); Crypto.blobEncryptDecryptAES.doFinal(buffer, ISO7816.OFFSET_CDATA, (short)32, scratch256, (short)0); pairingKey.setKey(scratch256, (short)0); pairingDone = true; } else { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } }
Example #11
Source File: Crypto.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
public static void signTransientPrivate(byte[] keyBuffer, short keyOffset, byte[] dataBuffer, short dataOffset, byte[] targetBuffer, short targetOffset) { initTransientPrivate(keyBuffer, keyOffset); Util.arrayFillNonAtomic(keyBuffer, keyOffset, (short)32, (byte)0x00); // recheck with the target platform, initializing once instead might be possible and save a few flash write // (this part is unspecified in the Java Card API) signature.init(transientPrivate, Signature.MODE_SIGN); signature.sign(dataBuffer, dataOffset, (short)32, targetBuffer, targetOffset); if (transientPrivateTransient) { transientPrivate.clearKey(); } }
Example #12
Source File: OpenPGPSecureMessaging.java From javacard-openpgpcard with GNU General Public License v2.0 | 5 votes |
/** * Set the MAC session key. Each key is a 16 byte 3DES EDE key. This method * may be called at any time and will immediately replace the session key. * * @param buffer byte array containing the session key. * @param offset location of the session key in the buffer. */ public void setSessionKeyMAC(byte[] buffer, short offset) { // Check for empty keys if(Util.arrayCompare(buffer, (short)0, EMPTY_KEY, (short)0, KEY_SIZE) == 0) { keyMAC.clearKey(); keyENC.clearKey(); } else { keyMAC.setKey(buffer, offset); signer.init(keyMAC, Signature.MODE_SIGN); verifier.init(keyMAC, Signature.MODE_VERIFY); } }
Example #13
Source File: Crypto.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
public static boolean verifyPublic(byte[] keyBuffer, short keyOffset, byte[] dataBuffer, short dataOffset, byte[] signatureBuffer, short signatureOffset) { publicKey.setW(keyBuffer, keyOffset, (short)65); signature.init(publicKey, Signature.MODE_VERIFY); try { return signature.verify(dataBuffer, dataOffset, (short)32, signatureBuffer, signatureOffset, (short)(signatureBuffer[(short)(signatureOffset + 1)] + 2)); } catch(Exception e) { return false; } }
Example #14
Source File: SigMsgRecApplet.java From JCMathLib with MIT License | 5 votes |
/** * This method is called when there is partial message recovery. The recoverable * message inside the signature is consumed by this applet. In this case, the * first APDU contains the signature and returns true if recovery successful * the second APDU contains the remainder of the message and the return value * represents signature verification **/ private void testCryptoVerifyPartMsgRecovery(APDU apdu){ byte []buffer = apdu.getBuffer(); short dataLength = (short)(buffer[ISO7816.OFFSET_LC] & (short)0xFF); //get the signature from APDU short bytesRead = apdu.setIncomingAndReceive(); Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, sigBuff, (short)0,bytesRead); if(recState == 0){ //recover the recoverable message from signature sig.init(pubKey,Signature.MODE_VERIFY); short m1Length = sig.beginVerify(sigBuff,(short)0,bytesRead); //consume the recoverable message. Theen discard it sigBuff[0] = (byte)((short)(m1Length & ((short)0xFF00)) >> ((short)8)); sigBuff[1] = (byte)(m1Length & ((short)0x00FF)); //return back the length of recoverable message apdu.setOutgoing(); apdu.setOutgoingLength((short)2); apdu.sendBytesLong(sigBuff,(short)0,(short)2); recState = 1; }else{ recState = 0; //rest of message sent. verify if(!sig.verify(sigBuff,(short)0,bytesRead)){ ISOException.throwIt(ERROR_VERIFICATION_FAILED); } } }
Example #15
Source File: ECPoint.java From JCMathLib with MIT License | 4 votes |
public static boolean SignVerifyECDSA(ECPrivateKey privateKey, ECPublicKey publicKey, Signature signEngine, byte[] tmpSignArray) { signEngine.init(privateKey, Signature.MODE_SIGN); short signLen = signEngine.sign(msg, (short) 0, (short) msg.length, tmpSignArray, (short) 0); signEngine.init(publicKey, Signature.MODE_VERIFY); return signEngine.verify(msg, (short) 0, (short) msg.length, tmpSignArray, (short) 0, signLen); }
Example #16
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 #17
Source File: JCardSIMProprietaryAPI.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
@Override public void signDeterministicECDSASHA256(Key key, byte[] in, short inBuffer, short inLength, byte[] out, short outOffset) { signature.init(key, Signature.MODE_SIGN); signature.sign(in, inBuffer, inLength, out, outOffset); }
Example #18
Source File: IsoApplet.java From IsoApplet with GNU General Public License v3.0 | 4 votes |
/** * \brief Compute a digital signature of the data from the apdu * using the private key referenced by an earlier * MANAGE SECURITY ENVIRONMENT apdu. * * \attention The apdu should contain a hash, not raw data for RSA keys. * PKCS1 padding will be applied if neccessary. * * \param apdu The PERFORM SECURITY OPERATION apdu with P1=9E and P2=9A. * * \throw ISOException SW_CONDITIONS_NOT_SATISFIED, SW_WRONG_LENGTH * and SW_UNKNOWN. */ private void computeDigitalSignature(APDU apdu) throws ISOException { byte[] buf = apdu.getBuffer(); short offset_cdata; short lc; short sigLen = 0; switch(currentAlgorithmRef[0]) { case ALG_RSA_PAD_PKCS1: // Receive. // Bytes received must be Lc. lc = apdu.setIncomingAndReceive(); if(lc != apdu.getIncomingLength()) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } offset_cdata = apdu.getOffsetCdata(); // RSA signature operation. RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) keys[currentPrivateKeyRef[0]]; if(lc > (short) 247) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } rsaPkcs1Cipher.init(rsaKey, Cipher.MODE_ENCRYPT); sigLen = rsaPkcs1Cipher.doFinal(buf, offset_cdata, lc, ram_buf, (short)0); if(sigLen != 256) { ISOException.throwIt(ISO7816.SW_UNKNOWN); } // A single short APDU can handle 256 bytes - only one send operation neccessary. short le = apdu.setOutgoing(); if(le < sigLen) { ISOException.throwIt(ISO7816.SW_CORRECT_LENGTH_00); } apdu.setOutgoingLength(sigLen); apdu.sendBytesLong(ram_buf, (short) 0, sigLen); break; case ALG_ECDSA_SHA1: // Get the key - it must be a EC private key, // checks have been done in MANAGE SECURITY ENVIRONMENT. ECPrivateKey ecKey = (ECPrivateKey) keys[currentPrivateKeyRef[0]]; // Initialisation should be done when: // - No command chaining is performed at all. // - Command chaining is performed and this is the first apdu in the chain. if(ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] == (short) 0) { ecdsaSignature.init(ecKey, Signature.MODE_SIGN); if(isCommandChainingCLA(apdu)) { ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] = (short) 1; } } short recvLen = apdu.setIncomingAndReceive(); offset_cdata = apdu.getOffsetCdata(); // Receive data. For extended APDUs, the data is received piecewise // and aggregated in the hash. When using short APDUs, command // chaining is performed. while (recvLen > 0) { ecdsaSignature.update(buf, offset_cdata, recvLen); recvLen = apdu.receiveBytes(offset_cdata); } if(!isCommandChainingCLA(apdu)) { sigLen = ecdsaSignature.sign(buf, (short)0, (short)0, buf, (short) 0); ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS] = (short) 0; apdu.setOutgoingAndSend((short) 0, sigLen); } else { ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS]++; } break; default: // Wrong/unknown algorithm. ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } }
Example #19
Source File: U2FApplet.java From ledger-u2f-javacard with Apache License 2.0 | 4 votes |
/** * Handle U2F_AUTHENTICATE. * * @param apdu * @throws ISOException */ 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; 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 #20
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function allows to initiate a Secure Channel * * ins: 0x81 * p1: 0x00 * p2: 0x00 * data: [client-pubkey(65b)] * return: [coordx_size(2b) | authentikey-coordx | sig_size(2b) | self-sig | sig2_size(optional) | authentikey-sig(optional)] */ private short InitiateSecureChannel(APDU apdu, byte[] buffer){ // get client pubkey short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); if (bytesLeft < (short)65) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); if (buffer[ISO7816.OFFSET_CDATA] != (byte)0x04) ISOException.throwIt(SW_INVALID_PARAMETER); // generate a new ephemeral key sc_ephemeralkey.clearKey(); Secp256k1.setCommonCurveParameters(sc_ephemeralkey);// keep public params! randomData.generateData(recvBuffer, (short)0, BIP32_KEY_SIZE); sc_ephemeralkey.setS(recvBuffer, (short)0, BIP32_KEY_SIZE); //random value first // compute the shared secret... keyAgreement.init(sc_ephemeralkey); short coordx_size= (short)32; keyAgreement.generateSecret(buffer, ISO7816.OFFSET_CDATA, (short) 65, recvBuffer, (short)0); //pubkey in uncompressed form // derive sc_sessionkey & sc_mackey HmacSha160.computeHmacSha160(recvBuffer, (short)1, (short)32, CST_SC, (short)6, (short)6, recvBuffer, (short)33); Util.arrayCopyNonAtomic(recvBuffer, (short)33, sc_buffer, OFFSET_SC_MACKEY, SIZE_SC_MACKEY); HmacSha160.computeHmacSha160(recvBuffer, (short)1, (short)32, CST_SC, (short)0, (short)6, recvBuffer, (short)33); sc_sessionkey.setKey(recvBuffer,(short)33); // AES-128: 16-bytes key!! // //alternatively: derive session_key (sha256 of coordx) // sha256.reset(); // sha256.doFinal(recvBuffer, (short)1, (short)32, recvBuffer, (short) 0); // sc_sessionkey.setKey(recvBuffer,(short)0); // AES-128: 16-bytes key!! // //derive mac_key // sha256.reset(); // sha256.doFinal(recvBuffer, (short)0, (short)32, sc_mackey, (short) 0); //reset IV counter Util.arrayFillNonAtomic(sc_buffer, OFFSET_SC_IV, SIZE_SC_IV, (byte) 0); // self signed ephemeral pubkey keyAgreement.generateSecret(Secp256k1.SECP256K1, Secp256k1.OFFSET_SECP256K1_G, (short) 65, buffer, (short)1); //pubkey in uncompressed form Util.setShort(buffer, (short)0, coordx_size); sigECDSA.init(sc_ephemeralkey, 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); // hash signed by authentikey if seed is initialized short offset= (short)(2+coordx_size+2+sign_size); if (bip32_seeded){ sigECDSA.init(bip32_authentikey, Signature.MODE_SIGN); short sign2_size= sigECDSA.sign(buffer, (short)0, offset, buffer, (short)(offset+2)); Util.setShort(buffer, offset, sign2_size); offset+=(short)(2+sign2_size); }else{ Util.setShort(buffer, offset, (short)0); offset+=(short)2; } initialized_secure_channel= true; // 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 | sig2_size(optional) | sig2(optional)] return offset; }
Example #21
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 #22
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 #23
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 #24
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 #25
Source File: AppletUtil.java From ECTester with MIT License | 4 votes |
public static short signCheck(Signature signature) { return nullCheck(signature, AppletBase.SW_SIGNATURE_NULL); }
Example #26
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 #27
Source File: TransitApplet.java From JCMathLib with MIT License | 3 votes |
/** * Generates the response message MAC: generates the MAC and appends the MAC * to the response message. * * @param buffer * The APDU buffer * @param offset * The offset of the MAC in the buffer * @return The resulting length of the response message */ private short generateMAC(byte[] buffer, short offset) { // Initialize signature with current session key for signing signature.init(sessionKey, Signature.MODE_SIGN); // Sign response message and append the MAC to the response message short sigLength = signature.sign(buffer, (short) 0, offset, buffer, offset); return (short) (offset + sigLength); }