fix(operation): pass operation-time params through to CipherPrimitive
createOperation was building effectiveParams from key-generation params but dropping operation-time fields (nonce, blockMode, padding, minMacLength). This caused GCM decrypt to fail with "IV must be specified in GCM mode" since the nonce from the begin call never reached CipherPrimitive. Also adds nonce field to KeyMintAttestation and handles GCM/CBC/CTR IV initialization in CipherPrimitive.
This commit is contained in:
@@ -46,6 +46,7 @@ data class KeyMintAttestation(
|
|||||||
val usageExpireDateTime: Date?,
|
val usageExpireDateTime: Date?,
|
||||||
val usageCountLimit: Int?,
|
val usageCountLimit: Int?,
|
||||||
val callerNonce: Boolean?,
|
val callerNonce: Boolean?,
|
||||||
|
val nonce: ByteArray?,
|
||||||
val unlockedDeviceRequired: Boolean?,
|
val unlockedDeviceRequired: Boolean?,
|
||||||
val includeUniqueId: Boolean?,
|
val includeUniqueId: Boolean?,
|
||||||
val rollbackResistance: Boolean?,
|
val rollbackResistance: Boolean?,
|
||||||
@@ -121,6 +122,7 @@ data class KeyMintAttestation(
|
|||||||
usageExpireDateTime = params.findDate(Tag.USAGE_EXPIRE_DATETIME),
|
usageExpireDateTime = params.findDate(Tag.USAGE_EXPIRE_DATETIME),
|
||||||
usageCountLimit = params.findInteger(Tag.USAGE_COUNT_LIMIT),
|
usageCountLimit = params.findInteger(Tag.USAGE_COUNT_LIMIT),
|
||||||
callerNonce = params.findBoolean(Tag.CALLER_NONCE),
|
callerNonce = params.findBoolean(Tag.CALLER_NONCE),
|
||||||
|
nonce = params.findBlob(Tag.NONCE),
|
||||||
unlockedDeviceRequired = params.findBoolean(Tag.UNLOCKED_DEVICE_REQUIRED),
|
unlockedDeviceRequired = params.findBoolean(Tag.UNLOCKED_DEVICE_REQUIRED),
|
||||||
includeUniqueId = params.findBoolean(Tag.INCLUDE_UNIQUE_ID),
|
includeUniqueId = params.findBoolean(Tag.INCLUDE_UNIQUE_ID),
|
||||||
rollbackResistance = params.findBoolean(Tag.ROLLBACK_RESISTANCE),
|
rollbackResistance = params.findBoolean(Tag.ROLLBACK_RESISTANCE),
|
||||||
|
|||||||
@@ -436,6 +436,7 @@ private data class LegacyKeygenParameters(
|
|||||||
usageExpireDateTime = null,
|
usageExpireDateTime = null,
|
||||||
usageCountLimit = null,
|
usageCountLimit = null,
|
||||||
callerNonce = null,
|
callerNonce = null,
|
||||||
|
nonce = null,
|
||||||
unlockedDeviceRequired = null,
|
unlockedDeviceRequired = null,
|
||||||
includeUniqueId = null,
|
includeUniqueId = null,
|
||||||
rollbackResistance = null,
|
rollbackResistance = null,
|
||||||
|
|||||||
+5
@@ -360,6 +360,10 @@ class KeyMintSecurityLevelInterceptor(
|
|||||||
keyParams.copy(
|
keyParams.copy(
|
||||||
purpose = parsedParams.purpose,
|
purpose = parsedParams.purpose,
|
||||||
digest = parsedParams.digest.ifEmpty { keyParams.digest },
|
digest = parsedParams.digest.ifEmpty { keyParams.digest },
|
||||||
|
blockMode = parsedParams.blockMode.ifEmpty { keyParams.blockMode },
|
||||||
|
padding = parsedParams.padding.ifEmpty { keyParams.padding },
|
||||||
|
nonce = parsedParams.nonce,
|
||||||
|
minMacLength = parsedParams.minMacLength ?: keyParams.minMacLength,
|
||||||
)
|
)
|
||||||
} else parsedParams
|
} else parsedParams
|
||||||
|
|
||||||
@@ -863,6 +867,7 @@ class KeyMintSecurityLevelInterceptor(
|
|||||||
usageExpireDateTime = null,
|
usageExpireDateTime = null,
|
||||||
usageCountLimit = null,
|
usageCountLimit = null,
|
||||||
callerNonce = null,
|
callerNonce = null,
|
||||||
|
nonce = null,
|
||||||
unlockedDeviceRequired = null,
|
unlockedDeviceRequired = null,
|
||||||
includeUniqueId = null,
|
includeUniqueId = null,
|
||||||
rollbackResistance = null,
|
rollbackResistance = null,
|
||||||
|
|||||||
+8
-1
@@ -137,7 +137,14 @@ private class CipherPrimitive(
|
|||||||
private val isAead = params.blockMode.firstOrNull() == BlockMode.GCM
|
private val isAead = params.blockMode.firstOrNull() == BlockMode.GCM
|
||||||
private val cipher: Cipher =
|
private val cipher: Cipher =
|
||||||
Cipher.getInstance(JcaAlgorithmMapper.mapCipherAlgorithm(params)).apply {
|
Cipher.getInstance(JcaAlgorithmMapper.mapCipherAlgorithm(params)).apply {
|
||||||
init(opMode, cryptoKey)
|
val nonce = params.nonce
|
||||||
|
if (nonce != null && isAead) {
|
||||||
|
init(opMode, cryptoKey, javax.crypto.spec.GCMParameterSpec(128, nonce))
|
||||||
|
} else if (nonce != null) {
|
||||||
|
init(opMode, cryptoKey, javax.crypto.spec.IvParameterSpec(nonce))
|
||||||
|
} else {
|
||||||
|
init(opMode, cryptoKey)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateAad(aadInput: ByteArray?) {
|
override fun updateAad(aadInput: ByteArray?) {
|
||||||
|
|||||||
Reference in New Issue
Block a user