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