Handle "hidden" authorization tags correctly.
Change-Id: I9fa18f8ab465a2faa0f358e12f72daf18ca02fe7
diff --git a/google_keymaster.cpp b/google_keymaster.cpp
index 4b49d79..8723cb1 100644
--- a/google_keymaster.cpp
+++ b/google_keymaster.cpp
@@ -32,34 +32,46 @@
namespace keymaster {
-GoogleKeymaster::GoogleKeymaster() {}
-GoogleKeymaster::~GoogleKeymaster() {}
+GoogleKeymaster::GoogleKeymaster() {
+}
+GoogleKeymaster::~GoogleKeymaster() {
+}
const int RSA_DEFAULT_KEY_SIZE = 2048;
const int RSA_DEFAULT_EXPONENT = 65537;
struct BIGNUM_Delete {
- void operator()(BIGNUM* p) const { BN_free(p); }
+ void operator()(BIGNUM* p) const {
+ BN_free(p);
+ }
};
typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
struct RSA_Delete {
- void operator()(RSA* p) const { RSA_free(p); }
+ void operator()(RSA* p) const {
+ RSA_free(p);
+ }
};
typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
struct EVP_PKEY_Delete {
- void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); }
+ void operator()(EVP_PKEY* p) const {
+ EVP_PKEY_free(p);
+ }
};
typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
struct AE_CTX_Delete {
- void operator()(ae_ctx* ctx) const { ae_free(ctx); }
+ void operator()(ae_ctx* ctx) const {
+ ae_free(ctx);
+ }
};
typedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx;
struct ByteArray_Delete {
- void operator()(void* p) const { delete[] reinterpret_cast<uint8_t*>(p); }
+ void operator()(void* p) const {
+ delete[] reinterpret_cast<uint8_t*>(p);
+ }
};
/**
@@ -187,7 +199,8 @@
return;
response->error = KM_ERROR_OK;
- if (!CopyAuthorizations(request.key_description, response))
+ AuthorizationSet hidden_auths;
+ if (!CopyAuthorizations(request.key_description, response, &hidden_auths))
return;
keymaster_algorithm_t algorithm;
@@ -197,7 +210,7 @@
}
switch (algorithm) {
case KM_ALGORITHM_RSA:
- if (!GenerateRsa(request.key_description, response))
+ if (!GenerateRsa(request.key_description, response, &hidden_auths))
return;
break;
default:
@@ -206,45 +219,16 @@
}
}
-bool GoogleKeymaster::CreateKeyBlob(GenerateKeyResponse* response, uint8_t* key_bytes,
- size_t key_length) {
- uint8_t nonce[KeyBlob::NONCE_LENGTH];
- GenerateNonce(nonce, array_size(nonce));
-
- keymaster_key_blob_t key_data = {key_bytes, key_length};
- UniquePtr<KeyBlob> blob(
- new KeyBlob(response->enforced, response->unenforced, key_data, MasterKey(), nonce));
- if (blob.get() == NULL) {
- response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
- return false;
- }
-
- if (blob->error() != KM_ERROR_OK) {
- return blob->error();
- return false;
- }
-
- size_t size = blob->SerializedSize();
- UniquePtr<uint8_t[]> blob_bytes(new uint8_t[size]);
- if (blob_bytes.get() == NULL) {
- response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
- return false;
- }
- blob->Serialize(blob_bytes.get(), blob_bytes.get() + size);
- response->key_blob.key_material_size = size;
- response->key_blob.key_material = blob_bytes.release();
- return true;
-}
-
-bool GoogleKeymaster::GenerateRsa(const AuthorizationSet& key_auths,
- GenerateKeyResponse* response) {
+bool GoogleKeymaster::GenerateRsa(const AuthorizationSet& key_auths, GenerateKeyResponse* response,
+ AuthorizationSet* hidden_auths) {
uint64_t public_exponent = RSA_DEFAULT_EXPONENT;
if (!key_auths.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent))
- AddAuthorization(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent), response);
+ AddAuthorization(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent), response,
+ hidden_auths);
uint32_t key_size = RSA_DEFAULT_KEY_SIZE;
if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
- AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
+ AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response, hidden_auths);
Unique_BIGNUM exponent(BN_new());
Unique_RSA rsa_key(RSA_new());
@@ -281,7 +265,38 @@
uint8_t* tmp = der_data.get();
i2d_PrivateKey(pkey.get(), &tmp);
- return CreateKeyBlob(response, der_data.get(), der_length);
+ return CreateKeyBlob(response, *hidden_auths, der_data.get(), der_length);
+}
+
+bool GoogleKeymaster::CreateKeyBlob(GenerateKeyResponse* response,
+ const AuthorizationSet& hidden_auths, uint8_t* key_bytes,
+ size_t key_length) {
+ uint8_t nonce[KeyBlob::NONCE_LENGTH];
+ GenerateNonce(nonce, array_size(nonce));
+
+ keymaster_key_blob_t key_data = {key_bytes, key_length};
+ UniquePtr<KeyBlob> blob(new KeyBlob(response->enforced, response->unenforced, hidden_auths,
+ key_data, MasterKey(), nonce));
+ if (blob.get() == NULL) {
+ response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ return false;
+ }
+
+ if (blob->error() != KM_ERROR_OK) {
+ return blob->error();
+ return false;
+ }
+
+ size_t size = blob->SerializedSize();
+ UniquePtr<uint8_t[]> blob_bytes(new uint8_t[size]);
+ if (blob_bytes.get() == NULL) {
+ response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ return false;
+ }
+ blob->Serialize(blob_bytes.get(), blob_bytes.get() + size);
+ response->key_blob.key_material_size = size;
+ response->key_blob.key_material = blob_bytes.release();
+ return true;
}
static keymaster_error_t CheckAuthorizationSet(const AuthorizationSet& set) {
@@ -297,7 +312,8 @@
}
bool GoogleKeymaster::CopyAuthorizations(const AuthorizationSet& key_description,
- GenerateKeyResponse* response) {
+ GenerateKeyResponse* response,
+ AuthorizationSet* hidden_auths) {
for (size_t i = 0; i < key_description.size(); ++i) {
switch (key_description[i].tag) {
case KM_TAG_ROOT_OF_TRUST:
@@ -309,14 +325,15 @@
response->error = KM_ERROR_UNSUPPORTED_TAG;
return false;
default:
- AddAuthorization(key_description[i], response);
+ AddAuthorization(key_description[i], response, hidden_auths);
break;
}
}
- AddAuthorization(Authorization(TAG_CREATION_DATETIME, java_time(time(NULL))), response);
- AddAuthorization(Authorization(TAG_ORIGIN, origin()), response);
- AddAuthorization(Authorization(TAG_ROOT_OF_TRUST, "SW", 2), response);
+ AddAuthorization(Authorization(TAG_CREATION_DATETIME, java_time(time(NULL))), response,
+ hidden_auths);
+ AddAuthorization(Authorization(TAG_ORIGIN, origin()), response, hidden_auths);
+ AddAuthorization(Authorization(TAG_ROOT_OF_TRUST, "SW", 2), response, hidden_auths);
response->error = CheckAuthorizationSet(response->enforced);
if (response->error != KM_ERROR_OK)
@@ -324,16 +341,29 @@
response->error = CheckAuthorizationSet(response->unenforced);
if (response->error != KM_ERROR_OK)
return false;
+ response->error = CheckAuthorizationSet(*hidden_auths);
+ if (response->error != KM_ERROR_OK)
+ return false;
return true;
}
void GoogleKeymaster::AddAuthorization(const keymaster_key_param_t& auth,
- GenerateKeyResponse* response) {
- if (is_enforced(auth.tag))
- response->enforced.push_back(auth);
- else
- response->unenforced.push_back(auth);
+ GenerateKeyResponse* response,
+ AuthorizationSet* hidden_auths) {
+ switch (auth.tag) {
+ case KM_TAG_ROOT_OF_TRUST:
+ case KM_TAG_APPLICATION_ID:
+ case KM_TAG_APPLICATION_DATA:
+ hidden_auths->push_back(auth);
+ break;
+ default:
+ if (is_enforced(auth.tag))
+ response->enforced.push_back(auth);
+ else
+ response->unenforced.push_back(auth);
+ break;
+ }
}
} // namespace keymaster