1d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden/*
2d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden * Copyright 2015 The Android Open Source Project
3d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden *
4d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden * Licensed under the Apache License, Version 2.0 (the "License");
5d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden * you may not use this file except in compliance with the License.
6d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden * You may obtain a copy of the License at
7d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden *
8d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden *      http://www.apache.org/licenses/LICENSE-2.0
9d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden *
10d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden * Unless required by applicable law or agreed to in writing, software
11d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden * distributed under the License is distributed on an "AS IS" BASIS,
12d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden * See the License for the specific language governing permissions and
14d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden * limitations under the License.
15d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden */
16d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
17d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden#include "ec_keymaster1_key.h"
18d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
19d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden#include <memory>
20d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
21d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden#include <keymaster/logger.h>
22d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
23d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden#include "ecdsa_keymaster1_operation.h"
24d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden#include "ecdsa_operation.h"
25d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
26d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdenusing std::unique_ptr;
27d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
28d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdennamespace keymaster {
29d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
30d599b15c0693950bdc72fb867872044fdc484ef5Shawn WilldenEcdsaKeymaster1KeyFactory::EcdsaKeymaster1KeyFactory(const SoftKeymasterContext* context,
31d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                                                     const Keymaster1Engine* engine)
32d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    : EcKeyFactory(context), engine_(engine),
33d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden      sign_factory_(new EcdsaKeymaster1OperationFactory(KM_PURPOSE_SIGN, engine)),
34d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden      // For pubkey ops we can use the normal operation factories.
35d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden      verify_factory_(new EcdsaVerifyOperationFactory) {}
36d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
37d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdenstatic bool is_supported(uint32_t digest) {
38d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256;
39d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden}
40d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
41d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdenstatic void UpdateToWorkAroundUnsupportedDigests(const AuthorizationSet& key_description,
42d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                                                 AuthorizationSet* new_description) {
43d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    bool have_unsupported_digests = false;
44d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    bool have_digest_none = false;
45d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    for (const keymaster_key_param_t& entry : key_description) {
46d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        new_description->push_back(entry);
47d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
48d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        if (entry.tag == TAG_DIGEST) {
49d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden            if (entry.enumerated == KM_DIGEST_NONE) {
50d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                have_digest_none = true;
51d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden            } else if (!is_supported(entry.enumerated)) {
52d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                LOG_D("Found request for unsupported digest %u", entry.enumerated);
53d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                have_unsupported_digests = true;
54d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden            }
55d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        }
56d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    }
57d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
58d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    if (have_unsupported_digests && !have_digest_none) {
59d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        LOG_I("Adding KM_DIGEST_NONE to key authorization, to enable software digesting", 0);
60d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        new_description->push_back(TAG_DIGEST, KM_DIGEST_NONE);
61d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    }
62d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden}
63d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
64d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdenkeymaster_error_t EcdsaKeymaster1KeyFactory::GenerateKey(const AuthorizationSet& key_description,
65d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                                                         KeymasterKeyBlob* key_blob,
66d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                                                         AuthorizationSet* hw_enforced,
67d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                                                         AuthorizationSet* sw_enforced) const {
68d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    AuthorizationSet key_params_copy;
69d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy);
70d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    return engine_->GenerateKey(key_params_copy, key_blob, hw_enforced, sw_enforced);
71d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden}
72d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
73d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdenkeymaster_error_t EcdsaKeymaster1KeyFactory::ImportKey(
74d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
75d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
76d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
77d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    AuthorizationSet key_params_copy;
78d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy);
79d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    return engine_->ImportKey(key_params_copy, input_key_material_format, input_key_material,
80d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                              output_key_blob, hw_enforced, sw_enforced);
81d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden}
82d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
83d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdenkeymaster_error_t EcdsaKeymaster1KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
84d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                                                     const AuthorizationSet& additional_params,
85d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                                                     const AuthorizationSet& hw_enforced,
86d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                                                     const AuthorizationSet& sw_enforced,
87d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden                                                     UniquePtr<Key>* key) const {
88d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    if (!key)
89d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        return KM_ERROR_OUTPUT_PARAMETER_NULL;
90d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
91d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    keymaster_error_t error;
92fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong    unique_ptr<EC_KEY, EC_KEY_Delete> ecdsa(
93d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        engine_->BuildEcKey(key_material, additional_params, &error));
94d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    if (!ecdsa)
95d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        return error;
96d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
97d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    key->reset(new (std::nothrow)
984fc15704d86aab977c2bdbb14345a2c417be2babShawn Willden                   EcdsaKeymaster1Key(ecdsa.release(), hw_enforced, sw_enforced, &error));
99d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    if (!key->get())
100d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
101d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
102d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    if (error != KM_ERROR_OK)
103d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        return error;
104d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
105d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    return KM_ERROR_OK;
106d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden}
107d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
108d599b15c0693950bdc72fb867872044fdc484ef5Shawn WilldenOperationFactory*
109d599b15c0693950bdc72fb867872044fdc484ef5Shawn WilldenEcdsaKeymaster1KeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
110d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    switch (purpose) {
111d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    case KM_PURPOSE_SIGN:
112d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        return sign_factory_.get();
113d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    case KM_PURPOSE_VERIFY:
114d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        return verify_factory_.get();
115d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    default:
116d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden        return nullptr;
117d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden    }
118d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden}
119d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden
120d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden}  // namespace keymaster
121