This is a collection of JavaCardOS applets for Specter-DIY secrets storage.
Documentation for classes and applets is in the docs/
folder.
Currently all the applets are tested on NXP JCOP3 J3H145 card, but we plan to add support of Infineon SLE78
and G&D SmartCafe 7.0
soon.
Teapot
— a very simple "Hello world" class that doesn't use any PIN protection or secure communication. It can only store up to255
bytes of data and give it back on request. Perfect for testing communication with the card.SecureApplet
— base class with PIN protection and secure communication.MemoryCard
— extendsSecureApplet
, allows arbitrary data storage.BlindOracle
— extendsSecureApplet
, stores root xprv and supports bip32 key derivation and signing.SingleUseKey
— extendsSecureApplet
, generates a temporary key on the card that can be used only once to sign a single hash. After that the key is deleted. Can be used for proposals like Bob's and Bryan's presigned transactions stuff.
JDK8 works. The most recent one doesn't.
Big thanks to https://adoptopenjdk.net/ for all old versions of jdk!
Install deps:
brew tap adoptopenjdk/openjdk
brew install --cask adoptopenjdk/openjdk/adoptopenjdk8
brew install [email protected]
Add to your path (maybe put into .bash_profile
):
export PATH="/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/bin/:$PATH"
export PATH="/usr/local/opt/[email protected]/bin:$PATH"
export JAVA_HOME="/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home"
sudo apt install openjdk-8-jdk
sudo apt install ant
Install the smartcard service:
sudo apt install pcscd
gp.jar
- a working and easy to use tool for applets management, by martinpaljak (LGPL3)ant-javacard.jar
- ant task to build javacard applet, by martinpaljak (MIT)sdks
folder - submodule with JavaCard SDKs of different versions (Oracle-owns-you-and-your-grandma license)
It's convenient to make an alias for gp.jar
:
alias gp="java -jar $PWD/gp.jar"
Make sure to clone recursively or run git submodule update --init --recursive
if you have an error "No usable JavaCard SDK referenced"
Run to compile all applets:
ant all
You should get .cap
files for all the applets in the build/cap
folder.
Run to compile a specific applet:
ant MemoryCard
To see the build targets:
ant -projecthelp
Now upload applet to the card:
gp --install build/cap/MemoryCardApplet.cap
Check that it appeared in the list of applets (should appear with aid B00B5111CB01
):
gp -l
Now you can communicate with the applet.
Check out tests folder to get an idea how to communicate with the card.
A simple way to run simulator with a particular applet (MemoryCard for example):
python3 run_sim.py MemoryCard
It will spawn the simulator on port 21111
and restart it on every disconnect.
To run BlindOracle
on port 21111
with AID B00B5111CE01
directly with simulator.jar
:
java -jar "simulator.jar" -p 21111 -a "B00B5111CE01" -c "toys.BlindOracleApplet" -u "file://$PWD/build/classes/BlindOracle/"
- https://github.com/OpenCryptoProject/JCMathLib - library for arbitrary elliptic curve operations on javacard
- https://opencryptojc.org/ - making JavaCards open
- https://pyscard.sourceforge.io/ - python tool to talk to smartcards
- https://smartcard-atr.apdu.fr/ - ATR (Answer To Reset) parser
- keycard.tech - JavaCard applet with BIP-32 support
- https://www.youtube.com/watch?v=vd0-Uhx2OoQ - nice talk about JavaCards and open-source ecosystem
Compatibility table: https://www.fi.muni.cz/~xsvenda/jcalgtest/table.html
ALG_EC_SVDP_DH_PLAIN
should be there. Many cards support it. Not necessarily ALG_EC_SVDP_DH_PLAIN_XY
. Required for point multiplication (other than G, i.e. for Schnorr)
ALG_EC_PACE_GM
is a nice one - allows point addition. AFAIK available only on NXP JCOP3 J3H145 and NXP JCOP4 series.
TYPE_EC_FP_PRIVATE_TRANSIENT
- useful for bip32 derivation.
Available on:
- Infineon SLE78 JCard
- G&D Smartcafe 7.0
- NXP JCOP4 P71D321
- NXP JCOP4 J3R200
- Taisys SIMoME Vault
ALG_HMAC_SHA512
- useful for fast PBKDF2 in BIP-39. Available only on Taisys SIMoME Vault
But sometimes we have to... Here we have modulo addition for bip32 key derivation, this one is critical. For public key uncompression we can use fast functions as no secrets are involved there.
For finite field ariphmetics we are abusing RSA
encryption coprocessor where we set modulo to FP
or N
of secp256k1
curve and public key to the exponent we need.
Point addition is implemented using ALG_EC_PACE_GM
, but can be also done manually with a few simple equations over FP
.
- No branching -
if/switch
statements can leak information through side channels - Don't do case-via-offset - access time to elements with different indexes can be different
- Use transient arrays when possible - it's orders of magnitude faster than EEPROM
- Use
Key
class when possible, JC platforms secures them better than simple arrays - Encrypt-then-hmac is the right way to build the secure communiaction channel
- Use ephimerial keys or random nonces when possible, they help against replay attacks