free hmac_signature string after use
[strongswan.git] / src / libstrongswan / fips / fips_canister_start.c
1 /**
2 * @file fips_canister_start.c
3 *
4 * @brief Marks the start of TEXT and RODATA.
5 *
6 */
7
8 /* ====================================================================
9 * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
10 * and usage in source and binary forms are granted according to the
11 * OpenSSL license.
12 */
13
14 #include <stdio.h>
15 #if defined(__DECC)
16 # include <c_asm.h>
17 # pragma __nostandard
18 #endif
19
20 #if !defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
21 # if (defined(__sun) && (defined(__sparc) || defined(__sparcv9))) || \
22 (defined(__sgi) && (defined(__mips) || defined(mips))) || \
23 (defined(__osf__) && defined(__alpha)) || \
24 (defined(__linux) && (defined(__arm) || defined(__arm__))) || \
25 (defined(__i386) || defined(__i386__)) || \
26 (defined(__x86_64) || defined(__x86_64__)) || \
27 (defined(vax) || defined(__vax__))
28 # define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION
29 # endif
30 #endif
31
32
33 #define FIPS_ref_point FIPS_text_start
34 /* Some compilers put string literals into a separate segment. As we
35 * are mostly interested to hash AES tables in .rodata, we declare
36 * reference points accordingly. In case you wonder, the values are
37 * big-endian encoded variable names, just to prevent these arrays
38 * from being merged by linker. */
39 const unsigned int FIPS_rodata_start[]=
40 { 0x46495053, 0x5f726f64, 0x6174615f, 0x73746172 };
41
42
43 /*
44 * I declare reference function as static in order to avoid certain
45 * pitfalls in -dynamic linker behaviour...
46 */
47 static void *instruction_pointer(void)
48 {
49 void *ret = NULL;
50
51 /* These are ABI-neutral CPU-specific snippets. ABI-neutrality means
52 * that they are designed to work under any OS running on particular
53 * CPU, which is why you don't find any #ifdef THIS_OR_THAT_OS in
54 * this function. */
55 #if defined(INSTRUCTION_POINTER_IMPLEMENTED)
56 INSTRUCTION_POINTER_IMPLEMENTED(ret);
57 #elif defined(__GNUC__) && __GNUC__>=2
58 # if defined(__alpha) || defined(__alpha__)
59 # define INSTRUCTION_POINTER_IMPLEMENTED
60 __asm __volatile ( "br %0,1f\n1:" : "=r"(ret) );
61 # elif defined(__i386) || defined(__i386__)
62 # define INSTRUCTION_POINTER_IMPLEMENTED
63 __asm __volatile ( "call 1f\n1: popl %0" : "=r"(ret) );
64 ret = (void *)((size_t)ret&~3UL); /* align for better performance */
65 # elif defined(__ia64) || defined(__ia64__)
66 # define INSTRUCTION_POINTER_IMPLEMENTED
67 __asm __volatile ( "mov %0=ip" : "=r"(ret) );
68 # elif defined(__hppa) || defined(__hppa__) || defined(__pa_risc)
69 # define INSTRUCTION_POINTER_IMPLEMENTED
70 __asm __volatile ( "blr %%r0,%0\n\tnop" : "=r"(ret) );
71 ret = (void *)((size_t)ret&~3UL); /* mask privilege level */
72 # elif defined(__mips) || defined(__mips__)
73 # define INSTRUCTION_POINTER_IMPLEMENTED
74 void *scratch;
75 __asm __volatile ( "move %1,$31\n\t" /* save ra */
76 "bal .+8; nop\n\t"
77 "move %0,$31\n\t"
78 "move $31,%1" /* restore ra */
79 : "=r"(ret),"=r"(scratch) );
80 # elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \
81 defined(__POWERPC__) || defined(_POWER) || defined(__PPC__) || \
82 defined(__PPC64__) || defined(__powerpc64__)
83 # define INSTRUCTION_POINTER_IMPLEMENTED
84 void *scratch;
85 __asm __volatile ( "mfspr %1,8\n\t" /* save lr */
86 "bl .+4\n\t"
87 "mfspr %0,8\n\t" /* mflr ret */
88 "mtspr 8,%1" /* restore lr */
89 : "=r"(ret),"=r"(scratch) );
90 # elif defined(__sparc) || defined(__sparc__) || defined(__sparcv9)
91 # define INSTRUCTION_POINTER_IMPLEMENTED
92 void *scratch;
93 __asm __volatile ( "mov %%o7,%1\n\t"
94 "call .+8; nop\n\t"
95 "mov %%o7,%0\n\t"
96 "mov %1,%%o7"
97 : "=r"(ret),"=r"(scratch) );
98 # elif defined(__x86_64) || defined(__x86_64__)
99 # define INSTRUCTION_POINTER_IMPLEMENTED
100 __asm __volatile ( "leaq 0(%%rip),%0" : "=r"(ret) );
101 ret = (void *)((size_t)ret&~3UL); /* align for better performance */
102 # endif
103 #elif defined(__DECC) && defined(__alpha)
104 # define INSTRUCTION_POINTER_IMPLEMENTED
105 ret = (void *)(size_t)asm("br %v0,1f\n1:");
106 #elif defined(_MSC_VER) && defined(_M_IX86)
107 # undef INSTRUCTION_POINTER_IMPLEMENTED
108 void *scratch;
109 _asm {
110 call self
111 self: pop eax
112 mov scratch,eax
113 }
114 ret = (void *)((size_t)scratch&~3UL);
115 #endif
116 return ret;
117 }
118
119 /*
120 * This function returns pointer to an instruction in the vicinity of
121 * its entry point, but not outside this object module. This guarantees
122 * that sequestered code is covered...
123 */
124 void *FIPS_ref_point()
125 {
126 #if defined(INSTRUCTION_POINTER_IMPLEMENTED)
127 return instruction_pointer();
128 /* Below we essentially cover vendor compilers which do not support
129 * inline assembler... */
130 #elif defined(_AIX)
131 struct { void *ip,*gp,*env; } *p = (void *)instruction_pointer;
132 return p->ip;
133 #elif defined(_HPUX_SOURCE)
134 # if defined(__hppa) || defined(__hppa__)
135 struct { void *i[4]; } *p = (void *)FIPS_ref_point;
136
137 if (sizeof(p) == 8) /* 64-bit */
138 return p->i[2];
139 else if ((size_t)p & 2)
140 { p = (void *)((size_t)p&~3UL);
141 return p->i[0];
142 }
143 else
144 return (void *)p;
145 # elif defined(__ia64) || defined(__ia64__)
146 struct { unsigned long long ip,gp; } *p=(void *)instruction_pointer;
147 return (void *)(size_t)p->ip;
148 # endif
149 #elif (defined(__VMS) || defined(VMS)) && !(defined(vax) || defined(__vax__))
150 /* applies to both alpha and ia64 */
151 struct { unsigned __int64 opaque,ip; } *p=(void *)instruction_pointer;
152 return (void *)(size_t)p->ip;
153 #elif defined(__VOS__)
154 /* applies to both pa-risc and ia32 */
155 struct { void *dp,*ip,*gp; } *p = (void *)instruction_pointer;
156 return p->ip;
157 #elif defined(_WIN32)
158 # if defined(_WIN64) && defined(_M_IA64)
159 struct { void *ip,*gp; } *p = (void *)FIPS_ref_point;
160 return p->ip;
161 # else
162 return (void *)FIPS_ref_point;
163 # endif
164 /*
165 * In case you wonder why there is no #ifdef __linux. All Linux targets
166 * are GCC-based and therefore are covered by instruction_pointer above
167 * [well, some are covered by by the one below]...
168 */
169 #elif defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
170 return (void *)instruction_pointer;
171 #else
172 return NULL;
173 #endif
174 }