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