Do digesting, and sometimes padding, in SW when HW doesnt.

The keymaster1 specification only requires HW modules to implement
SHA256 out of the list of keymaster1 digest modes.  That would force
many keys to be software only, and would break legacy scenarios.  This
change uses SoftKeymasterDevice to front keymaster modules that don't
implement the full suite of digests, quietly inserting KM_DIGEST_NONE
and KM_PAD_NONE into key generation/import requests when necessary, then
performing the digesting, and sometimes padding, in software, then
delegating crypto operations to the hardware.

This is only done for RSA and EC keys.  Software digesting isn't
possible for HMAC or AES-GCM keys.

Note that this is not the complete fix for the bug.  Some changes in
keystore are also required, coming in another CL.

Bug: 24873723
Change-Id: I740572eb11341fb0659085309da01d5cbcd3854d
diff --git a/keymaster1_engine.cpp b/keymaster1_engine.cpp
new file mode 100644
index 0000000..866a255
--- /dev/null
+++ b/keymaster1_engine.cpp
@@ -0,0 +1,415 @@
+/*
+ * 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 "keymaster1_engine.h"
+
+#include <assert.h>
+
+#include <algorithm>
+#include <memory>
+
+#define LOG_TAG "Keymaster1Engine"
+#include <cutils/log.h>
+
+#include "keymaster/android_keymaster_utils.h"
+
+#include <openssl/bn.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
+
+#include "openssl_err.h"
+#include "openssl_utils.h"
+
+using std::shared_ptr;
+using std::unique_ptr;
+
+namespace keymaster {
+
+Keymaster1Engine* Keymaster1Engine::instance_ = nullptr;
+
+Keymaster1Engine::Keymaster1Engine(const keymaster1_device_t* keymaster1_device)
+    : keymaster1_device_(keymaster1_device), engine_(ENGINE_new()),
+      rsa_index_(RSA_get_ex_new_index(0 /* argl */, NULL /* argp */, NULL /* new_func */,
+                                      Keymaster1Engine::duplicate_key_data,
+                                      Keymaster1Engine::free_key_data)),
+      ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */, NULL /* argp */, NULL /* new_func */,
+                                            Keymaster1Engine::duplicate_key_data,
+                                            Keymaster1Engine::free_key_data)),
+      rsa_method_(BuildRsaMethod()), ecdsa_method_(BuildEcdsaMethod()) {
+    assert(rsa_index_ != -1);
+    assert(ec_key_index_ != -1);
+    assert(keymaster1_device);
+    assert(!instance_);
+
+    instance_ = this;
+
+    ENGINE_set_RSA_method(engine_.get(), &rsa_method_, sizeof(rsa_method_));
+    ENGINE_set_ECDSA_method(engine_.get(), &ecdsa_method_, sizeof(ecdsa_method_));
+}
+
+Keymaster1Engine::~Keymaster1Engine() {
+    keymaster1_device_->common.close(
+        reinterpret_cast<hw_device_t*>(const_cast<keymaster1_device_t*>(keymaster1_device_)));
+    instance_ = nullptr;
+}
+
+static void ConvertCharacteristics(keymaster_key_characteristics_t* characteristics,
+                                   AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) {
+    unique_ptr<keymaster_key_characteristics_t, Characteristics_Delete> characteristics_deleter(
+        characteristics);
+    if (hw_enforced)
+        hw_enforced->Reinitialize(characteristics->hw_enforced);
+    if (sw_enforced)
+        sw_enforced->Reinitialize(characteristics->sw_enforced);
+}
+
+keymaster_error_t Keymaster1Engine::GenerateKey(const AuthorizationSet& key_description,
+                                                KeymasterKeyBlob* key_blob,
+                                                AuthorizationSet* hw_enforced,
+                                                AuthorizationSet* sw_enforced) const {
+    assert(key_blob);
+
+    keymaster_key_characteristics_t* characteristics;
+    keymaster_key_blob_t blob;
+    keymaster_error_t error = keymaster1_device_->generate_key(keymaster1_device_, &key_description,
+                                                               &blob, &characteristics);
+    if (error != KM_ERROR_OK)
+        return error;
+    unique_ptr<uint8_t, Malloc_Delete> blob_deleter(const_cast<uint8_t*>(blob.key_material));
+    key_blob->key_material = dup_buffer(blob.key_material, blob.key_material_size);
+    key_blob->key_material_size = blob.key_material_size;
+
+    ConvertCharacteristics(characteristics, hw_enforced, sw_enforced);
+    return error;
+}
+
+keymaster_error_t Keymaster1Engine::ImportKey(const AuthorizationSet& key_description,
+                                              keymaster_key_format_t input_key_material_format,
+                                              const KeymasterKeyBlob& input_key_material,
+                                              KeymasterKeyBlob* output_key_blob,
+                                              AuthorizationSet* hw_enforced,
+                                              AuthorizationSet* sw_enforced) const {
+    assert(output_key_blob);
+
+    keymaster_key_characteristics_t* characteristics;
+    const keymaster_blob_t input_key = {input_key_material.key_material,
+                                        input_key_material.key_material_size};
+    keymaster_key_blob_t blob;
+    keymaster_error_t error = keymaster1_device_->import_key(keymaster1_device_, &key_description,
+                                                             input_key_material_format, &input_key,
+                                                             &blob, &characteristics);
+    if (error != KM_ERROR_OK)
+        return error;
+    unique_ptr<uint8_t, Malloc_Delete> blob_deleter(const_cast<uint8_t*>(blob.key_material));
+    output_key_blob->key_material = dup_buffer(blob.key_material, blob.key_material_size);
+    output_key_blob->key_material_size = blob.key_material_size;
+
+    ConvertCharacteristics(characteristics, hw_enforced, sw_enforced);
+    return error;
+}
+
+RSA* Keymaster1Engine::BuildRsaKey(const KeymasterKeyBlob& blob,
+                                   const AuthorizationSet& additional_params,
+                                   keymaster_error_t* error) const {
+    // Create new RSA key (with engine methods) and add metadata
+    unique_ptr<RSA, RSA_Delete> rsa(RSA_new_method(engine_.get()));
+    if (!rsa) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    KeyData* key_data = new KeyData(blob, additional_params);
+    if (!RSA_set_ex_data(rsa.get(), rsa_index_, key_data)) {
+        *error = TranslateLastOpenSslError();
+        delete key_data;
+        return nullptr;
+    }
+
+    // Copy public key into new RSA key
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+        GetKeymaster1PublicKey(key_data->key_material, key_data->begin_params, error));
+    if (!pkey) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    unique_ptr<RSA, RSA_Delete> public_rsa(EVP_PKEY_get1_RSA(pkey.get()));
+    if (!public_rsa) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    rsa->n = BN_dup(public_rsa->n);
+    rsa->e = BN_dup(public_rsa->e);
+    if (!rsa->n || !rsa->e) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    *error = KM_ERROR_OK;
+    return rsa.release();
+}
+
+EC_KEY* Keymaster1Engine::BuildEcKey(const KeymasterKeyBlob& blob,
+                                     const AuthorizationSet& additional_params,
+                                     keymaster_error_t* error) const {
+    // Create new EC key (with engine methods) and insert blob
+    unique_ptr<EC_KEY, EC_Delete> ec_key(EC_KEY_new_method(engine_.get()));
+    if (!ec_key) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    KeyData* key_data = new KeyData(blob, additional_params);
+    if (!EC_KEY_set_ex_data(ec_key.get(), ec_key_index_, key_data)) {
+        *error = TranslateLastOpenSslError();
+        delete key_data;
+        return nullptr;
+    }
+
+    // Copy public key into new EC key
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+        GetKeymaster1PublicKey(blob, additional_params, error));
+    if (!pkey) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    unique_ptr<EC_KEY, EC_Delete> public_ec_key(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (!public_ec_key) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    if (!EC_KEY_set_group(ec_key.get(), EC_KEY_get0_group(public_ec_key.get())) ||
+        !EC_KEY_set_public_key(ec_key.get(), EC_KEY_get0_public_key(public_ec_key.get()))) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    *error = KM_ERROR_OK;
+    return ec_key.release();
+}
+
+Keymaster1Engine::KeyData* Keymaster1Engine::GetData(EVP_PKEY* key) const {
+    switch (EVP_PKEY_type(key->type)) {
+    case EVP_PKEY_RSA: {
+        unique_ptr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(key));
+        return GetData(rsa.get());
+    }
+
+    case EVP_PKEY_EC: {
+        unique_ptr<EC_KEY, EC_Delete> ec_key(EVP_PKEY_get1_EC_KEY(key));
+        return GetData(ec_key.get());
+    }
+
+    default:
+        return nullptr;
+    };
+}
+
+Keymaster1Engine::KeyData* Keymaster1Engine::GetData(const RSA* rsa) const {
+    if (!rsa)
+        return nullptr;
+    return reinterpret_cast<KeyData*>(RSA_get_ex_data(rsa, rsa_index_));
+}
+
+Keymaster1Engine::KeyData* Keymaster1Engine::GetData(const EC_KEY* ec_key) const {
+    if (!ec_key)
+        return nullptr;
+    return reinterpret_cast<KeyData*>(EC_KEY_get_ex_data(ec_key, ec_key_index_));
+}
+
+/* static */
+int Keymaster1Engine::duplicate_key_data(CRYPTO_EX_DATA* /* to */, const CRYPTO_EX_DATA* /* from */,
+                                         void** from_d, int /* index */, long /* argl */,
+                                         void* /* argp */) {
+    KeyData* data = reinterpret_cast<KeyData*>(*from_d);
+    if (!data)
+        return 1;
+
+    // Default copy ctor is good.
+    *from_d = new KeyData(*data);
+    if (*from_d)
+        return 1;
+    return 0;
+}
+
+/* static */
+void Keymaster1Engine::free_key_data(void* /* parent */, void* ptr, CRYPTO_EX_DATA* /* data */,
+                                     int /* index*/, long /* argl */, void* /* argp */) {
+    delete reinterpret_cast<KeyData*>(ptr);
+}
+
+keymaster_error_t Keymaster1Engine::Keymaster1Finish(const KeyData* key_data,
+                                                     const keymaster_blob_t& input,
+                                                     keymaster_blob_t* output) {
+    if (key_data->op_handle == 0)
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    size_t input_consumed;
+    // Note: devices are required to consume all input in a single update call for undigested
+    // signing operations and encryption operations.  No need to loop here.
+    keymaster_error_t error =
+        device()->update(device(), key_data->op_handle, &key_data->finish_params, &input,
+                         &input_consumed, nullptr /* out_params */, nullptr /* output */);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return device()->finish(device(), key_data->op_handle, &key_data->finish_params,
+                            nullptr /* signature */, nullptr /* out_params */, output);
+}
+
+/* static */
+int Keymaster1Engine::rsa_sign_raw(RSA* rsa, size_t* out_len, uint8_t* out, size_t max_out,
+                                   const uint8_t* in, size_t in_len, int padding) {
+    KeyData* key_data = instance_->GetData(rsa);
+    if (!key_data)
+        return 0;
+
+    if (padding != key_data->expected_openssl_padding) {
+        LOG_E("Expected sign_raw with padding %d but got padding %d",
+              key_data->expected_openssl_padding, padding);
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+
+    keymaster_blob_t input = {in, in_len};
+    keymaster_blob_t output;
+    key_data->error = instance_->Keymaster1Finish(key_data, input, &output);
+    if (key_data->error != KM_ERROR_OK)
+        return 0;
+    unique_ptr<uint8_t, Malloc_Delete> output_deleter(const_cast<uint8_t*>(output.data));
+
+    *out_len = std::min(output.data_length, max_out);
+    memcpy(out, output.data, *out_len);
+    return 1;
+}
+
+/* static */
+int Keymaster1Engine::rsa_decrypt(RSA* rsa, size_t* out_len, uint8_t* out, size_t max_out,
+                                  const uint8_t* in, size_t in_len, int padding) {
+    KeyData* key_data = instance_->GetData(rsa);
+    if (!key_data)
+        return 0;
+
+    if (padding != key_data->expected_openssl_padding) {
+        LOG_E("Expected sign_raw with padding %d but got padding %d",
+              key_data->expected_openssl_padding, padding);
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+
+    keymaster_blob_t input = {in, in_len};
+    keymaster_blob_t output;
+    key_data->error = instance_->Keymaster1Finish(key_data, input, &output);
+    if (key_data->error != KM_ERROR_OK)
+        return 0;
+    unique_ptr<uint8_t, Malloc_Delete> output_deleter(const_cast<uint8_t*>(output.data));
+
+    *out_len = std::min(output.data_length, max_out);
+    memcpy(out, output.data, *out_len);
+    return 1;
+}
+
+/* static */
+int Keymaster1Engine::ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
+                                 unsigned int* sig_len, EC_KEY* ec_key) {
+    KeyData* key_data = instance_->GetData(ec_key);
+    if (!key_data)
+        return 0;
+
+    // Truncate digest if it's too long
+    size_t max_input_len = (ec_group_size_bits(ec_key) + 7) / 8;
+    if (digest_len > max_input_len)
+        digest_len = max_input_len;
+
+    keymaster_blob_t input = {digest, digest_len};
+    keymaster_blob_t output;
+    key_data->error = instance_->Keymaster1Finish(key_data, input, &output);
+    if (key_data->error != KM_ERROR_OK)
+        return 0;
+    unique_ptr<uint8_t, Malloc_Delete> output_deleter(const_cast<uint8_t*>(output.data));
+
+    *sig_len = std::min(output.data_length, ECDSA_size(ec_key));
+    memcpy(sig, output.data, *sig_len);
+    return 1;
+}
+
+EVP_PKEY* Keymaster1Engine::GetKeymaster1PublicKey(const KeymasterKeyBlob& blob,
+                                                   const AuthorizationSet& additional_params,
+                                                   keymaster_error_t* error) const {
+    keymaster_blob_t client_id = {nullptr, 0};
+    keymaster_blob_t app_data = {nullptr, 0};
+    keymaster_blob_t* client_id_ptr = nullptr;
+    keymaster_blob_t* app_data_ptr = nullptr;
+    if (additional_params.GetTagValue(TAG_APPLICATION_ID, &client_id))
+        client_id_ptr = &client_id;
+    if (additional_params.GetTagValue(TAG_APPLICATION_DATA, &app_data))
+        app_data_ptr = &app_data;
+
+    keymaster_blob_t export_data = {nullptr, 0};
+    *error = keymaster1_device_->export_key(keymaster1_device_, KM_KEY_FORMAT_X509, &blob,
+                                            client_id_ptr, app_data_ptr, &export_data);
+    if (*error != KM_ERROR_OK)
+        return nullptr;
+
+    unique_ptr<uint8_t, Malloc_Delete> pub_key(const_cast<uint8_t*>(export_data.data));
+
+    const uint8_t* p = export_data.data;
+    return d2i_PUBKEY(nullptr /* allocate new struct */, &p, export_data.data_length);
+}
+
+RSA_METHOD Keymaster1Engine::BuildRsaMethod() {
+    RSA_METHOD method;
+
+    method.common.references = 0;
+    method.common.is_static = 1;
+    method.app_data = nullptr;
+    method.init = nullptr;
+    method.finish = nullptr;
+    method.size = nullptr;
+    method.sign = nullptr;
+    method.verify = nullptr;
+    method.encrypt = nullptr;
+    method.sign_raw = Keymaster1Engine::rsa_sign_raw;
+    method.decrypt = Keymaster1Engine::rsa_decrypt;
+    method.verify_raw = nullptr;
+    method.private_transform = nullptr;
+    method.mod_exp = nullptr;
+    method.bn_mod_exp = BN_mod_exp_mont;
+    method.flags = RSA_FLAG_OPAQUE;
+    method.keygen = nullptr;
+    method.supports_digest = nullptr;
+
+    return method;
+}
+
+ECDSA_METHOD Keymaster1Engine::BuildEcdsaMethod() {
+    ECDSA_METHOD method;
+
+    method.common.references = 0;
+    method.common.is_static = 1;
+    method.app_data = nullptr;
+    method.init = nullptr;
+    method.finish = nullptr;
+    method.group_order_size = nullptr;
+    method.sign = Keymaster1Engine::ecdsa_sign;
+    method.verify = nullptr;
+    method.flags = ECDSA_FLAG_OPAQUE;
+
+    return method;
+}
+
+}  // namespace keymaster