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