• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <../proto_utils.h>
18 
19 #include <MockKeymaster.client.h>
20 #include <KeymasterDevice.h>
21 
22 #include <keymasterV4_0/keymaster_tags.h>
23 
24 #include <android-base/logging.h>
25 #include <gtest/gtest.h>
26 
27 #include <openssl/evp.h>
28 #include <openssl/rsa.h>
29 #include <openssl/pkcs8.h>
30 
31 #include <string>
32 
33 using ::std::string;
34 using ::std::unique_ptr;
35 
36 using ::testing::_;
37 using ::testing::DoAll;
38 using ::testing::Eq;
39 using ::testing::Matcher;
40 using ::testing::MatcherInterface;
41 using ::testing::MatchResultListener;
42 using ::testing::Return;
43 using ::testing::SetArgPointee;
44 
45 // Hardware
46 using ::android::hardware::hidl_vec;
47 using ::android::hardware::keymaster::KeymasterDevice;
48 
49 // HAL
50 using ::android::hardware::keymaster::V4_0::Algorithm;
51 using ::android::hardware::keymaster::V4_0::EcCurve;
52 using ::android::hardware::keymaster::V4_0::ErrorCode;
53 using ::android::hardware::keymaster::V4_0::KeyFormat;
54 using ::android::hardware::keymaster::V4_0::KeyParameter;
55 using ::android::hardware::keymaster::V4_0::KeyCharacteristics;
56 using ::android::hardware::keymaster::V4_0::Tag;
57 using android::hardware::keymaster::pb_to_hidl_params;
58 
59 // App
60 //using namespace ::nugget::app::keymaster;
61 namespace nosapp = ::nugget::app::keymaster;
62 using ::nugget::app::keymaster::MockKeymaster;
63 using ::nugget::app::keymaster::ImportKeyRequest;
64 using ::nugget::app::keymaster::ImportKeyResponse;
65 
66 // ImportKey
67 
68 static uint8_t TEST_RSA1024_KEY[] = {
69     0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xba,
70     0x9f, 0x5e, 0xf0, 0x58, 0xda, 0x49, 0xbe, 0x6b, 0x3c, 0xef, 0x17, 0x6f,
71     0x2f, 0x4f, 0x81, 0x18, 0x21, 0x4f, 0xbd, 0x6c, 0x17, 0xaa, 0x74, 0x99,
72     0xcc, 0x55, 0x94, 0x0f, 0xee, 0xa4, 0x0e, 0xae, 0x68, 0x4c, 0xaf, 0x11,
73     0x86, 0xdd, 0x50, 0xbf, 0x5c, 0x0f, 0x22, 0xad, 0xfa, 0xd1, 0x42, 0xab,
74     0xb8, 0x01, 0x7c, 0x2f, 0x54, 0xc7, 0xd9, 0xac, 0x47, 0xe3, 0xe1, 0x6b,
75     0x51, 0x48, 0xb6, 0xbb, 0x33, 0xab, 0xba, 0x9f, 0x86, 0x1b, 0xdf, 0xea,
76     0x9f, 0x2d, 0xb6, 0x40, 0xe3, 0x22, 0xbe, 0x90, 0xd6, 0x0d, 0xca, 0x2e,
77     0xb7, 0x8d, 0x8f, 0xf9, 0xd7, 0xeb, 0xa5, 0x74, 0x69, 0xc0, 0x87, 0x9b,
78     0x73, 0x17, 0x65, 0xde, 0x90, 0xb9, 0x5a, 0xde, 0xe0, 0xa4, 0xf3, 0xde,
79     0xeb, 0x9d, 0x3d, 0xb3, 0x12, 0x84, 0xf0, 0xdb, 0x43, 0x82, 0x0a, 0x8c,
80     0x64, 0x48, 0x4e, 0x9d, 0xd8, 0x13, 0x6d, 0x02, 0x03, 0x01, 0x00, 0x01,
81     0x02, 0x81, 0x80, 0x48, 0x20, 0xc7, 0x8f, 0x4a, 0x30, 0x17, 0xf7, 0x5e,
82     0x38, 0x1f, 0x4a, 0x65, 0xe1, 0x19, 0xaf, 0xd1, 0xd5, 0x32, 0x1e, 0x0a,
83     0x74, 0x7d, 0x1f, 0x72, 0xbf, 0xdc, 0x45, 0x8d, 0x00, 0xd5, 0x6c, 0x8d,
84     0x30, 0xe7, 0x8e, 0x74, 0x4e, 0x35, 0x24, 0x7b, 0xc9, 0x47, 0x5a, 0x46,
85     0x76, 0xdd, 0xc1, 0x10, 0x60, 0x5e, 0x46, 0x92, 0x7e, 0x88, 0x7d, 0x53,
86     0x4e, 0x37, 0xbf, 0x8c, 0x7c, 0x4e, 0x87, 0x12, 0x97, 0x5a, 0xbc, 0x4a,
87     0x13, 0x56, 0xf4, 0x6f, 0xd7, 0x85, 0xd8, 0xe9, 0xed, 0x86, 0x6e, 0xc0,
88     0x7b, 0xe5, 0x9e, 0x0e, 0x2a, 0xd2, 0x55, 0x60, 0x5c, 0x79, 0x36, 0xe0,
89     0x09, 0x46, 0xf2, 0xf3, 0x61, 0x87, 0xc5, 0x53, 0xb0, 0x83, 0x6c, 0x9b,
90     0x16, 0x37, 0x6e, 0x23, 0xb7, 0xfb, 0x37, 0xef, 0x53, 0xd8, 0x2b, 0xca,
91     0x2d, 0x6e, 0x53, 0x91, 0xb4, 0x79, 0xf0, 0x1c, 0x5b, 0xa8, 0x5b, 0x02,
92     0x41, 0x00, 0xfe, 0x93, 0x73, 0x43, 0xab, 0xd9, 0x38, 0xbe, 0x6e, 0x54,
93     0x38, 0x2b, 0x01, 0x45, 0x77, 0x18, 0xa6, 0x40, 0x84, 0xa0, 0x7c, 0x74,
94     0x76, 0x6d, 0x9e, 0x1d, 0xa0, 0x36, 0xc6, 0xb2, 0x3d, 0x6f, 0xd4, 0xa8,
95     0xb0, 0xac, 0xfc, 0x8e, 0x3d, 0xfd, 0x81, 0xea, 0x52, 0x0f, 0x1b, 0x08,
96     0x3f, 0xe5, 0x32, 0x9e, 0xa2, 0x77, 0x7d, 0x3b, 0x7f, 0x41, 0x24, 0x74,
97     0xea, 0xce, 0xd2, 0x80, 0xb8, 0x77, 0x02, 0x41, 0x00, 0xbb, 0xaa, 0x9c,
98     0xb2, 0x83, 0x5a, 0x29, 0xae, 0xfb, 0x90, 0x20, 0xcd, 0x39, 0x0d, 0x5a,
99     0x1a, 0x8c, 0xb0, 0xc5, 0xc7, 0x62, 0x7a, 0xf4, 0xa5, 0xd8, 0x80, 0xac,
100     0xd1, 0x5f, 0xb9, 0xea, 0xea, 0xeb, 0x53, 0xae, 0x27, 0x45, 0x07, 0x0d,
101     0xd7, 0x5b, 0x68, 0x55, 0x53, 0x64, 0x83, 0xa0, 0xf0, 0xd7, 0x4a, 0xdf,
102     0x0e, 0x7f, 0xe6, 0xe7, 0xf2, 0xba, 0x30, 0x4e, 0x13, 0x4a, 0x32, 0xf0,
103     0x3b, 0x02, 0x40, 0x6f, 0xce, 0x74, 0x8e, 0x20, 0xf8, 0x6b, 0x0a, 0x7f,
104     0xcc, 0x2f, 0x4a, 0xfb, 0xe8, 0xf5, 0x50, 0x77, 0x1b, 0xd8, 0xe3, 0xdf,
105     0x25, 0x0b, 0x2a, 0x43, 0x8a, 0x41, 0x66, 0x2d, 0x47, 0xf4, 0xe1, 0x9b,
106     0xa5, 0x66, 0xca, 0xe2, 0xb4, 0xda, 0x16, 0xef, 0xaa, 0xe8, 0xd5, 0x47,
107     0x8b, 0x0c, 0xfc, 0xed, 0x89, 0x6c, 0x53, 0x4c, 0x46, 0x08, 0x32, 0xa4,
108     0xff, 0x50, 0x6c, 0xfb, 0x58, 0x9b, 0x2b, 0x02, 0x40, 0x49, 0x49, 0x3a,
109     0x42, 0x38, 0x2b, 0x68, 0xa5, 0xcd, 0xd5, 0x9e, 0x09, 0xa6, 0xa3, 0x01,
110     0x31, 0xe7, 0x09, 0x4d, 0x63, 0x2c, 0xa1, 0x29, 0x92, 0xee, 0x76, 0x69,
111     0x86, 0xa6, 0x24, 0x5b, 0x89, 0xfb, 0xf6, 0x44, 0xc7, 0x4f, 0x1c, 0x8f,
112     0x1a, 0x2f, 0xb7, 0x11, 0xc3, 0x2c, 0x38, 0x7f, 0x0c, 0x2e, 0x77, 0x2d,
113     0x9e, 0x62, 0xf2, 0x50, 0x58, 0x28, 0xbf, 0x9e, 0x6d, 0xc8, 0x07, 0x16,
114     0x6b, 0x02, 0x41, 0x00, 0xe8, 0x72, 0x7b, 0xce, 0x08, 0x27, 0x0a, 0xf5,
115     0x1b, 0xf6, 0x1a, 0xec, 0x66, 0x5b, 0x65, 0x60, 0x7f, 0xcc, 0x5e, 0xcf,
116     0x8e, 0xa6, 0xe4, 0x48, 0xcd, 0x82, 0x87, 0x59, 0xee, 0x9f, 0x22, 0x9e,
117     0x81, 0x32, 0x34, 0x0c, 0x14, 0x7f, 0x89, 0xab, 0xc7, 0xe8, 0xab, 0x0a,
118     0x1f, 0xdd, 0x99, 0x2c, 0xa9, 0xa3, 0xf1, 0x64, 0xa2, 0x1a, 0x93, 0xa6,
119     0x2a, 0xfe, 0x68, 0x42, 0xea, 0x5f, 0xab, 0x93
120 };
121 
122 class ImportKeyRequestMatcher
123     : public MatcherInterface<const ImportKeyRequest&> {
124   public:
ImportKeyRequestMatcher(const hidl_vec<KeyParameter> & params,const RSA * rsa)125     explicit ImportKeyRequestMatcher(
126         const hidl_vec<KeyParameter>& params, const RSA *rsa)
127         : params_(params),
128           rsa_(rsa),
129           ec_key_(NULL),
130           symmetric_key_(NULL),
131           symmetric_key_size_(0) {
132     }
133 
ImportKeyRequestMatcher(const hidl_vec<KeyParameter> & params,const EC_KEY * ec)134     explicit ImportKeyRequestMatcher(
135         const hidl_vec<KeyParameter>& params, const EC_KEY *ec)
136         : params_(params),
137           rsa_(NULL),
138           ec_key_(ec),
139           symmetric_key_(NULL),
140           symmetric_key_size_(0) {
141     }
142 
ImportKeyRequestMatcher(const hidl_vec<KeyParameter> & params,const uint8_t * symmetric_key,size_t symmetric_key_size)143     explicit ImportKeyRequestMatcher(
144         const hidl_vec<KeyParameter>& params,
145         const uint8_t *symmetric_key, size_t symmetric_key_size)
146         : params_(params),
147           rsa_(NULL),
148           ec_key_(NULL),
149           symmetric_key_(symmetric_key),
150           symmetric_key_size_(symmetric_key_size) {
151     }
152 
DescribeTo(::std::ostream * os) const153     virtual void DescribeTo(::std::ostream* os) const {
154         *os << "ImportKeyRequest matched expectation";
155     }
156 
DescribeNegationTo(::std::ostream * os) const157     virtual void DescribeNegationTo(::std::ostream* os) const {
158         *os << "ImportKeyRequest mis-matched expectation";
159     }
160 
MatchAndExplain(const ImportKeyRequest & request,MatchResultListener * listener) const161     virtual bool MatchAndExplain(const ImportKeyRequest& request,
162                                  MatchResultListener* listener) const {
163         (void)listener;
164 
165         if (rsa_ != nullptr) {
166             return this->MatchAndExplainRSA(request);
167         } else if (ec_key_ != nullptr) {
168             return this->MatchAndExplainEC(request);
169         } else {
170             return this->MatchAndExplainSymmetricKey(request);
171         }
172     }
173 
174   private:
MatchAndExplainRSA(const ImportKeyRequest & request) const175     bool MatchAndExplainRSA(const ImportKeyRequest& request) const {
176         if (params_.size() != (size_t)request.params().params().size()) {
177             LOG(ERROR) << "test: KeyParameters len mis-match";
178             return false;
179         }
180 
181         hidl_vec<KeyParameter> params;
182         if (pb_to_hidl_params(request.params(), &params) != ErrorCode::OK) {
183             LOG(ERROR) << "test: pb_to_hidl_params failed";
184             return false;
185         }
186 
187         for (size_t i = 0; i < params_.size(); i++) {
188             if(!(params[i] == params_[i])) {
189                 LOG(ERROR) << "test: KeyParameters mis-match";
190                 return false;
191             }
192         }
193 
194         const BIGNUM *n;
195         const BIGNUM *e;
196         const BIGNUM *d;
197         RSA_get0_key(rsa_, &n, &e, &d);
198 
199         if (request.rsa().e() != BN_get_word(e)) {
200             LOG(ERROR) << "e mismatch, expected: "
201                        << BN_get_word(e)
202                        << " got "
203                        << request.rsa().e();
204             return false;
205         }
206 
207         unique_ptr<uint8_t[]> d_buf(new uint8_t[BN_num_bytes(n)]);
208         if (!BN_bn2le_padded(d_buf.get(), BN_num_bytes(n), d)) {
209             LOG(ERROR) << "bn2le(d) failed";
210             return false;
211         }
212         // Expect d to be zero-padded to sizeof n if necessary.
213         if (request.rsa().d().size() != BN_num_bytes(n) &&
214             memcmp(request.rsa().d().data(), d_buf.get(),
215                    BN_num_bytes(n)) != 0) {
216             LOG(ERROR) << "d-bytes mis-matched";
217             return false;
218         }
219 
220         unique_ptr<uint8_t[]> n_buf(new uint8_t[BN_num_bytes(n)]);
221         if (!BN_bn2le_padded(n_buf.get(), BN_num_bytes(n), n)) {
222             LOG(ERROR) << "bn2le(n) failed";
223             return false;
224         }
225         if (request.rsa().n().size() != BN_num_bytes(n) &&
226             memcmp(request.rsa().n().data(), n_buf.get(),
227                    BN_num_bytes(n)) != 0) {
228             LOG(ERROR) << "n-bytes mis-matched";
229             return false;
230         }
231 
232         return true;
233     }
234 
MatchAndExplainEC(const ImportKeyRequest & request) const235     bool MatchAndExplainEC(const ImportKeyRequest& request) const {
236         // Curve parameter.
237         uint32_t expected_curve_id = (uint32_t)-1;
238         const EC_GROUP *group = EC_KEY_get0_group(ec_key_);
239         switch (EC_GROUP_get_curve_name(group)) {
240         case NID_secp224r1:
241             expected_curve_id = (uint32_t)EcCurve::P_224;
242             break;
243         case NID_X9_62_prime256v1:
244             expected_curve_id = (uint32_t)EcCurve::P_256;
245             break;
246         case NID_secp384r1:
247             expected_curve_id = (uint32_t)EcCurve::P_384;
248             break;
249         case NID_secp521r1:
250             expected_curve_id = (uint32_t)EcCurve::P_521;
251             break;
252         }
253 
254         if (request.ec().curve_id() != expected_curve_id) {
255             LOG(ERROR) << "Curve-id mismatch, got: "
256                        << request.ec().curve_id()
257                        << " expected "
258                        << expected_curve_id;
259             return false;
260         }
261 
262         const BIGNUM *d = EC_KEY_get0_private_key(ec_key_);
263         const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key_);
264         bssl::UniquePtr<BIGNUM> x(BN_new());
265         bssl::UniquePtr<BIGNUM> y(BN_new());
266 
267         if (!EC_POINT_get_affine_coordinates_GFp(
268                 EC_KEY_get0_group(ec_key_),
269                 pub_key, x.get(), y.get(), NULL)) {
270             LOG(ERROR) << "failed to get public key in affine coordinates";
271             return false;
272         }
273 
274         // Private key.
275         const size_t field_size = (EC_GROUP_get_degree(group) + 7) >> 3;
276         unique_ptr<uint8_t[]> d_buf(new uint8_t[field_size]);
277         if (!BN_bn2le_padded(d_buf.get(), field_size, d)) {
278             LOG(ERROR) << "bn2le(d) failed";
279             return false;
280         }
281         if (request.ec().d().size() != field_size ||
282             memcmp(request.ec().d().data(), d_buf.get(), field_size) != 0) {
283             LOG(ERROR) << "d-bytes mis-matched";
284             return false;
285         }
286 
287         // Public key.
288         unique_ptr<uint8_t[]> x_buf(new uint8_t[field_size]);
289         if (!BN_bn2le_padded(x_buf.get(), field_size, x.get())) {
290             LOG(ERROR) << "bn2le(x) failed";
291             return false;
292         }
293         if (request.ec().x().size() != field_size ||
294             memcmp(request.ec().x().data(), x_buf.get(), field_size) != 0) {
295             LOG(ERROR) << "x-bytes mis-matched";
296             return false;
297         }
298 
299         unique_ptr<uint8_t[]> y_buf(new uint8_t[field_size]);
300         if (!BN_bn2le_padded(y_buf.get(), field_size, y.get())) {
301             LOG(ERROR) << "bn2le(y) failed";
302             return false;
303         }
304         if (request.ec().y().size() != field_size ||
305             memcmp(request.ec().y().data(), y_buf.get(), field_size) != 0) {
306             LOG(ERROR) << "y-bytes mis-matched";
307             return false;
308         }
309 
310         return false;
311     }
312 
MatchAndExplainSymmetricKey(const ImportKeyRequest & request) const313     bool MatchAndExplainSymmetricKey(const ImportKeyRequest& request) const {
314         if (request.symmetric_key().material().size() != symmetric_key_size_ ||
315             memcmp(request.symmetric_key().material().data(),
316                    symmetric_key_, symmetric_key_size_) != 0) {
317             LOG(ERROR) << "symmetric key bytes mis-match";
318             return false;
319         }
320 
321         return true;
322     }
323 
324   private:
325     const hidl_vec<KeyParameter> params_;
326     const RSA *rsa_;
327     const EC_KEY *ec_key_;
328     const uint8_t *symmetric_key_;
329     size_t symmetric_key_size_;
330 };
331 
ImportKeyRequestEq(const hidl_vec<KeyParameter> & params,const RSA * rsa)332 static Matcher<const ImportKeyRequest&> ImportKeyRequestEq(
333     const hidl_vec<KeyParameter>& params, const RSA *rsa) {
334     return MakeMatcher(new ImportKeyRequestMatcher(params, rsa));
335 }
336 
TEST(KeymasterHalTest,importKeyPKCS8Success)337 TEST(KeymasterHalTest, importKeyPKCS8Success) {
338     MockKeymaster mockService;
339     ImportKeyResponse response;
340 
341     KeyParameter kp;
342     kp.tag = Tag::ALGORITHM;
343     kp.f.algorithm = Algorithm::RSA;
344 
345     bssl::UniquePtr<RSA> rsa;
346     bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
347     bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> pkcs8;
348 
349     // TODO: Avoid parsing in the validator, use known values instead.
350     rsa.reset(RSA_private_key_from_bytes(TEST_RSA1024_KEY,
351                                          sizeof(TEST_RSA1024_KEY)));
352     EXPECT_NE(rsa.get(), nullptr);
353     EXPECT_EQ(EVP_PKEY_set1_RSA(pkey.get(), rsa.get()), 1);
354     pkcs8.reset(EVP_PKEY2PKCS8(pkey.get()));
355     EXPECT_NE(pkcs8.get(), nullptr);
356 
357     int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
358     std::unique_ptr<uint8_t[]> der(new uint8_t[len]);
359     uint8_t *tmp = der.get();
360     EXPECT_EQ(i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp), len);
361 
362     hidl_vec<uint8_t> der_vec;
363     der_vec.setToExternal(const_cast<uint8_t*>(der.get()), len);
364 
365     // response
366     string dummy_blob("Dummy");
367     response.mutable_blob()->set_blob(dummy_blob);
368     nosapp::KeyParameter *noskp =
369         response.mutable_characteristics()->
370         mutable_tee_enforced()->add_params();
371     noskp->set_tag(nosapp::Tag::ALGORITHM);
372     noskp->set_integer((uint32_t)nosapp::Algorithm::RSA);
373 
374     EXPECT_CALL(
375         mockService,
376         ImportKey(ImportKeyRequestEq(hidl_vec<KeyParameter>{kp}, rsa.get()), _))
377         .WillOnce(DoAll(SetArgPointee<1>(response), Return(APP_SUCCESS)));
378 
379     KeymasterDevice hal{mockService};
380     hal.importKey(
381         hidl_vec<KeyParameter>{kp}, KeyFormat::PKCS8, der_vec,
382         [&](ErrorCode error, hidl_vec<uint8_t> blob,
383             KeyCharacteristics characteristics) {
384             EXPECT_EQ(error, ErrorCode::OK);
385             EXPECT_THAT(blob, Eq(hidl_vec<uint8_t>{'D', 'u', 'm', 'm', 'y'}));;
386 
387             EXPECT_EQ(characteristics.hardwareEnforced.size(), 1u);
388             EXPECT_EQ(characteristics.hardwareEnforced[0].tag, Tag::ALGORITHM);
389             EXPECT_EQ(characteristics.hardwareEnforced[0].f.algorithm,
390                       Algorithm::RSA);
391     });
392 }
393 
394 // TODO: add negative tests for PKCS8 RSA
395 // TODO: add tests for EC
396 // TODO: add tests for AES / HMAC
397