fixup commit for branch 'XPCDOM_20010223_BRANCH' XPCDOM_20010223_BRANCH XPCDOM_20010223_BASE
authorcvs2hg
Tue, 13 Feb 2001 21:47:31 +0000
branchXPCDOM_20010223_BRANCH
changeset 1230 0a0fb4a0503d8bbae3043e2a3fecd9cf190b0091
parent 798 c1ff026ec55fc0f419f2ee2e23b0776bae9d4539
child 1263 4c6951084e87aa225ba56cc11fa002c10a35a17e
child 14029 cd0eac9716782a778ada5f1b2d9a9e4454cde92c
push idunknown
push userunknown
push dateunknown
fixup commit for branch 'XPCDOM_20010223_BRANCH'
dbm/include/cdefs.h
dbm/src/db.c
dbm/src/h_page.c
dbm/src/hash.c
dbm/src/hsearch.c
security/coreconf/HP-UXB.11.mk
security/coreconf/Linux.mk
security/coreconf/OS2.mk
security/coreconf/SunOS5.8_i86pc.mk
security/coreconf/arch.mk
security/coreconf/config.mk
security/coreconf/headers.mk
security/coreconf/nsinstall/Makefile
security/coreconf/prefix.mk
security/coreconf/rules.mk
security/coreconf/suffix.mk
security/nss/Makefile
security/nss/cmd/platlibs.mk
security/nss/cmd/selfserv/selfserv.c
security/nss/lib/base/hashops.c
security/nss/lib/base/tracker.c
security/nss/lib/certdb/certt.h
security/nss/lib/ckfw/builtins/Makefile
security/nss/lib/ckfw/ckapi.perl
security/nss/lib/ckfw/nssck.api
security/nss/lib/ckfw/nssckepv.h
security/nss/lib/fortcrypt/swfort/swfutl.c
security/nss/lib/freebl/mpi/mpi-priv.h
security/nss/lib/freebl/mpi/mpi-test.c
security/nss/lib/freebl/mpi/mpi.c
security/nss/lib/freebl/mpi/mpi.h
security/nss/lib/freebl/mpi/mpi_sparc.c
security/nss/lib/freebl/mpi/mpi_x86.s
security/nss/lib/freebl/mpi/mpprime.c
security/nss/lib/jar/jarevil.c
security/nss/lib/nss/nssinit.c
security/nss/lib/pk11wrap/pk11sdr.c
security/nss/lib/pki1/oid.c
security/nss/lib/ssl/ssl3con.c
security/nss/lib/ssl/ssl3gthr.c
security/nss/lib/ssl/sslgathr.c
security/nss/lib/util/os2_rand.c
security/nss/lib/util/unix_rand.c
security/nss/macbuild/LoadableRoots.mcp
security/nss/macbuild/LoadableRoots.mcp.exp
security/nss/macbuild/NSS.mcp
security/nss/macbuild/NSSCommon.h
security/nss/macbuild/NSSckfw.mcp
security/nss/makefile.win
--- a/dbm/include/cdefs.h
+++ b/dbm/include/cdefs.h
@@ -96,17 +96,17 @@
 #define	__const		const		/* define reserved names to standard */
 #endif  /* __const */
 #define	__signed	signed
 #define	__volatile	volatile
 #ifndef _WINDOWS
 #if defined(__cplusplus)
 #define	__inline	inline		/* convert to C++ keyword */
 #else
-#ifndef __GNUC__
+#if !defined(__GNUC__) && !defined(__MWERKS__)
 #define	__inline			/* delete GCC keyword */
 #endif /* !__GNUC__ */
 #endif /* !__cplusplus */
 #endif /* !_WINDOWS */
 
 #else	/* !(__STDC__ || __cplusplus) */
 #define	__P(protos)	()		/* traditional C preprocessor */
 #define	__CONCAT(x,y)	x/**/y
--- a/dbm/src/db.c
+++ b/dbm/src/db.c
@@ -42,19 +42,17 @@ static char sccsid[] = "@(#)db.c	8.4 (Be
 #endif
 #ifdef macintosh
 #include <unix.h>
 #else
 #include <sys/types.h>
 #endif
 
 #include <errno.h>
-#ifndef macintosh
 #include <fcntl.h>
-#endif
 #include <stddef.h>
 #include <stdio.h>
 
 #include "mcom_db.h"
 
 /* a global flag that locks closed all databases */
 int all_databases_locked_closed = 0;
 
--- a/dbm/src/h_page.c
+++ b/dbm/src/h_page.c
@@ -61,20 +61,22 @@ static char sccsid[] = "@(#)hash_page.c	
  * Internal
  *	overflow_page
  *	open_temp
  */
 #ifndef macintosh
 #include <sys/types.h>
 #endif
 
+#if defined(macintosh)
+#include <unistd.h>
+#endif
+
 #include <errno.h>
-#ifndef macintosh
 #include <fcntl.h>
-#endif
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) && !defined(XP_OS2_VACPP)
 #include <unistd.h>
 #endif
--- a/dbm/src/hash.c
+++ b/dbm/src/hash.c
@@ -46,22 +46,23 @@ static char sccsid[] = "@(#)hash.c	8.9 (
 
 #if !defined(macintosh)
 #ifdef XP_OS2_EMX
 #include <sys/types.h>
 #endif
 #include <sys/stat.h>
 #endif
 
-#include <errno.h>
-#ifdef macintosh
+#if defined(macintosh)
 #include <unix.h>
-#else
+#include <unistd.h>
+#endif
+
+#include <errno.h>
 #include <fcntl.h>
-#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) && !defined(XP_OS2_VACPP)
 #include <unistd.h>
 #endif
 
--- a/dbm/src/hsearch.c
+++ b/dbm/src/hsearch.c
@@ -37,19 +37,19 @@
 #if defined(LIBC_SCCS) && !defined(lint)
 static char sccsid[] = "@(#)hsearch.c	8.4 (Berkeley) 7/21/94";
 #endif /* LIBC_SCCS and not lint */
 
 #include "watcomfx.h"
 
 #ifndef macintosh
 #include <sys/types.h>
+#endif
 
 #include <fcntl.h>
-#endif
 #include <string.h>
 
 #include "mcom_db.h"
 #include "hsearch.h"
 
 static DB *dbp = NULL;
 static ENTRY retval;
 
--- a/security/coreconf/HP-UXB.11.mk
+++ b/security/coreconf/HP-UXB.11.mk
@@ -39,17 +39,17 @@ ifndef NS_USE_GCC
     ifeq ($(USE_64), 1)
 	OS_CFLAGS       +=  -Aa +e +DA2.0W +DS2.0 +DChpux
 # Next line replaced by generic name handling in arch.mk
 #	COMPILER_TAG    = _64
     else
 	ifdef USE_LONG_LONGS
 	    OS_CFLAGS 	+= -Aa +e +DA2.0 +DS2.0 
 	else
-	    OS_CFLAGS   += +DAportable +DS1.1
+	    OS_CFLAGS   += +DAportable +DS2.0
 	endif
     endif
 else
     CCC = aCC
 endif
 
 OS_CFLAGS += -DHPUX11 
 OS_LIBS   += -lpthread -lm -lrt
--- a/security/coreconf/Linux.mk
+++ b/security/coreconf/Linux.mk
@@ -46,27 +46,37 @@ endif
 
 CC			= gcc
 CCC			= g++
 RANLIB			= ranlib
 
 DEFAULT_COMPILER = gcc
 
 ifeq ($(OS_TEST),ppc)
-	OS_REL_CFLAGS	= -DMACLINUX -DLINUX1_2
+	OS_REL_CFLAGS	= -DLINUX1_2 -D_XOPEN_SOURCE
 	CPU_ARCH	= ppc
 else
 ifeq ($(OS_TEST),alpha)
         OS_REL_CFLAGS   = -D_ALPHA_ -DLINUX1_2 -D_XOPEN_SOURCE
 	CPU_ARCH	= alpha
 else
+ifeq ($(OS_TEST),sparc)
+	OS_REL_CFLAGS   = -DLINUX1_2 -D_XOPEN_SOURCE
+	CPU_ARCH        = sparc
+else
+ifeq ($(OS_TEST),sparc64)
+	OS_REL_CFLAGS   = -DLINUX1_2 -D_XOPEN_SOURCE
+	CPU_ARCH        = sparc
+else
 	OS_REL_CFLAGS	= -DLINUX1_2 -Di386 -D_XOPEN_SOURCE
 	CPU_ARCH	= x86
 endif
 endif
+endif
+endif
 
 
 LIBC_TAG		= _glibc
 
 ifeq ($(OS_RELEASE),2.0)
 	OS_REL_CFLAGS	+= -DLINUX2_0
 	MKSHLIB		= $(CC) -shared -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
 	ifdef BUILD_OPT
--- a/security/coreconf/OS2.mk
+++ b/security/coreconf/OS2.mk
@@ -52,66 +52,126 @@ XP_DEFINE  += -DXP_PC=1  -DXP_OS2=1
 # Override suffix in suffix.mk
 LIB_SUFFIX  = lib
 DLL_SUFFIX  = dll
 OBJ_SUFFIX  = .obj
 ASM_SUFFIX  = .asm
 PROG_SUFFIX = .exe
 
 
+ifdef XP_OS2_EMX
+
 #
 # On OS/2 we proudly support gbash...
 #
 SHELL = GBASH.EXE
-CCC			= icc -q -DXP_OS2 -DOS2=4 -N10
-LINK			= ilink
+CCC			= gcc
+LINK			= gcc
 AR                      = emxomfar -p256 r $@
 # Keep AR_FLAGS blank so that we do not have to change rules.mk
 AR_FLAGS                = 
 RANLIB 			= @echo OS2 RANLIB
 BSDECHO 		= @echo OS2 BSDECHO
+FILTER    = emxexp
 
 ifndef NO_SHARED_LIB
 WRAP_MALLOC_LIB         = 
 WRAP_MALLOC_CFLAGS      = 
 DSO_CFLAGS              = 
 DSO_PIC_CFLAGS          = 
 MKSHLIB                 = $(CXX) $(CXXFLAGS) $(DSO_LDOPTS) -o $@
 MKCSHLIB                = $(CC) $(CFLAGS) $(DSO_LDOPTS) -o $@
 MKSHLIB_FORCE_ALL       = 
 MKSHLIB_UNFORCE_ALL     = 
 DSO_LDOPTS              = -Zomf -Zdll -Zmt -Zcrtdll -Zlinker /NOO
 # DLL_SUFFIX              = .dll
 SHLIB_LDSTARTFILE	= 
 SHLIB_LDENDFILE		= 
-endif
+endif   #NO_SHARED_LIB
 
 OS_CFLAGS          = -Wall -W -Wno-unused -Wpointer-arith -Wcast-align -Zmtd -Zomf -Zmt  -DDEBUG -DDEBUG_wintrinh -DTRACING -g
 
 # Where the libraries are
 MOZ_COMPONENT_NSPR_LIBS=-L$(DIST)/lib $(NSPR_LIBS)
 NSPR_LIBS	= -lplds4 -lplc4 -lnspr4 
 NSPR_INCLUDE_DIR =   
 
 
-
 ifdef BUILD_OPT
-OPTIMIZER		= -O+ -Oi 
+OPTIMIZER		= -O6 
 DEFINES 		+= -UDEBUG -U_DEBUG -DNDEBUG
 DLLFLAGS		= -DLL -OUT:$@ -MAP:$(@:.dll=.map)
 EXEFLAGS    		= -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE
 OBJDIR_TAG 		= _OPT
 else
 #OPTIMIZER		= -O+ -Oi
 DEFINES 		+= -DDEBUG -D_DEBUG -DDEBUGPRINTS     #HCT Need += to avoid overidding manifest.mn 
 DLLFLAGS		= -DEBUG -DLL -OUT:$@ -MAP:$(@:.dll=.map)
 EXEFLAGS    		= -DEBUG -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE
 OBJDIR_TAG 		= _DBG
 LDFLAGS 		= -DEBUG 
-endif
+endif   # BUILD_OPT
+
+else    # XP_OS2_VACPP
+
+#
+# On OS/2 we proudly support gbash...
+#
+SHELL = GBASH.EXE
+CCC			= icc -q -DXP_OS2 -DOS2=4 -N10
+LINK			= -ilink
+AR		= -ilib /NOL /NOI /O:$(subst /,\\,$@)
+# Keep AR_FLAGS blank so that we do not have to change rules.mk
+AR_FLAGS                = 
+RANLIB 			= @echo OS2 RANLIB
+BSDECHO 		= @echo OS2 BSDECHO
+FILTER    = cppfilt -b -p -q
+
+ifndef NO_SHARED_LIB
+WRAP_MALLOC_LIB         = 
+WRAP_MALLOC_CFLAGS      = 
+DSO_CFLAGS              = 
+DSO_PIC_CFLAGS          = 
+MKSHLIB                 = $(LD) $(DSO_LDOPTS)
+MKCSHLIB                = $(LD) $(DSO_LDOPTS)
+MKSHLIB_FORCE_ALL       = 
+MKSHLIB_UNFORCE_ALL     = 
+DSO_LDOPTS              = 
+# DLL_SUFFIX              = .dll
+SHLIB_LDSTARTFILE	= 
+SHLIB_LDENDFILE		= 
+endif   #NO_SHARED_LIB
+
+OS_CFLAGS          = /Q /qlibansi /Gd /Gm /Su4 /Mp /Tl-
+INCLUDES        += -I$(CORE_DEPTH)/../dist/include
+DEFINES         += -DXP_OS2_VACPP -DTCPV40HDRS
+
+# Where the libraries are
+NSPR_LIBS	= $(DIST)/lib/nspr4.lib $(DIST)/lib/plc4.lib $(DIST)/lib/plds4.lib
+MOZ_COMPONENT_NSPR_LIBS=-L$(DIST)/lib $(NSPR_LIBS)
+NSPR_INCLUDE_DIR =   
+
+
+ifdef BUILD_OPT
+OPTIMIZER		= -O+ -Oi 
+DEFINES 		+= -UDEBUG -U_DEBUG -DNDEBUG
+DLLFLAGS		= /DLL /O:$@ /INC:_dllentry /MAP:$(@:.dll=.map)
+EXEFLAGS    		= -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE
+OBJDIR_TAG 		= _OPT
+LDFLAGS     = /FREE /NODEBUG /NOE /LINENUMBERS /nologo
+else
+OS_CFLAGS   += /Ti+
+DEFINES 		+= -DDEBUG -D_DEBUG -DDEBUGPRINTS     #HCT Need += to avoid overidding manifest.mn 
+DLLFLAGS		= /DEBUG /DLL /O:$@ /INC:_dllentry /MAP:$(@:.dll=.map)
+EXEFLAGS    		= -DEBUG -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE
+OBJDIR_TAG 		= _DBG
+LDFLAGS 		= /FREE /DE /NOE /LINENUMBERS /nologo 
+endif   # BUILD_OPT
+
+endif   # XP_OS2_VACPP
 
 # OS/2 use nsinstall that is included in the toolkit.
 # since we do not wish to support and maintain 3 version of nsinstall in mozilla, nspr and nss
 
 NSINSTALL_DIR  = $(CORE_DEPTH)/coreconf/nsinstall
 # NSINSTALL      = $(NSINSTALL_DIR)/$(OBJDIR_NAME)/nsinstall
 NSINSTALL 	= nsinstall             # HCT4OS2
 INSTALL		= $(NSINSTALL)
new file mode 100644
--- /dev/null
+++ b/security/coreconf/SunOS5.8_i86pc.mk
@@ -0,0 +1,47 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+# 
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+# 
+# The Original Code is the Netscape security libraries.
+# 
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation.  Portions created by Netscape are 
+# Copyright (C) 2000 Netscape Communications Corporation.  All
+# Rights Reserved.
+# 
+# Contributor(s):
+# 
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable 
+# instead of those above.  If you wish to allow use of your 
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL.  If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+# Config stuff for Solaris 8 on x86
+# 
+
+SOL_CFLAGS	= -D_SVID_GETTOD
+
+include $(CORE_DEPTH)/coreconf/SunOS5.mk
+
+CPU_ARCH		= x86
+OS_DEFINES		+= -Di386
+
+ifeq ($(OS_RELEASE),5.8_i86pc)
+	OS_DEFINES += -DSOLARIS2_8
+endif
+
+OS_LIBS += -lthread -lnsl -lsocket -lposix4 -ldl -lc
--- a/security/coreconf/arch.mk
+++ b/security/coreconf/arch.mk
@@ -133,16 +133,24 @@ endif
 ifeq (,$(filter-out Linux FreeBSD,$(OS_ARCH)))
 OS_RELEASE	:= $(shell echo $(OS_RELEASE) | sed 's/-.*//')
 endif
 
 ifeq ($(OS_ARCH),Linux)
 	OS_RELEASE := $(basename $(OS_RELEASE))
 endif
 
+#
+# For OS/2
+#
+ifeq ($(OS_ARCH),OS_2)
+	OS_ARCH = OS2
+	OS_RELEASE := $(shell uname -v)
+endif
+
 #######################################################################
 # Master "Core Components" macros for getting the OS target           #
 #######################################################################
 
 #
 # Note: OS_TARGET should be specified on the command line for gmake.
 # When OS_TARGET=WIN95 is specified, then a Windows 95 target is built.
 # The difference between the Win95 target and the WinNT target is that
