• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2016, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #include "keystore_aidl_hidl_marshalling_utils.h"
19 
20 #include <keystore/ExportResult.h>
21 #include <keystore/KeyCharacteristics.h>
22 #include <keystore/KeymasterBlob.h>
23 #include <keystore/KeymasterCertificateChain.h>
24 #include <keystore/keymaster_types.h>
25 #include <keystore/keystore_hidl_support.h>
26 
27 namespace keystore {
28 
29 // reads byte[]
readKeymasterBlob(const android::Parcel & in)30 hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in) {
31 
32     ssize_t length = in.readInt32();
33     if (length <= 0) {
34         return {};
35     }
36 
37     const void* buf = in.readInplace(length);
38     if (!buf) return {};
39 
40     return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length));
41 }
42 
writeKeymasterBlob(const hidl_vec<uint8_t> & blob,android::Parcel * out)43 android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out) {
44     int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max()));
45 
46     auto rc = out->writeInt32(size);
47     if (rc != ::android::OK) return rc;
48 
49     if (!size) return ::android::OK;
50 
51     return out->write(blob.data(), size);
52 }
53 
writeKeymasterBlob(const::std::vector<int32_t> & blob,android::Parcel * out)54 android::status_t writeKeymasterBlob(const ::std::vector<int32_t>& blob, android::Parcel* out) {
55 
56     int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max()));
57 
58     auto rc = out->writeInt32(size);
59     if (rc != ::android::OK) return rc;
60 
61     if (!size) return ::android::OK;
62 
63     return out->write(blob.data(), size);
64 }
65 
readKeyParameterFromParcel(const android::Parcel & in)66 NullOr<KeyParameter> readKeyParameterFromParcel(const android::Parcel& in) {
67     // Method must be in sync with KeymasterArgument.java
68     if (in.readInt32() == 0) {
69         return {};
70     }
71     KeyParameter result;
72 
73     Tag tag = static_cast<Tag>(in.readInt32());
74     result.tag = tag;
75     switch (typeFromTag(tag)) {
76     case TagType::ENUM:
77     case TagType::ENUM_REP:
78     case TagType::UINT:
79     case TagType::UINT_REP:
80         result.f.integer = in.readInt32();
81         break;
82     case TagType::ULONG:
83     case TagType::ULONG_REP:
84     case TagType::DATE:
85         result.f.longInteger = in.readInt64();
86         break;
87     case TagType::BOOL:
88         result.f.boolValue = true;
89         break;
90     case TagType::BIGNUM:
91     case TagType::BYTES:
92         result.blob = readKeymasterBlob(in);  // byte array
93         break;
94     default:
95         ALOGE("Unsupported KeyParameter tag %d", tag);
96         return {};
97     }
98     return result;
99 }
100 
writeKeyParameterToParcel(const KeyParameter & param,android::Parcel * out)101 android::status_t writeKeyParameterToParcel(const KeyParameter& param, android::Parcel* out) {
102     // Method must be in sync with with KeymasterArgument.java
103     // Presence flag must be written by caller.
104 
105     auto tag = param.tag;
106     auto rc = out->writeInt32(uint32_t(tag));
107     if (rc != ::android::OK) return rc;
108     switch (typeFromTag(param.tag)) {
109     case TagType::ENUM:
110     case TagType::ENUM_REP:
111     case TagType::UINT:
112     case TagType::UINT_REP:
113         rc = out->writeInt32(param.f.integer);
114         break;
115     case TagType::ULONG:
116     case TagType::ULONG_REP:
117     case TagType::DATE:
118         rc = out->writeInt64(param.f.longInteger);
119         break;
120     case TagType::BOOL:
121         // nothing to do here presence indicates true
122         break;
123     case TagType::BIGNUM:
124     case TagType::BYTES:
125         rc = writeKeymasterBlob(param.blob, out);
126         break;
127     default:
128         ALOGE("Failed to write KeyParameter: Unsupported tag %d", param.tag);
129         rc = android::BAD_VALUE;
130         break;
131     }
132     return rc;
133 }
134 
readParamSetFromParcel(const android::Parcel & in)135 hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in) {
136 
137     ssize_t length = in.readInt32();  // -1 for null
138     size_t ulength = (size_t)length;
139     if (length < 0) {
140         ulength = 0;
141     }
142     hidl_vec<KeyParameter> result;
143     result.resize(ulength);
144     for (size_t i = 0; i < ulength; ++i) {
145         auto param = readKeyParameterFromParcel(in);
146         if (!param.isOk()) {
147             ALOGE("Error reading KeyParameter from parcel");
148             return {};
149         }
150         result[i] = param.value();
151     }
152     return result;
153 }
154 
writeParamSetToParcel(const hidl_vec<KeyParameter> & params,android::Parcel * out)155 android::status_t writeParamSetToParcel(const hidl_vec<KeyParameter>& params,
156                                         android::Parcel* out) {
157     int32_t size = int32_t(std::min<size_t>(params.size(), std::numeric_limits<int32_t>::max()));
158 
159     auto rc = out->writeInt32(size);
160     if (rc != ::android::OK) return rc;
161     for (int32_t i = 0; i < size; ++i) {
162         rc = out->writeInt32(1);  // writeTypedObject presence flag.
163         if (rc != ::android::OK) return rc;
164         rc = writeKeyParameterToParcel(params[i], out);
165         if (rc != ::android::OK) return rc;
166     }
167     return rc;
168 }
169 
readCertificateChainFromParcel(const android::Parcel & in)170 hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in) {
171     hidl_vec<hidl_vec<uint8_t>> result;
172 
173     ssize_t count = in.readInt32();
174     size_t ucount = count;
175     if (count <= 0) {
176         return result;
177     }
178 
179     result.resize(ucount);
180 
181     for (size_t i = 0; i < ucount; ++i) {
182         result[i] = readKeymasterBlob(in);
183     }
184     return result;
185 };
186 
writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>> & certs,android::Parcel * out)187 android::status_t writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>>& certs,
188                                                 android::Parcel* out) {
189     int32_t count = int32_t(std::min<size_t>(certs.size(), std::numeric_limits<int32_t>::max()));
190     auto rc = out->writeInt32(count);
191 
192     for (int32_t i = 0; i < count; ++i) {
193         rc = writeKeymasterBlob(certs[i], out);
194         if (rc != ::android::OK) return rc;
195     }
196     return rc;
197 }
198 
199 };  // namespace keystore
200 
201 // Implementation for  keystore parcelables.
202 // TODO: split implementation into separate classes
203 namespace android {
204 namespace security {
205 namespace keymaster {
206 
207 using ::android::status_t;
208 using ::keystore::keymaster::ErrorCode;
209 
ExportResult()210 ExportResult::ExportResult() : resultCode() {}
211 
~ExportResult()212 ExportResult::~ExportResult() {}
213 
readFromParcel(const Parcel * inn)214 status_t ExportResult::readFromParcel(const Parcel* inn) {
215     const Parcel& in = *inn;
216     resultCode = ErrorCode(in.readInt32());
217     exportData = keystore::readKeymasterBlob(in);
218     return OK;
219 }
220 
writeToParcel(Parcel * out) const221 status_t ExportResult::writeToParcel(Parcel* out) const {
222     out->writeInt32(resultCode.getErrorCode());
223     return keystore::writeKeymasterBlob(exportData, out);
224 }
225 
readFromParcel(const Parcel * in)226 status_t KeyCharacteristics::readFromParcel(const Parcel* in) {
227     softwareEnforced.readFromParcel(in);
228     return hardwareEnforced.readFromParcel(in);
229 }
230 
writeToParcel(Parcel * out) const231 status_t KeyCharacteristics::writeToParcel(Parcel* out) const {
232     softwareEnforced.writeToParcel(out);
233     return hardwareEnforced.writeToParcel(out);
234 }
235 
readFromParcel(const Parcel * in)236 status_t KeymasterBlob::readFromParcel(const Parcel* in) {
237     data_ = keystore::readKeymasterBlob(*in);
238     return OK;
239 }
240 
writeToParcel(Parcel * out) const241 status_t KeymasterBlob::writeToParcel(Parcel* out) const {
242     return keystore::writeKeymasterBlob(data_, out);
243 }
244 
readFromParcel(const Parcel * in)245 status_t KeymasterCertificateChain::readFromParcel(const Parcel* in) {
246     chain = keystore::readCertificateChainFromParcel(*in);
247     return OK;
248 }
249 
writeToParcel(Parcel * out) const250 status_t KeymasterCertificateChain::writeToParcel(Parcel* out) const {
251     return keystore::writeCertificateChainToParcel(chain, out);
252 }
253 
254 }  // namespace keymaster
255 }  // namespace security
256 
257 }  // namespace android
258