javacard.security.Key Java Examples

The following examples show how to use javacard.security.Key. 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 7 votes vote down vote up
/**
 * Retrieves the Key object to be used w/ the specified key number, key type
 * (KEY_XX) and size. If exists, check it has the proper key type If not,
 * creates it.
 * 
 * @return Retrieved Key object or throws SW_UNATUTHORIZED,
 *         SW_OPERATION_NOT_ALLOWED
 */
private Key getKey(byte key_nb, byte key_type, short key_size) {
	
	if (eckeys[key_nb] == null) {
		// We have to create the Key
		eckeys[key_nb] = KeyBuilder.buildKey(key_type, key_size, false);
	} else {
		// Key already exists: check size & type
		/*
		 * TODO: As an option, we could just discard and recreate if not of
		 * the correct type, but creates trash objects
		 */
		if ((eckeys[key_nb].getSize() != key_size) || (eckeys[key_nb].getType() != key_type))
			ISOException.throwIt(SW_OPERATION_NOT_ALLOWED);
	}
	return eckeys[key_nb];
}
 
Example #2
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 4 votes vote down vote up
/** 
 * 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 #3
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 4 votes vote down vote up
/** 
 * 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 #4
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
   * 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 #5
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
   * 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 #6
Source File: JCardSIMProprietaryAPI.java    From ledger-javacard with GNU Affero General Public License v3.0 4 votes vote down vote up
@Override
public void hmacSHA512(Key key, byte[] in, short inBuffer, short inLength, byte[] out, short outOffset) {
}
 
Example #7
Source File: JCardSIMProprietaryAPI.java    From ledger-javacard with GNU Affero General Public License v3.0 4 votes vote down vote up
@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 #8
Source File: ProprietaryAPI.java    From ledger-javacard with GNU Affero General Public License v3.0 2 votes vote down vote up
/**
 * Perform an optimized HMAC SHA512 operation
 * @param key HMAC key object provisioned with the HMAC key
 * @param in buffer containing the data to HMAC
 * @param inBuffer offset to the data
 * @param inLength length of the data
 * @param out buffer that will contain the HMAC SHA512 result
 * @param outOffset offset to the result
 */
public void hmacSHA512(Key key, byte[] in, short inBuffer, short inLength, byte[] out, short outOffset);
 
Example #9
Source File: ProprietaryAPI.java    From ledger-javacard with GNU Affero General Public License v3.0 2 votes vote down vote up
/**
 * Perform a deterministic ECDSA SHA-256 signature
 * Non malleability is not guaranteed and should be checked by the host
 * (see https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures)
 * @param key Private ECC key object provisioned with the signature key
 * @param in buffer containing the data to hash and sign
 * @param inBuffer offset to the data
 * @param inLength length of the data
 * @param out buffer that will contain the signature
 * @param outOffset offset to the signature
 */	
public void signDeterministicECDSASHA256(Key key, byte[] in, short inBuffer, short inLength, byte[] out, short outOffset);