use of android.security.keystore.KeyGenParameterSpec in project android_frameworks_base by ResurrectionRemix.
the class AndroidKeyStoreKeyGeneratorSpi method engineInit.
@Override
protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException {
resetAll();
boolean success = false;
try {
if ((params == null) || (!(params instanceof KeyGenParameterSpec))) {
throw new InvalidAlgorithmParameterException("Cannot initialize without a " + KeyGenParameterSpec.class.getName() + " parameter");
}
KeyGenParameterSpec spec = (KeyGenParameterSpec) params;
if (spec.getKeystoreAlias() == null) {
throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided");
}
mRng = random;
mSpec = spec;
mKeySizeBits = (spec.getKeySize() != -1) ? spec.getKeySize() : mDefaultKeySizeBits;
if (mKeySizeBits <= 0) {
throw new InvalidAlgorithmParameterException("Key size must be positive: " + mKeySizeBits);
} else if ((mKeySizeBits % 8) != 0) {
throw new InvalidAlgorithmParameterException("Key size must be a multiple of 8: " + mKeySizeBits);
}
try {
mKeymasterPurposes = KeyProperties.Purpose.allToKeymaster(spec.getPurposes());
mKeymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(spec.getEncryptionPaddings());
if (spec.getSignaturePaddings().length > 0) {
throw new InvalidAlgorithmParameterException("Signature paddings not supported for symmetric key algorithms");
}
mKeymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0) && (spec.isRandomizedEncryptionRequired())) {
for (int keymasterBlockMode : mKeymasterBlockModes) {
if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto(keymasterBlockMode)) {
throw new InvalidAlgorithmParameterException("Randomized encryption (IND-CPA) required but may be violated" + " by block mode: " + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + ". See " + KeyGenParameterSpec.class.getName() + " documentation.");
}
}
}
if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
// JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm
// implies SHA-256 digest). Because keymaster HMAC key is authorized only for
// one digest, we don't let algorithm parameter spec override the digest implied
// by the key. If the spec specifies digests at all, it must specify only one
// digest, the only implied by key algorithm.
mKeymasterDigests = new int[] { mKeymasterDigest };
if (spec.isDigestsSpecified()) {
// Digest(s) explicitly specified in the spec. Check that the list
// consists of exactly one digest, the one implied by key algorithm.
int[] keymasterDigestsFromSpec = KeyProperties.Digest.allToKeymaster(spec.getDigests());
if ((keymasterDigestsFromSpec.length != 1) || (keymasterDigestsFromSpec[0] != mKeymasterDigest)) {
throw new InvalidAlgorithmParameterException("Unsupported digests specification: " + Arrays.asList(spec.getDigests()) + ". Only " + KeyProperties.Digest.fromKeymaster(mKeymasterDigest) + " supported for this HMAC key algorithm");
}
}
} else {
// Key algorithm does not imply a digest.
if (spec.isDigestsSpecified()) {
mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests());
} else {
mKeymasterDigests = EmptyArray.INT;
}
}
// Check that user authentication related parameters are acceptable. This method
// will throw an IllegalStateException if there are issues (e.g., secure lock screen
// not set up).
KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds(), spec.isUserAuthenticationValidWhileOnBody(), spec.isInvalidatedByBiometricEnrollment());
} catch (IllegalStateException | IllegalArgumentException e) {
throw new InvalidAlgorithmParameterException(e);
}
success = true;
} finally {
if (!success) {
resetAll();
}
}
}
Aggregations