Home | History | Annotate | Download | only in vold
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "Keymaster.h"
     18 
     19 #include <android-base/logging.h>
     20 #include <keymasterV4_0/authorization_set.h>
     21 #include <keymasterV4_0/keymaster_utils.h>
     22 
     23 namespace android {
     24 namespace vold {
     25 
     26 using ::android::hardware::hidl_string;
     27 using ::android::hardware::hidl_vec;
     28 using ::android::hardware::keymaster::V4_0::SecurityLevel;
     29 
     30 KeymasterOperation::~KeymasterOperation() {
     31     if (mDevice) mDevice->abort(mOpHandle);
     32 }
     33 
     34 bool KeymasterOperation::updateCompletely(const char* input, size_t inputLen,
     35                                           const std::function<void(const char*, size_t)> consumer) {
     36     uint32_t inputConsumed = 0;
     37 
     38     km::ErrorCode km_error;
     39     auto hidlCB = [&](km::ErrorCode ret, uint32_t inputConsumedDelta,
     40                       const hidl_vec<km::KeyParameter>& /*ignored*/,
     41                       const hidl_vec<uint8_t>& _output) {
     42         km_error = ret;
     43         if (km_error != km::ErrorCode::OK) return;
     44         inputConsumed += inputConsumedDelta;
     45         consumer(reinterpret_cast<const char*>(&_output[0]), _output.size());
     46     };
     47 
     48     while (inputConsumed != inputLen) {
     49         size_t toRead = static_cast<size_t>(inputLen - inputConsumed);
     50         auto inputBlob = km::support::blob2hidlVec(
     51             reinterpret_cast<const uint8_t*>(&input[inputConsumed]), toRead);
     52         auto error = mDevice->update(mOpHandle, hidl_vec<km::KeyParameter>(), inputBlob,
     53                                      km::HardwareAuthToken(), km::VerificationToken(), hidlCB);
     54         if (!error.isOk()) {
     55             LOG(ERROR) << "update failed: " << error.description();
     56             mDevice = nullptr;
     57             return false;
     58         }
     59         if (km_error != km::ErrorCode::OK) {
     60             LOG(ERROR) << "update failed, code " << int32_t(km_error);
     61             mDevice = nullptr;
     62             return false;
     63         }
     64         if (inputConsumed > inputLen) {
     65             LOG(ERROR) << "update reported too much input consumed";
     66             mDevice = nullptr;
     67             return false;
     68         }
     69     }
     70     return true;
     71 }
     72 
     73 bool KeymasterOperation::finish(std::string* output) {
     74     km::ErrorCode km_error;
     75     auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<km::KeyParameter>& /*ignored*/,
     76                       const hidl_vec<uint8_t>& _output) {
     77         km_error = ret;
     78         if (km_error != km::ErrorCode::OK) return;
     79         if (output) output->assign(reinterpret_cast<const char*>(&_output[0]), _output.size());
     80     };
     81     auto error = mDevice->finish(mOpHandle, hidl_vec<km::KeyParameter>(), hidl_vec<uint8_t>(),
     82                                  hidl_vec<uint8_t>(), km::HardwareAuthToken(),
     83                                  km::VerificationToken(), hidlCb);
     84     mDevice = nullptr;
     85     if (!error.isOk()) {
     86         LOG(ERROR) << "finish failed: " << error.description();
     87         return false;
     88     }
     89     if (km_error != km::ErrorCode::OK) {
     90         LOG(ERROR) << "finish failed, code " << int32_t(km_error);
     91         return false;
     92     }
     93     return true;
     94 }
     95 
     96 /* static */ bool Keymaster::hmacKeyGenerated = false;
     97 
     98 Keymaster::Keymaster() {
     99     auto devices = KmDevice::enumerateAvailableDevices();
    100     if (!hmacKeyGenerated) {
    101         KmDevice::performHmacKeyAgreement(devices);
    102         hmacKeyGenerated = true;
    103     }
    104     for (auto& dev : devices) {
    105         // Do not use StrongBox for device encryption / credential encryption.  If a security chip
    106         // is present it will have Weaver, which already strengthens CE.  We get no additional
    107         // benefit from using StrongBox here, so skip it.
    108         if (dev->halVersion().securityLevel != SecurityLevel::STRONGBOX) {
    109             mDevice = std::move(dev);
    110             break;
    111         }
    112     }
    113     if (!mDevice) return;
    114     auto& version = mDevice->halVersion();
    115     LOG(INFO) << "Using " << version.keymasterName << " from " << version.authorName
    116               << " for encryption.  Security level: " << toString(version.securityLevel)
    117               << ", HAL: " << mDevice->descriptor() << "/" << mDevice->instanceName();
    118 }
    119 
    120 bool Keymaster::generateKey(const km::AuthorizationSet& inParams, std::string* key) {
    121     km::ErrorCode km_error;
    122     auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
    123                       const km::KeyCharacteristics& /*ignored*/) {
    124         km_error = ret;
    125         if (km_error != km::ErrorCode::OK) return;
    126         if (key) key->assign(reinterpret_cast<const char*>(&keyBlob[0]), keyBlob.size());
    127     };
    128 
    129     auto error = mDevice->generateKey(inParams.hidl_data(), hidlCb);
    130     if (!error.isOk()) {
    131         LOG(ERROR) << "generate_key failed: " << error.description();
    132         return false;
    133     }
    134     if (km_error != km::ErrorCode::OK) {
    135         LOG(ERROR) << "generate_key failed, code " << int32_t(km_error);
    136         return false;
    137     }
    138     return true;
    139 }
    140 
    141 bool Keymaster::deleteKey(const std::string& key) {
    142     auto keyBlob = km::support::blob2hidlVec(key);
    143     auto error = mDevice->deleteKey(keyBlob);
    144     if (!error.isOk()) {
    145         LOG(ERROR) << "delete_key failed: " << error.description();
    146         return false;
    147     }
    148     if (error != km::ErrorCode::OK) {
    149         LOG(ERROR) << "delete_key failed, code " << int32_t(km::ErrorCode(error));
    150         return false;
    151     }
    152     return true;
    153 }
    154 
    155 bool Keymaster::upgradeKey(const std::string& oldKey, const km::AuthorizationSet& inParams,
    156                            std::string* newKey) {
    157     auto oldKeyBlob = km::support::blob2hidlVec(oldKey);
    158     km::ErrorCode km_error;
    159     auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
    160         km_error = ret;
    161         if (km_error != km::ErrorCode::OK) return;
    162         if (newKey)
    163             newKey->assign(reinterpret_cast<const char*>(&upgradedKeyBlob[0]),
    164                            upgradedKeyBlob.size());
    165     };
    166     auto error = mDevice->upgradeKey(oldKeyBlob, inParams.hidl_data(), hidlCb);
    167     if (!error.isOk()) {
    168         LOG(ERROR) << "upgrade_key failed: " << error.description();
    169         return false;
    170     }
    171     if (km_error != km::ErrorCode::OK) {
    172         LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error);
    173         return false;
    174     }
    175     return true;
    176 }
    177 
    178 KeymasterOperation Keymaster::begin(km::KeyPurpose purpose, const std::string& key,
    179                                     const km::AuthorizationSet& inParams,
    180                                     const km::HardwareAuthToken& authToken,
    181                                     km::AuthorizationSet* outParams) {
    182     auto keyBlob = km::support::blob2hidlVec(key);
    183     uint64_t mOpHandle;
    184     km::ErrorCode km_error;
    185 
    186     auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<km::KeyParameter>& _outParams,
    187                       uint64_t operationHandle) {
    188         km_error = ret;
    189         if (km_error != km::ErrorCode::OK) return;
    190         if (outParams) *outParams = _outParams;
    191         mOpHandle = operationHandle;
    192     };
    193 
    194     auto error = mDevice->begin(purpose, keyBlob, inParams.hidl_data(), authToken, hidlCb);
    195     if (!error.isOk()) {
    196         LOG(ERROR) << "begin failed: " << error.description();
    197         return KeymasterOperation(km::ErrorCode::UNKNOWN_ERROR);
    198     }
    199     if (km_error != km::ErrorCode::OK) {
    200         LOG(ERROR) << "begin failed, code " << int32_t(km_error);
    201         return KeymasterOperation(km_error);
    202     }
    203     return KeymasterOperation(mDevice.get(), mOpHandle);
    204 }
    205 
    206 bool Keymaster::isSecure() {
    207     return mDevice->halVersion().securityLevel != km::SecurityLevel::SOFTWARE;
    208 }
    209 
    210 }  // namespace vold
    211 }  // namespace android
    212 
    213 using namespace ::android::vold;
    214 
    215 int keymaster_compatibility_cryptfs_scrypt() {
    216     Keymaster dev;
    217     if (!dev) {
    218         LOG(ERROR) << "Failed to initiate keymaster session";
    219         return -1;
    220     }
    221     return dev.isSecure();
    222 }
    223 
    224 static bool write_string_to_buf(const std::string& towrite, uint8_t* buffer, uint32_t buffer_size,
    225                                 uint32_t* out_size) {
    226     if (!buffer || !out_size) {
    227         LOG(ERROR) << "Missing target pointers";
    228         return false;
    229     }
    230     *out_size = towrite.size();
    231     if (buffer_size < towrite.size()) {
    232         LOG(ERROR) << "Buffer too small " << buffer_size << " < " << towrite.size();
    233         return false;
    234     }
    235     memset(buffer, '\0', buffer_size);
    236     std::copy(towrite.begin(), towrite.end(), buffer);
    237     return true;
    238 }
    239 
    240 static km::AuthorizationSet keyParams(uint32_t rsa_key_size, uint64_t rsa_exponent,
    241                                       uint32_t ratelimit) {
    242     return km::AuthorizationSetBuilder()
    243         .RsaSigningKey(rsa_key_size, rsa_exponent)
    244         .NoDigestOrPadding()
    245         .Authorization(km::TAG_BLOB_USAGE_REQUIREMENTS, km::KeyBlobUsageRequirements::STANDALONE)
    246         .Authorization(km::TAG_NO_AUTH_REQUIRED)
    247         .Authorization(km::TAG_MIN_SECONDS_BETWEEN_OPS, ratelimit);
    248 }
    249 
    250 int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
    251                                             uint32_t ratelimit, uint8_t* key_buffer,
    252                                             uint32_t key_buffer_size, uint32_t* key_out_size) {
    253     if (key_out_size) {
    254         *key_out_size = 0;
    255     }
    256     Keymaster dev;
    257     if (!dev) {
    258         LOG(ERROR) << "Failed to initiate keymaster session";
    259         return -1;
    260     }
    261     std::string key;
    262     if (!dev.generateKey(keyParams(rsa_key_size, rsa_exponent, ratelimit), &key)) return -1;
    263     if (!write_string_to_buf(key, key_buffer, key_buffer_size, key_out_size)) return -1;
    264     return 0;
    265 }
    266 
    267 int keymaster_upgrade_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
    268                                              uint32_t ratelimit, const uint8_t* key_blob,
    269                                              size_t key_blob_size, uint8_t* key_buffer,
    270                                              uint32_t key_buffer_size, uint32_t* key_out_size) {
    271     if (key_out_size) {
    272         *key_out_size = 0;
    273     }
    274     Keymaster dev;
    275     if (!dev) {
    276         LOG(ERROR) << "Failed to initiate keymaster session";
    277         return -1;
    278     }
    279     std::string old_key(reinterpret_cast<const char*>(key_blob), key_blob_size);
    280     std::string new_key;
    281     if (!dev.upgradeKey(old_key, keyParams(rsa_key_size, rsa_exponent, ratelimit), &new_key))
    282         return -1;
    283     if (!write_string_to_buf(new_key, key_buffer, key_buffer_size, key_out_size)) return -1;
    284     return 0;
    285 }
    286 
    287 KeymasterSignResult keymaster_sign_object_for_cryptfs_scrypt(
    288     const uint8_t* key_blob, size_t key_blob_size, uint32_t ratelimit, const uint8_t* object,
    289     const size_t object_size, uint8_t** signature_buffer, size_t* signature_buffer_size) {
    290     Keymaster dev;
    291     if (!dev) {
    292         LOG(ERROR) << "Failed to initiate keymaster session";
    293         return KeymasterSignResult::error;
    294     }
    295     if (!key_blob || !object || !signature_buffer || !signature_buffer_size) {
    296         LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
    297         return KeymasterSignResult::error;
    298     }
    299 
    300     km::AuthorizationSet outParams;
    301     std::string key(reinterpret_cast<const char*>(key_blob), key_blob_size);
    302     std::string input(reinterpret_cast<const char*>(object), object_size);
    303     std::string output;
    304     KeymasterOperation op;
    305 
    306     auto paramBuilder = km::AuthorizationSetBuilder().NoDigestOrPadding();
    307     while (true) {
    308         op = dev.begin(km::KeyPurpose::SIGN, key, paramBuilder, km::HardwareAuthToken(), &outParams);
    309         if (op.errorCode() == km::ErrorCode::KEY_RATE_LIMIT_EXCEEDED) {
    310             sleep(ratelimit);
    311             continue;
    312         } else
    313             break;
    314     }
    315 
    316     if (op.errorCode() == km::ErrorCode::KEY_REQUIRES_UPGRADE) {
    317         LOG(ERROR) << "Keymaster key requires upgrade";
    318         return KeymasterSignResult::upgrade;
    319     }
    320 
    321     if (op.errorCode() != km::ErrorCode::OK) {
    322         LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode());
    323         return KeymasterSignResult::error;
    324     }
    325 
    326     if (!op.updateCompletely(input, &output)) {
    327         LOG(ERROR) << "Error sending data to keymaster signature transaction: "
    328                    << uint32_t(op.errorCode());
    329         return KeymasterSignResult::error;
    330     }
    331 
    332     if (!op.finish(&output)) {
    333         LOG(ERROR) << "Error finalizing keymaster signature transaction: "
    334                    << int32_t(op.errorCode());
    335         return KeymasterSignResult::error;
    336     }
    337 
    338     *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size()));
    339     if (*signature_buffer == nullptr) {
    340         LOG(ERROR) << "Error allocation buffer for keymaster signature";
    341         return KeymasterSignResult::error;
    342     }
    343     *signature_buffer_size = output.size();
    344     std::copy(output.data(), output.data() + output.size(), *signature_buffer);
    345     return KeymasterSignResult::ok;
    346 }
    347