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