1 /*
2  * Copyright 2020, 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  *
18  *  The original Work has been changed by NXP.
19  *
20  *  Licensed under the Apache License, Version 2.0 (the "License");
21  *  you may not use this file except in compliance with the License.
22  *  You may obtain a copy of the License at
23  *
24  *  http://www.apache.org/licenses/LICENSE-2.0
25  *
26  *  Unless required by applicable law or agreed to in writing, software
27  *  distributed under the License is distributed on an "AS IS" BASIS,
28  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29  *  See the License for the specific language governing permissions and
30  *  limitations under the License.
31  *
32  *  Copyright 2023-2024 NXP
33  *
34  ******************************************************************************/
35 
36 #pragma once
37 
38 #include "CborConverter.h"
39 #include "JavacardSecureElement.h"
40 
41 #include <aidl/android/hardware/security/keymint/BnKeyMintOperation.h>
42 #include <aidl/android/hardware/security/secureclock/ISecureClock.h>
43 #include <hardware/keymaster_defs.h>
44 #include <vector>
45 
46 #define AES_BLOCK_SIZE 16
47 #define DES_BLOCK_SIZE 8
48 #define RSA_BUFFER_SIZE 256
49 #define EC_BUFFER_SIZE 32
50 #define MAX_CHUNK_SIZE 256
51 namespace aidl::android::hardware::security::keymint {
52 using cppbor::Array;
53 using cppbor::Item;
54 using ::keymint::javacard::CborConverter;
55 using ::keymint::javacard::Instruction;
56 using ::keymint::javacard::JavacardSecureElement;
57 using ::ndk::ScopedAStatus;
58 using secureclock::TimeStampToken;
59 using std::optional;
60 using std::shared_ptr;
61 using std::string;
62 using std::vector;
63 
64 // Bufferig modes for update
65 enum class BufferingMode : int32_t {
66     NONE = 0,           // Send everything to javacard - most of the assymteric operations
67     RSA_NO_DIGEST = 1,  // Buffer everything in update upto 256 bytes and send in finish. If
68                         // input data is greater than 256 bytes than it is an error. Javacard
69                         // will further check according to exact key size and crypto provider.
70     EC_NO_DIGEST = 2,   // Buffer upto 65 bytes and then truncate. Javacard will further truncate
71                         // upto exact keysize.
72     BUF_AES_ENCRYPT_PKCS7_BLOCK_ALIGNED = 3, // Buffer 16 bytes.
73     BUF_AES_DECRYPT_PKCS7_BLOCK_ALIGNED = 4, // Buffer 16 bytes.
74     BUF_DES_ENCRYPT_PKCS7_BLOCK_ALIGNED = 5, // Buffer 8 bytes.
75     BUF_DES_DECRYPT_PKCS7_BLOCK_ALIGNED = 6, // Buffer 8 bytes.
76     BUF_AES_GCM_DECRYPT_BLOCK_ALIGNED = 7, // Buffer 16 bytes.
77 
78 };
79 
80 // The is the view in the input data being processed by update/finish funcion.
81 
82 struct DataView {
83     vector<uint8_t> buffer;       // previously buffered data from cycle n-1
84     const vector<uint8_t>& data;  // current data in cycle n.
85     uint32_t start;               // start of the view
86     size_t length;                // length of the view
87 };
88 
89 class JavacardKeyMintOperation : public BnKeyMintOperation {
90   public:
JavacardKeyMintOperation(keymaster_operation_handle_t opHandle,BufferingMode bufferingMode,uint16_t macLength,shared_ptr<JavacardSecureElement> card)91     explicit JavacardKeyMintOperation(keymaster_operation_handle_t opHandle,
92                                       BufferingMode bufferingMode,
93                                       uint16_t macLength,
94                                       shared_ptr<JavacardSecureElement> card)
95         : buffer_(vector<uint8_t>()), bufferingMode_(bufferingMode),
96           macLength_(macLength), card_(std::move(card)), opHandle_(opHandle) {
97 #ifdef NXP_EXTNS
98         card_->setOperationState(
99             ::keymint::javacard::CryptoOperationState::STARTED);
100 #endif
101     }
102     virtual ~JavacardKeyMintOperation();
103 
104     ScopedAStatus updateAad(const vector<uint8_t>& input,
105                             const optional<HardwareAuthToken>& authToken,
106                             const optional<TimeStampToken>& timestampToken) override;
107 
108     ScopedAStatus update(const vector<uint8_t>& input, const optional<HardwareAuthToken>& authToken,
109                          const optional<TimeStampToken>& timestampToken,
110                          vector<uint8_t>* output) override;
111 
112     ScopedAStatus finish(const optional<vector<uint8_t>>& input,
113                          const optional<vector<uint8_t>>& signature,
114                          const optional<HardwareAuthToken>& authToken,
115                          const optional<TimeStampToken>& timestampToken,
116                          const optional<vector<uint8_t>>& confirmationToken,
117                          vector<uint8_t>* output) override;
118 
119     ScopedAStatus abort() override;
120 
121   private:
122     vector<uint8_t> popNextChunk(DataView& view, uint32_t chunkSize);
123 
124     keymaster_error_t updateInChunks(DataView& data, HardwareAuthToken& authToken,
125                                      TimeStampToken& timestampToken, vector<uint8_t>* output);
126 
127     keymaster_error_t sendFinish(const vector<uint8_t>& data, const vector<uint8_t>& signature,
128                                  const HardwareAuthToken& authToken,
129                                  const TimeStampToken& timestampToken, const vector<uint8_t>& confToken, vector<uint8_t>& output);
130 
131     keymaster_error_t sendUpdate(const vector<uint8_t>& data, const HardwareAuthToken& authToken,
132                                  const TimeStampToken& timestampToken, vector<uint8_t>& output);
133 
appendBufferedData(DataView & view)134     inline void appendBufferedData(DataView& view) {
135         if (!buffer_.empty()) {
136             view.buffer = buffer_;
137             view.length = view.length + buffer_.size();
138             view.start = 0;
139             // view.buffer = insert(data.begin(), buffer_.begin(), buffer_.end());
140             buffer_.clear();
141         }
142     }
143 
144     std::tuple<std::unique_ptr<Item>, keymaster_error_t> sendRequest(Instruction ins,
145                                                                      Array& request);
146     keymaster_error_t bufferData(DataView& data);
147     void blockAlign(DataView& data, uint16_t blockSize);
148     uint16_t getDataViewOffset(DataView& view, uint16_t blockSize);
149 
150     vector<uint8_t> buffer_;
151     BufferingMode bufferingMode_;
152     uint16_t macLength_;
153     const shared_ptr<JavacardSecureElement> card_;
154     keymaster_operation_handle_t opHandle_;
155     CborConverter cbor_;
156 };
157 
158 }  // namespace aidl::android::hardware::security::keymint
159