Home | History | Annotate | Download | only in km_openssl
      1 /*
      2  * Copyright 2018 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_BLOCK_CIPHER_OPERATION_H_
     18 #define SYSTEM_KEYMASTER_BLOCK_CIPHER_OPERATION_H_
     19 
     20 #include <openssl/evp.h>
     21 
     22 #include <keymaster/operation.h>
     23 
     24 namespace keymaster {
     25 
     26 /**
     27  * EvpCipherDescription is an abstract interface that provides information about a block cipher.
     28  */
     29 class EvpCipherDescription {
     30   public:
     31     virtual ~EvpCipherDescription() {}
     32     virtual keymaster_algorithm_t algorithm() const = 0;
     33 
     34     virtual const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const = 0;
     35 
     36     virtual const EVP_CIPHER* GetCipherInstance(size_t key_size, keymaster_block_mode_t block_mode,
     37                                                 keymaster_error_t* error) const = 0;
     38 
     39     virtual size_t block_size_bytes() const = 0;
     40 };
     41 
     42 /**
     43  * Abstract base for block cipher operation factories.  This class does all of the work to create
     44  * block cipher operations.
     45  */
     46 class BlockCipherOperationFactory : public OperationFactory {
     47   public:
     48     BlockCipherOperationFactory(keymaster_purpose_t purpose) : purpose_(purpose) {}
     49 
     50     KeyType registry_key() const override {
     51         return KeyType(GetCipherDescription().algorithm(), purpose_);
     52     }
     53 
     54     OperationPtr CreateOperation(Key&& key, const AuthorizationSet& begin_params,
     55                                  keymaster_error_t* error) override;
     56 
     57     const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const override {
     58         return GetCipherDescription().SupportedBlockModes(block_mode_count);
     59     }
     60 
     61     const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const override;
     62 
     63     virtual const EvpCipherDescription& GetCipherDescription() const = 0;
     64 
     65   private:
     66     const keymaster_purpose_t purpose_;
     67 };
     68 
     69 class BlockCipherEvpOperation : public Operation {
     70   public:
     71     BlockCipherEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
     72                             keymaster_padding_t padding, bool caller_iv, size_t tag_length,
     73                             Key&& key, const EvpCipherDescription& cipher_description);
     74     ~BlockCipherEvpOperation();
     75 
     76     keymaster_error_t Begin(const AuthorizationSet& input_params,
     77                             AuthorizationSet* output_params) override;
     78     keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
     79                              AuthorizationSet* output_params, Buffer* output,
     80                              size_t* input_consumed) override;
     81     keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
     82                              const Buffer& signature, AuthorizationSet* output_params,
     83                              Buffer* output) override;
     84     keymaster_error_t Abort() override;
     85 
     86   protected:
     87     virtual int evp_encrypt_mode() = 0;
     88 
     89     bool need_iv() const;
     90     keymaster_error_t InitializeCipher(KeymasterKeyBlob key);
     91     keymaster_error_t GetIv(const AuthorizationSet& input_params);
     92     bool HandleAad(const AuthorizationSet& input_params, const Buffer& input,
     93                    keymaster_error_t* error);
     94     bool ProcessAadBlocks(const uint8_t* data, size_t blocks, keymaster_error_t* error);
     95     void FillBufferedAadBlock(keymaster_blob_t* aad);
     96     bool ProcessBufferedAadBlock(keymaster_error_t* error);
     97     bool InternalUpdate(const uint8_t* input, size_t input_length, Buffer* output,
     98                         keymaster_error_t* error);
     99     bool UpdateForFinish(const AuthorizationSet& additional_params, const Buffer& input,
    100                          AuthorizationSet* output_params, Buffer* output, keymaster_error_t* error);
    101     size_t block_size_bytes() const { return cipher_description_.block_size_bytes(); }
    102 
    103     const keymaster_block_mode_t block_mode_;
    104     EVP_CIPHER_CTX ctx_;
    105     KeymasterBlob iv_;
    106     const bool caller_iv_;
    107     const size_t tag_length_;
    108 
    109   private:
    110     UniquePtr<uint8_t[]> aad_block_buf_;
    111     size_t aad_block_buf_len_;
    112     bool data_started_;
    113     const keymaster_padding_t padding_;
    114     KeymasterKeyBlob key_;
    115     const EvpCipherDescription& cipher_description_;
    116 };
    117 
    118 class BlockCipherEvpEncryptOperation : public BlockCipherEvpOperation {
    119   public:
    120     BlockCipherEvpEncryptOperation(keymaster_block_mode_t block_mode, keymaster_padding_t padding,
    121                                    bool caller_iv, size_t tag_length, Key&& key,
    122                                    const EvpCipherDescription& cipher_description)
    123         : BlockCipherEvpOperation(KM_PURPOSE_ENCRYPT, block_mode, padding, caller_iv, tag_length,
    124                                   move(key), cipher_description) {}
    125 
    126     keymaster_error_t Begin(const AuthorizationSet& input_params,
    127                             AuthorizationSet* output_params) override;
    128     keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
    129                              const Buffer& signature, AuthorizationSet* output_params,
    130                              Buffer* output) override;
    131 
    132     int evp_encrypt_mode() override { return 1; }
    133 
    134   private:
    135     keymaster_error_t GenerateIv();
    136 };
    137 
    138 class BlockCipherEvpDecryptOperation : public BlockCipherEvpOperation {
    139   public:
    140     BlockCipherEvpDecryptOperation(keymaster_block_mode_t block_mode, keymaster_padding_t padding,
    141                                    size_t tag_length, Key&& key,
    142                                    const EvpCipherDescription& cipher_description)
    143         : BlockCipherEvpOperation(KM_PURPOSE_DECRYPT, block_mode, padding,
    144                                   false /* caller_iv -- don't care */, tag_length, move(key),
    145                                   cipher_description) {}
    146 
    147     keymaster_error_t Begin(const AuthorizationSet& input_params,
    148                             AuthorizationSet* output_params) override;
    149     keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
    150                              AuthorizationSet* output_params, Buffer* output,
    151                              size_t* input_consumed) override;
    152     keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
    153                              const Buffer& signature, AuthorizationSet* output_params,
    154                              Buffer* output) override;
    155 
    156     int evp_encrypt_mode() override { return 0; }
    157 
    158   private:
    159     size_t tag_buf_unused() { return tag_length_ - tag_buf_len_; }
    160 
    161     keymaster_error_t ProcessAllButTagLengthBytes(const Buffer& input, Buffer* output);
    162     bool ProcessTagBufContentsAsData(size_t to_process, Buffer* output, keymaster_error_t* error);
    163     void BufferCandidateTagData(const uint8_t* data, size_t data_length);
    164 
    165     UniquePtr<uint8_t[]> tag_buf_;
    166     size_t tag_buf_len_;
    167 };
    168 
    169 }  // namespace keymaster
    170 
    171 #endif  // SYSTEM_KEYMASTER_BLOCK_CIPHER_OPERATION_H_
    172