@@ -285,17 +293,8 @@ ifndef BUILD_OPT
 #
 ifdef USE_DEBUG_RTL
 	OBJDIR_NAME = $(OS_CONFIG)$(CPU_TAG)$(COMPILER_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJD
 endif
 endif
 endif
 endif
 
-#
-# For OS/2
-#
-ifeq ($(OS_ARCH), OS_2)
-OS_ARCH		:= OS2
-OS_RELEASE	:= $(shell uname -v)
-OS_CONFIG	:= $(OS_ARCH)
-endif
-
--- a/security/coreconf/config.mk
+++ b/security/coreconf/config.mk
@@ -51,17 +51,17 @@ include $(CORE_DEPTH)/coreconf/command.m
 # [3.0] Master "Core Components" <architecture>-specific macros       #
 #       (dependent upon <architecture> tags)                          #
 #                                                                     #
 #       We are moving towards just having a $(OS_TARGET).mk file      #
 #       as opposed to multiple $(OS_CONFIG).mk files, one for         #
 #       each OS release.                                              #
 #######################################################################
 
-ifeq (,$(filter-out NetBSD,$(OS_TARGET)))
+ifeq (,$(filter-out NetBSD OS2,$(OS_TARGET)))
 include $(CORE_DEPTH)/coreconf/$(OS_TARGET).mk
 else
 include $(CORE_DEPTH)/coreconf/$(OS_CONFIG).mk
 endif
 
 #######################################################################
 # [4.0] Master "Core Components" source and release <platform> tags   #
 #       (dependent upon <architecture> tags)                          #
--- a/security/coreconf/headers.mk
+++ b/security/coreconf/headers.mk
@@ -35,17 +35,17 @@
 # Master "Core Components" include switch for support header files    #
 #######################################################################
 
 #
 #  Always append source-side machine-dependent (md) and cross-platform
 #  (xp) include paths
 #
 
-INCLUDES  += -I$(SOURCE_MDHEADERS_DIR) 
+INCLUDES  += -I$(SOURCE_MDHEADERS_DIR) -I$(SOURCE_XP_DIR)/include
 
 ifneq ($(OS_TARGET),WIN16)
 INCLUDES  += -I$(SOURCE_XPHEADERS_DIR)
 endif
 
 #
 #  Only append source-side private cross-platform include paths for
 #  sectools
--- a/security/coreconf/nsinstall/Makefile
+++ b/security/coreconf/nsinstall/Makefile
@@ -39,17 +39,17 @@ MODULE		= coreconf
 CSRCS		= nsinstall.c pathsub.c
 
 PLSRCS		= nfspwd.pl
 
 PROGRAM		= nsinstall
 
 include $(DEPTH)/coreconf/config.mk
 
-ifeq ($(OS_ARCH),WINNT)
+ifeq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
 PROGRAM		=
 else
 TARGETS		= $(PROGRAM) $(PLSRCS:.pl=)
 endif
 
 include $(DEPTH)/coreconf/rules.mk
 
 # Redefine MAKE_OBJDIR for just this directory
--- a/security/coreconf/prefix.mk
+++ b/security/coreconf/prefix.mk
@@ -52,17 +52,17 @@ ifndef LIB_PREFIX
 		LIB_PREFIX = 
 	else
 		LIB_PREFIX = lib
 	endif
 endif
 
 
 ifndef DLL_PREFIX
-	ifeq ($(OS_ARCH), WINNT)
+	ifeq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
 		DLL_PREFIX = 
 	else
 		DLL_PREFIX = lib
 	endif
 endif
 
 
 ifndef IMPORT_LIB_PREFIX
--- a/security/coreconf/rules.mk
+++ b/security/coreconf/rules.mk
@@ -301,18 +301,22 @@ ifeq ($(OS_TARGET),WIN16)
 	echo library >>w16link
 	echo winsock.lib >>w16link
 	$(LINK) @w16link.
 	rm w16link
 else
 	$(MKPROG) $(OBJS) -Fe$@ -link $(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)
 endif
 else
+ifdef XP_OS2_VACPP
+	$(MKPROG) -Fe$@ $(CFLAGS) $(OBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)
+else
 	$(MKPROG) -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)
 endif
+endif
 ifneq ($(POLICY),)
 	-$(PLCYPATCH) $(PLCYPATCH_ARGS) $@
 endif
 
 $(LIBRARY): $(OBJS)
 	@$(MAKE_OBJDIR)
 	rm -f $@
 	$(AR) $(OBJS)
@@ -348,17 +352,29 @@ ifeq ($(OS_TARGET), WIN16)
 	echo $(W16LIBS) >>w16link
 	echo libfile libentry >>w16link
 	$(LINK) @w16link.
 	rm w16link
 else
 	$(LINK_DLL) -MAP $(DLLBASE) $(OBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) $(LD_LIBS)
 endif
 else
+ifeq ($(OS_ARCH),OS2)
+	@cmd /C "echo LIBRARY $(notdir $(basename $(SHARED_LIBRARY))) INITINSTANCE TERMINSTANCE >$@.def"
+	@cmd /C "echo PROTMODE >>$@.def"
+	@cmd /C "echo CODE    LOADONCALL MOVEABLE DISCARDABLE >>$@.def"
+	@cmd /C "echo DATA    PRELOAD MOVEABLE MULTIPLE NONSHARED >>$@.def"	
+	@cmd /C "echo EXPORTS >>$@.def"
+	@cmd /C "$(FILTER) $(OBJS) >>$@.def"
+endif #OS2
+ifdef XP_OS2_VACPP
+	$(MKSHLIB) $(DLLFLAGS) $(LDFLAGS) $(OBJS) $(LD_LIBS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $@.def
+else
 	$(MKSHLIB) -o $@ $(OBJS) $(LD_LIBS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS)
+endif
 	chmod +x $@
 endif
 endif
 ifneq ($(POLICY),)
 	-$(PLCYPATCH) $(PLCYPATCH_ARGS) $@
 endif
 
 $(PURE_LIBRARY):
@@ -405,18 +421,22 @@ ifeq ($(OS_ARCH), WINNT)
 ifeq ($(OS_TARGET), WIN16)
 	echo $(WCCFLAGS3) >w16wccf
 	$(CC) -zq -fo$(OBJDIR)\\$(PROG_PREFIX)$*$(OBJ_SUFFIX)  @w16wccf $*.c
 	rm w16wccf
 else
 	$(CC) -Fo$@ -c $(CFLAGS) $*.c
 endif
 else
+ifdef XP_OS2_VACPP
+	$(CC) -Fo$@ -c $(CFLAGS) $*.c
+else
 	$(CC) -o $@ -c $(CFLAGS) $*.c
 endif
+endif
 
 ifneq ($(OS_ARCH), WINNT)
 $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.s
 	@$(MAKE_OBJDIR)
 	$(AS) -o $@ $(ASFLAGS) -c $*.s
 endif
 
 $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.asm
@@ -447,18 +467,22 @@ endif
 ifdef STRICT_CPLUSPLUS_SUFFIX
 	echo "#line 1 \"$*.cpp\"" | cat - $*.cpp > $(OBJDIR)/t_$*.cc
 	$(CCC) -o $@ -c $(CFLAGS) $(OBJDIR)/t_$*.cc
 	rm -f $(OBJDIR)/t_$*.cc
 else
 ifeq ($(OS_ARCH),WINNT)
 	$(CCC) -Fo$@ -c $(CFLAGS) $*.cpp
 else
+ifdef XP_OS2_VACPP
+	$(CCC) -Fo$@ -c $(CFLAGS) $*.cpp
+else
 	$(CCC) -o $@ -c $(CFLAGS) $*.cpp
 endif
+endif
 endif #STRICT_CPLUSPLUS_SUFFIX
 
 %.i: %.cpp
 ifeq ($(OS_TARGET), WIN16)
 	echo $(WCCFLAGS3) >w16wccf
 	$(CCC) -pl -fo=$* @w16wccf $*.cpp
 	rm w16wccf
 else
@@ -847,17 +871,17 @@ endif
 
 
 
 
 ################################################################################
 
 -include $(DEPENDENCIES)
 
-ifneq ($(OS_ARCH),WINNT)
+ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
 # Can't use sed because of its 4000-char line length limit, so resort to perl
 .DEFAULT:
 	@perl -e '                                                            \
 	    open(MD, "< $(DEPENDENCIES)");                                    \
 	    while (<MD>) {                                                    \
 		if (m@ \.*/*$< @) {                                           \
 		    $$found = 1;                                              \
 		    last;                                                     \
--- a/security/coreconf/suffix.mk
+++ b/security/coreconf/suffix.mk
@@ -123,18 +123,14 @@ ifndef DYNAMIC_LIB_SUFFIX_FOR_LINKING
 	endif
 endif
 
 #
 # Program suffixes
 #
 
 ifndef PROG_SUFFIX
-	ifeq ($(OS_ARCH), WINNT)
+	ifeq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
 		PROG_SUFFIX = .exe
 	else
-	    ifeq ($(OS_ARCH), OS2)
-		PROG_SUFFIX = .exe
-	    else
 		PROG_SUFFIX =
-	    endif
 	endif
 endif
--- a/security/nss/Makefile
+++ b/security/nss/Makefile
@@ -82,19 +82,19 @@ ifeq ($(OS_ARCH),WINNT)
 ifdef BUILD_OPT
 	cp $(DIST)/../WIN32_O.OBJ/lib/* $(DIST)/lib
 else
 	cp $(DIST)/../WIN32_D.OBJ/lib/* $(DIST)/lib
 endif
 	mv $(DIST)/lib/dbm32.lib $(DIST)/lib/dbm.lib
 else
 ifeq ($(OS_ARCH),OS2)
-	cp -r $(DIST)/../include $(DIST)
-	cp -r $(DIST)/../lib $(DIST)
-	mv $(DIST)/lib/libmozdbm_s.$(LIB_SUFFIX) $(DIST)/lib/libdbm.$(LIB_SUFFIX)
+	cp -rf $(DIST)/../include $(DIST)
+	cp -rf $(DIST)/../lib $(DIST)
+	cp -f $(DIST)/lib/libmozdbm_s.$(LIB_SUFFIX) $(DIST)/lib/libdbm.$(LIB_SUFFIX)
 else
 	$(NSINSTALL) -L ../../dist include $(DIST)
 	$(NSINSTALL) -L ../../dist lib $(DIST)
 	cp $(DIST)/lib/libmozdbm_s.$(LIB_SUFFIX) $(DIST)/lib/libdbm.$(LIB_SUFFIX)
 endif
 endif
 
 nsm:: all 
--- a/security/nss/cmd/platlibs.mk
+++ b/security/nss/cmd/platlibs.mk
@@ -102,16 +102,24 @@ EXTRA_LIBS += \
 	$(DIST)/lib/libswfci.$(LIB_SUFFIX) \
 	$(CRYPTOLIB) \
 	$(DIST)/lib/libsecutil.$(LIB_SUFFIX) \
 	$(DIST)/lib/libdbm.$(LIB_SUFFIX) \
 	$(NULL)
 
 # $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
 # $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
+ifdef XP_OS2_VACPP
+EXTRA_SHARED_LIBS += \
+	$(DIST)/lib/plc4.lib \
+	$(DIST)/lib/plds4.lib \
+	$(DIST)/lib/nspr4.lib \
+	$(NULL)
+else
 EXTRA_SHARED_LIBS += \
 	-L$(DIST)/lib/ \
 	-lplc4 \
 	-lplds4 \
 	-lnspr4 \
 	$(NULL)
 endif
+endif
 
--- a/security/nss/cmd/selfserv/selfserv.c
+++ b/security/nss/cmd/selfserv/selfserv.c
@@ -41,16 +41,20 @@
 #include <string.h>
 
 #include "secutil.h"
 
 #if defined(XP_UNIX)
 #include <unistd.h>
 #endif
 
+#ifdef XP_OS2_VACPP
+#include <Process.h>	/* for getpid() */
+#endif
+
 #include <stdlib.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdarg.h>
 
 #include "nspr.h"
 #include "prio.h"
 #include "prerror.h"
--- a/security/nss/lib/base/hashops.c
+++ b/security/nss/lib/base/hashops.c
@@ -40,17 +40,17 @@ static const char CVS_ID[] = "@(#) $RCSf
  *
  * This file includes a set of PLHashAllocOps that use NSSArenas.
  */
 
 #ifndef BASE_H
 #include "base.h"
 #endif /* BASE_H */
 
-static PR_CALLBACK void *
+static void * PR_CALLBACK
 nss_arena_hash_alloc_table
 (
   void *pool,
   PRSize size
 )
 {
   NSSArena *arena = (NSSArena *)pool;
 
@@ -60,27 +60,27 @@ nss_arena_hash_alloc_table
       return (void *)NULL;
     }
   }
 #endif /* NSSDEBUG */
 
   return nss_ZAlloc(arena, size);
 }
 
-static PR_CALLBACK void
+static void PR_CALLBACK
 nss_arena_hash_free_table
 (
   void *pool, 
   void *item
 )
 {
   (void)nss_ZFreeIf(item);
 }
 
-static PR_CALLBACK PLHashEntry *
+static PLHashEntry * PR_CALLBACK
 nss_arena_hash_alloc_entry
 (
   void *pool,
   const void *key
 )
 {
   NSSArena *arena = (NSSArena *)pool;
 
@@ -90,17 +90,17 @@ nss_arena_hash_alloc_entry
       return (void *)NULL;
     }
   }
 #endif /* NSSDEBUG */
 
   return nss_ZNEW(arena, PLHashEntry);
 }
 
