summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/freebl/lowhash_vector.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/freebl/lowhash_vector.c')
-rw-r--r--security/nss/lib/freebl/lowhash_vector.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/security/nss/lib/freebl/lowhash_vector.c b/security/nss/lib/freebl/lowhash_vector.c
new file mode 100644
index 000000000..7690c98da
--- /dev/null
+++ b/security/nss/lib/freebl/lowhash_vector.c
@@ -0,0 +1,217 @@
+/*
+ * loader.c - load platform dependent DSO containing freebl implementation.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#define _GNU_SOURCE 1
+#include "loader.h"
+#include "prmem.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prenv.h"
+#include "blname.c"
+
+#include "prio.h"
+#include "prprf.h"
+#include <stdio.h>
+#include "prsystem.h"
+#include "nsslowhash.h"
+#include <dlfcn.h>
+#include "pratom.h"
+
+static PRLibrary *blLib;
+
+#define LSB(x) ((x)&0xff)
+#define MSB(x) ((x) >> 8)
+
+static const NSSLOWVector *vector;
+static const char *libraryName = NULL;
+
+/* pretty much only glibc uses this, make sure we don't have any depenencies
+ * on nspr.. */
+#undef PORT_Alloc
+#undef PORT_Free
+#define PORT_Alloc malloc
+#define PR_Malloc malloc
+#define PORT_Free free
+#define PR_Free free
+#define PR_GetDirectorySeparator() '/'
+#define PR_LoadLibraryWithFlags(libspec, flags) \
+ (PRLibrary *)dlopen(libSpec.value.pathname, RTLD_NOW | RTLD_LOCAL)
+#define PR_GetLibraryFilePathname(name, addr) \
+ freebl_lowhash_getLibraryFilePath(addr)
+
+static char *
+freebl_lowhash_getLibraryFilePath(void *addr)
+{
+ Dl_info dli;
+ if (dladdr(addr, &dli) == 0) {
+ return NULL;
+ }
+ return strdup(dli.dli_fname);
+}
+
+/*
+ * The PR_LoadLibraryWithFlags call above defines this variable away, so we
+ * don't need it..
+ */
+#ifdef nodef
+static const char *NameOfThisSharedLib =
+ SHLIB_PREFIX "freebl" SHLIB_VERSION "." SHLIB_SUFFIX;
+#endif
+
+#include "genload.c"
+
+/* This function must be run only once. */
+/* determine if hybrid platform, then actually load the DSO. */
+static PRStatus
+freebl_LoadDSO(void)
+{
+ PRLibrary *handle;
+ const char *name = getLibName();
+
+ if (!name) {
+ /*PR_SetError(PR_LOAD_LIBRARY_ERROR,0); */
+ return PR_FAILURE;
+ }
+ handle = loader_LoadLibrary(name);
+ if (handle) {
+ void *address = dlsym(handle, "NSSLOW_GetVector");
+ if (address) {
+ NSSLOWGetVectorFn *getVector = (NSSLOWGetVectorFn *)address;
+ const NSSLOWVector *dsoVector = getVector();
+ if (dsoVector) {
+ unsigned short dsoVersion = dsoVector->version;
+ unsigned short myVersion = NSSLOW_VERSION;
+ if (MSB(dsoVersion) == MSB(myVersion) &&
+ LSB(dsoVersion) >= LSB(myVersion) &&
+ dsoVector->length >= sizeof(NSSLOWVector)) {
+ vector = dsoVector;
+ libraryName = name;
+ blLib = handle;
+ return PR_SUCCESS;
+ }
+ }
+ }
+ (void)dlclose(handle);
+ }
+ return PR_FAILURE;
+}
+
+static PRCallOnceType loadFreeBLOnce;
+
+static PRStatus
+freebl_RunLoaderOnce(void)
+{
+ /* Don't have NSPR, so can use the real PR_CallOnce, implement a stripped
+ * down version. */
+ if (loadFreeBLOnce.initialized) {
+ return loadFreeBLOnce.status;
+ }
+ if (__sync_lock_test_and_set(&loadFreeBLOnce.inProgress, 1) == 0) {
+ loadFreeBLOnce.status = freebl_LoadDSO();
+ loadFreeBLOnce.initialized = 1;
+ } else {
+ /* shouldn't have a lot of takers on the else clause, which is good
+ * since we don't have condition variables yet.
+ * 'initialized' only ever gets set (not cleared) so we don't
+ * need the traditional locks. */
+ while (!loadFreeBLOnce.initialized) {
+ sleep(1); /* don't have condition variables, just give up the CPU */
+ }
+ }
+
+ return loadFreeBLOnce.status;
+}
+
+const FREEBLVector *
+FREEBL_GetVector(void)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) {
+ return NULL;
+ }
+ if (vector) {
+ return (vector->p_FREEBL_GetVector)();
+ }
+ return NULL;
+}
+
+NSSLOWInitContext *
+NSSLOW_Init(void)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_NSSLOW_Init)();
+}
+
+void
+NSSLOW_Shutdown(NSSLOWInitContext *context)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOW_Shutdown)(context);
+}
+
+void
+NSSLOW_Reset(NSSLOWInitContext *context)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOW_Reset)(context);
+}
+
+NSSLOWHASHContext *
+NSSLOWHASH_NewContext(
+ NSSLOWInitContext *initContext,
+ HASH_HashType hashType)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_NSSLOWHASH_NewContext)(initContext, hashType);
+}
+
+void
+NSSLOWHASH_Begin(NSSLOWHASHContext *context)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOWHASH_Begin)(context);
+}
+
+void
+NSSLOWHASH_Update(NSSLOWHASHContext *context,
+ const unsigned char *buf,
+ unsigned int len)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOWHASH_Update)(context, buf, len);
+}
+
+void
+NSSLOWHASH_End(NSSLOWHASHContext *context,
+ unsigned char *buf,
+ unsigned int *ret, unsigned int len)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOWHASH_End)(context, buf, ret, len);
+}
+
+void
+NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOWHASH_Destroy)(context);
+}
+
+unsigned int
+NSSLOWHASH_Length(NSSLOWHASHContext *context)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return -1;
+ return (vector->p_NSSLOWHASH_Length)(context);
+}