1 /* 2 * Copyright 2014 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 #ifndef SYSTEM_KEYMASTER_ECDSA_OPERATION_H_ 18 #define SYSTEM_KEYMASTER_ECDSA_OPERATION_H_ 19 20 #include <openssl/ec.h> 21 #include <openssl/evp.h> 22 23 #include <keymaster/UniquePtr.h> 24 25 #include <keymaster/key.h> 26 #include <keymaster/km_openssl/curve25519_key.h> 27 #include <keymaster/operation.h> 28 29 namespace keymaster { 30 31 class EcdsaOperation : public Operation { 32 public: EcdsaOperation(AuthorizationSet && hw_enforced,AuthorizationSet && sw_enforced,keymaster_purpose_t purpose,keymaster_digest_t digest,EVP_PKEY * key)33 EcdsaOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, 34 keymaster_purpose_t purpose, keymaster_digest_t digest, EVP_PKEY* key) 35 : Operation(purpose, move(hw_enforced), move(sw_enforced)), digest_(digest), 36 digest_algorithm_(nullptr), ecdsa_key_(key) { 37 EVP_MD_CTX_init(&digest_ctx_); 38 } 39 ~EcdsaOperation(); 40 Abort()41 keymaster_error_t Abort() override { return KM_ERROR_OK; } 42 43 protected: 44 keymaster_error_t StoreData(const Buffer& input, size_t* input_consumed); 45 keymaster_error_t InitDigest(); 46 47 keymaster_digest_t digest_; 48 const EVP_MD* digest_algorithm_; 49 EVP_PKEY* ecdsa_key_; 50 EVP_MD_CTX digest_ctx_; 51 Buffer data_; 52 }; 53 54 class EcdsaSignOperation : public EcdsaOperation { 55 public: EcdsaSignOperation(AuthorizationSet && hw_enforced,AuthorizationSet && sw_enforced,keymaster_digest_t digest,EVP_PKEY * key)56 EcdsaSignOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, 57 keymaster_digest_t digest, EVP_PKEY* key) 58 : EcdsaOperation(move(hw_enforced), move(sw_enforced), KM_PURPOSE_SIGN, digest, key) {} 59 keymaster_error_t Begin(const AuthorizationSet& input_params, 60 AuthorizationSet* output_params) override; 61 keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input, 62 AuthorizationSet* output_params, Buffer* output, 63 size_t* input_consumed) override; 64 keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input, 65 const Buffer& signature, AuthorizationSet* output_params, 66 Buffer* output) override; 67 }; 68 69 class EcdsaVerifyOperation : public EcdsaOperation { 70 public: EcdsaVerifyOperation(AuthorizationSet && hw_enforced,AuthorizationSet && sw_enforced,keymaster_digest_t digest,EVP_PKEY * key)71 EcdsaVerifyOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, 72 keymaster_digest_t digest, EVP_PKEY* key) 73 : EcdsaOperation(move(hw_enforced), move(sw_enforced), KM_PURPOSE_VERIFY, digest, key) {} 74 keymaster_error_t Begin(const AuthorizationSet& input_params, 75 AuthorizationSet* output_params) override; 76 keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input, 77 AuthorizationSet* output_params, Buffer* output, 78 size_t* input_consumed) override; 79 keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input, 80 const Buffer& signature, AuthorizationSet* output_params, 81 Buffer* output) override; 82 }; 83 84 class Ed25519SignOperation : public EcdsaSignOperation { 85 public: Ed25519SignOperation(AuthorizationSet && hw_enforced,AuthorizationSet && sw_enforced,keymaster_digest_t digest,EVP_PKEY * key)86 Ed25519SignOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, 87 keymaster_digest_t digest, EVP_PKEY* key) 88 : EcdsaSignOperation(move(hw_enforced), move(sw_enforced), digest, key) {} 89 keymaster_error_t Begin(const AuthorizationSet& input_params, 90 AuthorizationSet* output_params) override; 91 keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input, 92 AuthorizationSet* output_params, Buffer* output, 93 size_t* input_consumed) override; 94 keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input, 95 const Buffer& signature, AuthorizationSet* output_params, 96 Buffer* output) override; 97 98 protected: 99 keymaster_error_t StoreAllData(const Buffer& input, size_t* input_consumed); 100 }; 101 102 class EcdsaOperationFactory : public OperationFactory { 103 private: registry_key()104 KeyType registry_key() const override { return KeyType(KM_ALGORITHM_EC, purpose()); } 105 OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params, 106 keymaster_error_t* error) override; 107 const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override; 108 109 virtual keymaster_purpose_t purpose() const = 0; 110 virtual Operation* InstantiateOperation(AuthorizationSet&& hw_enforced, 111 AuthorizationSet&& sw_enforced, 112 keymaster_digest_t digest, EVP_PKEY* key) = 0; 113 }; 114 115 class EcdsaSignOperationFactory : public EcdsaOperationFactory { 116 private: purpose()117 keymaster_purpose_t purpose() const override { return KM_PURPOSE_SIGN; } InstantiateOperation(AuthorizationSet && hw_enforced,AuthorizationSet && sw_enforced,keymaster_digest_t digest,EVP_PKEY * key)118 Operation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, 119 keymaster_digest_t digest, EVP_PKEY* key) override { 120 if (IsEd25519Key(hw_enforced, sw_enforced)) { 121 return new (std::nothrow) 122 Ed25519SignOperation(move(hw_enforced), move(sw_enforced), digest, key); 123 } else { 124 return new (std::nothrow) 125 EcdsaSignOperation(move(hw_enforced), move(sw_enforced), digest, key); 126 } 127 } 128 }; 129 130 class EcdsaVerifyOperationFactory : public EcdsaOperationFactory { 131 public: purpose()132 keymaster_purpose_t purpose() const override { return KM_PURPOSE_VERIFY; } InstantiateOperation(AuthorizationSet && hw_enforced,AuthorizationSet && sw_enforced,keymaster_digest_t digest,EVP_PKEY * key)133 Operation* InstantiateOperation(AuthorizationSet&& hw_enforced, AuthorizationSet&& sw_enforced, 134 keymaster_digest_t digest, EVP_PKEY* key) override { 135 return new (std::nothrow) 136 EcdsaVerifyOperation(move(hw_enforced), move(sw_enforced), digest, key); 137 } 138 }; 139 140 } // namespace keymaster 141 142 #endif // SYSTEM_KEYMASTER_ECDSA_OPERATION_H_ 143