-static PR_CALLBACK void
+static void PR_CALLBACK
 nss_arena_hash_free_entry
 (
   void *pool,
   PLHashEntry *he,
   PRUintn flag
 )
 {
   if( HT_FREE_ENTRY == flag ) {
--- a/security/nss/lib/base/tracker.c
+++ b/security/nss/lib/base/tracker.c
@@ -150,17 +150,17 @@ call_once
 /*
  * identity_hash
  *
  * This static callback is a PLHashFunction as defined in plhash.h
  * It merely returns the value of the object pointer as its hash.
  * There are no possible errors.
  */
 
-static PR_CALLBACK PLHashNumber
+static PLHashNumber PR_CALLBACK
 identity_hash
 (
   const void *key
 )
 {
   return (PLHashNumber)key;
 }
 
@@ -240,17 +240,17 @@ nssPointerTracker_initialize
 /*
  * count_entries
  *
  * This static routine is a PLHashEnumerator, as defined in plhash.h.
  * It merely causes the enumeration function to count the number of
  * entries.
  */
 
-static PR_CALLBACK PRIntn
+static PRIntn PR_CALLBACK
 count_entries
 (
   PLHashEntry *he,
   PRIntn index,
   void *arg
 )
 {
   return HT_ENUMERATE_NEXT;
--- a/security/nss/lib/certdb/certt.h
+++ b/security/nss/lib/certdb/certt.h
@@ -694,22 +694,22 @@ struct CERTVerifyLogStr {
 
 
 struct CERTOKDomainNameStr {
     CERTOKDomainName *next;
     char              name[1]; /* actual length may be longer. */
 };
 
 
-typedef SECStatus PR_CALLBACK (*CERTStatusChecker) (CERTCertDBHandle *handle,
+typedef SECStatus (PR_CALLBACK *CERTStatusChecker) (CERTCertDBHandle *handle,
 						    CERTCertificate *cert,
 						    int64 time,
 						    void *pwArg);
 
-typedef SECStatus PR_CALLBACK (*CERTStatusDestroy) (CERTStatusConfig *handle);
+typedef SECStatus (PR_CALLBACK *CERTStatusDestroy) (CERTStatusConfig *handle);
 
 struct CERTStatusConfigStr {
     CERTStatusChecker statusChecker;	/* NULL means no checking enabled */
     CERTStatusDestroy statusDestroy;	/* enabled or no, will clean up */
     void *statusContext;		/* cx specific to checking protocol */
 };
 
 struct CERTAuthInfoAccessStr {
--- a/security/nss/lib/ckfw/builtins/Makefile
+++ b/security/nss/lib/ckfw/builtins/Makefile
@@ -68,16 +68,25 @@ EXTRA_LIBS += \
 	$(PLC_STATIC_LIB) \
 	$(PLDS_STATIC_LIB) \
 	$(NULL)
 
 endif
 endif
 
 
+ifeq ($(OS_ARCH), WINNT)
+	SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).dll
+	IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).lib
+endif
+
+ifeq ($(OS_ARCH),OS2)
+	SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).dll
+endif
+
 
 include $(CORE_DEPTH)/coreconf/rules.mk
 
 certdata.c: certdata.txt certdata.perl
 	perl certdata.perl < certdata.txt
 
 # This'll need some help from a build person.
 
--- a/security/nss/lib/ckfw/ckapi.perl
+++ b/security/nss/lib/ckfw/ckapi.perl
@@ -234,28 +234,32 @@ static const char NSSCKEPV_CVS_ID[] = "$
 #ifndef NSSCKT_H
 #include "nssckt.h"
 #endif /* NSSCKT_H */
 
 #ifndef NSSCKFT_H
 #include "nssckft.h"
 #endif /* NSSCKFT_H */
 
+#include "nssckp.h"
+
 struct CK_FUNCTION_LIST {
   CK_VERSION version;
 EOD
     ;
 
 for( $j = 0; $j <= $count; $j++ ) {
   print "  CK_$x[$j]{name} $x[$j]{name};\n";
 }
 
 print <<EOD
 };
 
+#include "nsscku.h"
+
 #endif /* NSSCKEPV_H */
 EOD
     ;
 
 select API;
 
 print $copyright;
 print <<EOD
@@ -478,17 +482,21 @@ CK_RV CK_ENTRY
   CK_FUNCTION_LIST_PTR_PTR ppFunctionList
 )
 {
   *ppFunctionList = &FunctionList;
   return CKR_OK;
 }
 
 /* This one is always present */
+#ifdef WIN32
+CK_RV _declspec(dllexport)
+#else
 CK_RV CK_ENTRY
+#endif
 C_GetFunctionList
 (
   CK_FUNCTION_LIST_PTR_PTR ppFunctionList
 )
 {
   return __ADJOIN(MODULE_NAME,C_GetFunctionList)(ppFunctionList);
 }
 
--- a/security/nss/lib/ckfw/nssck.api
+++ b/security/nss/lib/ckfw/nssck.api
@@ -1867,17 +1867,21 @@ CK_RV CK_ENTRY
   CK_FUNCTION_LIST_PTR_PTR ppFunctionList
 )
 {
   *ppFunctionList = &FunctionList;
   return CKR_OK;
 }
 
 /* This one is always present */
+#ifdef WIN32
+CK_RV _declspec(dllexport)
+#else
 CK_RV CK_ENTRY
+#endif
 C_GetFunctionList
 (
   CK_FUNCTION_LIST_PTR_PTR ppFunctionList
 )
 {
   return __ADJOIN(MODULE_NAME,C_GetFunctionList)(ppFunctionList);
 }
 
--- a/security/nss/lib/ckfw/nssckepv.h
+++ b/security/nss/lib/ckfw/nssckepv.h
@@ -48,16 +48,18 @@ static const char NSSCKEPV_CVS_ID[] = "@
 #ifndef NSSCKT_H
 #include "nssckt.h"
 #endif /* NSSCKT_H */
 
 #ifndef NSSCKFT_H
 #include "nssckft.h"
 #endif /* NSSCKFT_H */
 
+#include "nssckp.h"
+
 struct CK_FUNCTION_LIST {
   CK_VERSION version;
   CK_C_Initialize C_Initialize;
   CK_C_Finalize C_Finalize;
   CK_C_GetInfo C_GetInfo;
   CK_C_GetFunctionList C_GetFunctionList;
   CK_C_GetSlotList C_GetSlotList;
   CK_C_GetSlotInfo C_GetSlotInfo;
@@ -120,9 +122,11 @@ struct CK_FUNCTION_LIST {
   CK_C_DeriveKey C_DeriveKey;
   CK_C_SeedRandom C_SeedRandom;
   CK_C_GenerateRandom C_GenerateRandom;
   CK_C_GetFunctionStatus C_GetFunctionStatus;
   CK_C_CancelFunction C_CancelFunction;
   CK_C_WaitForSlotEvent C_WaitForSlotEvent;
 };
 
+#include "nsscku.h"
+
 #endif /* NSSCKEPV_H */
--- a/security/nss/lib/fortcrypt/swfort/swfutl.c
+++ b/security/nss/lib/fortcrypt/swfort/swfutl.c
@@ -40,17 +40,17 @@
 
 #include "swforti.h"
 #include "keyt.h"
 /* #include "dh.h" */
 #include "maci.h"
 #include "secport.h"
 #include "secrng.h"
 #ifdef XP_OS2
-#include <stat.h> 	/* Needed for OS/2 emx */
+#include <sys/stat.h>
 #endif
 
 #ifdef XP_WIN
 #include <windows.h>
 #include <winsock.h>
 #include <direct.h>
 #endif
 
--- a/security/nss/lib/freebl/mpi/mpi-priv.h
+++ b/security/nss/lib/freebl/mpi/mpi-priv.h
@@ -212,23 +212,26 @@ mp_err   s_mp_sqr(mp_int *a);           
 #else
 #define  s_mp_sqr(a) s_mp_mul(a, a)
 #endif
 mp_err   s_mp_div(mp_int *a, mp_int *b);       /* magnitude divide        */
 mp_err   s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
 mp_err   s_mp_2expt(mp_int *a, mp_digit k);    /* a = 2^k                 */
 int      s_mp_cmp(const mp_int *a, const mp_int *b); /* magnitude comparison */
 int      s_mp_cmp_d(const mp_int *a, mp_digit d); /* magnitude digit compare */
-int      s_mp_ispow2(mp_int *v);               /* is v a power of 2?      */
+int      s_mp_ispow2(const mp_int *v);         /* is v a power of 2?      */
 int      s_mp_ispow2d(mp_digit d);             /* is d a power of 2?      */
 
 int      s_mp_tovalue(char ch, int r);          /* convert ch to value    */
 char     s_mp_todigit(mp_digit val, int r, int low); /* convert val to digit */
 int      s_mp_outlen(int bits, int r);          /* output length in bytes */
 mp_digit s_mp_invmod_radix(mp_digit P);   /* returns (P ** -1) mod RADIX */
+mp_err   s_mp_invmod_odd_m( const mp_int *a, const mp_int *m, mp_int *c);
+mp_err   s_mp_invmod_2d(    const mp_int *a, mp_size k,       mp_int *c);
+mp_err   s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c);
 
 /* ------ mpv functions, operate on arrays of digits, not on mp_int's ------ */
 void     s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c);
 void     s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, 
 			 mp_digit *c);
 void     s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, 
 			      mp_digit *c);
 void     s_mpv_sqr_add_prop(const mp_digit *a, mp_size a_len, mp_digit *sqrs);
@@ -236,8 +239,9 @@ mp_err   s_mpv_div_2dx1d(mp_digit Nhi, m
 		         mp_digit *quot, mp_digit *rem);
 
 /* c += a * b * (MP_RADIX ** offset);  */
 #define s_mp_mul_d_add_offset(a, b, c, off) \
 (s_mpv_mul_d_add_prop(MP_DIGITS(a), MP_USED(a), b, MP_DIGITS(c) + off), MP_OKAY)
 
 /* }}} */
 #endif
+
--- a/security/nss/lib/freebl/mpi/mpi-test.c
+++ b/security/nss/lib/freebl/mpi/mpi-test.c
@@ -60,105 +60,107 @@
   the corresponding solutions below.  Basically, these are just hex
   strings (for the big integers) or integer values (for the digits).
 
   The comparison tests think they know what relationships hold between
   these values.  If you change that, you may have to adjust the code
   for the comparison tests accordingly.  Most of the other tests
   should be fine as long as you re-compute the solutions, though.
  */
-char   *mp1  = "639A868CDA0C569861B";
-char   *mp2  = "AAFC0A3FE45E5E09DBE2C29";
-char   *mp3  = "B55AA8DF8A7E83241F38AC7A9E479CAEF2E4D7C5";
-char   *mp4  = "-63DBC2265B88268DC801C10EA68476B7BDE0090F";
-char   *mp5  = "F595CB42";
-char   *mp5a = "-4B597E";
-char   *mp6  = "0";
-char   *mp7  = "EBFA7121CD838CE6439CC59DDB4CBEF3";
-char   *mp8  = "5";
-char   *mp9  = "F74A2876A1432698923B0767DA19DCF3D71795EE";
-char   *mp10 = "9184E72A000";
-char   *mp11 = "54D79A3557E8";
-char   *mp12 = "10000000000000000";
-char   *mp13 = 
+const char   *mp1  = "639A868CDA0C569861B";
+const char   *mp2  = "AAFC0A3FE45E5E09DBE2C29";
+const char   *mp3  = "B55AA8DF8A7E83241F38AC7A9E479CAEF2E4D7C5";
+const char   *mp4  = "-63DBC2265B88268DC801C10EA68476B7BDE0090F";
+const char   *mp5  = "F595CB42";
+const char   *mp5a = "-4B597E";
+const char   *mp6  = "0";
+const char   *mp7  = "EBFA7121CD838CE6439CC59DDB4CBEF3";
+const char   *mp8  = "5";
+const char   *mp9  = "F74A2876A1432698923B0767DA19DCF3D71795EE";
+const char   *mp10 = "9184E72A000";
+const char   *mp11 = "54D79A3557E8";
+const char   *mp12 = "10000000000000000";
+const char   *mp13 = 
 "34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342BDAB6163963C"
 "D5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45F2B050D226E6DA88";
-char   *mp14 =
+const char   *mp14 =
 "AC3FA0EABAAC45724814D798942A1E28E14C81E0DE8055CED630E7689DA648683645DB6E"
 "458D9F5338CC3D4E33A5D1C9BF42780133599E60DEE0049AFA8F9489501AE5C9AA2B8C13"
 "FD21285A538B2CA87A626BB56E0A654C8707535E637FF4E39174157402BDE3AA30C9F134"
 "0C1307BAA864B075A9CC828B6A5E2B2BF1AE406D920CC5E7657D7C0E697DEE5375773AF9"
 "E200A1B8FAD7CD141F9EE47ABB55511FEB9A4D99EBA22F3A3FF6792FA7EE9E5DC0EE94F7"
 "7A631EDF3D7DD7C2DAAAFDF234D60302AB63D5234CEAE941B9AF0ADDD9E6E3A940A94EE5"
 "5DB45A7C66E61EDD0477419BBEFA44C325129601C4F45671C6A0E64665DF341D17FBC71F"
 "77418BD9F4375DDB3B9D56126526D8E5E0F35A121FD4F347013DA880020A752324F31DDD"
 "9BCDB13A3B86E207A2DE086825E6EEB87B3A64232CFD8205B799BC018634AAE193F19531"
 "D6EBC19A75F27CFFAA03EB5974898F53FD569AA5CE60F431B53B0CDE715A5F382405C9C4"
 "761A8E24888328F09F7BCE4E8D80C957DF177629C8421ACCD0C268C63C0DD47C3C0D954F"
 "D79F7D7297C6788DF4B3E51381759864D880ACA246DF09533739B8BB6085EAF7AE8DC2D9"
 "F224E6874926C8D24D34B457FD2C9A586C6B99582DC24F787A39E3942786CF1D494B6EB4"
 "A513498CDA0B217C4E80BCE7DA1C704C35E071AC21E0DA9F57C27C3533F46A8D20B04137"
 "C1B1384BE4B2EB46";
-char   *mp15 = 
+const char   *mp15 = 
 "39849CF7FD65AF2E3C4D87FE5526221103D90BA26A6642FFE3C3ECC0887BBBC57E011BF1"
 "05D822A841653509C68F79EBE51C0099B8CBB04DEF31F36F5954208A3209AC122F0E11D8"
 "4AE67A494D78336A2066D394D42E27EF6B03DDAF6D69F5112C93E714D27C94F82FC7EF77"
 "445768C68EAE1C4A1407BE1B303243391D325090449764AE469CC53EC8012C4C02A72F37"
 "07ED7275D2CC8D0A14B5BCC6BF264941520EBA97E3E6BAE4EE8BC87EE0DDA1F5611A6ECB"
 "65F8AEF4F184E10CADBDFA5A2FEF828901D18C20785E5CC63473D638762DA80625003711"
 "9E984AC43E707915B133543AF9D5522C3E7180DC58E1E5381C1FB7DC6A5F4198F3E88FA6"
 "CBB6DFA8B2D1C763226B253E18BCCB79A29EE82D2DE735078C8AE3C3C86D476AAA08434C"
 "09C274BDD40A1D8FDE38D6536C22F44E807EB73DE4FB36C9F51E0BC835DDBE3A8EFCF2FE"
 "672B525769DC39230EE624D5EEDBD837C82A52E153F37378C3AD68A81A7ADBDF3345DBCE"
 "8FA18CA1DE618EF94DF72EAD928D4F45B9E51632ACF158CF8332C51891D1D12C2A7E6684"
 "360C4BF177C952579A9F442CFFEC8DAE4821A8E7A31C4861D8464CA9116C60866C5E72F7"
 "434ADBED36D54ACDFDFF70A4EFB46E285131FE725F1C637D1C62115EDAD01C4189716327"
 "BFAA79618B1656CBFA22C2C965687D0381CC2FE0245913C4D8D96108213680BD8E93E821"
 "822AD9DDBFE4BD04";
-char   *mp16 = "4A724340668DB150339A70";
-char   *mp17 = "8ADB90F58";
-char   *mp18 = "C64C230AB20E5";
-char *mp19 = "F1C9DACDA287F2E3C88DCE2393B8F53DAAAC1196DC36510962B6B59454CFE64B";
-char *mp20 = "D445662C8B6FE394107B867797750C326E0F4A967E135FC430F6CD7207913AC7";
+const char   *mp16 = "4A724340668DB150339A70";
+const char   *mp17 = "8ADB90F58";
+const char   *mp18 = "C64C230AB20E5";
+const char *mp19 = 
+"F1C9DACDA287F2E3C88DCE2393B8F53DAAAC1196DC36510962B6B59454CFE64B";
+const char *mp20 = 
+"D445662C8B6FE394107B867797750C326E0F4A967E135FC430F6CD7207913AC7";
 
-mp_digit md1 = 0;
-mp_digit md2 = 0x1;
-mp_digit md3 = 0x80;
-mp_digit md4 = 0x9C97;
-mp_digit md5 = 0xF5BF;
-mp_digit md6 = 0x14A0;
-mp_digit md7 = 0x03E8;
-mp_digit md8 = 0x0101;
-mp_digit md9 = 0xA;
+const mp_digit md1 = 0;
+const mp_digit md2 = 0x1;
+const mp_digit md3 = 0x80;
+const mp_digit md4 = 0x9C97;
+const mp_digit md5 = 0xF5BF;
+const mp_digit md6 = 0x14A0;
+const mp_digit md7 = 0x03E8;
+const mp_digit md8 = 0x0101;
+const mp_digit md9 = 0xA;
 
 /* 
    Solutions of the form x_mpABC, where:
 
    x = (p)roduct, (s)um, (d)ifference, (q)uotient, (r)emainder, (g)cd,
        (i)nverse, (e)xponent, square roo(t), (g)cd, (l)cm.  A
        leading 'm' indicates a modular operation, e.g. ms_mp12 is the
        modular sum of operands 1 and 2
 
    ABC are the operand numbers involved in the computation.  If a 'd'
    precedes the number, it is a digit operand; if a 'c' precedes it,
    it is a constant; otherwise, it is a full integer.  
  */
 
-char *p_mp12   = "4286AD72E095C9FE009938750743174ADDD7FD1E53";
-char *p_mp34   = "-46BDBD66CA108C94A8CF46C325F7B6E2F2BA82D35"
-                 "A1BFD6934C441EE369B60CA29BADC26845E918B";
-char *p_mp57   = "E260C265A0A27C17AD5F4E59D6E0360217A2EBA6";
-char *p_mp22   = "7233B5C1097FFC77CCF55928FDC3A5D31B712FDE7A1E91";
-char *p_mp1d4  = "3CECEA2331F4220BEF68DED";
-char *p_mp8d6  = "6720";
-char *p_mp1113 =
+const char *p_mp12   = "4286AD72E095C9FE009938750743174ADDD7FD1E53";
+const char *p_mp34   = "-46BDBD66CA108C94A8CF46C325F7B6E2F2BA82D35"
+                       "A1BFD6934C441EE369B60CA29BADC26845E918B";
+const char *p_mp57   = "E260C265A0A27C17AD5F4E59D6E0360217A2EBA6";
+const char *p_mp22   = "7233B5C1097FFC77CCF55928FDC3A5D31B712FDE7A1E91";
+const char *p_mp1d4  = "3CECEA2331F4220BEF68DED";
+const char *p_mp8d6  = "6720";
+const char *p_mp1113 =
 "11590FC3831C8C3C51813142C88E566408DB04F9E27642F6471A1822E0100B12F7F1"
 "5699A127C0FA9D26DCBFF458522661F30C6ADA4A07C8C90F9116893F6DBFBF24C3A2"
 "4340";
-char *p_mp1415 = 
+const char *p_mp1415 = 
 "26B36540DE8B3586699CCEAE218A2842C7D5A01590E70C4A26E789107FBCDB06AA2C"
 "6DDC39E6FA18B16FCB2E934C9A5F844DAD60EE3B1EA82199EC5E9608F67F860FB965"
 "736055DF0E8F2540EB28D07F47E309B5F5D7C94FF190AB9C83A6970160CA700B1081"
 "F60518132AF28C6CEE6B7C473E461ABAC52C39CED50A08DD4E7EA8BA18DAD545126D"
 "A388F6983C29B6BE3F9DCBC15766E8E6D626A92C5296A9C4653CAE5788350C0E2107"
 "F57E5E8B6994C4847D727FF1A63A66A6CEF42B9C9E6BD04C92550B85D5527DE8A132"
 "E6BE89341A9285C7CE7FB929D871BBCBD0ED2863B6B078B0DBB30FCA66D6C64284D6"
 "57F394A0271E15B6EC7A9D530EBAC6CA262EF6F97E1A29FCE7749240E4AECA591ECF"
@@ -181,25 +183,25 @@ char *p_mp1415 =
 "7984610B27B5786DE55C184DDF556EDFEA79A3652831940DAD941E243F482DC17E50"
 "284BC2FB1AD712A92542C573E55678878F02DFD9E3A863C7DF863227AEDE14B47AD3"
 "957190124820ADC19F5353878EDB6BF7D0C77352A6E3BDB53EEB88F5AEF6226D6E68"
 "756776A8FB49B77564147A641664C2A54F7E5B680CCC6A4D22D894E464DF20537094"
 "548F1732452F9E7F810C0B4B430C073C0FBCE03F0D03F82630654BCE166AA772E1EE"
 "DD0C08D3E3EBDF0AF54203B43AFDFC40D8FC79C97A4B0A4E1BEB14D8FCEFDDED8758"
 "6ED65B18";
 
