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