Home | History | Annotate | Download | only in keystore
      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