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/KeystoreArg.h> 25 #include <keystore/keymaster_types.h> 26 #include <keystore/keystore_hidl_support.h> 27 28 namespace keystore { 29 30 // reads byte[] 31 hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in, bool inPlace) { 32 33 ssize_t length = in.readInt32(); 34 if (length <= 0) { 35 return {}; 36 } 37 38 const void* buf = in.readInplace(length); 39 if (!buf) return {}; 40 41 return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length), inPlace); 42 } 43 44 android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out) { 45 int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max())); 46 47 auto rc = out->writeInt32(size); 48 if (rc != ::android::OK) return rc; 49 50 if (!size) return ::android::OK; 51 52 return out->write(blob.data(), size); 53 } 54 55 android::status_t writeKeymasterBlob(const ::std::vector<int32_t>& blob, android::Parcel* out) { 56 57 int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max())); 58 59 auto rc = out->writeInt32(size); 60 if (rc != ::android::OK) return rc; 61 62 if (!size) return ::android::OK; 63 64 return out->write(blob.data(), size); 65 } 66 67 NullOr<KeyParameter> readKeyParameterFromParcel(const android::Parcel& in) { 68 // Method must be in sync with KeymasterArgument.java 69 if (in.readInt32() == 0) { 70 return {}; 71 } 72 KeyParameter result; 73 74 Tag tag = static_cast<Tag>(in.readInt32()); 75 result.tag = tag; 76 switch (typeFromTag(tag)) { 77 case TagType::ENUM: 78 case TagType::ENUM_REP: 79 case TagType::UINT: 80 case TagType::UINT_REP: 81 result.f.integer = in.readInt32(); 82 break; 83 case TagType::ULONG: 84 case TagType::ULONG_REP: 85 case TagType::DATE: 86 result.f.longInteger = in.readInt64(); 87 break; 88 case TagType::BOOL: 89 result.f.boolValue = true; 90 break; 91 case TagType::BIGNUM: 92 case TagType::BYTES: 93 result.blob = readKeymasterBlob(in); // byte array 94 break; 95 default: 96 ALOGE("Unsupported KeyParameter tag %d", tag); 97 return {}; 98 } 99 return result; 100 } 101 102 android::status_t writeKeyParameterToParcel(const KeyParameter& param, android::Parcel* out) { 103 // Method must be in sync with with KeymasterArgument.java 104 // Presence flag must be written by caller. 105 106 auto tag = param.tag; 107 auto rc = out->writeInt32(uint32_t(tag)); 108 if (rc != ::android::OK) return rc; 109 switch (typeFromTag(param.tag)) { 110 case TagType::ENUM: 111 case TagType::ENUM_REP: 112 case TagType::UINT: 113 case TagType::UINT_REP: 114 rc = out->writeInt32(param.f.integer); 115 break; 116 case TagType::ULONG: 117 case TagType::ULONG_REP: 118 case TagType::DATE: 119 rc = out->writeInt64(param.f.longInteger); 120 break; 121 case TagType::BOOL: 122 // nothing to do here presence indicates true 123 break; 124 case TagType::BIGNUM: 125 case TagType::BYTES: 126 rc = writeKeymasterBlob(param.blob, out); 127 break; 128 default: 129 ALOGE("Failed to write KeyParameter: Unsupported tag %d", param.tag); 130 rc = android::BAD_VALUE; 131 break; 132 } 133 return rc; 134 } 135 136 hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in) { 137 138 ssize_t length = in.readInt32(); // -1 for null 139 size_t ulength = (size_t)length; 140 if (length < 0) { 141 ulength = 0; 142 } 143 hidl_vec<KeyParameter> result; 144 result.resize(ulength); 145 for (size_t i = 0; i < ulength; ++i) { 146 auto param = readKeyParameterFromParcel(in); 147 if (!param.isOk()) { 148 ALOGE("Error reading KeyParameter from parcel"); 149 return {}; 150 } 151 result[i] = param.value(); 152 } 153 return result; 154 } 155 156 android::status_t writeParamSetToParcel(const hidl_vec<KeyParameter>& params, 157 android::Parcel* out) { 158 int32_t size = int32_t(std::min<size_t>(params.size(), std::numeric_limits<int32_t>::max())); 159 160 auto rc = out->writeInt32(size); 161 if (rc != ::android::OK) return rc; 162 for (int32_t i = 0; i < size; ++i) { 163 rc = out->writeInt32(1); // writeTypedObject presence flag. 164 if (rc != ::android::OK) return rc; 165 rc = writeKeyParameterToParcel(params[i], out); 166 if (rc != ::android::OK) return rc; 167 } 168 return rc; 169 } 170 171 hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in) { 172 hidl_vec<hidl_vec<uint8_t>> result; 173 174 ssize_t count = in.readInt32(); 175 size_t ucount = count; 176 if (count <= 0) { 177 return result; 178 } 179 180 result.resize(ucount); 181 182 for (size_t i = 0; i < ucount; ++i) { 183 result[i] = readKeymasterBlob(in); 184 } 185 return result; 186 }; 187 188 android::status_t writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>>& certs, 189 android::Parcel* out) { 190 int32_t count = int32_t(std::min<size_t>(certs.size(), std::numeric_limits<int32_t>::max())); 191 auto rc = out->writeInt32(count); 192 193 for (int32_t i = 0; i < count; ++i) { 194 rc = writeKeymasterBlob(certs[i], out); 195 if (rc != ::android::OK) return rc; 196 } 197 return rc; 198 } 199 200 }; // namespace keystore 201 202 // Implementation for keystore parcelables. 203 // TODO: split implementation into separate classes 204 namespace android { 205 namespace security { 206 namespace keymaster { 207 208 using ::android::status_t; 209 using ::keystore::keymaster::ErrorCode; 210 211 ExportResult::ExportResult() : resultCode() {} 212 213 ExportResult::~ExportResult() {} 214 215 status_t ExportResult::readFromParcel(const Parcel* inn) { 216 const Parcel& in = *inn; 217 resultCode = ErrorCode(in.readInt32()); 218 exportData = keystore::readKeymasterBlob(in); 219 return OK; 220 } 221 222 status_t ExportResult::writeToParcel(Parcel* out) const { 223 out->writeInt32(resultCode); 224 return keystore::writeKeymasterBlob(exportData, out); 225 } 226 227 status_t KeyCharacteristics::readFromParcel(const Parcel* in) { 228 softwareEnforced.readFromParcel(in); 229 return hardwareEnforced.readFromParcel(in); 230 } 231 232 status_t KeyCharacteristics::writeToParcel(Parcel* out) const { 233 softwareEnforced.writeToParcel(out); 234 return hardwareEnforced.writeToParcel(out); 235 } 236 237 status_t KeymasterBlob::readFromParcel(const Parcel* in) { 238 data_ = keystore::readKeymasterBlob(*in, true /* in place */); 239 return OK; 240 } 241 242 status_t KeymasterBlob::writeToParcel(Parcel* out) const { 243 return keystore::writeKeymasterBlob(data_, out); 244 } 245 246 status_t KeymasterCertificateChain::readFromParcel(const Parcel* in) { 247 chain = keystore::readCertificateChainFromParcel(*in); 248 return OK; 249 } 250 251 status_t KeymasterCertificateChain::writeToParcel(Parcel* out) const { 252 return keystore::writeCertificateChainToParcel(chain, out); 253 } 254 255 } // namespace keymaster 256 } // namespace security 257 258 } // namespace android 259