-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Task specification
The External Encryption Key (EEK) is a feature that allows protecting factor keys used for authentication code calculation with an additional, externally provided encryption key.
The goal of this task is to carefully discontinue this feature. Since we still have clients using it, we must ensure that existing activations continue to work.
Specifically, the task is to add logic to the V3 core classes to disable EEK with minimal effort required from application developers.
API changes
There following changes are proposed to PowerAuthSDK methods:
-
Do not allow set EEK in configuration.
-
hasExternalEncryptionKey- If activation is already at protocol V4, then returns always false.
- If activation is at protocol V3.3 then returns information that EEK is present in the persistent data.
-
setExternalEncryptionKey()- Remove method
-
addExternalEncryptionKey()- Remove method
-
removeExternalEncryptionKey(eek: PowerAuthCoreData)- If activation is V3 and requires EEK (e.g. appropriate flag is set in persistent data), then remove EEK (see algorithm below)
- Otherwise throws error
- API of this method is changed (1.9.x doesn't have eek parameter)
Internal checks
- If V3 authentication code is being calculated and EEK is still active, then throw Exception
Application changes
Application should use the following code to remove EEK:
if sdk.hasExternalEncryptionKey {
sdk.removeExternalEncryptionKey(eek: oldEEK)
}How to remove EEK
void RemoveEEK(const ByteRange& eek, SessionData& sd)
{
auto &pd = sd.persistentData().v3;
if (!pd.flags.usesExternalKey) { throw Exception(EC_NotAllowed); }
const auto& uke = algorithms().v3.uke();
// unwrap keys
auto knowledge = uke.unwrap(eek, pd.cKnowledgeKey);
auto biometry = pd.cBiometryKey.empty() ? ByteArray() : uke.unwrap(eek, pd.cBiometryKey);
// change PD
pd.cKnowledgeKey = knowledge;
pd.cBiometryKey = biometry;
pd.flags.usesExternalKey = 0;
}The algorithm above should be equal to implementation from 1.9.x. For the reference:
bool ProtectSignatureKeysWithEEK(SignatureKeys & secret, const cc7::ByteRange & eek, bool protect)
{
if (secret.usesExternalKey == protect) {
// Internal error. The PD has probably different value than SK structure.
CC7_ASSERT(false, "PD flag for EEK usage is different than in SK structure");
return false;
}
cc7::ByteArray c_knowledge_key;
cc7::ByteArray c_biometry_key;
if (protect) {
c_knowledge_key = crypto::AES_CBC_Encrypt(eek, ZERO_IV, secret.knowledgeKey);
} else {
c_knowledge_key = crypto::AES_CBC_Decrypt(eek, ZERO_IV, secret.knowledgeKey);
}
if (c_knowledge_key.size() != SIGNATURE_KEY_SIZE) {
return false;
}
if (!secret.biometryKey.empty()) {
if (protect) {
c_biometry_key = crypto::AES_CBC_Encrypt(eek, ZERO_IV, secret.biometryKey);
} else {
c_biometry_key = crypto::AES_CBC_Decrypt(eek, ZERO_IV, secret.biometryKey);
}
if (c_biometry_key.size() != SIGNATURE_KEY_SIZE) {
return false;
}
secret.biometryKey = c_biometry_key;
}
secret.knowledgeKey = c_knowledge_key;
secret.usesExternalKey = protect;
return true;
}If protect == false then EEK is removed.
How to test
This feature is difficult to test without a functionality provided in low level C++ code. We should add a function to PowerAuthCoreSession (or appropriate android's class), available only in DEBUG build, that allows add EEK to the existing V3 activation. The functionality should not be exposed to high level PowerAuthSDK class.