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