]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/cc.h
4ea8e63d08b117dd3177f68587c33f156d5c18d6
[apple/xnu.git] / EXTERNAL_HEADERS / corecrypto / cc.h
1 /* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
2 *
3 * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which
4 * is contained in the License.txt file distributed with corecrypto) and only to
5 * people who accept that license. IMPORTANT: Any license rights granted to you by
6 * Apple Inc. (if any) are limited to internal use within your organization only on
7 * devices and computers you own or control, for the sole purpose of verifying the
8 * security characteristics and correct functioning of the Apple Software. You may
9 * not, directly or indirectly, redistribute the Apple Software or any portions thereof.
10 */
11
12 #ifndef _CORECRYPTO_CC_H_
13 #define _CORECRYPTO_CC_H_
14
15 #include <corecrypto/cc_config.h>
16 #include <corecrypto/cc_error.h>
17 #include <string.h>
18 #include <stdint.h>
19
20 #if __has_feature(attribute_availability_with_replacement)
21 #if __has_feature(attribute_availability_bridgeos)
22 #ifndef __CC_BRIDGE_OS_DEPRECATED
23 #define __CC_BRIDGEOS_DEPRECATED(_dep, _msg) __attribute__((availability(bridgeos,deprecated=_dep, replacement=_msg)))
24 #endif
25 #endif
26
27 #ifndef __CC_BRIDGEOS_DEPRECATED
28 #define __CC_BRIDGEOS_DEPRECATED(_dep, _msg)
29 #endif
30
31 #define cc_deprecate_with_replacement(replacement_message, ios_version, macos_version, tvos_version, watchos_version, bridgeos_version) \
32 __attribute__((availability(macos,deprecated=macos_version, replacement=replacement_message)))\
33 __attribute__((availability(ios,deprecated=ios_version, replacement=replacement_message)))\
34 __attribute__((availability(watchos,deprecated=watchos_version, replacement=replacement_message)))\
35 __attribute__((availability(tvos,deprecated=tvos_version, replacement=replacement_message)))\
36 __CC_BRIDGEOS_DEPRECATED(bridgeos_version, replacement_message)
37
38 #else /* !__has_feature(attribute_availability_with_replacement) */
39
40 #define cc_deprecate_with_replacement(replacement_message, ios_version, macos_version, tvos_version, watchos_version, bridgeos_version)
41
42 #endif /* __has_feature(attribute_availability_with_replacement) */
43
44 /* Provide a general purpose macro concat method. */
45 #define cc_concat_(a, b) a##b
46 #define cc_concat(a, b) cc_concat_(a, b)
47
48 #if defined(_MSC_VER)
49 #define __asm__(x)
50 #endif
51
52 /* Manage asserts here because a few functions in header public files do use asserts */
53 #if CORECRYPTO_DEBUG
54 #define cc_assert(x) assert(x)
55 #else
56 #define cc_assert(x)
57 #endif
58
59 #if CC_KERNEL
60 #include <kern/assert.h>
61 #elif CC_USE_S3
62 #define assert(args) // No assert in S3
63 #else
64 #include <assert.h>
65 #endif
66
67 /* Provide a static assert that can be used to create compile-type failures. */
68 #define cc_static_assert(e,m) \
69 enum { cc_concat(static_assert_, __COUNTER__) = 1/(int)(!!(e)) }
70
71 /* Declare a struct element with a guarenteed alignment of _alignment_.
72 The resulting struct can be used to create arrays that are aligned by
73 a certain amount. */
74 #define cc_aligned_struct(_alignment_) \
75 typedef struct { \
76 uint8_t b[_alignment_]; \
77 } CC_ALIGNED(_alignment_)
78
79 #if defined(__BIGGEST_ALIGNMENT__)
80 #define CC_MAX_ALIGNMENT ((size_t)__BIGGEST_ALIGNMENT__)
81 #else
82 #define CC_MAX_ALIGNMENT ((size_t)16)
83 #endif
84
85 /* pads a given size to be a multiple of the biggest alignment for any type */
86 #define cc_pad_align(_size_) ((_size_ + CC_MAX_ALIGNMENT - 1) & (~(CC_MAX_ALIGNMENT - 1)))
87
88 /* number of array elements used in a cc_ctx_decl */
89 #define cc_ctx_n(_type_, _size_) ((_size_ + sizeof(_type_) - 1) / sizeof(_type_))
90
91 /* sizeof of a context declared with cc_ctx_decl */
92 #define cc_ctx_sizeof(_type_, _size_) sizeof(_type_[cc_ctx_n(_type_, _size_)])
93
94 /*
95 1. _alloca cannot be removed becasue this header file is compiled with both MSVC++ and with clang.
96 2. The _MSC_VER version of cc_ctx_decl() is not compatible with the way *_decl macros as used in CommonCrypto, AppleKeyStore and SecurityFrameworks. To observe the incompatibilities and errors, use below definition. Corecrypto itself, accepts both deinitions
97 #define cc_ctx_decl(_type_, _size_, _name_) _type_ _name_ ## _array[cc_ctx_n(_type_, (_size_))]; _type_ *_name_ = _name_ ## _array
98 3. Never use sizeof() operator for the variables declared with cc_ctx_decl(), because it is not be compatible with the _MSC_VER version of cc_ctx_decl().
99 */
100 #if defined(_MSC_VER)
101 #include <malloc.h>
102 #define cc_ctx_decl(_type_, _size_, _name_) _type_ * _name_ = (_type_ *) _alloca(sizeof(_type_) * cc_ctx_n(_type_, _size_) )
103 #define cc_ctx_decl_field(_type_, _size_, _name_) _type_ _name_ [cc_ctx_n(_type_, _size_)]
104 #else
105 // FIXME <rdar://problem/57372917> this pragma is the wrong fix for VLA usage, but since this API is central to corecrypto it's difficult to remove VLAs. The macro is then used in many other projects who don't need to be warned about VLAs at the moment. It's therefore desirable to silence the diagnostic and let corecrypto deal with removing VLAs.
106 #define cc_ctx_decl(_type_, _size_, _name_) \
107 _Pragma("GCC diagnostic push") \
108 _Pragma("GCC diagnostic ignored \"-Wvla\"") \
109 _type_ _name_ [cc_ctx_n(_type_, _size_)] \
110 _Pragma("GCC diagnostic pop")
111 #define cc_ctx_decl_field cc_ctx_decl
112 #endif
113
114 /*!
115 @brief cc_clear(len, dst) zeroizes array dst and it will not be optimized out.
116 @discussion It is used to clear sensitive data, particularly when the are defined in the stack
117 @param len number of bytes to be cleared in dst
118 @param dst input array
119 */
120 CC_NONNULL((2))
121 void cc_clear(size_t len, void *dst);
122
123 // cc_zero is deprecated, please use cc_clear instead.
124 cc_deprecate_with_replacement("cc_clear", 13.0, 10.15, 13.0, 6.0, 4.0)
125 CC_NONNULL_ALL CC_INLINE
126 void cc_zero(size_t len, void *dst)
127 {
128 cc_clear(len, dst);
129 }
130
131 #define cc_copy(_size_, _dst_, _src_) memcpy(_dst_, _src_, _size_)
132
133 CC_INLINE CC_NONNULL((2, 3, 4))
134 void cc_xor(size_t size, void *r, const void *s, const void *t) {
135 uint8_t *_r=(uint8_t *)r;
136 const uint8_t *_s=(const uint8_t *)s;
137 const uint8_t *_t=(const uint8_t *)t;
138 while (size--) {
139 _r[size] = _s[size] ^ _t[size];
140 }
141 }
142
143 /*!
144 @brief cc_cmp_safe(num, pt1, pt2) compares two array ptr1 and ptr2 of num bytes.
145 @discussion The execution time/cycles is independent of the data and therefore guarantees no leak about the data. However, the execution time depends on num.
146 @param num number of bytes in each array
147 @param ptr1 input array
148 @param ptr2 input array
149 @return returns 0 if the num bytes starting at ptr1 are identical to the num bytes starting at ptr2 and 1 if they are different or if num is 0 (empty arrays).
150 */
151 CC_NONNULL((2, 3))
152 int cc_cmp_safe (size_t num, const void * ptr1, const void * ptr2);
153
154 /* Exchange S and T of any type. NOTE: Both and S and T are evaluated
155 mutliple times and MUST NOT be expressions. */
156 #define CC_SWAP(S,T) do { \
157 volatile __typeof__(S) _cc_swap_tmp = S; S = T; T = _cc_swap_tmp; \
158 _cc_swap_tmp = 0;\
159 } while(0)
160
161 /* Return the maximum value between S and T. */
162 #define CC_MAX(S, T) ({__typeof__(S) _cc_max_s = S; __typeof__(T) _cc_max_t = T; _cc_max_s > _cc_max_t ? _cc_max_s : _cc_max_t;})
163
164 /* Clone of CC_MAX() that evalutes S and T multiple times to allow nesting. */
165 #define CC_MAX_EVAL(S, T) ((S) > (T) ? (S) : (T))
166
167 /* Return the minimum value between S and T. */
168 #define CC_MIN(S, T) ({__typeof__(S) _cc_min_s = S; __typeof__(T) _cc_min_t = T; _cc_min_s <= _cc_min_t ? _cc_min_s : _cc_min_t;})
169
170 #endif /* _CORECRYPTO_CC_H_ */