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 #define LOG_TAG "KeystoreService"
19 #include <utils/Log.h>
20 
21 #include "keystore_aidl_hidl_marshalling_utils.h"
22 #include <keystore/keystore_hidl_support.h>
23 
24 namespace keystore {
25 
readKeymasterBlob(const android::Parcel & in,bool inPlace)26 hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in, bool inPlace) {
27     ssize_t length = in.readInt32();
28     if (length <= 0) {
29         return {};
30     }
31 
32     const void* buf = in.readInplace(length);
33     if (!buf) return {};
34 
35     return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length), inPlace);
36 }
37 
writeKeymasterBlob(const hidl_vec<uint8_t> & blob,android::Parcel * out)38 android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out) {
39     int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max()));
40 
41     auto rc = out->writeInt32(size);
42     if (rc != ::android::OK) return rc;
43 
44     if (!size) return ::android::OK;
45 
46     return out->write(&blob[0], size);
47 }
48 
readBlobAsByteArray(const android::Parcel & in,bool inPlace)49 NullOr<hidl_vec<uint8_t>> readBlobAsByteArray(const android::Parcel& in, bool inPlace) {
50     // The distinction from readKeymasterBob is that the byte array is not prefixed with a presence
51     // value, instead a -1 in the length field indicates NULL.
52     ssize_t length = in.readInt32();
53     if (length < 0) {
54         return {};
55     }
56 
57     if (length == 0) {
58         return hidl_vec<uint8_t>();
59     }
60 
61     const void* buf = in.readInplace(length);
62     if (!buf) return hidl_vec<uint8_t>();
63 
64     return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length), inPlace);
65 }
66 
writeBlobAsByteArray(const NullOr<const hidl_vec<uint8_t> &> & blob,android::Parcel * out)67 android::status_t writeBlobAsByteArray(const NullOr<const hidl_vec<uint8_t>&>& blob,
68                                        android::Parcel* out) {
69     if (!blob.isOk()) {
70         return out->writeInt32(-1);
71     }
72     int32_t size =
73         int32_t(std::min<size_t>(blob.value().size(), std::numeric_limits<int32_t>::max()));
74 
75     auto rc = out->writeInt32(size);
76     if (rc != ::android::OK) return rc;
77 
78     if (!size) return ::android::OK;
79 
80     return out->write(&blob.value()[0], size);
81 }
82 
readKeyParameterFromParcel(const android::Parcel & in)83 NullOr<KeyParameter> readKeyParameterFromParcel(const android::Parcel& in) {
84     if (in.readInt32() == 0) {
85         return {};
86     }
87     KeyParameter result;
88 
89     Tag tag = static_cast<Tag>(in.readInt32());
90     result.tag = tag;
91     switch (typeFromTag(tag)) {
92     case TagType::ENUM:
93     case TagType::ENUM_REP:
94     case TagType::UINT:
95     case TagType::UINT_REP:
96         result.f.integer = in.readInt32();
97         break;
98     case TagType::ULONG:
99     case TagType::ULONG_REP:
100     case TagType::DATE:
101         result.f.longInteger = in.readInt64();
102         break;
103     case TagType::BOOL:
104         result.f.boolValue = true;
105         break;
106     case TagType::BIGNUM:
107     case TagType::BYTES:
108         result.blob = readKeymasterBlob(in);
109         break;
110     default:
111         ALOGE("Unsupported KeyParameter tag %d", tag);
112         return {};
113     }
114     return result;
115 }
116 
writeKeyParameterToParcel(const KeyParameter & param,android::Parcel * out)117 android::status_t writeKeyParameterToParcel(const KeyParameter& param, android::Parcel* out) {
118     auto tag = param.tag;
119     auto rc = out->writeInt32(uint32_t(tag));
120     if (rc != ::android::OK) return rc;
121     switch (typeFromTag(param.tag)) {
122     case TagType::ENUM:
123     case TagType::ENUM_REP:
124     case TagType::UINT:
125     case TagType::UINT_REP:
126         rc = out->writeInt32(param.f.integer);
127         break;
128     case TagType::ULONG:
129     case TagType::ULONG_REP:
130     case TagType::DATE:
131         rc = out->writeInt64(param.f.longInteger);
132         break;
133     case TagType::BOOL:
134         // nothing to do here presence indicates true
135         break;
136     case TagType::BIGNUM:
137     case TagType::BYTES:
138         rc = writeKeymasterBlob(param.blob, out);
139         break;
140     default:
141         ALOGE("Failed to write KeyParameter: Unsupported tag %d", param.tag);
142         rc = android::BAD_VALUE;
143         break;
144     }
145     return rc;
146 }
147 
readParamSetFromParcel(const android::Parcel & in)148 hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in) {
149     ssize_t length = in.readInt32();
150     size_t ulength = (size_t)length;
151     if (length < 0) {
152         ulength = 0;
153     }
154     hidl_vec<KeyParameter> result;
155     result.resize(ulength);
156     for (size_t i = 0; i < ulength; ++i) {
157         auto param = readKeyParameterFromParcel(in);
158         if (!param.isOk()) {
159             ALOGE("Error reading KeyParameter from parcel");
160             return {};
161         }
162         result[i] = param.value();
163     }
164     return result;
165 }
166 
writeParamSetToParcel(const hidl_vec<KeyParameter> & params,android::Parcel * out)167 android::status_t writeParamSetToParcel(const hidl_vec<KeyParameter>& params,
168                                         android::Parcel* out) {
169     int32_t size = int32_t(std::min<size_t>(params.size(), std::numeric_limits<int32_t>::max()));
170 
171     auto rc = out->writeInt32(size);
172     if (rc != ::android::OK) return rc;
173     for (int32_t i = 0; i < size; ++i) {
174         rc = out->writeInt32(1);
175         if (rc != ::android::OK) return rc;
176         rc = writeKeyParameterToParcel(params[i], out);
177         if (rc != ::android::OK) return rc;
178     }
179     return rc;
180 }
181 
readKeyCharacteristicsFromParcel(const android::Parcel & in)182 KeyCharacteristics readKeyCharacteristicsFromParcel(const android::Parcel& in) {
183     KeyCharacteristics result;
184     result.softwareEnforced = readParamSetFromParcel(in);
185     result.teeEnforced = readParamSetFromParcel(in);
186     return result;
187 }
188 
writeKeyCharacteristicsToParcel(const KeyCharacteristics & keyChara,android::Parcel * out)189 android::status_t writeKeyCharacteristicsToParcel(const KeyCharacteristics& keyChara,
190                                                   android::Parcel* out) {
191     auto rc = writeParamSetToParcel(keyChara.softwareEnforced, out);
192     if (rc != ::android::OK) return rc;
193 
194     return writeParamSetToParcel(keyChara.teeEnforced, out);
195 }
196 
readCertificateChainFromParcel(const android::Parcel & in)197 hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in) {
198     hidl_vec<hidl_vec<uint8_t>> result;
199 
200     ssize_t count = in.readInt32();
201     size_t ucount = count;
202     if (count <= 0) {
203         return result;
204     }
205 
206     result.resize(ucount);
207 
208     for (size_t i = 0; i < ucount; ++i) {
209         result[i] = readKeymasterBlob(in);
210     }
211     return result;
212 }
213 
writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>> & certs,android::Parcel * out)214 android::status_t writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>>& certs,
215                                                 android::Parcel* out) {
216     int32_t count = int32_t(std::min<size_t>(certs.size(), std::numeric_limits<int32_t>::max()));
217     auto rc = out->writeInt32(count);
218 
219     for (int32_t i = 0; i < count; ++i) {
220         rc = writeKeymasterBlob(certs[i], out);
221         if (rc != ::android::OK) return rc;
222     }
223     return rc;
224 }
225 }
226