1*789431f2SAndroid Build Coastguard Worker /* 2*789431f2SAndroid Build Coastguard Worker * Copyright 2018 The Android Open Source Project 3*789431f2SAndroid Build Coastguard Worker * 4*789431f2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*789431f2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*789431f2SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*789431f2SAndroid Build Coastguard Worker * 8*789431f2SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*789431f2SAndroid Build Coastguard Worker * 10*789431f2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*789431f2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*789431f2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*789431f2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*789431f2SAndroid Build Coastguard Worker * limitations under the License. 15*789431f2SAndroid Build Coastguard Worker */ 16*789431f2SAndroid Build Coastguard Worker 17*789431f2SAndroid Build Coastguard Worker #ifndef SYSTEM_KEYMASTER_BLOCK_CIPHER_OPERATION_H_ 18*789431f2SAndroid Build Coastguard Worker #define SYSTEM_KEYMASTER_BLOCK_CIPHER_OPERATION_H_ 19*789431f2SAndroid Build Coastguard Worker 20*789431f2SAndroid Build Coastguard Worker #include <utility> 21*789431f2SAndroid Build Coastguard Worker 22*789431f2SAndroid Build Coastguard Worker #include <openssl/evp.h> 23*789431f2SAndroid Build Coastguard Worker 24*789431f2SAndroid Build Coastguard Worker #include <keymaster/operation.h> 25*789431f2SAndroid Build Coastguard Worker 26*789431f2SAndroid Build Coastguard Worker namespace keymaster { 27*789431f2SAndroid Build Coastguard Worker 28*789431f2SAndroid Build Coastguard Worker /** 29*789431f2SAndroid Build Coastguard Worker * EvpCipherDescription is an abstract interface that provides information about a block cipher. 30*789431f2SAndroid Build Coastguard Worker */ 31*789431f2SAndroid Build Coastguard Worker class EvpCipherDescription { 32*789431f2SAndroid Build Coastguard Worker public: ~EvpCipherDescription()33*789431f2SAndroid Build Coastguard Worker virtual ~EvpCipherDescription() {} 34*789431f2SAndroid Build Coastguard Worker virtual keymaster_algorithm_t algorithm() const = 0; 35*789431f2SAndroid Build Coastguard Worker 36*789431f2SAndroid Build Coastguard Worker virtual const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const = 0; 37*789431f2SAndroid Build Coastguard Worker 38*789431f2SAndroid Build Coastguard Worker virtual const EVP_CIPHER* GetCipherInstance(size_t key_size, keymaster_block_mode_t block_mode, 39*789431f2SAndroid Build Coastguard Worker keymaster_error_t* error) const = 0; 40*789431f2SAndroid Build Coastguard Worker 41*789431f2SAndroid Build Coastguard Worker virtual size_t block_size_bytes() const = 0; 42*789431f2SAndroid Build Coastguard Worker }; 43*789431f2SAndroid Build Coastguard Worker 44*789431f2SAndroid Build Coastguard Worker /** 45*789431f2SAndroid Build Coastguard Worker * Abstract base for block cipher operation factories. This class does all of the work to create 46*789431f2SAndroid Build Coastguard Worker * block cipher operations. 47*789431f2SAndroid Build Coastguard Worker */ 48*789431f2SAndroid Build Coastguard Worker class BlockCipherOperationFactory : public OperationFactory { 49*789431f2SAndroid Build Coastguard Worker public: BlockCipherOperationFactory(keymaster_purpose_t purpose)50*789431f2SAndroid Build Coastguard Worker explicit BlockCipherOperationFactory(keymaster_purpose_t purpose) : purpose_(purpose) {} 51*789431f2SAndroid Build Coastguard Worker registry_key()52*789431f2SAndroid Build Coastguard Worker KeyType registry_key() const override { 53*789431f2SAndroid Build Coastguard Worker return KeyType(GetCipherDescription().algorithm(), purpose_); 54*789431f2SAndroid Build Coastguard Worker } 55*789431f2SAndroid Build Coastguard Worker 56*789431f2SAndroid Build Coastguard Worker OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params, 57*789431f2SAndroid Build Coastguard Worker keymaster_error_t* error) override; 58*789431f2SAndroid Build Coastguard Worker SupportedBlockModes(size_t * block_mode_count)59*789431f2SAndroid Build Coastguard Worker const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const override { 60*789431f2SAndroid Build Coastguard Worker return GetCipherDescription().SupportedBlockModes(block_mode_count); 61*789431f2SAndroid Build Coastguard Worker } 62*789431f2SAndroid Build Coastguard Worker 63*789431f2SAndroid Build Coastguard Worker const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const override; 64*789431f2SAndroid Build Coastguard Worker 65*789431f2SAndroid Build Coastguard Worker virtual const EvpCipherDescription& GetCipherDescription() const = 0; 66*789431f2SAndroid Build Coastguard Worker 67*789431f2SAndroid Build Coastguard Worker private: 68*789431f2SAndroid Build Coastguard Worker const keymaster_purpose_t purpose_; 69*789431f2SAndroid Build Coastguard Worker }; 70*789431f2SAndroid Build Coastguard Worker 71*789431f2SAndroid Build Coastguard Worker class BlockCipherEvpOperation : public Operation { 72*789431f2SAndroid Build Coastguard Worker public: 73*789431f2SAndroid Build Coastguard Worker BlockCipherEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode, 74*789431f2SAndroid Build Coastguard Worker keymaster_padding_t padding, bool caller_iv, size_t tag_length, 75*789431f2SAndroid Build Coastguard Worker Key&& key, const EvpCipherDescription& cipher_description); 76*789431f2SAndroid Build Coastguard Worker ~BlockCipherEvpOperation(); 77*789431f2SAndroid Build Coastguard Worker 78*789431f2SAndroid Build Coastguard Worker keymaster_error_t Begin(const AuthorizationSet& input_params, 79*789431f2SAndroid Build Coastguard Worker AuthorizationSet* output_params) override; 80*789431f2SAndroid Build Coastguard Worker keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input, 81*789431f2SAndroid Build Coastguard Worker AuthorizationSet* output_params, Buffer* output, 82*789431f2SAndroid Build Coastguard Worker size_t* input_consumed) override; 83*789431f2SAndroid Build Coastguard Worker keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input, 84*789431f2SAndroid Build Coastguard Worker const Buffer& signature, AuthorizationSet* output_params, 85*789431f2SAndroid Build Coastguard Worker Buffer* output) override; 86*789431f2SAndroid Build Coastguard Worker keymaster_error_t Abort() override; 87*789431f2SAndroid Build Coastguard Worker 88*789431f2SAndroid Build Coastguard Worker protected: 89*789431f2SAndroid Build Coastguard Worker virtual int evp_encrypt_mode() = 0; 90*789431f2SAndroid Build Coastguard Worker 91*789431f2SAndroid Build Coastguard Worker bool need_iv() const; 92*789431f2SAndroid Build Coastguard Worker keymaster_error_t InitializeCipher(const KeymasterKeyBlob& key); 93*789431f2SAndroid Build Coastguard Worker keymaster_error_t GetIv(const AuthorizationSet& input_params); 94*789431f2SAndroid Build Coastguard Worker bool HandleAad(const AuthorizationSet& input_params, const Buffer& input, 95*789431f2SAndroid Build Coastguard Worker keymaster_error_t* error); 96*789431f2SAndroid Build Coastguard Worker bool ProcessAadBlocks(const uint8_t* data, size_t blocks, keymaster_error_t* error); 97*789431f2SAndroid Build Coastguard Worker void FillBufferedAadBlock(keymaster_blob_t* aad); 98*789431f2SAndroid Build Coastguard Worker bool ProcessBufferedAadBlock(keymaster_error_t* error); 99*789431f2SAndroid Build Coastguard Worker bool InternalUpdate(const uint8_t* input, size_t input_length, Buffer* output, 100*789431f2SAndroid Build Coastguard Worker keymaster_error_t* error); 101*789431f2SAndroid Build Coastguard Worker bool UpdateForFinish(const AuthorizationSet& additional_params, const Buffer& input, 102*789431f2SAndroid Build Coastguard Worker AuthorizationSet* output_params, Buffer* output, keymaster_error_t* error); block_size_bytes()103*789431f2SAndroid Build Coastguard Worker size_t block_size_bytes() const { return cipher_description_.block_size_bytes(); } 104*789431f2SAndroid Build Coastguard Worker 105*789431f2SAndroid Build Coastguard Worker const keymaster_block_mode_t block_mode_; 106*789431f2SAndroid Build Coastguard Worker EVP_CIPHER_CTX ctx_; 107*789431f2SAndroid Build Coastguard Worker KeymasterBlob iv_; 108*789431f2SAndroid Build Coastguard Worker const bool caller_iv_; 109*789431f2SAndroid Build Coastguard Worker const size_t tag_length_; 110*789431f2SAndroid Build Coastguard Worker 111*789431f2SAndroid Build Coastguard Worker private: 112*789431f2SAndroid Build Coastguard Worker UniquePtr<uint8_t[]> aad_block_buf_; 113*789431f2SAndroid Build Coastguard Worker size_t aad_block_buf_len_; 114*789431f2SAndroid Build Coastguard Worker bool data_started_; 115*789431f2SAndroid Build Coastguard Worker const keymaster_padding_t padding_; 116*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob key_; 117*789431f2SAndroid Build Coastguard Worker const EvpCipherDescription& cipher_description_; 118*789431f2SAndroid Build Coastguard Worker }; 119*789431f2SAndroid Build Coastguard Worker 120*789431f2SAndroid Build Coastguard Worker class BlockCipherEvpEncryptOperation : public BlockCipherEvpOperation { 121*789431f2SAndroid Build Coastguard Worker public: BlockCipherEvpEncryptOperation(keymaster_block_mode_t block_mode,keymaster_padding_t padding,bool caller_iv,size_t tag_length,Key && key,const EvpCipherDescription & cipher_description)122*789431f2SAndroid Build Coastguard Worker BlockCipherEvpEncryptOperation(keymaster_block_mode_t block_mode, keymaster_padding_t padding, 123*789431f2SAndroid Build Coastguard Worker bool caller_iv, size_t tag_length, Key&& key, 124*789431f2SAndroid Build Coastguard Worker const EvpCipherDescription& cipher_description) 125*789431f2SAndroid Build Coastguard Worker : BlockCipherEvpOperation(KM_PURPOSE_ENCRYPT, block_mode, padding, caller_iv, tag_length, 126*789431f2SAndroid Build Coastguard Worker std::move(key), cipher_description) {} 127*789431f2SAndroid Build Coastguard Worker 128*789431f2SAndroid Build Coastguard Worker keymaster_error_t Begin(const AuthorizationSet& input_params, 129*789431f2SAndroid Build Coastguard Worker AuthorizationSet* output_params) override; 130*789431f2SAndroid Build Coastguard Worker keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input, 131*789431f2SAndroid Build Coastguard Worker const Buffer& signature, AuthorizationSet* output_params, 132*789431f2SAndroid Build Coastguard Worker Buffer* output) override; 133*789431f2SAndroid Build Coastguard Worker evp_encrypt_mode()134*789431f2SAndroid Build Coastguard Worker int evp_encrypt_mode() override { return 1; } 135*789431f2SAndroid Build Coastguard Worker 136*789431f2SAndroid Build Coastguard Worker private: 137*789431f2SAndroid Build Coastguard Worker keymaster_error_t GenerateIv(); 138*789431f2SAndroid Build Coastguard Worker }; 139*789431f2SAndroid Build Coastguard Worker 140*789431f2SAndroid Build Coastguard Worker class BlockCipherEvpDecryptOperation : public BlockCipherEvpOperation { 141*789431f2SAndroid Build Coastguard Worker public: BlockCipherEvpDecryptOperation(keymaster_block_mode_t block_mode,keymaster_padding_t padding,size_t tag_length,Key && key,const EvpCipherDescription & cipher_description)142*789431f2SAndroid Build Coastguard Worker BlockCipherEvpDecryptOperation(keymaster_block_mode_t block_mode, keymaster_padding_t padding, 143*789431f2SAndroid Build Coastguard Worker size_t tag_length, Key&& key, 144*789431f2SAndroid Build Coastguard Worker const EvpCipherDescription& cipher_description) 145*789431f2SAndroid Build Coastguard Worker : BlockCipherEvpOperation(KM_PURPOSE_DECRYPT, block_mode, padding, 146*789431f2SAndroid Build Coastguard Worker false /* caller_iv -- don't care */, tag_length, std::move(key), 147*789431f2SAndroid Build Coastguard Worker cipher_description) {} 148*789431f2SAndroid Build Coastguard Worker 149*789431f2SAndroid Build Coastguard Worker keymaster_error_t Begin(const AuthorizationSet& input_params, 150*789431f2SAndroid Build Coastguard Worker AuthorizationSet* output_params) override; 151*789431f2SAndroid Build Coastguard Worker keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input, 152*789431f2SAndroid Build Coastguard Worker AuthorizationSet* output_params, Buffer* output, 153*789431f2SAndroid Build Coastguard Worker size_t* input_consumed) override; 154*789431f2SAndroid Build Coastguard Worker keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input, 155*789431f2SAndroid Build Coastguard Worker const Buffer& signature, AuthorizationSet* output_params, 156*789431f2SAndroid Build Coastguard Worker Buffer* output) override; 157*789431f2SAndroid Build Coastguard Worker evp_encrypt_mode()158*789431f2SAndroid Build Coastguard Worker int evp_encrypt_mode() override { return 0; } 159*789431f2SAndroid Build Coastguard Worker 160*789431f2SAndroid Build Coastguard Worker private: tag_buf_unused()161*789431f2SAndroid Build Coastguard Worker size_t tag_buf_unused() { return tag_length_ - tag_buf_len_; } 162*789431f2SAndroid Build Coastguard Worker 163*789431f2SAndroid Build Coastguard Worker keymaster_error_t ProcessAllButTagLengthBytes(const Buffer& input, Buffer* output); 164*789431f2SAndroid Build Coastguard Worker bool ProcessTagBufContentsAsData(size_t to_process, Buffer* output, keymaster_error_t* error); 165*789431f2SAndroid Build Coastguard Worker void BufferCandidateTagData(const uint8_t* data, size_t data_length); 166*789431f2SAndroid Build Coastguard Worker 167*789431f2SAndroid Build Coastguard Worker UniquePtr<uint8_t[]> tag_buf_; 168*789431f2SAndroid Build Coastguard Worker size_t tag_buf_len_; 169*789431f2SAndroid Build Coastguard Worker }; 170*789431f2SAndroid Build Coastguard Worker 171*789431f2SAndroid Build Coastguard Worker } // namespace keymaster 172*789431f2SAndroid Build Coastguard Worker 173*789431f2SAndroid Build Coastguard Worker #endif // SYSTEM_KEYMASTER_BLOCK_CIPHER_OPERATION_H_ 174