Replace Entropy with RAND_bytes
/dev/urandom is not an approved random number generator
for NIAP certification. Changing to use BoringSSL's
RAND_bytes(), which is approved.
Bug: 121272336
Test: Ran Keystore CTS tests against Walleye, no new
test failures observed.
Change-Id: I0fb87c955512074fa714c1986ce99063ab430470
Merged-In: I579d140ef56c90b477b0d8989e3b02375681aee8
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 8af8717..9ce00c2 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -25,7 +25,6 @@
"auth_token_table.cpp",
"blob.cpp",
"confirmation_manager.cpp",
- "entropy.cpp",
"grant_store.cpp",
"key_config.proto",
"key_proto_handler.cpp",
diff --git a/keystore/KeyStore.cpp b/keystore/KeyStore.cpp
index f197d91..428b51e 100644
--- a/keystore/KeyStore.cpp
+++ b/keystore/KeyStore.cpp
@@ -63,9 +63,9 @@
return (*const_cast<KeymasterDevices*>(this))[secLevel];
}
-KeyStore::KeyStore(Entropy* entropy, const KeymasterDevices& kmDevices,
+KeyStore::KeyStore(const KeymasterDevices& kmDevices,
SecurityLevel minimalAllowedSecurityLevelForNewKeys)
- : mEntropy(entropy), mKmDevices(kmDevices),
+ : mKmDevices(kmDevices),
mAllowNewFallback(minimalAllowedSecurityLevelForNewKeys == SecurityLevel::SOFTWARE) {
memset(&mMetaData, '\0', sizeof(mMetaData));
}
@@ -89,7 +89,7 @@
ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
UserState* userState = getUserState(userId);
- return userState->initialize(pw, mEntropy);
+ return userState->initialize(pw);
}
ResponseCode KeyStore::copyMasterKey(uid_t srcUser, uid_t dstUser) {
@@ -100,12 +100,12 @@
ResponseCode KeyStore::writeMasterKey(const android::String8& pw, uid_t userId) {
UserState* userState = getUserState(userId);
- return userState->writeMasterKey(pw, mEntropy);
+ return userState->writeMasterKey(pw);
}
ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) {
UserState* userState = getUserState(userId);
- return userState->readMasterKey(pw, mEntropy);
+ return userState->readMasterKey(pw);
}
/* Here is the encoding of keys. This is necessary in order to allow arbitrary
@@ -360,8 +360,7 @@
ResponseCode KeyStore::put(const char* filename, Blob* keyBlob, uid_t userId) {
UserState* userState = getUserState(userId);
- return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(),
- mEntropy);
+ return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState());
}
static NullOr<std::tuple<uid_t, std::string>> filename2UidAlias(const std::string& filename);
diff --git a/keystore/KeyStore.h b/keystore/KeyStore.h
index 23476d2..f0fe9d3 100644
--- a/keystore/KeyStore.h
+++ b/keystore/KeyStore.h
@@ -40,7 +40,7 @@
class KeyStore {
public:
- KeyStore(Entropy* entropy, const KeymasterDevices& kmDevices,
+ KeyStore(const KeymasterDevices& kmDevices,
SecurityLevel minimalAllowedSecurityLevelForNewKeys);
~KeyStore();
@@ -140,7 +140,6 @@
static const char* kMetaDataFile;
static const android::String16 kRsaKeyType;
static const android::String16 kEcKeyType;
- Entropy* mEntropy;
KeymasterDevices mKmDevices;
bool mAllowNewFallback;
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index d21c691..ca5cb74 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -19,12 +19,12 @@
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
+#include <openssl/rand.h>
#include <string.h>
#include <cutils/log.h>
#include "blob.h"
-#include "entropy.h"
#include "keystore_utils.h"
@@ -205,8 +205,7 @@
}
}
-ResponseCode Blob::writeBlob(const std::string& filename, const uint8_t* aes_key, State state,
- Entropy* entropy) {
+ResponseCode Blob::writeBlob(const std::string& filename, const uint8_t* aes_key, State state) {
ALOGV("writing blob %s", filename.c_str());
const size_t dataLength = mBlob.length;
@@ -219,7 +218,7 @@
}
memset(mBlob.initialization_vector, 0, AES_BLOCK_SIZE);
- if (!entropy->generate_random_data(mBlob.initialization_vector, kGcmIvSizeBytes)) {
+ if (!RAND_bytes(mBlob.initialization_vector, kGcmIvSizeBytes)) {
ALOGW("Could not read random data for: %s", filename.c_str());
return ResponseCode::SYSTEM_ERROR;
}
diff --git a/keystore/blob.h b/keystore/blob.h
index 665e07a..6a52ca4 100644
--- a/keystore/blob.h
+++ b/keystore/blob.h
@@ -82,7 +82,6 @@
TYPE_KEY_CHARACTERISTICS = 5,
} BlobType;
-class Entropy;
class Blob {
public:
@@ -121,8 +120,7 @@
keystore::SecurityLevel getSecurityLevel() const;
void setSecurityLevel(keystore::SecurityLevel);
- ResponseCode writeBlob(const std::string& filename, const uint8_t* aes_key, State state,
- Entropy* entropy);
+ ResponseCode writeBlob(const std::string& filename, const uint8_t* aes_key, State state);
ResponseCode readBlob(const std::string& filename, const uint8_t* aes_key, State state);
private:
diff --git a/keystore/entropy.cpp b/keystore/entropy.cpp
deleted file mode 100644
index 1bfe9a1..0000000
--- a/keystore/entropy.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#define LOG_TAG "keystore"
-
-#include "entropy.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <cutils/log.h>
-
-#include "keystore_utils.h"
-
-Entropy::~Entropy() {
- if (mRandom >= 0) {
- close(mRandom);
- }
-}
-
-bool Entropy::open() {
- const char* randomDevice = "/dev/urandom";
- mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY));
- if (mRandom < 0) {
- ALOGE("open: %s: %s", randomDevice, strerror(errno));
- return false;
- }
- return true;
-}
-
-bool Entropy::generate_random_data(uint8_t* data, size_t size) const {
- return (readFully(mRandom, data, size) == size);
-}
diff --git a/keystore/entropy.h b/keystore/entropy.h
deleted file mode 100644
index 0e4d1b2..0000000
--- a/keystore/entropy.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#ifndef KEYSTORE_ENTROPY_H_
-#define KEYSTORE_ENTROPY_H_
-
-#include <stdint.h>
-
-class Entropy {
- public:
- Entropy() : mRandom(-1) {}
- ~Entropy();
-
- bool open();
- bool generate_random_data(uint8_t* data, size_t size) const;
-
- private:
- int mRandom;
-};
-
-#endif // KEYSTORE_ENTROPY_H_
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
index 82d4e69..52e83c8 100644
--- a/keystore/keystore_main.cpp
+++ b/keystore/keystore_main.cpp
@@ -32,7 +32,6 @@
#include <keystore/keystore_return_types.h>
#include "KeyStore.h"
-#include "entropy.h"
#include "key_store_service.h"
#include "legacy_keymaster_device_wrapper.h"
#include "permissions.h"
@@ -136,9 +135,6 @@
CHECK(argc >= 2) << "A directory must be specified!";
CHECK(chdir(argv[1]) != -1) << "chdir: " << argv[1] << ": " << strerror(errno);
- Entropy entropy;
- CHECK(entropy.open()) << "Failed to open entropy source.";
-
auto kmDevices = initializeKeymasters();
CHECK(kmDevices[SecurityLevel::SOFTWARE]) << "Missing software Keymaster device";
@@ -155,7 +151,7 @@
SecurityLevel minimalAllowedSecurityLevelForNewKeys =
halVersion.majorVersion >= 2 ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE;
- keystore::KeyStore keyStore(&entropy, kmDevices, minimalAllowedSecurityLevelForNewKeys);
+ keystore::KeyStore keyStore(kmDevices, minimalAllowedSecurityLevelForNewKeys);
keyStore.initialize();
android::sp<android::IServiceManager> sm = android::defaultServiceManager();
android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(&keyStore);
diff --git a/keystore/user_state.cpp b/keystore/user_state.cpp
index 5f9cd5f..b62598d 100644
--- a/keystore/user_state.cpp
+++ b/keystore/user_state.cpp
@@ -25,6 +25,7 @@
#include <sys/stat.h>
#include <openssl/evp.h>
+#include <openssl/rand.h>
#include <cutils/log.h>
@@ -76,11 +77,11 @@
return unlink(mMasterKeyFile) == 0 || errno == ENOENT;
}
-ResponseCode UserState::initialize(const android::String8& pw, Entropy* entropy) {
- if (!generateMasterKey(entropy)) {
+ResponseCode UserState::initialize(const android::String8& pw) {
+ if (!generateMasterKey()) {
return ResponseCode::SYSTEM_ERROR;
}
- ResponseCode response = writeMasterKey(pw, entropy);
+ ResponseCode response = writeMasterKey(pw);
if (response != ResponseCode::NO_ERROR) {
return response;
}
@@ -130,14 +131,14 @@
return ResponseCode::NO_ERROR;
}
-ResponseCode UserState::writeMasterKey(const android::String8& pw, Entropy* entropy) {
+ResponseCode UserState::writeMasterKey(const android::String8& pw) {
uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
- return masterKeyBlob.writeBlob(mMasterKeyFile, passwordKey, STATE_NO_ERROR, entropy);
+ return masterKeyBlob.writeBlob(mMasterKeyFile, passwordKey, STATE_NO_ERROR);
}
-ResponseCode UserState::readMasterKey(const android::String8& pw, Entropy* entropy) {
+ResponseCode UserState::readMasterKey(const android::String8& pw) {
int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY));
if (in < 0) {
return ResponseCode::SYSTEM_ERROR;
@@ -167,10 +168,10 @@
if (response == ResponseCode::NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
// If salt was missing, generate one and write a new master key file with the salt.
if (salt == NULL) {
- if (!generateSalt(entropy)) {
+ if (!generateSalt()) {
return ResponseCode::SYSTEM_ERROR;
}
- response = writeMasterKey(pw, entropy);
+ response = writeMasterKey(pw);
}
if (response == ResponseCode::NO_ERROR) {
memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
@@ -237,15 +238,15 @@
8192, keySize, key);
}
-bool UserState::generateSalt(Entropy* entropy) {
- return entropy->generate_random_data(mSalt, sizeof(mSalt));
+bool UserState::generateSalt() {
+ return RAND_bytes(mSalt, sizeof(mSalt));
}
-bool UserState::generateMasterKey(Entropy* entropy) {
- if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
+bool UserState::generateMasterKey() {
+ if (!RAND_bytes(mMasterKey, sizeof(mMasterKey))) {
return false;
}
- if (!generateSalt(entropy)) {
+ if (!generateSalt()) {
return false;
}
return true;
diff --git a/keystore/user_state.h b/keystore/user_state.h
index c28f7b8..e1d48bd 100644
--- a/keystore/user_state.h
+++ b/keystore/user_state.h
@@ -25,7 +25,6 @@
#include <keystore/keystore.h>
-#include "entropy.h"
class UserState {
public:
@@ -47,12 +46,12 @@
void zeroizeMasterKeysInMemory();
bool deleteMasterKey();
- ResponseCode initialize(const android::String8& pw, Entropy* entropy);
+ ResponseCode initialize(const android::String8& pw);
ResponseCode copyMasterKey(UserState* src);
ResponseCode copyMasterKeyFile(UserState* src);
- ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy);
- ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy);
+ ResponseCode writeMasterKey(const android::String8& pw);
+ ResponseCode readMasterKey(const android::String8& pw);
auto& getEncryptionKey() const { return mMasterKey; }
@@ -67,8 +66,8 @@
void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw,
uint8_t* salt);
- bool generateSalt(Entropy* entropy);
- bool generateMasterKey(Entropy* entropy);
+ bool generateSalt();
+ bool generateMasterKey();
void setupMasterKeys();
uid_t mUserId;