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:
~EvpCipherDescription()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:
BlockCipherOperationFactory(keymaster_purpose_t purpose)48     explicit BlockCipherOperationFactory(keymaster_purpose_t purpose) : purpose_(purpose) {}
49 
registry_key()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 
SupportedBlockModes(size_t * block_mode_count)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);
block_size_bytes()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:
BlockCipherEvpEncryptOperation(keymaster_block_mode_t block_mode,keymaster_padding_t padding,bool caller_iv,size_t tag_length,Key && key,const EvpCipherDescription & cipher_description)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 
evp_encrypt_mode()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:
BlockCipherEvpDecryptOperation(keymaster_block_mode_t block_mode,keymaster_padding_t padding,size_t tag_length,Key && key,const EvpCipherDescription & cipher_description)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 
evp_encrypt_mode()156     int evp_encrypt_mode() override { return 0; }
157 
158   private:
tag_buf_unused()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