1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
4 * All rights reserved.
5 ******************************************************************************/
6 #ifndef AUX_UTIL_H
7 #define AUX_UTIL_H
8
9 #include <stdbool.h>
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13 #include "tss2_tpm2_types.h"
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 #define SAFE_FREE(S) if((S) != NULL) {free((void*) (S)); (S)=NULL;}
19
20 #define TPM2_ERROR_FORMAT "%s%s (0x%08x)"
21 #define TPM2_ERROR_TEXT(r) "Error", "Code", r
22 #define SIZE_OF_ARY(ary) (sizeof(ary) / sizeof(ary[0]))
23
24 #if defined (__GNUC__)
25 #define COMPILER_ATTR(...) __attribute__((__VA_ARGS__))
26 #else
27 #define COMPILER_ATTR(...)
28 #endif
29
30 #define UNUSED(x) (void)(x)
31 #if (MAXLOGLEVEL == LOGL_NONE)
32 /* Note:
33 * MAYBE_UNUSED macro should be used to mark variables used only
34 * for assertions i.e. in debug mode, and/or for logging, which
35 * might be compiled out. This shuldn't trigger 'unused variable'
36 * or 'variable assigned, but not used' warnings when debug and
37 * logging is disabled on configure time, but should trigger
38 * warnings for variables that are not used for neither.
39 */
40 #define MAYBE_UNUSED COMPILER_ATTR(unused)
41 #else
42 #define MAYBE_UNUSED
43 #endif
44
45 #define return_if_error(r,msg) \
46 if (r != TSS2_RC_SUCCESS) { \
47 LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
48 return r; \
49 }
50
51 #define return_state_if_error(r,s,msg) \
52 if (r != TSS2_RC_SUCCESS) { \
53 LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
54 esysContext->state = s; \
55 return r; \
56 }
57
58 #define return_error(r,msg) \
59 { \
60 LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
61 return r; \
62 }
63
64 #define goto_state_if_error(r,s,msg,label) \
65 if (r != TSS2_RC_SUCCESS) { \
66 LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
67 esysContext->state = s; \
68 goto label; \
69 }
70
71 #define goto_if_null(p,msg,ec,label) \
72 if ((p) == NULL) { \
73 LOG_ERROR("%s ", (msg)); \
74 r = (ec); \
75 goto label; \
76 }
77
78 #define goto_if_error(r,msg,label) \
79 if (r != TSS2_RC_SUCCESS) { \
80 LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
81 goto label; \
82 }
83
84 #define goto_error(r,v,msg,label, ...) \
85 { r = v; \
86 LOG_ERROR(TPM2_ERROR_FORMAT " " msg, TPM2_ERROR_TEXT(r), ## __VA_ARGS__); \
87 goto label; \
88 }
89
90 #define return_if_null(p,msg,ec) \
91 if (p == NULL) { \
92 LOG_ERROR("%s ", msg); \
93 return ec; \
94 }
95
96 #define return_if_notnull(p,msg,ec) \
97 if (p != NULL) { \
98 LOG_ERROR("%s ", msg); \
99 return ec; \
100 }
101
102 #define set_return_code(r_max, r, msg) \
103 if (r != TSS2_RC_SUCCESS) { \
104 LOG_ERROR("%s " TPM2_ERROR_FORMAT, msg, TPM2_ERROR_TEXT(r)); \
105 r_max = r; \
106 }
107
108 #define base_rc(r) (r & ~TSS2_RC_LAYER_MASK)
109 #define number_rc(r) (r & ~TPM2_RC_N_MASK)
110
111 static inline TSS2_RC
tss2_fmt_p1_error_to_rc(UINT16 err)112 tss2_fmt_p1_error_to_rc(UINT16 err)
113 {
114 return TPM2_RC_1+TPM2_RC_P+err;
115 }
116
117 static inline bool
tss2_is_expected_error(TSS2_RC rc)118 tss2_is_expected_error(TSS2_RC rc)
119 {
120 /* Success is always expected */
121 if (rc == TSS2_RC_SUCCESS) {
122 return true;
123 }
124
125 /*
126 * drop the layer, any part of the TSS stack can gripe about this error
127 * if it wants too.
128 */
129 rc &= ~TSS2_RC_LAYER_MASK;
130
131 /*
132 * Format 1, parameter 1 errors plus the below RC's
133 * contain everything we care about:
134 * - TPM2_RC_CURVE
135 * - TPM2_RC_HASH
136 * - TPM2_RC_ASYMMETRIC
137 * - TPM2_RC_KEY_SIZE
138 */
139 if (rc == tss2_fmt_p1_error_to_rc(TPM2_RC_CURVE)
140 || rc == tss2_fmt_p1_error_to_rc(TPM2_RC_VALUE)
141 || rc == tss2_fmt_p1_error_to_rc(TPM2_RC_HASH)
142 || rc == tss2_fmt_p1_error_to_rc(TPM2_RC_ASYMMETRIC)
143 || rc == tss2_fmt_p1_error_to_rc(TPM2_RC_KEY_SIZE)) {
144 return true;
145 }
146
147 return false;
148 }
149
150 #ifdef __cplusplus
151 } /* extern "C" */
152 #endif
153
154 #endif /* AUX_UTIL_H */
155