upload android base code part6
This commit is contained in:
parent
421e214c7d
commit
4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions
149
android/system/keymaster/integrity_assured_key_blob.cpp
Normal file
149
android/system/keymaster/integrity_assured_key_blob.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "integrity_assured_key_blob.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <keymaster/new>
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include <keymaster/android_keymaster_utils.h>
|
||||
#include <keymaster/authorization_set.h>
|
||||
|
||||
#include "openssl_err.h"
|
||||
|
||||
namespace keymaster {
|
||||
|
||||
static const uint8_t BLOB_VERSION = 0;
|
||||
static const size_t HMAC_SIZE = 8;
|
||||
static const char HMAC_KEY[] = "IntegrityAssuredBlob0";
|
||||
|
||||
inline size_t min(size_t a, size_t b) {
|
||||
if (a < b)
|
||||
return a;
|
||||
return b;
|
||||
}
|
||||
|
||||
class HmacCleanup {
|
||||
public:
|
||||
explicit HmacCleanup(HMAC_CTX* ctx) : ctx_(ctx) {}
|
||||
~HmacCleanup() { HMAC_CTX_cleanup(ctx_); }
|
||||
|
||||
private:
|
||||
HMAC_CTX* ctx_;
|
||||
};
|
||||
|
||||
static keymaster_error_t ComputeHmac(const uint8_t* serialized_data, size_t serialized_data_size,
|
||||
const AuthorizationSet& hidden, uint8_t hmac[HMAC_SIZE]) {
|
||||
size_t hidden_bytes_size = hidden.SerializedSize();
|
||||
UniquePtr<uint8_t[]> hidden_bytes(new (std::nothrow) uint8_t[hidden_bytes_size]);
|
||||
if (!hidden_bytes.get())
|
||||
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
|
||||
hidden.Serialize(hidden_bytes.get(), hidden_bytes.get() + hidden_bytes_size);
|
||||
|
||||
HMAC_CTX ctx;
|
||||
HMAC_CTX_init(&ctx);
|
||||
const EVP_MD* md = EVP_sha256();
|
||||
if (!HMAC_Init_ex(&ctx, HMAC_KEY, sizeof(HMAC_KEY), md, NULL /* engine */))
|
||||
return TranslateLastOpenSslError();
|
||||
HmacCleanup cleanup(&ctx);
|
||||
|
||||
uint8_t tmp[EVP_MAX_MD_SIZE];
|
||||
unsigned tmp_len;
|
||||
if (!HMAC_Update(&ctx, serialized_data, serialized_data_size) ||
|
||||
!HMAC_Update(&ctx, hidden_bytes.get(), hidden_bytes_size) || //
|
||||
!HMAC_Final(&ctx, tmp, &tmp_len))
|
||||
return TranslateLastOpenSslError();
|
||||
|
||||
assert(tmp_len >= HMAC_SIZE);
|
||||
memcpy(hmac, tmp, min(HMAC_SIZE, tmp_len));
|
||||
|
||||
return KM_ERROR_OK;
|
||||
}
|
||||
|
||||
keymaster_error_t SerializeIntegrityAssuredBlob(const KeymasterKeyBlob& key_material,
|
||||
const AuthorizationSet& hidden,
|
||||
const AuthorizationSet& hw_enforced,
|
||||
const AuthorizationSet& sw_enforced,
|
||||
KeymasterKeyBlob* key_blob) {
|
||||
size_t size = 1 /* version */ + //
|
||||
key_material.SerializedSize() + //
|
||||
hw_enforced.SerializedSize() + //
|
||||
sw_enforced.SerializedSize() + //
|
||||
HMAC_SIZE;
|
||||
|
||||
if (!key_blob->Reset(size))
|
||||
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
|
||||
|
||||
uint8_t* p = key_blob->writable_data();
|
||||
*p++ = BLOB_VERSION;
|
||||
p = key_material.Serialize(p, key_blob->end());
|
||||
p = hw_enforced.Serialize(p, key_blob->end());
|
||||
p = sw_enforced.Serialize(p, key_blob->end());
|
||||
|
||||
return ComputeHmac(key_blob->key_material, p - key_blob->key_material, hidden, p);
|
||||
}
|
||||
|
||||
keymaster_error_t DeserializeIntegrityAssuredBlob(const KeymasterKeyBlob& key_blob,
|
||||
const AuthorizationSet& hidden,
|
||||
KeymasterKeyBlob* key_material,
|
||||
AuthorizationSet* hw_enforced,
|
||||
AuthorizationSet* sw_enforced) {
|
||||
const uint8_t* p = key_blob.begin();
|
||||
const uint8_t* end = key_blob.end();
|
||||
|
||||
if (p > end || p + HMAC_SIZE > end)
|
||||
return KM_ERROR_INVALID_KEY_BLOB;
|
||||
|
||||
uint8_t computed_hmac[HMAC_SIZE];
|
||||
keymaster_error_t error = ComputeHmac(key_blob.begin(), key_blob.key_material_size - HMAC_SIZE,
|
||||
hidden, computed_hmac);
|
||||
if (error != KM_ERROR_OK)
|
||||
return error;
|
||||
|
||||
if (CRYPTO_memcmp(key_blob.end() - HMAC_SIZE, computed_hmac, HMAC_SIZE) != 0)
|
||||
return KM_ERROR_INVALID_KEY_BLOB;
|
||||
|
||||
return DeserializeIntegrityAssuredBlob_NoHmacCheck(key_blob, key_material, hw_enforced,
|
||||
sw_enforced);
|
||||
}
|
||||
|
||||
keymaster_error_t DeserializeIntegrityAssuredBlob_NoHmacCheck(const KeymasterKeyBlob& key_blob,
|
||||
KeymasterKeyBlob* key_material,
|
||||
AuthorizationSet* hw_enforced,
|
||||
AuthorizationSet* sw_enforced) {
|
||||
const uint8_t* p = key_blob.begin();
|
||||
const uint8_t* end = key_blob.end() - HMAC_SIZE;
|
||||
|
||||
if (p > end)
|
||||
return KM_ERROR_INVALID_KEY_BLOB;
|
||||
|
||||
if (*p != BLOB_VERSION)
|
||||
return KM_ERROR_INVALID_KEY_BLOB;
|
||||
++p;
|
||||
|
||||
if (!key_material->Deserialize(&p, end) || //
|
||||
!hw_enforced->Deserialize(&p, end) || //
|
||||
!sw_enforced->Deserialize(&p, end))
|
||||
return KM_ERROR_INVALID_KEY_BLOB;
|
||||
|
||||
return KM_ERROR_OK;
|
||||
}
|
||||
|
||||
} // namespace keymaster;
|
Loading…
Add table
Add a link
Reference in a new issue