"ec_pre_comp",
"store",
"comp",
-#if CRYPTO_NUM_LOCKS != 39
+ "fips",
+ "fips2",
+#if CRYPTO_NUM_LOCKS != 41
# error "Inconsistency between crypto.h and cryptlib.c"
#endif
};
const char *file,int line)=0;
static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
int type,const char *file,int line)=0;
+#ifndef OPENSSL_NO_DEPRECATED
static unsigned long (MS_FAR *id_callback)(void)=0;
-static void *(MS_FAR *idptr_callback)(void)=0;
+#endif
+static void (MS_FAR *threadid_callback)(CRYPTO_THREADID *)=0;
static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
(const char *file,int line)=0;
static void (MS_FAR *dynlock_lock_callback)(int mode,
#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
/* A hack to make Visual C++ 5.0 work correctly when linking as
* a DLL using /MT. Without this, the application cannot use
- * and floating point printf's.
+ * any floating point printf's.
* It also seems to be needed for Visual C 1.5 (win16) */
SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
#endif
add_lock_callback=func;
}
-/* Thread IDs. So ... if we build without OPENSSL_NO_DEPRECATED, then we leave
- * the existing implementations and just layer CRYPTO_THREADID_[get|cmp]
- * harmlessly on top. Otherwise, we only use 'id_callback' or 'idptr_callback'
- * if they're non-NULL, ie. we ignore CRYPTO_thread_id()'s fallbacks and we
- * move CRYPTO_thread_idptr()'s "&errno" fallback trick into
- * CRYPTO_THREADID_set(). */
+/* the memset() here and in set_pointer() seem overkill, but for the sake of
+ * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
+ * "equal" THREADID structs to not be memcmp()-identical. */
+void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
+ {
+ memset(id, 0, sizeof(*id));
+ id->val = val;
+ }
-void CRYPTO_set_id_callback(unsigned long (*func)(void))
+static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
+void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
{
- id_callback=func;
+ unsigned char *dest = (void *)&id->val;
+ unsigned int accum = 0;
+ unsigned char dnum = sizeof(id->val);
+
+ memset(id, 0, sizeof(*id));
+ id->ptr = ptr;
+ if (sizeof(id->val) >= sizeof(id->ptr))
+ {
+ /* 'ptr' can be embedded in 'val' without loss of uniqueness */
+ id->val = (unsigned long)id->ptr;
+ return;
+ }
+ /* hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a
+ * linear function over the bytes in 'ptr', the co-efficients of which
+ * are a sequence of low-primes (hash_coeffs is an 8-element cycle) -
+ * the starting prime for the sequence varies for each byte of 'val'
+ * (unique polynomials unless pointers are >64-bit). For added spice,
+ * the totals accumulate rather than restarting from zero, and the index
+ * of the 'val' byte is added each time (position dependence). If I was
+ * a black-belt, I'd scan big-endian pointers in reverse to give
+ * low-order bits more play, but this isn't crypto and I'd prefer nobody
+ * mistake it as such. Plus I'm lazy. */
+ while (dnum--)
+ {
+ const unsigned char *src = (void *)&id->ptr;
+ unsigned char snum = sizeof(id->ptr);
+ while (snum--)
+ accum += *(src++) * hash_coeffs[(snum + dnum) & 7];
+ accum += dnum;
+ *(dest++) = accum & 255;
+ }
}
-void CRYPTO_set_idptr_callback(void *(*func)(void))
+int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
{
- idptr_callback=func;
+ if (threadid_callback)
+ return 0;
+ threadid_callback = func;
+ return 1;
}
-void CRYPTO_THREADID_set(CRYPTO_THREADID *id)
+void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *)
{
- if (id_callback)
- id->ulong = id_callback();
- else
- id->ulong = 0;
+ return threadid_callback;
+ }
- if (idptr_callback)
- id->ptr = idptr_callback();
- else
- id->ptr = &errno;
+void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
+ {
+ if (threadid_callback)
+ {
+ threadid_callback(id);
+ return;
+ }
+#ifndef OPENSSL_NO_DEPRECATED
+ /* If the deprecated callback was set, fall back to that */
+ if (id_callback)
+ {
+ CRYPTO_THREADID_set_numeric(id, id_callback());
+ return;
+ }
+#endif
+ /* Else pick a backup */
+#ifdef OPENSSL_SYS_WIN16
+ CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
+#elif defined(OPENSSL_SYS_WIN32)
+ CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
+#elif defined(OPENSSL_SYS_BEOS)
+ CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
+#else
+ /* For everything else, default to using the address of 'errno' */
+ CRYPTO_THREADID_set_pointer(id, &errno);
+#endif
}
-int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *id1, const CRYPTO_THREADID *id2)
+int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
{
- if (id1->ulong != id2->ulong)
- return ((id1->ulong < id2->ulong) ? -1 : 1);
- if (id1->ptr != id2->ptr)
- return ((id1->ptr < id2->ptr) ? -1 : 1);
- return 0;
+ return memcmp(a, b, sizeof(*a));
}
-unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
+void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
{
- /* will need further processing to arrive at a good hash (mem_dbg.c uses this) */
- return id->ulong + (unsigned long)id->ptr;
+ memcpy(dest, src, sizeof(*src));
}
-void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dst, const CRYPTO_THREADID *src)
+unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
{
- memcpy(dst, src, sizeof(*src));
+ return id->val;
}
#ifndef OPENSSL_NO_DEPRECATED
return(id_callback);
}
+void CRYPTO_set_id_callback(unsigned long (*func)(void))
+ {
+ id_callback=func;
+ }
+
unsigned long CRYPTO_thread_id(void)
{
unsigned long ret=0;
{
#ifdef LOCK_DEBUG
{
+ CRYPTO_THREADID id;
char *rw_text,*operation_text;
- CRYPTO_THREADID tid;
if (mode & CRYPTO_LOCK)
operation_text="lock ";
else
rw_text="ERROR";
- CRYPTO_THREADID_set(&tid);
+ CRYPTO_THREADID_current(&id);
fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
- CRYPTO_THREADID_hash(&tid), rw_text, operation_text,
+ CRYPTO_THREADID_hash(&id), rw_text, operation_text,
CRYPTO_get_lock_name(type), file, line);
}
#endif
int line)
{
int ret = 0;
-#ifdef LOCK_DEBUG
- CRYPTO_THREADID tid;
- CRYPTO_THREADID_set(&tid);
-#endif
if (add_lock_callback != NULL)
{
ret=add_lock_callback(pointer,amount,type,file,line);
#ifdef LOCK_DEBUG
+ {
+ CRYPTO_THREADID id;
+ CRYPTO_THREADID_current(&id);
fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
- CRYPTO_THREADID_hash(&tid), before,amount,ret,
+ CRYPTO_THREADID_hash(&id), before,amount,ret,
CRYPTO_get_lock_name(type),
file,line);
+ }
#endif
}
else
ret= *pointer+amount;
#ifdef LOCK_DEBUG
+ {
+ CRYPTO_THREADID id;
+ CRYPTO_THREADID_current(&id);
fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
- CRYPTO_THREADID_hash(&tid), *pointer,amount,ret,
+ CRYPTO_THREADID_hash(&id),
+ *pointer,amount,ret,
CRYPTO_get_lock_name(type),
file,line);
+ }
#endif
*pointer=ret;
CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__INTEL__) || \
- defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64)
+ defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
-unsigned long OPENSSL_ia32cap_P=0;
-unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; }
+unsigned int OPENSSL_ia32cap_P[2];
+unsigned int *OPENSSL_ia32cap_loc(void) { return OPENSSL_ia32cap_P; }
#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
#define OPENSSL_CPUID_SETUP
+#if defined(_WIN32)
+typedef unsigned __int64 IA32CAP;
+#else
+typedef unsigned long long IA32CAP;
+#endif
void OPENSSL_cpuid_setup(void)
{ static int trigger=0;
- unsigned long OPENSSL_ia32_cpuid(void);
+ IA32CAP OPENSSL_ia32_cpuid(void);
+ IA32CAP vec;
char *env;
if (trigger) return;
trigger=1;
if ((env=getenv("OPENSSL_ia32cap")))
- OPENSSL_ia32cap_P = strtoul(env,NULL,0)|(1<<10);
+#if defined(_WIN32)
+ { if (!sscanf(env,"%I64i",&vec)) vec = strtoul(env,NULL,0); }
+#else
+ vec = strtoull(env,NULL,0);
+#endif
else
- OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid()|(1<<10);
+ vec = OPENSSL_ia32_cpuid();
+
/*
* |(1<<10) sets a reserved bit to signal that variable
* was initialized already... This is to avoid interference
* with cpuid snippets in ELF .init segment.
*/
+ OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10);
+ OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32);
}
#endif
#else
-unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; }
+unsigned int *OPENSSL_ia32cap_loc(void) { return NULL; }
#endif
int OPENSSL_NONPIC_relocated = 0;
#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)