• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ANDROID_KEYMASTER_UTILS_H_
18 #define SYSTEM_KEYMASTER_ANDROID_KEYMASTER_UTILS_H_
19 
20 #include <stdint.h>
21 #ifndef  __clang__
22 // We need to diable foritfy level for memset in gcc because we want to use
23 // memset unoptimized. This would falsely trigger __warn_memset_zero_len in
24 // /usr/include/bits/string3.h. The inline checking function is only supposed to
25 // work when the optimization level is at least 1.
26 #pragma push_macro("__USE_FORTIFY_LEVEL")
27 #undef __USE_FORTIFY_LEVEL
28 #endif
29 #include <string.h>
30 #ifndef  __clang__
31 #pragma pop_macro("__USE_FORTIFY_LEVEL")
32 #endif
33 #include <time.h>  // for time_t.
34 
35 #include <keymaster/UniquePtr.h>
36 
37 #include <hardware/keymaster_defs.h>
38 #include <keymaster/serializable.h>
39 
40 #ifndef __has_cpp_attribute
41 #define __has_cpp_attribute(x) 0
42 #endif
43 
44 // Mark intentional fallthroughts in switch statements to silence
45 // -Wimplicit-fallthrough.
46 #if __has_cpp_attribute(clang::fallthrough)
47 #define FALLTHROUGH [[clang::fallthrough]]
48 #else
49 #define FALLTHROUGH
50 #endif
51 
52 namespace keymaster {
53 
54 /**
55  * Convert the specified time value into "Java time", which is a signed 64-bit integer representing
56  * elapsed milliseconds since Jan 1, 1970.
57  */
java_time(time_t time)58 inline int64_t java_time(time_t time) {
59     // The exact meaning of a time_t value is implementation-dependent.  If this code is ported to a
60     // platform that doesn't define it as "seconds since Jan 1, 1970 UTC", this function will have
61     // to be revised.
62     return static_cast<int64_t>(time) * 1000;
63 }
64 
65 /*
66  * Array Manipulation functions.  This set of templated inline functions provides some nice tools
67  * for operating on c-style arrays.  C-style arrays actually do have a defined size associated with
68  * them, as long as they are not allowed to decay to a pointer.  These template methods exploit this
69  * to allow size-based array operations without explicitly specifying the size.  If passed a pointer
70  * rather than an array, they'll fail to compile.
71  */
72 
73 /**
74  * Return the size in bytes of the array \p a.
75  */
array_size(const T (& a)[N])76 template <typename T, size_t N> inline size_t array_size(const T (&a)[N]) {
77     return sizeof(a);
78 }
79 
80 /**
81  * Return the number of elements in array \p a.
82  */
array_length(const T (&)[N])83 template <typename T, size_t N> inline size_t array_length(const T (&)[N]) {
84     return N;
85 }
86 
87 /**
88  * Duplicate the array \p a.  The memory for the new array is allocated and the caller takes
89  * responsibility.
90  */
dup_array(const T * a,size_t n)91 template <typename T> inline T* dup_array(const T* a, size_t n) {
92     T* dup = new (std::nothrow) T[n];
93     if (dup)
94         for (size_t i = 0; i < n; ++i)
95             dup[i] = a[i];
96     return dup;
97 }
98 
99 /**
100  * Duplicate the array \p a.  The memory for the new array is allocated and the caller takes
101  * responsibility.  Note that the dup is necessarily returned as a pointer, so size is lost.  Call
102  * array_length() on the original array to discover the size.
103  */
dup_array(const T (& a)[N])104 template <typename T, size_t N> inline T* dup_array(const T (&a)[N]) {
105     return dup_array(a, N);
106 }
107 
108 /**
109  * Duplicate the buffer \p buf.  The memory for the new buffer is allocated and the caller takes
110  * responsibility.
111  */
112 uint8_t* dup_buffer(const void* buf, size_t size);
113 
114 /**
115  * Copy the contents of array \p arr to \p dest.
116  */
copy_array(const T (& arr)[N],T * dest)117 template <typename T, size_t N> inline void copy_array(const T (&arr)[N], T* dest) {
118     for (size_t i = 0; i < N; ++i)
119         dest[i] = arr[i];
120 }
121 
122 /**
123  * Search array \p a for value \p val, returning true if found.  Note that this function is
124  * early-exit, meaning that it should not be used in contexts where timing analysis attacks could be
125  * a concern.
126  */
array_contains(const T (& a)[N],T val)127 template <typename T, size_t N> inline bool array_contains(const T (&a)[N], T val) {
128     for (size_t i = 0; i < N; ++i) {
129         if (a[i] == val) {
130             return true;
131         }
132     }
133     return false;
134 }
135 
136 /**
137  * Variant of memset() that uses GCC-specific pragmas to disable optimizations, so effect is not
138  * optimized away.  This is important because we often need to wipe blocks of sensitive data from
139  * memory.  As an additional convenience, this implementation avoids writing to NULL pointers.
140  */
141 #ifdef __clang__
142 #define OPTNONE __attribute__((optnone))
143 #else  // not __clang__
144 #define OPTNONE __attribute__((optimize("O0")))
145 #endif  // not __clang__
memset_s(void * s,int c,size_t n)146 inline OPTNONE void* memset_s(void* s, int c, size_t n) {
147     if (!s)
148         return s;
149     return memset(s, c, n);
150 }
151 #undef OPTNONE
152 
153 /**
154  * Variant of memcmp that has the same runtime regardless of whether the data matches (i.e. doesn't
155  * short-circuit).  Not an exact equivalent to memcmp because it doesn't return <0 if p1 < p2, just
156  * 0 for match and non-zero for non-match.
157  */
158 int memcmp_s(const void* p1, const void* p2, size_t length);
159 
160 /**
161  * Eraser clears buffers.  Construct it with a buffer or object and the destructor will ensure that
162  * it is zeroed.
163  */
164 class Eraser {
165   public:
166     /* Not implemented.  If this gets used, we want a link error. */
167     template <typename T> explicit Eraser(T* t);
168 
169     template <typename T>
Eraser(T & t)170     explicit Eraser(T& t) : buf_(reinterpret_cast<uint8_t*>(&t)), size_(sizeof(t)) {}
171 
Eraser(uint8_t (& arr)[N])172     template <size_t N> explicit Eraser(uint8_t (&arr)[N]) : buf_(arr), size_(N) {}
173 
Eraser(void * buf,size_t size)174     Eraser(void* buf, size_t size) : buf_(static_cast<uint8_t*>(buf)), size_(size) {}
~Eraser()175     ~Eraser() { memset_s(buf_, 0, size_); }
176 
177   private:
178     Eraser(const Eraser&);
179     void operator=(const Eraser&);
180 
181     uint8_t* buf_;
182     size_t size_;
183 };
184 
185 /**
186  * ArrayWrapper is a trivial wrapper around a C-style array that provides begin() and end()
187  * methods. This is primarily to facilitate range-based iteration on arrays.  It does not copy, nor
188  * does it take ownership; it just holds pointers.
189  */
190 template <typename T> class ArrayWrapper {
191   public:
ArrayWrapper(T * array,size_t size)192     ArrayWrapper(T* array, size_t size) : begin_(array), end_(array + size) {}
193 
begin()194     T* begin() { return begin_; }
end()195     T* end() { return end_; }
196 
197   private:
198     T* begin_;
199     T* end_;
200 };
201 
array_range(T * begin,size_t length)202 template <typename T> ArrayWrapper<T> array_range(T* begin, size_t length) {
203     return ArrayWrapper<T>(begin, length);
204 }
205 
array_range(T (& a)[n])206 template <typename T, size_t n> ArrayWrapper<T> array_range(T (&a)[n]) {
207     return ArrayWrapper<T>(a, n);
208 }
209 
210 /**
211  * Convert any unsigned integer from network to host order.  We implement this here rather than
212  * using the functions from arpa/inet.h because the TEE doesn't have inet.h.  This isn't the most
213  * efficient implementation, but the compiler should unroll the loop and tighten it up.
214  */
ntoh(T t)215 template <typename T> T ntoh(T t) {
216     const uint8_t* byte_ptr = reinterpret_cast<const uint8_t*>(&t);
217     T retval = 0;
218     for (size_t i = 0; i < sizeof(t); ++i) {
219         retval <<= 8;
220         retval |= byte_ptr[i];
221     }
222     return retval;
223 }
224 
225 /**
226  * Convert any unsigned integer from host to network order.  We implement this here rather than
227  * using the functions from arpa/inet.h because the TEE doesn't have inet.h.  This isn't the most
228  * efficient implementation, but the compiler should unroll the loop and tighten it up.
229  */
hton(T t)230 template <typename T> T hton(T t) {
231     T retval;
232     uint8_t* byte_ptr = reinterpret_cast<uint8_t*>(&retval);
233     for (size_t i = sizeof(t); i > 0; --i) {
234         byte_ptr[i - 1] = t & 0xFF;
235         t >>= 8;
236     }
237     return retval;
238 }
239 
240 inline
accessBlobData(const keymaster_key_blob_t * blob)241 const uint8_t* const & accessBlobData(const keymaster_key_blob_t* blob) {
242     return blob->key_material;
243 }
244 inline
accessBlobData(keymaster_key_blob_t * blob)245 const uint8_t*& accessBlobData(keymaster_key_blob_t* blob) {
246     return blob->key_material;
247 }
248 inline
accessBlobSize(const keymaster_key_blob_t * blob)249 const size_t& accessBlobSize(const keymaster_key_blob_t* blob) {
250     return blob->key_material_size;
251 }
252 inline
accessBlobSize(keymaster_key_blob_t * blob)253 size_t& accessBlobSize(keymaster_key_blob_t* blob) {
254     return blob->key_material_size;
255 }
256 
257 inline
accessBlobData(const keymaster_blob_t * blob)258 const uint8_t* const & accessBlobData(const keymaster_blob_t* blob) {
259     return blob->data;
260 }
261 inline
accessBlobData(keymaster_blob_t * blob)262 const uint8_t*& accessBlobData(keymaster_blob_t* blob) {
263     return blob->data;
264 }
265 inline
accessBlobSize(const keymaster_blob_t * blob)266 const size_t & accessBlobSize(const keymaster_blob_t* blob) {
267     return blob->data_length;
268 }
269 inline
accessBlobSize(keymaster_blob_t * blob)270 size_t& accessBlobSize(keymaster_blob_t* blob) {
271     return blob->data_length;
272 }
273 
274 /**
275  * TKeymasterBlob is a very simple extension of the C structs keymaster_blob_t and
276  * keymaster_key_blob_t.  It manages its own memory, which makes avoiding memory leaks
277  * much easier.
278  */
279 template <typename BlobType>
280 struct TKeymasterBlob : public BlobType {
TKeymasterBlobTKeymasterBlob281     TKeymasterBlob() {
282         accessBlobData(this) = nullptr;
283         accessBlobSize(this) = 0;
284     }
285 
TKeymasterBlobTKeymasterBlob286     TKeymasterBlob(const uint8_t* data, size_t size) {
287         accessBlobSize(this) = 0;
288         accessBlobData(this) = dup_buffer(data, size);
289         if (accessBlobData(this))
290             accessBlobSize(this) = size;
291     }
292 
TKeymasterBlobTKeymasterBlob293     explicit TKeymasterBlob(size_t size) {
294         accessBlobSize(this) = 0;
295         accessBlobData(this) = new (std::nothrow) uint8_t[size];
296         if (accessBlobData(this))
297             accessBlobSize(this) = size;
298     }
299 
TKeymasterBlobTKeymasterBlob300     explicit TKeymasterBlob(const BlobType& blob) {
301         accessBlobSize(this) = 0;
302         accessBlobData(this) = dup_buffer(accessBlobData(&blob), accessBlobSize(&blob));
303         if (accessBlobData(this))
304             accessBlobSize(this) = accessBlobSize(&blob);
305     }
306 
307     template<size_t N>
TKeymasterBlobTKeymasterBlob308     explicit TKeymasterBlob(const uint8_t (&data)[N]) {
309         accessBlobSize(this) = 0;
310         accessBlobData(this) = dup_buffer(data, N);
311         if (accessBlobData(this))
312             accessBlobSize(this) = N;
313     }
314 
TKeymasterBlobTKeymasterBlob315     TKeymasterBlob(const TKeymasterBlob& blob) {
316         accessBlobSize(this) = 0;
317         accessBlobData(this) = dup_buffer(accessBlobData(&blob), accessBlobSize(&blob));
318         if (accessBlobData(this))
319             accessBlobSize(this) = accessBlobSize(&blob);
320     }
321 
TKeymasterBlobTKeymasterBlob322     TKeymasterBlob(TKeymasterBlob&& rhs) {
323         accessBlobSize(this) = accessBlobSize(&rhs);
324         accessBlobData(this) = accessBlobData(&rhs);
325         accessBlobSize(&rhs) = 0;
326         accessBlobData(&rhs) = nullptr;
327     }
328 
329     TKeymasterBlob& operator=(const TKeymasterBlob& blob) {
330         if (this != &blob) {
331             Clear();
332             accessBlobData(this) = dup_buffer(accessBlobData(&blob), accessBlobSize(&blob));
333             accessBlobSize(this) = accessBlobSize(&blob);
334         }
335         return *this;
336     }
337 
338     TKeymasterBlob& operator=(TKeymasterBlob&& rhs) {
339         if (this != &rhs) {
340             Clear();
341             accessBlobSize(this) = accessBlobSize(&rhs);
342             accessBlobData(this) = accessBlobData(&rhs);
343             accessBlobSize(&rhs) = 0;
344             accessBlobData(&rhs) = nullptr;
345         }
346         return *this;
347     }
348 
~TKeymasterBlobTKeymasterBlob349     ~TKeymasterBlob() { Clear(); }
350 
beginTKeymasterBlob351     const uint8_t* begin() const { return accessBlobData(this); }
endTKeymasterBlob352     const uint8_t* end() const { return accessBlobData(this) + accessBlobSize(this); }
353 
ClearTKeymasterBlob354     void Clear() {
355         if (accessBlobSize(this)) {
356             memset_s(const_cast<uint8_t*>(accessBlobData(this)), 0, accessBlobSize(this));
357         }
358         delete[] accessBlobData(this);
359         accessBlobData(this) = nullptr;
360         accessBlobSize(this) = 0;
361     }
362 
ResetTKeymasterBlob363     const uint8_t* Reset(size_t new_size) {
364         Clear();
365         accessBlobData(this) = new (std::nothrow) uint8_t[new_size];
366         if (accessBlobData(this))
367             accessBlobSize(this) = new_size;
368         return accessBlobData(this);
369     }
370 
371     // The key_material in keymaster_key_blob_t is const, which is the right thing in most
372     // circumstances, but occasionally we do need to write into it.  This method exposes a non-const
373     // version of the pointer.  Use sparingly.
writable_dataTKeymasterBlob374     uint8_t* writable_data() { return const_cast<uint8_t*>(accessBlobData(this)); }
375 
releaseTKeymasterBlob376     BlobType release() {
377         BlobType tmp = {accessBlobData(this), accessBlobSize(this)};
378         accessBlobData(this) = nullptr;
379         accessBlobSize(this) = 0;
380         return tmp;
381     }
382 
SerializedSizeTKeymasterBlob383     size_t SerializedSize() const { return sizeof(uint32_t) + accessBlobSize(this); }
SerializeTKeymasterBlob384     uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const {
385         return append_size_and_data_to_buf(buf, end, accessBlobData(this), accessBlobSize(this));
386     }
387 
DeserializeTKeymasterBlob388     bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
389         Clear();
390         UniquePtr<uint8_t[]> tmp;
391         if (!copy_size_and_data_from_buf(buf_ptr, end, &accessBlobSize(this), &tmp)) {
392             accessBlobData(this) = nullptr;
393             accessBlobSize(this) = 0;
394             return false;
395         }
396         accessBlobData(this) = tmp.release();
397         return true;
398     }
399 };
400 
401 typedef TKeymasterBlob<keymaster_blob_t> KeymasterBlob;
402 typedef TKeymasterBlob<keymaster_key_blob_t> KeymasterKeyBlob;
403 
404 struct Characteristics_Delete {
operatorCharacteristics_Delete405     void operator()(keymaster_key_characteristics_t* p) {
406         keymaster_free_characteristics(p);
407         free(p);
408     }
409 };
410 
411 struct Malloc_Delete {
operatorMalloc_Delete412     void operator()(void* p) { free(p); }
413 };
414 
415 struct CertificateChainDelete {
operatorCertificateChainDelete416     void operator()(keymaster_cert_chain_t* p) {
417         if (!p)
418             return;
419         for (size_t i = 0; i < p->entry_count; ++i)
420             delete[] p->entries[i].data;
421         delete[] p->entries;
422         delete p;
423     }
424 };
425 
426 typedef UniquePtr<keymaster_cert_chain_t, CertificateChainDelete> CertChainPtr;
427 
428 keymaster_error_t EcKeySizeToCurve(uint32_t key_size_bits, keymaster_ec_curve_t* curve);
429 keymaster_error_t EcCurveToKeySize(keymaster_ec_curve_t curve, uint32_t* key_size_bits);
430 
431 template<typename T> struct remove_reference      {typedef T type;};
432 template<typename T> struct remove_reference<T&>  {typedef T type;};
433 template<typename T> struct remove_reference<T&&> {typedef T type;};
434 template<typename T>
435 using remove_reference_t = typename remove_reference<T>::type;
436 template<typename T>
437 remove_reference_t<T>&& move(T&& x) {
438     return static_cast<remove_reference_t<T>&&>(x);
439 }
440 
441 template<typename T>
442 constexpr T&& forward(remove_reference_t<T>& x) {
443     return static_cast<T&&>(x);
444 }
445 template<typename T>
446 constexpr T&& forward(remove_reference_t<T>&& x) {
447     return static_cast<T&&>(x);
448 }
449 
450 template <class F> class final_action {
451   public:
452     explicit final_action(F f) : f_(move(f)) {}
453     ~final_action() { f_(); }
454 
455   private:
456     F f_;
457 };
458 
459 template <class F> inline final_action<F> finally(const F& f) {
460     return final_action<F>(f);
461 }
462 
463 }  // namespace keymaster
464 
465 #endif  // SYSTEM_KEYMASTER_ANDROID_KEYMASTER_UTILS_H_
466