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