Java Code Examples for javacard.framework.Util#setShort()
The following examples show how to use
javacard.framework.Util#setShort() .
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: 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 2
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 6 votes |
/** * This function returns a 2 byte bit mask of the available PINs that are currently in * use. Each set bit corresponds to an active PIN. * * ins: 0x48 * p1: 0x00 * p2: 0x00 * data: none * return: [RFU(1b) | PIN_mask(1b)] */ private short ListPINs(APDU apdu, byte[] buffer) { // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); // Checking P1 & P2 if (buffer[ISO7816.OFFSET_P1] != (byte) 0x00) ISOException.throwIt(SW_INCORRECT_P1); if (buffer[ISO7816.OFFSET_P2] != (byte) 0x00) ISOException.throwIt(SW_INCORRECT_P2); byte expectedBytes = (byte) (buffer[ISO7816.OFFSET_LC]); if (expectedBytes != (short) 2) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // Build the PIN bit mask short mask = (short) 0x00; short b; for (b = (short) 0; b < MAX_NUM_PINS; b++) if (pins[b] != null) mask |= (short) (((short) 0x01) << b); // Fill the buffer Util.setShort(buffer, (short) 0, mask); // Send response return (short)2; }
Example 3
Source File: PasswordManagerApplet.java From sim-password-manager with Apache License 2.0 | 6 votes |
private void prng(byte[] buff, short offset, short len) { if (len > AES_BLOCK_LEN) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Util.arrayCopyNonAtomic(prngNonce, OFFSET_ZERO, cipherBuff, OFFSET_ZERO, (short) prngNonce.length); Util.setShort(cipherBuff, (short) (AES_BLOCK_LEN - 2), prngCounter); try { aesCipher.RoundKeysSchedule(prngKey, (short) 0, roundKeysBuff); // encrypts in place boolean success = aesCipher.AESEncryptBlock(cipherBuff, OFFSET_ZERO, roundKeysBuff); if (!success) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } prngCounter++; Util.arrayCopyNonAtomic(cipherBuff, OFFSET_ZERO, buff, offset, len); } finally { clearCipherState(); } }
Example 4
Source File: ECKeyGenerator.java From ECTester with MIT License | 6 votes |
/** * Exports selected parameters from a given keyPairs key. * Raw parameter data is always prepended by its length as a * short value. The order of parameters is the usual one from * EC_Consts: field,a,b,g,r,k,w,s. * * @param keypair keyPair to export from * @param key key to export from (KEY_PUBLIC || KEY_PRIVATE) * @param params params to export (EC_Consts.PARAMETER_* | ...) * @param buffer buffer to export to * @param offset offset to start writing in buffer * @return length of data written */ public short exportParameters(KeyPair keypair, byte key, short params, byte[] buffer, short offset) { sw = ISO7816.SW_NO_ERROR; if (params == EC_Consts.PARAMETERS_NONE) { return sw; } short length = 0; short paramMask = EC_Consts.PARAMETER_FP; while (paramMask <= EC_Consts.PARAMETER_S) { short masked = (short) (paramMask & params); if (masked != 0) { short len = exportParameter(keypair, key, masked, buffer, (short) (offset + 2)); if (len == 0) { paramMask = (short) (paramMask << 1); continue; } Util.setShort(buffer, offset, len); offset += len + 2; length += len + 2; } paramMask = (short) (paramMask << 1); } return length; }
Example 5
Source File: TransitApplet.java From JCMathLib with MIT License | 6 votes |
/** * Gets/returns the balance. * * Request Message: [] * * Response Message: [2-bytes Balance] * * @param buffer * The APDU buffer * @param messageOffset * The offset of the request message content in the APDU buffer * @param messageLength * The length of the request message content. * @return The offset at which content can be appended to the response * message */ private short getBalance(byte[] buffer, short messageOffset, short messageLength) { // Check access authorization if (!pin.isValidated()) { ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED); } // Request Message: [] if (messageLength != 0) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Response Message: [2-bytes Balance] short offset = 0; // Append balance to response message offset = Util.setShort(buffer, offset, balance); return offset; }
Example 6
Source File: Gpg.java From OpenPGP-Card with GNU General Public License v3.0 | 5 votes |
/** * Append a fixed length byte buffer as a TLV * * @param src the source data, must be <= 127 bytes * @param out the destination for the tlv * @param offset the offset into out * @return the offset to the next byte to be written */ private short addShortTLV(short tag, byte[] src, byte[] out, short offset) { if ((short) (tag & (short) 0xFF00) != (short) 0) { Util.setShort(out, offset, tag); offset += 2; } else { out[offset++] = (byte) tag; } out[offset++] = (byte) src.length; return Util.arrayCopyNonAtomic(src, (short) 0, out, offset, (short) src.length); }
Example 7
Source File: GidsPINManager.java From GidsApplet with GNU General Public License v3.0 | 5 votes |
/** * \brief return information regarding the PIN */ public void returnPINStatus(APDU apdu, short id) { byte[] buf = apdu.getBuffer(); GidsPIN pin = null; switch(id) { default: ISOException.throwIt(ErrorCode.SW_REFERENCE_DATA_NOT_FOUND); break; case (short) 0x7F71: case (short) 0x7F72: pin = pin_pin; break; } Util.setShort(buf, (short) 0, id); buf[2] = (byte) 0x06; buf[3] = (byte) 0x97; buf[4] = (byte) 0x01; buf[5] = pin.getTriesRemaining(); buf[6] = (byte) 0x93; buf[7] = (byte) 0x01; buf[8] = pin.getTryLimit(); apdu.setOutgoing(); apdu.setOutgoingLength((short)9); apdu.sendBytes((short) 0, (short) 9); }
Example 8
Source File: NdefApplet.java From openjavacard-ndef with GNU General Public License v3.0 | 5 votes |
/** * Create and initialize the CAPABILITIES file * * @param dataSize to be allocated * @param dataReadAccess to put in the CC * @param dataWriteAccess to put in the CC * @return an array for use as the CC file */ private byte[] makeCaps(short dataSize, byte dataReadAccess, byte dataWriteAccess) { short capsLen = (short)(CC_LEN_HEADER + 2 + CC_LEN_NDEF_FILE_CONTROL); byte[] caps = new byte[capsLen]; short pos = 0; // CC length pos = Util.setShort(caps, pos, capsLen); // mapping version caps[pos++] = NDEF_MAPPING_VERSION; // maximum read size pos = Util.setShort(caps, pos, NDEF_MAX_READ); // maximum write size pos = Util.setShort(caps, pos, NDEF_MAX_WRITE); // NDEF File Control TLV caps[pos++] = CC_TAG_NDEF_FILE_CONTROL; caps[pos++] = CC_LEN_NDEF_FILE_CONTROL; // file ID pos = Util.setShort(caps, pos, FILEID_NDEF_DATA); // file size pos = Util.setShort(caps, pos, dataSize); // read access caps[pos++] = dataReadAccess; // write access caps[pos++] = dataWriteAccess; // check consistency if(pos != capsLen) { ISOException.throwIt(ISO7816.SW_UNKNOWN); } // return the file return caps; }
Example 9
Source File: NdefApplet.java From openjavacard-ndef with GNU General Public License v3.0 | 5 votes |
/** * Create and initialize the CAPABILITIES file * * @param dataSize to be allocated * @return an array for use as the CC file */ private byte[] makeCaps(short dataSize) { short capsLen = (short)(CC_LEN_HEADER + 2 + CC_LEN_NDEF_FILE_CONTROL); byte[] caps = new byte[capsLen]; short pos = 0; // CC length pos = Util.setShort(caps, pos, capsLen); // mapping version caps[pos++] = NDEF_MAPPING_VERSION; // maximum read size pos = Util.setShort(caps, pos, NDEF_MAX_READ); // maximum write size pos = Util.setShort(caps, pos, NDEF_MAX_WRITE); // NDEF File Control TLV caps[pos++] = CC_TAG_NDEF_FILE_CONTROL; caps[pos++] = CC_LEN_NDEF_FILE_CONTROL; // file ID pos = Util.setShort(caps, pos, FILEID_NDEF_DATA); // file size pos = Util.setShort(caps, pos, dataSize); // read access caps[pos++] = NDEF_READ_ACCESS; // write access caps[pos++] = NDEF_WRITE_ACCESS; // check consistency if(pos != capsLen) { ISOException.throwIt(ISO7816.SW_UNKNOWN); } // return the file return caps; }
Example 10
Source File: LWNFCForumApplet.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
public static void writeHeader(short textSize) { short offset = (short)0; Util.setShort(FILE_DATA, offset, (short)(textSize + 1 + 5 + 4 + 2 + 1)); // prefix with size of full record offset += (short)(2 + 4); Util.setShort(FILE_DATA, offset, (short)(textSize + 1 + 5)); // size of text record payload }
Example 11
Source File: OpenPGPSecureMessaging.java From javacard-openpgpcard with GNU General Public License v2.0 | 4 votes |
/** * Wraps (encrypts and build MAC) the response data and places it in the * APDU buffer starting at offset 0. The buffer can be any buffer including * the APDU buffer itself. If the length is zero the buffer will not be * addressed and no response data will be present in the wrapped output. * * @param buffer byte array containing the data which needs to be wrapped. * @param offset location of the data in the buffer. * @param length of the data in the buffer (in bytes). * @param status word which has to be wrapped in the response APDU. * @return the length of the wrapped data in the <apdu> buffer */ public short wrapResponseAPDU(byte[] buffer, short offset, short length, short status) { byte[] apdu = APDU.getCurrentAPDUBuffer(); short apdu_p = 0; // smallest multiple of 8 strictly larger than plaintextLen (length + padding) short do87DataLen = (short) ((((short) (length + 8)) / 8) * 8); // for 0x01 marker (indicating padding is used) do87DataLen++; short do87DataLenBytes = (short)(do87DataLen > 0xff? 2 : 1); short do87HeaderBytes = getApduBufferOffset(length); short do87Bytes = (short)(do87HeaderBytes + do87DataLen - 1); // 0x01 is counted twice boolean hasDo87 = length > 0; incrementSSC(); short ciphertextLength=0; if(hasDo87) { // Copy the plain text to temporary buffer to avoid data corruption. Util.arrayCopyNonAtomic(buffer, offset, tmp, (short) 0, length); // Put the cipher text in the proper position. ciphertextLength = cipher.doFinal(tmp, (short) 0, length, apdu, do87HeaderBytes); } //sanity check //note that this check // (possiblyPaddedPlaintextLength != (short)(do87DataLen -1)) //does not always hold because some algs do the padding in the final, some in the init. if (hasDo87 && (((short) (do87DataLen - 1) != ciphertextLength))) ISOException.throwIt(SW_INTERNAL_ERROR); if (hasDo87) { // build do87 apdu[apdu_p++] = (byte) 0x87; if(do87DataLen < 0x80) { apdu[apdu_p++] = (byte)do87DataLen; } else { apdu[apdu_p++] = (byte) (0x80 + do87DataLenBytes); for(short i = (short) (do87DataLenBytes - 1); i >= 0; i--) { apdu[apdu_p++] = (byte) ((do87DataLen >>> (i * 8)) & 0xff); } } apdu[apdu_p++] = 0x01; } if(hasDo87) { apdu_p = do87Bytes; } // build do99 apdu[apdu_p++] = (byte) 0x99; apdu[apdu_p++] = 0x02; Util.setShort(apdu, apdu_p, status); apdu_p += 2; // calculate and write mac signer.update(ssc, (short) 0, (short) ssc.length); signer.sign(apdu, (short) 0, apdu_p, apdu, (short) (apdu_p + 2)); // write do8e apdu[apdu_p++] = (byte) 0x8e; apdu[apdu_p++] = 0x08; apdu_p += 8; // for mac written earlier return apdu_p; }
Example 12
Source File: Uint32Helper.java From ledger-javacard with GNU Affero General Public License v3.0 | 4 votes |
public static void setShort(byte[] buffer, short offset, short value) { clear(buffer, offset); Util.setShort(buffer, (short)(offset + 2), value); }
Example 13
Source File: EC_Consts.java From ECTester with MIT License | 4 votes |
public static short transformParameter(short transformation, byte[] buffer, short offset, short length) { if (transformation == TRANSFORMATION_NONE) { return length; } short transformationMask = TRANSFORMATION_FIXED; while (transformationMask <= TRANSFORMATION_04_MASK) { short transformationPart = (short) (transformationMask & transformation); switch (transformationPart) { case (short) 0: break; case TRANSFORMATION_FIXED: if (length >= 1) { buffer[offset] = (byte) 0xcc; buffer[(short) (offset + length - 1)] = (byte) 0xcc; } break; case TRANSFORMATION_FULLRANDOM: randomData.generateData(buffer, offset, length); break; case TRANSFORMATION_ONEBYTERANDOM: short first = Util.getShort(buffer, (short) 0); // save first two bytes randomData.generateData(buffer, (short) 0, (short) 2); // generate position short rngPos = Util.getShort(buffer, (short) 0); // save generated position Util.setShort(buffer, (short) 0, first); // restore first two bytes if (rngPos < 0) { // make positive rngPos = (short) -rngPos; } rngPos %= length; // make < param length byte original = buffer[rngPos]; do { randomData.generateData(buffer, rngPos, (short) 1); } while (original == buffer[rngPos]); break; case TRANSFORMATION_ZERO: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); break; case TRANSFORMATION_ONE: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); buffer[(short) (offset + length)] = (byte) 1; break; case TRANSFORMATION_MAX: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 1); break; case TRANSFORMATION_INCREMENT: short index = (short) (offset + length - 1); byte value; do { value = buffer[index]; buffer[index--] = ++value; } while (value == (byte) 0 && index >= offset); break; case TRANSFORMATION_INFINITY: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); length = 1; break; case TRANSFORMATION_COMPRESS_HYBRID: case TRANSFORMATION_COMPRESS: if ((short) (length % 2) != 1) { // an uncompressed point should have odd length (since 1 byte type, + 2 * coords) ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } short half = (short) ((short) (length - 1) / 2); byte yLSB = buffer[(short) (offset + length)]; byte yBit = (byte) (yLSB & 0x01); if (yBit == 1) { buffer[offset] = 3; } else { buffer[offset] = 2; } if (transformationPart == TRANSFORMATION_COMPRESS) { length = (short) (half + 1); } else { buffer[offset] += 4; } break; case TRANSFORMATION_04_MASK: buffer[offset] = 4; break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } transformationMask = (short) (transformationMask << 1); } return length; }
Example 14
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 15
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 16
Source File: Gpg.java From OpenPGP-Card with GNU General Public License v3.0 | 4 votes |
private void decrypt(APDU apdu) { byte[] buffer = apdu.getBuffer(); // PW1 with 0x82 if (!pins[PIN_INDEX_PW1].isValidated() || !pinSubmitted[1]) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } if (!confidentialityKey.getPrivate().isInitialized()) { ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND); } boolean firstCommand = (commandChainingBuffer[TEMP_INS] != buffer[ISO7816.OFFSET_INS]); // Mark the command chain as bad so it stays in this state in case of exception. short len = apdu.setIncomingAndReceive(); if (len < 1) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (firstCommand) { Util.arrayCopyNonAtomic(buffer, (short) (ISO7816.OFFSET_CDATA + 1), commandChainingBuffer, TEMP_GET_RESPONSE_DATA, (short) (len - 1)); len = (short) (len - 1); } else { short existing = Util.getShort(commandChainingBuffer, TEMP_GET_RESPONSE_LENGTH); if ((short) (len + existing) > RSA_KEY_LENGTH_BYTES) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, commandChainingBuffer, (short) (TEMP_GET_RESPONSE_DATA + existing), len); len += existing; } if (len < RSA_KEY_LENGTH_BYTES) { commandChainingBuffer[TEMP_INS] = CMD_COMPUTE_PSO; Util.setShort(commandChainingBuffer, TEMP_GET_RESPONSE_LENGTH, len); return; // For compatibily with GPG } // We have enough bytes to decrypt. cipherRSA.init(confidentialityKey.getPrivate(), Cipher.MODE_DECRYPT); len = cipherRSA.doFinal(commandChainingBuffer, TEMP_GET_RESPONSE_DATA, RSA_KEY_LENGTH_BYTES, buffer, (short) 0); // Clear command chaining buffer to make ready for next operation. Util.arrayFillNonAtomic(commandChainingBuffer, (short) 0, (short) commandChainingBuffer.length, (byte) 0); apdu.setOutgoingAndSend((short) 0, len); }
Example 17
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 18
Source File: Bignat.java From JCMathLib with MIT License | 4 votes |
/** * Add short value to this bignat * @param other short value to add */ public void add(short other) { Util.setShort(bnh.tmp_array_short, (short) 0, other); // serialize other into array this.add_carry(bnh.tmp_array_short, (short) 0, (short) 2); // add as array }
Example 19
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 3 votes |
/** * DEPRECATED - Not necessary anymore when recovering the pubkey with ALG_EC_SVDP_DH_PLAIN_XY * A minimalist API is maintained for backward compatibility. * * This function allows to compute the authentikey pubkey externally and * store it in the secure memory cache for future use. * This allows to speed up computation during derivation of non-hardened child. * * ins: 0x75 * p1: * p2: * data: [coordx_size(2b) | coordx | sig_size(2b) | sig][coordy_size(2b) | coordy] * * returns: none */ private short setBIP32AuthentikeyPubkey(APDU apdu, byte[] buffer){ // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); short pos=0; Util.setShort(buffer, pos, bip32_om.nb_elem_free); // number of slot available pos += (short) 2; Util.setShort(buffer, pos, bip32_om.nb_elem_used); // number of slot used pos += (short) 2; return pos; }
Example 20
Source File: CardEdge.java From SatochipApplet with GNU Affero General Public License v3.0 | 3 votes |
/** * DEPRECATED - Not necessary anymore when recovering the pubkey with ALG_EC_SVDP_DH_PLAIN_XY * A minimalist API is maintained for backward compatibility. * * This function allows to compute an extended pubkey externally and * store it in the secure BIP32 memory cache for future use. * This allows to speed up computation during derivation of non-hardened child. * * ins: 0x74 * p1: * p2: * data: [chaincode(32b) | coordx_size(2b) | coordx | sig_size(2b) | sig | sig_size(2b) | sig2 ] * [ coordy_size(2b) | coordy] * returns: none */ private short setBIP32ExtendedPubkey(APDU apdu, byte[] buffer){ // check that PIN[0] has been entered previously if (!pins[0].isValidated()) ISOException.throwIt(SW_UNAUTHORIZED); short pos=0; Util.setShort(buffer, pos, bip32_om.nb_elem_free); // number of slot available pos += (short) 2; Util.setShort(buffer, pos, bip32_om.nb_elem_used); // number of slot used pos += (short) 2; return pos; }