-char *mp_mp345 = "B9B6D3A3";
-char *mp_mp335 = "16609C2D";
+const char *mp_mp345 = "B9B6D3A3";
+const char *mp_mp335 = "16609C2D";
 
-char *s_mp13   = "B55AA8DF8A7E83241F38B2B446B06A4FB84E5DE0";
-char *s_mp34   = "517EE6B92EF65C965736EB6BF7C325F73504CEB6";
-char *s_mp46   = "-63DBC2265B88268DC801C10EA68476B7BDE0090F";
-char *s_mp5d4  = "F59667D9";
-char *s_mp2d5  = "AAFC0A3FE45E5E09DBF21E8";
-char *s_mp1415 = 
+const char *s_mp13   = "B55AA8DF8A7E83241F38B2B446B06A4FB84E5DE0";
+const char *s_mp34   = "517EE6B92EF65C965736EB6BF7C325F73504CEB6";
+const char *s_mp46   = "-63DBC2265B88268DC801C10EA68476B7BDE0090F";
+const char *s_mp5d4  = "F59667D9";
+const char *s_mp2d5  = "AAFC0A3FE45E5E09DBF21E8";
+const char *s_mp1415 = 
 "E5C43DE2B811F4A084625F96E9504039E5258D8348E698CEB9F4D4292622042DB446"
 "F75F4B65C1FB7A317257FA354BB5A45E789AEC254EAECE11F80A53E3B513822491DB"
 "D9399DEC4807A2A3A10360129AC93F4A42388D3BF20B310DD0E9E9F4BE07FC88D53A"
 "78A26091E0AB506A70813712CCBFBDD440A69A906E650EE090FDD6A42A95AC1A414D"
 "317F1A9F781E6A30E9EE142ECDA45A1E3454A1417A7B9A613DA90831CF88EA1F2E82"
 "41AE88CC4053220903C2E05BCDD42F02B8CF8868F84C64C5858BAD356143C5494607"
 "EE22E11650148BAF65A985F6FC4CA540A55697F2B5AA95D6B8CF96EF638416DE1DD6"
 "3BA9E2C09E22D03E75B60BE456C642F86B82A709253E5E087B507DE3A45F8392423F"
@@ -207,68 +209,69 @@ char *s_mp1415 =
 "1B6111F8B8CFACB7C7C9BC12691C22EE88303E1713F1DFCEB622B8EA102F6365678B"
 "C580ED87225467AA78E875868BD53B17574BA59305BC1AC666E4B7E9ED72FCFC200E"
 "189D98FC8C5C7533739C53F52DDECDDFA5A8668BFBD40DABC9640F8FCAE58F532940"
 "8162261320A25589E9FB51B50F80056471F24B7E1AEC35D1356FC2747FFC13A04B34"
 "24FCECE10880BD9D97CA8CDEB2F5969BF4F30256EB5ED2BCD1DC64BDC2EE65217848"
 "48A37FB13F84ED4FB7ACA18C4639EE64309BDD3D552AEB4AAF44295943DC1229A497"
 "A84A";
 
-char *ms_mp345 = "1E71E292";
+const char *ms_mp345 = "1E71E292";
 
-char *d_mp12   = "-AAFBA6A55DD183FD854A60E";
-char *d_mp34   = "119366B05E606A9B1E73A6D8944CC1366B0C4E0D4";
-char *d_mp5d4  = "F5952EAB";
-char *d_mp6d2  = "-1";
-char *md_mp345 = "26596B86";
+const char *d_mp12   = "-AAFBA6A55DD183FD854A60E";
+const char *d_mp34   = "119366B05E606A9B1E73A6D8944CC1366B0C4E0D4";
+const char *d_mp5d4  = "F5952EAB";
+const char *d_mp6d2  = "-1";
+const char *md_mp345 = "26596B86";
 
-char *q_mp42   = "-95825A1FFA1A155D5";
-char *r_mp42   = "-6312E99D7700A3DCB32ADF2";
-char *q_mp45a  = "15344CDA3D841F661D2B61B6EDF7828CE36";
-char *r_mp45a  = "-47C47B";
-char *q_mp7c2  = "75FD3890E6C1C67321CE62CEEDA65F79";
-char *q_mp3d6  = "8CAFD53C272BD6FE8B0847BDC3B539EFAB5C3";
-char *r_mp3d6  = "1E5";
-char *r_mp5d5  = "1257";
-char *r_mp47   = "B3A9018D970281A90FB729A181D95CB8";
-char *q_mp1404 = 
+const char *q_mp42   = "-95825A1FFA1A155D5";
+const char *r_mp42   = "-6312E99D7700A3DCB32ADF2";
+const char *q_mp45a  = "15344CDA3D841F661D2B61B6EDF7828CE36";
+const char *r_mp45a  = "-47C47B";
+const char *q_mp7c2  = "75FD3890E6C1C67321CE62CEEDA65F79";
+const char *q_mp3d6  = "8CAFD53C272BD6FE8B0847BDC3B539EFAB5C3";
+const char *r_mp3d6  = "1E5";
+const char *r_mp5d5  = "1257";
+const char *r_mp47   = "B3A9018D970281A90FB729A181D95CB8";
+const char *q_mp1404 = 
 "-1B994D869142D3EF6123A3CBBC3C0114FA071CFCEEF4B7D231D65591D32501AD80F"
 "FF49AE4EC80514CC071EF6B42521C2508F4CB2FEAD69A2D2EF3934087DCAF88CC4C4"
 "659F1CA8A7F4D36817D802F778F1392337FE36302D6865BF0D4645625DF8BB044E19"
 "930635BE2609FAC8D99357D3A9F81F2578DE15A300964188292107DAC980E0A08CD7"
 "E938A2135FAD45D50CB1D8C2D4C4E60C27AB98B9FBD7E4DBF752C57D2674520E4BB2"
 "7E42324C0EFE84FB3E38CF6950E699E86FD45FE40D428400F2F94EDF7E94FAE10B45"
 "89329E1BF61E5A378C7B31C9C6A234F8254D4C24823B84D0BF8D671D8BC9154DFAC9"
 "49BD8ACABD6BD32DD4DC587F22C86153CB3954BDF7C2A890D623642492C482CF3E2C"
 "776FC019C3BBC61688B485E6FD35D6376089C1E33F880E84C4E51E8ABEACE1B3FB70"
 "3EAD0E28D2D44E7F1C0A859C840775E94F8C1369D985A3C5E8114B21D68B3CBB75D2"
 "791C586153C85B90CAA483E57A40E2D97950AAB84920A4396C950C87C7FFFE748358"
 "42A0BF65445B26D40F05BE164B822CA96321F41D85A289C5F5CD5F438A78704C9683"
 "422299D21899A22F853B0C93081CC9925E350132A0717A611DD932A68A0ACC6E4C7F"
 "7F685EF8C1F4910AEA5DC00BB5A36FCA07FFEAA490C547F6E14A08FE87041AB803E1"
 "BD9E23E4D367A2C35762F209073DFF48F3";
-char *r_mp1404 = "12FF98621ABF63144BFFC3207AC8FC10D8D1A09";
+const char *r_mp1404 = "12FF98621ABF63144BFFC3207AC8FC10D8D1A09";
 
-char *q_mp13c  = "34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342"
-                 "BDAB6163963CD5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45";
-char *r_mp13c  = "F2B050D226E6DA88";
-char *q_mp9c16 = "F74A2876A1432698923B0767DA19DCF3D71795E";
-char *r_mp9c16 = "E";
+const char *q_mp13c  = 
+		"34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342"
+		"BDAB6163963CD5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45";
+const char *r_mp13c  = "F2B050D226E6DA88";
+const char *q_mp9c16 = "F74A2876A1432698923B0767DA19DCF3D71795E";
+const char *r_mp9c16 = "E";
 
-char *e_mp5d9 = "A8FD7145E727A20E52E73D22990D35D158090307A"
-                "13A5215AAC4E9AB1E96BD34E531209E03310400";
-char *e_mp78  = "AA5F72C737DFFD8CCD108008BFE7C79ADC01A819B"
-                "32B75FB82EC0FB8CA83311DA36D4063F1E57857A2"
-                "1AB226563D84A15BB63CE975FF1453BD6750C58D9"
-                "D113175764F5D0B3C89B262D4702F4D9640A3";
-char *me_mp817 = "E504493ACB02F7F802B327AB13BF25";
-char *me_mp5d47 = "1D45ED0D78F2778157992C951DD2734C";
-char *me_mp1512 = "FB5B2A28D902B9D9";
-char *me_mp161718 = "423C6AC6DBD74";
-char *me_mp5114 =
+const char *e_mp5d9 = "A8FD7145E727A20E52E73D22990D35D158090307A"
+		      "13A5215AAC4E9AB1E96BD34E531209E03310400";
+const char *e_mp78  = "AA5F72C737DFFD8CCD108008BFE7C79ADC01A819B"
+		      "32B75FB82EC0FB8CA83311DA36D4063F1E57857A2"
+		      "1AB226563D84A15BB63CE975FF1453BD6750C58D9"
+		      "D113175764F5D0B3C89B262D4702F4D9640A3";
+const char *me_mp817 = "E504493ACB02F7F802B327AB13BF25";
+const char *me_mp5d47 = "1D45ED0D78F2778157992C951DD2734C";
+const char *me_mp1512 = "FB5B2A28D902B9D9";
+const char *me_mp161718 = "423C6AC6DBD74";
+const char *me_mp5114 =
 "64F0F72807993578BBA3C7C36FFB184028F9EB9A810C92079E1498D8A80FC848E1F0"
 "25F1DE43B7F6AC063F5CC29D8A7C2D7A66269D72BF5CDC327AF88AF8EF9E601DCB0A"
 "3F35BFF3525FB1B61CE3A25182F17C0A0633B4089EA15BDC47664A43FEF639748AAC"
 "19CF58E83D8FA32CD10661D2D4210CC84792937E6F36CB601851356622E63ADD4BD5"
 "542412C2E0C4958E51FD2524AABDC7D60CFB5DB332EEC9DC84210F10FAE0BA2018F2"
 "14C9D6867C9D6E49CF28C18D06CE009FD4D04BFC8837C3FAAA773F5CCF6DED1C22DE"
 "181786AFE188540586F2D74BF312E595244E6936AE52E45742109BAA76C36F2692F5"
 "CEF97AD462B138BE92721194B163254CBAAEE9B9864B21CCDD5375BCAD0D24132724"
@@ -276,43 +279,43 @@ char *me_mp5114 =
 "D7A2C8B280C2A278BA9BF5D93244D563015C9484B86D9FEB602501DC16EEBC3EFF19"
 "53D7999682BF1A1E3B2E7B21F4BDCA3C355039FEF55B9C0885F98DC355CA7A6D8ECF"
 "5F7F1A6E11A764F2343C823B879B44616B56BF6AE3FA2ACF5483660E618882018E3F"
 "C8459313BACFE1F93CECC37B2576A5C0B2714BD3EEDEEC22F0E7E3E77B11396B9B99"
 "D683F2447A4004BBD4A57F6A616CDDFEC595C4FC19884CC2FC21CF5BF5B0B81E0F83"
 "B9DDA0CF4DFF35BB8D31245912BF4497FD0BD95F0C604E26EA5A8EA4F5EAE870A5BD"
 "FE8C";
 
-char *e_mpc2d3 = "100000000000000000000000000000000";
+const char *e_mpc2d3 = "100000000000000000000000000000000";
 
-char *t_mp9    = "FB9B6E32FF0452A34746";
-char *i_mp27   = "B6AD8DCCDAF92B6FE57D062FFEE3A99";
-char *i_mp2019 = 
+const char *t_mp9    = "FB9B6E32FF0452A34746";
+const char *i_mp27   = "B6AD8DCCDAF92B6FE57D062FFEE3A99";
+const char *i_mp2019 = 
 "BDF3D88DC373A63EED92903115B03FC8501910AF68297B4C41870AED3EA9F839";
 /* "15E3FE09E8AE5523AABA197BD2D16318D3CA148EDF4AE1C1C52FC96AFAF5680B"; */
 
 
-char *t_mp15 =
+const char *t_mp15 =
 "795853094E59B0008093BCA8DECF68587C64BDCA2F3F7F8963DABC12F1CFFFA9B8C4"
 "365232FD4751870A0EF6CA619287C5D8B7F1747D95076AB19645EF309773E9EACEA0"
 "975FA4AE16251A8DA5865349C3A903E3B8A2C0DEA3C0720B6020C7FED69AFF62BB72"
 "10FAC443F9FFA2950776F949E819260C2AF8D94E8A1431A40F8C23C1973DE5D49AA2"
 "0B3FF5DA5C1D5324E712A78FF33A9B1748F83FA529905924A31DF38643B3F693EF9B"
 "58D846BB1AEAE4523ECC843FF551C1B300A130B65C1677402778F98C51C10813250E"
 "2496882877B069E877B59740DC1226F18A5C0F66F64A5F59A9FAFC5E9FC45AEC0E7A"
 "BEE244F7DD3AC268CF512A0E52E4F5BE5B94";
 
-char *g_mp71   = "1";
-char *g_mp25   = "7";
-char *l_mp1011 = "C589E3D7D64A6942A000";
+const char *g_mp71   = "1";
+const char *g_mp25   = "7";
+const char *l_mp1011 = "C589E3D7D64A6942A000";
 
 /* mp9 in radices from 5 to 64 inclusive */
 #define LOW_RADIX   5
 #define HIGH_RADIX  64
