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 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 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 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 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 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 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 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 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 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 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 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 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