Home | History | Annotate | Download | only in keymaster
      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_GOOGLE_KEYMASTER_UTILS_H_
     18 #define SYSTEM_KEYMASTER_GOOGLE_KEYMASTER_UTILS_H_
     19 
     20 #include <stdint.h>
     21 #include <string.h>
     22 #include <time.h>  // for time_t.
     23 
     24 #include <UniquePtr.h>
     25 
     26 #include <keymaster/serializable.h>
     27 
     28 namespace keymaster {
     29 
     30 /**
     31  * Convert the specified time value into "Java time", which is a signed 64-bit integer representing
     32  * elapsed milliseconds since Jan 1, 1970.
     33  */
     34 inline int64_t java_time(time_t time) {
     35     // The exact meaning of a time_t value is implementation-dependent.  If this code is ported to a
     36     // platform that doesn't define it as "seconds since Jan 1, 1970 UTC", this function will have
     37     // to be revised.
     38     return time * 1000;
     39 }
     40 
     41 /*
     42  * Array Manipulation functions.  This set of templated inline functions provides some nice tools
     43  * for operating on c-style arrays.  C-style arrays actually do have a defined size associated with
     44  * them, as long as they are not allowed to decay to a pointer.  These template methods exploit this
     45  * to allow size-based array operations without explicitly specifying the size.  If passed a pointer
     46  * rather than an array, they'll fail to compile.
     47  */
     48 
     49 /**
     50  * Return the size in bytes of the array \p a.
     51  */
     52 template <typename T, size_t N> inline size_t array_size(const T (&a)[N]) {
     53     return sizeof(a);
     54 }
     55 
     56 /**
     57  * Return the number of elements in array \p a.
     58  */
     59 template <typename T, size_t N> inline size_t array_length(const T (&)[N]) {
     60     return N;
     61 }
     62 
     63 /**
     64  * Duplicate the array \p a.  The memory for the new array is allocated and the caller takes
     65  * responsibility.  Note that the dup is necessarily returned as a pointer, so size is lost.  Call
     66  * array_length() on the original array to discover the size.
     67  */
     68 template <typename T, size_t N> inline T* dup_array(const T (&a)[N]) {
     69     T* dup = new T[N];
     70     if (dup != NULL) {
     71         memcpy(dup, &a, array_size(a));
     72     }
     73     return dup;
     74 }
     75 
     76 /**
     77  * Duplicate the buffer \p buf.  The memory for the new buffer is allocated and the caller takes
     78  * responsibility.
     79  */
     80 uint8_t* dup_buffer(const void* buf, size_t size);
     81 
     82 /**
     83  * Copy the contents of array \p arr to \p dest.
     84  */
     85 template <typename T, size_t N> inline void copy_array(const T (&arr)[N], T* dest) {
     86     for (size_t i = 0; i < N; ++i)
     87         dest[i] = arr[i];
     88 }
     89 
     90 /**
     91  * Search array \p a for value \p val, returning true if found.  Note that this function is
     92  * early-exit, meaning that it should not be used in contexts where timing analysis attacks could be
     93  * a concern.
     94  */
     95 template <typename T, size_t N> inline bool array_contains(const T (&a)[N], T val) {
     96     for (size_t i = 0; i < N; ++i) {
     97         if (a[i] == val) {
     98             return true;
     99         }
    100     }
    101     return false;
    102 }
    103 
    104 /**
    105  * Variant of memset() that uses GCC-specific pragmas to disable optimizations, so effect is not
    106  * optimized away.  This is important because we often need to wipe blocks of sensitive data from
    107  * memory.  As an additional convenience, this implementation avoids writing to NULL pointers.
    108  */
    109 #ifdef KEYMASTER_CLANG_TEST_BUILD
    110 #define OPTIMIZE(x)
    111 #else  // not KEYMASTER_CLANG_TEST_BUILD
    112 #define OPTIMIZE(x) __attribute__((optimize(x)))
    113 #endif  // not KEYMASTER_CLANG_TEST_BUILD
    114 inline OPTIMIZE("O0") void* memset_s(void* s, int c, size_t n) {
    115     if (!s)
    116         return s;
    117     return memset(s, c, n);
    118 }
    119 #undef OPTIMIZE
    120 
    121 /**
    122  * Variant of memcmp that has the same runtime regardless of whether the data matches (i.e. doesn't
    123  * short-circuit).  Not an exact equivalent to memcmp because it doesn't return <0 if p1 < p2, just
    124  * 0 for match and non-zero for non-match.
    125  */
    126 int memcmp_s(const void* p1, const void* p2, size_t length);
    127 
    128 /**
    129  * Eraser clears buffers.  Construct it with a buffer or object and the destructor will ensure that
    130  * it is zeroed.
    131  */
    132 class Eraser {
    133   public:
    134     /* Not implemented.  If this gets used, we want a link error. */
    135     template <typename T> explicit Eraser(T* t);
    136 
    137     template <typename T>
    138     explicit Eraser(T& t)
    139         : buf_(reinterpret_cast<uint8_t*>(&t)), size_(sizeof(t)) {}
    140 
    141     template <size_t N> explicit Eraser(uint8_t (&arr)[N]) : buf_(arr), size_(N) {}
    142 
    143     Eraser(void* buf, size_t size) : buf_(static_cast<uint8_t*>(buf)), size_(size) {}
    144     ~Eraser() { memset_s(buf_, 0, size_); }
    145 
    146   private:
    147     Eraser(const Eraser&);
    148     void operator=(const Eraser&);
    149 
    150     uint8_t* buf_;
    151     size_t size_;
    152 };
    153 
    154 }  // namespace keymaster
    155 
    156 #endif  // SYSTEM_KEYMASTER_GOOGLE_KEYMASTER_UTILS_H_
    157