-char *v_mp9[] = {
+const char *v_mp9[] = {
   "404041130042310320100141302000203430214122130002340212132414134210033",
   "44515230120451152500101352430105520150025145320010504454125502",
   "644641136612541136016610100564613624243140151310023515322",
   "173512120732412062323044435407317550316717172705712756",
   "265785018434285762514442046172754680368422060744852",
   "1411774500397290569709059837552310354075408897518",
   "184064268501499311A17746095910428222A241708032A",
   "47706011B225950B02BB45602AA039893118A85950892",
@@ -365,17 +368,17 @@ char *v_mp9[] = {
   "2A70gDPX2AtiicvIGGk9poiMtgvu",
   "1MjiRxjk10J6SVAxFguv9kZiUnIc",
   "rpre2vIDeb4h3sp50r1YBbtEx9L",
   "ZHcoip0AglDAfibrsUcJ9M1C8fm",
   "NHP18+eoe6uU54W49Kc6ZK7+bT2",
   "FTAA7QXGoQOaZi7PzePtFFN5vNk"
 };
 
-unsigned char b_mp4[] = {
+const unsigned char b_mp4[] = {
   0x01, 
 #if MP_DIGIT_MAX > MP_32BIT_MAX
   0x00, 0x00, 0x00, 0x00,
 #endif
   0x63, 0xDB, 0xC2, 0x26, 
   0x5B, 0x88, 0x26, 0x8D, 
   0xC8, 0x01, 0xC1, 0x0E, 
   0xA6, 0x84, 0x76, 0xB7, 
@@ -385,16 +388,17 @@ unsigned char b_mp4[] = {
 /* Search for a test suite name in the names table  */
 int  find_name(char *name);
 void reason(char *fmt, ...);
 
 /*------------------------------------------------------------------------*/
 /*------------------------------------------------------------------------*/
 
 char g_intbuf[4096];  /* buffer for integer comparison   */
+char a_intbuf[4096];  /* buffer for integer comparison   */
 int  g_verbose = 1;   /* print out reasons for failure?  */
 int  res;
 
 #define IFOK(x) { if (MP_OKAY > (res = (x))) { \
   reason("test %s failed: error %d\n", #x, res); return 1; }}
 
 int main(int argc, char *argv[])
 {
@@ -1337,19 +1341,28 @@ int test_exptmod_d(void)
 
   return 0;
 }
 
 /*------------------------------------------------------------------------*/
 
 int test_invmod(void)
 {
-  mp_int  a, m;
+  mp_int  a, m, c;
+  mp_int  p1, p2, p3, p4, p5;
+  mp_int  t1, t2, t3, t4;
   mp_err  res;
 
+  /* 5 128-bit primes. */
+  static const char ivp1[] = { "AAD8A5A2A2BEF644BAEE7DB0CA643719" };
+  static const char ivp2[] = { "CB371AD2B79A90BCC88D0430663E40B9" };
+  static const char ivp3[] = { "C6C818D4DF2618406CA09280C0400099" };
+  static const char ivp4[] = { "CE949C04512E68918006B1F0D7E93F27" };
+  static const char ivp5[] = { "F8EE999B6416645040687440E0B89F51" };
+
   mp_init(&a); mp_init(&m);
   mp_read_radix(&a, mp2, 16); mp_read_radix(&m, mp7, 16);
 
   IFOK( mp_invmod(&a, &m, &a) );
 
   mp_toradix(&a, g_intbuf, 16);
   mp_clear(&a); mp_clear(&m);
 
@@ -1366,16 +1379,226 @@ int test_invmod(void)
   mp_toradix(&a, g_intbuf, 16);
   mp_clear(&a); mp_clear(&m);
 
   if(strcmp(g_intbuf, i_mp2019) != 0) {
     reason("error: invmod test 2 computed %s, expected %s\n", g_intbuf, i_mp2019);
     return 1;
   }
 
+/* Need the following test cases:
+  Odd modulus
+    - a is odd,      relatively prime to m
+    - a is odd,  not relatively prime to m
+    - a is even,     relatively prime to m
+    - a is even, not relatively prime to m
+  Even modulus
+    - a is even  (should fail)
+    - a is odd,  not relatively prime to m
+    - a is odd,      relatively prime to m,
+      m is not a power of 2
+	- m has factor 2**k, k < 32
+	- m has factor 2**k, k > 32
+      m is a power of 2, 2**k
+	- k < 32
+	- k > 32
+*/
+
+  mp_init(&a);  mp_init(&m);  mp_init(&c);  
+  mp_init(&p1); mp_init(&p2); mp_init(&p3); mp_init(&p4); mp_init(&p5); 
+  mp_init(&t1); mp_init(&t2); mp_init(&t3); mp_init(&t4); 
+
+  mp_read_radix(&p1, ivp1, 16);
+  mp_read_radix(&p2, ivp2, 16);
+  mp_read_radix(&p3, ivp3, 16);
+  mp_read_radix(&p4, ivp4, 16);
+  mp_read_radix(&p5, ivp5, 16);
+
+  IFOK( mp_2expt(&t2, 68) );	/* t2 = 2**68 */
+  IFOK( mp_2expt(&t3, 128) );	/* t3 = 2**128 */
+  IFOK( mp_2expt(&t4, 31) );	/* t4 = 2**31 */
+
+/* test 3: Odd modulus - a is odd, relatively prime to m */
+
+  IFOK( mp_mul(&p1, &p2, &a) );
+  IFOK( mp_mul(&p3, &p4, &m) );
+  IFOK( mp_invmod(&a, &m, &t1) );
+  IFOK( mp_invmod_xgcd(&a, &m, &c) );
+
+  if (mp_cmp(&t1, &c) != 0) {
+    mp_toradix(&t1, g_intbuf, 16);
+    mp_toradix(&c,  a_intbuf, 16);
+    reason("error: invmod test 3 computed %s, expected %s\n", 
+           g_intbuf, a_intbuf);
+    return 1;
+  }
+  mp_clear(&a);  mp_clear(&t1); mp_clear(&c);  
+  mp_init(&a);   mp_init(&t1);  mp_init(&c);   
+
+/* test 4: Odd modulus - a is odd, NOT relatively prime to m */
+
+  IFOK( mp_mul(&p1, &p3, &a) );
+  /* reuse same m as before */
+
+  res = mp_invmod_xgcd(&a, &m, &c);
+  if (res != MP_UNDEF) 
+    goto CLEANUP4;
+
+  res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
+  if (res != MP_UNDEF) {
+CLEANUP4:
+    reason("error: invmod test 4 succeeded, should have failed.\n");
+    return 1;
+  }
+  mp_clear(&a);  mp_clear(&t1); mp_clear(&c);  
+  mp_init(&a);   mp_init(&t1);  mp_init(&c);   
+
+/* test 5: Odd modulus - a is even, relatively prime to m */
+
+  IFOK( mp_mul(&p1, &t2, &a) );
+  /* reuse m */
+  IFOK( mp_invmod(&a, &m, &t1) );
+  IFOK( mp_invmod_xgcd(&a, &m, &c) );
+
+  if (mp_cmp(&t1, &c) != 0) {
+    mp_toradix(&t1, g_intbuf, 16);
+    mp_toradix(&c,  a_intbuf, 16);
+    reason("error: invmod test 5 computed %s, expected %s\n", 
+           g_intbuf, a_intbuf);
+    return 1;
+  }
+  mp_clear(&a);  mp_clear(&t1); mp_clear(&c);  
+  mp_init(&a);   mp_init(&t1);  mp_init(&c);   
+
+/* test 6: Odd modulus - a is odd, NOT relatively prime to m */
+
+  /* reuse t2 */
+  IFOK( mp_mul(&t2, &p3, &a) );
+  /* reuse same m as before */
+
+  res = mp_invmod_xgcd(&a, &m, &c);
+  if (res != MP_UNDEF) 
+    goto CLEANUP6;
+
+  res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
+  if (res != MP_UNDEF) {
+CLEANUP6:
+    reason("error: invmod test 6 succeeded, should have failed.\n");
+    return 1;
+  }
+  mp_clear(&a);  mp_clear(&m); mp_clear(&c);  mp_clear(&t1); 
+  mp_init(&a);   mp_init(&m);  mp_init(&c);   mp_init(&t1); 
+
+/* test 7: Even modulus, even a, should fail */
+
+  IFOK( mp_mul(&p3, &t3, &m) ); /* even m */
+  /* reuse t2 */
+  IFOK( mp_mul(&p1, &t2, &a) ); /* even a */
+
+  res = mp_invmod_xgcd(&a, &m, &c);
+  if (res != MP_UNDEF) 
+    goto CLEANUP7;
+
+  res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
+  if (res != MP_UNDEF) {
+CLEANUP7:
+    reason("error: invmod test 7 succeeded, should have failed.\n");
+    return 1;
+  }
+  mp_clear(&a);  mp_clear(&c);  mp_clear(&t1); 
+  mp_init(&a);   mp_init(&c);   mp_init(&t1); 
+
+/* test 8: Even modulus    - a is odd,  not relatively prime to m */
+
+  /* reuse m */
+  IFOK( mp_mul(&p3, &p1, &a) ); /* even a */
+
+  res = mp_invmod_xgcd(&a, &m, &c);
+  if (res != MP_UNDEF) 
+    goto CLEANUP8;
+
+  res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
+  if (res != MP_UNDEF) {
+CLEANUP8:
+    reason("error: invmod test 8 succeeded, should have failed.\n");
+    return 1;
+  }
+  mp_clear(&a);  mp_clear(&m); mp_clear(&c);  mp_clear(&t1); 
+  mp_init(&a);   mp_init(&m);  mp_init(&c);   mp_init(&t1); 
+
+/* test 9: Even modulus    - m has factor 2**k, k < 32
+ *	                   - a is odd, relatively prime to m,
+ */
+  IFOK( mp_mul(&p3, &t4, &m) ); /* even m */
+  IFOK( mp_mul(&p1, &p2, &a) );
+  IFOK( mp_invmod(&a, &m, &t1) );
+  IFOK( mp_invmod_xgcd(&a, &m, &c) );
+
+  if (mp_cmp(&t1, &c) != 0) {
+    mp_toradix(&t1, g_intbuf, 16);
+    mp_toradix(&c,  a_intbuf, 16);
+    reason("error: invmod test 9 computed %s, expected %s\n", 
+           g_intbuf, a_intbuf);
+    return 1;
+  }
+  mp_clear(&m);  mp_clear(&t1); mp_clear(&c);  
+  mp_init(&m);   mp_init(&t1);  mp_init(&c);   
+
+/* test 10: Even modulus    - m has factor 2**k, k > 32
+ *	                    - a is odd, relatively prime to m,
+ */
+  IFOK( mp_mul(&p3, &t3, &m) ); /* even m */
+  /* reuse a */
+  IFOK( mp_invmod(&a, &m, &t1) );
+  IFOK( mp_invmod_xgcd(&a, &m, &c) );
+
+  if (mp_cmp(&t1, &c) != 0) {
+    mp_toradix(&t1, g_intbuf, 16);
+    mp_toradix(&c,  a_intbuf, 16);
+    reason("error: invmod test 10 computed %s, expected %s\n", 
+           g_intbuf, a_intbuf);
+    return 1;
+  }
+  mp_clear(&t1); mp_clear(&c);  
+  mp_init(&t1);  mp_init(&c);   
+
+/* test 11: Even modulus    - m is a power of 2, 2**k | k < 32
+ *                          - a is odd, relatively prime to m,
+ */
+  IFOK( mp_invmod(&a, &t4, &t1) );
+  IFOK( mp_invmod_xgcd(&a, &t4, &c) );
+
+  if (mp_cmp(&t1, &c) != 0) {
+    mp_toradix(&t1, g_intbuf, 16);
+    mp_toradix(&c,  a_intbuf, 16);
+    reason("error: invmod test 11 computed %s, expected %s\n", 
+           g_intbuf, a_intbuf);
+    return 1;
+  }
+  mp_clear(&t1); mp_clear(&c);  
+  mp_init(&t1);  mp_init(&c);   
+
+/* test 12: Even modulus    - m is a power of 2, 2**k | k > 32
+ *                          - a is odd, relatively prime to m,
+ */
+  IFOK( mp_invmod(&a, &t3, &t1) );
+  IFOK( mp_invmod_xgcd(&a, &t3, &c) );
+
+  if (mp_cmp(&t1, &c) != 0) {
+    mp_toradix(&t1, g_intbuf, 16);
+    mp_toradix(&c,  a_intbuf, 16);
+    reason("error: invmod test 12 computed %s, expected %s\n", 
+           g_intbuf, a_intbuf);
+    return 1;
+  }
+
+  mp_clear(&a);  mp_clear(&m);  mp_clear(&c);  
+  mp_clear(&t1); mp_clear(&t2); mp_clear(&t3); mp_clear(&t4); 
+  mp_clear(&p1); mp_clear(&p2); mp_clear(&p3); mp_clear(&p4); mp_clear(&p5); 
+
   return 0;
 }
 
 /*------------------------------------------------------------------------*/
 
 int test_cmp_d(void)
 {
   mp_int  a;
@@ -1650,25 +1873,46 @@ int test_raw(void)
 }
 
 /*------------------------------------------------------------------------*/
 
 int test_pprime(void)
 {
   mp_int   p;
   int      err = 0;
+  mp_err   res;
 
   mp_init(&p);
   mp_read_radix(&p, mp7, 16);
 
   if(mpp_pprime(&p, 5) != MP_YES) {
     reason("error: %s failed Rabin-Miller test, but is prime\n", mp7);
     err = 1;
   }
 
+  IFOK( mp_set_int(&p, 9) );
+  res = mpp_pprime(&p, 50);
+  if (res == MP_YES) {
+    reason("error: 9 is composite but passed Rabin-Miller test\n");
+    err = 1;
+  } else if (res != MP_NO) {
+    reason("test mpp_pprime(9, 50) failed: error %d\n", res); 
+    err = 1;
+  }
+
+  IFOK( mp_set_int(&p, 15) );
+  res = mpp_pprime(&p, 50);
+  if (res == MP_YES) {
+    reason("error: 15 is composite but passed Rabin-Miller test\n");
+    err = 1;
+  } else if (res != MP_NO) {
+    reason("test mpp_pprime(15, 50) failed: error %d\n", res); 
+    err = 1;
+  }
+
   mp_clear(&p);
 
   return err;
 
 }
 
 /*------------------------------------------------------------------------*/
 
--- a/security/nss/lib/freebl/mpi/mpi.c
+++ b/security/nss/lib/freebl/mpi/mpi.c
@@ -942,20 +942,17 @@ CLEANUP:
 /* {{{ mp_div(a, b, q, r) */
 
 /*
   mp_div(a, b, q, r)
 
   Compute q = a / b and r = a mod b.  Input parameters may be re-used
   as output parameters.  If q or r is NULL, that portion of the
   computation will be discarded (although it will still be computed)
-
-  Pay no attention to the hacker behind the curtain.
  */
-
 mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)
 {
   mp_err   res;
   mp_int   *pQ, *pR;
   mp_int   qtmp, rtmp;
   int      cmp;
 
   ARGCHK(a != NULL && b != NULL, MP_BADARG);
@@ -1860,131 +1857,173 @@ mp_err mp_lcm(mp_int *a, mp_int *b, mp_i
 /* }}} */
 
 /* {{{ mp_xgcd(a, b, g, x, y) */
 
 /*
   mp_xgcd(a, b, g, x, y)
 
   Compute g = (a, b) and values x and y satisfying Bezout's identity
-  (that is, ax + by = g).  This uses the extended binary GCD algorithm
+  (that is, ax + by = g).  This uses the binary extended GCD algorithm
   based on the Stein algorithm used for mp_gcd()
+  See algorithm 14.61 in Handbook of Applied Cryptogrpahy.
  */
 
-mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y)
+mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y)
 {
   mp_int   gx, xc, yc, u, v, A, B, C, D;
   mp_int  *clean[9];
   mp_err   res;
   int      last = -1;
 
   if(mp_cmp_z(b) == 0)
     return MP_RANGE;
 
   /* Initialize all these variables we need */
-  if((res = mp_init(&u)) != MP_OKAY) goto CLEANUP;
+  MP_CHECKOK( mp_init(&u) );
   clean[++last] = &u;
-  if((res = mp_init(&v)) != MP_OKAY) goto CLEANUP;
+  MP_CHECKOK( mp_init(&v) );
   clean[++last] = &v;
-  if((res = mp_init(&gx)) != MP_OKAY) goto CLEANUP;
+  MP_CHECKOK( mp_init(&gx) );
   clean[++last] = &gx;
-  if((res = mp_init(&A)) != MP_OKAY) goto CLEANUP;
+  MP_CHECKOK( mp_init(&A) );
   clean[++last] = &A;
-  if((res = mp_init(&B)) != MP_OKAY) goto CLEANUP;
+  MP_CHECKOK( mp_init(&B) );
   clean[++last] = &B;
-  if((res = mp_init(&C)) != MP_OKAY) goto CLEANUP;
+  MP_CHECKOK( mp_init(&C) );
   clean[++last] = &C;
-  if((res = mp_init(&D)) != MP_OKAY) goto CLEANUP;
+  MP_CHECKOK( mp_init(&D) );
   clean[++last] = &D;
-  if((res = mp_init_copy(&xc, a)) != MP_OKAY) goto CLEANUP;
+  MP_CHECKOK( mp_init_copy(&xc, a) );
   clean[++last] = &xc;
   mp_abs(&xc, &xc);
-  if((res = mp_init_copy(&yc, b)) != MP_OKAY) goto CLEANUP;
+  MP_CHECKOK( mp_init_copy(&yc, b) );
   clean[++last] = &yc;
   mp_abs(&yc, &yc);
 
   mp_set(&gx, 1);
 
-  /* Divide by two until at least one of them is even */
+  /* Divide by two until at least one of them is odd */
   while(mp_iseven(&xc) && mp_iseven(&yc)) {
-    s_mp_div_2(&xc);
-    s_mp_div_2(&yc);
-    if((res = s_mp_mul_2(&gx)) != MP_OKAY)
-      goto CLEANUP;
+    mp_size nx = mp_trailing_zeros(&xc);
+    mp_size ny = mp_trailing_zeros(&yc);
+    mp_size n  = MP_MIN(nx, ny);
+    s_mp_div_2d(&xc,n);
+    s_mp_div_2d(&yc,n);
+    MP_CHECKOK( s_mp_mul_2d(&gx,n) );
   }
 
   mp_copy(&xc, &u);
   mp_copy(&yc, &v);
   mp_set(&A, 1); mp_set(&D, 1);
 
   /* Loop through binary GCD algorithm */
-  for(;;) {
+  do {
     while(mp_iseven(&u)) {
       s_mp_div_2(&u);
 
       if(mp_iseven(&A) && mp_iseven(&B)) {
 	s_mp_div_2(&A); s_mp_div_2(&B);
       } else {
-	if((res = mp_add(&A, &yc, &A)) != MP_OKAY) goto CLEANUP;
+	MP_CHECKOK( mp_add(&A, &yc, &A) );
 	s_mp_div_2(&A);
-	if((res = mp_sub(&B, &xc, &B)) != MP_OKAY) goto CLEANUP;
+	MP_CHECKOK( mp_sub(&B, &xc, &B) );
 	s_mp_div_2(&B);
       }
     }
 
     while(mp_iseven(&v)) {
       s_mp_div_2(&v);
 
       if(mp_iseven(&C) && mp_iseven(&D)) {
 	s_mp_div_2(&C); s_mp_div_2(&D);
       } else {
-	if((res = mp_add(&C, &yc, &C)) != MP_OKAY) goto CLEANUP;
+	MP_CHECKOK( mp_add(&C, &yc, &C) );
 	s_mp_div_2(&C);
-	if((res = mp_sub(&D, &xc, &D)) != MP_OKAY) goto CLEANUP;
+	MP_CHECKOK( mp_sub(&D, &xc, &D) );
 	s_mp_div_2(&D);
       }
     }
 
     if(mp_cmp(&u, &v) >= 0) {
-      if((res = mp_sub(&u, &v, &u)) != MP_OKAY) goto CLEANUP;
-      if((res = mp_sub(&A, &C, &A)) != MP_OKAY) goto CLEANUP;
-      if((res = mp_sub(&B, &D, &B)) != MP_OKAY) goto CLEANUP;
-
+      MP_CHECKOK( mp_sub(&u, &v, &u) );
+      MP_CHECKOK( mp_sub(&A, &C, &A) );
+      MP_CHECKOK( mp_sub(&B, &D, &B) );
     } else {
-      if((res = mp_sub(&v, &u, &v)) != MP_OKAY) goto CLEANUP;
-      if((res = mp_sub(&C, &A, &C)) != MP_OKAY) goto CLEANUP;
-      if((res = mp_sub(&D, &B, &D)) != MP_OKAY) goto CLEANUP;
-
+      MP_CHECKOK( mp_sub(&v, &u, &v) );
+      MP_CHECKOK( mp_sub(&C, &A, &C) );
+      MP_CHECKOK( mp_sub(&D, &B, &D) );
     }
-
-    /* If we're done, copy results to output */
-    if(mp_cmp_z(&u) == 0) {
-      if(x)
-	if((res = mp_copy(&C, x)) != MP_OKAY) goto CLEANUP;
-
-      if(y)
-	if((res = mp_copy(&D, y)) != MP_OKAY) goto CLEANUP;
+  } while (mp_cmp_z(&u) != 0);
+
+  /* copy results to output */
+  if(x)
+    MP_CHECKOK( mp_copy(&C, x) );
+
+  if(y)
+    MP_CHECKOK( mp_copy(&D, y) );
       
-      if(g)
-	if((res = mp_mul(&gx, &v, g)) != MP_OKAY) goto CLEANUP;
-
-      break;
-    }
-  }
+  if(g)
+    MP_CHECKOK( mp_mul(&gx, &v, g) );
 
  CLEANUP:
   while(last >= 0)
     mp_clear(clean[last--]);
 
   return res;
 
 } /* end mp_xgcd() */
 
 /* }}} */
 
+mp_size mp_trailing_zeros(const mp_int *mp)
+{
+  mp_digit d;
+  mp_size  n = 0;
+  int      ix;
+
+  if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
+    return n;
+
+  for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix)
+    n += MP_DIGIT_BIT;
+  if (!d)
+    return 0;	/* shouldn't happen, but ... */
+#if (MP_DIGIT_MAX > MP_32BIT_MAX) 
+  if (!(d & 0xffffffffU)) {
+    d >>= 32;
+    n  += 32;
+  }
+#endif
+  if (!(d & 0xffffU)) {
+    d >>= 16;
+    n  += 16;
+  }
+  if (!(d & 0xffU)) {
+    d >>= 8;
+    n  += 8;
+  }
+  if (!(d & 0xfU)) {
+    d >>= 4;
+    n  += 4;
+  }
+  if (!(d & 0x3U)) {
+    d >>= 2;
+    n  += 2;
+  }
+  if (!(d & 0x1U)) {
+    d >>= 1;
+    n  += 1;
+  }
+#if MP_ARGCHK == 2
+  assert(0 != (d & 1));
+#endif
+  return n;
+}
+
 /* Given a and prime p, computes c and k such that a*c == 2**k (mod p).
 ** Returns k (positive) or error (negative).
 ** This technique from the paper "Fast Modular Reciprocals" (unpublished)
 ** by Richard Schroeppel (a.k.a. Captain Nemo).
 */
 mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
 {
   mp_err res;
@@ -2004,19 +2043,24 @@ mp_err s_mp_almost_inverse(const mp_int 
   mp_zero(&d);
 
   if (mp_cmp_z(&f) == 0) {
     res = MP_UNDEF;
   } else 
   for (;;) {
     int diff_sign;
     while (mp_iseven(&f)) {
-      s_mp_div_2d(&f, 1);
-      MP_CHECKOK( s_mp_mul_2d(&d, 1) );
-      ++k;
+      mp_size n = mp_trailing_zeros(&f);
+      if (!n) {
+	res = MP_UNDEF;
+	goto CLEANUP;
+      }
+      s_mp_div_2d(&f, n);
+      MP_CHECKOK( s_mp_mul_2d(&d, n) );
+      k += n;
     }
     if (mp_cmp_d(&f, 1) == MP_EQ) {	/* f == 1 */
       res = k;
       break;
     }
     diff_sign = mp_cmp(&f, &g);
     if (diff_sign < 0) {		/* f < g */
       s_mp_exch(&f, &g);
@@ -2042,17 +2086,17 @@ mp_err s_mp_almost_inverse(const mp_int 
 
 CLEANUP:
   mp_clear(&d);
   mp_clear(&f);
   mp_clear(&g);
   return res;
 }
 
-/* Compute T = (P ** -1) mod (2 ** 32).  Also works for 16-bit mp_digits.
+/* Compute T = (P ** -1) mod MP_RADIX.  Also works for 16-bit mp_digits.
 ** This technique from the paper "Fast Modular Reciprocals" (unpublished)
 ** by Richard Schroeppel (a.k.a. Captain Nemo).
 */
 mp_digit  s_mp_invmod_radix(mp_digit P)
 {
   mp_digit T = P;
   T *= 2 - (P * T);
   T *= 2 - (P * T);
@@ -2102,80 +2146,245 @@ mp_err  s_mp_fixup_reciprocal(const mp_i
   s_mp_clamp(x);
   s_mp_div_2d(x, k_orig);
   res = MP_OKAY;
 
 CLEANUP:
   return res;
 }
 
-/* {{{ mp_invmod(a, m, c) */
-
-/*
-  mp_invmod(a, m, c)
-
-  Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
-  This is equivalent to the question of whether (a, m) = 1.  If not,
-  MP_UNDEF is returned, and there is no inverse.
- */
-
-mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c)
+/* compute mod inverse using Schroeppel's method, only if m is odd */
+mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c)
+{
+  int k;
+  mp_err  res;
+  mp_int  x;
+
+  ARGCHK(a && m && c, MP_BADARG);
+
+  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
+    return MP_RANGE;
+  if (mp_iseven(m))
+    return MP_UNDEF;
+
+  MP_DIGITS(&x) = 0;
+
+  if (a == c) {
+    if ((res = mp_init_copy(&x, a)) != MP_OKAY)
+      return res;
+    if (a == m) 
+      m = &x;
+    a = &x;
+  } else if (m == c) {
+    if ((res = mp_init_copy(&x, m)) != MP_OKAY)
+      return res;
+    m = &x;
+  } else {
+    MP_DIGITS(&x) = 0;
+  }
+
+  MP_CHECKOK( s_mp_almost_inverse(a, m, c) );
+  k = res;
+  MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) );
+CLEANUP:
+  mp_clear(&x);
+  return res;
+}
+
+/* Known good algorithm for computing modular inverse.  But slow. */
+mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)
 {
   mp_int  g, x;
   mp_err  res;
 
   ARGCHK(a && m && c, MP_BADARG);
 
   if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
     return MP_RANGE;
 
   MP_DIGITS(&g) = 0;
   MP_DIGITS(&x) = 0;
-
-  if (mp_isodd(m)) {
-    int k;
-
-    if (a == c) {
-      if ((res = mp_init_copy(&x, a)) != MP_OKAY)
-	return res;
-      if (a == m) 
-	m = &x;
-      a = &x;
-    } else if (m == c) {
-      if ((res = mp_init_copy(&x, m)) != MP_OKAY)
-	return res;
-      m = &x;
-    } else {
-      MP_DIGITS(&x) = 0;
-    }
-
-    MP_CHECKOK( s_mp_almost_inverse(a, m, c) );
-    k = res;
-    MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) );
-    goto CLEANUP;
-  }
-
   MP_CHECKOK( mp_init(&x) );
   MP_CHECKOK( mp_init(&g) );
 
   MP_CHECKOK( mp_xgcd(a, m, &g, &x, NULL) );
 
-  if(mp_cmp_d(&g, 1) != MP_EQ) {
+  if (mp_cmp_d(&g, 1) != MP_EQ) {
     res = MP_UNDEF;
     goto CLEANUP;
   }
 
   res = mp_mod(&x, m, c);
   SIGN(c) = SIGN(a);
 
 CLEANUP:
   mp_clear(&x);
   mp_clear(&g);
 
   return res;
+}
+
+/* modular inverse where modulus is 2**k. */
+/* c = a**-1 mod 2**k */
+mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c)
+{
+  mp_err res;
+  mp_size ix = k + 4;
+  mp_int t0, t1, val, tmp, two2k;
+
+  static const mp_digit d2 = 2;
+  static const mp_int two = { MP_ZPOS, 1, 1, (mp_digit *)&d2 };
+
+  if (mp_iseven(a))
+    return MP_UNDEF;
+  if (k <= MP_DIGIT_BIT) {
+    mp_digit i = s_mp_invmod_radix(MP_DIGIT(a,0));
+    if (k < MP_DIGIT_BIT)
+      i &= ((mp_digit)1 << k) - (mp_digit)1;
+    mp_set(c, i);
+    return MP_OKAY;
+  }
+  MP_DIGITS(&t0) = 0;
+  MP_DIGITS(&t1) = 0;
+  MP_DIGITS(&val) = 0;
+  MP_DIGITS(&tmp) = 0;
+  MP_DIGITS(&two2k) = 0;
+  MP_CHECKOK( mp_init_copy(&val, a) );
+  s_mp_mod_2d(&val, k);
+  MP_CHECKOK( mp_init_copy(&t0, &val) );
+  MP_CHECKOK( mp_init_copy(&t1, &t0)  );
+  MP_CHECKOK( mp_init(&tmp) );
+  MP_CHECKOK( mp_init(&two2k) );
+  MP_CHECKOK( s_mp_2expt(&two2k, k) );
+  do {
+    MP_CHECKOK( mp_mul(&val, &t1, &tmp)  );
+    MP_CHECKOK( mp_sub(&two, &tmp, &tmp) );
+    MP_CHECKOK( mp_mul(&t1, &tmp, &t1)   );
+    s_mp_mod_2d(&t1, k);
+    while (MP_SIGN(&t1) != MP_ZPOS) {
+      MP_CHECKOK( mp_add(&t1, &two2k, &t1) );
+    }
+    if (mp_cmp(&t1, &t0) == MP_EQ) 
+      break;
+    MP_CHECKOK( mp_copy(&t1, &t0) );
+  } while (--ix > 0);
+  if (!ix) {
+    res = MP_UNDEF;
+  } else {
+    mp_exch(c, &t1);
+  }
+
+CLEANUP:
+  mp_clear(&t0);
+  mp_clear(&t1);
+  mp_clear(&val);
+  mp_clear(&tmp);
+  mp_clear(&two2k);
+  return res;
+}
+
+mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c)
+{
+  mp_err res;
+  mp_size k;
+  mp_int oddFactor, evenFactor;	/* factors of the modulus */
+  mp_int oddPart, evenPart;	/* parts to combine via CRT. */
+  mp_int C2, tmp1, tmp2;
+
+  static const mp_digit d1 = 1;
+  static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 };
+
+  if ((res = s_mp_ispow2(m)) >= 0) {
+    k = res;
+    return s_mp_invmod_2d(a, k, c);
+  }
+  MP_DIGITS(&oddFactor) = 0;
+  MP_DIGITS(&evenFactor) = 0;
+  MP_DIGITS(&oddPart) = 0;
+  MP_DIGITS(&evenPart) = 0;
+  MP_DIGITS(&C2)     = 0;
+  MP_DIGITS(&tmp1)   = 0;
+  MP_DIGITS(&tmp2)   = 0;
+
+  MP_CHECKOK( mp_init_copy(&oddFactor, m) );    /* oddFactor = m */
+  MP_CHECKOK( mp_init(&evenFactor) );
+  MP_CHECKOK( mp_init(&oddPart) );
+  MP_CHECKOK( mp_init(&evenPart) );
+  MP_CHECKOK( mp_init(&C2)     );
+  MP_CHECKOK( mp_init(&tmp1)   );
+  MP_CHECKOK( mp_init(&tmp2)   );
+
+  k = mp_trailing_zeros(m);
+  s_mp_div_2d(&oddFactor, k);
+  MP_CHECKOK( s_mp_2expt(&evenFactor, k) );
+
+  /* compute a**-1 mod oddFactor. */
+  MP_CHECKOK( s_mp_invmod_odd_m(a, &oddFactor, &oddPart) );
+  /* compute a**-1 mod evenFactor, where evenFactor == 2**k. */
+  MP_CHECKOK( s_mp_invmod_2d(   a,       k,    &evenPart) );
+
+  /* Use Chinese Remainer theorem to compute a**-1 mod m. */
+  /* let m1 = oddFactor,  v1 = oddPart, 
+   * let m2 = evenFactor, v2 = evenPart.
+   */
+
+  /* Compute C2 = m1**-1 mod m2. */
+  MP_CHECKOK( s_mp_invmod_2d(&oddFactor, k,    &C2) );
+
+  /* compute u = (v2 - v1)*C2 mod m2 */
+  MP_CHECKOK( mp_sub(&evenPart, &oddPart,   &tmp1) );
+  MP_CHECKOK( mp_mul(&tmp1,     &C2,        &tmp2) );
+  s_mp_mod_2d(&tmp2, k);
+  while (MP_SIGN(&tmp2) != MP_ZPOS) {
+    MP_CHECKOK( mp_add(&tmp2, &evenFactor, &tmp2) );
+  }
+
+  /* compute answer = v1 + u*m1 */
+  MP_CHECKOK( mp_mul(&tmp2,     &oddFactor, c) );
+  MP_CHECKOK( mp_add(&oddPart,  c,          c) );
+  /* not sure this is necessary, but it's low cost if not. */
+  MP_CHECKOK( mp_mod(c,         m,          c) );
+
+CLEANUP:
+  mp_clear(&oddFactor);
+  mp_clear(&evenFactor);
+  mp_clear(&oddPart);
+  mp_clear(&evenPart);
+  mp_clear(&C2);
+  mp_clear(&tmp1);
+  mp_clear(&tmp2);
+  return res;
+}
+
+
+/* {{{ mp_invmod(a, m, c) */
+
+/*
+  mp_invmod(a, m, c)
+
+  Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
+  This is equivalent to the question of whether (a, m) = 1.  If not,
+  MP_UNDEF is returned, and there is no inverse.
+ */
+
+mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
+{
+
+  ARGCHK(a && m && c, MP_BADARG);
+
+  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
+    return MP_RANGE;
+
+  if (mp_isodd(m)) {
+    return s_mp_invmod_odd_m(a, m, c);
+  }
+  if (mp_iseven(a))
+    return MP_UNDEF;	/* not invertable */
+
+  return s_mp_invmod_even_m(a, m, c);
 
 } /* end mp_invmod() */
 
 /* }}} */
 #endif /* if MP_NUMTH */
 
 /* }}} */
 
