fix DERIVE KEY

This commit is contained in:
Michele Balistreri 2017-10-18 15:51:03 +03:00
parent 32fbcfdcd5
commit c4b0da3703
3 changed files with 16 additions and 10 deletions

View File

@ -34,6 +34,7 @@ public class Crypto {
hmacSHA512 = Signature.getInstance(Signature.ALG_HMAC_SHA_512, false); hmacSHA512 = Signature.getInstance(Signature.ALG_HMAC_SHA_512, false);
hmacKey = (HMACKey) KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC_TRANSIENT_DESELECT, KEY_SECRET_SIZE, false); hmacKey = (HMACKey) KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC_TRANSIENT_DESELECT, KEY_SECRET_SIZE, false);
} catch (CryptoException e) { } catch (CryptoException e) {
hmacSHA512 = null;
sha512 = MessageDigest.getInstance(MessageDigest.ALG_SHA_512, false); sha512 = MessageDigest.getInstance(MessageDigest.ALG_SHA_512, false);
blockSize = HMAC_BLOCK_SIZE; blockSize = HMAC_BLOCK_SIZE;
} }
@ -49,7 +50,7 @@ public class Crypto {
off += privateKey.getS(tmp, off); off += privateKey.getS(tmp, off);
} else { } else {
off = (short) (publicKey.getW(tmp, (short) 0) - 1); off = (short) (publicKey.getW(tmp, (short) 0) - 1);
tmp[0] = ((tmp[(short) off] & 1) != 0 ? (byte) 0x03 : (byte) 0x02); tmp[0] = ((tmp[off] & 1) != 0 ? (byte) 0x03 : (byte) 0x02);
off = (short) ((short) (off / 2) + 1); off = (short) ((short) (off / 2) + 1);
} }
@ -63,7 +64,7 @@ public class Crypto {
privateKey.getS(tmp, (short) 0); privateKey.getS(tmp, (short) 0);
addm256(tmp, off, tmp, (short) 0, SECP256k1.SECP256K1_R, (short)0, tmp, off); addm256(tmp, off, tmp, (short) 0, SECP256k1.SECP256K1_R, (short) 0, tmp, off);
if (isZero256(tmp, off)) { if (isZero256(tmp, off)) {
return false; return false;
@ -135,10 +136,9 @@ public class Crypto {
} }
private static short add256(byte[] a, short aOff, byte[] b, short bOff, byte[] out, short outOff) { private static short add256(byte[] a, short aOff, byte[] b, short bOff, byte[] out, short outOff) {
short outI = 0; short outI = 0;
for (short i = 31 ; i >= 0 ; i--) { for (short i = 31 ; i >= 0 ; i--) {
outI = (short) ((short)(a[(short)(aOff + i)] & 0x00FF) + (short)(b[(short)(bOff + i)] & 0xFF) + outI); outI = (short) ((short)(a[(short)(aOff + i)] & 0xFF) + (short)(b[(short)(bOff + i)] & 0xFF) + outI);
out[(short)(outOff + i)] = (byte)outI ; out[(short)(outOff + i)] = (byte)outI ;
outI = (short)(outI >> 8); outI = (short)(outI >> 8);
} }

View File

@ -357,12 +357,13 @@ public class WalletApplet extends Applet {
ISOException.throwIt(ISO7816.SW_WRONG_DATA); ISOException.throwIt(ISO7816.SW_WRONG_DATA);
} }
resetKeys(apduBuffer, len); short chainEnd = (short) (ISO7816.OFFSET_CDATA + len);
resetKeys(apduBuffer, chainEnd);
for (short i = 0; i < len; i += 4) { for (short i = ISO7816.OFFSET_CDATA; i < chainEnd; i += 4) {
Crypto.bip32CKDPriv(apduBuffer, i, privateKey, publicKey, chainCode, (short) 0); Crypto.bip32CKDPriv(apduBuffer, i, privateKey, publicKey, chainCode, (short) 0);
short pubLen = SECP256k1.derivePublicKey(privateKey, apduBuffer, (short) 0); short pubLen = SECP256k1.derivePublicKey(privateKey, apduBuffer, chainEnd);
publicKey.setW(apduBuffer, (short) 0, pubLen); publicKey.setW(apduBuffer, chainEnd, pubLen);
} }
} }

View File

@ -399,10 +399,15 @@ public class WalletAppletTest {
response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00}); response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00});
assertEquals(0x6A80, response.getSW()); assertEquals(0x6A80, response.getSW());
// Correct example // Correct
response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x00}); response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x01});
assertEquals(0x9000, response.getSW()); assertEquals(0x9000, response.getSW());
verifyKeyDerivation(keyPair, chainCode, new int[] { 1 }); verifyKeyDerivation(keyPair, chainCode, new int[] { 1 });
// 3 level with hardned key
response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x01, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02});
assertEquals(0x9000, response.getSW());
verifyKeyDerivation(keyPair, chainCode, new int[] { 1, 0x80000000, 2});
} }
@Test @Test