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