@@ -2299,17 +2508,17 @@ mp_err mp_toraw(mp_int *mp, char *str)
   mp_read_radix(mp, str, radix)
 
   Read an integer from the given string, and set mp to the resulting
   value.  The input is presumed to be in base 10.  Leading non-digit
   characters are ignored, and the function reads until a non-digit
   character or the end of the string.
  */
 
-mp_err  mp_read_radix(mp_int *mp, char *str, int radix)
+mp_err  mp_read_radix(mp_int *mp, const char *str, int radix)
 {
   int     ix = 0, val = 0;
   mp_err  res;
   mp_sign sig = ZPOS;
 
   ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX, 
 	 MP_BADARG);
 
@@ -4162,17 +4371,17 @@ int      s_mp_cmp_d(const mp_int *a, mp_
 /* }}} */
 
 /* {{{ s_mp_ispow2(v) */
 
 /*
   Returns -1 if the value is not a power of two; otherwise, it returns
   k such that v = 2^k, i.e. lg(v).
  */
-int      s_mp_ispow2(mp_int *v)
+int      s_mp_ispow2(const mp_int *v)
 {
   mp_digit d;
   int      extra = 0, ix;
 
   ix = MP_USED(v) - 1;
   d = MP_DIGIT(v, ix); /* most significant digit of v */
 
   extra = s_mp_ispow2d(d);
--- a/security/nss/lib/freebl/mpi/mpi.h
+++ b/security/nss/lib/freebl/mpi/mpi.h
@@ -50,17 +50,21 @@
 #endif
 
 #if MP_IOFUNC
 #include <stdio.h>
 #include <ctype.h>
 #endif
 
 #include <limits.h>
+#ifdef macintosh
+#include <Types.h>
+#else
 #include <sys/types.h>
+#endif
 
 #define  MP_NEG    1
 #define  MP_ZPOS   0
 
 #define  MP_OKAY          0 /* no error, all is well */
 #define  MP_YES           0 /* yes (boolean result)  */
 #define  MP_NO           -1 /* no (boolean result)   */
 #define  MP_MEM          -2 /* out of memory         */
@@ -241,30 +245,31 @@ int    mp_cmp_mag(mp_int *a, mp_int *b);
 int    mp_cmp_int(const mp_int *a, long z);
 int    mp_isodd(const mp_int *a);
 int    mp_iseven(const mp_int *a);
 
 /* Number theoretic        */
 #if MP_NUMTH
 mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
 mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c);
-mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y);
-mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c);
+mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y);
+mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c);
+mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c);
 #endif /* end MP_NUMTH */
 
 /* Input and output        */
 #if MP_IOFUNC
 void   mp_print(mp_int *mp, FILE *ofp);
 #endif /* end MP_IOFUNC */
 
 /* Base conversion         */
 mp_err mp_read_raw(mp_int *mp, char *str, int len);
 int    mp_raw_size(mp_int *mp);
 mp_err mp_toraw(mp_int *mp, char *str);
-mp_err mp_read_radix(mp_int *mp, char *str, int radix);
+mp_err mp_read_radix(mp_int *mp, const char *str, int radix);
 int    mp_radix_size(mp_int *mp, int radix);
 mp_err mp_toradix(mp_int *mp, char *str, int radix);
 int    mp_tovalue(char ch, int r);
 
 #define mp_tobinary(M, S)  mp_toradix((M), (S), 2)
 #define mp_tooctal(M, S)   mp_toradix((M), (S), 8)
 #define mp_todecimal(M, S) mp_toradix((M), (S), 10)
 #define mp_tohex(M, S)     mp_toradix((M), (S), 16)
@@ -274,16 +279,19 @@ const  char  *mp_strerror(mp_err ec);
 
 /* Octet string conversion functions */
 mp_err mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len);
 int    mp_unsigned_octet_size(const mp_int *mp);
 mp_err mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen);
 mp_err mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen);
 mp_err mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size len);
 
