1 /*
2  * Copyright 2015 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 GOOGLE_GATEKEEPER_UTILS_H_
18 #define GOOGLE_GATEKEEPER_UTILS_H_
19 
20 #include <string.h>
21 
22 namespace gatekeeper {
23 /**
24  * Variant of memset() that uses GCC-specific pragmas to disable optimizations, so effect is not
25  * optimized away.  This is important because we often need to wipe blocks of sensitive data from
26  * memory.  As an additional convenience, this implementation avoids writing to NULL pointers.
27  */
28 #ifdef __clang__
29 #define OPTNONE __attribute__((optnone))
30 #else  // not __clang__
31 #define OPTNONE __attribute__((optimize("O0")))
32 #endif  // not __clang__
memset_s(void * s,int c,size_t n)33 inline OPTNONE void* memset_s(void* s, int c, size_t n) {
34     if (!s)
35         return s;
36     return memset(s, c, n);
37 }
38 #undef OPTNONE
39 
40 /**
41  * Return the number of elements in array \p a.
42  */
array_length(const T (&)[N])43 template <typename T, size_t N> inline size_t array_length(const T (&)[N]) {
44     return N;
45 }
46 
memcmp_s(const void * p1,const void * p2,size_t length)47 static inline int memcmp_s(const void* p1, const void* p2, size_t length) {
48     const uint8_t* s1 = static_cast<const uint8_t*>(p1);
49     const uint8_t* s2 = static_cast<const uint8_t*>(p2);
50     uint8_t result = 0;
51     for (; length > 0; length--)
52         result |= *s1++ ^ *s2++;
53     return result == 0 ? 0 : 1;
54 }
55 
56 template<typename T> struct remove_reference      {typedef T type;};
57 template<typename T> struct remove_reference<T&>  {typedef T type;};
58 template<typename T> struct remove_reference<T&&> {typedef T type;};
59 template<typename T>
60 using remove_reference_t = typename remove_reference<T>::type;
61 template<typename T>
62 remove_reference_t<T>&& move(T&& x) {
63     return static_cast<remove_reference_t<T>&&>(x);
64 }
65 
66 template<typename T>
67 constexpr T&& forward(remove_reference_t<T>& x) {
68     return static_cast<T&&>(x);
69 }
70 template<typename T>
71 constexpr T&& forward(remove_reference_t<T>&& x) {
72     return static_cast<T&&>(x);
73 }
74 
75 
76 };
77 #endif //GOOGLE_GATEKEEPER_UTILS_H_
78