From c4b0da3703a28dd4a4aeecaf7a14ec835ac8bcfb Mon Sep 17 00:00:00 2001 From: Michele Balistreri Date: Wed, 18 Oct 2017 15:51:03 +0300 Subject: [PATCH] fix DERIVE KEY --- src/main/java/im/status/wallet/Crypto.java | 8 ++++---- src/main/java/im/status/wallet/WalletApplet.java | 9 +++++---- src/test/java/im/status/wallet/WalletAppletTest.java | 9 +++++++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/java/im/status/wallet/Crypto.java b/src/main/java/im/status/wallet/Crypto.java index 059648a..9ee0b1b 100644 --- a/src/main/java/im/status/wallet/Crypto.java +++ b/src/main/java/im/status/wallet/Crypto.java @@ -34,6 +34,7 @@ public class Crypto { hmacSHA512 = Signature.getInstance(Signature.ALG_HMAC_SHA_512, false); hmacKey = (HMACKey) KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC_TRANSIENT_DESELECT, KEY_SECRET_SIZE, false); } catch (CryptoException e) { + hmacSHA512 = null; sha512 = MessageDigest.getInstance(MessageDigest.ALG_SHA_512, false); blockSize = HMAC_BLOCK_SIZE; } @@ -49,7 +50,7 @@ public class Crypto { off += privateKey.getS(tmp, off); } else { 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); } @@ -63,7 +64,7 @@ public class Crypto { 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)) { 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) { - short outI = 0; 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 ; outI = (short)(outI >> 8); } diff --git a/src/main/java/im/status/wallet/WalletApplet.java b/src/main/java/im/status/wallet/WalletApplet.java index 1fef6cc..227da5a 100644 --- a/src/main/java/im/status/wallet/WalletApplet.java +++ b/src/main/java/im/status/wallet/WalletApplet.java @@ -357,12 +357,13 @@ public class WalletApplet extends Applet { 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); - short pubLen = SECP256k1.derivePublicKey(privateKey, apduBuffer, (short) 0); - publicKey.setW(apduBuffer, (short) 0, pubLen); + short pubLen = SECP256k1.derivePublicKey(privateKey, apduBuffer, chainEnd); + publicKey.setW(apduBuffer, chainEnd, pubLen); } } diff --git a/src/test/java/im/status/wallet/WalletAppletTest.java b/src/test/java/im/status/wallet/WalletAppletTest.java index e23b136..4dd0766 100644 --- a/src/test/java/im/status/wallet/WalletAppletTest.java +++ b/src/test/java/im/status/wallet/WalletAppletTest.java @@ -399,10 +399,15 @@ public class WalletAppletTest { response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00}); assertEquals(0x6A80, response.getSW()); - // Correct example - response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x00}); + // Correct + response = cmdSet.deriveKey(new byte[] {0x00, 0x00, 0x00, 0x01}); assertEquals(0x9000, response.getSW()); 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