19
19
import com .android .javacard .seprovider .KMAttestationCert ;
20
20
import com .android .javacard .seprovider .KMDeviceUniqueKeyPair ;
21
21
import com .android .javacard .seprovider .KMException ;
22
- import com .android .javacard .seprovider .KMHmacKey ;
23
22
import com .android .javacard .seprovider .KMSEProvider ;
24
23
import javacard .framework .APDU ;
25
24
import javacard .framework .Applet ;
29
28
import javacard .framework .JCSystem ;
30
29
import javacard .framework .Util ;
31
30
import javacard .security .CryptoException ;
32
- import javacard .security .HMACKey ;
33
- import javacard .security .KeyBuilder ;
34
31
import javacardx .apdu .ExtendedLength ;
35
32
36
33
/**
@@ -227,6 +224,10 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe
227
224
// Key type constants
228
225
public static final byte SYM_KEY_TYPE = 0 ;
229
226
public static final byte ASYM_KEY_TYPE = 1 ;
227
+ // SHA-256 Digest length in bits
228
+ public static final short SHA256_DIGEST_LEN_BITS = 256 ;
229
+ // Minimum HMAC length in bits
230
+ public static final short MIN_HMAC_LENGTH_BITS = 64 ;
230
231
231
232
protected static RemotelyProvisionedComponentDevice rkp ;
232
233
protected static KMEncoder encoder ;
@@ -983,7 +984,7 @@ private boolean isKeyUpgradeRequired(short keyBlob, short appId, short appData,
983
984
KMException .throwIt (KMError .INVALID_ARGUMENT );
984
985
}
985
986
} else {
986
- KMException .throwIt (KMError .UNKNOWN_ERROR );
987
+ KMException .throwIt (KMError .UNKNOWN_ERROR );
987
988
}
988
989
index += 4 ;
989
990
}
@@ -1728,8 +1729,7 @@ private void finishSigningVerifyingOperation(KMOperationState op, byte[] scratch
1728
1729
// the truncated signature back to the caller. At the time of verfication
1729
1730
// we again compute the signature of the plain text input, truncate it to
1730
1731
// TAG_MAC_LENGTH and compare it with the input signature for
1731
- // verification. So this is the reason we are using KMType.SIGN directly
1732
- // instead of using op.getPurpose().
1732
+ // verification.
1733
1733
op .getOperation ()
1734
1734
.sign (
1735
1735
KMByteBlob .cast (data [INPUT_DATA ]).getBuffer (),
@@ -1741,10 +1741,18 @@ private void finishSigningVerifyingOperation(KMOperationState op, byte[] scratch
1741
1741
// Copy only signature of mac length size.
1742
1742
data [OUTPUT_DATA ] =
1743
1743
KMByteBlob .instance (scratchPad , (short ) 0 , (short ) (op .getMacLength () / 8 ));
1744
- }else if (op .getPurpose () == KMType .VERIFY ) {
1744
+ } else if (op .getPurpose () == KMType .VERIFY ) {
1745
+ if ((KMByteBlob .cast (data [SIGNATURE ]).length () < (MIN_HMAC_LENGTH_BITS / 8 )) ||
1746
+ KMByteBlob .cast (data [SIGNATURE ]).length () > (SHA256_DIGEST_LEN_BITS / 8 )) {
1747
+ KMException .throwIt (KMError .UNSUPPORTED_MAC_LENGTH );
1748
+ }
1749
+ if ((KMByteBlob .cast (data [SIGNATURE ]).length () < (short )(op .getMinMacLength () / 8 ))) {
1750
+ KMException .throwIt (KMError .INVALID_MAC_LENGTH );
1751
+ }
1752
+
1745
1753
if (0
1746
1754
!= Util .arrayCompare (
1747
- scratchPad , (short )0 ,
1755
+ scratchPad , (short ) 0 ,
1748
1756
KMByteBlob .cast (data [SIGNATURE ]).getBuffer (),
1749
1757
KMByteBlob .cast (data [SIGNATURE ]).getStartOff (),
1750
1758
KMByteBlob .cast (data [SIGNATURE ]).length ())) {
@@ -2167,14 +2175,17 @@ private void processBeginOperationCmd(APDU apdu) {
2167
2175
} else {
2168
2176
iv = KMArray .instance ((short ) 0 );
2169
2177
}
2170
-
2178
+ short macLen = 0 ;
2179
+ if (op .getMacLength () != KMType .INVALID_VALUE ) {
2180
+ macLen = (short ) (op .getMacLength ()/8 ) ;
2181
+ }
2171
2182
short params = KMKeyParameters .instance (iv );
2172
2183
short resp = KMArray .instance ((short ) 5 );
2173
2184
KMArray .cast (resp ).add ((short ) 0 , KMInteger .uint_16 (KMError .OK ));
2174
2185
KMArray .cast (resp ).add ((short ) 1 , params );
2175
2186
KMArray .cast (resp ).add ((short ) 2 , data [OP_HANDLE ]);
2176
2187
KMArray .cast (resp ).add ((short ) 3 , KMInteger .uint_8 (op .getBufferingMode ()));
2177
- KMArray .cast (resp ).add ((short ) 4 , KMInteger .uint_16 (( short ) ( op . getMacLength () / 8 ) ));
2188
+ KMArray .cast (resp ).add ((short ) 4 , KMInteger .uint_16 (macLen ));
2178
2189
sendOutgoing (apdu , resp );
2179
2190
}
2180
2191
@@ -2404,6 +2415,9 @@ private void authorizeBlockModeAndMacLength(KMOperationState op) {
2404
2415
}
2405
2416
break ;
2406
2417
case KMType .HMAC :
2418
+ short minMacLen = KMIntegerTag .getShortValue (KMType .UINT_TAG , KMType .MIN_MAC_LENGTH ,
2419
+ data [HW_PARAMETERS ]);
2420
+ op .setMinMacLength (minMacLen );
2407
2421
if (macLen == KMType .INVALID_VALUE ) {
2408
2422
if (op .getPurpose () == KMType .SIGN ) {
2409
2423
KMException .throwIt (KMError .MISSING_MAC_LENGTH );
@@ -2413,12 +2427,13 @@ private void authorizeBlockModeAndMacLength(KMOperationState op) {
2413
2427
if (op .getPurpose () == KMType .VERIFY ) {
2414
2428
KMException .throwIt (KMError .INVALID_ARGUMENT );
2415
2429
}
2416
- if (macLen
2417
- < KMIntegerTag .getShortValue (
2418
- KMType .UINT_TAG , KMType .MIN_MAC_LENGTH , data [HW_PARAMETERS ])) {
2430
+ if (macLen % 8 != 0 ||
2431
+ macLen > SHA256_DIGEST_LEN_BITS ||
2432
+ macLen < MIN_HMAC_LENGTH_BITS ) {
2433
+ KMException .throwIt (KMError .UNSUPPORTED_MAC_LENGTH );
2434
+ }
2435
+ if (macLen < minMacLen ) {
2419
2436
KMException .throwIt (KMError .INVALID_MAC_LENGTH );
2420
- } else if (macLen % 8 != 0 || macLen > 256 ) {
2421
- KMException .throwIt (KMError .UNSUPPORTED_MAC_LENGTH );
2422
2437
}
2423
2438
op .setMacLength (macLen );
2424
2439
}
@@ -3720,8 +3735,8 @@ private static void validateHmacKey() {
3720
3735
KMIntegerTag .getShortValue (KMType .UINT_TAG , KMType .MIN_MAC_LENGTH , data [KEY_PARAMETERS ]);
3721
3736
3722
3737
if (((short ) (minMacLength % 8 ) != 0 )
3723
- || minMacLength < ( short ) 64
3724
- || minMacLength > ( short ) 256 ) {
3738
+ || minMacLength < MIN_HMAC_LENGTH_BITS
3739
+ || minMacLength > SHA256_DIGEST_LEN_BITS ) {
3725
3740
KMException .throwIt (KMError .UNSUPPORTED_MIN_MAC_LENGTH );
3726
3741
}
3727
3742
// Read Keysize
0 commit comments