Java Code Examples for javacard.framework.Util#arrayCompare()
The following examples show how to use
javacard.framework.Util#arrayCompare() .
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: ECPoint.java From JCMathLib with MIT License | 6 votes |
/** * Compares this and provided point for equality. The comparison is made using hash of both values to prevent leak of position of mismatching byte. * @param other second point for comparison * @return true if both point are exactly equal (same length, same value), false otherwise */ public boolean isEqual(ECPoint other) { boolean bResult = false; if (this.length() != other.length()) { return false; } else { // The comparison is made with hash of point values instead of directly values. // This way, offset of first mismatching byte is not leaked via timing side-channel. // Additionally, only single array is required for storage of plain point values thus saving some RAM. ech.lock(ech.uncompressed_point_arr1); ech.lock(ech.fnc_isEqual_hashArray); //ech.lock(ech.fnc_isEqual_hashEngine); short len = this.getW(ech.uncompressed_point_arr1, (short) 0); ech.fnc_isEqual_hashEngine.doFinal(ech.uncompressed_point_arr1, (short) 0, len, ech.fnc_isEqual_hashArray, (short) 0); len = other.getW(ech.uncompressed_point_arr1, (short) 0); len = ech.fnc_isEqual_hashEngine.doFinal(ech.uncompressed_point_arr1, (short) 0, len, ech.uncompressed_point_arr1, (short) 0); bResult = Util.arrayCompare(ech.fnc_isEqual_hashArray, (short) 0, ech.uncompressed_point_arr1, (short) 0, len) == 0; //ech.unlock(ech.fnc_isEqual_hashEngine); ech.unlock(ech.fnc_isEqual_hashArray); ech.unlock(ech.uncompressed_point_arr1); } return bResult; }
Example 2
Source File: FIDOCCImplementation.java From CCU2F with Apache License 2.0 | 6 votes |
public boolean unwrap(byte[] keyHandle, short keyHandleOffset, short keyHandleLength, byte[] applicationParameter, short applicationParameterOffset, ECPrivateKey unwrappedPrivateKey) { calcMAC(applicationParameter, applicationParameterOffset, keyHandle, keyHandleOffset); //Compare MAC if (Util.arrayCompare(scratch, (short) 0, keyHandle, (short)(keyHandleOffset+32), (short)32)!=0) { return false; } //only get key if signing is required if (unwrappedPrivateKey != null) { //Regenerate PrivKey generatePrivateKey(applicationParameter, applicationParameterOffset, keyHandle, keyHandleOffset); unwrappedPrivateKey.setS(scratch, (short)0, (short)32); } Util.arrayFillNonAtomic(scratch, (short)0, (short)32, (byte)0x00); return true; }
Example 3
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 4
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 5
Source File: Secp256k1.java From SatochipApplet with GNU Affero General Public License v3.0 | 6 votes |
public static boolean checkCurveParameters(ECKey eckey, byte[] tmpbuffer, short tmpoffset){ eckey.getA(tmpbuffer, tmpoffset); if (0!=Util.arrayCompare(tmpbuffer, tmpoffset, SECP256K1, OFFSET_SECP256K1_a, (short)32)) return false; eckey.getB(tmpbuffer, tmpoffset); if (0!=Util.arrayCompare(tmpbuffer, tmpoffset, SECP256K1, OFFSET_SECP256K1_b, (short)32)) return false; eckey.getG(tmpbuffer, tmpoffset); if (0!=Util.arrayCompare(tmpbuffer, tmpoffset, SECP256K1, OFFSET_SECP256K1_G, (short)65)) return false; eckey.getR(tmpbuffer, tmpoffset); if (0!=Util.arrayCompare(tmpbuffer, tmpoffset, SECP256K1, OFFSET_SECP256K1_R, (short)32)) return false; eckey.getField(tmpbuffer, tmpoffset); if (0!=Util.arrayCompare(tmpbuffer, tmpoffset, SECP256K1, OFFSET_SECP256K1_P, (short)32)) return false; if (eckey.getK()!= SECP256K1_K) return false; return true; }
Example 6
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 5 votes |
/** * This function allows to reset the 2FA key and disable 2FA. * Once activated, 2FA can only be deactivated when the seed is reset and all eckeys cleared. * * ins: 0x78 * p1: 0x00 * p2: 0x00 * data: [hmacsha1_key(20b)] * return: (none) */ private short reset2FAKey(APDU apdu, byte[] buffer){ // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); // check length short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); if (bytesLeft < (short)20) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // reset 2FA can only be done if all private keys are cleared if (!needs_2FA) ISOException.throwIt(SW_2FA_UNINITIALIZED_KEY); if (bip32_seeded) ISOException.throwIt(SW_BIP32_INITIALIZED_SEED); if (eckeys_flag != 0x0000) ISOException.throwIt(SW_ECKEYS_INITIALIZED_KEY); // compute hmac(2FA_ID) and compare with value provided // hmac of 64-bytes msg: (id_2FA(20b) | 44 bytes 0xAA-padding) short offset= ISO7816.OFFSET_CDATA; Util.arrayFillNonAtomic(recvBuffer, (short)0, (short)64, (byte)0xAA); Util.arrayCopyNonAtomic(data2FA, OFFSET_2FA_ID, recvBuffer, (short)0, (short)20); HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, recvBuffer, (short)0, (short)64, recvBuffer, (short)64); if (Util.arrayCompare(buffer, offset, recvBuffer, (short)64, (short)20)!=0) ISOException.throwIt(SW_SIGNATURE_INVALID); // reset flag and data needs_2FA= false; key_2FA.clearKey(); Util.arrayFillNonAtomic(data2FA, (short)0, OFFSET_2FA_SIZE, (byte)0x00); return (short)0; }
Example 7
Source File: LedgerWalletApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static void verifyKeyChecksum(byte[] buffer, short offset, short length, byte[] scratch, short scratchOffset) { Crypto.digestScratch.doFinal(buffer, offset, (short)(length - 4), scratch, scratchOffset); Crypto.digestScratch.doFinal(scratch, scratchOffset, TC.SIZEOF_SHA256, scratch, scratchOffset); if (Util.arrayCompare(scratch, scratchOffset, buffer, (short)(offset + length - 4), (short)4) != (byte)0x00) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } }
Example 8
Source File: Bip32Cache.java From ledger-javacard with GNU Affero General Public License v3.0 | 5 votes |
private static Bip32Cache findPath(byte[] path, short pathOffset, byte pathLength, boolean setLast) { for (short i=0; i<CACHE_SIZE; i++) { if ((cache[i].pathLength == pathLength) && (Util.arrayCompare(path, pathOffset, cache[i].path, (short)0, (short)(pathLength * 4)) == 0)) { if (setLast) { lastCacheIndex[0] = (byte)i; } return cache[i]; } } return null; }
Example 9
Source File: Bip32ObjectManager.java From SatochipApplet with GNU Affero General Public License v3.0 | 5 votes |
/** 1 * Returns the object base address (offset) for an object that start with data provided in array * <p> * * @param src * a byte array to compare object with * @param srcOff * the offset for the source array */ public short getBaseAddress(byte[] src, short srcOff) { short base = 0; while (base<this.size) { if (Util.arrayCompare(src, srcOff, this.ptr, base, this.size_id)==0){ return base; } base+=this.size_elem; } return NULL_OFFSET; }
Example 10
Source File: Bip32ObjectManager.java From SatochipApplet with GNU Affero General Public License v3.0 | 5 votes |
public short reset(){ short base = 0; short nb_deleted=0; while (base<this.size) { if (Util.arrayCompare(this.ptr, base, this.empty, (short)0, this.size_id)!=0){ Util.arrayFillNonAtomic(this.ptr, base, this.size_elem, (byte)0x00); this.nb_elem_free++; this.nb_elem_used--; nb_deleted++; } base+=this.size_elem; } return nb_deleted; }
Example 11
Source File: Bip32ObjectManager.java From SatochipApplet with GNU Affero General Public License v3.0 | 5 votes |
/** * Destroy the object starting with specific value * * @param src * a byte array to compare object with * @param srcOff * the offset for the source array */ public void destroyObject(byte[] src, short srcOff){ short base = 0; while (base<this.size) { if (Util.arrayCompare(src, srcOff, this.ptr, base, this.size_id)==0){ Util.arrayFillNonAtomic(this.ptr, base, this.size_elem, (byte)0x00); this.nb_elem_free++; this.nb_elem_used--; return; } base+=this.size_elem; } }
Example 12
Source File: Bignat.java From JCMathLib with MIT License | 5 votes |
/** * Equality check. Requires that this object and other have the same size or are padded with zeroes. * Returns true if all digits (except for leading zeroes) are equal. * * * @param other Bignat to compare * @return true if this and other have the same value, false otherwise. */ public boolean same_value(Bignat other) { short hashLen; // Compare using hash engine // The comparison is made with hash of point values instead of directly values. // This way, offset of first mismatching byte is not leaked via timing side-channel. bnh.lock(bnh.fnc_same_value_array1); bnh.lock(bnh.fnc_same_value_hash); if (this.length() == other.length()) { // Same length, we can hash directly from BN values bnh.hashEngine.doFinal(this.value, (short) 0, this.length(), bnh.fnc_same_value_hash, (short) 0); hashLen = bnh.hashEngine.doFinal(other.value, (short) 0, other.length(), bnh.fnc_same_value_array1, (short) 0); } else { // Different length of bignats - can be still same if prepended with zeroes // Find the length of longer one and padd other one with starting zeroes if (this.length() < other.length()) { this.prepend_zeros(other.length(), bnh.fnc_same_value_array1, (short) 0); bnh.hashEngine.doFinal(bnh.fnc_same_value_array1, (short) 0, other.length(), bnh.fnc_same_value_hash, (short) 0); hashLen = bnh.hashEngine.doFinal(other.value, (short) 0, other.length(), bnh.fnc_same_value_array1, (short) 0); } else { other.prepend_zeros(this.length(), bnh.fnc_same_value_array1, (short) 0); bnh.hashEngine.doFinal(bnh.fnc_same_value_array1, (short) 0, this.length(), bnh.fnc_same_value_hash, (short) 0); hashLen = bnh.hashEngine.doFinal(this.value, (short) 0, this.length(), bnh.fnc_same_value_array1, (short) 0); } } boolean bResult = Util.arrayCompare(bnh.fnc_same_value_hash, (short) 0, bnh.fnc_same_value_array1, (short) 0, hashLen) == 0; bnh.unlock(bnh.fnc_same_value_array1); bnh.unlock(bnh.fnc_same_value_hash); return bResult; }
Example 13
Source File: OpenPGPSecureMessaging.java From javacard-openpgpcard with GNU General Public License v2.0 | 5 votes |
/** * Set the encryption 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 setSessionKeyEncryption(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 { keyENC.setKey(buffer, (short) (offset + KEY_SIZE)); cipher.init(keyENC, Cipher.MODE_ENCRYPT); decipher.init(keyENC, Cipher.MODE_DECRYPT); } }
Example 14
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 15
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function allows to decrypt a secure channel message * * ins: 0x82 * * p1: 0x00 (RFU) * p2: 0x00 (RFU) * data: [IV(16b) | data_size(2b) | encrypted_command | mac_size(2b) | mac] * * return: [decrypted command] * */ private short ProcessSecureChannel(APDU apdu, byte[] buffer){ short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); short offset = ISO7816.OFFSET_CDATA; if (!initialized_secure_channel){ ISOException.throwIt(SW_SECURE_CHANNEL_UNINITIALIZED); } // check hmac if (bytesLeft<18) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); short sizein = Util.getShort(buffer, (short) (offset+SIZE_SC_IV)); if (bytesLeft<(short)(SIZE_SC_IV+2+sizein+2)) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); short sizemac= Util.getShort(buffer, (short) (offset+SIZE_SC_IV+2+sizein)); if (sizemac != (short)20) ISOException.throwIt(SW_SECURE_CHANNEL_WRONG_MAC); if (bytesLeft<(short)(SIZE_SC_IV+2+sizein+2+sizemac)) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); HmacSha160.computeHmacSha160(sc_buffer, OFFSET_SC_MACKEY, SIZE_SC_MACKEY, buffer, offset, (short)(SIZE_SC_IV+2+sizein), recvBuffer, (short)0); if ( Util.arrayCompare(recvBuffer, (short)0, buffer, (short)(offset+SIZE_SC_IV+2+sizein+2), (short)20) != (byte)0 ) ISOException.throwIt(SW_SECURE_CHANNEL_WRONG_MAC); // process IV // IV received from client should be odd and strictly greater than locally saved IV // IV should be random (the 12 first bytes), never reused (the last 4 bytes counter) and different for send and receive if ((buffer[(short)(offset+SIZE_SC_IV-(short)1)] & (byte)0x01)==0x00)// should be odd ISOException.throwIt(SW_SECURE_CHANNEL_WRONG_IV); if ( !Biginteger.lessThan(sc_buffer, OFFSET_SC_IV_COUNTER, buffer, (short)(offset+SIZE_SC_IV_RANDOM), SIZE_SC_IV_COUNTER ) ) //and greater than local IV ISOException.throwIt(SW_SECURE_CHANNEL_WRONG_IV); // update local IV Util.arrayCopy(buffer, (short)(offset+SIZE_SC_IV_RANDOM), sc_buffer, OFFSET_SC_IV_COUNTER, SIZE_SC_IV_COUNTER); Biginteger.add1_carry(sc_buffer, OFFSET_SC_IV_COUNTER, SIZE_SC_IV_COUNTER); randomData.generateData(sc_buffer, OFFSET_SC_IV_RANDOM, SIZE_SC_IV_RANDOM); sc_aes128_cbc.init(sc_sessionkey, Cipher.MODE_DECRYPT, buffer, offset, SIZE_SC_IV); offset+=SIZE_SC_IV; bytesLeft-=SIZE_SC_IV; //decrypt command offset+=2; bytesLeft-=2; if (bytesLeft<sizein) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); short sizeout=sc_aes128_cbc.doFinal(buffer, offset, sizein, buffer, (short) (0)); return sizeout; }
Example 16
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 17
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 18
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 4 votes |
/** * This function resets the Bip32 seed and all derived keys: the master key, chain code, authentikey * and the 32-bit AES key that is used to encrypt/decrypt Bip32 object stored in secure memory. * If 2FA is enabled, then a hmac code must be provided, based on the 4-byte counter-2FA. * * ins: 0x77 * p1: PIN_size * p2: 0x00 * data: [PIN | optional-hmac(20b)] * return: (none) */ private short resetBIP32Seed(APDU apdu, byte[] buffer){ short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]); // check provided PIN byte pin_size= buffer[ISO7816.OFFSET_P1]; OwnerPIN pin = pins[(byte)0x00]; if (bytesLeft < pin_size) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); if (!CheckPINPolicy(buffer, ISO7816.OFFSET_CDATA, 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, (byte) pin_size)) { LogoutIdentity((byte)0x00); ISOException.throwIt((short)(SW_PIN_FAILED + triesRemaining - 1)); } // check if seeded if (!bip32_seeded) ISOException.throwIt(SW_BIP32_UNINITIALIZED_SEED); // check 2FA if required if (needs_2FA){ short offset= Util.makeShort((byte)0, ISO7816.OFFSET_CDATA); offset+=pin_size; bytesLeft-= pin_size; if (bytesLeft < (short)20) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // compute hmac(counter_2FA) and compare with value provided // hmac of 64-bytes msg: ( authentikey-coordx(32b) | 32bytes 0xFF-padding) Util.arrayFillNonAtomic(recvBuffer, (short)0, (short)64, (byte)0xFF); Util.arrayCopyNonAtomic(authentikey_pubkey, (short)0x01, recvBuffer, (short)0, BIP32_KEY_SIZE); HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, recvBuffer, (short)0, (short)64, recvBuffer, (short)64); if (Util.arrayCompare(buffer, offset, recvBuffer, (short)64, (short)20)!=0) ISOException.throwIt(SW_SIGNATURE_INVALID); } // reset memory cache, bip32 flag and all data! bip32_om.reset(); bip32_seeded= false; bip32_masterkey.clearKey(); bip32_masterchaincode.clearKey(); bip32_encryptkey.clearKey(); bip32_authentikey.clearKey(); Secp256k1.setCommonCurveParameters(bip32_authentikey);// keep public params! Util.arrayFillNonAtomic(authentikey_pubkey, (short)0, (short)(2*BIP32_KEY_SIZE+1), (byte)0x00); LogOutAll(); return (short)0; }
Example 19
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 20
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); } }