Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,5 @@ bin/*
vendor_libs/*
/.apt_generated/
tools/format.bat
/tools/sdk/jdk-11.0.2
/output
/tools/sdk/jdk-*
/output
2 changes: 1 addition & 1 deletion build/build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ REM These values must be defined correctly
REM *********************************************************************

set ANT_HOME=..\tools\ant
set JAVA_HOME=..\tools\sdk\jdk-11.0.2
set JAVA_HOME=..\tools\sdk\jdk-11.0.30

IF NOT EXIST %JAVA_HOME% (
ECHO The JDK path %JAVA_HOME% does not exist, aborting.
Expand Down
25 changes: 24 additions & 1 deletion build/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,30 @@
</javacard>
</target>

<target name="all" depends="jc305-release,jc305-debug">
<target name="jc304-release">
<property name="platform" value="jc304"/>
<javacard jckit="tools/sdk/jcdk-3.0.4">
<cap targetsdk="tools/sdk/jcdk-3.0.4" sources="src;src-platform/jc304" debug="false" ints="true" aid="A0000003084F46323031" version="${version}"
output="${outputPath}/bin-release/%n-v${version}-jc%j-%J.cap">
<applet class="org.openfips201.applet.OpenFIPS201" aid="A000000308000010000100"/>
<import jar="tools/sdk/org.globalplatform-1.6/gpapi-globalplatform.jar"/>
</cap>
</javacard>
</target>


<target name="jc304-debug">
<property name="platform" value="jc304"/>
<javacard jckit="tools/sdk/jcdk-3.0.4">
<cap targetsdk="tools/sdk/jcdk-3.0.4" sources="src;src-platform/jc304" debug="true" ints="true" aid="A0000003084F46323031" version="${version}"
output="${outputPath}/bin-debug/%n-v${version}-jc%j-%J.cap">
<applet class="org.openfips201.applet.OpenFIPS201" aid="A000000308000010000100"/>
<import jar="tools/sdk/org.globalplatform-1.6/gpapi-globalplatform.jar"/>
</cap>
</javacard>
</target>

<target name="all" depends="jc305-release,jc305-debug,jc304-release,jc304-debug">
<tstamp/>
</target>

Expand Down
3 changes: 2 additions & 1 deletion doc/asn1/OpenFIPS201-PUT-DATA.asn
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ PutDataRequest ::= CHOICE {
secureRequest [APPLICATION 31] NULL
}

PutDataBulkRequest ::= [APPLICATION 10] SEQUENCE OF PutDataRequest
-- Moved from [APPLICATION 10] to avoid coliding with PutDataRequest.deletePinRequest
PutDataBulkRequest ::= [APPLICATION 30] SEQUENCE OF PutDataRequest

PutDataCreateObjectRequest ::= SEQUENCE {
id [11] OCTET STRING (SIZE(1..3)),
Expand Down
196 changes: 98 additions & 98 deletions src-platform/jc304/org/openfips201/applet/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import javacard.security.RandomData;
import javacard.security.SecretKey;
import javacard.security.Signature;
import javacard.security.CryptoException;
import javacardx.crypto.Cipher;

/*
Expand Down Expand Up @@ -187,95 +188,19 @@ static class Cryptography {
private static MessageDigest cspSHA384;
private static RandomData cspRandom;

private Cryptography() {
}
// Basic support bitmap per mechanism ID
private static short mechanismSupport = (short) 0xffff;

private static void init() {

try {
if (cspAES == null) {
cspAES = Cipher.getInstance(Cipher.CIPHER_AES_ECB, false);
}
} catch (Exception ex) {
// Just fall-through if it isn't supported
cspAES = null;
}
// Keygen support bitmap per mechanism ID
private static short generateSupport = (short) 0xffff;

try {
if (cspTDEA == null) {
cspTDEA = Cipher.getInstance(Cipher.CIPHER_DES_ECB, false);
}
} catch (Exception ex) {
// Just fall-through if it isn't supported
cspTDEA = null;
}

try {
if (cspRSA == null) {
cspRSA = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false);
}
} catch (Exception ex) {
// Just fall-through if it isn't supported
cspRSA = null;
}

try {
if (cspECDSA == null) {
cspECDSA = Signature.getInstance(Signature.SIG_CIPHER_ECDSA, false);
}
} catch (Exception ex) {
// Just fall-through if it isn't supported
cspECDSA = null;
}

try {
if (cspCMAC == null) {
cspCMAC = null;
}
} catch (Exception ex) {
// Just fall-through if it isn't supported
cspCMAC = null;
}

try {
if (cspECDH == null) {
cspECDH = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH_PLAIN, false);
}
} catch (Exception ex) {
// Just fall-through if it isn't supported
cspECDH = null;
}

try {
if (cspSHA256 == null) {
cspSHA256 = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false);
}
} catch (Exception ex) {
// Just fall-through if it isn't supported
cspSHA256 = null;
}

try {
if (cspSHA384 == null) {
cspSHA384 = MessageDigest.getInstance(MessageDigest.ALG_SHA_384, false);
}
} catch (Exception ex) {
// Just fall-through if it isn't supported
cspSHA384 = null;
}

try {
if (cspRandom == null) {
cspRandom = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
}
} catch (Exception ex) {
// Just fall-through if it isn't supported
cspRandom = null;
}
private Cryptography() {
}

static void init() {
}

private static void terminate() {
static void terminate() {
cspAES = null;
cspTDEA = null;
cspRSA = null;
Expand All @@ -286,35 +211,87 @@ private static void terminate() {
requestObjectDeletion();
}

private static short mechanismBit(byte mechanism) {
switch (mechanism) {
case Constants.ID_ALG_DEFAULT:
case Constants.ID_ALG_TDEA_3KEY:
return (short) 0x0001;
case Constants.ID_ALG_AES_128:
return (short) 0x0002;
case Constants.ID_ALG_AES_192:
return (short) 0x0004;
case Constants.ID_ALG_AES_256:
return (short) 0x0008;
case Constants.ID_ALG_RSA_1024:
return (short) 0x0010;
case Constants.ID_ALG_RSA_2048:
return (short) 0x0020;
case Constants.ID_ALG_RSA_3072:
return (short) 0x0040;
case Constants.ID_ALG_RSA_4096:
return (short) 0x0080;
case Constants.ID_ALG_ECC_P256:
case Constants.ID_ALG_ECC_CS2:
return (short) 0x0100;
case Constants.ID_ALG_ECC_P384:
case Constants.ID_ALG_ECC_CS7:
return (short) 0x0200;
default:
return (short) 0x0000;
}
}

private static void setUnsupported(byte mechanism) {
mechanismSupport &= (short) ~mechanismBit(mechanism);
}

private static void setGenerateUnsupported(byte mechanism) {
generateSupport &= (short) ~mechanismBit(mechanism);
}

static boolean supportsGenerate(byte mechanism) {
return supportsMechanism(mechanism) && (generateSupport & mechanismBit(mechanism)) != (short) 0;
}

// Ensures mechanism is flagged unsupported when encountering a NO_SUCH_ALGORITHM CryptoException.
static void onCryptoException(byte mechanism, CryptoException ex) {
if (ex.getReason() == CryptoException.NO_SUCH_ALGORITHM) {
setUnsupported(mechanism);
ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
}
throw ex;
}

// As per onCryptoException, but flagging keygen support.
static void onGenerateException(byte mechanism, CryptoException ex) {
if (ex.getReason() == CryptoException.NO_SUCH_ALGORITHM) {
setGenerateUnsupported(mechanism);
ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
}
throw ex;
}

static boolean supportsMechanism(byte mechanism) {

switch (mechanism) {

// Supported Algorithms
case Constants.ID_ALG_DEFAULT:
case Constants.ID_ALG_TDEA_3KEY:
// FIPS: Disabled in Approved mode
return (!Config.FIPS_APPROVED_MODE && cspTDEA != null);
case Constants.ID_ALG_RSA_1024:
return !Config.FIPS_APPROVED_MODE && (mechanismSupport & mechanismBit(mechanism)) != (short) 0;

case Constants.ID_ALG_AES_128:
case Constants.ID_ALG_AES_192:
case Constants.ID_ALG_AES_256:
return (cspAES != null);

case Constants.ID_ALG_RSA_1024:
// FIPS: Disabled in Approved mode
return (!Config.FIPS_APPROVED_MODE && cspRSA != null);

case Constants.ID_ALG_RSA_2048:
case Constants.ID_ALG_RSA_3072:
case Constants.ID_ALG_RSA_4096:
return (cspRSA != null);

case Constants.ID_ALG_ECC_P256:
case Constants.ID_ALG_ECC_P384:
case Constants.ID_ALG_ECC_CS2:
case Constants.ID_ALG_ECC_CS7:
return (cspECDSA != null && cspECDH != null);
return (mechanismSupport & mechanismBit(mechanism)) != (short) 0;

default:
return false;
Expand All @@ -324,10 +301,16 @@ static boolean supportsMechanism(byte mechanism) {
static MessageDigest getMessageDigest(byte algorithm) {
switch (algorithm) {
case MessageDigest.ALG_SHA_256:
if (cspSHA256 == null) {
cspSHA256 = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false);
}
cspSHA256.reset();
return cspSHA256;
case MessageDigest.ALG_SHA_384:
cspSHA256.reset();
if (cspSHA384 == null) {
cspSHA384 = MessageDigest.getInstance(MessageDigest.ALG_SHA_384, false);
}
cspSHA384.reset();
return cspSHA384;
default:
ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
Expand Down Expand Up @@ -385,7 +368,7 @@ static Key buildKey(byte algorithm, short length) {
ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
}

return null;
return (Key) key;

default:
return null;
Expand Down Expand Up @@ -431,12 +414,18 @@ static short encipher(SecretKey secretKey, byte[] inBuffer, short inOffset, shor
case KeyBuilder.TYPE_DES:
case KeyBuilder.TYPE_DES_TRANSIENT_DESELECT:
case KeyBuilder.TYPE_DES_TRANSIENT_RESET:
if (cspTDEA == null) {
cspTDEA = Cipher.getInstance(Cipher.CIPHER_DES_ECB, false);
}
cipher = cspTDEA;
break;

case KeyBuilder.TYPE_AES:
case KeyBuilder.TYPE_AES_TRANSIENT_DESELECT:
case KeyBuilder.TYPE_AES_TRANSIENT_RESET:
if (cspAES == null) {
cspAES = Cipher.getInstance(Cipher.CIPHER_AES_ECB, false);
}
cipher = cspAES;
break;

Expand Down Expand Up @@ -513,6 +502,9 @@ static short sign(ECPrivateKey privateKey, byte[] inBuffer, short inOffset, shor
return (short) 0; // Keep compiler happy
}

if (cspECDSA == null) {
cspECDSA = Signature.getInstance(Signature.SIG_CIPHER_ECDSA, false);
}
cspECDSA.init(privateKey, Signature.MODE_SIGN);
return cspECDSA.signPreComputedHash(inBuffer, inOffset, inLength, outBuffer, outOffset);
}
Expand Down Expand Up @@ -550,6 +542,9 @@ static short computeRSADP1(PrivateKey privateKey, byte[] inBuffer, short inOffse
// with the only remaining option, which is to perform a private key decryption
// operation, which makes us feel awkward and wrong.
//
if (cspRSA == null) {
cspRSA = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false);
}
cspRSA.init(privateKey, Cipher.MODE_DECRYPT);
return cspRSA.doFinal(inBuffer, inOffset, inLength, outBuffer, outOffset);
}
Expand All @@ -570,7 +565,9 @@ static short computeECDH(ECPrivateKey privateKey, byte[] inBuffer, short inOffse

// NOTE: The Java Card implementation of generateSecret() performs sufficient buffer state and
// length checking that we don't double-up here.

if (cspECDH == null) {
cspECDH = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH_PLAIN, false);
}
cspECDH.init(privateKey);
return cspECDH.generateSecret(inBuffer, inOffset, inLength, outBuffer, outOffset);
}
Expand All @@ -589,6 +586,9 @@ static short generateRandom(byte[] buffer, short offset, short length) {
buffer[(short) (offset + i)] = (byte) (i % 256);
}
} else {
if (cspRandom == null) {
cspRandom = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
}
cspRandom.generateData(buffer, offset, length);
}

Expand Down
Loading