+/* Miscellaneous */
+mp_size mp_trailing_zeros(const mp_int *mp);
+
 #define MP_CHECKOK(x)  if (MP_OKAY > (res = (x))) goto CLEANUP
 #define MP_CHECKERR(x) if (MP_OKAY > (res = (x))) goto CLEANUP
 
 #if defined(MP_API_COMPATIBLE)
 #define NEG             MP_NEG
 #define ZPOS            MP_ZPOS
 #define DIGIT_MAX       MP_DIGIT_MAX
 #define DIGIT_BIT       MP_DIGIT_BIT
--- a/security/nss/lib/freebl/mpi/mpi_sparc.c
+++ b/security/nss/lib/freebl/mpi/mpi_sparc.c
@@ -175,30 +175,31 @@ v8_mpv_mul_d_add_prop(const mp_digit *a,
 }
 
 /* vis versions of these functions run only on v8+vis or v9+vis CPUs. */
 
 /* c = a * b */
 static void 
 vis_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
 {
+    mp_digit d;
     mp_digit x[258];
     if (a_len <= 256) {
-	if (a == c) {
+	if (a == c || ((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) {
 	    mp_digit * px;
 	    px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x;
 	    memcpy(px, a, a_len * sizeof(*a));
 	    a = px;
 	    if (a_len & 1) {
 		px[a_len] = 0;
-		a_len++;
 	    }
 	}
 	s_mp_setz(c, a_len + 1);
-	s_mpv_mul_d_add(a, a_len, b, c);
+	d = mul_add_inp(c, a, a_len, b);
+	c[a_len] = d;
     } else {
 	v8_mpv_mul_d(a, a_len, b, c);
     }
 }
 
 /* c += a * b, where a is a_len words long. */
 static void     
 vis_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
@@ -208,17 +209,16 @@ vis_mpv_mul_d_add(const mp_digit *a, mp_
     if (a_len <= 256) {
 	if (((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) {
 	    mp_digit * px;
 	    px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x;
 	    memcpy(px, a, a_len * sizeof(*a));
 	    a = px;
 	    if (a_len & 1) {
 		px[a_len] = 0;
-		a_len++;
 	    }
 	}
 	d = mul_add_inp(c, a, a_len, b);
 	c[a_len] = d;
     } else {
 	v8_mpv_mul_d_add(a, a_len, b, c);
     }
 }
@@ -233,17 +233,16 @@ vis_mpv_mul_d_add_prop(const mp_digit *a
     if (a_len <= 256) {
 	if (((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) {
 	    mp_digit * px;
 	    px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x;
 	    memcpy(px, a, a_len * sizeof(*a));
 	    a = px;
 	    if (a_len & 1) {
 		px[a_len] = 0;
-		a_len++;
 	    }
 	}
 	d = mul_add_inp(c, a, a_len, b);
 	if (d) {
 	    c += a_len;
 	    do {
 		mp_digit sum = d + *c;
 		*c++ = sum;
--- a/security/nss/lib/freebl/mpi/mpi_x86.s
+++ b/security/nss/lib/freebl/mpi/mpi_x86.s
@@ -59,16 +59,17 @@
 .globl	s_mpv_mul_d
 .type	s_mpv_mul_d,@function
 s_mpv_mul_d:
     push   %ebp
     mov    %esp,%ebp
     sub    $28,%esp
     push   %edi
     push   %esi
+    push   %ebx
     movl   $0,%ebx		# carry = 0
     mov    12(%ebp),%ecx	# ecx = a_len
     mov    20(%ebp),%edi
     cmp    $0,%ecx
     je     2f			# jmp if a_len == 0
     mov    8(%ebp),%esi		# esi = a
     cld
 1:
@@ -80,16 +81,17 @@ 1:
     adc    $0,%edx
     mov    %edx,%ebx		# high half of product becomes next carry
 
     stosl			# [es:edi] = ax; edi += 4;
     dec    %ecx			# --a_len
     jnz    1b			# jmp if a_len != 0
 2:
     mov    %ebx,0(%edi)		# *c = carry
+    pop    %ebx
     pop    %esi
     pop    %edi
     leave  
     ret    
     nop
 
  #  ebp - 36:	caller's esi
  #  ebp - 32:	caller's edi
@@ -116,16 +118,17 @@ 2:
 .globl	s_mpv_mul_d_add
 .type	s_mpv_mul_d_add,@function
 s_mpv_mul_d_add:
     push   %ebp
     mov    %esp,%ebp
     sub    $28,%esp
     push   %edi
     push   %esi
+    push   %ebx
     movl   $0,%ebx		# carry = 0
     mov    12(%ebp),%ecx	# ecx = a_len
     mov    20(%ebp),%edi
     cmp    $0,%ecx
     je     4f			# jmp if a_len == 0
     mov    8(%ebp),%esi		# esi = a
     cld
 3:
@@ -140,16 +143,17 @@ 3:
     adc    $0,%edx
     mov    %edx,%ebx		# high half of product becomes next carry
 
     stosl			# [es:edi] = ax; edi += 4;
     dec    %ecx			# --a_len
     jnz    3b			# jmp if a_len != 0
 4:
     mov    %ebx,0(%edi)		# *c = carry
+    pop    %ebx
     pop    %esi
     pop    %edi
     leave  
     ret    
     nop
 
  #  ebp - 36:	caller's esi
  #  ebp - 32:	caller's edi
@@ -176,16 +180,17 @@ 4:
 .globl	s_mpv_mul_d_add_prop
 .type	s_mpv_mul_d_add_prop,@function
 s_mpv_mul_d_add_prop:
     push   %ebp
     mov    %esp,%ebp
     sub    $28,%esp
     push   %edi
     push   %esi
+    push   %ebx
     movl   $0,%ebx		# carry = 0
     mov    12(%ebp),%ecx	# ecx = a_len
     mov    20(%ebp),%edi
     cmp    $0,%ecx
     je     6f			# jmp if a_len == 0
     cld
     mov    8(%ebp),%esi		# esi = a
 5:
@@ -211,16 +216,17 @@ 6:
     stosl			# [es:edi] = ax; edi += 4;
     jnc    8f
 7:
     mov    0(%edi),%eax		# add in current word from *c
     adc	   $0,%eax
     stosl			# [es:edi] = ax; edi += 4;
     jc     7b
 8:
+    pop    %ebx
     pop    %esi
     pop    %edi
     leave  
     ret    
     nop
 
  #  ebp - 20:	caller's esi
  #  ebp - 16:	caller's edi
@@ -244,16 +250,17 @@ 8:
 .globl	s_mpv_sqr_add_prop
 .type	s_mpv_sqr_add_prop,@function
 s_mpv_sqr_add_prop:
      push   %ebp
      mov    %esp,%ebp
      sub    $12,%esp
      push   %edi
      push   %esi
+     push   %ebx
      movl   $0,%ebx		# carry = 0
      mov    12(%ebp),%ecx	# a_len
      mov    16(%ebp),%edi	# edi = ps
      cmp    $0,%ecx
      je     11f			# jump if a_len == 0
      cld
      mov    8(%ebp),%esi	# esi = pa
 10:
@@ -281,52 +288,55 @@ 11:
     stosl			# [es:edi] = ax; edi += 4;
     jnc    14f
 12:
     mov    0(%edi),%eax		# add in current word from *c
     adc	   $0,%eax
     stosl			# [es:edi] = ax; edi += 4;
     jc     12b
 14:
+    pop    %ebx
     pop    %esi
     pop    %edi
     leave  
     ret    
     nop
 
  #
  # Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
  # so its high bit is 1.   This code is from NSPR.
  #
  # mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
  # 		          mp_digit *qp, mp_digit *rp)
 
- # Dump of assembler code for function s_mpv_div_2dx1d:
- # 
- #  esp +  0:	return address
- #  esp +  4:	Nhi	argument
- #  esp +  8:	Nlo	argument
- #  esp + 12:	divisor	argument
- #  esp + 16:	qp	argument
- #  esp + 20:   rp	argument
+ #  esp +  0:   Caller's ebx
+ #  esp +  4:	return address
+ #  esp +  8:	Nhi	argument
+ #  esp + 12:	Nlo	argument
+ #  esp + 16:	divisor	argument
+ #  esp + 20:	qp	argument
+ #  esp + 24:   rp	argument
  #  registers:
  # 	eax:
  #	ebx:	carry
  #	ecx:	a_len
  #	edx:
  #	esi:	a ptr
  #	edi:	c ptr
  # 
+
 .globl	s_mpv_div_2dx1d
 .type	s_mpv_div_2dx1d,@function
 s_mpv_div_2dx1d:
-       mov    4(%esp),%edx
-       mov    8(%esp),%eax
-       mov    12(%esp),%ebx
+       push   %ebx
+       mov    8(%esp),%edx
+       mov    12(%esp),%eax
+       mov    16(%esp),%ebx
        div    %ebx
-       mov    16(%esp),%ebx
+       mov    20(%esp),%ebx
        mov    %eax,0(%ebx)
-       mov    20(%esp),%ebx
+       mov    24(%esp),%ebx
        mov    %edx,0(%ebx)
        xor    %eax,%eax		# return zero
+       pop    %ebx
        ret    
        nop
   
--- a/security/nss/lib/freebl/mpi/mpprime.c
+++ b/security/nss/lib/freebl/mpi/mpprime.c
@@ -290,70 +290,63 @@ mp_err mpp_fermat_list(mp_int *a, const 
   If MP_NO is returned, the number is definitely composite.  If MP_YES
   is returned, it is probably prime (but that is not guaranteed).
  */
 
 mp_err  mpp_pprime(mp_int *a, int nt)
 {
   mp_err   res;
   mp_int   x, amo, m, z;	/* "amo" = "a minus one" */
-  int      iter, jx, b;
+  int      iter, jx;
+  mp_size  b;
 
   ARGCHK(a != NULL, MP_BADARG);
 
-  /* Initialize temporaries... */
-  if((res = mp_init(&amo)) != MP_OKAY)
-    return res;
-  /* Compute amo = a - 1 for what follows...    */
-  if ((res = mp_sub_d(a, 1, &amo)) != MP_OKAY)
-    goto X;
+  MP_DIGITS(&x) = 0;
+  MP_DIGITS(&amo) = 0;
+  MP_DIGITS(&m) = 0;
+  MP_DIGITS(&z) = 0;
 
-  /* How many times does 2 divide (a - 1)?    */
-  for (b = 0; (res = mpl_get_bit(&amo, b)) == 0; ++b) {
-    /* do nothing */
-  }
-  if (res < 0)
-    goto X;
+  /* Initialize temporaries... */
+  MP_CHECKOK( mp_init(&amo));
+  /* Compute amo = a - 1 for what follows...    */
+  MP_CHECKOK( mp_sub_d(a, 1, &amo) );
+
+  b = mp_trailing_zeros(&amo);
   if (!b) { /* a was even ? */
     res = MP_NO;
-    goto X;
+    goto CLEANUP;
   }
 
-  if((res = mp_init_size(&x, USED(a))) != MP_OKAY)
-    goto X;
-  if((res = mp_init(&z)) != MP_OKAY)
-    goto Z;
-  if ((res = mp_init(&m)) != MP_OKAY)
-    goto M;
-  if ((res = mp_div_2d(&amo, b, &m, 0)) != MP_OKAY)
-    goto CLEANUP;
+  MP_CHECKOK( mp_init_size(&x, MP_USED(a)) );
+  MP_CHECKOK( mp_init(&z) );
+  MP_CHECKOK( mp_init(&m) );
+  MP_CHECKOK( mp_div_2d(&amo, b, &m, 0) );
 
   /* Do the test nt times... */
   for(iter = 0; iter < nt; iter++) {
 
     /* Choose a random value for x < a          */
     s_mp_pad(&x, USED(a));
     mpp_random(&x);
-    if((res = mp_mod(&x, a, &x)) != MP_OKAY)
-      goto CLEANUP;
+    MP_CHECKOK( mp_mod(&x, a, &x) );
 
     /* Compute z = (x ** m) mod a               */
-    if((res = mp_exptmod(&x, &m, a, &z)) != MP_OKAY)
-      goto CLEANUP;
+    MP_CHECKOK( mp_exptmod(&x, &m, a, &z) );
     
     if(mp_cmp_d(&z, 1) == 0 || mp_cmp(&z, &amo) == 0) {
       res = MP_YES;
       continue;
     }
     
+    res = MP_NO;  /* just in case the following for loop never executes. */
     for (jx = 1; jx < b; jx++) {
       /* z = z^2 (mod a) */
-      if((res = mp_sqrmod(&z, a, &z)) != MP_OKAY)
-	goto CLEANUP;
-	
+      MP_CHECKOK( mp_sqrmod(&z, a, &z) );
+
       if(mp_cmp_d(&z, 1) == 0) {
 	res = MP_NO;
 	break;
       }
       if(mp_cmp(&z, &amo) == 0) {
 	res = MP_YES;
 	break;
       } 
@@ -366,21 +359,18 @@ mp_err  mpp_pprime(mp_int *a, int nt)
      */
     if(res == MP_NO)
       break;
 
   } /* end iterations loop */
   
 CLEANUP:
   mp_clear(&m);
-M:
   mp_clear(&z);
-Z:
   mp_clear(&x);
-X:
   mp_clear(&amo);
   return res;
 
 } /* end mpp_pprime() */
 
 /* }}} */
 
 /* Produce table of composites from list of primes and trial value.  
@@ -417,26 +407,40 @@ mp_err mpp_sieve(mp_int *trial, const mp
     for (i = offset; i < nSieve ; i += prime) {
       sieve[i] = 1;
     }
   }
 
   return MP_OKAY;
 }
 
+#define SIEVE_SIZE 32*1024
+
 mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
 		      unsigned long * nTries)
 {
   mp_digit      np;
   mp_err        res;
   int           i	= 0;
   mp_int        trial;
   mp_int        q;
   mp_size       num_tests;
-  unsigned char sieve[32*1024];
+  /*
+   * Always make sieve the last variabale allocated so that 
+   * Mac builds don't break by adding an extra variable
+   * on the stack. -javi
+   */
+#ifdef macintosh
+  unsigned char *sieve;
+  
+  sieve = malloc(SIEVE_SIZE);
+  ARGCHK(sieve != NULL, MP_MEM);
+#else
+  unsigned char sieve[SIEVE_SIZE];
+#endif  
 
   ARGCHK(start != 0, MP_BADARG);
   ARGCHK(nBits > 16, MP_RANGE);
 
   MP_DIGITS(&trial) = 0;
   MP_DIGITS(&q) = 0;
   MP_CHECKOK( mp_init(&trial) );
   MP_CHECKOK( mp_init(&q)     );
@@ -543,16 +547,22 @@ mp_err mpp_make_prime(mp_int *start, mp_
 
   } /* end of loop through sieved values */
   if (res == MP_YES) 
     mp_exch(&trial, start);
 CLEANUP:
   mp_clear(&trial);
   if (nTries)
     *nTries += i;
+#ifdef macintosh
+  if (sieve != NULL) {
+  	memset(sieve, 0, SIEVE_SIZE);
+  	free (sieve);
+  }
+#endif    
   return res;
 }
 
 /*========================================================================*/
 /*------------------------------------------------------------------------*/
 /* Static functions visible only to the library internally                */
 
 /* {{{ s_mpp_divp(a, vec, size, which) */
--- a/security/nss/lib/jar/jarevil.c
+++ b/security/nss/lib/jar/jarevil.c
@@ -52,17 +52,17 @@
 typedef void (*ETVoidPtrFunc) (void * data);
 extern void ET_moz_CallFunction (ETVoidPtrFunc fn, void *data);
 
 extern void *mozilla_event_queue;
 #endif
 
 
 /* Special macros facilitate running on Win 16 */
-#if defined(XP_PC) && !defined(_WIN32)   /* then we are win 16 */ 
+#if defined(XP_WIN16)
 
   /* 
    * Allocate the data passed to the callback functions from the heap...
    *
    * This inter-thread structure cannot reside on a thread stack since the 
    * thread's stack is swapped away with the thread under Win16...
    */
 
--- a/security/nss/lib/nss/nssinit.c
+++ b/security/nss/lib/nss/nssinit.c
@@ -156,21 +156,21 @@ SECStatus
 nss_Init(const char *configdir, PRBool readOnly)
 {
     SECStatus status;
     SECStatus rv      = SECFailure;
 
     RNG_RNGInit();     		/* initialize random number generator */
     RNG_SystemInfoForRNG();
 
-    status = nss_OpenCertDB(configdir, PR_TRUE);
+    status = nss_OpenCertDB(configdir, readOnly);
     if (status != SECSuccess)
 	goto loser;
 
-    status = nss_OpenKeyDB(configdir, PR_TRUE);
+    status = nss_OpenKeyDB(configdir, readOnly);
     if (status != SECSuccess)
 	goto loser;
 
     status = nss_OpenSecModDB(configdir);
     if (status != SECSuccess)
 	goto loser;
 
     rv = SECSuccess;
--- a/security/nss/lib/pk11wrap/pk11sdr.c
+++ b/security/nss/lib/pk11wrap/pk11sdr.c
@@ -189,17 +189,17 @@ PK11SDR_Encrypt(SECItem *keyid, SECItem 
   if (!ctx) { rv = SECFailure; goto loser; }
 
   rv = padBlock(data, PK11_GetBlockSize(type, 0), &paddedData);
   if (rv != SECSuccess) goto loser;
 
   sdrResult.data.len = paddedData.len;
   sdrResult.data.data = (unsigned char *)PORT_ArenaAlloc(arena, sdrResult.data.len);
 
-  rv = PK11_CipherOp(ctx, sdrResult.data.data, &sdrResult.data.len, sdrResult.data.len,
+  rv = PK11_CipherOp(ctx, sdrResult.data.data, (int*)&sdrResult.data.len, sdrResult.data.len,
                      paddedData.data, paddedData.len);
   if (rv != SECSuccess) goto loser;
 
   PK11_Finalize(ctx);
 
   sdrResult.keyid = *pKeyID;
 
   rv = PK11_ParamToAlgid(SEC_OID_DES_EDE3_CBC, params, arena, &sdrResult.alg);
@@ -261,17 +261,17 @@ PK11SDR_Decrypt(SECItem *data, SECItem *
   if (!params) { rv = SECFailure; goto loser; }
 
   ctx = PK11_CreateContextBySymKey(type, CKA_DECRYPT, key, params);
   if (!ctx) { rv = SECFailure; goto loser; }
 
   paddedResult.len = sdrResult.data.len;
   paddedResult.data = PORT_ArenaAlloc(arena, paddedResult.len);
 
-  rv = PK11_CipherOp(ctx, paddedResult.data, &paddedResult.len, paddedResult.len,
+  rv = PK11_CipherOp(ctx, paddedResult.data, (int*)&paddedResult.len, paddedResult.len,
                      sdrResult.data.data, sdrResult.data.len);
   if (rv != SECSuccess) goto loser;
 
   PK11_Finalize(ctx);
 
   /* Remove the padding */
   rv = unpadBlock(&paddedResult, PK11_GetBlockSize(type, 0), result);
   if (rv) goto loser;
--- a/security/nss/lib/pki1/oid.c
+++ b/security/nss/lib/pki1/oid.c
@@ -277,17 +277,17 @@ static PRLock *oid_hash_lock;
 
 /*
  * This is the hash function.  We simply XOR the encoded form with
  * itself in sizeof(PLHashNumber)-byte chunks.  Improving this
  * routine is left as an excercise for the more mathematically
  * inclined student.
  */
 
-static PR_CALLBACK PLHashNumber
+static PLHashNumber PR_CALLBACK
 oid_hash
 (
   const void *key
 )
 {
   const NSSItem *item = (const NSSItem *)key;
   PLHashNumber rv = 0;
 
@@ -305,17 +305,17 @@ oid_hash
 
 /*
  * This is the key-compare function.  It simply does a lexical
  * comparison on the encoded OID form.  This does not result in
  * quite the same ordering as the "sequence of numbers" order,
  * but heck it's only used internally by the hash table anyway.
  */
 
-static PR_CALLBACK PRIntn
+static PRIntn PR_CALLBACK
 oid_hash_compare
 (
   const void *k1,
   const void *k2
 )
 {
   PRIntn rv;
 
@@ -402,17 +402,17 @@ oid_remove_pointer
 static NSSArena *oid_arena;
 
 /*
  * This is the call-once function which initializes the hashtable.
  * It creates it, then prepopulates it with all of the builtin OIDs.
  * It also creates the aforementioned NSSArena.
  */
 
-static PR_CALLBACK PRStatus
+static PRStatus PR_CALLBACK
 oid_once_func
 (
   void
 )
 {
   PRUint32 i;
   
   /* Initialize the arena */
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -6964,16 +6964,17 @@ const ssl3BulkCipherDef *cipher_def;
 
     ssl_GetSpecReadLock(ss); /******************************************/
 
     crSpec = ssl3->crSpec;
     cipher_def = crSpec->cipher_def;
     isTLS = (PRBool)(crSpec->version > SSL_LIBRARY_VERSION_3_0);
 
     if (isTLS && cText->buf->len > (MAX_FRAGMENT_LENGTH + 2048)) {
+	ssl_ReleaseSpecReadLock(ss);
 	SSL3_SendAlert(ss, alert_fatal, record_overflow);
 	PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
 	return SECFailure;
     }
     /* decrypt from cText buf to databuf. */
     rv = crSpec->decode(
 	crSpec->decodeContext, databuf->buf, (int *)&databuf->len,
 	databuf->space, cText->buf->buf, cText->buf->len);
--- a/security/nss/lib/ssl/ssl3gthr.c
+++ b/security/nss/lib/ssl/ssl3gthr.c
@@ -71,16 +71,17 @@ ssl3_GatherData(sslSocket *ss, sslGather
 
     PORT_Assert( ssl_HaveRecvBufLock(ss) );
     if (gs->state == GS_INIT) {
 	gs->state       = GS_HEADER;
 	gs->remainder   = 5;
 	gs->offset      = 0;
 	gs->writeOffset = 0;
 	gs->readOffset  = 0;
+	gs->inbuf.len   = 0;
     }
     
     lbp = gs->inbuf.buf;
     for(;;) {
 	SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)",
 		SSL_GETPID(), ss->fd, gs->state, gs->remainder));
 	bp = ((gs->state != GS_HEADER) ? lbp : gs->hdr) + gs->offset;
 	nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
@@ -103,18 +104,19 @@ ssl3_GatherData(sslSocket *ss, sslGather
 	if (nb > gs->remainder) {
 	    /* ssl_DefRecv is misbehaving!  this error is fatal to SSL. */
 	    gs->state = GS_INIT;         /* so we don't crash next time */
 	    rv = SECFailure;
 	    break;
 	}
 
 	gs->offset    += nb;
-	gs->inbuf.len += nb;
 	gs->remainder -= nb;
+	if (gs->state == GS_DATA)
+	    gs->inbuf.len += nb;
 
 	/* if there's more to go, read some more. */
 	if (gs->remainder > 0) {
 	    continue;
 	}
 
 	/* have received entire record header, or entire record. */
 	switch (gs->state) {
--- a/security/nss/lib/ssl/sslgathr.c
+++ b/security/nss/lib/ssl/sslgathr.c
@@ -431,21 +431,19 @@ ssl_NewGather(void)
     }
     return gs;
 }
 
 /* Caller must hold RecvBufLock. */
 void 
 ssl_DestroyGather(sslGather *gs)
 {
-    if (gs->inbuf.buf != NULL) {
-	PORT_ZFree(gs->inbuf.buf, gs->inbuf.len);
-    }
-    if (gs) {
-	PORT_Free(gs->buf.buf);
+    if (gs) {	/* the PORT_*Free functions check for NULL pointers. */
+	PORT_ZFree(gs->buf.buf, gs->buf.space);
+	PORT_Free(gs->inbuf.buf);
 	PORT_Free(gs);
     }
 }
 
 /* Caller must hold RecvBufLock. */
 static SECStatus
 ssl2_HandleV3HandshakeRecord(sslSocket *ss)
 {
--- a/security/nss/lib/util/os2_rand.c
+++ b/security/nss/lib/util/os2_rand.c
@@ -33,17 +33,17 @@
 
 #define INCL_DOS
 #define INCL_DOSERRORS
 #include <os2.h>
 #include <secrng.h>
 #include <stdlib.h>
 #include <time.h>
 #include <stdio.h>
-#include <stat.h>
+#include <sys/stat.h>
 
 static BOOL clockTickTime(unsigned long *phigh, unsigned long *plow)
 {
     APIRET rc = NO_ERROR;
     QWORD qword = {0,0};
 
     rc = DosTmrQueryTime(&qword);
     if (rc != NO_ERROR)
@@ -101,33 +101,122 @@ size_t RNG_GetNoise(void *buf, size_t ma
     time(&sTime);
     nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime);
     memcpy(((char *)buf) + n, &sTime, nBytes);
     n += nBytes;
 
     return n;
 }
 
+static BOOL
+EnumSystemFiles(void (*func)(char *))
+{
+    APIRET              rc;
+    ULONG               sysInfo = 0;
+    char                bootLetter[2];
+    char                sysDir[_MAX_PATH] = "";
+    char                filename[_MAX_PATH];
+    HDIR                hdir = HDIR_CREATE;
+    ULONG               numFiles = 1;
+    FILEFINDBUF3        fileBuf = {0};
+    ULONG               buflen = sizeof(FILEFINDBUF3);
+
+    if (DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PVOID)&sysInfo,
+                        sizeof(ULONG)) == NO_ERROR)
+    {
+      bootLetter[0] = sysInfo + 'A' -1;
+      strcpy(sysDir, bootLetter);
+      strcpy(sysDir+1, ":\\OS2\\");
+
+      strcpy( filename, sysDir );
+      strcat( filename, "*.*" );
+    }
+
+    rc =DosFindFirst( filename, &hdir, FILE_NORMAL, &fileBuf, buflen,
+                      &numFiles, FIL_STANDARD );
+    if( rc == NO_ERROR )
+    {
+      do {
+        // pass the full pathname to the callback
+        sprintf( filename, "%s\\%s", sysDir, fileBuf.achName );
+        (*func)(filename);
+
+        numFiles = 1;
+        rc = DosFindNext( hdir, &fileBuf, buflen, &numFiles );
+        if( rc != NO_ERROR && rc != ERROR_NO_MORE_FILES )
+          printf( "DosFindNext errod code = %d\n", rc );
+      } while ( rc == NO_ERROR );
+
+      rc = DosFindClose(hdir);
+      if( rc != NO_ERROR )
+        printf( "DosFindClose error code = %d", rc );
+    }
+    else
+      printf( "DosFindFirst error code = %d", rc );
+
+    return TRUE;
+}
+
+static int    dwNumFiles, dwReadEvery;
+
+static void
+CountFiles(char *file)
+{
+    dwNumFiles++;
+}
+
+static void
+ReadFiles(char *file)
+{
+    if ((dwNumFiles % dwReadEvery) == 0)
+        RNG_FileForRNG(file);
+
+    dwNumFiles++;
+}
+
+static void
+ReadSystemFiles()
+{
+    // first count the number of files
+    dwNumFiles = 0;
+    if (!EnumSystemFiles(CountFiles))
+        return;
+
+    RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles));
+
+    // now read 10 files
+    if (dwNumFiles == 0)
+        return;
+
+    dwReadEvery = dwNumFiles / 10;
+    if (dwReadEvery == 0)
+        dwReadEvery = 1;  // less than 10 files
+
+    dwNumFiles = 0;
+    EnumSystemFiles(ReadFiles);
+}
+
 void RNG_SystemInfoForRNG(void)
 {
    unsigned long *plong = 0;
    PTIB ptib;
    PPIB ppib;
    APIRET rc = NO_ERROR;
    DATETIME dt;
-   COUNTRYCODE cc;
-   COUNTRYINFO ci;
-   unsigned long actual;
+   COUNTRYCODE cc = {0};
+   COUNTRYINFO ci = {0};
+   unsigned long actual = 0;
    char path[_MAX_PATH]="";
+   char fullpath[_MAX_PATH]="";
    unsigned long pathlength = sizeof(path);
    FSALLOCATE fsallocate;
    FILESTATUS3 fstatus;
    unsigned long defaultdrive = 0;
    unsigned long logicaldrives = 0;
-   unsigned long counter = 0;
+   unsigned long sysInfo[QSV_MAX] = {0};
    char buffer[20];
    int nBytes = 0;
 
    nBytes = RNG_GetNoise(buffer, sizeof(buffer));
    RNG_RandomUpdate(buffer, nBytes);
    
    /* allocate memory and use address and memory */
    plong = (unsigned long *)malloc(sizeof(*plong));
@@ -156,21 +245,23 @@ void RNG_SystemInfoForRNG(void)
    {
       RNG_RandomUpdate(&cc, sizeof(cc));
       RNG_RandomUpdate(&ci, sizeof(ci));
       RNG_RandomUpdate(&actual, sizeof(actual));
    }
 
    /* current directory */
    rc = DosQueryCurrentDir(0, path, &pathlength);
+   strcat(fullpath, "\\");
+   strcat(fullpath, path);
    if (rc == NO_ERROR)
    {
-      RNG_RandomUpdate(path, strlen(path));
+      RNG_RandomUpdate(fullpath, strlen(fullpath));
       // path info
-      rc = DosQueryPathInfo(path, FIL_STANDARD, &fstatus, sizeof(fstatus));
+      rc = DosQueryPathInfo(fullpath, FIL_STANDARD, &fstatus, sizeof(fstatus));
       if (rc == NO_ERROR)
       {
          RNG_RandomUpdate(&fstatus, sizeof(fstatus));
       }
    }
 
    /* file system info */
    rc = DosQueryFSInfo(0, FSIL_ALLOC, &fsallocate, sizeof(fsallocate));
@@ -183,22 +274,25 @@ void RNG_SystemInfoForRNG(void)
    rc = DosQueryCurrentDisk(&defaultdrive, &logicaldrives);
    if (rc == NO_ERROR)
    {
       RNG_RandomUpdate(&defaultdrive, sizeof(defaultdrive));
       RNG_RandomUpdate(&logicaldrives, sizeof(logicaldrives));
    }
 
    /* system info */
-   rc = DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &counter, sizeof(counter));
+   rc = DosQuerySysInfo(1L, QSV_MAX, (PVOID)&sysInfo, sizeof(ULONG)*QSV_MAX);
    if (rc == NO_ERROR)
    {
-      RNG_RandomUpdate(&counter, sizeof(counter));
+      RNG_RandomUpdate(&sysInfo, sizeof(sysInfo));
    }
 
+   // now let's do some files
+   ReadSystemFiles();
+
    /* more noise */
    nBytes = RNG_GetNoise(buffer, sizeof(buffer));
    RNG_RandomUpdate(buffer, nBytes);
 }
 
 void RNG_FileForRNG(char *filename)
 {
     struct stat stat_buf;
--- a/security/nss/lib/util/unix_rand.c
+++ b/security/nss/lib/util/unix_rand.c
@@ -257,17 +257,17 @@ GetHighResClock(void *buf, size_t maxbyt
 
 static void
 GiveSystemInfo(void)
 {
     /* XXX haven't found any yet! */
 }
 #endif /* IBM R2 */
 
-#if defined(__linux)
+#if defined(LINUX)
 #include <linux/kernel.h>
 
 static size_t
 GetHighResClock(void *buf, size_t maxbytes)
 {
     return 0;
 }
 
@@ -278,17 +278,17 @@ GiveSystemInfo(void)
 #if 0
     struct sysinfo si;
     char hn[2000];
     if (sysinfo(&si) == 0) {
 	RNG_RandomUpdate(&si, sizeof(si));
     }
 #endif
 }
-#endif /* __linux */
+#endif /* LINUX */
 
 #if defined(NCR)
 
 #include <sys/utsname.h>
 #include <sys/systeminfo.h>
 
 #define getdtablesize() sysconf(_SC_OPEN_MAX)
 
@@ -695,17 +695,17 @@ void RNG_SystemInfoForRNG(void)
 	"/var/tmp",
 	"/usr/tmp",
 	0
     };
 
 #ifdef DO_PS
 For now it is considered that it is too expensive to run the ps command
 for the small amount of entropy it provides.
-#if defined(__sun) && (!defined(__svr4) && !defined(SVR4)) || defined(bsdi) || defined(__linux)
+#if defined(__sun) && (!defined(__svr4) && !defined(SVR4)) || defined(bsdi) || defined(LINUX)
     static char ps_cmd[] = "ps aux";
 #else
     static char ps_cmd[] = "ps -el";
 #endif
 #endif /* DO_PS */
     static char netstat_ni_cmd[] = "netstat -ni";
 
     GiveSystemInfo();
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ac6ad286b81e3921d542663e43de35f97dbf95d5
GIT binary patch
literal 48127
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
new file mode 100644
--- /dev/null
+++ b/security/nss/macbuild/LoadableRoots.mcp.exp
@@ -0,0 +1,1 @@
+C_GetFunctionList
index c34a514c03dd168ccec42218a61b775205d74137..c7ade9ba94a4cdc9abad39adaf8ccac56fbe7448
GIT binary patch
literal 97893
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
Dx5SKF
--- a/security/nss/macbuild/NSSCommon.h
+++ b/security/nss/macbuild/NSSCommon.h
@@ -1,3 +1,5 @@
 /* Defines common to all versions of NSS */
 
 #define NSPR20 1
+#define MP_API_COMPATIBLE 1
+
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d16cdaf247d9509fc6a466d525ab708b0e5218be
GIT binary patch
literal 44740
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
--- a/security/nss/makefile.win
+++ b/security/nss/makefile.win
@@ -69,23 +69,31 @@ GMAKE_FLAGS = $(GMAKE_FLAGS) USE_DEBUG_R
 # The rules.  Simply invoke gmake with the same target.
 # The default target is 'all'.  For Win16, set up the
 # environment to use the Watcom compiler, Watcom headers,
 # and Watcom libs.
 #
 
 all:: export libs install
 
-export libs install clobber clobber_all clean depend::
+install:: moz_import install_roots
+
+depend::
+
+export libs install clobber clobber_all clean::
 !if "$(MOZ_BITS)" == "16"
 	set PATH=%WATCPATH%
 	set INCLUDE=%WATC_INC%
 	set LIB=%WATC_LIB%
 !endif
+	cd lib
 	$(GMAKE) $(GMAKE_FLAGS) $@
 !if "$(MOZ_BITS)" == "16"
 	set PATH=%MSVCPATH%
 	set INCLUDE=%MSVC_INC%
 	set LIB=%MSVC_LIB%
 !endif
 
 moz_import::
 	copy $(DIST)\lib\dbm32.lib $(DIST)\lib\dbm.lib
+
+install_roots::
+	$(MAKE_INSTALL) $(DIST)\lib\nssckbi.dll $(DIST)\bin