xref: /aosp_15_r20/system/keymaster/km_openssl/block_cipher_operation.h (revision 789431f29546679ab5188a97751fb38e3018d44d)
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