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