1/*
2 * Copyright (C) 2014 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 <gtest/gtest.h>
18
19#include <keymaster/authorization_set.h>
20#include <keymaster/android_keymaster_utils.h>
21
22#include "android_keymaster_test_utils.h"
23
24namespace keymaster {
25
26namespace test {
27
28TEST(Construction, ListProvided) {
29    keymaster_key_param_t params[] = {
30        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
31        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_USER_ID, 7),
32        Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD),
33        Authorization(TAG_APPLICATION_ID, "my_app", 6), Authorization(TAG_KEY_SIZE, 256),
34        Authorization(TAG_AUTH_TIMEOUT, 300),
35    };
36    AuthorizationSet set(params, array_length(params));
37    EXPECT_EQ(8U, set.size());
38}
39
40TEST(Construction, Copy) {
41    keymaster_key_param_t params[] = {
42        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
43        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_USER_ID, 7),
44        Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD),
45        Authorization(TAG_APPLICATION_ID, "my_app", 6), Authorization(TAG_KEY_SIZE, 256),
46        Authorization(TAG_AUTH_TIMEOUT, 300),
47    };
48    AuthorizationSet set(params, array_length(params));
49    AuthorizationSet set2(set);
50    EXPECT_EQ(set, set2);
51}
52
53TEST(Construction, NullProvided) {
54    keymaster_key_param_t params[] = {
55        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
56    };
57
58    AuthorizationSet set1(params, 0);
59    EXPECT_EQ(0U, set1.size());
60    EXPECT_EQ(AuthorizationSet::OK, set1.is_valid());
61
62    AuthorizationSet set2(reinterpret_cast<keymaster_key_param_t*>(NULL), array_length(params));
63    EXPECT_EQ(0U, set2.size());
64    EXPECT_EQ(AuthorizationSet::OK, set2.is_valid());
65}
66
67TEST(Lookup, NonRepeated) {
68    AuthorizationSet set(AuthorizationSetBuilder()
69                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
70                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
71                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
72                             .Authorization(TAG_USER_ID, 7)
73                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
74                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
75                             .Authorization(TAG_KEY_SIZE, 256)
76                             .Authorization(TAG_AUTH_TIMEOUT, 300));
77
78    EXPECT_EQ(8U, set.size());
79
80    int pos = set.find(TAG_ALGORITHM);
81    ASSERT_NE(-1, pos);
82    EXPECT_EQ(KM_TAG_ALGORITHM, set[pos].tag);
83    EXPECT_EQ(KM_ALGORITHM_RSA, set[pos].enumerated);
84
85    pos = set.find(TAG_MAC_LENGTH);
86    EXPECT_EQ(-1, pos);
87
88    uint32_t int_val = 0;
89    EXPECT_TRUE(set.GetTagValue(TAG_USER_ID, &int_val));
90    EXPECT_EQ(7U, int_val);
91
92    keymaster_blob_t blob_val;
93    EXPECT_TRUE(set.GetTagValue(TAG_APPLICATION_ID, &blob_val));
94    EXPECT_EQ(6U, blob_val.data_length);
95    EXPECT_EQ(0, memcmp(blob_val.data, "my_app", 6));
96}
97
98TEST(Lookup, Repeated) {
99    AuthorizationSet set(AuthorizationSetBuilder()
100                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
101                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
102                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
103                             .Authorization(TAG_USER_ID, 7)
104                             .Authorization(TAG_USER_SECURE_ID, 47727)
105                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
106                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
107                             .Authorization(TAG_KEY_SIZE, 256)
108                             .Authorization(TAG_AUTH_TIMEOUT, 300));
109    EXPECT_EQ(9U, set.size());
110
111    int pos = set.find(TAG_PURPOSE);
112    ASSERT_FALSE(pos == -1);
113    EXPECT_EQ(KM_TAG_PURPOSE, set[pos].tag);
114    EXPECT_EQ(KM_PURPOSE_SIGN, set[pos].enumerated);
115
116    pos = set.find(TAG_PURPOSE, pos);
117    EXPECT_EQ(KM_TAG_PURPOSE, set[pos].tag);
118    EXPECT_EQ(KM_PURPOSE_VERIFY, set[pos].enumerated);
119
120    EXPECT_EQ(-1, set.find(TAG_PURPOSE, pos));
121
122    pos = set.find(TAG_USER_SECURE_ID, pos);
123    EXPECT_EQ(KM_TAG_USER_SECURE_ID, set[pos].tag);
124    EXPECT_EQ(47727U, set[pos].long_integer);
125}
126
127TEST(Lookup, Indexed) {
128    AuthorizationSet set(AuthorizationSetBuilder()
129                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
130                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
131                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
132                             .Authorization(TAG_USER_ID, 7)
133                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
134                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
135                             .Authorization(TAG_KEY_SIZE, 256)
136                             .Authorization(TAG_AUTH_TIMEOUT, 300));
137    EXPECT_EQ(8U, set.size());
138
139    EXPECT_EQ(KM_TAG_PURPOSE, set[0].tag);
140    EXPECT_EQ(KM_PURPOSE_SIGN, set[0].enumerated);
141
142    // Lookup beyond end doesn't work, just returns zeros, but doens't blow up either (verify by
143    // running under valgrind).
144    EXPECT_EQ(KM_TAG_INVALID, set[10].tag);
145}
146
147TEST(Serialization, RoundTrip) {
148    AuthorizationSet set(AuthorizationSetBuilder()
149                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
150                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
151                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
152                             .Authorization(TAG_USER_ID, 7)
153                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
154                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
155                             .Authorization(TAG_KEY_SIZE, 256)
156                             .Authorization(TAG_USER_SECURE_ID, 47727)
157                             .Authorization(TAG_AUTH_TIMEOUT, 300)
158                             .Authorization(TAG_ALL_USERS)
159                             .Authorization(TAG_RSA_PUBLIC_EXPONENT, 3)
160                             .Authorization(TAG_ACTIVE_DATETIME, 10));
161
162    size_t size = set.SerializedSize();
163    EXPECT_TRUE(size > 0);
164
165    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
166    EXPECT_EQ(buf.get() + size, set.Serialize(buf.get(), buf.get() + size));
167    AuthorizationSet deserialized(buf.get(), size);
168
169    EXPECT_EQ(AuthorizationSet::OK, deserialized.is_valid());
170    EXPECT_EQ(set, deserialized);
171
172    int pos = deserialized.find(TAG_APPLICATION_ID);
173    ASSERT_NE(-1, pos);
174    EXPECT_EQ(KM_TAG_APPLICATION_ID, deserialized[pos].tag);
175    EXPECT_EQ(6U, deserialized[pos].blob.data_length);
176    EXPECT_EQ(0, memcmp(deserialized[pos].blob.data, "my_app", 6));
177}
178
179TEST(Deserialization, Deserialize) {
180    AuthorizationSet set(AuthorizationSetBuilder()
181                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
182                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
183                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
184                             .Authorization(TAG_USER_ID, 7)
185                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
186                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
187                             .Authorization(TAG_KEY_SIZE, 256)
188                             .Authorization(TAG_AUTH_TIMEOUT, 300));
189
190    size_t size = set.SerializedSize();
191    EXPECT_TRUE(size > 0);
192
193    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
194    EXPECT_EQ(buf.get() + size, set.Serialize(buf.get(), buf.get() + size));
195    AuthorizationSet deserialized;
196    const uint8_t* p = buf.get();
197    EXPECT_TRUE(deserialized.Deserialize(&p, p + size));
198    EXPECT_EQ(p, buf.get() + size);
199
200    EXPECT_EQ(AuthorizationSet::OK, deserialized.is_valid());
201
202    EXPECT_EQ(set.size(), deserialized.size());
203    for (size_t i = 0; i < set.size(); ++i) {
204        EXPECT_EQ(set[i].tag, deserialized[i].tag);
205    }
206
207    int pos = deserialized.find(TAG_APPLICATION_ID);
208    ASSERT_NE(-1, pos);
209    EXPECT_EQ(KM_TAG_APPLICATION_ID, deserialized[pos].tag);
210    EXPECT_EQ(6U, deserialized[pos].blob.data_length);
211    EXPECT_EQ(0, memcmp(deserialized[pos].blob.data, "my_app", 6));
212}
213
214TEST(Deserialization, TooShortBuffer) {
215    uint8_t buf[] = {0, 0, 0};
216    AuthorizationSet deserialized(buf, array_length(buf));
217    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized.is_valid());
218
219    const uint8_t* p = buf;
220    EXPECT_FALSE(deserialized.Deserialize(&p, p + array_length(buf)));
221    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized.is_valid());
222}
223
224TEST(Deserialization, InvalidLengthField) {
225    AuthorizationSet set(AuthorizationSetBuilder()
226                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
227                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
228                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
229                             .Authorization(TAG_USER_ID, 7)
230                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
231                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
232                             .Authorization(TAG_KEY_SIZE, 256)
233                             .Authorization(TAG_AUTH_TIMEOUT, 300));
234
235    size_t size = set.SerializedSize();
236    EXPECT_TRUE(size > 0);
237
238    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
239    EXPECT_EQ(buf.get() + size, set.Serialize(buf.get(), buf.get() + size));
240    *reinterpret_cast<uint32_t*>(buf.get()) = 9;
241
242    AuthorizationSet deserialized(buf.get(), size);
243    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized.is_valid());
244
245    const uint8_t* p = buf.get();
246    EXPECT_FALSE(deserialized.Deserialize(&p, p + size));
247    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized.is_valid());
248}
249
250static uint32_t read_uint32(const uint8_t* buf) {
251    uint32_t val;
252    memcpy(&val, buf, sizeof(val));
253    return val;
254}
255
256static void add_to_uint32(uint8_t* buf, int delta) {
257    uint32_t val;
258    memcpy(&val, buf, sizeof(val));
259    val += delta;
260    memcpy(buf, &val, sizeof(val));
261}
262
263TEST(Deserialization, MalformedIndirectData) {
264    AuthorizationSet set(AuthorizationSetBuilder()
265                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
266                             .Authorization(TAG_APPLICATION_DATA, "foo", 3));
267    size_t size = set.SerializedSize();
268
269    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
270    EXPECT_EQ(buf.get() + size, set.Serialize(buf.get(), buf.get() + size));
271
272    // This sucks.  This test, as written, requires intimate knowledge of the serialized layout of
273    // this particular set, which means it's brittle.  But it's important to test that we handle
274    // broken serialized data and I can't think of a better way to write this.
275    //
276    // The contents of buf are:
277    //
278    // Bytes:   Content:
279    // 0-3      Length of string data, which is 9.
280    // 4-9      "my_app"
281    // 10-12    "foo"
282    // 13-16    Number of elements, which is 2.
283    // 17-20    Length of elements, which is 24.
284    // 21-24    First tag, TAG_APPLICATION_ID
285    // 25-28    Length of string "my_app", 6
286    // 29-32    Offset of string "my_app", 0
287    // 33-36    Second tag, TAG_APPLICATION_DATA
288    // 37-40    Length of string "foo", 3
289    // 41-44    Offset of string "foo", 6
290
291    // Check that stuff is where we think.
292    EXPECT_EQ('m', buf[4]);
293    EXPECT_EQ('f', buf[10]);
294    // Length of "my_app"
295    EXPECT_EQ(6U, read_uint32(buf.get() + 25));
296    // Offset of "my_app"
297    EXPECT_EQ(0U, read_uint32(buf.get() + 29));
298    // Length of "foo"
299    EXPECT_EQ(3U, read_uint32(buf.get() + 37));
300    // Offset of "foo"
301    EXPECT_EQ(6U, read_uint32(buf.get() + 41));
302
303    // Check that deserialization works.
304    AuthorizationSet deserialized1(buf.get(), size);
305    EXPECT_EQ(AuthorizationSet::OK, deserialized1.is_valid());
306
307    const uint8_t* p = buf.get();
308    EXPECT_TRUE(deserialized1.Deserialize(&p, p + size));
309    EXPECT_EQ(AuthorizationSet::OK, deserialized1.is_valid());
310
311    //
312    // Now mess them up in various ways:
313    //
314
315    // Move "foo" offset so offset + length goes off the end
316    add_to_uint32(buf.get() + 41, 1);
317    AuthorizationSet deserialized2(buf.get(), size);
318    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized2.is_valid());
319    add_to_uint32(buf.get() + 41, -1);
320
321    // Shorten the "my_app" length to make a gap between the blobs.
322    add_to_uint32(buf.get() + 25, -1);
323    AuthorizationSet deserialized3(buf.get(), size);
324    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized3.is_valid());
325    add_to_uint32(buf.get() + 25, 1);
326
327    // Extend the "my_app" length to make them overlap, and decrease the "foo" length to keep the
328    // total length the same.  We don't detect this but should.
329    // TODO(swillden): Detect overlaps and holes that leave total size correct.
330    add_to_uint32(buf.get() + 25, 1);
331    add_to_uint32(buf.get() + 37, -1);
332    AuthorizationSet deserialized4(buf.get(), size);
333    EXPECT_EQ(AuthorizationSet::OK, deserialized4.is_valid());
334}
335
336TEST(Growable, SuccessfulRoundTrip) {
337    AuthorizationSet growable;
338    EXPECT_TRUE(growable.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)));
339    EXPECT_EQ(1U, growable.size());
340
341    EXPECT_TRUE(growable.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)));
342    EXPECT_EQ(2U, growable.size());
343
344    EXPECT_TRUE(growable.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)));
345    EXPECT_EQ(3U, growable.size());
346
347    EXPECT_TRUE(growable.push_back(Authorization(TAG_APPLICATION_ID, "data", 4)));
348    EXPECT_EQ(4U, growable.size());
349
350    EXPECT_TRUE(growable.push_back(Authorization(TAG_APPLICATION_DATA, "some more data", 14)));
351    EXPECT_EQ(5U, growable.size());
352
353    size_t serialize_size = growable.SerializedSize();
354    UniquePtr<uint8_t[]> serialized(new uint8_t[serialize_size]);
355    EXPECT_EQ(serialized.get() + serialize_size,
356              growable.Serialize(serialized.get(), serialized.get() + serialize_size));
357
358    AuthorizationSet deserialized(serialized.get(), serialize_size);
359    EXPECT_EQ(growable, deserialized);
360}
361
362TEST(Growable, InsufficientElemBuf) {
363    AuthorizationSet growable;
364    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
365
366    // First insertion fits.
367    EXPECT_TRUE(growable.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)));
368    EXPECT_EQ(1U, growable.size());
369    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
370
371    // Second does too.
372    EXPECT_TRUE(growable.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3)));
373    EXPECT_EQ(2U, growable.size());
374}
375
376TEST(Growable, InsufficientIndirectBuf) {
377    AuthorizationSet growable;
378    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
379
380    EXPECT_TRUE(growable.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)));
381    EXPECT_EQ(1U, growable.size());
382    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
383
384    EXPECT_TRUE(growable.push_back(Authorization(TAG_APPLICATION_ID, "1234567890", 10)));
385    EXPECT_EQ(2U, growable.size());
386    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
387
388    EXPECT_TRUE(growable.push_back(Authorization(TAG_APPLICATION_DATA, "1", 1)));
389    EXPECT_EQ(3U, growable.size());
390    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
391
392    // Can still add another entry without indirect data.  Now it's full.
393    EXPECT_TRUE(growable.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)));
394    EXPECT_EQ(4U, growable.size());
395    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
396}
397
398TEST(Growable, PushBackSets) {
399    AuthorizationSetBuilder builder;
400    builder.Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
401        .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
402        .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
403        .Authorization(TAG_USER_ID, 7)
404        .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
405        .Authorization(TAG_APPLICATION_ID, "my_app", 6)
406        .Authorization(TAG_KEY_SIZE, 256)
407        .Authorization(TAG_AUTH_TIMEOUT, 300);
408
409    AuthorizationSet set1(builder.build());
410    AuthorizationSet set2(builder.build());
411
412    AuthorizationSet combined;
413    EXPECT_TRUE(combined.push_back(set1));
414    EXPECT_TRUE(combined.push_back(set2));
415    EXPECT_EQ(set1.size() + set2.size(), combined.size());
416    EXPECT_EQ(12U, combined.indirect_size());
417}
418
419TEST(GetValue, GetInt) {
420    AuthorizationSet set(AuthorizationSetBuilder()
421                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
422                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
423                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
424                             .Authorization(TAG_USER_ID, 7)
425                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
426                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
427                             .Authorization(TAG_AUTH_TIMEOUT, 300));
428
429    uint32_t val;
430    EXPECT_TRUE(set.GetTagValue(TAG_USER_ID, &val));
431    EXPECT_EQ(7U, val);
432
433    // Find one that isn't there
434    EXPECT_FALSE(set.GetTagValue(TAG_KEY_SIZE, &val));
435}
436
437TEST(GetValue, GetLong) {
438    AuthorizationSet set1(AuthorizationSetBuilder()
439                              .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
440                              .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
441                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
442                              .Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
443
444    AuthorizationSet set2(AuthorizationSetBuilder()
445                              .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
446                              .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
447                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
448
449    uint64_t val;
450    EXPECT_TRUE(set1.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &val));
451    EXPECT_EQ(3U, val);
452
453    // Find one that isn't there
454    EXPECT_FALSE(set2.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &val));
455}
456
457TEST(GetValue, GetLongRep) {
458    AuthorizationSet set1(AuthorizationSetBuilder()
459                              .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
460                              .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
461                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
462                              .Authorization(TAG_USER_SECURE_ID, 8338)
463                              .Authorization(TAG_USER_SECURE_ID, 4334)
464                              .Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
465
466    AuthorizationSet set2(AuthorizationSetBuilder()
467                              .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
468                              .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
469                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
470
471    uint64_t val;
472    EXPECT_TRUE(set1.GetTagValue(TAG_USER_SECURE_ID, 0, &val));
473    EXPECT_EQ(8338U, val);
474    EXPECT_TRUE(set1.GetTagValue(TAG_USER_SECURE_ID, 1, &val));
475    EXPECT_EQ(4334U, val);
476
477    // Find one that isn't there
478    EXPECT_FALSE(set2.GetTagValue(TAG_USER_SECURE_ID, &val));
479}
480
481TEST(GetValue, GetEnum) {
482    AuthorizationSet set(AuthorizationSetBuilder()
483                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
484                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
485                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
486                             .Authorization(TAG_USER_ID, 7)
487                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
488                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
489                             .Authorization(TAG_AUTH_TIMEOUT, 300));
490
491    keymaster_algorithm_t val;
492    EXPECT_TRUE(set.GetTagValue(TAG_ALGORITHM, &val));
493    EXPECT_EQ(KM_ALGORITHM_RSA, val);
494
495    // Find one that isn't there
496    keymaster_padding_t val2;
497    EXPECT_FALSE(set.GetTagValue(TAG_PADDING, &val2));
498}
499
500TEST(GetValue, GetEnumRep) {
501    AuthorizationSet set(AuthorizationSetBuilder()
502                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
503                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
504                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
505                             .Authorization(TAG_USER_ID, 7)
506                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
507                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
508                             .Authorization(TAG_AUTH_TIMEOUT, 300));
509
510    keymaster_purpose_t val;
511    EXPECT_TRUE(set.GetTagValue(TAG_PURPOSE, 0, &val));
512    EXPECT_EQ(KM_PURPOSE_SIGN, val);
513    EXPECT_TRUE(set.GetTagValue(TAG_PURPOSE, 1, &val));
514    EXPECT_EQ(KM_PURPOSE_VERIFY, val);
515
516    // Find one that isn't there
517    EXPECT_FALSE(set.GetTagValue(TAG_PURPOSE, 2, &val));
518}
519
520TEST(GetValue, GetDate) {
521    AuthorizationSet set(AuthorizationSetBuilder()
522                             .Authorization(TAG_ACTIVE_DATETIME, 10)
523                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
524                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
525                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
526                             .Authorization(TAG_USER_ID, 7)
527                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
528                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
529                             .Authorization(TAG_AUTH_TIMEOUT, 300));
530
531    uint64_t val;
532    EXPECT_TRUE(set.GetTagValue(TAG_ACTIVE_DATETIME, &val));
533    EXPECT_EQ(10U, val);
534
535    // Find one that isn't there
536    EXPECT_FALSE(set.GetTagValue(TAG_USAGE_EXPIRE_DATETIME, &val));
537}
538
539TEST(GetValue, GetBlob) {
540    AuthorizationSet set(AuthorizationSetBuilder()
541                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
542                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
543                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
544                             .Authorization(TAG_USER_ID, 7)
545                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
546                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
547                             .Authorization(TAG_AUTH_TIMEOUT, 300));
548
549    keymaster_blob_t val;
550    EXPECT_TRUE(set.GetTagValue(TAG_APPLICATION_ID, &val));
551    EXPECT_EQ(6U, val.data_length);
552    EXPECT_EQ(0, memcmp(val.data, "my_app", 6));
553
554    // Find one that isn't there
555    EXPECT_FALSE(set.GetTagValue(TAG_APPLICATION_DATA, &val));
556}
557
558TEST(Deduplication, NoDuplicates) {
559    AuthorizationSet set(AuthorizationSetBuilder()
560                             .Authorization(TAG_ACTIVE_DATETIME, 10)
561                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
562                             .Authorization(TAG_USER_ID, 7)
563                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
564    AuthorizationSet copy(set);
565
566    EXPECT_EQ(copy, set);
567    set.Deduplicate();
568    EXPECT_EQ(copy.size(), set.size());
569
570    // Sets no longer compare equal, because of ordering (ugh, maybe it should be
571    // AuthorizationList, not AuthorizationSet).
572    EXPECT_NE(copy, set);
573}
574
575TEST(Deduplication, NoDuplicatesHasInvalid) {
576    AuthorizationSet set(AuthorizationSetBuilder()
577                             .Authorization(TAG_ACTIVE_DATETIME, 10)
578                             .Authorization(TAG_INVALID)
579                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
580                             .Authorization(TAG_USER_ID, 7)
581                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
582    AuthorizationSet copy(set);
583
584    EXPECT_EQ(copy, set);
585    set.Deduplicate();
586
587    // Deduplicate should have removed the invalid.
588    EXPECT_EQ(copy.size() - 1, set.size());
589    EXPECT_NE(copy, set);
590}
591
592TEST(Deduplication, DuplicateEnum) {
593    AuthorizationSet set(AuthorizationSetBuilder()
594                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
595                             .Authorization(TAG_ACTIVE_DATETIME, 10)
596                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
597                             .Authorization(TAG_USER_ID, 7)
598                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
599                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
600    AuthorizationSet copy(set);
601
602    EXPECT_EQ(copy, set);
603    set.Deduplicate();
604    EXPECT_EQ(copy.size() - 2, set.size());
605    EXPECT_NE(copy, set);
606}
607
608TEST(Deduplication, DuplicateBlob) {
609    AuthorizationSet set(AuthorizationSetBuilder()
610                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
611                             .Authorization(TAG_ACTIVE_DATETIME, 10)
612                             .Authorization(TAG_APPLICATION_DATA, "data", 4)
613                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
614                             .Authorization(TAG_USER_ID, 7)
615                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
616                             .Authorization(TAG_APPLICATION_DATA, "data", 4)
617                             .Authorization(TAG_APPLICATION_DATA, "foo", 3)
618                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
619    AuthorizationSet copy(set);
620
621    EXPECT_EQ(copy, set);
622    set.Deduplicate();
623    EXPECT_EQ(copy.size() - 3, set.size());
624    EXPECT_NE(copy, set);
625
626    // The real test here is that valgrind reports no leak.
627}
628
629TEST(Union, Disjoint) {
630    AuthorizationSet set1(AuthorizationSetBuilder()
631                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
632                             .Authorization(TAG_ACTIVE_DATETIME, 10)
633                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
634
635    AuthorizationSet set2(AuthorizationSetBuilder()
636                             .Authorization(TAG_USER_ID, 7)
637                             .Authorization(TAG_APPLICATION_DATA, "foo", 3)
638                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
639
640    AuthorizationSet expected(AuthorizationSetBuilder()
641                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
642                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
643                             .Authorization(TAG_USER_ID, 7)
644                             .Authorization(TAG_ACTIVE_DATETIME, 10)
645                             .Authorization(TAG_APPLICATION_DATA, "data", 4)
646                             .Authorization(TAG_APPLICATION_DATA, "foo", 3));
647
648    set1.Union(set2);
649    EXPECT_EQ(expected, set1);
650}
651
652TEST(Union, Overlap) {
653    AuthorizationSet set1(AuthorizationSetBuilder()
654                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
655                             .Authorization(TAG_ACTIVE_DATETIME, 10)
656                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
657
658    AuthorizationSet set2(AuthorizationSetBuilder()
659                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
660                             .Authorization(TAG_ACTIVE_DATETIME, 10)
661                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
662
663    AuthorizationSet expected(AuthorizationSetBuilder()
664                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
665                             .Authorization(TAG_ACTIVE_DATETIME, 10)
666                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
667
668    set1.Union(set2);
669    EXPECT_EQ(expected, set1);
670}
671
672TEST(Union, Empty) {
673    AuthorizationSet set1(AuthorizationSetBuilder()
674                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
675                             .Authorization(TAG_ACTIVE_DATETIME, 10)
676                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
677
678    AuthorizationSet set2;
679
680    AuthorizationSet expected(AuthorizationSetBuilder()
681                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
682                             .Authorization(TAG_ACTIVE_DATETIME, 10)
683                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
684
685    set1.Union(set2);
686    EXPECT_EQ(expected, set1);
687}
688
689TEST(Difference, Disjoint) {
690    AuthorizationSet set1(AuthorizationSetBuilder()
691                             .Authorization(TAG_APPLICATION_DATA, "data", 4)
692                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
693                             .Authorization(TAG_ACTIVE_DATETIME, 10));
694
695    AuthorizationSet set2(AuthorizationSetBuilder()
696                             .Authorization(TAG_USER_ID, 7)
697                             .Authorization(TAG_APPLICATION_DATA, "foo", 3)
698                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
699
700    // Elements are the same as set1, but happen to be in a different order
701    AuthorizationSet expected(AuthorizationSetBuilder()
702                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
703                             .Authorization(TAG_ACTIVE_DATETIME, 10)
704                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
705
706    set1.Difference(set2);
707    EXPECT_EQ(expected, set1);
708}
709
710TEST(Difference, Overlap) {
711    AuthorizationSet set1(AuthorizationSetBuilder()
712                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
713                             .Authorization(TAG_ACTIVE_DATETIME, 10)
714                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
715
716    AuthorizationSet set2(AuthorizationSetBuilder()
717                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
718                             .Authorization(TAG_ACTIVE_DATETIME, 10)
719                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
720
721    AuthorizationSet empty;
722    set1.Difference(set2);
723    EXPECT_EQ(empty, set1);
724    EXPECT_EQ(0U, set1.size());
725}
726
727TEST(Difference, NullSet) {
728    AuthorizationSet set1(AuthorizationSetBuilder()
729                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
730                             .Authorization(TAG_ACTIVE_DATETIME, 10)
731                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
732
733    AuthorizationSet set2;
734
735    AuthorizationSet expected(AuthorizationSetBuilder()
736                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
737                             .Authorization(TAG_ACTIVE_DATETIME, 10)
738                             .Authorization(TAG_APPLICATION_DATA, "data", 4));
739
740    set1.Difference(set2);
741    EXPECT_EQ(expected, set1);
742}
743
744}  // namespace test
745}  // namespace keymaster
746