1/*
2 * Copyright 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#ifndef SYSTEM_KEYMASTER_AUTHORIZATION_SET_H_
18#define SYSTEM_KEYMASTER_AUTHORIZATION_SET_H_
19
20#include <keymaster/UniquePtr.h>
21
22#include <hardware/keymaster_defs.h>
23#include <keymaster/keymaster_tags.h>
24#include <keymaster/serializable.h>
25
26namespace keymaster {
27
28class AuthorizationSetBuilder;
29
30/**
31 * An extension of the keymaster_key_param_set_t struct, which provides serialization memory
32 * management and methods for easy manipulation and construction.
33 */
34class AuthorizationSet : public Serializable, public keymaster_key_param_set_t {
35  public:
36    /**
37     * Construct an empty, dynamically-allocated, growable AuthorizationSet.  Does not actually
38     * allocate any storage until elements are added, so there is no cost to creating an
39     * AuthorizationSet with this constructor and then reinitializing it to point at pre-allocated
40     * buffers, with \p Reinitialize.
41     */
42    AuthorizationSet()
43        : elems_capacity_(0), indirect_data_(NULL), indirect_data_size_(0),
44          indirect_data_capacity_(0), error_(OK) {
45        elems_ = nullptr;
46        elems_size_ = 0;
47    }
48
49    /**
50     * Construct an AuthorizationSet from the provided array.  The AuthorizationSet copies the data
51     * from the provided array (and the data referenced by its embedded pointers, if any) into
52     * dynamically-allocated storage.  If allocation of the needed storage fails, \p is_valid() will
53     * return ALLOCATION_FAILURE. It is the responsibility of the caller to check before using the
54     * set, if allocations might fail.
55     */
56    AuthorizationSet(const keymaster_key_param_t* elems, size_t count) : indirect_data_(nullptr) {
57        elems_ = nullptr;
58        Reinitialize(elems, count);
59    }
60
61    explicit AuthorizationSet(const keymaster_key_param_set_t& set) : indirect_data_(nullptr) {
62        elems_ = nullptr;
63        Reinitialize(set.params, set.length);
64    }
65
66    explicit AuthorizationSet(const uint8_t* serialized_set, size_t serialized_size)
67        : indirect_data_(nullptr) {
68        elems_ = nullptr;
69        Deserialize(&serialized_set, serialized_set + serialized_size);
70    }
71
72    /**
73     * Construct an AuthorizationSet from the provided builder.  This extracts the data from the
74     * builder, rather than copying it, so after this call the builder is empty.
75     */
76    explicit AuthorizationSet(/* NOT const */ AuthorizationSetBuilder& builder);
77
78    // Copy constructor.
79    AuthorizationSet(const AuthorizationSet& set) : Serializable(), indirect_data_(nullptr) {
80        elems_ = nullptr;
81        error_ = set.error_;
82        if (error_ != OK) return;
83        Reinitialize(set.elems_, set.elems_size_);
84    }
85
86    // Move constructor.
87    AuthorizationSet(AuthorizationSet&& set) : Serializable() {
88        MoveFrom(set);
89    }
90
91    // Copy assignment.
92    AuthorizationSet& operator=(const AuthorizationSet& set) {
93        Reinitialize(set.elems_, set.elems_size_);
94        error_ = set.error_;
95        return *this;
96    }
97
98    // Move assignment.
99    AuthorizationSet& operator=(AuthorizationSet&& set) {
100        FreeData();
101        MoveFrom(set);
102        return *this;
103    }
104
105    /**
106     * Clear existing authorization set data
107     */
108    void Clear();
109
110    /**
111     * Reinitialize an AuthorizationSet as a dynamically-allocated, growable copy of the data in the
112     * provided array (and the data referenced by its embedded pointers, if any).  If the allocation
113     * of the needed storage fails this method will return false and \p is_valid() will return
114     * ALLOCATION_FAILURE.
115     */
116    bool Reinitialize(const keymaster_key_param_t* elems, size_t count);
117
118    bool Reinitialize(const AuthorizationSet& set) {
119        return Reinitialize(set.elems_, set.elems_size_);
120    }
121
122    bool Reinitialize(const keymaster_key_param_set_t& set) {
123        return Reinitialize(set.params, set.length);
124    }
125
126    ~AuthorizationSet();
127
128    enum Error {
129        OK,
130        ALLOCATION_FAILURE,
131        MALFORMED_DATA,
132    };
133
134    Error is_valid() const { return error_; }
135
136    /**
137     * Returns the size of the set.
138     */
139    size_t size() const { return elems_size_; }
140
141    /**
142     * Returns true if the set is empty.
143     */
144    bool empty() const { return size() == 0; }
145
146    /**
147     * Returns the total size of all indirect data referenced by set elements.
148     */
149    size_t indirect_size() const { return indirect_data_size_; }
150
151    /**
152     * Returns the data in the set, directly. Be careful with this.
153     */
154    const keymaster_key_param_t* data() const { return elems_; }
155
156    /**
157     * Sorts the set
158     */
159    void Sort();
160
161    /**
162     * Sorts the set and removes duplicates (inadvertently duplicating tags is easy to do with the
163     * AuthorizationSetBuilder).
164     */
165    void Deduplicate();
166
167    /**
168     * Adds all elements from \p set that are not already present in this AuthorizationSet.  As a
169     * side-effect, if \p set is not null this AuthorizationSet will end up sorted.
170     */
171    void Union(const keymaster_key_param_set_t& set);
172
173    /**
174     * Removes all elements in \p set from this AuthorizationSet.
175     */
176    void Difference(const keymaster_key_param_set_t& set);
177
178    /**
179     * Returns the data in a keymaster_key_param_set_t, suitable for returning to C code.  For C
180     * compatibility, the contents are malloced, not new'ed, and so must be freed with free(), or
181     * better yet with keymaster_free_param_set, not delete.  The caller takes ownership.
182     */
183    void CopyToParamSet(keymaster_key_param_set_t* set) const;
184
185    /**
186     * Returns the offset of the next entry that matches \p tag, starting from the element after \p
187     * begin.  If not found, returns -1.
188     */
189    int find(keymaster_tag_t tag, int begin = -1) const;
190
191    /**
192     * Removes the entry at the specified index. Returns true if successful, false if the index was
193     * out of bounds.
194     */
195    bool erase(int index);
196
197    /**
198     * Returns iterator (pointer) to beginning of elems array, to enable STL-style iteration
199     */
200    const keymaster_key_param_t* begin() const { return elems_; }
201
202    /**
203     * Returns iterator (pointer) one past end of elems array, to enable STL-style iteration
204     */
205    const keymaster_key_param_t* end() const { return elems_ + elems_size_; }
206
207    /**
208     * Returns the nth element of the set.
209     */
210    keymaster_key_param_t& operator[](int n);
211
212    /**
213     * Returns the nth element of the set.
214     */
215    keymaster_key_param_t operator[](int n) const;
216
217    /**
218     * Returns true if the set contains at least one instance of \p tag
219     */
220    bool Contains(keymaster_tag_t tag) const {
221        return find(tag) != -1;
222    }
223
224    /**
225     * Returns the number of \p tag entries.
226     */
227    size_t GetTagCount(keymaster_tag_t tag) const;
228
229    /**
230     * Returns true if the set contains the specified tag and value.
231     */
232    template <keymaster_tag_t Tag, typename T>
233    bool Contains(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, T val) const {
234        return ContainsEnumValue(tag, val);
235    }
236
237    /**
238     * Returns true if the set contains the specified tag and value.
239     */
240    template <keymaster_tag_t Tag, typename T>
241    bool Contains(TypedEnumTag<KM_ENUM, Tag, T> tag, T val) const {
242        return ContainsEnumValue(tag, val);
243    }
244
245    /**
246     * Returns true if the set contains the specified tag and value.
247     */
248    template <keymaster_tag_t Tag>
249    bool Contains(TypedTag<KM_UINT, Tag> tag, uint32_t val) const {
250        return ContainsIntValue(tag, val);
251    }
252
253    /**
254     * If the specified integer-typed \p tag exists, places its value in \p val and returns true.
255     * If \p tag is not present, leaves \p val unmodified and returns false.
256     */
257    template <keymaster_tag_t T>
258    inline bool GetTagValue(TypedTag<KM_UINT, T> tag, uint32_t* val) const {
259        return GetTagValueInt(tag, val);
260    }
261
262    /**
263     * If the specified instance of the specified integer-typed \p tag exists, places its value
264     * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
265     * false.
266     */
267    template <keymaster_tag_t Tag>
268    bool GetTagValue(TypedTag<KM_UINT_REP, Tag> tag, size_t instance, uint32_t* val) const {
269        return GetTagValueIntRep(tag, instance, val);
270    }
271
272    /**
273     * If the specified long-typed \p tag exists, places its value in \p val and returns true.
274     * If \p tag is not present, leaves \p val unmodified and returns false.
275     */
276    template <keymaster_tag_t T>
277    inline bool GetTagValue(TypedTag<KM_ULONG, T> tag, uint64_t* val) const {
278        return GetTagValueLong(tag, val);
279    }
280
281    /**
282     * If the specified instance of the specified integer-typed \p tag exists, places its value
283     * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
284     * false.
285     */
286    template <keymaster_tag_t Tag>
287    bool GetTagValue(TypedTag<KM_ULONG_REP, Tag> tag, size_t instance, uint64_t* val) const {
288        return GetTagValueLongRep(tag, instance, val);
289    }
290
291    /**
292     * If the specified enumeration-typed \p tag exists, places its value in \p val and returns
293     * true.  If \p tag is not present, leaves \p val unmodified and returns false.
294     */
295    template <keymaster_tag_t Tag, typename T>
296    bool GetTagValue(TypedEnumTag<KM_ENUM, Tag, T> tag, T* val) const {
297        return GetTagValueEnum(tag, reinterpret_cast<uint32_t*>(val));
298    }
299
300    /**
301     * If the specified instance of the specified enumeration-typed \p tag exists, places its value
302     * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
303     * false.
304     */
305    template <keymaster_tag_t Tag, typename T>
306    bool GetTagValue(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, size_t instance, T* val) const {
307        return GetTagValueEnumRep(tag, instance, reinterpret_cast<uint32_t*>(val));
308    }
309
310    /**
311     * If exactly one instance of the specified enumeration-typed \p tag exists, places its value in
312     * \p val and returns true.  If \p tag is not present or if multiple copies are present, leaves
313     * \p val unmodified and returns false.
314     */
315    template <keymaster_tag_t Tag, typename T>
316    bool GetTagValue(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, T* val) const {
317        if (GetTagCount(tag) != 1)
318            return false;
319        return GetTagValueEnumRep(tag, 0, reinterpret_cast<uint32_t*>(val));
320    }
321
322    /**
323     * If the specified date-typed \p tag exists, places its value in \p val and returns
324     * true.  If \p tag is not present, leaves \p val unmodified and returns false.
325     */
326    template <keymaster_tag_t Tag>
327    bool GetTagValue(TypedTag<KM_UINT_REP, Tag> tag, size_t instance,
328                     typename TypedTag<KM_UINT_REP, Tag>::value_type* val) const {
329        return GetTagValueIntRep(tag, instance, val);
330    }
331
332    /**
333     * If the specified bytes-typed \p tag exists, places its value in \p val and returns
334     * true.  If \p tag is not present, leaves \p val unmodified and returns false.
335     */
336    template <keymaster_tag_t Tag>
337    bool GetTagValue(TypedTag<KM_BYTES, Tag> tag, keymaster_blob_t* val) const {
338        return GetTagValueBlob(tag, val);
339    }
340
341    /**
342     * If the specified bignum-typed \p tag exists, places its value in \p val and returns
343     * true.  If \p tag is not present, leaves \p val unmodified and returns false.
344     */
345    template <keymaster_tag_t Tag>
346    bool GetTagValue(TypedTag<KM_BIGNUM, Tag> tag, keymaster_blob_t* val) const {
347        return GetTagValueBlob(tag, val);
348    }
349
350    /**
351     * Returns true if the specified tag is present, and therefore has the value 'true'.
352     */
353    template <keymaster_tag_t Tag> bool GetTagValue(TypedTag<KM_BOOL, Tag> tag) const {
354        return GetTagValueBool(tag);
355    }
356
357    /**
358     * If the specified \p tag exists, places its value in \p val and returns true.  If \p tag is
359     * not present, leaves \p val unmodified and returns false.
360     */
361    template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
362    bool GetTagValue(TypedTag<Type, Tag> tag, typename TagValueType<Type>::value_type* val) const {
363        return GetTagValueLong(tag, val);
364    }
365
366    bool push_back(keymaster_key_param_t elem);
367
368    /**
369     * Grow the elements array to ensure it can contain \p count entries.  Preserves any existing
370     * entries.
371     */
372    bool reserve_elems(size_t count);
373
374    /**
375     * Grow the indirect data array to ensure it can contain \p length bytes.  Preserves any
376     * existing indirect data.
377     */
378    bool reserve_indirect(size_t length);
379
380    bool push_back(const keymaster_key_param_set_t& set);
381
382    /**
383     * Append the tag and enumerated value to the set.
384     */
385    template <keymaster_tag_t Tag, keymaster_tag_type_t Type, typename KeymasterEnum>
386    bool push_back(TypedEnumTag<Type, Tag, KeymasterEnum> tag, KeymasterEnum val) {
387        return push_back(Authorization(tag, val));
388    }
389
390    /**
391     * Append the boolean tag (value "true") to the set.
392     */
393    template <keymaster_tag_t Tag> bool push_back(TypedTag<KM_BOOL, Tag> tag) {
394        return push_back(Authorization(tag));
395    }
396
397    /**
398     * Append the tag and byte array to the set.  Copies the array into internal storage; does not
399     * take ownership of the passed-in array.
400     */
401    template <keymaster_tag_t Tag>
402    bool push_back(TypedTag<KM_BYTES, Tag> tag, const void* bytes, size_t bytes_len) {
403        return push_back(keymaster_param_blob(tag, static_cast<const uint8_t*>(bytes), bytes_len));
404    }
405
406    /**
407     * Append the tag and blob to the set.  Copies the blob contents into internal storage; does not
408     * take ownership of the blob's data.
409     */
410    template <keymaster_tag_t Tag>
411    bool push_back(TypedTag<KM_BYTES, Tag> tag, const keymaster_blob_t& blob) {
412        return push_back(tag, blob.data, blob.data_length);
413    }
414
415    /**
416     * Append the tag and bignum array to the set.  Copies the array into internal storage; does not
417     * take ownership of the passed-in array.
418     */
419    template <keymaster_tag_t Tag>
420    bool push_back(TypedTag<KM_BIGNUM, Tag> tag, const void* bytes, size_t bytes_len) {
421        return push_back(keymaster_param_blob(tag, static_cast<const uint8_t*>(bytes), bytes_len));
422    }
423
424    template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
425    bool push_back(TypedTag<Type, Tag> tag, typename TypedTag<Type, Tag>::value_type val) {
426        return push_back(Authorization(tag, val));
427    }
428
429    template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
430    bool push_back(TypedTag<Type, Tag> tag, const void* bytes, size_t bytes_len) {
431        return push_back(Authorization(tag, bytes, bytes_len));
432    }
433
434    /* Virtual methods from Serializable */
435    size_t SerializedSize() const;
436    uint8_t* Serialize(uint8_t* serialized_set, const uint8_t* end) const;
437    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end);
438
439    size_t SerializedSizeOfElements() const;
440
441  private:
442    void FreeData();
443    void MoveFrom(AuthorizationSet& set);
444
445    void set_invalid(Error err);
446
447    static size_t ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count);
448    void CopyIndirectData();
449    bool CheckIndirectData();
450
451    bool DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end);
452    bool DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end);
453
454    bool GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const;
455    bool GetTagValueEnumRep(keymaster_tag_t tag, size_t instance, uint32_t* val) const;
456    bool GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const;
457    bool GetTagValueIntRep(keymaster_tag_t tag, size_t instance, uint32_t* val) const;
458    bool GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const;
459    bool GetTagValueLongRep(keymaster_tag_t tag, size_t instance, uint64_t* val) const;
460    bool GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const;
461    bool GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const;
462    bool GetTagValueBool(keymaster_tag_t tag) const;
463
464    bool ContainsEnumValue(keymaster_tag_t tag, uint32_t val) const;
465    bool ContainsIntValue(keymaster_tag_t tag, uint32_t val) const;
466
467    // Define elems_ and elems_size_ as aliases to params and length, respectively.  This is to
468    // avoid using the variables without the trailing underscore in the implementation.
469    keymaster_key_param_t*& elems_ = keymaster_key_param_set_t::params;
470    size_t& elems_size_ = keymaster_key_param_set_t::length;
471
472    size_t elems_capacity_;
473    uint8_t* indirect_data_;
474    size_t indirect_data_size_;
475    size_t indirect_data_capacity_;
476    Error error_;
477};
478
479class AuthorizationSetBuilder {
480  public:
481    template <typename TagType, typename ValueType>
482    AuthorizationSetBuilder& Authorization(TagType tag, ValueType value) {
483        set.push_back(tag, value);
484        return *this;
485    }
486
487    template <keymaster_tag_t Tag>
488    AuthorizationSetBuilder& Authorization(TypedTag<KM_BOOL, Tag> tag) {
489        set.push_back(tag);
490        return *this;
491    }
492
493    template <keymaster_tag_t Tag>
494    AuthorizationSetBuilder& Authorization(TypedTag<KM_INVALID, Tag> tag) {
495        keymaster_key_param_t param;
496        param.tag = tag;
497        set.push_back(param);
498        return *this;
499    }
500
501    template <keymaster_tag_t Tag>
502    AuthorizationSetBuilder& Authorization(TypedTag<KM_BYTES, Tag> tag, const uint8_t* data,
503                                           size_t data_length) {
504        set.push_back(tag, data, data_length);
505        return *this;
506    }
507
508    template <keymaster_tag_t Tag>
509    AuthorizationSetBuilder& Authorization(TypedTag<KM_BYTES, Tag> tag, const char* data,
510                                           size_t data_length) {
511        return Authorization(tag, reinterpret_cast<const uint8_t*>(data), data_length);
512    }
513
514    AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent);
515    AuthorizationSetBuilder& EcdsaKey(uint32_t key_size);
516    AuthorizationSetBuilder& AesKey(uint32_t key_size);
517    AuthorizationSetBuilder& HmacKey(uint32_t key_size);
518
519    AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent);
520    AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent);
521    AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size);
522    AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size);
523
524    AuthorizationSetBuilder& SigningKey();
525    AuthorizationSetBuilder& EncryptionKey();
526    AuthorizationSetBuilder& NoDigestOrPadding();
527    AuthorizationSetBuilder& EcbMode();
528
529    AuthorizationSetBuilder& Digest(keymaster_digest_t digest) {
530        return Authorization(TAG_DIGEST, digest);
531    }
532
533    AuthorizationSetBuilder& Padding(keymaster_padding_t padding) {
534        return Authorization(TAG_PADDING, padding);
535    }
536
537    AuthorizationSetBuilder& Deduplicate() {
538        set.Deduplicate();
539        return *this;
540    }
541
542    AuthorizationSet build() const { return set; }
543
544  private:
545    friend AuthorizationSet;
546    AuthorizationSet set;
547};
548
549inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
550                                                                uint64_t public_exponent) {
551    Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA);
552    Authorization(TAG_KEY_SIZE, key_size);
553    Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
554    return *this;
555}
556
557inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) {
558    Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC);
559    Authorization(TAG_KEY_SIZE, key_size);
560    return *this;
561}
562
563inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
564    Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES);
565    return Authorization(TAG_KEY_SIZE, key_size);
566}
567
568inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) {
569    Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC);
570    Authorization(TAG_KEY_SIZE, key_size);
571    return SigningKey();
572}
573
574inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
575                                                                       uint64_t public_exponent) {
576    RsaKey(key_size, public_exponent);
577    return SigningKey();
578}
579
580inline AuthorizationSetBuilder&
581AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) {
582    RsaKey(key_size, public_exponent);
583    return EncryptionKey();
584}
585
586inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
587    EcdsaKey(key_size);
588    return SigningKey();
589}
590
591inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
592    AesKey(key_size);
593    return EncryptionKey();
594}
595
596inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
597    Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN);
598    return Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY);
599}
600
601inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
602    Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
603    return Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
604}
605
606inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
607    Authorization(TAG_DIGEST, KM_DIGEST_NONE);
608    return Authorization(TAG_PADDING, KM_PAD_NONE);
609}
610
611inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
612    return Authorization(TAG_BLOCK_MODE, KM_MODE_ECB);
613}
614
615}  // namespace keymaster
616
617#endif  // SYSTEM_KEYMASTER_KEY_AUTHORIZATION_SET_H_
618