summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2hg <devnull@localhost>2003-12-23 00:52:07 +0000
committercvs2hg <devnull@localhost>2003-12-23 00:52:07 +0000
commit7ae644ebb6243b9c58f364084eb53a017e8a5289 (patch)
tree49c5db698b2f992b440b2ac8bff22fbb1274a91d
parent26b3b7b10e75bc46874b5c64058bd86929855d7b (diff)
downloadnss-hg-7ae644ebb6243b9c58f364084eb53a017e8a5289.tar.gz
fixup commit for branch 'MOZILLA_1_4_BRANCH'
-rw-r--r--security/coreconf/AIX5.2.mk54
-rw-r--r--security/coreconf/Linux2.6.mk49
-rw-r--r--security/nss/lib/freebl/ecl/Makefile224
-rw-r--r--security/nss/lib/freebl/ecl/README329
-rw-r--r--security/nss/lib/freebl/ecl/README.FP316
-rw-r--r--security/nss/lib/freebl/ecl/ec2.h122
-rw-r--r--security/nss/lib/freebl/ecl/ec2_163.c258
-rw-r--r--security/nss/lib/freebl/ecl/ec2_193.c275
-rw-r--r--security/nss/lib/freebl/ecl/ec2_233.c298
-rw-r--r--security/nss/lib/freebl/ecl/ec2_aff.c270
-rw-r--r--security/nss/lib/freebl/ecl/ec2_mont.c276
-rw-r--r--security/nss/lib/freebl/ecl/ec2_proj.c368
-rw-r--r--security/nss/lib/freebl/ecl/ec_naf.c101
-rw-r--r--security/nss/lib/freebl/ecl/ecl-curve.h646
-rw-r--r--security/nss/lib/freebl/ecl/ecl-exp.h194
-rw-r--r--security/nss/lib/freebl/ecl/ecl-priv.h216
-rw-r--r--security/nss/lib/freebl/ecl/ecl.c406
-rw-r--r--security/nss/lib/freebl/ecl/ecl.h82
-rw-r--r--security/nss/lib/freebl/ecl/ecl_curve.c120
-rw-r--r--security/nss/lib/freebl/ecl/ecl_gf.c337
-rw-r--r--security/nss/lib/freebl/ecl/ecl_mult.c359
-rw-r--r--security/nss/lib/freebl/ecl/ecp.h136
-rw-r--r--security/nss/lib/freebl/ecl/ecp_192.c228
-rw-r--r--security/nss/lib/freebl/ecl/ecp_224.c305
-rw-r--r--security/nss/lib/freebl/ecl/ecp_aff.c284
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fp.c566
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fp.h405
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fp160.c178
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fp192.c176
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fp224.c189
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fpinc.c854
-rw-r--r--security/nss/lib/freebl/ecl/ecp_jac.c553
-rw-r--r--security/nss/lib/freebl/ecl/ecp_jm.c320
-rw-r--r--security/nss/lib/freebl/ecl/ecp_mont.c190
-rw-r--r--security/nss/lib/freebl/mpi/mp_gf2m-priv.h101
-rw-r--r--security/nss/lib/freebl/mpi/target.mk220
-rw-r--r--security/nss/tests/cert/eccert.sh889
-rwxr-xr-xsecurity/nss/tests/cert/noeccert.sh654
-rwxr-xr-xsecurity/nss/tests/fixtests.sh104
-rw-r--r--security/nss/tests/ssl/ecssl.sh349
-rw-r--r--security/nss/tests/ssl/ecsslauth.txt50
-rw-r--r--security/nss/tests/ssl/ecsslcov.txt83
-rw-r--r--security/nss/tests/ssl/ecsslstress.txt24
-rw-r--r--security/nss/tests/ssl/sslreq.dat2
-rw-r--r--security/nss/tests/tools/ectools.sh210
-rw-r--r--security/nss/tests/tools/noectools.sh189
46 files changed, 12559 insertions, 0 deletions
diff --git a/security/coreconf/AIX5.2.mk b/security/coreconf/AIX5.2.mk
new file mode 100644
index 000000000..319569c52
--- /dev/null
+++ b/security/coreconf/AIX5.2.mk
@@ -0,0 +1,54 @@
+#
+# 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) 1994-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 AIX5.2
+#
+
+include $(CORE_DEPTH)/coreconf/AIX.mk
+
+
+ifeq ($(USE_64), 1)
+# Next line replaced by generic name handling in arch.mk
+# COMPILER_TAG = _64
+ OS_CFLAGS += -DAIX_64BIT
+ OBJECT_MODE=64
+ export OBJECT_MODE
+endif
+DSO_LDOPTS = -brtl -bM:SRE -bnoentry
+MKSHLIB = $(LD) $(DSO_LDOPTS) -blibpath:/usr/lib:/lib -lc -lm
+
+OS_LIBS += -blibpath:/usr/lib:/lib -lc -lm
+ifdef MAPFILE
+DSO_LDOPTS += -bexport:$(MAPFILE)
+else
+DSO_LDOPTS += -bexpall
+endif
diff --git a/security/coreconf/Linux2.6.mk b/security/coreconf/Linux2.6.mk
new file mode 100644
index 000000000..602b3abe1
--- /dev/null
+++ b/security/coreconf/Linux2.6.mk
@@ -0,0 +1,49 @@
+#
+# 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) 1994-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 Linux 2.6 (ELF)
+#
+
+include $(CORE_DEPTH)/coreconf/Linux.mk
+
+OS_REL_CFLAGS += -DLINUX2_1
+MKSHLIB = $(CC) -shared -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
+ifdef BUILD_OPT
+ OPTIMIZER = -O2
+endif
+
+ifdef MAPFILE
+ MKSHLIB += -Wl,--version-script,$(MAPFILE)
+endif
+PROCESS_MAP_FILE = grep -v ';-' $(LIBRARY_NAME).def | \
+ sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
+
diff --git a/security/nss/lib/freebl/ecl/Makefile b/security/nss/lib/freebl/ecl/Makefile
new file mode 100644
index 000000000..5ee99a730
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/Makefile
@@ -0,0 +1,224 @@
+##
+## Makefile for elliptic curve library
+##
+## 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 elliptic curve math library.
+##
+## The Initial Developer of the Original Code is Sun Microsystems, Inc.
+## Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+## Sun Microsystems, Inc. All Rights Reserved.
+##
+## Portions created by Michael J. Fromberger are
+## Copyright (C) 1998, 2000 Michael J. Fromberger. All Rights Reserved.
+##
+## Contributor(s):
+## Douglas Stebila <douglas@stebila.ca>
+## Michael J. Fromberger <sting@linguist.dartmouth.edu>
+## Netscape Communications Corporation
+## Richard C. Swift (swift@netscape.com)
+##
+## 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.
+
+## Define CC to be the C compiler you wish to use. The GNU cc
+## compiler (gcc) should work, at the very least
+#CC=cc
+#CC=gcc
+
+##
+## Define PERL to point to your local Perl interpreter. It
+## should be Perl 5.x, although it's conceivable that Perl 4
+## might work ... I haven't tested it.
+##
+#PERL=/usr/bin/perl
+PERL=perl
+
+include ../mpi/target.mk
+
+##
+## Define platform-dependent variables for use of floating-point code.
+##
+ifeq ($(TARGET),v9SOLARIS)
+ECL_USE_FP=1
+else
+ifeq ($(TARGET),v8plusSOLARIS)
+ECL_USE_FP=1
+else
+ifeq ($(TARGET),v8SOLARIS)
+ECL_USE_FP=1
+else
+ifeq ($(TARGET),x86LINUX)
+ECL_USE_FP=1
+endif
+endif
+endif
+endif
+
+##
+## Add to definition of CFLAGS depending on use of floating-point code.
+##
+ifeq ($(ECL_USE_FP),1)
+CFLAGS+= -DECL_USE_FP
+endif
+
+##
+## Define LIBS to include any libraries you need to link against.
+## If NO_TABLE is define, LIBS should include '-lm' or whatever is
+## necessary to bring in the math library. Otherwise, it can be
+## left alone, unless your system has other peculiar requirements.
+##
+LIBS=-L../mpi -lmpi -lm#-lmalloc#-lefence
+
+##
+## Define INCLUDES to include any include directories you need to
+## compile with.
+##
+INCLUDES=-I../mpi
+CFLAGS+= $(INCLUDES) $(XCFLAGS)
+
+##
+## Define RANLIB to be the library header randomizer; you might not
+## need this on some systems (just set it to 'echo' on these systems,
+## such as IRIX)
+##
+RANLIB=echo
+
+##
+## Define LIBOBJS to be the object files that will be created during
+## the build process.
+##
+LIBOBJS = ecl.o ecl_curve.o ecl_mult.o ecl_gf.o \
+ ec2_aff.o ec2_mont.o ec2_proj.o \
+ ec2_163.o ec2_193.o ec2_233.o \
+ ecp_aff.o ecp_jac.o ecp_mont.o \
+ ec_naf.o ecp_jm.o \
+ ecp_192.o ecp_224.o
+ifeq ($(ECL_USE_FP),1)
+LIBOBJS+= ecp_fp160.o ecp_fp192.o ecp_fp224.o ecp_fp.o
+endif
+
+## The headers contained in this library.
+LIBHDRS = ecl-exp.h ecl.h ec2.h ecp.h ecl-priv.h ecl-curve.h
+APPHDRS = ecl-exp.h ecl.h ec2.h ecp.h ecl-priv.h ecl-curve.h
+ifeq ($(ECL_GFP_ASSEMBLY_FP),1)
+LIBHDRS += ecp_fp.h
+APPHDRS += ecp_fp.h
+endif
+
+
+help:
+ @ echo ""
+ @ echo "The following targets can be built with this Makefile:"
+ @ echo ""
+ @ echo "libecl.a - elliptic curve library"
+ @ echo "tests - build command line tests"
+ @ echo "test - run command line tests"
+ @ echo "clean - clean up objects and such"
+ @ echo ""
+
+.SUFFIXES: .c .o .i
+
+.c.i:
+ $(CC) $(CFLAGS) -E $< > $@
+
+#---------------------------------------
+
+$(LIBOBJS): $(LIBHDRS)
+
+ecl.o: ecl.c $(LIBHDRS)
+ecl_curve.o: ecl_curve.c $(LIBHDRS)
+ecl_mult.o: ecl_mult.c $(LIBHDRS)
+ecl_gf.o: ecl_gf.c $(LIBHDRS)
+ec2_aff.o: ec2_aff.c $(LIBHDRS)
+ec2_mont.o: ec2_mont.c $(LIBHDRS)
+ec2_proj.o: ec2_proj.c $(LIBHDRS)
+ec2_163.o: ec2_163.c $(LIBHDRS)
+ec2_193.o: ec2_193.c $(LIBHDRS)
+ec2_233.o: ec2_233.c $(LIBHDRS)
+ecp_aff.o: ecp_aff.c $(LIBHDRS)
+ecp_jac.o: ecp_jac.c $(LIBHDRS)
+ecp_jm.o: ecp_jm.c $(LIBHDRS)
+ecp_mont.o: ecp_mont.c $(LIBHDRS)
+ecp_192.o: ecp_192.c $(LIBHDRS)
+ecp_224.o: ecp_224.c $(LIBHDRS)
+ecp_fp.o: ecp_fp.c $(LIBHDRS)
+ifeq ($(ECL_USE_FP),1)
+ecp_fp160.o: ecp_fp160.c ecp_fpinc.c $(LIBHDRS)
+ecp_fp192.o: ecp_fp192.c ecp_fpinc.c $(LIBHDRS)
+ecp_fp224.o: ecp_fp224.c ecp_fpinc.c $(LIBHDRS)
+endif
+
+libecl.a: $(LIBOBJS)
+ ar -cvr libecl.a $(LIBOBJS)
+ $(RANLIB) libecl.a
+
+lib libs: libecl.a
+
+ecl.i: ecl.h
+
+#---------------------------------------
+
+ECLTESTOBJS = ec2_test.o ecp_test.o ec_naft.o
+ifeq ($(ECL_USE_FP),1)
+ECLTESTOBJS+= ecp_fpt.o
+endif
+ECLTESTS = $(ECLTESTOBJS:.o=)
+
+$(ECLTESTOBJS): %.o: tests/%.c $(LIBHDRS)
+ $(CC) $(CFLAGS) -o $@ -c $< $(INCLUDES)
+
+$(ECLTESTS): %: %.o libecl.a
+ $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+
+ifeq ($(ECL_USE_FP),1)
+tests: ec2_test ecp_test ec_naft ecp_fpt
+else
+tests: ec2_test ecp_test ec_naft
+endif
+
+#---------------------------------------
+
+ifeq ($(ECL_USE_FP),1)
+test: tests
+ ./ecp_test
+ ./ec2_test
+ ./ec_naft
+ ./ecp_fpt
+else
+test: tests
+ ./ecp_test
+ ./ec_naft
+ ./ec2_test
+endif
+
+#---------------------------------------
+
+alltests: tests
+
+clean:
+ rm -f *.o *.a *.i
+ rm -f core
+ rm -f *~ .*~
+ rm -f $(ECLTESTS)
+
+clobber: clean
+
+# END
diff --git a/security/nss/lib/freebl/ecl/README b/security/nss/lib/freebl/ecl/README
new file mode 100644
index 000000000..d12eb3610
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/README
@@ -0,0 +1,329 @@
+
+Version: MPL 1.1/GPL 2.0/LGPL 2.1
+
+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 elliptic curve math library.
+
+The Initial Developer of the Original Code is Sun Microsystems, Inc.
+Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+Sun Microsystems, Inc. All Rights Reserved.
+
+Contributor(s):
+ Stephen Fung <fungstep@hotmail.com> and
+ Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+
+
+The ECL exposes routines for constructing and converting curve
+parameters for internal use.
+
+
+HEADER FILES
+============
+
+ecl-exp.h - Exports data structures and curve names. For use by code
+that does not have access to mp_ints.
+
+ecl-curve.h - Provides hex encodings (in the form of ECCurveParams
+structs) of standardizes elliptic curve domain parameters and mappings
+from ECCurveName to ECCurveParams. For use by code that does not have
+access to mp_ints.
+
+ecl.h - Interface to constructors for curve parameters and group object,
+and point multiplication operations. Used by higher level algorithms
+(like ECDH and ECDSA) to actually perform elliptic curve cryptography.
+
+ecl-priv.h - Data structures and functions for internal use within the
+library.
+
+ec2.h - Internal header file that contains all functions for point
+arithmetic over binary polynomial fields.
+
+ecp.h - Internal header file that contains all functions for point
+arithmetic over prime fields.
+
+DATA STRUCTURES AND TYPES
+=========================
+
+ECCurveName (from ecl-exp.h) - Opaque name for standardized elliptic
+curve domain parameters.
+
+ECCurveParams (from ecl-exp.h) - Provides hexadecimal encoding
+of elliptic curve domain parameters. Can be generated by a user
+and passed to ECGroup_fromHex or can be generated from a name by
+EC_GetNamedCurveParams. ecl-curve.h contains ECCurveParams structs for
+the standardized curves defined by ECCurveName.
+
+ECGroup (from ecl.h and ecl-priv.h) - Opaque data structure that
+represents a group of elliptic curve points for a particular set of
+elliptic curve domain parameters. Contains all domain parameters (curve
+a and b, field, base point) as well as pointers to the functions that
+should be used for point arithmetic and the underlying field GFMethod.
+Generated by either ECGroup_fromHex or ECGroup_fromName.
+
+GFMethod (from ecl-priv.h) - Represents a field underlying a set of
+elliptic curve domain parameters. Contains the irreducible that defines
+the field (either the prime or the binary polynomial) as well as
+pointers to the functions that should be used for field arithmetic.
+
+ARITHMETIC FUNCTIONS
+====================
+
+Higher-level algorithms (like ECDH and ECDSA) should call ECPoint_mul
+or ECPoints_mul (from ecl.h) to do point arithmetic. These functions
+will choose which underlying algorithms to use, based on the ECGroup
+structure.
+
+Point Multiplication
+--------------------
+
+ecl_mult.c provides the ECPoints_mul and ECPoint_mul wrappers.
+It also provides two implementations for the pts_mul operation -
+ec_pts_mul_basic (which computes kP, lQ, and then adds kP + lQ) and
+ec_pts_mul_simul_w2 (which does a simultaneous point multiplication
+using a table with window size 2*2).
+
+ec_naf.c provides an implementation of an algorithm to calculate a
+non-adjacent form of a scalar, minimizing the number of point
+additions that need to be done in a point multiplication.
+
+Point Arithmetic over Prime Fields
+----------------------------------
+
+ecp_aff.c provides point arithmetic using affine coordinates.
+
+ecp_jac.c provides point arithmetic using Jacobian projective
+coordinates and mixed Jacobian-affine coordinates. (Jacobian projective
+coordinates represent a point (x, y) as (X, Y, Z), where x=X/Z^2,
+y=Y/Z^3).
+
+ecp_jm.c provides point arithmetic using Modified Jacobian
+coordinates and mixed Modified_Jacobian-affine coordinates.
+(Modified Jacobian coordinates represent a point (x, y)
+as (X, Y, Z, a*Z^4), where x=X/Z^2, y=Y/Z^3, and a is
+the linear coefficient in the curve defining equation).
+
+ecp_192.c and ecp_224.c provide optimized field arithmetic.
+
+Point Arithmetic over Binary Polynomial Fields
+----------------------------------------------
+
+ec2_aff.c provides point arithmetic using affine coordinates.
+
+ec2_proj.c provides point arithmetic using projective coordinates.
+(Projective coordinates represent a point (x, y) as (X, Y, Z), where
+x=X/Z, y=Y/Z^2).
+
+ec2_mont.c provides point multiplication using Montgomery projective
+coordinates.
+
+ec2_163.c, ec2_193.c, and ec2_233.c provide optimized field arithmetic.
+
+Field Arithmetic
+----------------
+
+ecl_gf.c provides constructors for field objects (GFMethod) with the
+functions GFMethod_cons*. It also provides wrappers around the basic
+field operations.
+
+Prime Field Arithmetic
+----------------------
+
+The mpi library provides the basic prime field arithmetic.
+
+ecp_mont.c provides wrappers around the Montgomery multiplication
+functions from the mpi library and adds encoding and decoding functions.
+It also provides the function to construct a GFMethod object using
+Montgomery multiplication.
+
+ecp_192.c and ecp_224.c provide optimized modular reduction for the
+fields defined by nistp192 and nistp224 primes.
+
+ecl_gf.c provides wrappers around the basic field operations.
+
+Binary Polynomial Field Arithmetic
+----------------------------------
+
+../mpi/mp_gf2m.c provides basic binary polynomial field arithmetic,
+including addition, multiplication, squaring, mod, and division, as well
+as conversion ob polynomial representations between bitstring and int[].
+
+ec2_163.c, ec2_193.c, and ec2_233.c provide optimized field mod, mul,
+and sqr operations.
+
+ecl_gf.c provides wrappers around the basic field operations.
+
+Field Encoding
+--------------
+
+By default, field elements are encoded in their basic form. It is
+possible to use an alternative encoding, however. For example, it is
+possible to Montgomery representation of prime field elements and
+take advantage of the fast modular multiplication that Montgomery
+representation provides. The process of converting from basic form to
+Montgomery representation is called field encoding, and the opposite
+process would be field decoding. All internal point operations assume
+that the operands are field encoded as appropriate. By rewiring the
+underlying field arithmetic to perform operations on these encoded
+values, the same overlying point arithmetic operations can be used
+regardless of field representation.
+
+ALGORITHM WIRING
+================
+
+The EC library allows point and field arithmetic algorithms to be
+substituted ("wired-in") on a fine-grained basis. This allows for
+generic algorithms and algorithms that are optimized for a particular
+curve, field, or architecture, to coexist and to be automatically
+selected at runtime.
+
+Wiring Mechanism
+----------------
+
+The ECGroup and GFMethod structure contain pointers to the point and
+field arithmetic functions, respectively, that are to be used in
+operations.
+
+The selection of algorithms to use is handled in the function
+ecgroup_fromNameAndHex in ecl.c.
+
+Default Wiring
+--------------
+
+Curves over prime fields by default use montgomery field arithmetic,
+point multiplication using 5-bit window non-adjacent-form with
+Modified Jacobian coordinates, and 2*2-bit simultaneous point
+multiplication using Jacobian coordinates.
+(Wiring in function ECGroup_consGFp_mont in ecl.c.)
+
+Curves over prime fields that have optimized modular reduction (i.e.,
+secp160r1, nistp192, and nistp224) do not use Montgomery field
+arithmetic. Instead, they use basic field arithmetic with their
+optimized reduction (as in ecp_192.c and ecp_224.c). They
+use the same point multiplication and simultaneous point multiplication
+algorithms as other curves over prime fields.
+
+Curves over binary polynomial fields by default use generic field
+arithmetic with montgomery point multiplication and basic kP + lQ
+computation (multiply, multiply, and add). (Wiring in function
+ECGroup_cons_GF2m in ecl.c.)
+
+Curves over binary polynomial fields that have optimized field
+arithmetic (i.e., any 163-, 193, or 233-bit field) use their optimized
+field arithmetic. They use the same point multiplication and
+simultaneous point multiplication algorithms as other curves over binary
+fields.
+
+Example
+-------
+
+We provide an example for plugging in an optimized implementation for
+the Koblitz curve nistk163.
+
+Suppose the file ec2_k163.c contains the optimized implementation. In
+particular it contains a point multiplication function:
+
+ mp_err ec_GF2m_nistk163_pt_mul(const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry, const ECGroup *group);
+
+Since only a pt_mul function is provided, the generic pt_add function
+will be used.
+
+There are two options for handling the optimized field arithmetic used
+by the ..._pt_mul function. Say the optimized field arithmetic includes
+the following functions:
+
+ mp_err ec_GF2m_nistk163_add(const mp_int *a, const mp_int *b,
+ mp_int *r, const GFMethod *meth);
+ mp_err ec_GF2m_nistk163_mul(const mp_int *a, const mp_int *b,
+ mp_int *r, const GFMethod *meth);
+ mp_err ec_GF2m_nistk163_sqr(const mp_int *a, const mp_int *b,
+ mp_int *r, const GFMethod *meth);
+ mp_err ec_GF2m_nistk163_div(const mp_int *a, const mp_int *b,
+ mp_int *r, const GFMethod *meth);
+
+First, the optimized field arithmetic could simply be called directly
+by the ..._pt_mul function. This would be accomplished by changing
+the ecgroup_fromNameAndHex function in ecl.c to include the following
+statements:
+
+ if (name == ECCurve_NIST_K163) {
+ group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx,
+ &geny, &order, params->cofactor);
+ if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+ MP_CHECKOK( ec_group_set_nistk163(group) );
+ }
+
+and including in ec2_k163.c the following function:
+
+ mp_err ec_group_set_nistk163(ECGroup *group) {
+ group->point_mul = &ec_GF2m_nistk163_pt_mul;
+ return MP_OKAY;
+ }
+
+As a result, ec_GF2m_pt_add and similar functions would use the
+basic binary polynomial field arithmetic ec_GF2m_add, ec_GF2m_mul,
+ec_GF2m_sqr, and ec_GF2m_div.
+
+Alternatively, the optimized field arithmetic could be wired into the
+group's GFMethod. This would be accomplished by putting the following
+function in ec2_k163.c:
+
+ mp_err ec_group_set_nistk163(ECGroup *group) {
+ group->meth->field_add = &ec_GF2m_nistk163_add;
+ group->meth->field_mul = &ec_GF2m_nistk163_mul;
+ group->meth->field_sqr = &ec_GF2m_nistk163_sqr;
+ group->meth->field_div = &ec_GF2m_nistk163_div;
+ group->point_mul = &ec_GF2m_nistk163_pt_mul;
+ return MP_OKAY;
+ }
+
+For an example of functions that use special field encodings, take a
+look at ecp_mont.c.
+
+TESTING
+=======
+
+The ecl/tests directory contains a collection of standalone tests that
+verify the correctness of the elliptic curve library.
+
+Both ecp_test and ec2_test take the following arguments:
+
+ --print Print out results of each point arithmetic test.
+ --time Benchmark point operations and print results.
+
+The set of curves over which ecp_test and ec2_test run is coded into the
+program, but can be changed by editing the source files.
+
+BUILDING
+========
+
+The ecl can be built as a standalone library, separate from NSS,
+dependent only on the mpi library. To build the library:
+
+ > cd ../mpi
+ > make libs
+ > cd ../ecl
+ > make libs
+ > make tests # to build test files
+ > make test # to run automated tests
diff --git a/security/nss/lib/freebl/ecl/README.FP b/security/nss/lib/freebl/ecl/README.FP
new file mode 100644
index 000000000..e92a5affe
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/README.FP
@@ -0,0 +1,316 @@
+
+Version: MPL 1.1/GPL 2.0/LGPL 2.1
+
+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 elliptic curve math library.
+
+The Initial Developer of the Original Code is Sun Microsystems, Inc.
+Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+Sun Microsystems, Inc. All Rights Reserved.
+
+Contributor(s):
+ Stephen Fung <fungstep@hotmail.com> and
+ Nils Gura <nils.gura@sun.com>, Sun Microsystems Laboratories
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+
+
+The ECL exposes routines for constructing and converting curve
+parameters for internal use.
+
+The floating point code of the ECL provides algorithms for performing
+elliptic-curve point multiplications in floating point.
+
+The point multiplication algorithms perform calculations almost
+exclusively in floating point for efficiency, but have the same
+(integer) interface as the ECL for compatibility and to be easily
+wired-in to the ECL. Please see README file (not this README.FP file)
+for information on wiring-in.
+
+This has been implemented for 3 curves as specified in [1]:
+ secp160r1
+ secp192r1
+ secp224r1
+
+RATIONALE
+=========
+Calculations are done in the floating-point unit (FPU) since it
+gives better performance on the UltraSPARC III chips. This is
+because the FPU allows for faster multiplication than the integer unit.
+The integer unit has a longer multiplication instruction latency, and
+does not allow full pipelining, as described in [2].
+Since performance is an important selling feature of Elliptic Curve
+Cryptography (ECC), this implementation was created.
+
+DATA REPRESENTATION
+===================
+Data is primarily represented in an array of double-precision floating
+point numbers. Generally, each array element has 24 bits of precision
+(i.e. be x * 2^y, where x is an integer of at most 24 bits, y some positive
+integer), although the actual implementation details are more complicated.
+
+e.g. a way to store an 80 bit number might be:
+double p[4] = { 632613 * 2^0, 329841 * 2^24, 9961 * 2^48, 51 * 2^64 };
+See section ARITHMETIC OPERATIONS for more details.
+
+This implementation assumes that the floating-point unit rounding mode
+is round-to-even as specified in IEEE 754
+(as opposed to chopping, rounding up, or rounding down).
+When subtracting integers represented as arrays of floating point
+numbers, some coefficients (array elements) may become negative.
+This effectively gives an extra bit of precision that is important
+for correctness in some cases.
+
+The described number presentation limits the size of integers to 1023 bits.
+This is due to an upper bound of 1024 for the exponent of a double precision
+floating point number as specified in IEEE-754.
+However, this is acceptable for ECC key sizes of the foreseeable future.
+
+DATA STRUCTURES
+===============
+For more information on coordinate representations, see [3].
+
+ecfp_aff_pt
+-----------
+Affine EC Point Representation. This is the basic
+representation (x, y) of an elliptic curve point.
+
+ecfp_jac_pt
+-----------
+Jacobian EC Point. This stores a point as (X, Y, Z), where
+the affine point corresponds to (X/Z^2, Y/Z^3). This allows
+for fewer inversions in calculations.
+
+ecfp_chud_pt
+------------
+Chudnovsky Jacobian Point. This representation stores a point
+as (X, Y, Z, Z^2, Z^3), the same as a Jacobian representation
+but also storing Z^2 and Z^3 for faster point additions.
+
+ecfp_jm_pt
+----------
+Modified Jacobian Point. This representation stores a point
+as (X, Y, Z, a*Z^4), the same as Jacobian representation but
+also storing a*Z^4 for faster point doublings. Here "a" represents
+the linear coefficient of x defining the curve.
+
+EC_group_fp
+-----------
+Stores information on the elliptic curve group for floating
+point calculations. Contains curve specific information, as
+well as function pointers to routines, allowing different
+optimizations to be easily wired in.
+This should be made accessible from an ECGroup for the floating
+point implementations of point multiplication.
+
+POINT MULTIPLICATION ALGORITHMS
+===============================
+Elliptic Curve Point multiplication can be done at a higher level orthogonal
+to the implementation of point additions and point doublings. There
+are a variety of algorithms that can be used.
+
+The following algorithms have been implemented:
+
+4-bit Window (Jacobian Coordinates)
+Double & Add (Jacobian & Affine Coordinates)
+5-bit Non-Adjacent Form (Modified Jacobian & Chudnovsky Jacobian)
+
+Currently, the fastest algorithm for multiplying a generic point
+is the 5-bit Non-Adjacent Form.
+
+See comments in ecp_fp.c for more details and references.
+
+SOURCE / HEADER FILES
+=====================
+
+ecp_fp.c
+--------
+Main source file for floating point calculations. Contains routines
+to convert from floating-point to integer (mp_int format), point
+multiplication algorithms, and several other routines.
+
+ecp_fp.h
+--------
+Main header file. Contains most constants used and function prototypes.
+
+ecp_fp[160, 192, 224].c
+-----------------------
+Source files for specific curves. Contains curve specific code such
+as specialized reduction based on the field defining prime. Contains
+code wiring-in different algorithms and optimizations.
+
+ecp_fpinc.c
+-----------
+Source file that is included by ecp_fp[160, 192, 224].c. This generates
+functions with different preprocessor-defined names and loop iterations,
+allowing for static linking and strong compiler optimizations without
+code duplication.
+
+TESTING
+=======
+The test suite can be found in ecl/tests/ecp_fpt. This tests and gets
+timings of the different algorithms for the curves implemented.
+
+ARITHMETIC OPERATIONS
+---------------------
+The primary operations in ECC over the prime fields are modular arithmetic:
+i.e. n * m (mod p) and n + m (mod p). In this implementation, multiplication,
+addition, and reduction are implemented as separate functions. This
+enables computation of formulae with fewer reductions, e.g.
+(a * b) + (c * d) (mod p) rather than:
+((a * b) (mod p)) + ((c * d) (mod p)) (mod p)
+This takes advantage of the fact that the double precision mantissa in
+floating point can hold numbers up to 2^53, i.e. it has some leeway to
+store larger intermediate numbers. See further detail in the section on
+FLOATING POINT PRECISION.
+
+Multiplication
+--------------
+Multiplication is implemented in a standard polynomial multiplication
+fashion. The terms in opposite factors are pairwise multiplied and
+added together appropriately. Note that the result requires twice
+as many doubles for storage, as the bit size of the product is twice
+that of the multiplicands.
+e.g. suppose we have double n[3], m[3], r[6], and want to calculate r = n * m
+r[0] = n[0] * m[0]
+r[1] = n[0] * m[1] + n[1] * m[0]
+r[2] = n[0] * m[2] + n[1] * m[1] + n[2] * m[0]
+r[3] = n[1] * m[2] + n[2] * m[1]
+r[4] = n[2] * m[2]
+r[5] = 0 (This is used later to hold spillover from r[4], see tidying in
+the reduction section.)
+
+Addition
+--------
+Addition is done term by term. The only caveat is to be careful with
+the number of terms that need to be added. When adding results of
+multiplication (before reduction), twice as many terms need to be added
+together. This is done in the addLong function.
+e.g. for double n[4], m[4], r[4]: r = n + m
+r[0] = n[0] + m[0]
+r[1] = n[1] + m[1]
+r[2] = n[2] + m[2]
+r[3] = n[3] + m[3]
+
+Modular Reduction
+-----------------
+For the curves implemented, reduction is possible by fast reduction
+for Generalized Mersenne Primes, as described in [4]. For the
+floating point implementation, a significant step of the reduction
+process is tidying: that is, the propagation of carry bits from
+low-order to high-order coefficients to reduce the precision of each
+coefficient to 24 bits.
+This is done by adding and then subtracting
+ecfp_alpha, a large floating point number that induces precision roundoff.
+See [5] for more details on tidying using floating point arithmetic.
+e.g. suppose we have r = 961838 * 2^24 + 519308
+then if we set alpha = 3 * 2^51 * 2^24,
+FP(FP(r + alpha) - alpha) = 961838 * 2^24, because the precision for
+the intermediate results is limited. Our values of alpha are chosen
+to truncate to a desired number of bits.
+
+The reduction is then performed as in [4], adding multiples of prime p.
+e.g. suppose we are working over a polynomial of 10^2. Take the number
+2 * 10^8 + 11 * 10^6 + 53 * 10^4 + 23 * 10^2 + 95, stored in 5 elements
+for coefficients of 10^0, 10^2, ..., 10^8.
+We wish to reduce modulo p = 10^6 - 2 * 10^4 + 1
+We can subtract off from the higher terms
+(2 * 10^8 + 11 * 10^6 + 53 * 10^4 + 23 * 10^2 + 95) - (2 * 10^2) * (10^6 - 2 * 10^4 + 1)
+= 15 * 10^6 + 53 * 10^4 + 21 * 10^2 + 95
+= 15 * 10^6 + 53 * 10^4 + 21 * 10^2 + 95 - (15) * (10^6 - 2 * 10^4 + 1)
+= 83 * 10^4 + 21 * 10^2 + 80
+
+Integrated Example
+------------------
+This example shows how multiplication, addition, tidying, and reduction
+work together in our modular arithmetic. This is simplified from the
+actual implementation, but should convey the main concepts.
+Working over polynomials of 10^2 and with p as in the prior example,
+Let a = 16 * 10^4 + 53 * 10^2 + 33
+let b = 81 * 10^4 + 31 * 10^2 + 49
+let c = 22 * 10^4 + 0 * 10^2 + 95
+And suppose we want to compute a * b + c mod p.
+We first do a multiplication: then a * b =
+0 * 10^10 + 1296 * 10^8 + 4789 * 10^6 + 5100 * 10^4 + 3620 * 10^2 + 1617
+Then we add in c before doing reduction, allowing us to get a * b + c =
+0 * 10^10 + 1296 * 10^8 + 4789 * 10^6 + 5122 * 10^4 + 3620 * 10^2 + 1712
+We then perform a tidying on the upper half of the terms:
+0 * 10^10 + 1296 * 10^8 + 4789 * 10^6
+0 * 10^10 + (1296 + 47) * 10^8 + 89 * 10^6
+0 * 10^10 + 1343 * 10^8 + 89 * 10^6
+13 * 10^10 + 43 * 10^8 + 89 * 10^6
+which then gives us
+13 * 10^10 + 43 * 10^8 + 89 * 10^6 + 5122 * 10^4 + 3620 * 10^2 + 1712
+we then reduce modulo p similar to the reduction example above:
+13 * 10^10 + 43 * 10^8 + 89 * 10^6 + 5122 * 10^4 + 3620 * 10^2 + 1712
+ - (13 * 10^4 * p)
+69 * 10^8 + 89 * 10^6 + 5109 * 10^4 + 3620 * 10^2 + 1712
+ - (69 * 10^2 * p)
+227 * 10^6 + 5109 * 10^4 + 3551 * 10^2 + 1712
+ - (227 * p)
+5563 * 10^4 + 3551 * 10^2 + 1485
+finally, we do tidying to get the precision of each term down to 2 digits
+5563 * 10^4 + 3565 * 10^2 + 85
+5598 * 10^4 + 65 * 10^2 + 85
+55 * 10^6 + 98 * 10^4 + 65 * 10^2 + 85
+and perform another reduction step
+ - (55 * p)
+208 * 10^4 + 65 * 10^2 + 30
+There may be a small number of further reductions that could be done at
+this point, but this is typically done only at the end when converting
+from floating point to an integer unit representation.
+
+FLOATING POINT PRECISION
+========================
+This section discusses the precision of floating point numbers, which
+one writing new formulae or a larger bit size should be aware of. The
+danger is that an intermediate result may be required to store a
+mantissa larger than 53 bits, which would cause error by rounding off.
+
+Note that the tidying with IEEE rounding mode set to round-to-even
+allows negative numbers, which actually reduces the size of the double
+mantissa to 23 bits - since it rounds the mantissa to the nearest number
+modulo 2^24, i.e. roughly between -2^23 and 2^23.
+A multiplication increases the bit size to 2^46 * n, where n is the number
+of doubles to store a number. For the 224 bit curve, n = 10. This gives
+doubles of size 5 * 2^47. Adding two of these doubles gives a result
+of size 5 * 2^48, which is less than 2^53, so this is safe.
+Similar analysis can be done for other formulae to ensure numbers remain
+below 2^53.
+
+Extended-Precision Floating Point
+---------------------------------
+Some platforms, notably x86 Linux, may use an extended-precision floating
+point representation that has a 64-bit mantissa. [6] Although this
+implementation is optimized for the IEEE standard 53-bit mantissa,
+it should work with the 64-bit mantissa. A check is done at run-time
+in the function ec_set_fp_precision that detects if the precision is
+greater than 53 bits, and runs code for the 64-bit mantissa accordingly.
+
+REFERENCES
+==========
+[1] Certicom Corp., "SEC 2: Recommended Elliptic Curve Domain Parameters", Sept. 20, 2000. www.secg.org
+[2] Sun Microsystems Inc. UltraSPARC III Cu User's Manual, Version 1.0, May 2002, Table 4.4
+[3] H. Cohen, A. Miyaji, and T. Ono, "Efficient Elliptic Curve Exponentiation Using Mixed Coordinates".
+[4] Henk C.A. van Tilborg, Generalized Mersenne Prime. http://www.win.tue.nl/~henkvt/GenMersenne.pdf
+[5] Daniel J. Bernstein, Floating-Point Arithmetic and Message Authentication, Journal of Cryptology, March 2000, Section 2.
+[6] Daniel J. Bernstein, Floating-Point Arithmetic and Message Authentication, Journal of Cryptology, March 2000, Section 2 Notes.
diff --git a/security/nss/lib/freebl/ecl/ec2.h b/security/nss/lib/freebl/ecl/ec2.h
new file mode 100644
index 000000000..2c66b55f5
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ec2.h
@@ -0,0 +1,122 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for binary polynomial
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#ifndef __ec2_h_
+#define __ec2_h_
+
+#include "ecl-priv.h"
+
+/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
+mp_err ec_GF2m_pt_is_inf_aff(const mp_int *px, const mp_int *py);
+
+/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
+mp_err ec_GF2m_pt_set_inf_aff(mp_int *px, mp_int *py);
+
+/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx,
+ * qy). Uses affine coordinates. */
+mp_err ec_GF2m_pt_add_aff(const mp_int *px, const mp_int *py,
+ const mp_int *qx, const mp_int *qy, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+
+/* Computes R = P - Q. Uses affine coordinates. */
+mp_err ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py,
+ const mp_int *qx, const mp_int *qy, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+
+/* Computes R = 2P. Uses affine coordinates. */
+mp_err ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+
+/* by default, this routine is unused and thus doesn't need to be compiled */
+#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the irreducible that
+ * determines the field GF2m. Uses affine coordinates. */
+mp_err ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group);
+#endif
+
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the irreducible that
+ * determines the field GF2m. Uses Montgomery projective coordinates. */
+mp_err ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group);
+
+#ifdef ECL_ENABLE_GF2M_PROJ
+/* Converts a point P(px, py) from affine coordinates to projective
+ * coordinates R(rx, ry, rz). */
+mp_err ec_GF2m_pt_aff2proj(const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, mp_int *rz, const ECGroup *group);
+
+/* Converts a point P(px, py, pz) from projective coordinates to affine
+ * coordinates R(rx, ry). */
+mp_err ec_GF2m_pt_proj2aff(const mp_int *px, const mp_int *py,
+ const mp_int *pz, mp_int *rx, mp_int *ry,
+ const ECGroup *group);
+
+/* Checks if point P(px, py, pz) is at infinity. Uses projective
+ * coordinates. */
+mp_err ec_GF2m_pt_is_inf_proj(const mp_int *px, const mp_int *py,
+ const mp_int *pz);
+
+/* Sets P(px, py, pz) to be the point at infinity. Uses projective
+ * coordinates. */
+mp_err ec_GF2m_pt_set_inf_proj(mp_int *px, mp_int *py, mp_int *pz);
+
+/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
+ * (qx, qy, qz). Uses projective coordinates. */
+mp_err ec_GF2m_pt_add_proj(const mp_int *px, const mp_int *py,
+ const mp_int *pz, const mp_int *qx,
+ const mp_int *qy, mp_int *rx, mp_int *ry,
+ mp_int *rz, const ECGroup *group);
+
+/* Computes R = 2P. Uses projective coordinates. */
+mp_err ec_GF2m_pt_dbl_proj(const mp_int *px, const mp_int *py,
+ const mp_int *pz, mp_int *rx, mp_int *ry,
+ mp_int *rz, const ECGroup *group);
+
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GF2m. Uses projective coordinates. */
+mp_err ec_GF2m_pt_mul_proj(const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group);
+#endif
+
+#endif /* __ec2_h_ */
diff --git a/security/nss/lib/freebl/ecl/ec2_163.c b/security/nss/lib/freebl/ecl/ec2_163.c
new file mode 100644
index 000000000..d6872500d
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ec2_163.c
@@ -0,0 +1,258 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for binary polynomial
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ * Stephen Fung <fungstep@hotmail.com>, and
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ec2.h"
+#include "mp_gf2m.h"
+#include "mp_gf2m-priv.h"
+#include "mpi.h"
+#include "mpi-priv.h"
+#include <stdlib.h>
+
+/* Fast reduction for polynomials over a 163-bit curve. Assumes reduction
+ * polynomial with terms {163, 7, 6, 3, 0}. */
+mp_err
+ec_GF2m_163_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_digit *u, z;
+
+ if (a != r) {
+ MP_CHECKOK(mp_copy(a, r));
+ }
+#ifdef ECL_SIXTY_FOUR_BIT
+ if (MP_USED(r) < 6) {
+ MP_CHECKOK(s_mp_pad(r, 6));
+ }
+ u = MP_DIGITS(r);
+ MP_USED(r) = 6;
+
+ /* u[5] only has 6 significant bits */
+ z = u[5];
+ u[2] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
+ z = u[4];
+ u[2] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
+ u[1] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
+ z = u[3];
+ u[1] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
+ u[0] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
+ z = u[2] >> 35; /* z only has 29 significant bits */
+ u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
+ /* clear bits above 163 */
+ u[5] = u[4] = u[3] = 0;
+ u[2] ^= z << 35;
+#else
+ if (MP_USED(r) < 11) {
+ MP_CHECKOK(s_mp_pad(r, 11));
+ }
+ u = MP_DIGITS(r);
+ MP_USED(r) = 11;
+
+ /* u[11] only has 6 significant bits */
+ z = u[10];
+ u[5] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
+ u[4] ^= (z << 29);
+ z = u[9];
+ u[5] ^= (z >> 28) ^ (z >> 29);
+ u[4] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
+ u[3] ^= (z << 29);
+ z = u[8];
+ u[4] ^= (z >> 28) ^ (z >> 29);
+ u[3] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
+ u[2] ^= (z << 29);
+ z = u[7];
+ u[3] ^= (z >> 28) ^ (z >> 29);
+ u[2] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
+ u[1] ^= (z << 29);
+ z = u[6];
+ u[2] ^= (z >> 28) ^ (z >> 29);
+ u[1] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
+ u[0] ^= (z << 29);
+ z = u[5] >> 3; /* z only has 29 significant bits */
+ u[1] ^= (z >> 25) ^ (z >> 26);
+ u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
+ /* clear bits above 163 */
+ u[11] = u[10] = u[9] = u[8] = u[7] = u[6] = 0;
+ u[5] ^= z << 3;
+#endif
+ s_mp_clamp(r);
+
+ CLEANUP:
+ return res;
+}
+
+/* Fast squaring for polynomials over a 163-bit curve. Assumes reduction
+ * polynomial with terms {163, 7, 6, 3, 0}. */
+mp_err
+ec_GF2m_163_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_digit *u, *v;
+
+ v = MP_DIGITS(a);
+
+#ifdef ECL_SIXTY_FOUR_BIT
+ if (MP_USED(a) < 3) {
+ return mp_bsqrmod(a, meth->irr_arr, r);
+ }
+ if (MP_USED(r) < 6) {
+ MP_CHECKOK(s_mp_pad(r, 6));
+ }
+ MP_USED(r) = 6;
+#else
+ if (MP_USED(a) < 6) {
+ return mp_bsqrmod(a, meth->irr_arr, r);
+ }
+ if (MP_USED(r) < 12) {
+ MP_CHECKOK(s_mp_pad(r, 12));
+ }
+ MP_USED(r) = 12;
+#endif
+ u = MP_DIGITS(r);
+
+#ifdef ECL_THIRTY_TWO_BIT
+ u[11] = gf2m_SQR1(v[5]);
+ u[10] = gf2m_SQR0(v[5]);
+ u[9] = gf2m_SQR1(v[4]);
+ u[8] = gf2m_SQR0(v[4]);
+ u[7] = gf2m_SQR1(v[3]);
+ u[6] = gf2m_SQR0(v[3]);
+#endif
+ u[5] = gf2m_SQR1(v[2]);
+ u[4] = gf2m_SQR0(v[2]);
+ u[3] = gf2m_SQR1(v[1]);
+ u[2] = gf2m_SQR0(v[1]);
+ u[1] = gf2m_SQR1(v[0]);
+ u[0] = gf2m_SQR0(v[0]);
+ return ec_GF2m_163_mod(r, r, meth);
+
+ CLEANUP:
+ return res;
+}
+
+/* Fast multiplication for polynomials over a 163-bit curve. Assumes
+ * reduction polynomial with terms {163, 7, 6, 3, 0}. */
+mp_err
+ec_GF2m_163_mul(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_digit a2 = 0, a1 = 0, a0, b2 = 0, b1 = 0, b0;
+
+#ifdef ECL_THIRTY_TWO_BIT
+ mp_digit a5 = 0, a4 = 0, a3 = 0, b5 = 0, b4 = 0, b3 = 0;
+ mp_digit rm[6];
+#endif
+
+ if (a == b) {
+ return ec_GF2m_163_sqr(a, r, meth);
+ } else {
+ switch (MP_USED(a)) {
+#ifdef ECL_THIRTY_TWO_BIT
+ case 6:
+ a5 = MP_DIGIT(a, 5);
+ case 5:
+ a4 = MP_DIGIT(a, 4);
+ case 4:
+ a3 = MP_DIGIT(a, 3);
+#endif
+ case 3:
+ a2 = MP_DIGIT(a, 2);
+ case 2:
+ a1 = MP_DIGIT(a, 1);
+ default:
+ a0 = MP_DIGIT(a, 0);
+ }
+ switch (MP_USED(b)) {
+#ifdef ECL_THIRTY_TWO_BIT
+ case 6:
+ b5 = MP_DIGIT(b, 5);
+ case 5:
+ b4 = MP_DIGIT(b, 4);
+ case 4:
+ b3 = MP_DIGIT(b, 3);
+#endif
+ case 3:
+ b2 = MP_DIGIT(b, 2);
+ case 2:
+ b1 = MP_DIGIT(b, 1);
+ default:
+ b0 = MP_DIGIT(b, 0);
+ }
+#ifdef ECL_SIXTY_FOUR_BIT
+ MP_CHECKOK(s_mp_pad(r, 6));
+ s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
+ MP_USED(r) = 6;
+ s_mp_clamp(r);
+#else
+ MP_CHECKOK(s_mp_pad(r, 12));
+ s_bmul_3x3(MP_DIGITS(r) + 6, a5, a4, a3, b5, b4, b3);
+ s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
+ s_bmul_3x3(rm, a5 ^ a2, a4 ^ a1, a3 ^ a0, b5 ^ b2, b4 ^ b1,
+ b3 ^ b0);
+ rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 11);
+ rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 10);
+ rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 9);
+ rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 8);
+ rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 7);
+ rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 6);
+ MP_DIGIT(r, 8) ^= rm[5];
+ MP_DIGIT(r, 7) ^= rm[4];
+ MP_DIGIT(r, 6) ^= rm[3];
+ MP_DIGIT(r, 5) ^= rm[2];
+ MP_DIGIT(r, 4) ^= rm[1];
+ MP_DIGIT(r, 3) ^= rm[0];
+ MP_USED(r) = 12;
+ s_mp_clamp(r);
+#endif
+ return ec_GF2m_163_mod(r, r, meth);
+ }
+
+ CLEANUP:
+ return res;
+}
+
+/* Wire in fast field arithmetic for 163-bit curves. */
+mp_err
+ec_group_set_gf2m163(ECGroup *group, ECCurveName name)
+{
+ group->meth->field_mod = &ec_GF2m_163_mod;
+ group->meth->field_mul = &ec_GF2m_163_mul;
+ group->meth->field_sqr = &ec_GF2m_163_sqr;
+ return MP_OKAY;
+}
diff --git a/security/nss/lib/freebl/ecl/ec2_193.c b/security/nss/lib/freebl/ecl/ec2_193.c
new file mode 100644
index 000000000..5035a99bd
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ec2_193.c
@@ -0,0 +1,275 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for binary polynomial
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ * Stephen Fung <fungstep@hotmail.com>, and
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ec2.h"
+#include "mp_gf2m.h"
+#include "mp_gf2m-priv.h"
+#include "mpi.h"
+#include "mpi-priv.h"
+#include <stdlib.h>
+
+/* Fast reduction for polynomials over a 193-bit curve. Assumes reduction
+ * polynomial with terms {193, 15, 0}. */
+mp_err
+ec_GF2m_193_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_digit *u, z;
+
+ if (a != r) {
+ MP_CHECKOK(mp_copy(a, r));
+ }
+#ifdef ECL_SIXTY_FOUR_BIT
+ if (MP_USED(r) < 7) {
+ MP_CHECKOK(s_mp_pad(r, 7));
+ }
+ u = MP_DIGITS(r);
+ MP_USED(r) = 7;
+
+ /* u[6] only has 2 significant bits */
+ z = u[6];
+ u[3] ^= (z << 14) ^ (z >> 1);
+ u[2] ^= (z << 63);
+ z = u[5];
+ u[3] ^= (z >> 50);
+ u[2] ^= (z << 14) ^ (z >> 1);
+ u[1] ^= (z << 63);
+ z = u[4];
+ u[2] ^= (z >> 50);
+ u[1] ^= (z << 14) ^ (z >> 1);
+ u[0] ^= (z << 63);
+ z = u[3] >> 1; /* z only has 63 significant bits */
+ u[1] ^= (z >> 49);
+ u[0] ^= (z << 15) ^ z;
+ /* clear bits above 193 */
+ u[6] = u[5] = u[4] = 0;
+ u[3] ^= z << 1;
+#else
+ if (MP_USED(r) < 13) {
+ MP_CHECKOK(s_mp_pad(r, 13));
+ }
+ u = MP_DIGITS(r);
+ MP_USED(r) = 13;
+
+ /* u[12] only has 2 significant bits */
+ z = u[12];
+ u[6] ^= (z << 14) ^ (z >> 1);
+ u[5] ^= (z << 31);
+ z = u[11];
+ u[6] ^= (z >> 18);
+ u[5] ^= (z << 14) ^ (z >> 1);
+ u[4] ^= (z << 31);
+ z = u[10];
+ u[5] ^= (z >> 18);
+ u[4] ^= (z << 14) ^ (z >> 1);
+ u[3] ^= (z << 31);
+ z = u[9];
+ u[4] ^= (z >> 18);
+ u[3] ^= (z << 14) ^ (z >> 1);
+ u[2] ^= (z << 31);
+ z = u[8];
+ u[3] ^= (z >> 18);
+ u[2] ^= (z << 14) ^ (z >> 1);
+ u[1] ^= (z << 31);
+ z = u[7];
+ u[2] ^= (z >> 18);
+ u[1] ^= (z << 14) ^ (z >> 1);
+ u[0] ^= (z << 31);
+ z = u[6] >> 1; /* z only has 31 significant bits */
+ u[1] ^= (z >> 17);
+ u[0] ^= (z << 15) ^ z;
+ /* clear bits above 193 */
+ u[12] = u[11] = u[10] = u[9] = u[8] = u[7] = 0;
+ u[6] ^= z << 1;
+#endif
+ s_mp_clamp(r);
+
+ CLEANUP:
+ return res;
+}
+
+/* Fast squaring for polynomials over a 193-bit curve. Assumes reduction
+ * polynomial with terms {193, 15, 0}. */
+mp_err
+ec_GF2m_193_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_digit *u, *v;
+
+ v = MP_DIGITS(a);
+
+#ifdef ECL_SIXTY_FOUR_BIT
+ if (MP_USED(a) < 4) {
+ return mp_bsqrmod(a, meth->irr_arr, r);
+ }
+ if (MP_USED(r) < 7) {
+ MP_CHECKOK(s_mp_pad(r, 7));
+ }
+ MP_USED(r) = 7;
+#else
+ if (MP_USED(a) < 7) {
+ return mp_bsqrmod(a, meth->irr_arr, r);
+ }
+ if (MP_USED(r) < 13) {
+ MP_CHECKOK(s_mp_pad(r, 13));
+ }
+ MP_USED(r) = 13;
+#endif
+ u = MP_DIGITS(r);
+
+#ifdef ECL_THIRTY_TWO_BIT
+ u[12] = gf2m_SQR0(v[6]);
+ u[11] = gf2m_SQR1(v[5]);
+ u[10] = gf2m_SQR0(v[5]);
+ u[9] = gf2m_SQR1(v[4]);
+ u[8] = gf2m_SQR0(v[4]);
+ u[7] = gf2m_SQR1(v[3]);
+#endif
+ u[6] = gf2m_SQR0(v[3]);
+ u[5] = gf2m_SQR1(v[2]);
+ u[4] = gf2m_SQR0(v[2]);
+ u[3] = gf2m_SQR1(v[1]);
+ u[2] = gf2m_SQR0(v[1]);
+ u[1] = gf2m_SQR1(v[0]);
+ u[0] = gf2m_SQR0(v[0]);
+ return ec_GF2m_193_mod(r, r, meth);
+
+ CLEANUP:
+ return res;
+}
+
+/* Fast multiplication for polynomials over a 193-bit curve. Assumes
+ * reduction polynomial with terms {193, 15, 0}. */
+mp_err
+ec_GF2m_193_mul(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
+
+#ifdef ECL_THIRTY_TWO_BIT
+ mp_digit a6 = 0, a5 = 0, a4 = 0, b6 = 0, b5 = 0, b4 = 0;
+ mp_digit rm[8];
+#endif
+
+ if (a == b) {
+ return ec_GF2m_193_sqr(a, r, meth);
+ } else {
+ switch (MP_USED(a)) {
+#ifdef ECL_THIRTY_TWO_BIT
+ case 7:
+ a6 = MP_DIGIT(a, 6);
+ case 6:
+ a5 = MP_DIGIT(a, 5);
+ case 5:
+ a4 = MP_DIGIT(a, 4);
+#endif
+ case 4:
+ a3 = MP_DIGIT(a, 3);
+ case 3:
+ a2 = MP_DIGIT(a, 2);
+ case 2:
+ a1 = MP_DIGIT(a, 1);
+ default:
+ a0 = MP_DIGIT(a, 0);
+ }
+ switch (MP_USED(b)) {
+#ifdef ECL_THIRTY_TWO_BIT
+ case 7:
+ b6 = MP_DIGIT(b, 6);
+ case 6:
+ b5 = MP_DIGIT(b, 5);
+ case 5:
+ b4 = MP_DIGIT(b, 4);
+#endif
+ case 4:
+ b3 = MP_DIGIT(b, 3);
+ case 3:
+ b2 = MP_DIGIT(b, 2);
+ case 2:
+ b1 = MP_DIGIT(b, 1);
+ default:
+ b0 = MP_DIGIT(b, 0);
+ }
+#ifdef ECL_SIXTY_FOUR_BIT
+ MP_CHECKOK(s_mp_pad(r, 8));
+ s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
+ MP_USED(r) = 8;
+ s_mp_clamp(r);
+#else
+ MP_CHECKOK(s_mp_pad(r, 14));
+ s_bmul_3x3(MP_DIGITS(r) + 8, a6, a5, a4, b6, b5, b4);
+ s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
+ s_bmul_4x4(rm, a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b3, b6 ^ b2, b5 ^ b1,
+ b4 ^ b0);
+ rm[7] ^= MP_DIGIT(r, 7);
+ rm[6] ^= MP_DIGIT(r, 6);
+ rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
+ rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
+ rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
+ rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
+ rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
+ rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
+ MP_DIGIT(r, 11) ^= rm[7];
+ MP_DIGIT(r, 10) ^= rm[6];
+ MP_DIGIT(r, 9) ^= rm[5];
+ MP_DIGIT(r, 8) ^= rm[4];
+ MP_DIGIT(r, 7) ^= rm[3];
+ MP_DIGIT(r, 6) ^= rm[2];
+ MP_DIGIT(r, 5) ^= rm[1];
+ MP_DIGIT(r, 4) ^= rm[0];
+ MP_USED(r) = 14;
+ s_mp_clamp(r);
+#endif
+ return ec_GF2m_193_mod(r, r, meth);
+ }
+
+ CLEANUP:
+ return res;
+}
+
+/* Wire in fast field arithmetic for 193-bit curves. */
+mp_err
+ec_group_set_gf2m193(ECGroup *group, ECCurveName name)
+{
+ group->meth->field_mod = &ec_GF2m_193_mod;
+ group->meth->field_mul = &ec_GF2m_193_mul;
+ group->meth->field_sqr = &ec_GF2m_193_sqr;
+ return MP_OKAY;
+}
diff --git a/security/nss/lib/freebl/ecl/ec2_233.c b/security/nss/lib/freebl/ecl/ec2_233.c
new file mode 100644
index 000000000..719854229
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ec2_233.c
@@ -0,0 +1,298 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for binary polynomial
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ * Stephen Fung <fungstep@hotmail.com>, and
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ec2.h"
+#include "mp_gf2m.h"
+#include "mp_gf2m-priv.h"
+#include "mpi.h"
+#include "mpi-priv.h"
+#include <stdlib.h>
+
+/* Fast reduction for polynomials over a 233-bit curve. Assumes reduction
+ * polynomial with terms {233, 74, 0}. */
+mp_err
+ec_GF2m_233_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_digit *u, z;
+
+ if (a != r) {
+ MP_CHECKOK(mp_copy(a, r));
+ }
+#ifdef ECL_SIXTY_FOUR_BIT
+ if (MP_USED(r) < 8) {
+ MP_CHECKOK(s_mp_pad(r, 8));
+ }
+ u = MP_DIGITS(r);
+ MP_USED(r) = 8;
+
+ /* u[7] only has 18 significant bits */
+ z = u[7];
+ u[4] ^= (z << 33) ^ (z >> 41);
+ u[3] ^= (z << 23);
+ z = u[6];
+ u[4] ^= (z >> 31);
+ u[3] ^= (z << 33) ^ (z >> 41);
+ u[2] ^= (z << 23);
+ z = u[5];
+ u[3] ^= (z >> 31);
+ u[2] ^= (z << 33) ^ (z >> 41);
+ u[1] ^= (z << 23);
+ z = u[4];
+ u[2] ^= (z >> 31);
+ u[1] ^= (z << 33) ^ (z >> 41);
+ u[0] ^= (z << 23);
+ z = u[3] >> 41; /* z only has 23 significant bits */
+ u[1] ^= (z << 10);
+ u[0] ^= z;
+ /* clear bits above 233 */
+ u[7] = u[6] = u[5] = u[4] = 0;
+ u[3] ^= z << 41;
+#else
+ if (MP_USED(r) < 15) {
+ MP_CHECKOK(s_mp_pad(r, 15));
+ }
+ u = MP_DIGITS(r);
+ MP_USED(r) = 15;
+
+ /* u[14] only has 18 significant bits */
+ z = u[14];
+ u[9] ^= (z << 1);
+ u[7] ^= (z >> 9);
+ u[6] ^= (z << 23);
+ z = u[13];
+ u[9] ^= (z >> 31);
+ u[8] ^= (z << 1);
+ u[6] ^= (z >> 9);
+ u[5] ^= (z << 23);
+ z = u[12];
+ u[8] ^= (z >> 31);
+ u[7] ^= (z << 1);
+ u[5] ^= (z >> 9);
+ u[4] ^= (z << 23);
+ z = u[11];
+ u[7] ^= (z >> 31);
+ u[6] ^= (z << 1);
+ u[4] ^= (z >> 9);
+ u[3] ^= (z << 23);
+ z = u[10];
+ u[6] ^= (z >> 31);
+ u[5] ^= (z << 1);
+ u[3] ^= (z >> 9);
+ u[2] ^= (z << 23);
+ z = u[9];
+ u[5] ^= (z >> 31);
+ u[4] ^= (z << 1);
+ u[2] ^= (z >> 9);
+ u[1] ^= (z << 23);
+ z = u[8];
+ u[4] ^= (z >> 31);
+ u[3] ^= (z << 1);
+ u[1] ^= (z >> 9);
+ u[0] ^= (z << 23);
+ z = u[7] >> 9; /* z only has 23 significant bits */
+ u[3] ^= (z >> 22);
+ u[2] ^= (z << 10);
+ u[0] ^= z;
+ /* clear bits above 233 */
+ u[14] = u[13] = u[12] = u[11] = u[10] = u[9] = u[8] = 0;
+ u[7] ^= z << 9;
+#endif
+ s_mp_clamp(r);
+
+ CLEANUP:
+ return res;
+}
+
+/* Fast squaring for polynomials over a 233-bit curve. Assumes reduction
+ * polynomial with terms {233, 74, 0}. */
+mp_err
+ec_GF2m_233_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_digit *u, *v;
+
+ v = MP_DIGITS(a);
+
+#ifdef ECL_SIXTY_FOUR_BIT
+ if (MP_USED(a) < 4) {
+ return mp_bsqrmod(a, meth->irr_arr, r);
+ }
+ if (MP_USED(r) < 8) {
+ MP_CHECKOK(s_mp_pad(r, 8));
+ }
+ MP_USED(r) = 8;
+#else
+ if (MP_USED(a) < 8) {
+ return mp_bsqrmod(a, meth->irr_arr, r);
+ }
+ if (MP_USED(r) < 15) {
+ MP_CHECKOK(s_mp_pad(r, 15));
+ }
+ MP_USED(r) = 15;
+#endif
+ u = MP_DIGITS(r);
+
+#ifdef ECL_THIRTY_TWO_BIT
+ u[14] = gf2m_SQR0(v[7]);
+ u[13] = gf2m_SQR1(v[6]);
+ u[12] = gf2m_SQR0(v[6]);
+ u[11] = gf2m_SQR1(v[5]);
+ u[10] = gf2m_SQR0(v[5]);
+ u[9] = gf2m_SQR1(v[4]);
+ u[8] = gf2m_SQR0(v[4]);
+#endif
+ u[7] = gf2m_SQR1(v[3]);
+ u[6] = gf2m_SQR0(v[3]);
+ u[5] = gf2m_SQR1(v[2]);
+ u[4] = gf2m_SQR0(v[2]);
+ u[3] = gf2m_SQR1(v[1]);
+ u[2] = gf2m_SQR0(v[1]);
+ u[1] = gf2m_SQR1(v[0]);
+ u[0] = gf2m_SQR0(v[0]);
+ return ec_GF2m_233_mod(r, r, meth);
+
+ CLEANUP:
+ return res;
+}
+
+/* Fast multiplication for polynomials over a 233-bit curve. Assumes
+ * reduction polynomial with terms {233, 74, 0}. */
+mp_err
+ec_GF2m_233_mul(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
+
+#ifdef ECL_THIRTY_TWO_BIT
+ mp_digit a7 = 0, a6 = 0, a5 = 0, a4 = 0, b7 = 0, b6 = 0, b5 = 0, b4 =
+ 0;
+ mp_digit rm[8];
+#endif
+
+ if (a == b) {
+ return ec_GF2m_233_sqr(a, r, meth);
+ } else {
+ switch (MP_USED(a)) {
+#ifdef ECL_THIRTY_TWO_BIT
+ case 8:
+ a7 = MP_DIGIT(a, 7);
+ case 7:
+ a6 = MP_DIGIT(a, 6);
+ case 6:
+ a5 = MP_DIGIT(a, 5);
+ case 5:
+ a4 = MP_DIGIT(a, 4);
+#endif
+ case 4:
+ a3 = MP_DIGIT(a, 3);
+ case 3:
+ a2 = MP_DIGIT(a, 2);
+ case 2:
+ a1 = MP_DIGIT(a, 1);
+ default:
+ a0 = MP_DIGIT(a, 0);
+ }
+ switch (MP_USED(b)) {
+#ifdef ECL_THIRTY_TWO_BIT
+ case 8:
+ b7 = MP_DIGIT(b, 7);
+ case 7:
+ b6 = MP_DIGIT(b, 6);
+ case 6:
+ b5 = MP_DIGIT(b, 5);
+ case 5:
+ b4 = MP_DIGIT(b, 4);
+#endif
+ case 4:
+ b3 = MP_DIGIT(b, 3);
+ case 3:
+ b2 = MP_DIGIT(b, 2);
+ case 2:
+ b1 = MP_DIGIT(b, 1);
+ default:
+ b0 = MP_DIGIT(b, 0);
+ }
+#ifdef ECL_SIXTY_FOUR_BIT
+ MP_CHECKOK(s_mp_pad(r, 8));
+ s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
+ MP_USED(r) = 8;
+ s_mp_clamp(r);
+#else
+ MP_CHECKOK(s_mp_pad(r, 16));
+ s_bmul_4x4(MP_DIGITS(r) + 8, a7, a6, a5, a4, b7, b6, b5, b4);
+ s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
+ s_bmul_4x4(rm, a7 ^ a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b7 ^ b3,
+ b6 ^ b2, b5 ^ b1, b4 ^ b0);
+ rm[7] ^= MP_DIGIT(r, 7) ^ MP_DIGIT(r, 15);
+ rm[6] ^= MP_DIGIT(r, 6) ^ MP_DIGIT(r, 14);
+ rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
+ rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
+ rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
+ rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
+ rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
+ rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
+ MP_DIGIT(r, 11) ^= rm[7];
+ MP_DIGIT(r, 10) ^= rm[6];
+ MP_DIGIT(r, 9) ^= rm[5];
+ MP_DIGIT(r, 8) ^= rm[4];
+ MP_DIGIT(r, 7) ^= rm[3];
+ MP_DIGIT(r, 6) ^= rm[2];
+ MP_DIGIT(r, 5) ^= rm[1];
+ MP_DIGIT(r, 4) ^= rm[0];
+ MP_USED(r) = 16;
+ s_mp_clamp(r);
+#endif
+ return ec_GF2m_233_mod(r, r, meth);
+ }
+
+ CLEANUP:
+ return res;
+}
+
+/* Wire in fast field arithmetic for 233-bit curves. */
+mp_err
+ec_group_set_gf2m233(ECGroup *group, ECCurveName name)
+{
+ group->meth->field_mod = &ec_GF2m_233_mod;
+ group->meth->field_mul = &ec_GF2m_233_mul;
+ group->meth->field_sqr = &ec_GF2m_233_sqr;
+ return MP_OKAY;
+}
diff --git a/security/nss/lib/freebl/ecl/ec2_aff.c b/security/nss/lib/freebl/ecl/ec2_aff.c
new file mode 100644
index 000000000..5c7972c0c
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ec2_aff.c
@@ -0,0 +1,270 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for binary polynomial
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ec2.h"
+#include "mplogic.h"
+#include "mp_gf2m.h"
+#include <stdlib.h>
+
+/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
+mp_err
+ec_GF2m_pt_is_inf_aff(const mp_int *px, const mp_int *py)
+{
+
+ if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
+ return MP_YES;
+ } else {
+ return MP_NO;
+ }
+
+}
+
+/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
+mp_err
+ec_GF2m_pt_set_inf_aff(mp_int *px, mp_int *py)
+{
+ mp_zero(px);
+ mp_zero(py);
+ return MP_OKAY;
+}
+
+/* Computes R = P + Q based on IEEE P1363 A.10.2. Elliptic curve points P,
+ * Q, and R can all be identical. Uses affine coordinates. */
+mp_err
+ec_GF2m_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
+ const mp_int *qy, mp_int *rx, mp_int *ry,
+ const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int lambda, tempx, tempy;
+
+ MP_DIGITS(&lambda) = 0;
+ MP_DIGITS(&tempx) = 0;
+ MP_DIGITS(&tempy) = 0;
+ MP_CHECKOK(mp_init(&lambda));
+ MP_CHECKOK(mp_init(&tempx));
+ MP_CHECKOK(mp_init(&tempy));
+ /* if P = inf, then R = Q */
+ if (ec_GF2m_pt_is_inf_aff(px, py) == 0) {
+ MP_CHECKOK(mp_copy(qx, rx));
+ MP_CHECKOK(mp_copy(qy, ry));
+ res = MP_OKAY;
+ goto CLEANUP;
+ }
+ /* if Q = inf, then R = P */
+ if (ec_GF2m_pt_is_inf_aff(qx, qy) == 0) {
+ MP_CHECKOK(mp_copy(px, rx));
+ MP_CHECKOK(mp_copy(py, ry));
+ res = MP_OKAY;
+ goto CLEANUP;
+ }
+ /* if px != qx, then lambda = (py+qy) / (px+qx), tempx = a + lambda^2
+ * + lambda + px + qx */
+ if (mp_cmp(px, qx) != 0) {
+ MP_CHECKOK(group->meth->field_add(py, qy, &tempy, group->meth));
+ MP_CHECKOK(group->meth->field_add(px, qx, &tempx, group->meth));
+ MP_CHECKOK(group->meth->
+ field_div(&tempy, &tempx, &lambda, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
+ MP_CHECKOK(group->meth->
+ field_add(&tempx, &lambda, &tempx, group->meth));
+ MP_CHECKOK(group->meth->
+ field_add(&tempx, &group->curvea, &tempx, group->meth));
+ MP_CHECKOK(group->meth->
+ field_add(&tempx, px, &tempx, group->meth));
+ MP_CHECKOK(group->meth->
+ field_add(&tempx, qx, &tempx, group->meth));
+ } else {
+ /* if py != qy or qx = 0, then R = inf */
+ if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qx) == 0)) {
+ mp_zero(rx);
+ mp_zero(ry);
+ res = MP_OKAY;
+ goto CLEANUP;
+ }
+ /* lambda = qx + qy / qx */
+ MP_CHECKOK(group->meth->field_div(qy, qx, &lambda, group->meth));
+ MP_CHECKOK(group->meth->
+ field_add(&lambda, qx, &lambda, group->meth));
+ /* tempx = a + lambda^2 + lambda */
+ MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
+ MP_CHECKOK(group->meth->
+ field_add(&tempx, &lambda, &tempx, group->meth));
+ MP_CHECKOK(group->meth->
+ field_add(&tempx, &group->curvea, &tempx, group->meth));
+ }
+ /* ry = (qx + tempx) * lambda + tempx + qy */
+ MP_CHECKOK(group->meth->field_add(qx, &tempx, &tempy, group->meth));
+ MP_CHECKOK(group->meth->
+ field_mul(&tempy, &lambda, &tempy, group->meth));
+ MP_CHECKOK(group->meth->
+ field_add(&tempy, &tempx, &tempy, group->meth));
+ MP_CHECKOK(group->meth->field_add(&tempy, qy, ry, group->meth));
+ /* rx = tempx */
+ MP_CHECKOK(mp_copy(&tempx, rx));
+
+ CLEANUP:
+ mp_clear(&lambda);
+ mp_clear(&tempx);
+ mp_clear(&tempy);
+ return res;
+}
+
+/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
+ * identical. Uses affine coordinates. */
+mp_err
+ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
+ const mp_int *qy, mp_int *rx, mp_int *ry,
+ const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int nqy;
+
+ MP_DIGITS(&nqy) = 0;
+ MP_CHECKOK(mp_init(&nqy));
+ /* nqy = qx+qy */
+ MP_CHECKOK(group->meth->field_add(qx, qy, &nqy, group->meth));
+ MP_CHECKOK(group->point_add(px, py, qx, &nqy, rx, ry, group));
+ CLEANUP:
+ mp_clear(&nqy);
+ return res;
+}
+
+/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
+ * affine coordinates. */
+mp_err
+ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, const ECGroup *group)
+{
+ return group->point_add(px, py, px, py, rx, ry, group);
+}
+
+/* by default, this routine is unused and thus doesn't need to be compiled */
+#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
+/* Computes R = nP based on IEEE P1363 A.10.3. Elliptic curve points P and
+ * R can be identical. Uses affine coordinates. */
+mp_err
+ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
+ mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int k, k3, qx, qy, sx, sy;
+ int b1, b3, i, l;
+
+ MP_DIGITS(&k) = 0;
+ MP_DIGITS(&k3) = 0;
+ MP_DIGITS(&qx) = 0;
+ MP_DIGITS(&qy) = 0;
+ MP_DIGITS(&sx) = 0;
+ MP_DIGITS(&sy) = 0;
+ MP_CHECKOK(mp_init(&k));
+ MP_CHECKOK(mp_init(&k3));
+ MP_CHECKOK(mp_init(&qx));
+ MP_CHECKOK(mp_init(&qy));
+ MP_CHECKOK(mp_init(&sx));
+ MP_CHECKOK(mp_init(&sy));
+
+ /* if n = 0 then r = inf */
+ if (mp_cmp_z(n) == 0) {
+ mp_zero(rx);
+ mp_zero(ry);
+ res = MP_OKAY;
+ goto CLEANUP;
+ }
+ /* Q = P, k = n */
+ MP_CHECKOK(mp_copy(px, &qx));
+ MP_CHECKOK(mp_copy(py, &qy));
+ MP_CHECKOK(mp_copy(n, &k));
+ /* if n < 0 then Q = -Q, k = -k */
+ if (mp_cmp_z(n) < 0) {
+ MP_CHECKOK(group->meth->field_add(&qx, &qy, &qy, group->meth));
+ MP_CHECKOK(mp_neg(&k, &k));
+ }
+#ifdef ECL_DEBUG /* basic double and add method */
+ l = mpl_significant_bits(&k) - 1;
+ MP_CHECKOK(mp_copy(&qx, &sx));
+ MP_CHECKOK(mp_copy(&qy, &sy));
+ for (i = l - 1; i >= 0; i--) {
+ /* S = 2S */
+ MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
+ /* if k_i = 1, then S = S + Q */
+ if (mpl_get_bit(&k, i) != 0) {
+ MP_CHECKOK(group->
+ point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
+ }
+ }
+#else /* double and add/subtract method from
+ * standard */
+ /* k3 = 3 * k */
+ MP_CHECKOK(mp_set_int(&k3, 3));
+ MP_CHECKOK(mp_mul(&k, &k3, &k3));
+ /* S = Q */
+ MP_CHECKOK(mp_copy(&qx, &sx));
+ MP_CHECKOK(mp_copy(&qy, &sy));
+ /* l = index of high order bit in binary representation of 3*k */
+ l = mpl_significant_bits(&k3) - 1;
+ /* for i = l-1 downto 1 */
+ for (i = l - 1; i >= 1; i--) {
+ /* S = 2S */
+ MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
+ b3 = MP_GET_BIT(&k3, i);
+ b1 = MP_GET_BIT(&k, i);
+ /* if k3_i = 1 and k_i = 0, then S = S + Q */
+ if ((b3 == 1) && (b1 == 0)) {
+ MP_CHECKOK(group->
+ point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
+ /* if k3_i = 0 and k_i = 1, then S = S - Q */
+ } else if ((b3 == 0) && (b1 == 1)) {
+ MP_CHECKOK(group->
+ point_sub(&sx, &sy, &qx, &qy, &sx, &sy, group));
+ }
+ }
+#endif
+ /* output S */
+ MP_CHECKOK(mp_copy(&sx, rx));
+ MP_CHECKOK(mp_copy(&sy, ry));
+
+ CLEANUP:
+ mp_clear(&k);
+ mp_clear(&k3);
+ mp_clear(&qx);
+ mp_clear(&qy);
+ mp_clear(&sx);
+ mp_clear(&sy);
+ return res;
+}
+#endif
diff --git a/security/nss/lib/freebl/ecl/ec2_mont.c b/security/nss/lib/freebl/ecl/ec2_mont.c
new file mode 100644
index 000000000..6658d3295
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ec2_mont.c
@@ -0,0 +1,276 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for binary polynomial
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ * Stephen Fung <fungstep@hotmail.com>, and
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ec2.h"
+#include "mplogic.h"
+#include "mp_gf2m.h"
+#include <stdlib.h>
+
+/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery
+ * projective coordinates. Uses algorithm Mdouble in appendix of Lopez, J.
+ * and Dahab, R. "Fast multiplication on elliptic curves over GF(2^m)
+ * without precomputation". modified to not require precomputation of
+ * c=b^{2^{m-1}}. */
+static mp_err
+gf2m_Mdouble(mp_int *x, mp_int *z, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int t1;
+
+ MP_DIGITS(&t1) = 0;
+ MP_CHECKOK(mp_init(&t1));
+
+ MP_CHECKOK(group->meth->field_sqr(x, x, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(z, &t1, group->meth));
+ MP_CHECKOK(group->meth->field_mul(x, &t1, z, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(x, x, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(&t1, &t1, group->meth));
+ MP_CHECKOK(group->meth->
+ field_mul(&group->curveb, &t1, &t1, group->meth));
+ MP_CHECKOK(group->meth->field_add(x, &t1, x, group->meth));
+
+ CLEANUP:
+ mp_clear(&t1);
+ return res;
+}
+
+/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in
+ * Montgomery projective coordinates. Uses algorithm Madd in appendix of
+ * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
+ * GF(2^m) without precomputation". */
+static mp_err
+gf2m_Madd(const mp_int *x, mp_int *x1, mp_int *z1, mp_int *x2, mp_int *z2,
+ const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int t1, t2;
+
+ MP_DIGITS(&t1) = 0;
+ MP_DIGITS(&t2) = 0;
+ MP_CHECKOK(mp_init(&t1));
+ MP_CHECKOK(mp_init(&t2));
+
+ MP_CHECKOK(mp_copy(x, &t1));
+ MP_CHECKOK(group->meth->field_mul(x1, z2, x1, group->meth));
+ MP_CHECKOK(group->meth->field_mul(z1, x2, z1, group->meth));
+ MP_CHECKOK(group->meth->field_mul(x1, z1, &t2, group->meth));
+ MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(z1, z1, group->meth));
+ MP_CHECKOK(group->meth->field_mul(z1, &t1, x1, group->meth));
+ MP_CHECKOK(group->meth->field_add(x1, &t2, x1, group->meth));
+
+ CLEANUP:
+ mp_clear(&t1);
+ mp_clear(&t2);
+ return res;
+}
+
+/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
+ * using Montgomery point multiplication algorithm Mxy() in appendix of
+ * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
+ * GF(2^m) without precomputation". Returns: 0 on error 1 if return value
+ * should be the point at infinity 2 otherwise */
+static int
+gf2m_Mxy(const mp_int *x, const mp_int *y, mp_int *x1, mp_int *z1,
+ mp_int *x2, mp_int *z2, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ int ret = 0;
+ mp_int t3, t4, t5;
+
+ MP_DIGITS(&t3) = 0;
+ MP_DIGITS(&t4) = 0;
+ MP_DIGITS(&t5) = 0;
+ MP_CHECKOK(mp_init(&t3));
+ MP_CHECKOK(mp_init(&t4));
+ MP_CHECKOK(mp_init(&t5));
+
+ if (mp_cmp_z(z1) == 0) {
+ mp_zero(x2);
+ mp_zero(z2);
+ ret = 1;
+ goto CLEANUP;
+ }
+
+ if (mp_cmp_z(z2) == 0) {
+ MP_CHECKOK(mp_copy(x, x2));
+ MP_CHECKOK(group->meth->field_add(x, y, z2, group->meth));
+ ret = 2;
+ goto CLEANUP;
+ }
+
+ MP_CHECKOK(mp_set_int(&t5, 1));
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->field_enc(&t5, &t5, group->meth));
+ }
+
+ MP_CHECKOK(group->meth->field_mul(z1, z2, &t3, group->meth));
+
+ MP_CHECKOK(group->meth->field_mul(z1, x, z1, group->meth));
+ MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
+ MP_CHECKOK(group->meth->field_mul(z2, x, z2, group->meth));
+ MP_CHECKOK(group->meth->field_mul(z2, x1, x1, group->meth));
+ MP_CHECKOK(group->meth->field_add(z2, x2, z2, group->meth));
+
+ MP_CHECKOK(group->meth->field_mul(z2, z1, z2, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(x, &t4, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t4, y, &t4, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&t4, &t3, &t4, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t4, z2, &t4, group->meth));
+
+ MP_CHECKOK(group->meth->field_mul(&t3, x, &t3, group->meth));
+ MP_CHECKOK(group->meth->field_div(&t5, &t3, &t3, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&t3, &t4, &t4, group->meth));
+ MP_CHECKOK(group->meth->field_mul(x1, &t3, x2, group->meth));
+ MP_CHECKOK(group->meth->field_add(x2, x, z2, group->meth));
+
+ MP_CHECKOK(group->meth->field_mul(z2, &t4, z2, group->meth));
+ MP_CHECKOK(group->meth->field_add(z2, y, z2, group->meth));
+
+ ret = 2;
+
+ CLEANUP:
+ mp_clear(&t3);
+ mp_clear(&t4);
+ mp_clear(&t5);
+ if (res == MP_OKAY) {
+ return ret;
+ } else {
+ return 0;
+ }
+}
+
+/* Computes R = nP based on algorithm 2P of Lopex, J. and Dahab, R. "Fast
+ * multiplication on elliptic curves over GF(2^m) without
+ * precomputation". Elliptic curve points P and R can be identical. Uses
+ * Montgomery projective coordinates. */
+mp_err
+ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px, const mp_int *py,
+ mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int x1, x2, z1, z2;
+ int i, j;
+ mp_digit top_bit, mask;
+
+ MP_DIGITS(&x1) = 0;
+ MP_DIGITS(&x2) = 0;
+ MP_DIGITS(&z1) = 0;
+ MP_DIGITS(&z2) = 0;
+ MP_CHECKOK(mp_init(&x1));
+ MP_CHECKOK(mp_init(&x2));
+ MP_CHECKOK(mp_init(&z1));
+ MP_CHECKOK(mp_init(&z2));
+
+ /* if result should be point at infinity */
+ if ((mp_cmp_z(n) == 0) || (ec_GF2m_pt_is_inf_aff(px, py) == MP_YES)) {
+ MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
+ goto CLEANUP;
+ }
+
+ MP_CHECKOK(mp_copy(rx, &x2)); /* x2 = rx */
+ MP_CHECKOK(mp_copy(ry, &z2)); /* z2 = ry */
+
+ MP_CHECKOK(mp_copy(px, &x1)); /* x1 = px */
+ MP_CHECKOK(mp_set_int(&z1, 1)); /* z1 = 1 */
+ MP_CHECKOK(group->meth->field_sqr(&x1, &z2, group->meth)); /* z2 =
+ * x1^2 =
+ * x2^2 */
+ MP_CHECKOK(group->meth->field_sqr(&z2, &x2, group->meth));
+ MP_CHECKOK(group->meth->field_add(&x2, &group->curveb, &x2, group->meth)); /* x2
+ * =
+ * px^4
+ * +
+ * b
+ */
+
+ /* find top-most bit and go one past it */
+ i = MP_USED(n) - 1;
+ j = MP_DIGIT_BIT - 1;
+ top_bit = 1;
+ top_bit <<= MP_DIGIT_BIT - 1;
+ mask = top_bit;
+ while (!(MP_DIGITS(n)[i] & mask)) {
+ mask >>= 1;
+ j--;
+ }
+ mask >>= 1;
+ j--;
+
+ /* if top most bit was at word break, go to next word */
+ if (!mask) {
+ i--;
+ j = MP_DIGIT_BIT - 1;
+ mask = top_bit;
+ }
+
+ for (; i >= 0; i--) {
+ for (; j >= 0; j--) {
+ if (MP_DIGITS(n)[i] & mask) {
+ MP_CHECKOK(gf2m_Madd(px, &x1, &z1, &x2, &z2, group));
+ MP_CHECKOK(gf2m_Mdouble(&x2, &z2, group));
+ } else {
+ MP_CHECKOK(gf2m_Madd(px, &x2, &z2, &x1, &z1, group));
+ MP_CHECKOK(gf2m_Mdouble(&x1, &z1, group));
+ }
+ mask >>= 1;
+ }
+ j = MP_DIGIT_BIT - 1;
+ mask = top_bit;
+ }
+
+ /* convert out of "projective" coordinates */
+ i = gf2m_Mxy(px, py, &x1, &z1, &x2, &z2, group);
+ if (i == 0) {
+ res = MP_BADARG;
+ goto CLEANUP;
+ } else if (i == 1) {
+ MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
+ } else {
+ MP_CHECKOK(mp_copy(&x2, rx));
+ MP_CHECKOK(mp_copy(&z2, ry));
+ }
+
+ CLEANUP:
+ mp_clear(&x1);
+ mp_clear(&x2);
+ mp_clear(&z1);
+ mp_clear(&z2);
+ return res;
+}
diff --git a/security/nss/lib/freebl/ecl/ec2_proj.c b/security/nss/lib/freebl/ecl/ec2_proj.c
new file mode 100644
index 000000000..8df72433c
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ec2_proj.c
@@ -0,0 +1,368 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for binary polynomial
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ * Stephen Fung <fungstep@hotmail.com>, and
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ec2.h"
+#include "mplogic.h"
+#include "mp_gf2m.h"
+#include <stdlib.h>
+#ifdef ECL_DEBUG
+#include <assert.h>
+#endif
+
+/* by default, these routines are unused and thus don't need to be compiled */
+#ifdef ECL_ENABLE_GF2M_PROJ
+/* Converts a point P(px, py) from affine coordinates to projective
+ * coordinates R(rx, ry, rz). Assumes input is already field-encoded using
+ * field_enc, and returns output that is still field-encoded. */
+mp_err
+ec_GF2m_pt_aff2proj(const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, mp_int *rz, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+
+ MP_CHECKOK(mp_copy(px, rx));
+ MP_CHECKOK(mp_copy(py, ry));
+ MP_CHECKOK(mp_set_int(rz, 1));
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->field_enc(rz, rz, group->meth));
+ }
+ CLEANUP:
+ return res;
+}
+
+/* Converts a point P(px, py, pz) from projective coordinates to affine
+ * coordinates R(rx, ry). P and R can share x and y coordinates. Assumes
+ * input is already field-encoded using field_enc, and returns output that
+ * is still field-encoded. */
+mp_err
+ec_GF2m_pt_proj2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
+ mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int z1, z2;
+
+ MP_DIGITS(&z1) = 0;
+ MP_DIGITS(&z2) = 0;
+ MP_CHECKOK(mp_init(&z1));
+ MP_CHECKOK(mp_init(&z2));
+
+ /* if point at infinity, then set point at infinity and exit */
+ if (ec_GF2m_pt_is_inf_proj(px, py, pz) == MP_YES) {
+ MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
+ goto CLEANUP;
+ }
+
+ /* transform (px, py, pz) into (px / pz, py / pz^2) */
+ if (mp_cmp_d(pz, 1) == 0) {
+ MP_CHECKOK(mp_copy(px, rx));
+ MP_CHECKOK(mp_copy(py, ry));
+ } else {
+ MP_CHECKOK(group->meth->field_div(NULL, pz, &z1, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(&z1, &z2, group->meth));
+ MP_CHECKOK(group->meth->field_mul(px, &z1, rx, group->meth));
+ MP_CHECKOK(group->meth->field_mul(py, &z2, ry, group->meth));
+ }
+
+ CLEANUP:
+ mp_clear(&z1);
+ mp_clear(&z2);
+ return res;
+}
+
+/* Checks if point P(px, py, pz) is at infinity. Uses projective
+ * coordinates. */
+mp_err
+ec_GF2m_pt_is_inf_proj(const mp_int *px, const mp_int *py,
+ const mp_int *pz)
+{
+ return mp_cmp_z(pz);
+}
+
+/* Sets P(px, py, pz) to be the point at infinity. Uses projective
+ * coordinates. */
+mp_err
+ec_GF2m_pt_set_inf_proj(mp_int *px, mp_int *py, mp_int *pz)
+{
+ mp_zero(pz);
+ return MP_OKAY;
+}
+
+/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
+ * (qx, qy, 1). Elliptic curve points P, Q, and R can all be identical.
+ * Uses mixed projective-affine coordinates. Assumes input is already
+ * field-encoded using field_enc, and returns output that is still
+ * field-encoded. Uses equation (3) from Hankerson, Hernandez, Menezes.
+ * Software Implementation of Elliptic Curve Cryptography Over Binary
+ * Fields. */
+mp_err
+ec_GF2m_pt_add_proj(const mp_int *px, const mp_int *py, const mp_int *pz,
+ const mp_int *qx, const mp_int *qy, mp_int *rx,
+ mp_int *ry, mp_int *rz, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int A, B, C, D, E, F, G;
+
+ /* If either P or Q is the point at infinity, then return the other
+ * point */
+ if (ec_GF2m_pt_is_inf_proj(px, py, pz) == MP_YES) {
+ return ec_GF2m_pt_aff2proj(qx, qy, rx, ry, rz, group);
+ }
+ if (ec_GF2m_pt_is_inf_aff(qx, qy) == MP_YES) {
+ MP_CHECKOK(mp_copy(px, rx));
+ MP_CHECKOK(mp_copy(py, ry));
+ return mp_copy(pz, rz);
+ }
+
+ MP_DIGITS(&A) = 0;
+ MP_DIGITS(&B) = 0;
+ MP_DIGITS(&C) = 0;
+ MP_DIGITS(&D) = 0;
+ MP_DIGITS(&E) = 0;
+ MP_DIGITS(&F) = 0;
+ MP_DIGITS(&G) = 0;
+ MP_CHECKOK(mp_init(&A));
+ MP_CHECKOK(mp_init(&B));
+ MP_CHECKOK(mp_init(&C));
+ MP_CHECKOK(mp_init(&D));
+ MP_CHECKOK(mp_init(&E));
+ MP_CHECKOK(mp_init(&F));
+ MP_CHECKOK(mp_init(&G));
+
+ /* D = pz^2 */
+ MP_CHECKOK(group->meth->field_sqr(pz, &D, group->meth));
+
+ /* A = qy * pz^2 + py */
+ MP_CHECKOK(group->meth->field_mul(qy, &D, &A, group->meth));
+ MP_CHECKOK(group->meth->field_add(&A, py, &A, group->meth));
+
+ /* B = qx * pz + px */
+ MP_CHECKOK(group->meth->field_mul(qx, pz, &B, group->meth));
+ MP_CHECKOK(group->meth->field_add(&B, px, &B, group->meth));
+
+ /* C = pz * B */
+ MP_CHECKOK(group->meth->field_mul(pz, &B, &C, group->meth));
+
+ /* D = B^2 * (C + a * pz^2) (using E as a temporary variable) */
+ MP_CHECKOK(group->meth->
+ field_mul(&group->curvea, &D, &D, group->meth));
+ MP_CHECKOK(group->meth->field_add(&C, &D, &D, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(&B, &E, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&E, &D, &D, group->meth));
+
+ /* rz = C^2 */
+ MP_CHECKOK(group->meth->field_sqr(&C, rz, group->meth));
+
+ /* E = A * C */
+ MP_CHECKOK(group->meth->field_mul(&A, &C, &E, group->meth));
+
+ /* rx = A^2 + D + E */
+ MP_CHECKOK(group->meth->field_sqr(&A, rx, group->meth));
+ MP_CHECKOK(group->meth->field_add(rx, &D, rx, group->meth));
+ MP_CHECKOK(group->meth->field_add(rx, &E, rx, group->meth));
+
+ /* F = rx + qx * rz */
+ MP_CHECKOK(group->meth->field_mul(qx, rz, &F, group->meth));
+ MP_CHECKOK(group->meth->field_add(rx, &F, &F, group->meth));
+
+ /* G = rx + qy * rz */
+ MP_CHECKOK(group->meth->field_mul(qy, rz, &G, group->meth));
+ MP_CHECKOK(group->meth->field_add(rx, &G, &G, group->meth));
+
+ /* ry = E * F + rz * G (using G as a temporary variable) */
+ MP_CHECKOK(group->meth->field_mul(rz, &G, &G, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&E, &F, ry, group->meth));
+ MP_CHECKOK(group->meth->field_add(ry, &G, ry, group->meth));
+
+ CLEANUP:
+ mp_clear(&A);
+ mp_clear(&B);
+ mp_clear(&C);
+ mp_clear(&D);
+ mp_clear(&E);
+ mp_clear(&F);
+ mp_clear(&G);
+ return res;
+}
+
+/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
+ * projective coordinates.
+ *
+ * Assumes input is already field-encoded using field_enc, and returns
+ * output that is still field-encoded.
+ *
+ * Uses equation (3) from Hankerson, Hernandez, Menezes. Software
+ * Implementation of Elliptic Curve Cryptography Over Binary Fields.
+ */
+mp_err
+ec_GF2m_pt_dbl_proj(const mp_int *px, const mp_int *py, const mp_int *pz,
+ mp_int *rx, mp_int *ry, mp_int *rz,
+ const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int t0, t1;
+
+ if (ec_GF2m_pt_is_inf_proj(px, py, pz) == MP_YES) {
+ return ec_GF2m_pt_set_inf_proj(rx, ry, rz);
+ }
+
+ MP_DIGITS(&t0) = 0;
+ MP_DIGITS(&t1) = 0;
+ MP_CHECKOK(mp_init(&t0));
+ MP_CHECKOK(mp_init(&t1));
+
+ /* t0 = px^2 */
+ /* t1 = pz^2 */
+ MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(pz, &t1, group->meth));
+
+ /* rz = px^2 * pz^2 */
+ MP_CHECKOK(group->meth->field_mul(&t0, &t1, rz, group->meth));
+
+ /* t0 = px^4 */
+ /* t1 = b * pz^4 */
+ MP_CHECKOK(group->meth->field_sqr(&t0, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(&t1, &t1, group->meth));
+ MP_CHECKOK(group->meth->
+ field_mul(&group->curveb, &t1, &t1, group->meth));
+
+ /* rx = px^4 + b * pz^4 */
+ MP_CHECKOK(group->meth->field_add(&t0, &t1, rx, group->meth));
+
+ /* ry = b * pz^4 * rz + rx * (a * rz + py^2 + b * pz^4) */
+ MP_CHECKOK(group->meth->field_sqr(py, ry, group->meth));
+ MP_CHECKOK(group->meth->field_add(ry, &t1, ry, group->meth));
+ /* t0 = a * rz */
+ MP_CHECKOK(group->meth->
+ field_mul(&group->curvea, rz, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t0, ry, ry, group->meth));
+ MP_CHECKOK(group->meth->field_mul(rx, ry, ry, group->meth));
+ /* t1 = b * pz^4 * rz */
+ MP_CHECKOK(group->meth->field_mul(&t1, rz, &t1, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t1, ry, ry, group->meth));
+
+ CLEANUP:
+ mp_clear(&t0);
+ mp_clear(&t1);
+ return res;
+}
+
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GF2m. Elliptic curve points P and R can be
+ * identical. Uses mixed projective-affine coordinates. Assumes input is
+ * already field-encoded using field_enc, and returns output that is still
+ * field-encoded. Uses 4-bit window method. */
+mp_err
+ec_GF2m_pt_mul_proj(const mp_int *n, const mp_int *px, const mp_int *py,
+ mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int precomp[16][2], rz;
+ mp_digit precomp_arr[ECL_MAX_FIELD_SIZE_DIGITS * 16 * 2], *t;
+ int i, ni, d;
+
+ ARGCHK(group != NULL, MP_BADARG);
+ ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
+
+ /* initialize precomputation table */
+ t = precomp_arr;
+ for (i = 0; i < 16; i++) {
+ /* x co-ord */
+ MP_SIGN(&precomp[i][0]) = MP_ZPOS;
+ MP_ALLOC(&precomp[i][0]) = ECL_MAX_FIELD_SIZE_DIGITS;
+ MP_USED(&precomp[i][0]) = 1;
+ *t = 0;
+ MP_DIGITS(&precomp[i][0]) = t;
+ t += ECL_MAX_FIELD_SIZE_DIGITS;
+ /* y co-ord */
+ MP_SIGN(&precomp[i][1]) = MP_ZPOS;
+ MP_ALLOC(&precomp[i][1]) = ECL_MAX_FIELD_SIZE_DIGITS;
+ MP_USED(&precomp[i][1]) = 1;
+ *t = 0;
+ MP_DIGITS(&precomp[i][1]) = t;
+ t += ECL_MAX_FIELD_SIZE_DIGITS;
+ }
+
+ /* fill precomputation table */
+ mp_zero(&precomp[0][0]);
+ mp_zero(&precomp[0][1]);
+ MP_CHECKOK(mp_copy(px, &precomp[1][0]));
+ MP_CHECKOK(mp_copy(py, &precomp[1][1]));
+ for (i = 2; i < 16; i++) {
+ MP_CHECKOK(group->
+ point_add(&precomp[1][0], &precomp[1][1],
+ &precomp[i - 1][0], &precomp[i - 1][1],
+ &precomp[i][0], &precomp[i][1], group));
+ }
+
+ d = (mpl_significant_bits(n) + 3) / 4;
+
+ /* R = inf */
+ MP_DIGITS(&rz) = 0;
+ MP_CHECKOK(mp_init(&rz));
+ MP_CHECKOK(ec_GF2m_pt_set_inf_proj(rx, ry, &rz));
+
+ for (i = d - 1; i >= 0; i--) {
+ /* compute window ni */
+ ni = MP_GET_BIT(n, 4 * i + 3);
+ ni <<= 1;
+ ni |= MP_GET_BIT(n, 4 * i + 2);
+ ni <<= 1;
+ ni |= MP_GET_BIT(n, 4 * i + 1);
+ ni <<= 1;
+ ni |= MP_GET_BIT(n, 4 * i);
+ /* R = 2^4 * R */
+ MP_CHECKOK(ec_GF2m_pt_dbl_proj(rx, ry, &rz, rx, ry, &rz, group));
+ MP_CHECKOK(ec_GF2m_pt_dbl_proj(rx, ry, &rz, rx, ry, &rz, group));
+ MP_CHECKOK(ec_GF2m_pt_dbl_proj(rx, ry, &rz, rx, ry, &rz, group));
+ MP_CHECKOK(ec_GF2m_pt_dbl_proj(rx, ry, &rz, rx, ry, &rz, group));
+ /* R = R + (ni * P) */
+ MP_CHECKOK(ec_GF2m_pt_add_proj
+ (rx, ry, &rz, &precomp[ni][0], &precomp[ni][1], rx, ry,
+ &rz, group));
+ }
+
+ /* convert result S to affine coordinates */
+ MP_CHECKOK(ec_GF2m_pt_proj2aff(rx, ry, &rz, rx, ry, group));
+
+ CLEANUP:
+ mp_clear(&rz);
+ return res;
+}
+#endif
diff --git a/security/nss/lib/freebl/ecl/ec_naf.c b/security/nss/lib/freebl/ecl/ec_naf.c
new file mode 100644
index 000000000..a6b04add8
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ec_naf.c
@@ -0,0 +1,101 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecl-priv.h"
+
+/* Returns 2^e as an integer. This is meant to be used for small powers of
+ * two. */
+int
+ec_twoTo(int e)
+{
+ int a = 1;
+ int i;
+
+ for (i = 0; i < e; i++) {
+ a *= 2;
+ }
+ return a;
+}
+
+/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
+ * be an array of signed char's to output to, bitsize should be the number
+ * of bits of out, in is the original scalar, and w is the window size.
+ * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
+ * Menezes, "Software implementation of elliptic curve cryptography over
+ * binary fields", Proc. CHES 2000. */
+mp_err
+ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in, int w)
+{
+ mp_int k;
+ mp_err res = MP_OKAY;
+ int i, twowm1, mask;
+
+ twowm1 = ec_twoTo(w - 1);
+ mask = 2 * twowm1 - 1;
+
+ MP_DIGITS(&k) = 0;
+ MP_CHECKOK(mp_init_copy(&k, in));
+
+ i = 0;
+ /* Compute wNAF form */
+ while (mp_cmp_z(&k) > 0) {
+ if (mp_isodd(&k)) {
+ out[i] = MP_DIGIT(&k, 0) & mask;
+ if (out[i] >= twowm1)
+ out[i] -= 2 * twowm1;
+
+ /* Subtract off out[i]. Note mp_sub_d only works with
+ * unsigned digits */
+ if (out[i] >= 0) {
+ mp_sub_d(&k, out[i], &k);
+ } else {
+ mp_add_d(&k, -(out[i]), &k);
+ }
+ } else {
+ out[i] = 0;
+ }
+ mp_div_2(&k, &k);
+ i++;
+ }
+ /* Zero out the remaining elements of the out array. */
+ for (; i < bitsize + 1; i++) {
+ out[i] = 0;
+ }
+ CLEANUP:
+ mp_clear(&k);
+ return res;
+
+}
diff --git a/security/nss/lib/freebl/ecl/ecl-curve.h b/security/nss/lib/freebl/ecl/ecl-curve.h
new file mode 100644
index 000000000..5c03f3a84
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecl-curve.h
@@ -0,0 +1,646 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecl-exp.h"
+#include <stdlib.h>
+
+#ifndef __ecl_curve_h_
+#define __ecl_curve_h_
+
+/* NIST prime curves */
+static const ECCurveParams ecCurve_NIST_P192 = {
+ "NIST-P192", ECField_GFp, 192,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+ "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
+ "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
+ "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", 1
+};
+static const ECCurveParams ecCurve_NIST_P224 = {
+ "NIST-P224", ECField_GFp, 224,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
+ "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
+ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1
+};
+static const ECCurveParams ecCurve_NIST_P256 = {
+ "NIST-P256", ECField_GFp, 256,
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 1
+};
+static const ECCurveParams ecCurve_NIST_P384 = {
+ "NIST-P384", ECField_GFp, 384,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
+ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
+ 1
+};
+static const ECCurveParams ecCurve_NIST_P521 = {
+ "NIST-P521", ECField_GFp, 521,
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
+ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
+ 1
+};
+
+/* NIST binary curves */
+static const ECCurveParams ecCurve_NIST_K163 = {
+ "NIST-K163", ECField_GF2m, 163,
+ "0800000000000000000000000000000000000000C9",
+ "000000000000000000000000000000000000000001",
+ "000000000000000000000000000000000000000001",
+ "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
+ "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
+ "04000000000000000000020108A2E0CC0D99F8A5EF", 2
+};
+static const ECCurveParams ecCurve_NIST_B163 = {
+ "NIST-B163", ECField_GF2m, 163,
+ "0800000000000000000000000000000000000000C9",
+ "000000000000000000000000000000000000000001",
+ "020A601907B8C953CA1481EB10512F78744A3205FD",
+ "03F0EBA16286A2D57EA0991168D4994637E8343E36",
+ "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
+ "040000000000000000000292FE77E70C12A4234C33", 2
+};
+static const ECCurveParams ecCurve_NIST_K233 = {
+ "NIST-K233", ECField_GF2m, 233,
+ "020000000000000000000000000000000000000004000000000000000001",
+ "000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000000000000000000000000000000000000001",
+ "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
+ "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
+ "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4
+};
+static const ECCurveParams ecCurve_NIST_B233 = {
+ "NIST-B233", ECField_GF2m, 233,
+ "020000000000000000000000000000000000000004000000000000000001",
+ "000000000000000000000000000000000000000000000000000000000001",
+ "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
+ "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
+ "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
+ "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2
+};
+static const ECCurveParams ecCurve_NIST_K283 = {
+ "NIST-K283", ECField_GF2m, 283,
+ "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+ "000000000000000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000000000000000000000000000000000000000000000000001",
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
+ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
+ 4
+};
+static const ECCurveParams ecCurve_NIST_B283 = {
+ "NIST-B283", ECField_GF2m, 283,
+ "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+ "000000000000000000000000000000000000000000000000000000000000000000000001",
+ "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
+ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
+ "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
+ 2
+};
+static const ECCurveParams ecCurve_NIST_K409 = {
+ "NIST-K409", ECField_GF2m, 409,
+ "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
+ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
+ "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
+ 4
+};
+static const ECCurveParams ecCurve_NIST_B409 = {
+ "NIST-B409", ECField_GF2m, 409,
+ "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
+ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
+ "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
+ 2
+};
+static const ECCurveParams ecCurve_NIST_K571 = {
+ "NIST-K571", ECField_GF2m, 571,
+ "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
+ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
+ "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
+ 4
+};
+static const ECCurveParams ecCurve_NIST_B571 = {
+ "NIST-B571", ECField_GF2m, 571,
+ "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
+ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
+ "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
+ 2
+};
+
+/* ANSI X9.62 prime curves */
+static const ECCurveParams ecCurve_X9_62_PRIME_192V2 = {
+ "X9.62 P-192V2", ECField_GFp, 192,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+ "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
+ "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
+ "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
+ "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", 1
+};
+static const ECCurveParams ecCurve_X9_62_PRIME_192V3 = {
+ "X9.62 P-192V3", ECField_GFp, 192,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+ "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
+ "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
+ "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
+ "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", 1
+};
+static const ECCurveParams ecCurve_X9_62_PRIME_239V1 = {
+ "X9.62 P-239V1", ECField_GFp, 239,
+ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+ "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
+ "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
+ "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
+ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", 1
+};
+static const ECCurveParams ecCurve_X9_62_PRIME_239V2 = {
+ "X9.62 P-239V2", ECField_GFp, 239,
+ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+ "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
+ "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
+ "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
+ "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", 1
+};
+static const ECCurveParams ecCurve_X9_62_PRIME_239V3 = {
+ "X9.62 P-239V3", ECField_GFp, 239,
+ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+ "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
+ "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
+ "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
+ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", 1
+};
+
+/* ANSI X9.62 binary curves */
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V1 = {
+ "X9.62 C2-PNB163V1", ECField_GF2m, 163,
+ "080000000000000000000000000000000000000107",
+ "072546B5435234A422E0789675F432C89435DE5242",
+ "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9",
+ "07AF69989546103D79329FCC3D74880F33BBE803CB",
+ "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F",
+ "0400000000000000000001E60FC8821CC74DAEAFC1", 2
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V2 = {
+ "X9.62 C2-PNB163V2", ECField_GF2m, 163,
+ "080000000000000000000000000000000000000107",
+ "0108B39E77C4B108BED981ED0E890E117C511CF072",
+ "0667ACEB38AF4E488C407433FFAE4F1C811638DF20",
+ "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5",
+ "079F684DDF6684C5CD258B3890021B2386DFD19FC5",
+ "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V3 = {
+ "X9.62 C2-PNB163V3", ECField_GF2m, 163,
+ "080000000000000000000000000000000000000107",
+ "07A526C63D3E25A256A007699F5447E32AE456B50E",
+ "03F7061798EB99E238FD6F1BF95B48FEEB4854252B",
+ "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB",
+ "05B935590C155E17EA48EB3FF3718B893DF59A05D0",
+ "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB176V1 = {
+ "X9.62 C2-PNB176V1", ECField_GF2m, 176,
+ "0100000000000000000000000000000000080000000007",
+ "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B",
+ "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2",
+ "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798",
+ "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C",
+ "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V1 = {
+ "X9.62 C2-TNB191V1", ECField_GF2m, 191,
+ "800000000000000000000000000000000000000000000201",
+ "2866537B676752636A68F56554E12640276B649EF7526267",
+ "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC",
+ "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D",
+ "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB",
+ "40000000000000000000000004A20E90C39067C893BBB9A5", 2
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V2 = {
+ "X9.62 C2-TNB191V2", ECField_GF2m, 191,
+ "800000000000000000000000000000000000000000000201",
+ "401028774D7777C7B7666D1366EA432071274F89FF01E718",
+ "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01",
+ "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10",
+ "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A",
+ "20000000000000000000000050508CB89F652824E06B8173", 4
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V3 = {
+ "X9.62 C2-TNB191V3", ECField_GF2m, 191,
+ "800000000000000000000000000000000000000000000201",
+ "6C01074756099122221056911C77D77E77A777E7E7E77FCB",
+ "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8",
+ "375D4CE24FDE434489DE8746E71786015009E66E38A926DD",
+ "545A39176196575D985999366E6AD34CE0A77CD7127B06BE",
+ "155555555555555555555555610C0B196812BFB6288A3EA3", 6
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB208W1 = {
+ "X9.62 C2-PNB208W1", ECField_GF2m, 208,
+ "010000000000000000000000000000000800000000000000000007",
+ "0000000000000000000000000000000000000000000000000000",
+ "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E",
+ "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A",
+ "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3",
+ "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V1 = {
+ "X9.62 C2-TNB239V1", ECField_GF2m, 239,
+ "800000000000000000000000000000000000000000000000001000000001",
+ "32010857077C5431123A46B808906756F543423E8D27877578125778AC76",
+ "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16",
+ "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D",
+ "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305",
+ "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V2 = {
+ "X9.62 C2-TNB239V2", ECField_GF2m, 239,
+ "800000000000000000000000000000000000000000000000001000000001",
+ "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F",
+ "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B",
+ "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205",
+ "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833",
+ "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V3 = {
+ "X9.62 C2-TNB239V3", ECField_GF2m, 239,
+ "800000000000000000000000000000000000000000000000001000000001",
+ "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F",
+ "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40",
+ "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92",
+ "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461",
+ "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB272W1 = {
+ "X9.62 C2-PNB272W1", ECField_GF2m, 272,
+ "010000000000000000000000000000000000000000000000000000010000000000000B",
+ "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20",
+ "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7",
+ "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D",
+ "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23",
+ "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521",
+ 0xFF06
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB304W1 = {
+ "X9.62 C2-PNB304W1", ECField_GF2m, 304,
+ "010000000000000000000000000000000000000000000000000000000000000000000000000807",
+ "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681",
+ "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE",
+ "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614",
+ "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B",
+ "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D",
+ 0xFE2E
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB359V1 = {
+ "X9.62 C2-TNB359V1", ECField_GF2m, 359,
+ "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001",
+ "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557",
+ "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988",
+ "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097",
+ "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD",
+ "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B",
+ 0x4C
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_PNB368W1 = {
+ "X9.62 C2-PNB368W1", ECField_GF2m, 368,
+ "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007",
+ "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D",
+ "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A",
+ "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F",
+ "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310",
+ "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967",
+ 0xFF70
+};
+static const ECCurveParams ecCurve_X9_62_CHAR2_TNB431R1 = {
+ "X9.62 C2-TNB431R1", ECField_GF2m, 431,
+ "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001",
+ "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F",
+ "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618",
+ "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7",
+ "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760",
+ "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91",
+ 0x2760
+};
+
+/* SEC2 prime curves */
+static const ECCurveParams ecCurve_SECG_PRIME_112R1 = {
+ "SECP-112R1", ECField_GFp, 112,
+ "DB7C2ABF62E35E668076BEAD208B",
+ "DB7C2ABF62E35E668076BEAD2088",
+ "659EF8BA043916EEDE8911702B22",
+ "09487239995A5EE76B55F9C2F098",
+ "A89CE5AF8724C0A23E0E0FF77500",
+ "DB7C2ABF62E35E7628DFAC6561C5", 1
+};
+static const ECCurveParams ecCurve_SECG_PRIME_112R2 = {
+ "SECP-112R2", ECField_GFp, 112,
+ "DB7C2ABF62E35E668076BEAD208B",
+ "6127C24C05F38A0AAAF65C0EF02C",
+ "51DEF1815DB5ED74FCC34C85D709",
+ "4BA30AB5E892B4E1649DD0928643",
+ "adcd46f5882e3747def36e956e97",
+ "36DF0AAFD8B8D7597CA10520D04B", 4
+};
+static const ECCurveParams ecCurve_SECG_PRIME_128R1 = {
+ "SECP-128R1", ECField_GFp, 128,
+ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
+ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
+ "E87579C11079F43DD824993C2CEE5ED3",
+ "161FF7528B899B2D0C28607CA52C5B86",
+ "CF5AC8395BAFEB13C02DA292DDED7A83",
+ "FFFFFFFE0000000075A30D1B9038A115", 1
+};
+static const ECCurveParams ecCurve_SECG_PRIME_128R2 = {
+ "SECP-128R2", ECField_GFp, 128,
+ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
+ "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
+ "5EEEFCA380D02919DC2C6558BB6D8A5D",
+ "7B6AA5D85E572983E6FB32A7CDEBC140",
+ "27B6916A894D3AEE7106FE805FC34B44",
+ "3FFFFFFF7FFFFFFFBE0024720613B5A3", 4
+};
+static const ECCurveParams ecCurve_SECG_PRIME_160K1 = {
+ "SECP-160K1", ECField_GFp, 160,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
+ "0000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000007",
+ "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
+ "938CF935318FDCED6BC28286531733C3F03C4FEE",
+ "0100000000000000000001B8FA16DFAB9ACA16B6B3", 1
+};
+static const ECCurveParams ecCurve_SECG_PRIME_160R1 = {
+ "SECP-160R1", ECField_GFp, 160,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
+ "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
+ "4A96B5688EF573284664698968C38BB913CBFC82",
+ "23A628553168947D59DCC912042351377AC5FB32",
+ "0100000000000000000001F4C8F927AED3CA752257", 1
+};
+static const ECCurveParams ecCurve_SECG_PRIME_160R2 = {
+ "SECP-160R2", ECField_GFp, 160,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
+ "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
+ "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
+ "0100000000000000000000351EE786A818F3A1A16B", 1
+};
+static const ECCurveParams ecCurve_SECG_PRIME_192K1 = {
+ "SECP-192K1", ECField_GFp, 192,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
+ "000000000000000000000000000000000000000000000000",
+ "000000000000000000000000000000000000000000000003",
+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
+ "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
+ "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 1
+};
+static const ECCurveParams ecCurve_SECG_PRIME_224K1 = {
+ "SECP-224K1", ECField_GFp, 224,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
+ "00000000000000000000000000000000000000000000000000000000",
+ "00000000000000000000000000000000000000000000000000000005",
+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
+ "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
+ "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 1
+};
+static const ECCurveParams ecCurve_SECG_PRIME_256K1 = {
+ "SECP-256K1", ECField_GFp, 256,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000007",
+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
+ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 1
+};
+
+/* SEC2 binary curves */
+static const ECCurveParams ecCurve_SECG_CHAR2_113R1 = {
+ "SECT-113R1", ECField_GF2m, 113,
+ "020000000000000000000000000201",
+ "003088250CA6E7C7FE649CE85820F7",
+ "00E8BEE4D3E2260744188BE0E9C723",
+ "009D73616F35F4AB1407D73562C10F",
+ "00A52830277958EE84D1315ED31886",
+ "0100000000000000D9CCEC8A39E56F", 2
+};
+static const ECCurveParams ecCurve_SECG_CHAR2_113R2 = {
+ "SECT-113R2", ECField_GF2m, 113,
+ "020000000000000000000000000201",
+ "00689918DBEC7E5A0DD6DFC0AA55C7",
+ "0095E9A9EC9B297BD4BF36E059184F",
+ "01A57A6A7B26CA5EF52FCDB8164797",
+ "00B3ADC94ED1FE674C06E695BABA1D",
+ "010000000000000108789B2496AF93", 2
+};
+static const ECCurveParams ecCurve_SECG_CHAR2_131R1 = {
+ "SECT-131R1", ECField_GF2m, 131,
+ "080000000000000000000000000000010D",
+ "07A11B09A76B562144418FF3FF8C2570B8",
+ "0217C05610884B63B9C6C7291678F9D341",
+ "0081BAF91FDF9833C40F9C181343638399",
+ "078C6E7EA38C001F73C8134B1B4EF9E150",
+ "0400000000000000023123953A9464B54D", 2
+};
+static const ECCurveParams ecCurve_SECG_CHAR2_131R2 = {
+ "SECT-131R2", ECField_GF2m, 131,
+ "080000000000000000000000000000010D",
+ "03E5A88919D7CAFCBF415F07C2176573B2",
+ "04B8266A46C55657AC734CE38F018F2192",
+ "0356DCD8F2F95031AD652D23951BB366A8",
+ "0648F06D867940A5366D9E265DE9EB240F",
+ "0400000000000000016954A233049BA98F", 2
+};
+static const ECCurveParams ecCurve_SECG_CHAR2_163R1 = {
+ "SECT-163R1", ECField_GF2m, 163,
+ "0800000000000000000000000000000000000000C9",
+ "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
+ "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
+ "0369979697AB43897789566789567F787A7876A654",
+ "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
+ "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2
+};
+static const ECCurveParams ecCurve_SECG_CHAR2_193R1 = {
+ "SECT-193R1", ECField_GF2m, 193,
+ "02000000000000000000000000000000000000000000008001",
+ "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
+ "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
+ "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1",
+ "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
+ "01000000000000000000000000C7F34A778F443ACC920EBA49", 2
+};
+static const ECCurveParams ecCurve_SECG_CHAR2_193R2 = {
+ "SECT-193R2", ECField_GF2m, 193,
+ "02000000000000000000000000000000000000000000008001",
+ "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
+ "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
+ "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F",
+ "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
+ "010000000000000000000000015AAB561B005413CCD4EE99D5", 2
+};
+static const ECCurveParams ecCurve_SECG_CHAR2_239K1 = {
+ "SECT-239K1", ECField_GF2m, 239,
+ "800000000000000000004000000000000000000000000000000000000001",
+ "000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000000000000000000000000000000000000001",
+ "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC",
+ "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
+ "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4
+};
+
+/* WTLS curves */
+static const ECCurveParams ecCurve_WTLS_1 = {
+ "WTLS-1", ECField_GF2m, 113,
+ "020000000000000000000000000201",
+ "000000000000000000000000000001",
+ "000000000000000000000000000001",
+ "01667979A40BA497E5D5C270780617",
+ "00F44B4AF1ECC2630E08785CEBCC15",
+ "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2
+};
+static const ECCurveParams ecCurve_WTLS_8 = {
+ "WTLS-8", ECField_GFp, 112,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFDE7",
+ "0000000000000000000000000000",
+ "0000000000000000000000000003",
+ "0000000000000000000000000001",
+ "0000000000000000000000000002",
+ "0100000000000001ECEA551AD837E9", 1
+};
+static const ECCurveParams ecCurve_WTLS_9 = {
+ "WTLS-9", ECField_GFp, 160,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",
+ "0000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000003",
+ "0000000000000000000000000000000000000001",
+ "0000000000000000000000000000000000000002",
+ "0100000000000000000001CDC98AE0E2DE574ABF33", 1
+};
+
+/* mapping between ECCurveName enum and pointers to ECCurveParams */
+static const ECCurveParams *ecCurve_map[] = {
+ NULL, /* ECCurve_noName */
+ &ecCurve_NIST_P192, /* ECCurve_NIST_P192 */
+ &ecCurve_NIST_P224, /* ECCurve_NIST_P224 */
+ &ecCurve_NIST_P256, /* ECCurve_NIST_P256 */
+ &ecCurve_NIST_P384, /* ECCurve_NIST_P384 */
+ &ecCurve_NIST_P521, /* ECCurve_NIST_P521 */
+ &ecCurve_NIST_K163, /* ECCurve_NIST_K163 */
+ &ecCurve_NIST_B163, /* ECCurve_NIST_B163 */
+ &ecCurve_NIST_K233, /* ECCurve_NIST_K233 */
+ &ecCurve_NIST_B233, /* ECCurve_NIST_B233 */
+ &ecCurve_NIST_K283, /* ECCurve_NIST_K283 */
+ &ecCurve_NIST_B283, /* ECCurve_NIST_B283 */
+ &ecCurve_NIST_K409, /* ECCurve_NIST_K409 */
+ &ecCurve_NIST_B409, /* ECCurve_NIST_B409 */
+ &ecCurve_NIST_K571, /* ECCurve_NIST_K571 */
+ &ecCurve_NIST_B571, /* ECCurve_NIST_B571 */
+ &ecCurve_X9_62_PRIME_192V2, /* ECCurve_X9_62_PRIME_192V2 */
+ &ecCurve_X9_62_PRIME_192V3, /* ECCurve_X9_62_PRIME_192V3 */
+ &ecCurve_X9_62_PRIME_239V1, /* ECCurve_X9_62_PRIME_239V1 */
+ &ecCurve_X9_62_PRIME_239V2, /* ECCurve_X9_62_PRIME_239V2 */
+ &ecCurve_X9_62_PRIME_239V3, /* ECCurve_X9_62_PRIME_239V3 */
+ &ecCurve_X9_62_CHAR2_PNB163V1, /* ECCurve_X9_62_CHAR2_PNB163V1 */
+ &ecCurve_X9_62_CHAR2_PNB163V2, /* ECCurve_X9_62_CHAR2_PNB163V2 */
+ &ecCurve_X9_62_CHAR2_PNB163V3, /* ECCurve_X9_62_CHAR2_PNB163V3 */
+ &ecCurve_X9_62_CHAR2_PNB176V1, /* ECCurve_X9_62_CHAR2_PNB176V1 */
+ &ecCurve_X9_62_CHAR2_TNB191V1, /* ECCurve_X9_62_CHAR2_TNB191V1 */
+ &ecCurve_X9_62_CHAR2_TNB191V2, /* ECCurve_X9_62_CHAR2_TNB191V2 */
+ &ecCurve_X9_62_CHAR2_TNB191V3, /* ECCurve_X9_62_CHAR2_TNB191V3 */
+ &ecCurve_X9_62_CHAR2_PNB208W1, /* ECCurve_X9_62_CHAR2_PNB208W1 */
+ &ecCurve_X9_62_CHAR2_TNB239V1, /* ECCurve_X9_62_CHAR2_TNB239V1 */
+ &ecCurve_X9_62_CHAR2_TNB239V2, /* ECCurve_X9_62_CHAR2_TNB239V2 */
+ &ecCurve_X9_62_CHAR2_TNB239V3, /* ECCurve_X9_62_CHAR2_TNB239V3 */
+ &ecCurve_X9_62_CHAR2_PNB272W1, /* ECCurve_X9_62_CHAR2_PNB272W1 */
+ &ecCurve_X9_62_CHAR2_PNB304W1, /* ECCurve_X9_62_CHAR2_PNB304W1 */
+ &ecCurve_X9_62_CHAR2_TNB359V1, /* ECCurve_X9_62_CHAR2_TNB359V1 */
+ &ecCurve_X9_62_CHAR2_PNB368W1, /* ECCurve_X9_62_CHAR2_PNB368W1 */
+ &ecCurve_X9_62_CHAR2_TNB431R1, /* ECCurve_X9_62_CHAR2_TNB431R1 */
+ &ecCurve_SECG_PRIME_112R1, /* ECCurve_SECG_PRIME_112R1 */
+ &ecCurve_SECG_PRIME_112R2, /* ECCurve_SECG_PRIME_112R2 */
+ &ecCurve_SECG_PRIME_128R1, /* ECCurve_SECG_PRIME_128R1 */
+ &ecCurve_SECG_PRIME_128R2, /* ECCurve_SECG_PRIME_128R2 */
+ &ecCurve_SECG_PRIME_160K1, /* ECCurve_SECG_PRIME_160K1 */
+ &ecCurve_SECG_PRIME_160R1, /* ECCurve_SECG_PRIME_160R1 */
+ &ecCurve_SECG_PRIME_160R2, /* ECCurve_SECG_PRIME_160R2 */
+ &ecCurve_SECG_PRIME_192K1, /* ECCurve_SECG_PRIME_192K1 */
+ &ecCurve_SECG_PRIME_224K1, /* ECCurve_SECG_PRIME_224K1 */
+ &ecCurve_SECG_PRIME_256K1, /* ECCurve_SECG_PRIME_256K1 */
+ &ecCurve_SECG_CHAR2_113R1, /* ECCurve_SECG_CHAR2_113R1 */
+ &ecCurve_SECG_CHAR2_113R2, /* ECCurve_SECG_CHAR2_113R2 */
+ &ecCurve_SECG_CHAR2_131R1, /* ECCurve_SECG_CHAR2_131R1 */
+ &ecCurve_SECG_CHAR2_131R2, /* ECCurve_SECG_CHAR2_131R2 */
+ &ecCurve_SECG_CHAR2_163R1, /* ECCurve_SECG_CHAR2_163R1 */
+ &ecCurve_SECG_CHAR2_193R1, /* ECCurve_SECG_CHAR2_193R1 */
+ &ecCurve_SECG_CHAR2_193R2, /* ECCurve_SECG_CHAR2_193R2 */
+ &ecCurve_SECG_CHAR2_239K1, /* ECCurve_SECG_CHAR2_239K1 */
+ &ecCurve_WTLS_1, /* ECCurve_WTLS_1 */
+ &ecCurve_WTLS_8, /* ECCurve_WTLS_8 */
+ &ecCurve_WTLS_9, /* ECCurve_WTLS_9 */
+ NULL /* ECCurve_pastLastCurve */
+};
+
+#endif
diff --git a/security/nss/lib/freebl/ecl/ecl-exp.h b/security/nss/lib/freebl/ecl/ecl-exp.h
new file mode 100644
index 000000000..1a3421c81
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecl-exp.h
@@ -0,0 +1,194 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#ifndef __ecl_exp_h_
+#define __ecl_exp_h_
+
+/* Curve field type */
+typedef enum {
+ ECField_GFp,
+ ECField_GF2m
+} ECField;
+
+/* Hexadecimal encoding of curve parameters */
+struct ECCurveParamsStr {
+ char *text;
+ ECField field;
+ unsigned int size;
+ char *irr;
+ char *curvea;
+ char *curveb;
+ char *genx;
+ char *geny;
+ char *order;
+ int cofactor;
+};
+typedef struct ECCurveParamsStr ECCurveParams;
+
+/* Named curve parameters */
+typedef enum {
+
+ ECCurve_noName = 0,
+
+ /* NIST prime curves */
+ ECCurve_NIST_P192,
+ ECCurve_NIST_P224,
+ ECCurve_NIST_P256,
+ ECCurve_NIST_P384,
+ ECCurve_NIST_P521,
+
+ /* NIST binary curves */
+ ECCurve_NIST_K163,
+ ECCurve_NIST_B163,
+ ECCurve_NIST_K233,
+ ECCurve_NIST_B233,
+ ECCurve_NIST_K283,
+ ECCurve_NIST_B283,
+ ECCurve_NIST_K409,
+ ECCurve_NIST_B409,
+ ECCurve_NIST_K571,
+ ECCurve_NIST_B571,
+
+ /* ANSI X9.62 prime curves */
+ /* ECCurve_X9_62_PRIME_192V1 == ECCurve_NIST_P192 */
+ ECCurve_X9_62_PRIME_192V2,
+ ECCurve_X9_62_PRIME_192V3,
+ ECCurve_X9_62_PRIME_239V1,
+ ECCurve_X9_62_PRIME_239V2,
+ ECCurve_X9_62_PRIME_239V3,
+ /* ECCurve_X9_62_PRIME_256V1 == ECCurve_NIST_P256 */
+
+ /* ANSI X9.62 binary curves */
+ ECCurve_X9_62_CHAR2_PNB163V1,
+ ECCurve_X9_62_CHAR2_PNB163V2,
+ ECCurve_X9_62_CHAR2_PNB163V3,
+ ECCurve_X9_62_CHAR2_PNB176V1,
+ ECCurve_X9_62_CHAR2_TNB191V1,
+ ECCurve_X9_62_CHAR2_TNB191V2,
+ ECCurve_X9_62_CHAR2_TNB191V3,
+ ECCurve_X9_62_CHAR2_PNB208W1,
+ ECCurve_X9_62_CHAR2_TNB239V1,
+ ECCurve_X9_62_CHAR2_TNB239V2,
+ ECCurve_X9_62_CHAR2_TNB239V3,
+ ECCurve_X9_62_CHAR2_PNB272W1,
+ ECCurve_X9_62_CHAR2_PNB304W1,
+ ECCurve_X9_62_CHAR2_TNB359V1,
+ ECCurve_X9_62_CHAR2_PNB368W1,
+ ECCurve_X9_62_CHAR2_TNB431R1,
+
+ /* SEC2 prime curves */
+ ECCurve_SECG_PRIME_112R1,
+ ECCurve_SECG_PRIME_112R2,
+ ECCurve_SECG_PRIME_128R1,
+ ECCurve_SECG_PRIME_128R2,
+ ECCurve_SECG_PRIME_160K1,
+ ECCurve_SECG_PRIME_160R1,
+ ECCurve_SECG_PRIME_160R2,
+ ECCurve_SECG_PRIME_192K1,
+ /* ECCurve_SECG_PRIME_192R1 == ECCurve_NIST_P192 */
+ ECCurve_SECG_PRIME_224K1,
+ /* ECCurve_SECG_PRIME_224R1 == ECCurve_NIST_P224 */
+ ECCurve_SECG_PRIME_256K1,
+ /* ECCurve_SECG_PRIME_256R1 == ECCurve_NIST_P256 */
+ /* ECCurve_SECG_PRIME_384R1 == ECCurve_NIST_P384 */
+ /* ECCurve_SECG_PRIME_521R1 == ECCurve_NIST_P521 */
+
+ /* SEC2 binary curves */
+ ECCurve_SECG_CHAR2_113R1,
+ ECCurve_SECG_CHAR2_113R2,
+ ECCurve_SECG_CHAR2_131R1,
+ ECCurve_SECG_CHAR2_131R2,
+ /* ECCurve_SECG_CHAR2_163K1 == ECCurve_NIST_K163 */
+ ECCurve_SECG_CHAR2_163R1,
+ /* ECCurve_SECG_CHAR2_163R2 == ECCurve_NIST_B163 */
+ ECCurve_SECG_CHAR2_193R1,
+ ECCurve_SECG_CHAR2_193R2,
+ /* ECCurve_SECG_CHAR2_233K1 == ECCurve_NIST_K233 */
+ /* ECCurve_SECG_CHAR2_233R1 == ECCurve_NIST_B233 */
+ ECCurve_SECG_CHAR2_239K1,
+ /* ECCurve_SECG_CHAR2_283K1 == ECCurve_NIST_K283 */
+ /* ECCurve_SECG_CHAR2_283R1 == ECCurve_NIST_B283 */
+ /* ECCurve_SECG_CHAR2_409K1 == ECCurve_NIST_K409 */
+ /* ECCurve_SECG_CHAR2_409R1 == ECCurve_NIST_B409 */
+ /* ECCurve_SECG_CHAR2_571K1 == ECCurve_NIST_K571 */
+ /* ECCurve_SECG_CHAR2_571R1 == ECCurve_NIST_B571 */
+
+ /* WTLS curves */
+ ECCurve_WTLS_1,
+ /* there is no WTLS 2 curve */
+ /* ECCurve_WTLS_3 == ECCurve_NIST_K163 */
+ /* ECCurve_WTLS_4 == ECCurve_SECG_CHAR2_113R1 */
+ /* ECCurve_WTLS_5 == ECCurve_X9_62_CHAR2_PNB163V1 */
+ /* ECCurve_WTLS_6 == ECCurve_SECG_PRIME_112R1 */
+ /* ECCurve_WTLS_7 == ECCurve_SECG_PRIME_160R1 */
+ ECCurve_WTLS_8,
+ ECCurve_WTLS_9,
+ /* ECCurve_WTLS_10 == ECCurve_NIST_K233 */
+ /* ECCurve_WTLS_11 == ECCurve_NIST_B233 */
+ /* ECCurve_WTLS_12 == ECCurve_NIST_P224 */
+
+ ECCurve_pastLastCurve
+} ECCurveName;
+
+/* Aliased named curves */
+
+#define ECCurve_X9_62_PRIME_192V1 ECCurve_NIST_P192
+#define ECCurve_X9_62_PRIME_256V1 ECCurve_NIST_P256
+#define ECCurve_SECG_PRIME_192R1 ECCurve_NIST_P192
+#define ECCurve_SECG_PRIME_224R1 ECCurve_NIST_P224
+#define ECCurve_SECG_PRIME_256R1 ECCurve_NIST_P256
+#define ECCurve_SECG_PRIME_384R1 ECCurve_NIST_P384
+#define ECCurve_SECG_PRIME_521R1 ECCurve_NIST_P521
+#define ECCurve_SECG_CHAR2_163K1 ECCurve_NIST_K163
+#define ECCurve_SECG_CHAR2_163R2 ECCurve_NIST_B163
+#define ECCurve_SECG_CHAR2_233K1 ECCurve_NIST_K233
+#define ECCurve_SECG_CHAR2_233R1 ECCurve_NIST_B233
+#define ECCurve_SECG_CHAR2_283K1 ECCurve_NIST_K283
+#define ECCurve_SECG_CHAR2_283R1 ECCurve_NIST_B283
+#define ECCurve_SECG_CHAR2_409K1 ECCurve_NIST_K409
+#define ECCurve_SECG_CHAR2_409R1 ECCurve_NIST_B409
+#define ECCurve_SECG_CHAR2_571K1 ECCurve_NIST_K571
+#define ECCurve_SECG_CHAR2_571R1 ECCurve_NIST_B571
+#define ECCurve_WTLS_3 ECCurve_NIST_K163
+#define ECCurve_WTLS_4 ECCurve_SECG_CHAR2_113R1
+#define ECCurve_WTLS_5 ECCurve_X9_62_CHAR2_PNB163V1
+#define ECCurve_WTLS_6 ECCurve_SECG_PRIME_112R1
+#define ECCurve_WTLS_7 ECCurve_SECG_PRIME_160R1
+#define ECCurve_WTLS_10 ECCurve_NIST_K233
+#define ECCurve_WTLS_11 ECCurve_NIST_B233
+#define ECCurve_WTLS_12 ECCurve_NIST_P224
+
+#endif /* __ecl_exp_h_ */
diff --git a/security/nss/lib/freebl/ecl/ecl-priv.h b/security/nss/lib/freebl/ecl/ecl-priv.h
new file mode 100644
index 000000000..908ed8ebc
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecl-priv.h
@@ -0,0 +1,216 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Fung <fungstep@hotmail.com> and
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#ifndef __ecl_priv_h_
+#define __ecl_priv_h_
+
+#include "ecl.h"
+#include "mpi.h"
+#include "mplogic.h"
+
+/* MAX_FIELD_SIZE_DIGITS is the maximum size of field element supported */
+#if defined(MP_USE_LONG_LONG_DIGIT) || defined(MP_USE_LONG_DIGIT)
+#define ECL_SIXTY_FOUR_BIT
+#define ECL_BITS 64
+#define ECL_MAX_FIELD_SIZE_DIGITS 10
+#else
+#define ECL_THIRTY_TWO_BIT
+#define ECL_BITS 32
+#define ECL_MAX_FIELD_SIZE_DIGITS 20
+#endif
+
+/* Gets the i'th bit in the binary representation of a. If i >= length(a),
+ * then return 0. (The above behaviour differs from mpl_get_bit, which
+ * causes an error if i >= length(a).) */
+#define MP_GET_BIT(a, i) \
+ ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i))
+
+struct GFMethodStr;
+typedef struct GFMethodStr GFMethod;
+struct GFMethodStr {
+ /* Indicates whether the structure was constructed from dynamic memory
+ * or statically created. */
+ int constructed;
+ /* Irreducible that defines the field. For prime fields, this is the
+ * prime p. For binary polynomial fields, this is the bitstring
+ * representation of the irreducible polynomial. */
+ mp_int irr;
+ /* For prime fields, the value irr_arr[0] is the number of bits in the
+ * field. For binary polynomial fields, the irreducible polynomial
+ * f(t) is represented as an array of unsigned int[], where f(t) is
+ * of the form: f(t) = t^p[0] + t^p[1] + ... + t^p[4] where m = p[0]
+ * > p[1] > ... > p[4] = 0. */
+ unsigned int irr_arr[5];
+ /* Field arithmetic methods. All methods (except field_enc and
+ * field_dec) are assumed to take field-encoded parameters and return
+ * field-encoded values. All methods (except field_enc and field_dec)
+ * are required to be implemented. */
+ mp_err (*field_add) (const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+ mp_err (*field_neg) (const mp_int *a, mp_int *r, const GFMethod *meth);
+ mp_err (*field_sub) (const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+ mp_err (*field_mod) (const mp_int *a, mp_int *r, const GFMethod *meth);
+ mp_err (*field_mul) (const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+ mp_err (*field_sqr) (const mp_int *a, mp_int *r, const GFMethod *meth);
+ mp_err (*field_div) (const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+ mp_err (*field_enc) (const mp_int *a, mp_int *r, const GFMethod *meth);
+ mp_err (*field_dec) (const mp_int *a, mp_int *r, const GFMethod *meth);
+ /* Extra storage for implementation-specific data. Any memory
+ * allocated to these extra fields will be cleared by extra_free. */
+ void *extra1;
+ void *extra2;
+ void (*extra_free) (GFMethod *meth);
+};
+
+/* Construct generic GFMethods. */
+GFMethod *GFMethod_consGFp(const mp_int *irr);
+GFMethod *GFMethod_consGFp_mont(const mp_int *irr);
+GFMethod *GFMethod_consGF2m(const mp_int *irr,
+ const unsigned int irr_arr[5]);
+/* Free the memory allocated (if any) to a GFMethod object. */
+void GFMethod_free(GFMethod *meth);
+
+struct ECGroupStr {
+ /* Indicates whether the structure was constructed from dynamic memory
+ * or statically created. */
+ int constructed;
+ /* Field definition and arithmetic. */
+ GFMethod *meth;
+ /* Textual representation of curve name, if any. */
+ char *text;
+ /* Curve parameters, field-encoded. */
+ mp_int curvea, curveb;
+ /* x and y coordinates of the base point, field-encoded. */
+ mp_int genx, geny;
+ /* Order and cofactor of the base point. */
+ mp_int order;
+ int cofactor;
+ /* Point arithmetic methods. All methods are assumed to take
+ * field-encoded parameters and return field-encoded values. All
+ * methods (except base_point_mul and points_mul) are required to be
+ * implemented. */
+ mp_err (*point_add) (const mp_int *px, const mp_int *py,
+ const mp_int *qx, const mp_int *qy, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+ mp_err (*point_sub) (const mp_int *px, const mp_int *py,
+ const mp_int *qx, const mp_int *qy, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+ mp_err (*point_dbl) (const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+ mp_err (*point_mul) (const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group);
+ mp_err (*base_point_mul) (const mp_int *n, mp_int *rx, mp_int *ry,
+ const ECGroup *group);
+ mp_err (*points_mul) (const mp_int *k1, const mp_int *k2,
+ const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+ /* Extra storage for implementation-specific data. Any memory
+ * allocated to these extra fields will be cleared by extra_free. */
+ void *extra1;
+ void *extra2;
+ void (*extra_free) (ECGroup *group);
+};
+
+/* Wrapper functions for generic prime field arithmetic. */
+mp_err ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+mp_err ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+mp_err ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+mp_err ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+/* Wrapper functions for generic binary polynomial field arithmetic. */
+mp_err ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+mp_err ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+mp_err ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+
+/* Montgomery prime field arithmetic. */
+mp_err ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+mp_err ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth);
+mp_err ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
+mp_err ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
+void ec_GFp_extra_free_mont(GFMethod *meth);
+
+/* point multiplication */
+mp_err ec_pts_mul_basic(const mp_int *k1, const mp_int *k2,
+ const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+mp_err ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2,
+ const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+
+/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
+ * be an array of signed char's to output to, bitsize should be the number
+ * of bits of out, in is the original scalar, and w is the window size.
+ * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
+ * Menezes, "Software implementation of elliptic curve cryptography over
+ * binary fields", Proc. CHES 2000. */
+mp_err ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in,
+ int w);
+
+/* Optimized field arithmetic */
+mp_err ec_group_set_gfp192(ECGroup *group, ECCurveName);
+mp_err ec_group_set_gfp224(ECGroup *group, ECCurveName);
+mp_err ec_group_set_gf2m163(ECGroup *group, ECCurveName name);
+mp_err ec_group_set_gf2m193(ECGroup *group, ECCurveName name);
+mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name);
+
+/* Optimized floating-point arithmetic */
+#ifdef ECL_USE_FP
+mp_err ec_group_set_secp160r1_fp(ECGroup *group);
+mp_err ec_group_set_nistp192_fp(ECGroup *group);
+mp_err ec_group_set_nistp224_fp(ECGroup *group);
+#endif
+
+#endif /* __ecl_priv_h_ */
diff --git a/security/nss/lib/freebl/ecl/ecl.c b/security/nss/lib/freebl/ecl/ecl.c
new file mode 100644
index 000000000..9d7af0624
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecl.c
@@ -0,0 +1,406 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "mpi.h"
+#include "mplogic.h"
+#include "ecl.h"
+#include "ecl-priv.h"
+#include "ec2.h"
+#include "ecp.h"
+#include <stdlib.h>
+#include <string.h>
+
+/* Allocate memory for a new ECGroup object. */
+ECGroup *
+ECGroup_new()
+{
+ mp_err res = MP_OKAY;
+ ECGroup *group;
+ group = (ECGroup *) malloc(sizeof(ECGroup));
+ if (group == NULL)
+ return NULL;
+ group->constructed = MP_YES;
+ group->text = NULL;
+ MP_DIGITS(&group->curvea) = 0;
+ MP_DIGITS(&group->curveb) = 0;
+ MP_DIGITS(&group->genx) = 0;
+ MP_DIGITS(&group->geny) = 0;
+ MP_DIGITS(&group->order) = 0;
+ MP_CHECKOK(mp_init(&group->curvea));
+ MP_CHECKOK(mp_init(&group->curveb));
+ MP_CHECKOK(mp_init(&group->genx));
+ MP_CHECKOK(mp_init(&group->geny));
+ MP_CHECKOK(mp_init(&group->order));
+ group->base_point_mul = NULL;
+ group->points_mul = NULL;
+ group->extra1 = NULL;
+ group->extra2 = NULL;
+ group->extra_free = NULL;
+
+ CLEANUP:
+ if (res != MP_OKAY) {
+ ECGroup_free(group);
+ return NULL;
+ }
+ return group;
+}
+
+/* Construct a generic ECGroup for elliptic curves over prime fields. */
+ECGroup *
+ECGroup_consGFp(const mp_int *irr, const mp_int *curvea,
+ const mp_int *curveb, const mp_int *genx,
+ const mp_int *geny, const mp_int *order, int cofactor)
+{
+ mp_err res = MP_OKAY;
+ ECGroup *group = NULL;
+
+ group = ECGroup_new();
+ if (group == NULL)
+ return NULL;
+
+ group->meth = GFMethod_consGFp(irr);
+ if (group->meth == NULL) {
+ res = MP_MEM;
+ goto CLEANUP;
+ }
+ MP_CHECKOK(mp_copy(curvea, &group->curvea));
+ MP_CHECKOK(mp_copy(curveb, &group->curveb));
+ MP_CHECKOK(mp_copy(genx, &group->genx));
+ MP_CHECKOK(mp_copy(geny, &group->geny));
+ MP_CHECKOK(mp_copy(order, &group->order));
+ group->cofactor = cofactor;
+ group->point_add = &ec_GFp_pt_add_aff;
+ group->point_sub = &ec_GFp_pt_sub_aff;
+ group->point_dbl = &ec_GFp_pt_dbl_aff;
+ group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
+ group->base_point_mul = NULL;
+ group->points_mul = &ec_GFp_pts_mul_jac;
+
+ CLEANUP:
+ if (res != MP_OKAY) {
+ ECGroup_free(group);
+ return NULL;
+ }
+ return group;
+}
+
+/* Construct a generic ECGroup for elliptic curves over prime fields with
+ * field arithmetic implemented in Montgomery coordinates. */
+ECGroup *
+ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea,
+ const mp_int *curveb, const mp_int *genx,
+ const mp_int *geny, const mp_int *order, int cofactor)
+{
+ mp_err res = MP_OKAY;
+ ECGroup *group = NULL;
+
+ group = ECGroup_new();
+ if (group == NULL)
+ return NULL;
+
+ group->meth = GFMethod_consGFp_mont(irr);
+ if (group->meth == NULL) {
+ res = MP_MEM;
+ goto CLEANUP;
+ }
+ MP_CHECKOK(group->meth->
+ field_enc(curvea, &group->curvea, group->meth));
+ MP_CHECKOK(group->meth->
+ field_enc(curveb, &group->curveb, group->meth));
+ MP_CHECKOK(group->meth->field_enc(genx, &group->genx, group->meth));
+ MP_CHECKOK(group->meth->field_enc(geny, &group->geny, group->meth));
+ MP_CHECKOK(mp_copy(order, &group->order));
+ group->cofactor = cofactor;
+ group->point_add = &ec_GFp_pt_add_aff;
+ group->point_sub = &ec_GFp_pt_sub_aff;
+ group->point_dbl = &ec_GFp_pt_dbl_aff;
+ group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
+ group->base_point_mul = NULL;
+ group->points_mul = &ec_GFp_pts_mul_jac;
+
+ CLEANUP:
+ if (res != MP_OKAY) {
+ ECGroup_free(group);
+ return NULL;
+ }
+ return group;
+}
+
+/* Construct a generic ECGroup for elliptic curves over binary polynomial
+ * fields. */
+ECGroup *
+ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5],
+ const mp_int *curvea, const mp_int *curveb,
+ const mp_int *genx, const mp_int *geny,
+ const mp_int *order, int cofactor)
+{
+ mp_err res = MP_OKAY;
+ ECGroup *group = NULL;
+
+ group = ECGroup_new();
+ if (group == NULL)
+ return NULL;
+
+ group->meth = GFMethod_consGF2m(irr, irr_arr);
+ if (group->meth == NULL) {
+ res = MP_MEM;
+ goto CLEANUP;
+ }
+ MP_CHECKOK(mp_copy(curvea, &group->curvea));
+ MP_CHECKOK(mp_copy(curveb, &group->curveb));
+ MP_CHECKOK(mp_copy(genx, &group->genx));
+ MP_CHECKOK(mp_copy(geny, &group->geny));
+ MP_CHECKOK(mp_copy(order, &group->order));
+ group->cofactor = cofactor;
+ group->point_add = &ec_GF2m_pt_add_aff;
+ group->point_sub = &ec_GF2m_pt_sub_aff;
+ group->point_dbl = &ec_GF2m_pt_dbl_aff;
+ group->point_mul = &ec_GF2m_pt_mul_mont;
+ group->base_point_mul = NULL;
+ group->points_mul = &ec_pts_mul_basic;
+
+ CLEANUP:
+ if (res != MP_OKAY) {
+ ECGroup_free(group);
+ return NULL;
+ }
+ return group;
+}
+
+/* Helper macros for ecgroup_fromNameAndHex. */
+#define CHECK_GROUP \
+ if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
+#define CONS_GF2M \
+ group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor); \
+ CHECK_GROUP
+
+/* Construct ECGroup from hex parameters and name, if any. Called by
+ * ECGroup_fromHex and ECGroup_fromName. */
+ECGroup *
+ecgroup_fromNameAndHex(const ECCurveName name,
+ const ECCurveParams * params)
+{
+ mp_int irr, curvea, curveb, genx, geny, order;
+ int bits;
+ ECGroup *group = NULL;
+ mp_err res = MP_OKAY;
+
+ /* initialize values */
+ MP_DIGITS(&irr) = 0;
+ MP_DIGITS(&curvea) = 0;
+ MP_DIGITS(&curveb) = 0;
+ MP_DIGITS(&genx) = 0;
+ MP_DIGITS(&geny) = 0;
+ MP_DIGITS(&order) = 0;
+ MP_CHECKOK(mp_init(&irr));
+ MP_CHECKOK(mp_init(&curvea));
+ MP_CHECKOK(mp_init(&curveb));
+ MP_CHECKOK(mp_init(&genx));
+ MP_CHECKOK(mp_init(&geny));
+ MP_CHECKOK(mp_init(&order));
+ MP_CHECKOK(mp_read_radix(&irr, params->irr, 16));
+ MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16));
+ MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16));
+ MP_CHECKOK(mp_read_radix(&genx, params->genx, 16));
+ MP_CHECKOK(mp_read_radix(&geny, params->geny, 16));
+ MP_CHECKOK(mp_read_radix(&order, params->order, 16));
+
+ /* determine number of bits */
+ bits = mpl_significant_bits(&irr) - 1;
+ if (bits < MP_OKAY) {
+ res = bits;
+ goto CLEANUP;
+ }
+
+ /* determine which optimizations (if any) to use */
+ if (params->field == ECField_GFp) {
+ if ((name == ECCurve_SECG_PRIME_160K1)
+ || (name == ECCurve_SECG_PRIME_160R2)) {
+ group =
+ ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+ } else if ((name == ECCurve_SECG_PRIME_160R1)) {
+#ifdef ECL_USE_FP
+ group =
+ ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+ CHECK_GROUP MP_CHECKOK(ec_group_set_secp160r1_fp(group));
+#else
+ group =
+ ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+#endif
+ } else if ((name == ECCurve_SECG_PRIME_192K1)) {
+ group =
+ ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+ CHECK_GROUP MP_CHECKOK(ec_group_set_gfp192(group, name));
+ } else if ((name == ECCurve_SECG_PRIME_192R1)) {
+#ifdef ECL_USE_FP
+ group =
+ ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+ CHECK_GROUP MP_CHECKOK(ec_group_set_nistp192_fp(group));
+#else
+ group =
+ ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+ CHECK_GROUP MP_CHECKOK(ec_group_set_gfp192(group, name));
+#endif
+ } else if ((name == ECCurve_SECG_PRIME_224K1)) {
+ group =
+ ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+ CHECK_GROUP MP_CHECKOK(ec_group_set_gfp224(group, name));
+ } else if ((name == ECCurve_SECG_PRIME_224R1)) {
+#ifdef ECL_USE_FP
+ group =
+ ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+ CHECK_GROUP MP_CHECKOK(ec_group_set_nistp224_fp(group));
+#else
+ group =
+ ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+ CHECK_GROUP MP_CHECKOK(ec_group_set_gfp224(group, name));
+#endif
+ } else {
+ group =
+ ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+ CHECK_GROUP}
+ /* XXX secp521r1 fails ecp_test with &ec_GFp_pts_mul_jac */
+ if (name == ECCurve_SECG_PRIME_521R1) {
+ group->points_mul = &ec_pts_mul_simul_w2;
+ }
+ } else if (params->field == ECField_GF2m) {
+ switch (bits) {
+ case 163:
+ CONS_GF2M MP_CHECKOK(ec_group_set_gf2m163(group, name));
+ break;
+ case 193:
+ CONS_GF2M MP_CHECKOK(ec_group_set_gf2m193(group, name));
+ break;
+ case 233:
+ CONS_GF2M MP_CHECKOK(ec_group_set_gf2m233(group, name));
+ break;
+ default:
+ group =
+ ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx,
+ &geny, &order, params->cofactor);
+ CHECK_GROUP break;
+ }
+ }
+
+ /* set name, if any */
+ if (params->text != NULL) {
+ group->text = (char *) malloc(sizeof(char) * strlen(params->text));
+ if (group->text == NULL) {
+ res = MP_MEM;
+ }
+ strcpy(group->text, params->text);
+ }
+
+ CLEANUP:
+ mp_clear(&irr);
+ mp_clear(&curvea);
+ mp_clear(&curveb);
+ mp_clear(&genx);
+ mp_clear(&geny);
+ mp_clear(&order);
+ if (res != MP_OKAY) {
+ ECGroup_free(group);
+ return NULL;
+ }
+ return group;
+}
+
+#undef CHECK_GROUP
+#undef CONS_GFP
+#undef CONS_GF2M
+
+/* Construct ECGroup from hexadecimal representations of parameters. */
+ECGroup *
+ECGroup_fromHex(const ECCurveParams * params)
+{
+ return ecgroup_fromNameAndHex(ECCurve_noName, params);
+}
+
+/* Construct ECGroup from named parameters. */
+ECGroup *
+ECGroup_fromName(const ECCurveName name)
+{
+ ECGroup *group = NULL;
+ ECCurveParams *params = NULL;
+ mp_err res = MP_OKAY;
+
+ params = EC_GetNamedCurveParams(name);
+ if (params == NULL) {
+ res = MP_UNDEF;
+ goto CLEANUP;
+ }
+
+ /* construct actual group */
+ group = ecgroup_fromNameAndHex(name, params);
+ if (group == NULL) {
+ res = MP_UNDEF;
+ goto CLEANUP;
+ }
+
+ CLEANUP:
+ EC_FreeCurveParams(params);
+ if (res != MP_OKAY) {
+ ECGroup_free(group);
+ return NULL;
+ }
+ return group;
+}
+
+/* Free the memory allocated (if any) to an ECGroup object. */
+void
+ECGroup_free(ECGroup *group)
+{
+ if (group == NULL)
+ return;
+ GFMethod_free(group->meth);
+ if (group->constructed == MP_NO)
+ return;
+ if (group->text != NULL)
+ free(group->text);
+ if (group->extra_free != NULL)
+ group->extra_free(group);
+ free(group);
+}
diff --git a/security/nss/lib/freebl/ecl/ecl.h b/security/nss/lib/freebl/ecl/ecl.h
new file mode 100644
index 000000000..7db9deb0a
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecl.h
@@ -0,0 +1,82 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+/* Although this is not an exported header file, code which uses elliptic
+ * curve point operations will need to include it. */
+
+#ifndef __ecl_h_
+#define __ecl_h_
+
+#include "ecl-exp.h"
+#include "mpi.h"
+
+struct ECGroupStr;
+typedef struct ECGroupStr ECGroup;
+
+/* Construct ECGroup from hexadecimal representations of parameters. */
+ECGroup *ECGroup_fromHex(const ECCurveParams * params);
+
+/* Construct ECGroup from named parameters. */
+ECGroup *ECGroup_fromName(const ECCurveName name);
+
+/* Free an allocated ECGroup. */
+void ECGroup_free(ECGroup *group);
+
+/* Construct ECCurveParams from an ECCurveName */
+ECCurveParams *EC_GetNamedCurveParams(const ECCurveName name);
+
+/* Duplicates an ECCurveParams */
+ECCurveParams *ECCurveParams_dup(const ECCurveParams * params);
+
+/* Free an allocated ECCurveParams */
+void EC_FreeCurveParams(ECCurveParams * params);
+
+/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k * P(x,
+ * y). If x, y = NULL, then P is assumed to be the generator (base point)
+ * of the group of points on the elliptic curve. Input and output values
+ * are assumed to be NOT field-encoded. */
+mp_err ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
+ const mp_int *py, mp_int *qx, mp_int *qy);
+
+/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k1 * G +
+ * k2 * P(x, y), where G is the generator (base point) of the group of
+ * points on the elliptic curve. Input and output values are assumed to
+ * be NOT field-encoded. */
+mp_err ECPoints_mul(const ECGroup *group, const mp_int *k1,
+ const mp_int *k2, const mp_int *px, const mp_int *py,
+ mp_int *qx, mp_int *qy);
+
+#endif /* __ecl_h_ */
diff --git a/security/nss/lib/freebl/ecl/ecl_curve.c b/security/nss/lib/freebl/ecl/ecl_curve.c
new file mode 100644
index 000000000..d8368092e
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecl_curve.c
@@ -0,0 +1,120 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecl.h"
+#include "ecl-curve.h"
+#include "ecl-priv.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define CHECK(func) if ((func) == NULL) { res = 0; goto CLEANUP; }
+
+/* Duplicates an ECCurveParams */
+ECCurveParams *
+ECCurveParams_dup(const ECCurveParams * params)
+{
+ int res = 1;
+ ECCurveParams *ret = NULL;
+
+ CHECK(ret = (ECCurveParams *) malloc(sizeof(ECCurveParams)));
+ if (params->text != NULL) {
+ CHECK(ret->text = strdup(params->text));
+ }
+ ret->field = params->field;
+ ret->size = params->size;
+ if (params->irr != NULL) {
+ CHECK(ret->irr = strdup(params->irr));
+ }
+ if (params->curvea != NULL) {
+ CHECK(ret->curvea = strdup(params->curvea));
+ }
+ if (params->curveb != NULL) {
+ CHECK(ret->curveb = strdup(params->curveb));
+ }
+ if (params->genx != NULL) {
+ CHECK(ret->genx = strdup(params->genx));
+ }
+ if (params->geny != NULL) {
+ CHECK(ret->geny = strdup(params->geny));
+ }
+ if (params->order != NULL) {
+ CHECK(ret->order = strdup(params->order));
+ }
+ ret->cofactor = params->cofactor;
+
+ CLEANUP:
+ if (res != 1) {
+ EC_FreeCurveParams(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+#undef CHECK
+
+/* Construct ECCurveParams from an ECCurveName */
+ECCurveParams *
+EC_GetNamedCurveParams(const ECCurveName name)
+{
+ if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name)) {
+ return NULL;
+ } else {
+ return ECCurveParams_dup(ecCurve_map[name]);
+ }
+}
+
+/* Free the memory allocated (if any) to an ECCurveParams object. */
+void
+EC_FreeCurveParams(ECCurveParams * params)
+{
+ if (params == NULL)
+ return;
+ if (params->text != NULL)
+ free(params->text);
+ if (params->irr != NULL)
+ free(params->irr);
+ if (params->curvea != NULL)
+ free(params->curvea);
+ if (params->curveb != NULL)
+ free(params->curveb);
+ if (params->genx != NULL)
+ free(params->genx);
+ if (params->geny != NULL)
+ free(params->geny);
+ if (params->order != NULL)
+ free(params->order);
+ free(params);
+}
diff --git a/security/nss/lib/freebl/ecl/ecl_gf.c b/security/nss/lib/freebl/ecl/ecl_gf.c
new file mode 100644
index 000000000..000f97b86
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecl_gf.c
@@ -0,0 +1,337 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Fung <fungstep@hotmail.com> and
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "mpi.h"
+#include "mp_gf2m.h"
+#include "ecl-priv.h"
+#include <stdlib.h>
+
+/* Allocate memory for a new GFMethod object. */
+GFMethod *
+GFMethod_new()
+{
+ mp_err res = MP_OKAY;
+ GFMethod *meth;
+ meth = (GFMethod *) malloc(sizeof(GFMethod));
+ if (meth == NULL)
+ return NULL;
+ meth->constructed = MP_YES;
+ MP_CHECKOK(mp_init(&meth->irr));
+ meth->extra_free = NULL;
+
+ CLEANUP:
+ if (res != MP_OKAY) {
+ GFMethod_free(meth);
+ return NULL;
+ }
+ return meth;
+}
+
+/* Construct a generic GFMethod for arithmetic over prime fields with
+ * irreducible irr. */
+GFMethod *
+GFMethod_consGFp(const mp_int *irr)
+{
+ mp_err res = MP_OKAY;
+ GFMethod *meth = NULL;
+
+ meth = GFMethod_new();
+ if (meth == NULL)
+ return NULL;
+
+ MP_CHECKOK(mp_copy(irr, &meth->irr));
+ meth->irr_arr[0] = mpl_significant_bits(irr);
+ meth->irr_arr[1] = meth->irr_arr[2] = meth->irr_arr[3] =
+ meth->irr_arr[4] = 0;
+ meth->field_add = &ec_GFp_add;
+ meth->field_neg = &ec_GFp_neg;
+ meth->field_sub = &ec_GFp_sub;
+ meth->field_mod = &ec_GFp_mod;
+ meth->field_mul = &ec_GFp_mul;
+ meth->field_sqr = &ec_GFp_sqr;
+ meth->field_div = &ec_GFp_div;
+ meth->field_enc = NULL;
+ meth->field_dec = NULL;
+ meth->extra1 = NULL;
+ meth->extra2 = NULL;
+ meth->extra_free = NULL;
+
+ CLEANUP:
+ if (res != MP_OKAY) {
+ GFMethod_free(meth);
+ return NULL;
+ }
+ return meth;
+}
+
+/* Construct a generic GFMethod for arithmetic over binary polynomial
+ * fields with irreducible irr that has array representation irr_arr (see
+ * ecl-priv.h for description of the representation). If irr_arr is NULL,
+ * then it is constructed from the bitstring representation. */
+GFMethod *
+GFMethod_consGF2m(const mp_int *irr, const unsigned int irr_arr[5])
+{
+ mp_err res = MP_OKAY;
+ int ret;
+ GFMethod *meth = NULL;
+
+ meth = GFMethod_new();
+ if (meth == NULL)
+ return NULL;
+
+ MP_CHECKOK(mp_copy(irr, &meth->irr));
+ if (irr_arr != NULL) {
+ /* Irreducible polynomials are either trinomials or pentanomials. */
+ meth->irr_arr[0] = irr_arr[0];
+ meth->irr_arr[1] = irr_arr[1];
+ meth->irr_arr[2] = irr_arr[2];
+ if (irr_arr[2] > 0) {
+ meth->irr_arr[3] = irr_arr[3];
+ meth->irr_arr[4] = irr_arr[4];
+ } else {
+ meth->irr_arr[3] = meth->irr_arr[4] = 0;
+ }
+ } else {
+ ret = mp_bpoly2arr(irr, meth->irr_arr, 5);
+ /* Irreducible polynomials are either trinomials or pentanomials. */
+ if ((ret != 5) && (ret != 3)) {
+ res = MP_UNDEF;
+ goto CLEANUP;
+ }
+ }
+ meth->field_add = &ec_GF2m_add;
+ meth->field_neg = &ec_GF2m_neg;
+ meth->field_sub = &ec_GF2m_add;
+ meth->field_mod = &ec_GF2m_mod;
+ meth->field_mul = &ec_GF2m_mul;
+ meth->field_sqr = &ec_GF2m_sqr;
+ meth->field_div = &ec_GF2m_div;
+ meth->field_enc = NULL;
+ meth->field_dec = NULL;
+ meth->extra1 = NULL;
+ meth->extra2 = NULL;
+ meth->extra_free = NULL;
+
+ CLEANUP:
+ if (res != MP_OKAY) {
+ GFMethod_free(meth);
+ return NULL;
+ }
+ return meth;
+}
+
+/* Free the memory allocated (if any) to a GFMethod object. */
+void
+GFMethod_free(GFMethod *meth)
+{
+ if (meth == NULL)
+ return;
+ if (meth->constructed == MP_NO)
+ return;
+ if (meth->extra_free != NULL)
+ meth->extra_free(meth);
+ free(meth);
+}
+
+/* Wrapper functions for generic prime field arithmetic. */
+
+/* Add two field elements. Assumes that 0 <= a, b < meth->irr */
+mp_err
+ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a + b (mod p) */
+ mp_err res;
+
+ if ((res = mp_add(a, b, r)) != MP_OKAY) {
+ return res;
+ }
+ if (mp_cmp(r, &meth->irr) >= 0) {
+ return mp_sub(r, &meth->irr, r);
+ }
+ return res;
+}
+
+/* Negates a field element. Assumes that 0 <= a < meth->irr */
+mp_err
+ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ /* PRE: 0 <= a < p = meth->irr POST: 0 <= r < p, r = -a (mod p) */
+
+ if (mp_cmp_z(a) == 0) {
+ mp_zero(r);
+ return MP_OKAY;
+ }
+ return mp_sub(&meth->irr, a, r);
+}
+
+/* Subtracts two field elements. Assumes that 0 <= a, b < meth->irr */
+mp_err
+ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+
+ /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a - b (mod p) */
+ res = mp_sub(a, b, r);
+ if (res == MP_RANGE) {
+ MP_CHECKOK(mp_sub(b, a, r));
+ if (mp_cmp_z(r) < 0) {
+ MP_CHECKOK(mp_add(r, &meth->irr, r));
+ }
+ MP_CHECKOK(ec_GFp_neg(r, r, meth));
+ }
+ if (mp_cmp_z(r) < 0) {
+ MP_CHECKOK(mp_add(r, &meth->irr, r));
+ }
+ CLEANUP:
+ return res;
+}
+
+/* Reduces an integer to a field element. */
+mp_err
+ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ return mp_mod(a, &meth->irr, r);
+}
+
+/* Multiplies two field elements. */
+mp_err
+ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ return mp_mulmod(a, b, &meth->irr, r);
+}
+
+/* Squares a field element. */
+mp_err
+ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ return mp_sqrmod(a, &meth->irr, r);
+}
+
+/* Divides two field elements. If a is NULL, then returns the inverse of
+ * b. */
+mp_err
+ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_int t;
+
+ /* If a is NULL, then return the inverse of b, otherwise return a/b. */
+ if (a == NULL) {
+ return mp_invmod(b, &meth->irr, r);
+ } else {
+ /* MPI doesn't support divmod, so we implement it using invmod and
+ * mulmod. */
+ MP_CHECKOK(mp_init(&t));
+ MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
+ MP_CHECKOK(mp_mulmod(a, &t, &meth->irr, r));
+ CLEANUP:
+ mp_clear(&t);
+ return res;
+ }
+}
+
+/* Wrapper functions for generic binary polynomial field arithmetic. */
+
+/* Adds two field elements. */
+mp_err
+ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ return mp_badd(a, b, r);
+}
+
+/* Negates a field element. Note that for binary polynomial fields, the
+ * negation of a field element is the field element itself. */
+mp_err
+ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ if (a == r) {
+ return MP_OKAY;
+ } else {
+ return mp_copy(a, r);
+ }
+}
+
+/* Reduces a binary polynomial to a field element. */
+mp_err
+ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ return mp_bmod(a, meth->irr_arr, r);
+}
+
+/* Multiplies two field elements. */
+mp_err
+ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ return mp_bmulmod(a, b, meth->irr_arr, r);
+}
+
+/* Squares a field element. */
+mp_err
+ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ return mp_bsqrmod(a, meth->irr_arr, r);
+}
+
+/* Divides two field elements. If a is NULL, then returns the inverse of
+ * b. */
+mp_err
+ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_int t;
+
+ /* If a is NULL, then return the inverse of b, otherwise return a/b. */
+ if (a == NULL) {
+ /* The GF(2^m) portion of MPI doesn't support invmod, so we
+ * compute 1/b. */
+ MP_CHECKOK(mp_init(&t));
+ MP_CHECKOK(mp_set_int(&t, 1));
+ MP_CHECKOK(mp_bdivmod(&t, b, &meth->irr, meth->irr_arr, r));
+ CLEANUP:
+ mp_clear(&t);
+ return res;
+ } else {
+ return mp_bdivmod(a, b, &meth->irr, meth->irr_arr, r);
+ }
+}
diff --git a/security/nss/lib/freebl/ecl/ecl_mult.c b/security/nss/lib/freebl/ecl/ecl_mult.c
new file mode 100644
index 000000000..9609733de
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecl_mult.c
@@ -0,0 +1,359 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "mpi.h"
+#include "mplogic.h"
+#include "ecl.h"
+#include "ecl-priv.h"
+#include <stdlib.h>
+#include <strings.h>
+
+/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k * P(x,
+ * y). If x, y = NULL, then P is assumed to be the generator (base point)
+ * of the group of points on the elliptic curve. Input and output values
+ * are assumed to be NOT field-encoded. */
+mp_err
+ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry)
+{
+ mp_err res = MP_OKAY;
+ mp_int kt;
+
+ ARGCHK((k != NULL) && (group != NULL), MP_BADARG);
+ MP_DIGITS(&kt) = 0;
+
+ /* want scalar to be less than or equal to group order */
+ if (mp_cmp(k, &group->order) >= 0) {
+ MP_CHECKOK(mp_init(&kt));
+ MP_CHECKOK(mp_mod(k, &group->order, &kt));
+ } else {
+ MP_SIGN(&kt) = MP_ZPOS;
+ MP_USED(&kt) = MP_USED(k);
+ MP_ALLOC(&kt) = MP_ALLOC(k);
+ MP_DIGITS(&kt) = MP_DIGITS(k);
+ }
+
+ if ((px == NULL) || (py == NULL)) {
+ if (group->base_point_mul) {
+ MP_CHECKOK(group->base_point_mul(&kt, rx, ry, group));
+ } else {
+ MP_CHECKOK(group->
+ point_mul(&kt, &group->genx, &group->geny, rx, ry,
+ group));
+ }
+ } else {
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->field_enc(px, rx, group->meth));
+ MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
+ MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group));
+ } else {
+ MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group));
+ }
+ }
+ if (group->meth->field_dec) {
+ MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
+ MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
+ }
+
+ CLEANUP:
+ if (MP_DIGITS(&kt) != MP_DIGITS(k)) {
+ mp_clear(&kt);
+ }
+ return res;
+}
+
+/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
+ * k2 * P(x, y), where G is the generator (base point) of the group of
+ * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
+ * Input and output values are assumed to be NOT field-encoded. */
+mp_err
+ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int sx, sy;
+
+ ARGCHK(group != NULL, MP_BADARG);
+ ARGCHK(!((k1 == NULL)
+ && ((k2 == NULL) || (px == NULL)
+ || (py == NULL))), MP_BADARG);
+
+ /* if some arguments are not defined used ECPoint_mul */
+ if (k1 == NULL) {
+ return ECPoint_mul(group, k2, px, py, rx, ry);
+ } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
+ return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
+ }
+
+ MP_DIGITS(&sx) = 0;
+ MP_DIGITS(&sy) = 0;
+ MP_CHECKOK(mp_init(&sx));
+ MP_CHECKOK(mp_init(&sy));
+
+ MP_CHECKOK(ECPoint_mul(group, k1, NULL, NULL, &sx, &sy));
+ MP_CHECKOK(ECPoint_mul(group, k2, px, py, rx, ry));
+
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->field_enc(&sx, &sx, group->meth));
+ MP_CHECKOK(group->meth->field_enc(&sy, &sy, group->meth));
+ MP_CHECKOK(group->meth->field_enc(rx, rx, group->meth));
+ MP_CHECKOK(group->meth->field_enc(ry, ry, group->meth));
+ }
+
+ MP_CHECKOK(group->point_add(&sx, &sy, rx, ry, rx, ry, group));
+
+ if (group->meth->field_dec) {
+ MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
+ MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
+ }
+
+ CLEANUP:
+ mp_clear(&sx);
+ mp_clear(&sy);
+ return res;
+}
+
+/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
+ * k2 * P(x, y), where G is the generator (base point) of the group of
+ * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
+ * Input and output values are assumed to be NOT field-encoded. Uses
+ * algorithm 15 (simultaneous multiple point multiplication) from Brown,
+ * Hankerson, Lopez, Menezes. Software Implementation of the NIST
+ * Elliptic Curves over Prime Fields. */
+mp_err
+ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int precomp[4][4][2];
+ mp_digit precomp_arr[ECL_MAX_FIELD_SIZE_DIGITS * 4 * 4 * 2], *t;
+ const mp_int *a, *b;
+ int i, j;
+ int ai, bi, d;
+
+ ARGCHK(group != NULL, MP_BADARG);
+ ARGCHK(!((k1 == NULL)
+ && ((k2 == NULL) || (px == NULL)
+ || (py == NULL))), MP_BADARG);
+
+ /* if some arguments are not defined used ECPoint_mul */
+ if (k1 == NULL) {
+ return ECPoint_mul(group, k2, px, py, rx, ry);
+ } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
+ return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
+ }
+
+ /* initialize precomputation table */
+ t = precomp_arr;
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ /* x co-ord */
+ MP_SIGN(&precomp[i][j][0]) = MP_ZPOS;
+ MP_ALLOC(&precomp[i][j][0]) = ECL_MAX_FIELD_SIZE_DIGITS;
+ MP_USED(&precomp[i][j][0]) = 1;
+ *t = 0;
+ MP_DIGITS(&precomp[i][j][0]) = t;
+ t += ECL_MAX_FIELD_SIZE_DIGITS;
+ /* y co-ord */
+ MP_SIGN(&precomp[i][j][1]) = MP_ZPOS;
+ MP_ALLOC(&precomp[i][j][1]) = ECL_MAX_FIELD_SIZE_DIGITS;
+ MP_USED(&precomp[i][j][1]) = 1;
+ *t = 0;
+ MP_DIGITS(&precomp[i][j][1]) = t;
+ t += ECL_MAX_FIELD_SIZE_DIGITS;
+ }
+ }
+
+ /* fill precomputation table */
+ /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
+ if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
+ a = k2;
+ b = k1;
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->
+ field_enc(px, &precomp[1][0][0], group->meth));
+ MP_CHECKOK(group->meth->
+ field_enc(py, &precomp[1][0][1], group->meth));
+ } else {
+ MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
+ MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
+ }
+ MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
+ MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
+ } else {
+ a = k1;
+ b = k2;
+ MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
+ MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->
+ field_enc(px, &precomp[0][1][0], group->meth));
+ MP_CHECKOK(group->meth->
+ field_enc(py, &precomp[0][1][1], group->meth));
+ } else {
+ MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
+ MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
+ }
+ }
+ /* precompute [*][0][*] */
+ mp_zero(&precomp[0][0][0]);
+ mp_zero(&precomp[0][0][1]);
+ MP_CHECKOK(group->
+ point_dbl(&precomp[1][0][0], &precomp[1][0][1],
+ &precomp[2][0][0], &precomp[2][0][1], group));
+ MP_CHECKOK(group->
+ point_add(&precomp[1][0][0], &precomp[1][0][1],
+ &precomp[2][0][0], &precomp[2][0][1],
+ &precomp[3][0][0], &precomp[3][0][1], group));
+ /* precompute [*][1][*] */
+ for (i = 1; i < 4; i++) {
+ MP_CHECKOK(group->
+ point_add(&precomp[0][1][0], &precomp[0][1][1],
+ &precomp[i][0][0], &precomp[i][0][1],
+ &precomp[i][1][0], &precomp[i][1][1], group));
+ }
+ /* precompute [*][2][*] */
+ MP_CHECKOK(group->
+ point_dbl(&precomp[0][1][0], &precomp[0][1][1],
+ &precomp[0][2][0], &precomp[0][2][1], group));
+ for (i = 1; i < 4; i++) {
+ MP_CHECKOK(group->
+ point_add(&precomp[0][2][0], &precomp[0][2][1],
+ &precomp[i][0][0], &precomp[i][0][1],
+ &precomp[i][2][0], &precomp[i][2][1], group));
+ }
+ /* precompute [*][3][*] */
+ MP_CHECKOK(group->
+ point_add(&precomp[0][1][0], &precomp[0][1][1],
+ &precomp[0][2][0], &precomp[0][2][1],
+ &precomp[0][3][0], &precomp[0][3][1], group));
+ for (i = 1; i < 4; i++) {
+ MP_CHECKOK(group->
+ point_add(&precomp[0][3][0], &precomp[0][3][1],
+ &precomp[i][0][0], &precomp[i][0][1],
+ &precomp[i][3][0], &precomp[i][3][1], group));
+ }
+
+ d = (mpl_significant_bits(a) + 1) / 2;
+
+ /* R = inf */
+ mp_zero(rx);
+ mp_zero(ry);
+
+ for (i = d - 1; i >= 0; i--) {
+ ai = MP_GET_BIT(a, 2 * i + 1);
+ ai <<= 1;
+ ai |= MP_GET_BIT(a, 2 * i);
+ bi = MP_GET_BIT(b, 2 * i + 1);
+ bi <<= 1;
+ bi |= MP_GET_BIT(b, 2 * i);
+ /* R = 2^2 * R */
+ MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group));
+ MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group));
+ /* R = R + (ai * A + bi * B) */
+ MP_CHECKOK(group->
+ point_add(rx, ry, &precomp[ai][bi][0],
+ &precomp[ai][bi][1], rx, ry, group));
+ }
+
+ if (group->meth->field_dec) {
+ MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
+ MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
+ }
+
+ CLEANUP:
+ return res;
+}
+
+/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
+ * k2 * P(x, y), where G is the generator (base point) of the group of
+ * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
+ * Input and output values are assumed to be NOT field-encoded. */
+mp_err
+ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2,
+ const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry)
+{
+ mp_err res = MP_OKAY;
+ mp_int k1t, k2t;
+ const mp_int *k1p, *k2p;
+
+ MP_DIGITS(&k1t) = 0;
+ MP_DIGITS(&k2t) = 0;
+
+ ARGCHK(group != NULL, MP_BADARG);
+
+ /* want scalar to be less than or equal to group order */
+ if (k1 != NULL) {
+ if (mp_cmp(k1, &group->order) >= 0) {
+ MP_CHECKOK(mp_init(&k1t));
+ MP_CHECKOK(mp_mod(k1, &group->order, &k1t));
+ k1p = &k1t;
+ } else {
+ k1p = k1;
+ }
+ } else {
+ k1p = k1;
+ }
+ if (k2 != NULL) {
+ if (mp_cmp(k2, &group->order) >= 0) {
+ MP_CHECKOK(mp_init(&k2t));
+ MP_CHECKOK(mp_mod(k2, &group->order, &k2t));
+ k2p = &k2t;
+ } else {
+ k2p = k2;
+ }
+ } else {
+ k2p = k2;
+ }
+
+ /* if points_mul is defined, then use it */
+ if (group->points_mul) {
+ return group->points_mul(k1p, k2p, px, py, rx, ry, group);
+ } else {
+ return ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group);
+ }
+
+ CLEANUP:
+ if (k1 != k1p) {
+ mp_clear(&k1t);
+ }
+ if (k2 != k2p) {
+ mp_clear(&k2t);
+ }
+ return res;
+}
diff --git a/security/nss/lib/freebl/ecl/ecp.h b/security/nss/lib/freebl/ecl/ecp.h
new file mode 100644
index 000000000..801c83c56
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp.h
@@ -0,0 +1,136 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#ifndef __ecp_h_
+#define __ecp_h_
+
+#include "ecl-priv.h"
+
+/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
+mp_err ec_GFp_pt_is_inf_aff(const mp_int *px, const mp_int *py);
+
+/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
+mp_err ec_GFp_pt_set_inf_aff(mp_int *px, mp_int *py);
+
+/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx,
+ * qy). Uses affine coordinates. */
+mp_err ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py,
+ const mp_int *qx, const mp_int *qy, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+
+/* Computes R = P - Q. Uses affine coordinates. */
+mp_err ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py,
+ const mp_int *qx, const mp_int *qy, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+
+/* Computes R = 2P. Uses affine coordinates. */
+mp_err ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, const ECGroup *group);
+
+#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GFp. Uses affine coordinates. */
+mp_err ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group);
+#endif
+
+/* Converts a point P(px, py) from affine coordinates to Jacobian
+ * projective coordinates R(rx, ry, rz). */
+mp_err ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, mp_int *rz, const ECGroup *group);
+
+/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
+ * affine coordinates R(rx, ry). */
+mp_err ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py,
+ const mp_int *pz, mp_int *rx, mp_int *ry,
+ const ECGroup *group);
+
+/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
+ * coordinates. */
+mp_err ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py,
+ const mp_int *pz);
+
+/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
+ * coordinates. */
+mp_err ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz);
+
+/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
+ * (qx, qy, qz). Uses Jacobian coordinates. */
+mp_err ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py,
+ const mp_int *pz, const mp_int *qx,
+ const mp_int *qy, mp_int *rx, mp_int *ry,
+ mp_int *rz, const ECGroup *group);
+
+/* Computes R = 2P. Uses Jacobian coordinates. */
+mp_err ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py,
+ const mp_int *pz, mp_int *rx, mp_int *ry,
+ mp_int *rz, const ECGroup *group);
+
+#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GFp. Uses Jacobian coordinates. */
+mp_err ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group);
+#endif
+
+/* Computes R(x, y) = k1 * G + k2 * P(x, y), where G is the generator
+ * (base point) of the group of points on the elliptic curve. Allows k1 =
+ * NULL or { k2, P } = NULL. Implemented using mixed Jacobian-affine
+ * coordinates. Input and output values are assumed to be NOT
+ * field-encoded and are in affine form. */
+mp_err
+ ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group);
+
+/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
+ * curve points P and R can be identical. Uses mixed Modified-Jacobian
+ * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
+ * additions. Assumes input is already field-encoded using field_enc, and
+ * returns output that is still field-encoded. Uses 5-bit window NAF
+ * method (algorithm 11) for scalar-point multiplication from Brown,
+ * Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
+ * Curves Over Prime Fields. */
+mp_err
+ ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
+ mp_int *rx, mp_int *ry, const ECGroup *group);
+
+#endif /* __ecp_h_ */
diff --git a/security/nss/lib/freebl/ecl/ecp_192.c b/security/nss/lib/freebl/ecl/ecp_192.c
new file mode 100644
index 000000000..914349e63
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_192.c
@@ -0,0 +1,228 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecp.h"
+#include "mpi.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+#include <stdlib.h>
+
+/* Fast modular reduction for p192 = 2^192 - 2^64 - 1. a can be r. Uses
+ * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software
+ * Implementation of the NIST Elliptic Curves over Prime Fields. */
+mp_err
+ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_size a_used = MP_USED(a);
+
+ /* s is a statically-allocated mp_int of exactly the size we need */
+ mp_int s;
+
+#ifdef ECL_THIRTY_TWO_BIT
+ mp_digit sa[6];
+ mp_digit a11 = 0, a10, a9 = 0, a8, a7 = 0, a6;
+
+ MP_SIGN(&s) = MP_ZPOS;
+ MP_ALLOC(&s) = 6;
+ MP_USED(&s) = 6;
+ MP_DIGITS(&s) = sa;
+#else
+ mp_digit sa[3];
+ mp_digit a5 = 0, a4 = 0, a3 = 0;
+
+ MP_SIGN(&s) = MP_ZPOS;
+ MP_ALLOC(&s) = 3;
+ MP_USED(&s) = 3;
+ MP_DIGITS(&s) = sa;
+#endif
+
+ /* reduction not needed if a is not larger than field size */
+#ifdef ECL_THIRTY_TWO_BIT
+ if (a_used < 6) {
+#else
+ if (a_used < 3) {
+#endif
+ return mp_copy(a, r);
+ }
+#ifdef ECL_THIRTY_TWO_BIT
+ /* for polynomials larger than twice the field size, use regular
+ * reduction */
+ if (a_used > 12) {
+ MP_CHECKOK(mp_mod(a, &meth->irr, r));
+ } else {
+ /* copy out upper words of a */
+ switch (a_used) {
+ case 12:
+ a11 = MP_DIGIT(a, 11);
+ case 11:
+ a10 = MP_DIGIT(a, 10);
+ case 10:
+ a9 = MP_DIGIT(a, 9);
+ case 9:
+ a8 = MP_DIGIT(a, 8);
+ case 8:
+ a7 = MP_DIGIT(a, 7);
+ case 7:
+ a6 = MP_DIGIT(a, 6);
+ }
+ /* set the lower words of r */
+ if (a != r) {
+ MP_CHECKOK(s_mp_pad(r, 7));
+ MP_DIGIT(r, 5) = MP_DIGIT(a, 5);
+ MP_DIGIT(r, 4) = MP_DIGIT(a, 4);
+ MP_DIGIT(r, 3) = MP_DIGIT(a, 3);
+ MP_DIGIT(r, 2) = MP_DIGIT(a, 2);
+ MP_DIGIT(r, 1) = MP_DIGIT(a, 1);
+ MP_DIGIT(r, 0) = MP_DIGIT(a, 0);
+ }
+ MP_USED(r) = 6;
+ /* compute r = s1 + s2 + s3 + s4, where s1 = (a2,a1,a0), s2 =
+ * (0,a3,a3), s3 = (a4,a4,0), and s4 = (a5,a5,a5), for
+ * sixty-four-bit words */
+ switch (a_used) {
+ case 12:
+ case 11:
+ sa[5] = sa[3] = sa[1] = a11;
+ sa[4] = sa[2] = sa[0] = a10;
+ MP_CHECKOK(mp_add(r, &s, r));
+ case 10:
+ case 9:
+ sa[5] = sa[3] = a9;
+ sa[4] = sa[2] = a8;
+ sa[1] = sa[0] = 0;
+ MP_CHECKOK(mp_add(r, &s, r));
+ case 8:
+ case 7:
+ sa[5] = sa[4] = 0;
+ sa[3] = sa[1] = a7;
+ sa[2] = sa[0] = a6;
+ MP_CHECKOK(mp_add(r, &s, r));
+ }
+ /* there might be 1 or 2 bits left to reduce; use regular
+ * reduction for this */
+ MP_CHECKOK(mp_mod(r, &meth->irr, r));
+ }
+#else
+ /* for polynomials larger than twice the field size, use regular
+ * reduction */
+ if (a_used > 6) {
+ MP_CHECKOK(mp_mod(a, &meth->irr, r));
+ } else {
+ /* copy out upper words of a */
+ switch (a_used) {
+ case 6:
+ a5 = MP_DIGIT(a, 5);
+ case 5:
+ a4 = MP_DIGIT(a, 4);
+ case 4:
+ a3 = MP_DIGIT(a, 3);
+ }
+ /* set the lower words of r */
+ if (a != r) {
+ MP_CHECKOK(s_mp_pad(r, 4));
+ MP_DIGIT(r, 2) = MP_DIGIT(a, 2);
+ MP_DIGIT(r, 1) = MP_DIGIT(a, 1);
+ MP_DIGIT(r, 0) = MP_DIGIT(a, 0);
+ }
+ MP_USED(r) = 3;
+ /* compute r = s1 + s2 + s3 + s4, where s1 = (a2,a1,a0), s2 =
+ * (0,a3,a3), s3 = (a4,a4,0), and s4 = (a5,a5,a5) */
+ switch (a_used) {
+ case 6:
+ sa[2] = sa[1] = sa[0] = a5;
+ MP_CHECKOK(mp_add(r, &s, r));
+ case 5:
+ sa[2] = sa[1] = a4;
+ sa[0] = 0;
+ MP_CHECKOK(mp_add(r, &s, r));
+ case 4:
+ sa[2] = 0;
+ sa[1] = sa[0] = a3;
+ MP_CHECKOK(mp_add(r, &s, r));
+ }
+ /* there might be 1 or 2 bits left to reduce; use regular
+ * reduction for this */
+ MP_CHECKOK(mp_mod(r, &meth->irr, r));
+ }
+#endif
+
+ CLEANUP:
+ return res;
+}
+
+/* Compute the square of polynomial a, reduce modulo p192. Store the
+ * result in r. r could be a. Uses optimized modular reduction for p192.
+ */
+mp_err
+ec_GFp_nistp192_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+
+ MP_CHECKOK(mp_sqr(a, r));
+ MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
+ CLEANUP:
+ return res;
+}
+
+/* Compute the product of two polynomials a and b, reduce modulo p192.
+ * Store the result in r. r could be a or b; a could be b. Uses
+ * optimized modular reduction for p192. */
+mp_err
+ec_GFp_nistp192_mul(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+
+ MP_CHECKOK(mp_mul(a, b, r));
+ MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
+ CLEANUP:
+ return res;
+}
+
+/* Wire in fast field arithmetic and precomputation of base point for
+ * named curves. */
+mp_err
+ec_group_set_gfp192(ECGroup *group, ECCurveName name)
+{
+ if (name == ECCurve_NIST_P192) {
+ group->meth->field_mod = &ec_GFp_nistp192_mod;
+ group->meth->field_mul = &ec_GFp_nistp192_mul;
+ group->meth->field_sqr = &ec_GFp_nistp192_sqr;
+ }
+ return MP_OKAY;
+}
diff --git a/security/nss/lib/freebl/ecl/ecp_224.c b/security/nss/lib/freebl/ecl/ecp_224.c
new file mode 100644
index 000000000..6e6e81ce4
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_224.c
@@ -0,0 +1,305 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecp.h"
+#include "mpi.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+#include <stdlib.h>
+
+/* Fast modular reduction for p224 = 2^224 - 2^96 + 1. a can be r. Uses
+ * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software
+ * Implementation of the NIST Elliptic Curves over Prime Fields. */
+mp_err
+ec_GFp_nistp224_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+ mp_size a_used = MP_USED(a);
+
+ /* s is a statically-allocated mp_int of exactly the size we need */
+ mp_int s;
+
+#ifdef ECL_THIRTY_TWO_BIT
+ mp_digit sa[8];
+ mp_digit a13 = 0, a12 = 0, a11 = 0, a10, a9 = 0, a8, a7;
+
+ MP_SIGN(&s) = MP_ZPOS;
+ MP_ALLOC(&s) = 8;
+ MP_USED(&s) = 7;
+ MP_DIGITS(&s) = sa;
+#else
+ mp_digit sa[4];
+ mp_digit a6 = 0, a5 = 0, a4 = 0, a3 = 0;
+
+ MP_SIGN(&s) = MP_ZPOS;
+ MP_ALLOC(&s) = 4;
+ MP_USED(&s) = 4;
+ MP_DIGITS(&s) = sa;
+#endif
+
+ /* reduction not needed if a is not larger than field size */
+#ifdef ECL_THIRTY_TWO_BIT
+ if (a_used < 8) {
+#else
+ if (a_used < 4) {
+#endif
+ return mp_copy(a, r);
+ }
+#ifdef ECL_THIRTY_TWO_BIT
+ /* for polynomials larger than twice the field size, use regular
+ * reduction */
+ if (a_used > 14) {
+ MP_CHECKOK(mp_mod(a, &meth->irr, r));
+ } else {
+ /* copy out upper words of a */
+ switch (a_used) {
+ case 14:
+ a13 = MP_DIGIT(a, 13);
+ case 13:
+ a12 = MP_DIGIT(a, 12);
+ case 12:
+ a11 = MP_DIGIT(a, 11);
+ case 11:
+ a10 = MP_DIGIT(a, 10);
+ case 10:
+ a9 = MP_DIGIT(a, 9);
+ case 9:
+ a8 = MP_DIGIT(a, 8);
+ case 8:
+ a7 = MP_DIGIT(a, 7);
+ }
+ /* set the lower words of r */
+ if (a != r) {
+ MP_CHECKOK(s_mp_pad(r, 8));
+ MP_DIGIT(r, 6) = MP_DIGIT(a, 6);
+ MP_DIGIT(r, 5) = MP_DIGIT(a, 5);
+ MP_DIGIT(r, 4) = MP_DIGIT(a, 4);
+ MP_DIGIT(r, 3) = MP_DIGIT(a, 3);
+ MP_DIGIT(r, 2) = MP_DIGIT(a, 2);
+ MP_DIGIT(r, 1) = MP_DIGIT(a, 1);
+ MP_DIGIT(r, 0) = MP_DIGIT(a, 0);
+ }
+ MP_USED(r) = 7;
+ switch (a_used) {
+ case 14:
+ case 13:
+ case 12:
+ case 11:
+ sa[6] = a10;
+ case 10:
+ sa[5] = a9;
+ case 9:
+ sa[4] = a8;
+ case 8:
+ sa[3] = a7;
+ sa[2] = sa[1] = sa[0] = 0;
+ MP_USED(&s) = a_used - 4;
+ if (MP_USED(&s) > 7)
+ MP_USED(&s) = 7;
+ MP_CHECKOK(mp_add(r, &s, r));
+ }
+ switch (a_used) {
+ case 14:
+ sa[5] = a13;
+ case 13:
+ sa[4] = a12;
+ case 12:
+ sa[3] = a11;
+ sa[2] = sa[1] = sa[0] = 0;
+ MP_USED(&s) = a_used - 8;
+ MP_CHECKOK(mp_add(r, &s, r));
+ }
+ switch (a_used) {
+ case 14:
+ sa[6] = a13;
+ case 13:
+ sa[5] = a12;
+ case 12:
+ sa[4] = a11;
+ case 11:
+ sa[3] = a10;
+ case 10:
+ sa[2] = a9;
+ case 9:
+ sa[1] = a8;
+ case 8:
+ sa[0] = a7;
+ MP_USED(&s) = a_used - 7;
+ MP_CHECKOK(mp_sub(r, &s, r));
+ }
+ switch (a_used) {
+ case 14:
+ sa[2] = a13;
+ case 13:
+ sa[1] = a12;
+ case 12:
+ sa[0] = a11;
+ MP_USED(&s) = a_used - 11;
+ MP_CHECKOK(mp_sub(r, &s, r));
+ }
+ /* there might be 1 or 2 bits left to reduce; use regular
+ * reduction for this */
+ MP_CHECKOK(mp_mod(r, &meth->irr, r));
+ }
+#else
+ /* for polynomials larger than twice the field size, use regular
+ * reduction */
+ if (a_used > 7) {
+ MP_CHECKOK(mp_mod(a, &meth->irr, r));
+ } else {
+ /* copy out upper words of a */
+ switch (a_used) {
+ case 7:
+ a6 = MP_DIGIT(a, 6);
+ case 6:
+ a5 = MP_DIGIT(a, 5);
+ case 5:
+ a4 = MP_DIGIT(a, 4);
+ case 4:
+ a3 = MP_DIGIT(a, 3) >> 32;
+ }
+ /* set the lower words of r */
+ if (a != r) {
+ MP_CHECKOK(s_mp_pad(r, 5));
+ MP_DIGIT(r, 3) = MP_DIGIT(a, 3) & 0xFFFFFFFF;
+ MP_DIGIT(r, 2) = MP_DIGIT(a, 2);
+ MP_DIGIT(r, 1) = MP_DIGIT(a, 1);
+ MP_DIGIT(r, 0) = MP_DIGIT(a, 0);
+ } else {
+ MP_DIGIT(r, 3) &= 0xFFFFFFFF;
+ }
+ MP_USED(r) = 4;
+ switch (a_used) {
+ case 7:
+ case 6:
+ sa[3] = a5 & 0xFFFFFFFF;
+ case 5:
+ sa[2] = a4;
+ case 4:
+ sa[1] = a3 << 32;
+ sa[0] = 0;
+ MP_USED(&s) = a_used - 2;
+ if (MP_USED(&s) == 5)
+ MP_USED(&s) = 4;
+ MP_CHECKOK(mp_add(r, &s, r));
+ }
+ switch (a_used) {
+ case 7:
+ sa[2] = a6;
+ case 6:
+ sa[1] = (a5 >> 32) << 32;
+ sa[0] = 0;
+ MP_USED(&s) = a_used - 4;
+ MP_CHECKOK(mp_add(r, &s, r));
+ }
+ sa[2] = sa[1] = sa[0] = 0;
+ switch (a_used) {
+ case 7:
+ sa[3] = a6 >> 32;
+ sa[2] = a6 << 32;
+ case 6:
+ sa[2] |= a5 >> 32;
+ sa[1] = a5 << 32;
+ case 5:
+ sa[1] |= a4 >> 32;
+ sa[0] = a4 << 32;
+ case 4:
+ sa[0] |= a3;
+ MP_USED(&s) = a_used - 3;
+ MP_CHECKOK(mp_sub(r, &s, r));
+ }
+ sa[0] = 0;
+ switch (a_used) {
+ case 7:
+ sa[1] = a6 >> 32;
+ sa[0] = a6 << 32;
+ case 6:
+ sa[0] |= a5 >> 32;
+ MP_USED(&s) = a_used - 5;
+ MP_CHECKOK(mp_sub(r, &s, r));
+ }
+ /* there might be 1 or 2 bits left to reduce; use regular
+ * reduction for this */
+ MP_CHECKOK(mp_mod(r, &meth->irr, r));
+ }
+#endif
+
+ CLEANUP:
+ return res;
+}
+
+/* Compute the square of polynomial a, reduce modulo p224. Store the
+ * result in r. r could be a. Uses optimized modular reduction for p224.
+ */
+mp_err
+ec_GFp_nistp224_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+
+ MP_CHECKOK(mp_sqr(a, r));
+ MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
+ CLEANUP:
+ return res;
+}
+
+/* Compute the product of two polynomials a and b, reduce modulo p224.
+ * Store the result in r. r could be a or b; a could be b. Uses
+ * optimized modular reduction for p224. */
+mp_err
+ec_GFp_nistp224_mul(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+
+ MP_CHECKOK(mp_mul(a, b, r));
+ MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
+ CLEANUP:
+ return res;
+}
+
+/* Wire in fast field arithmetic and precomputation of base point for
+ * named curves. */
+mp_err
+ec_group_set_gfp224(ECGroup *group, ECCurveName name)
+{
+ if (name == ECCurve_NIST_P224) {
+ group->meth->field_mod = &ec_GFp_nistp224_mod;
+ group->meth->field_mul = &ec_GFp_nistp224_mul;
+ group->meth->field_sqr = &ec_GFp_nistp224_sqr;
+ }
+ return MP_OKAY;
+}
diff --git a/security/nss/lib/freebl/ecl/ecp_aff.c b/security/nss/lib/freebl/ecl/ecp_aff.c
new file mode 100644
index 000000000..0bda87657
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_aff.c
@@ -0,0 +1,284 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ * Stephen Fung <fungstep@hotmail.com>, and
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>,
+ * Nils Larsch <nla@trustcenter.de>, and
+ * Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecp.h"
+#include "mplogic.h"
+#include <stdlib.h>
+
+/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
+mp_err
+ec_GFp_pt_is_inf_aff(const mp_int *px, const mp_int *py)
+{
+
+ if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
+ return MP_YES;
+ } else {
+ return MP_NO;
+ }
+
+}
+
+/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
+mp_err
+ec_GFp_pt_set_inf_aff(mp_int *px, mp_int *py)
+{
+ mp_zero(px);
+ mp_zero(py);
+ return MP_OKAY;
+}
+
+/* Computes R = P + Q based on IEEE P1363 A.10.1. Elliptic curve points P,
+ * Q, and R can all be identical. Uses affine coordinates. Assumes input
+ * is already field-encoded using field_enc, and returns output that is
+ * still field-encoded. */
+mp_err
+ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
+ const mp_int *qy, mp_int *rx, mp_int *ry,
+ const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int lambda, temp, tempx, tempy;
+
+ MP_DIGITS(&lambda) = 0;
+ MP_DIGITS(&temp) = 0;
+ MP_DIGITS(&tempx) = 0;
+ MP_DIGITS(&tempy) = 0;
+ MP_CHECKOK(mp_init(&lambda));
+ MP_CHECKOK(mp_init(&temp));
+ MP_CHECKOK(mp_init(&tempx));
+ MP_CHECKOK(mp_init(&tempy));
+ /* if P = inf, then R = Q */
+ if (ec_GFp_pt_is_inf_aff(px, py) == 0) {
+ MP_CHECKOK(mp_copy(qx, rx));
+ MP_CHECKOK(mp_copy(qy, ry));
+ res = MP_OKAY;
+ goto CLEANUP;
+ }
+ /* if Q = inf, then R = P */
+ if (ec_GFp_pt_is_inf_aff(qx, qy) == 0) {
+ MP_CHECKOK(mp_copy(px, rx));
+ MP_CHECKOK(mp_copy(py, ry));
+ res = MP_OKAY;
+ goto CLEANUP;
+ }
+ /* if px != qx, then lambda = (py-qy) / (px-qx) */
+ if (mp_cmp(px, qx) != 0) {
+ MP_CHECKOK(group->meth->field_sub(py, qy, &tempy, group->meth));
+ MP_CHECKOK(group->meth->field_sub(px, qx, &tempx, group->meth));
+ MP_CHECKOK(group->meth->
+ field_div(&tempy, &tempx, &lambda, group->meth));
+ } else {
+ /* if py != qy or qy = 0, then R = inf */
+ if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qy) == 0)) {
+ mp_zero(rx);
+ mp_zero(ry);
+ res = MP_OKAY;
+ goto CLEANUP;
+ }
+ /* lambda = (3qx^2+a) / (2qy) */
+ MP_CHECKOK(group->meth->field_sqr(qx, &tempx, group->meth));
+ MP_CHECKOK(mp_set_int(&temp, 3));
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
+ }
+ MP_CHECKOK(group->meth->
+ field_mul(&tempx, &temp, &tempx, group->meth));
+ MP_CHECKOK(group->meth->
+ field_add(&tempx, &group->curvea, &tempx, group->meth));
+ MP_CHECKOK(mp_set_int(&temp, 2));
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
+ }
+ MP_CHECKOK(group->meth->field_mul(qy, &temp, &tempy, group->meth));
+ MP_CHECKOK(group->meth->
+ field_div(&tempx, &tempy, &lambda, group->meth));
+ }
+ /* rx = lambda^2 - px - qx */
+ MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
+ MP_CHECKOK(group->meth->field_sub(&tempx, px, &tempx, group->meth));
+ MP_CHECKOK(group->meth->field_sub(&tempx, qx, &tempx, group->meth));
+ /* ry = (x1-x2) * lambda - y1 */
+ MP_CHECKOK(group->meth->field_sub(qx, &tempx, &tempy, group->meth));
+ MP_CHECKOK(group->meth->
+ field_mul(&tempy, &lambda, &tempy, group->meth));
+ MP_CHECKOK(group->meth->field_sub(&tempy, qy, &tempy, group->meth));
+ MP_CHECKOK(mp_copy(&tempx, rx));
+ MP_CHECKOK(mp_copy(&tempy, ry));
+
+ CLEANUP:
+ mp_clear(&lambda);
+ mp_clear(&temp);
+ mp_clear(&tempx);
+ mp_clear(&tempy);
+ return res;
+}
+
+/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
+ * identical. Uses affine coordinates. Assumes input is already
+ * field-encoded using field_enc, and returns output that is still
+ * field-encoded. */
+mp_err
+ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
+ const mp_int *qy, mp_int *rx, mp_int *ry,
+ const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int nqy;
+
+ MP_DIGITS(&nqy) = 0;
+ MP_CHECKOK(mp_init(&nqy));
+ /* nqy = -qy */
+ MP_CHECKOK(group->meth->field_neg(qy, &nqy, group->meth));
+ res = group->point_add(px, py, qx, &nqy, rx, ry, group);
+ CLEANUP:
+ mp_clear(&nqy);
+ return res;
+}
+
+/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
+ * affine coordinates. Assumes input is already field-encoded using
+ * field_enc, and returns output that is still field-encoded. */
+mp_err
+ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, const ECGroup *group)
+{
+ return ec_GFp_pt_add_aff(px, py, px, py, rx, ry, group);
+}
+
+/* by default, this routine is unused and thus doesn't need to be compiled */
+#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
+/* Computes R = nP based on IEEE P1363 A.10.3. Elliptic curve points P and
+ * R can be identical. Uses affine coordinates. Assumes input is already
+ * field-encoded using field_enc, and returns output that is still
+ * field-encoded. */
+mp_err
+ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
+ mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int k, k3, qx, qy, sx, sy;
+ int b1, b3, i, l;
+
+ MP_DIGITS(&k) = 0;
+ MP_DIGITS(&k3) = 0;
+ MP_DIGITS(&qx) = 0;
+ MP_DIGITS(&qy) = 0;
+ MP_DIGITS(&sx) = 0;
+ MP_DIGITS(&sy) = 0;
+ MP_CHECKOK(mp_init(&k));
+ MP_CHECKOK(mp_init(&k3));
+ MP_CHECKOK(mp_init(&qx));
+ MP_CHECKOK(mp_init(&qy));
+ MP_CHECKOK(mp_init(&sx));
+ MP_CHECKOK(mp_init(&sy));
+
+ /* if n = 0 then r = inf */
+ if (mp_cmp_z(n) == 0) {
+ mp_zero(rx);
+ mp_zero(ry);
+ res = MP_OKAY;
+ goto CLEANUP;
+ }
+ /* Q = P, k = n */
+ MP_CHECKOK(mp_copy(px, &qx));
+ MP_CHECKOK(mp_copy(py, &qy));
+ MP_CHECKOK(mp_copy(n, &k));
+ /* if n < 0 then Q = -Q, k = -k */
+ if (mp_cmp_z(n) < 0) {
+ MP_CHECKOK(group->meth->field_neg(&qy, &qy, group->meth));
+ MP_CHECKOK(mp_neg(&k, &k));
+ }
+#ifdef ECL_DEBUG /* basic double and add method */
+ l = mpl_significant_bits(&k) - 1;
+ MP_CHECKOK(mp_copy(&qx, &sx));
+ MP_CHECKOK(mp_copy(&qy, &sy));
+ for (i = l - 1; i >= 0; i--) {
+ /* S = 2S */
+ MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
+ /* if k_i = 1, then S = S + Q */
+ if (mpl_get_bit(&k, i) != 0) {
+ MP_CHECKOK(group->
+ point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
+ }
+ }
+#else /* double and add/subtract method from
+ * standard */
+ /* k3 = 3 * k */
+ MP_CHECKOK(mp_set_int(&k3, 3));
+ MP_CHECKOK(mp_mul(&k, &k3, &k3));
+ /* S = Q */
+ MP_CHECKOK(mp_copy(&qx, &sx));
+ MP_CHECKOK(mp_copy(&qy, &sy));
+ /* l = index of high order bit in binary representation of 3*k */
+ l = mpl_significant_bits(&k3) - 1;
+ /* for i = l-1 downto 1 */
+ for (i = l - 1; i >= 1; i--) {
+ /* S = 2S */
+ MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
+ b3 = MP_GET_BIT(&k3, i);
+ b1 = MP_GET_BIT(&k, i);
+ /* if k3_i = 1 and k_i = 0, then S = S + Q */
+ if ((b3 == 1) && (b1 == 0)) {
+ MP_CHECKOK(group->
+ point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
+ /* if k3_i = 0 and k_i = 1, then S = S - Q */
+ } else if ((b3 == 0) && (b1 == 1)) {
+ MP_CHECKOK(group->
+ point_sub(&sx, &sy, &qx, &qy, &sx, &sy, group));
+ }
+ }
+#endif
+ /* output S */
+ MP_CHECKOK(mp_copy(&sx, rx));
+ MP_CHECKOK(mp_copy(&sy, ry));
+
+ CLEANUP:
+ mp_clear(&k);
+ mp_clear(&k3);
+ mp_clear(&qx);
+ mp_clear(&qy);
+ mp_clear(&sx);
+ mp_clear(&sy);
+ return res;
+}
+#endif
diff --git a/security/nss/lib/freebl/ecl/ecp_fp.c b/security/nss/lib/freebl/ecl/ecp_fp.c
new file mode 100644
index 000000000..1b9c6ed67
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_fp.c
@@ -0,0 +1,566 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves using floating point operations.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ * Stephen Fung <fungstep@hotmail.com>, and
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecp_fp.h"
+#include "ecl-priv.h"
+#include <stdlib.h>
+
+/* Performs tidying on a short multi-precision floating point integer (the
+ * lower group->numDoubles floats). */
+void
+ecfp_tidyShort(double *t, const EC_group_fp * group)
+{
+ group->ecfp_tidy(t, group->alpha, group);
+}
+
+/* Performs tidying on only the upper float digits of a multi-precision
+ * floating point integer, i.e. the digits beyond the regular length which
+ * are removed in the reduction step. */
+void
+ecfp_tidyUpper(double *t, const EC_group_fp * group)
+{
+ group->ecfp_tidy(t + group->numDoubles,
+ group->alpha + group->numDoubles, group);
+}
+
+/* Performs a "tidy" operation, which performs carrying, moving excess
+ * bits from one double to the next double, so that the precision of the
+ * doubles is reduced to the regular precision group->doubleBitSize. This
+ * might result in some float digits being negative. Alternative C version
+ * for portability. */
+void
+ecfp_tidy(double *t, const double *alpha, const EC_group_fp * group)
+{
+ double q;
+ int i;
+
+ /* Do carrying */
+ for (i = 0; i < group->numDoubles - 1; i++) {
+ q = t[i] + alpha[i + 1];
+ q -= alpha[i + 1];
+ t[i] -= q;
+ t[i + 1] += q;
+
+ /* If we don't assume that truncation rounding is used, then q
+ * might be 2^n bigger than expected (if it rounds up), then t[0]
+ * could be negative and t[1] 2^n larger than expected. */
+ }
+}
+
+/* Performs a more mathematically precise "tidying" so that each term is
+ * positive. This is slower than the regular tidying, and is used for
+ * conversion from floating point to integer. */
+void
+ecfp_positiveTidy(double *t, const EC_group_fp * group)
+{
+ double q;
+ int i;
+
+ /* Do carrying */
+ for (i = 0; i < group->numDoubles - 1; i++) {
+ /* Subtract beta to force rounding down */
+ q = t[i] - ecfp_beta[i + 1];
+ q += group->alpha[i + 1];
+ q -= group->alpha[i + 1];
+ t[i] -= q;
+ t[i + 1] += q;
+
+ /* Due to subtracting ecfp_beta, we should have each term a
+ * non-negative int */
+ ECFP_ASSERT(t[i] / ecfp_exp[i] ==
+ (unsigned long long) (t[i] / ecfp_exp[i]));
+ ECFP_ASSERT(t[i] >= 0);
+ }
+}
+
+/* Converts from a floating point representation into an mp_int. Expects
+ * that d is already reduced. */
+void
+ecfp_fp2i(mp_int *mpout, double *d, const ECGroup *ecgroup)
+{
+ EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
+ unsigned short i16[(group->primeBitSize + 15) / 16];
+ double q = 1;
+
+#ifdef ECL_THIRTY_TWO_BIT
+ /* TEST uint32_t z = 0; */
+ unsigned int z = 0;
+#else
+ uint64_t z = 0;
+#endif
+ int zBits = 0;
+ int copiedBits = 0;
+ int i = 0;
+ int j = 0;
+
+ mp_digit *out;
+
+ /* Result should always be >= 0, so set sign accordingly */
+ MP_SIGN(mpout) = MP_ZPOS;
+
+ /* Tidy up so we're just dealing with positive numbers */
+ ecfp_positiveTidy(d, group);
+
+ /* We might need to do this reduction step more than once if the
+ * reduction adds smaller terms which carry-over to cause another
+ * reduction. However, this should happen very rarely, if ever,
+ * depending on the elliptic curve. */
+ do {
+ /* Init loop data */
+ z = 0;
+ zBits = 0;
+ q = 1;
+ i = 0;
+ j = 0;
+ copiedBits = 0;
+
+ /* Might have to do a bit more reduction */
+ group->ecfp_singleReduce(d, group);
+
+ /* Grow the size of the mpint if it's too small */
+ s_mp_grow(mpout, group->numInts);
+ MP_USED(mpout) = group->numInts;
+ out = MP_DIGITS(mpout);
+
+ /* Convert double to 16 bit integers */
+ while (copiedBits < group->primeBitSize) {
+ if (zBits < 16) {
+ z += d[i] * q;
+ i++;
+ ECFP_ASSERT(i < (group->primeBitSize + 15) / 16);
+ zBits += group->doubleBitSize;
+ }
+ i16[j] = z;
+ j++;
+ z >>= 16;
+ zBits -= 16;
+ q *= ecfp_twom16;
+ copiedBits += 16;
+ }
+ } while (z != 0);
+
+ /* Convert 16 bit integers to mp_digit */
+#ifdef ECL_THIRTY_TWO_BIT
+ for (i = 0; i < (group->primeBitSize + 15) / 16; i += 2) {
+ *out = 0;
+ if (i + 1 < (group->primeBitSize + 15) / 16) {
+ *out = i16[i + 1];
+ *out <<= 16;
+ }
+ *out++ += i16[i];
+ }
+#else /* 64 bit */
+ for (i = 0; i < (group->primeBitSize + 15) / 16; i += 4) {
+ *out = 0;
+ if (i + 3 < (group->primeBitSize + 15) / 16) {
+ *out = i16[i + 3];
+ *out <<= 16;
+ }
+ if (i + 2 < (group->primeBitSize + 15) / 16) {
+ *out += i16[i + 2];
+ *out <<= 16;
+ }
+ if (i + 1 < (group->primeBitSize + 15) / 16) {
+ *out += i16[i + 1];
+ *out <<= 16;
+ }
+ *out++ += i16[i];
+ }
+#endif
+
+ /* Perform final reduction. mpout should already be the same number
+ * of bits as p, but might not be less than p. Make it so. Since
+ * mpout has the same number of bits as p, and 2p has a larger bit
+ * size, then mpout < 2p, so a single subtraction of p will suffice. */
+ if (mp_cmp(mpout, &ecgroup->meth->irr) >= 0) {
+ mp_sub(mpout, &ecgroup->meth->irr, mpout);
+ }
+
+ /* Shrink the size of the mp_int to the actual used size (required for
+ * mp_cmp_z == 0) */
+ out = MP_DIGITS(mpout);
+ for (i = group->numInts - 1; i > 0; i--) {
+ if (out[i] != 0)
+ break;
+ }
+ MP_USED(mpout) = i + 1;
+
+ /* Should be between 0 and p-1 */
+ ECFP_ASSERT(mp_cmp(mpout, &ecgroup->meth->irr) < 0);
+ ECFP_ASSERT(mp_cmp_z(mpout) >= 0);
+}
+
+/* Converts from an mpint into a floating point representation. */
+void
+ecfp_i2fp(double *out, const mp_int *x, const ECGroup *ecgroup)
+{
+ int i;
+ int j = 0;
+ int size;
+ double shift = 1;
+ mp_digit *in;
+ EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
+
+#ifdef ECL_DEBUG
+ /* if debug mode, convert result back using ecfp_fp2i into cmp, then
+ * compare to x. */
+ mp_int cmp;
+
+ MP_DIGITS(&cmp) = NULL;
+ mp_init(&cmp);
+#endif
+
+ ECFP_ASSERT(group != NULL);
+
+ /* init output to 0 (since we skip over some terms) */
+ for (i = 0; i < group->numDoubles; i++)
+ out[i] = 0;
+ i = 0;
+
+ size = MP_USED(x);
+ in = MP_DIGITS(x);
+
+ /* Copy from int into doubles */
+#ifdef ECL_THIRTY_TWO_BIT
+ while (j < size) {
+ while (group->doubleBitSize * (i + 1) <= 32 * j) {
+ i++;
+ }
+ ECFP_ASSERT(group->doubleBitSize * i <= 32 * j);
+ out[i] = in[j];
+ out[i] *= shift;
+ shift *= ecfp_two32;
+ j++;
+ }
+#else
+ while (j < size) {
+ while (group->doubleBitSize * (i + 1) <= 64 * j) {
+ i++;
+ }
+ ECFP_ASSERT(group->doubleBitSize * i <= 64 * j);
+ out[i] = (in[j] & 0x00000000FFFFFFFF) * shift;
+
+ while (group->doubleBitSize * (i + 1) <= 64 * j + 32) {
+ i++;
+ }
+ ECFP_ASSERT(24 * i <= 64 * j + 32);
+ out[i] = (in[j] & 0xFFFFFFFF00000000) * shift;
+
+ shift *= ecfp_two64;
+ j++;
+ }
+#endif
+ /* Realign bits to match double boundaries */
+ ecfp_tidyShort(out, group);
+
+#ifdef ECL_DEBUG
+ /* Convert result back to mp_int, compare to original */
+ ecfp_fp2i(&cmp, out, ecgroup);
+ ECFP_ASSERT(mp_cmp(&cmp, x) == 0);
+ mp_clear(&cmp);
+#endif
+}
+
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GFp. Elliptic curve points P and R can be
+ * identical. Uses Jacobian coordinates. Uses 4-bit window method. */
+mp_err
+ec_GFp_point_mul_jac_4w_fp(const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *ecgroup)
+{
+ mp_err res = MP_OKAY;
+ ecfp_jac_pt precomp[16], r;
+ ecfp_aff_pt p;
+ EC_group_fp *group;
+
+ mp_int rz;
+ int i, ni, d;
+
+ ARGCHK(ecgroup != NULL, MP_BADARG);
+ ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
+
+ group = (EC_group_fp *) ecgroup->extra1;
+ MP_DIGITS(&rz) = 0;
+ MP_CHECKOK(mp_init(&rz));
+
+ /* init p, da */
+ ecfp_i2fp(p.x, px, ecgroup);
+ ecfp_i2fp(p.y, py, ecgroup);
+ ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
+
+ /* Do precomputation */
+ group->precompute_jac(precomp, &p, group);
+
+ /* Do main body of calculations */
+ d = (mpl_significant_bits(n) + 3) / 4;
+
+ /* R = inf */
+ for (i = 0; i < group->numDoubles; i++) {
+ r.z[i] = 0;
+ }
+
+ for (i = d - 1; i >= 0; i--) {
+ /* compute window ni */
+ ni = MP_GET_BIT(n, 4 * i + 3);
+ ni <<= 1;
+ ni |= MP_GET_BIT(n, 4 * i + 2);
+ ni <<= 1;
+ ni |= MP_GET_BIT(n, 4 * i + 1);
+ ni <<= 1;
+ ni |= MP_GET_BIT(n, 4 * i);
+
+ /* R = 2^4 * R */
+ group->pt_dbl_jac(&r, &r, group);
+ group->pt_dbl_jac(&r, &r, group);
+ group->pt_dbl_jac(&r, &r, group);
+ group->pt_dbl_jac(&r, &r, group);
+
+ /* R = R + (ni * P) */
+ group->pt_add_jac(&r, &precomp[ni], &r, group);
+ }
+
+ /* Convert back to integer */
+ ecfp_fp2i(rx, r.x, ecgroup);
+ ecfp_fp2i(ry, r.y, ecgroup);
+ ecfp_fp2i(&rz, r.z, ecgroup);
+
+ /* convert result S to affine coordinates */
+ MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, ecgroup));
+
+ CLEANUP:
+ mp_clear(&rz);
+ return res;
+}
+
+/* Uses mixed Jacobian-affine coordinates to perform a point
+ * multiplication: R = n * P, n scalar. Uses mixed Jacobian-affine
+ * coordinates (Jacobian coordinates for doubles and affine coordinates
+ * for additions; based on recommendation from Brown et al.). Not very
+ * time efficient but quite space efficient, no precomputation needed.
+ * group contains the elliptic curve coefficients and the prime that
+ * determines the field GFp. Elliptic curve points P and R can be
+ * identical. Performs calculations in floating point number format, since
+ * this is faster than the integer operations on the ULTRASPARC III.
+ * Uses left-to-right binary method (double & add) (algorithm 9) for
+ * scalar-point multiplication from Brown, Hankerson, Lopez, Menezes.
+ * Software Implementation of the NIST Elliptic Curves Over Prime Fields. */
+mp_err
+ec_GFp_pt_mul_jac_fp(const mp_int *n, const mp_int *px, const mp_int *py,
+ mp_int *rx, mp_int *ry, const ECGroup *ecgroup)
+{
+ mp_err res;
+ mp_int sx, sy, sz;
+
+ ecfp_aff_pt p;
+ ecfp_jac_pt r;
+ EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
+
+ int i, l;
+
+ MP_DIGITS(&sx) = 0;
+ MP_DIGITS(&sy) = 0;
+ MP_DIGITS(&sz) = 0;
+ MP_CHECKOK(mp_init(&sx));
+ MP_CHECKOK(mp_init(&sy));
+ MP_CHECKOK(mp_init(&sz));
+
+ /* if n = 0 then r = inf */
+ if (mp_cmp_z(n) == 0) {
+ mp_zero(rx);
+ mp_zero(ry);
+ res = MP_OKAY;
+ goto CLEANUP;
+ /* if n < 0 then out of range error */
+ } else if (mp_cmp_z(n) < 0) {
+ res = MP_RANGE;
+ goto CLEANUP;
+ }
+
+ /* Convert from integer to floating point */
+ ecfp_i2fp(p.x, px, ecgroup);
+ ecfp_i2fp(p.y, py, ecgroup);
+ ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);
+
+ /* Init r to point at infinity */
+ for (i = 0; i < group->numDoubles; i++) {
+ r.z[i] = 0;
+ }
+
+ /* double and add method */
+ l = mpl_significant_bits(n) - 1;
+
+ for (i = l; i >= 0; i--) {
+ /* R = 2R */
+ group->pt_dbl_jac(&r, &r, group);
+
+ /* if n_i = 1, then R = R + Q */
+ if (MP_GET_BIT(n, i) != 0) {
+ group->pt_add_jac_aff(&r, &p, &r, group);
+ }
+ }
+
+ /* Convert from floating point to integer */
+ ecfp_fp2i(&sx, r.x, ecgroup);
+ ecfp_fp2i(&sy, r.y, ecgroup);
+ ecfp_fp2i(&sz, r.z, ecgroup);
+
+ /* convert result R to affine coordinates */
+ MP_CHECKOK(ec_GFp_pt_jac2aff(&sx, &sy, &sz, rx, ry, ecgroup));
+
+ CLEANUP:
+ mp_clear(&sx);
+ mp_clear(&sy);
+ mp_clear(&sz);
+ return res;
+}
+
+/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
+ * curve points P and R can be identical. Uses mixed Modified-Jacobian
+ * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
+ * additions. Uses 5-bit window NAF method (algorithm 11) for scalar-point
+ * multiplication from Brown, Hankerson, Lopez, Menezes. Software
+ * Implementation of the NIST Elliptic Curves Over Prime Fields. */
+mp_err
+ec_GFp_point_mul_wNAF_fp(const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *ecgroup)
+{
+ mp_err res = MP_OKAY;
+ mp_int sx, sy, sz;
+ EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
+ ecfp_chud_pt precomp[16];
+
+ ecfp_aff_pt p;
+ ecfp_jm_pt r;
+
+ signed char naf[group->orderBitSize + 1];
+ int i;
+
+ MP_DIGITS(&sx) = 0;
+ MP_DIGITS(&sy) = 0;
+ MP_DIGITS(&sz) = 0;
+ MP_CHECKOK(mp_init(&sx));
+ MP_CHECKOK(mp_init(&sy));
+ MP_CHECKOK(mp_init(&sz));
+
+ /* if n = 0 then r = inf */
+ if (mp_cmp_z(n) == 0) {
+ mp_zero(rx);
+ mp_zero(ry);
+ res = MP_OKAY;
+ goto CLEANUP;
+ /* if n < 0 then out of range error */
+ } else if (mp_cmp_z(n) < 0) {
+ res = MP_RANGE;
+ goto CLEANUP;
+ }
+
+ /* Convert from integer to floating point */
+ ecfp_i2fp(p.x, px, ecgroup);
+ ecfp_i2fp(p.y, py, ecgroup);
+ ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);
+
+ /* Perform precomputation */
+ group->precompute_chud(precomp, &p, group);
+
+ /* Compute 5NAF */
+ ec_compute_wNAF(naf, group->orderBitSize, n, 5);
+
+ /* Init R = pt at infinity */
+ for (i = 0; i < group->numDoubles; i++) {
+ r.z[i] = 0;
+ }
+
+ /* wNAF method */
+ for (i = group->orderBitSize; i >= 0; i--) {
+ /* R = 2R */
+ group->pt_dbl_jm(&r, &r, group);
+
+ if (naf[i] != 0) {
+ group->pt_add_jm_chud(&r, &precomp[(naf[i] + 15) / 2], &r,
+ group);
+ }
+ }
+
+ /* Convert from floating point to integer */
+ ecfp_fp2i(&sx, r.x, ecgroup);
+ ecfp_fp2i(&sy, r.y, ecgroup);
+ ecfp_fp2i(&sz, r.z, ecgroup);
+
+ /* convert result R to affine coordinates */
+ MP_CHECKOK(ec_GFp_pt_jac2aff(&sx, &sy, &sz, rx, ry, ecgroup));
+
+ CLEANUP:
+ mp_clear(&sx);
+ mp_clear(&sy);
+ mp_clear(&sz);
+ return res;
+}
+
+/* Cleans up extra memory allocated in ECGroup for this implementation. */
+void
+ec_GFp_extra_free_fp(ECGroup *group)
+{
+ if (group->extra1 != NULL) {
+ free(group->extra1);
+ group->extra1 = NULL;
+ }
+}
+
+/* Tests what precision floating point arithmetic is set to. This should
+ * be either a 53-bit mantissa (IEEE standard) or a 64-bit mantissa
+ * (extended precision on x86) and sets it into the EC_group_fp. Returns
+ * either 53 or 64 accordingly. */
+int
+ec_set_fp_precision(EC_group_fp * group)
+{
+ double a = 9007199254740992.0; /* 2^53 */
+ double b = a + 1;
+
+ if (a == b) {
+ group->fpPrecision = 53;
+ group->alpha = ecfp_alpha_53;
+ return 53;
+ }
+ group->fpPrecision = 64;
+ group->alpha = ecfp_alpha_64;
+ return 64;
+}
diff --git a/security/nss/lib/freebl/ecl/ecp_fp.h b/security/nss/lib/freebl/ecl/ecp_fp.h
new file mode 100644
index 000000000..6df7b9e69
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_fp.h
@@ -0,0 +1,405 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves using floating point operations.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#ifndef __ecp_fp_h_
+#define __ecp_fp_h_
+
+#include "mpi.h"
+#include "ecl.h"
+#include "ecp.h"
+
+#include <sys/types.h>
+#include "mpi-priv.h"
+
+#ifdef ECL_DEBUG
+#include <assert.h>
+#endif
+
+/* Largest number of doubles to store one reduced number in floating
+ * point. Used for memory allocation on the stack. */
+#define ECFP_MAXDOUBLES 10
+
+/* For debugging purposes */
+#ifndef ECL_DEBUG
+#define ECFP_ASSERT(x)
+#else
+#define ECFP_ASSERT(x) assert(x)
+#endif
+
+/* ECFP_Ti = 2^(i*24) Define as preprocessor constants so we can use in
+ * multiple static constants */
+#define ECFP_T0 1.0
+#define ECFP_T1 16777216.0
+#define ECFP_T2 281474976710656.0
+#define ECFP_T3 4722366482869645213696.0
+#define ECFP_T4 79228162514264337593543950336.0
+#define ECFP_T5 1329227995784915872903807060280344576.0
+#define ECFP_T6 22300745198530623141535718272648361505980416.0
+#define ECFP_T7 374144419156711147060143317175368453031918731001856.0
+#define ECFP_T8 6277101735386680763835789423207666416102355444464034512896.0
+#define ECFP_T9 105312291668557186697918027683670432318895095400549111254310977536.0
+#define ECFP_T10 1766847064778384329583297500742918515827483896875618958121606201292619776.0
+#define ECFP_T11 29642774844752946028434172162224104410437116074403984394101141506025761187823616.0
+#define ECFP_T12 497323236409786642155382248146820840100456150797347717440463976893159497012533375533056.0
+#define ECFP_T13 8343699359066055009355553539724812947666814540455674882605631280555545803830627148527195652096.0
+#define ECFP_T14 139984046386112763159840142535527767382602843577165595931249318810236991948760059086304843329475444736.0
+#define ECFP_T15 2348542582773833227889480596789337027375682548908319870707290971532209025114608443463698998384768703031934976.0
+#define ECFP_T16 39402006196394479212279040100143613805079739270465446667948293404245\
+721771497210611414266254884915640806627990306816.0
+#define ECFP_T17 66105596879024859895191530803277103982840468296428121928464879527440\
+5791236311345825189210439715284847591212025023358304256.0
+#define ECFP_T18 11090678776483259438313656736572334813745748301503266300681918322458\
+485231222502492159897624416558312389564843845614287315896631296.0
+#define ECFP_T19 18607071341967536398062689481932916079453218833595342343206149099024\
+36577570298683715049089827234727835552055312041415509848580169253519\
+36.0
+
+#define ECFP_TWO160 1461501637330902918203684832716283019655932542976.0
+#define ECFP_TWO192 6277101735386680763835789423207666416102355444464034512896.0
+#define ECFP_TWO224 26959946667150639794667015087019630673637144422540572481103610249216.0
+
+/* Multiplicative constants */
+static const double ecfp_two32 = 4294967296.0;
+static const double ecfp_two64 = 18446744073709551616.0;
+static const double ecfp_twom16 = .0000152587890625;
+static const double ecfp_twom128 =
+ .00000000000000000000000000000000000000293873587705571876992184134305561419454666389193021880377187926569604314863681793212890625;
+static const double ecfp_twom129 =
+ .000000000000000000000000000000000000001469367938527859384960920671527807097273331945965109401885939632848021574318408966064453125;
+static const double ecfp_twom160 =
+ .0000000000000000000000000000000000000000000000006842277657836020854119773355907793609766904013068924666782559979930620520927053718196475529111921787261962890625;
+static const double ecfp_twom192 =
+ .000000000000000000000000000000000000000000000000000000000159309191113245227702888039776771180559110455519261878607388585338616290151305816094308987472018268594098344692611135542392730712890625;
+static const double ecfp_twom224 =
+ .00000000000000000000000000000000000000000000000000000000000000000003709206150687421385731735261547639513367564778757791002453039058917581340095629358997312082723208437536338919136001159027049567384892725385725498199462890625;
+
+/* ecfp_exp[i] = 2^(i*ECFP_DSIZE) */
+static const double ecfp_exp[2 * ECFP_MAXDOUBLES] = {
+ ECFP_T0, ECFP_T1, ECFP_T2, ECFP_T3, ECFP_T4, ECFP_T5,
+ ECFP_T6, ECFP_T7, ECFP_T8, ECFP_T9, ECFP_T10, ECFP_T11,
+ ECFP_T12, ECFP_T13, ECFP_T14, ECFP_T15, ECFP_T16, ECFP_T17, ECFP_T18,
+ ECFP_T19
+};
+
+/* 1.1 * 2^52 Uses 2^52 to truncate, the .1 is an extra 2^51 to protect
+ * the 2^52 bit, so that adding alphas to a negative number won't borrow
+ * and empty the important 2^52 bit */
+#define ECFP_ALPHABASE_53 6755399441055744.0
+/* Special case: On some platforms, notably x86 Linux, there is an
+ * extended-precision floating point representation with 64-bits of
+ * precision in the mantissa. These extra bits of precision require a
+ * larger value of alpha to truncate, i.e. 1.1 * 2^63. */
+#define ECFP_ALPHABASE_64 13835058055282163712.0
+
+/*
+ * ecfp_alpha[i] = 1.5 * 2^(52 + i*ECFP_DSIZE) we add and subtract alpha
+ * to truncate floating point numbers to a certain number of bits for
+ * tidying */
+static const double ecfp_alpha_53[2 * ECFP_MAXDOUBLES] = {
+ ECFP_ALPHABASE_53 * ECFP_T0,
+ ECFP_ALPHABASE_53 * ECFP_T1,
+ ECFP_ALPHABASE_53 * ECFP_T2,
+ ECFP_ALPHABASE_53 * ECFP_T3,
+ ECFP_ALPHABASE_53 * ECFP_T4,
+ ECFP_ALPHABASE_53 * ECFP_T5,
+ ECFP_ALPHABASE_53 * ECFP_T6,
+ ECFP_ALPHABASE_53 * ECFP_T7,
+ ECFP_ALPHABASE_53 * ECFP_T8,
+ ECFP_ALPHABASE_53 * ECFP_T9,
+ ECFP_ALPHABASE_53 * ECFP_T10,
+ ECFP_ALPHABASE_53 * ECFP_T11,
+ ECFP_ALPHABASE_53 * ECFP_T12,
+ ECFP_ALPHABASE_53 * ECFP_T13,
+ ECFP_ALPHABASE_53 * ECFP_T14,
+ ECFP_ALPHABASE_53 * ECFP_T15,
+ ECFP_ALPHABASE_53 * ECFP_T16,
+ ECFP_ALPHABASE_53 * ECFP_T17,
+ ECFP_ALPHABASE_53 * ECFP_T18,
+ ECFP_ALPHABASE_53 * ECFP_T19
+};
+
+/*
+ * ecfp_alpha[i] = 1.5 * 2^(63 + i*ECFP_DSIZE) we add and subtract alpha
+ * to truncate floating point numbers to a certain number of bits for
+ * tidying */
+static const double ecfp_alpha_64[2 * ECFP_MAXDOUBLES] = {
+ ECFP_ALPHABASE_64 * ECFP_T0,
+ ECFP_ALPHABASE_64 * ECFP_T1,
+ ECFP_ALPHABASE_64 * ECFP_T2,
+ ECFP_ALPHABASE_64 * ECFP_T3,
+ ECFP_ALPHABASE_64 * ECFP_T4,
+ ECFP_ALPHABASE_64 * ECFP_T5,
+ ECFP_ALPHABASE_64 * ECFP_T6,
+ ECFP_ALPHABASE_64 * ECFP_T7,
+ ECFP_ALPHABASE_64 * ECFP_T8,
+ ECFP_ALPHABASE_64 * ECFP_T9,
+ ECFP_ALPHABASE_64 * ECFP_T10,
+ ECFP_ALPHABASE_64 * ECFP_T11,
+ ECFP_ALPHABASE_64 * ECFP_T12,
+ ECFP_ALPHABASE_64 * ECFP_T13,
+ ECFP_ALPHABASE_64 * ECFP_T14,
+ ECFP_ALPHABASE_64 * ECFP_T15,
+ ECFP_ALPHABASE_64 * ECFP_T16,
+ ECFP_ALPHABASE_64 * ECFP_T17,
+ ECFP_ALPHABASE_64 * ECFP_T18,
+ ECFP_ALPHABASE_64 * ECFP_T19
+};
+
+/* 0.011111111111111111111111 (binary) = 0.5 - 2^25 (24 ones) */
+#define ECFP_BETABASE 0.4999999701976776123046875
+
+/*
+ * We subtract beta prior to using alpha to simulate rounding down. We
+ * make this close to 0.5 to round almost everything down, but exactly 0.5
+ * would cause some incorrect rounding. */
+static const double ecfp_beta[2 * ECFP_MAXDOUBLES] = {
+ ECFP_BETABASE * ECFP_T0,
+ ECFP_BETABASE * ECFP_T1,
+ ECFP_BETABASE * ECFP_T2,
+ ECFP_BETABASE * ECFP_T3,
+ ECFP_BETABASE * ECFP_T4,
+ ECFP_BETABASE * ECFP_T5,
+ ECFP_BETABASE * ECFP_T6,
+ ECFP_BETABASE * ECFP_T7,
+ ECFP_BETABASE * ECFP_T8,
+ ECFP_BETABASE * ECFP_T9,
+ ECFP_BETABASE * ECFP_T10,
+ ECFP_BETABASE * ECFP_T11,
+ ECFP_BETABASE * ECFP_T12,
+ ECFP_BETABASE * ECFP_T13,
+ ECFP_BETABASE * ECFP_T14,
+ ECFP_BETABASE * ECFP_T15,
+ ECFP_BETABASE * ECFP_T16,
+ ECFP_BETABASE * ECFP_T17,
+ ECFP_BETABASE * ECFP_T18,
+ ECFP_BETABASE * ECFP_T19
+};
+
+static const double ecfp_beta_160 = ECFP_BETABASE * ECFP_TWO160;
+static const double ecfp_beta_192 = ECFP_BETABASE * ECFP_TWO192;
+static const double ecfp_beta_224 = ECFP_BETABASE * ECFP_TWO224;
+
+/* Affine EC Point. This is the basic representation (x, y) of an elliptic
+ * curve point. */
+typedef struct {
+ double x[ECFP_MAXDOUBLES];
+ double y[ECFP_MAXDOUBLES];
+} ecfp_aff_pt;
+
+/* Jacobian EC Point. This coordinate system uses X = x/z^2, Y = y/z^3,
+ * which enables calculations with fewer inversions than affine
+ * coordinates. */
+typedef struct {
+ double x[ECFP_MAXDOUBLES];
+ double y[ECFP_MAXDOUBLES];
+ double z[ECFP_MAXDOUBLES];
+} ecfp_jac_pt;
+
+/* Chudnovsky Jacobian EC Point. This coordinate system is the same as
+ * Jacobian, except it keeps z^2, z^3 for faster additions. */
+typedef struct {
+ double x[ECFP_MAXDOUBLES];
+ double y[ECFP_MAXDOUBLES];
+ double z[ECFP_MAXDOUBLES];
+ double z2[ECFP_MAXDOUBLES];
+ double z3[ECFP_MAXDOUBLES];
+} ecfp_chud_pt;
+
+/* Modified Jacobian EC Point. This coordinate system is the same as
+ * Jacobian, except it keeps a*z^4 for faster doublings. */
+typedef struct {
+ double x[ECFP_MAXDOUBLES];
+ double y[ECFP_MAXDOUBLES];
+ double z[ECFP_MAXDOUBLES];
+ double az4[ECFP_MAXDOUBLES];
+} ecfp_jm_pt;
+
+struct EC_group_fp_str;
+
+typedef struct EC_group_fp_str EC_group_fp;
+struct EC_group_fp_str {
+ int fpPrecision; /* Set to number of bits in mantissa, 53
+ * or 64 */
+ int numDoubles;
+ int primeBitSize;
+ int orderBitSize;
+ int doubleBitSize;
+ int numInts;
+ int aIsM3; /* True if curvea == -3 (mod p), then we
+ * can optimize doubling */
+ double curvea[ECFP_MAXDOUBLES];
+ /* Used to truncate a double to the number of bits in the curve */
+ double bitSize_alpha;
+ /* Pointer to either ecfp_alpha_53 or ecfp_alpha_64 */
+ const double *alpha;
+
+ void (*ecfp_singleReduce) (double *r, const EC_group_fp * group);
+ void (*ecfp_reduce) (double *r, double *x, const EC_group_fp * group);
+ /* Performs a "tidy" operation, which performs carrying, moving excess
+ * bits from one double to the next double, so that the precision of
+ * the doubles is reduced to the regular precision ECFP_DSIZE. This
+ * might result in some float digits being negative. */
+ void (*ecfp_tidy) (double *t, const double *alpha,
+ const EC_group_fp * group);
+ /* Perform a point addition using coordinate system Jacobian + Affine
+ * -> Jacobian. Input and output should be multi-precision floating
+ * point integers. */
+ void (*pt_add_jac_aff) (const ecfp_jac_pt * p, const ecfp_aff_pt * q,
+ ecfp_jac_pt * r, const EC_group_fp * group);
+ /* Perform a point doubling in Jacobian coordinates. Input and output
+ * should be multi-precision floating point integers. */
+ void (*pt_dbl_jac) (const ecfp_jac_pt * dp, ecfp_jac_pt * dr,
+ const EC_group_fp * group);
+ /* Perform a point addition using Jacobian coordinate system. Input
+ * and output should be multi-precision floating point integers. */
+ void (*pt_add_jac) (const ecfp_jac_pt * p, const ecfp_jac_pt * q,
+ ecfp_jac_pt * r, const EC_group_fp * group);
+ /* Perform a point doubling in Modified Jacobian coordinates. Input
+ * and output should be multi-precision floating point integers. */
+ void (*pt_dbl_jm) (const ecfp_jm_pt * p, ecfp_jm_pt * r,
+ const EC_group_fp * group);
+ /* Perform a point doubling using coordinates Affine -> Chudnovsky
+ * Jacobian. Input and output should be multi-precision floating point
+ * integers. */
+ void (*pt_dbl_aff2chud) (const ecfp_aff_pt * p, ecfp_chud_pt * r,
+ const EC_group_fp * group);
+ /* Perform a point addition using coordinates: Modified Jacobian +
+ * Chudnovsky Jacobian -> Modified Jacobian. Input and output should
+ * be multi-precision floating point integers. */
+ void (*pt_add_jm_chud) (ecfp_jm_pt * p, ecfp_chud_pt * q,
+ ecfp_jm_pt * r, const EC_group_fp * group);
+ /* Perform a point addition using Chudnovsky Jacobian coordinates.
+ * Input and output should be multi-precision floating point integers.
+ */
+ void (*pt_add_chud) (const ecfp_chud_pt * p, const ecfp_chud_pt * q,
+ ecfp_chud_pt * r, const EC_group_fp * group);
+ /* Expects out to be an array of size 16 of Chudnovsky Jacobian
+ * points. Fills in Chudnovsky Jacobian form (x, y, z, z^2, z^3), for
+ * -15P, -13P, -11P, -9P, -7P, -5P, -3P, -P, P, 3P, 5P, 7P, 9P, 11P,
+ * 13P, 15P */
+ void (*precompute_chud) (ecfp_chud_pt * out, const ecfp_aff_pt * p,
+ const EC_group_fp * group);
+ /* Expects out to be an array of size 16 of Jacobian points. Fills in
+ * Chudnovsky Jacobian form (x, y, z), for O, P, 2P, ... 15P */
+ void (*precompute_jac) (ecfp_jac_pt * out, const ecfp_aff_pt * p,
+ const EC_group_fp * group);
+
+};
+
+/* Computes r = x*y.
+ * r must be different (point to different memory) than x and y.
+ * Does not tidy or reduce. */
+void ecfp_multiply(double *r, const double *x, const double *y);
+
+/* Performs a "tidy" operation, which performs carrying, moving excess
+ * bits from one double to the next double, so that the precision of the
+ * doubles is reduced to the regular precision group->doubleBitSize. This
+ * might result in some float digits being negative. */
+void ecfp_tidy(double *t, const double *alpha, const EC_group_fp * group);
+
+/* Performs tidying on only the upper float digits of a multi-precision
+ * floating point integer, i.e. the digits beyond the regular length which
+ * are removed in the reduction step. */
+void ecfp_tidyUpper(double *t, const EC_group_fp * group);
+
+/* Performs tidying on a short multi-precision floating point integer (the
+ * lower group->numDoubles floats). */
+void ecfp_tidyShort(double *t, const EC_group_fp * group);
+
+/* Performs a more mathematically precise "tidying" so that each term is
+ * positive. This is slower than the regular tidying, and is used for
+ * conversion from floating point to integer. */
+void ecfp_positiveTidy(double *t, const EC_group_fp * group);
+
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GFp. Elliptic curve points P and R can be
+ * identical. Uses mixed Jacobian-affine coordinates. Uses 4-bit window
+ * method. */
+mp_err
+ ec_GFp_point_mul_jac_4w_fp(const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *ecgroup);
+
+/* Computes R = nP where R is (rx, ry) and P is the base point. The
+ * parameters a, b and p are the elliptic curve coefficients and the prime
+ * that determines the field GFp. Elliptic curve points P and R can be
+ * identical. Uses mixed Jacobian-affine coordinates (Jacobian
+ * coordinates for doubles and affine coordinates for additions; based on
+ * recommendation from Brown et al.). Uses window NAF method (algorithm
+ * 11) for scalar-point multiplication from Brown, Hankerson, Lopez,
+ * Menezes. Software Implementation of the NIST Elliptic Curves Over Prime
+ * Fields. */
+mp_err ec_GFp_point_mul_wNAF_fp(const mp_int *n, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *ecgroup);
+
+/* Uses mixed Jacobian-affine coordinates to perform a point
+ * multiplication: R = n * P, n scalar. Uses mixed Jacobian-affine
+ * coordinates (Jacobian coordinates for doubles and affine coordinates
+ * for additions; based on recommendation from Brown et al.). Not very
+ * time efficient but quite space efficient, no precomputation needed.
+ * group contains the elliptic curve coefficients and the prime that
+ * determines the field GFp. Elliptic curve points P and R can be
+ * identical. Performs calculations in floating point number format, since
+ * this is faster than the integer operations on the ULTRASPARC III.
+ * Uses left-to-right binary method (double & add) (algorithm 9) for
+ * scalar-point multiplication from Brown, Hankerson, Lopez, Menezes.
+ * Software Implementation of the NIST Elliptic Curves Over Prime Fields. */
+mp_err
+ ec_GFp_pt_mul_jac_fp(const mp_int *n, const mp_int *px, const mp_int *py,
+ mp_int *rx, mp_int *ry, const ECGroup *ecgroup);
+
+/* Cleans up extra memory allocated in ECGroup for this implementation. */
+void ec_GFp_extra_free_fp(ECGroup *group);
+
+/* Converts from a floating point representation into an mp_int. Expects
+ * that d is already reduced. */
+void
+ ecfp_fp2i(mp_int *mpout, double *d, const ECGroup *ecgroup);
+
+/* Converts from an mpint into a floating point representation. */
+void
+ ecfp_i2fp(double *out, const mp_int *x, const ECGroup *ecgroup);
+
+/* Tests what precision floating point arithmetic is set to. This should
+ * be either a 53-bit mantissa (IEEE standard) or a 64-bit mantissa
+ * (extended precision on x86) and sets it into the EC_group_fp. Returns
+ * either 53 or 64 accordingly. */
+int ec_set_fp_precision(EC_group_fp * group);
+
+#endif
diff --git a/security/nss/lib/freebl/ecl/ecp_fp160.c b/security/nss/lib/freebl/ecl/ecp_fp160.c
new file mode 100644
index 000000000..57399d494
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_fp160.c
@@ -0,0 +1,178 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves using floating point operations.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecp_fp.h"
+#include <stdlib.h>
+
+#define ECFP_BSIZE 160
+#define ECFP_NUMDOUBLES 7
+
+#include "ecp_fpinc.c"
+
+/* Performs a single step of reduction, just on the uppermost float
+ * (assumes already tidied), and then retidies. Note, this does not
+ * guarantee that the result will be less than p, but truncates the number
+ * of bits. */
+void
+ecfp160_singleReduce(double *d, const EC_group_fp * group)
+{
+ double q;
+
+ ECFP_ASSERT(group->doubleBitSize == 24);
+ ECFP_ASSERT(group->primeBitSize == 160);
+ ECFP_ASSERT(ECFP_NUMDOUBLES == 7);
+
+ q = d[ECFP_NUMDOUBLES - 1] - ecfp_beta_160;
+ q += group->bitSize_alpha;
+ q -= group->bitSize_alpha;
+
+ d[ECFP_NUMDOUBLES - 1] -= q;
+ d[0] += q * ecfp_twom160;
+ d[1] += q * ecfp_twom129;
+ ecfp_positiveTidy(d, group);
+
+ /* Assertions for the highest order term */
+ ECFP_ASSERT(d[ECFP_NUMDOUBLES - 1] / ecfp_exp[ECFP_NUMDOUBLES - 1] ==
+ (unsigned long long) (d[ECFP_NUMDOUBLES - 1] /
+ ecfp_exp[ECFP_NUMDOUBLES - 1]));
+ ECFP_ASSERT(d[ECFP_NUMDOUBLES - 1] >= 0);
+}
+
+/* Performs imperfect reduction. This might leave some negative terms,
+ * and one more reduction might be required for the result to be between 0
+ * and p-1. x should not already be reduced, i.e. should have
+ * 2*ECFP_NUMDOUBLES significant terms. x and r can be the same, but then
+ * the upper parts of r are not zeroed */
+void
+ecfp160_reduce(double *r, double *x, const EC_group_fp * group)
+{
+
+ double x7, x8, q;
+
+ ECFP_ASSERT(group->doubleBitSize == 24);
+ ECFP_ASSERT(group->primeBitSize == 160);
+ ECFP_ASSERT(ECFP_NUMDOUBLES == 7);
+
+ /* Tidy just the upper bits, the lower bits can wait. */
+ ecfp_tidyUpper(x, group);
+
+ /* Assume that this is already tidied so that we have enough extra
+ * bits */
+ x7 = x[7] + x[13] * ecfp_twom129; /* adds bits 15-39 */
+
+ /* Tidy x7, or we won't have enough bits later to add it in */
+ q = x7 + group->alpha[8];
+ q -= group->alpha[8];
+ x7 -= q; /* holds bits 0-24 */
+ x8 = x[8] + q; /* holds bits 0-25 */
+
+ r[6] = x[6] + x[13] * ecfp_twom160 + x[12] * ecfp_twom129; /* adds
+ * bits
+ * 8-39 */
+ r[5] = x[5] + x[12] * ecfp_twom160 + x[11] * ecfp_twom129;
+ r[4] = x[4] + x[11] * ecfp_twom160 + x[10] * ecfp_twom129;
+ r[3] = x[3] + x[10] * ecfp_twom160 + x[9] * ecfp_twom129;
+ r[2] = x[2] + x[9] * ecfp_twom160 + x8 * ecfp_twom129; /* adds bits
+ * 8-40 */
+ r[1] = x[1] + x8 * ecfp_twom160 + x7 * ecfp_twom129; /* adds bits
+ * 8-39 */
+ r[0] = x[0] + x7 * ecfp_twom160;
+
+ /* Tidy up just r[ECFP_NUMDOUBLES-2] so that the number of reductions
+ * is accurate plus or minus one. (Rather than tidy all to make it
+ * totally accurate, which is more costly.) */
+ q = r[ECFP_NUMDOUBLES - 2] + group->alpha[ECFP_NUMDOUBLES - 1];
+ q -= group->alpha[ECFP_NUMDOUBLES - 1];
+ r[ECFP_NUMDOUBLES - 2] -= q;
+ r[ECFP_NUMDOUBLES - 1] += q;
+
+ /* Tidy up the excess bits on r[ECFP_NUMDOUBLES-1] using reduction */
+ /* Use ecfp_beta so we get a positive result */
+ q = r[ECFP_NUMDOUBLES - 1] - ecfp_beta_160;
+ q += group->bitSize_alpha;
+ q -= group->bitSize_alpha;
+
+ r[ECFP_NUMDOUBLES - 1] -= q;
+ r[0] += q * ecfp_twom160;
+ r[1] += q * ecfp_twom129;
+
+ /* Tidy the result */
+ ecfp_tidyShort(r, group);
+}
+
+/* Sets group to use optimized calculations in this file */
+mp_err
+ec_group_set_secp160r1_fp(ECGroup *group)
+{
+
+ EC_group_fp *fpg = NULL;
+
+ /* Allocate memory for floating point group data */
+ fpg = (EC_group_fp *) malloc(sizeof(EC_group_fp));
+ if (fpg == NULL) {
+ return MP_MEM;
+ }
+
+ fpg->numDoubles = ECFP_NUMDOUBLES;
+ fpg->primeBitSize = ECFP_BSIZE;
+ fpg->orderBitSize = 161;
+ fpg->doubleBitSize = 24;
+ fpg->numInts = (ECFP_BSIZE + ECL_BITS - 1) / ECL_BITS;
+ fpg->aIsM3 = 1;
+ fpg->ecfp_singleReduce = &ecfp160_singleReduce;
+ fpg->ecfp_reduce = &ecfp160_reduce;
+ fpg->ecfp_tidy = &ecfp_tidy;
+
+ fpg->pt_add_jac_aff = &ecfp160_pt_add_jac_aff;
+ fpg->pt_add_jac = &ecfp160_pt_add_jac;
+ fpg->pt_add_jm_chud = &ecfp160_pt_add_jm_chud;
+ fpg->pt_add_chud = &ecfp160_pt_add_chud;
+ fpg->pt_dbl_jac = &ecfp160_pt_dbl_jac;
+ fpg->pt_dbl_jm = &ecfp160_pt_dbl_jm;
+ fpg->pt_dbl_aff2chud = &ecfp160_pt_dbl_aff2chud;
+ fpg->precompute_chud = &ecfp160_precompute_chud;
+ fpg->precompute_jac = &ecfp160_precompute_jac;
+
+ group->point_mul = &ec_GFp_point_mul_wNAF_fp;
+ group->points_mul = &ec_pts_mul_basic;
+ group->extra1 = fpg;
+ group->extra_free = &ec_GFp_extra_free_fp;
+
+ ec_set_fp_precision(fpg);
+ fpg->bitSize_alpha = ECFP_TWO160 * fpg->alpha[0];
+ return MP_OKAY;
+}
diff --git a/security/nss/lib/freebl/ecl/ecp_fp192.c b/security/nss/lib/freebl/ecl/ecp_fp192.c
new file mode 100644
index 000000000..2e143aa49
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_fp192.c
@@ -0,0 +1,176 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves using floating point operations.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecp_fp.h"
+#include <stdlib.h>
+
+#define ECFP_BSIZE 192
+#define ECFP_NUMDOUBLES 8
+
+#include "ecp_fpinc.c"
+
+/* Performs a single step of reduction, just on the uppermost float
+ * (assumes already tidied), and then retidies. Note, this does not
+ * guarantee that the result will be less than p. */
+void
+ecfp192_singleReduce(double *d, const EC_group_fp * group)
+{
+ double q;
+
+ ECFP_ASSERT(group->doubleBitSize == 24);
+ ECFP_ASSERT(group->primeBitSize == 192);
+ ECFP_ASSERT(group->numDoubles == 8);
+
+ q = d[ECFP_NUMDOUBLES - 1] - ecfp_beta_192;
+ q += group->bitSize_alpha;
+ q -= group->bitSize_alpha;
+
+ d[ECFP_NUMDOUBLES - 1] -= q;
+ d[0] += q * ecfp_twom192;
+ d[2] += q * ecfp_twom128;
+ ecfp_positiveTidy(d, group);
+}
+
+/*
+ * Performs imperfect reduction. This might leave some negative terms,
+ * and one more reduction might be required for the result to be between 0
+ * and p-1. x should be be an array of at least 16, and r at least 8 x and
+ * r can be the same, but then the upper parts of r are not zeroed */
+void
+ecfp_reduce_192(double *r, double *x, const EC_group_fp * group)
+{
+ double x8, x9, x10, q;
+
+ ECFP_ASSERT(group->doubleBitSize == 24);
+ ECFP_ASSERT(group->primeBitSize == 192);
+ ECFP_ASSERT(group->numDoubles == 8);
+
+ /* Tidy just the upper portion, the lower part can wait */
+ ecfp_tidyUpper(x, group);
+
+ x8 = x[8] + x[14] * ecfp_twom128; /* adds bits 16-40 */
+ x9 = x[9] + x[15] * ecfp_twom128; /* adds bits 16-40 */
+
+ /* Tidy up, or we won't have enough bits later to add it in */
+
+ q = x8 + group->alpha[9];
+ q -= group->alpha[9];
+ x8 -= q;
+ x9 += q;
+
+ q = x9 + group->alpha[10];
+ q -= group->alpha[10];
+ x9 -= q;
+ x10 = x[10] + q;
+
+ r[7] = x[7] + x[15] * ecfp_twom192 + x[13] * ecfp_twom128; /* adds
+ * bits
+ * 0-40 */
+ r[6] = x[6] + x[14] * ecfp_twom192 + x[12] * ecfp_twom128;
+ r[5] = x[5] + x[13] * ecfp_twom192 + x[11] * ecfp_twom128;
+ r[4] = x[4] + x[12] * ecfp_twom192 + x10 * ecfp_twom128;
+ r[3] = x[3] + x[11] * ecfp_twom192 + x9 * ecfp_twom128; /* adds bits
+ * 0-40 */
+ r[2] = x[2] + x10 * ecfp_twom192 + x8 * ecfp_twom128;
+ r[1] = x[1] + x9 * ecfp_twom192; /* adds bits 16-40 */
+ r[0] = x[0] + x8 * ecfp_twom192;
+
+ /*
+ * Tidy up just r[group->numDoubles-2] so that the number of
+ * reductions is accurate plus or minus one. (Rather than tidy all to
+ * make it totally accurate) */
+ q = r[ECFP_NUMDOUBLES - 2] + group->alpha[ECFP_NUMDOUBLES - 1];
+ q -= group->alpha[ECFP_NUMDOUBLES - 1];
+ r[ECFP_NUMDOUBLES - 2] -= q;
+ r[ECFP_NUMDOUBLES - 1] += q;
+
+ /* Tidy up the excess bits on r[group->numDoubles-1] using reduction */
+ /* Use ecfp_beta so we get a positive res */
+ q = r[ECFP_NUMDOUBLES - 1] - ecfp_beta_192;
+ q += group->bitSize_alpha;
+ q -= group->bitSize_alpha;
+
+ r[ECFP_NUMDOUBLES - 1] -= q;
+ r[0] += q * ecfp_twom192;
+ r[2] += q * ecfp_twom128;
+
+ /* Tidy the result */
+ ecfp_tidyShort(r, group);
+}
+
+/* Sets group to use optimized calculations in this file */
+mp_err
+ec_group_set_nistp192_fp(ECGroup *group)
+{
+ EC_group_fp *fpg;
+
+ /* Allocate memory for floating point group data */
+ fpg = (EC_group_fp *) malloc(sizeof(EC_group_fp));
+ if (fpg == NULL) {
+ return MP_MEM;
+ }
+
+ fpg->numDoubles = ECFP_NUMDOUBLES;
+ fpg->primeBitSize = ECFP_BSIZE;
+ fpg->orderBitSize = 192;
+ fpg->doubleBitSize = 24;
+ fpg->numInts = (ECFP_BSIZE + ECL_BITS - 1) / ECL_BITS;
+ fpg->aIsM3 = 1;
+ fpg->ecfp_singleReduce = &ecfp192_singleReduce;
+ fpg->ecfp_reduce = &ecfp_reduce_192;
+ fpg->ecfp_tidy = &ecfp_tidy;
+
+ fpg->pt_add_jac_aff = &ecfp192_pt_add_jac_aff;
+ fpg->pt_add_jac = &ecfp192_pt_add_jac;
+ fpg->pt_add_jm_chud = &ecfp192_pt_add_jm_chud;
+ fpg->pt_add_chud = &ecfp192_pt_add_chud;
+ fpg->pt_dbl_jac = &ecfp192_pt_dbl_jac;
+ fpg->pt_dbl_jm = &ecfp192_pt_dbl_jm;
+ fpg->pt_dbl_aff2chud = &ecfp192_pt_dbl_aff2chud;
+ fpg->precompute_chud = &ecfp192_precompute_chud;
+ fpg->precompute_jac = &ecfp192_precompute_jac;
+
+ group->point_mul = &ec_GFp_point_mul_wNAF_fp;
+ group->points_mul = &ec_pts_mul_basic;
+ group->extra1 = fpg;
+ group->extra_free = &ec_GFp_extra_free_fp;
+
+ ec_set_fp_precision(fpg);
+ fpg->bitSize_alpha = ECFP_TWO192 * fpg->alpha[0];
+
+ return MP_OKAY;
+}
diff --git a/security/nss/lib/freebl/ecl/ecp_fp224.c b/security/nss/lib/freebl/ecl/ecp_fp224.c
new file mode 100644
index 000000000..f32e8d717
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_fp224.c
@@ -0,0 +1,189 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves using floating point operations.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecp_fp.h"
+#include <stdlib.h>
+
+#define ECFP_BSIZE 224
+#define ECFP_NUMDOUBLES 10
+
+#include "ecp_fpinc.c"
+
+/* Performs a single step of reduction, just on the uppermost float
+ * (assumes already tidied), and then retidies. Note, this does not
+ * guarantee that the result will be less than p. */
+void
+ecfp224_singleReduce(double *r, const EC_group_fp * group)
+{
+ double q;
+
+ ECFP_ASSERT(group->doubleBitSize == 24);
+ ECFP_ASSERT(group->primeBitSize == 224);
+ ECFP_ASSERT(group->numDoubles == 10);
+
+ q = r[ECFP_NUMDOUBLES - 1] - ecfp_beta_224;
+ q += group->bitSize_alpha;
+ q -= group->bitSize_alpha;
+
+ r[ECFP_NUMDOUBLES - 1] -= q;
+ r[0] -= q * ecfp_twom224;
+ r[4] += q * ecfp_twom128;
+
+ ecfp_positiveTidy(r, group);
+}
+
+/*
+ * Performs imperfect reduction. This might leave some negative terms,
+ * and one more reduction might be required for the result to be between 0
+ * and p-1. x should be be an array of at least 20, and r at least 10 x
+ * and r can be the same, but then the upper parts of r are not zeroed */
+void
+ecfp224_reduce(double *r, double *x, const EC_group_fp * group)
+{
+
+ double x10, x11, x12, x13, x14, q;
+
+ ECFP_ASSERT(group->doubleBitSize == 24);
+ ECFP_ASSERT(group->primeBitSize == 224);
+ ECFP_ASSERT(group->numDoubles == 10);
+
+ /* Tidy just the upper bits of x. Don't need to tidy the lower ones
+ * yet. */
+ ecfp_tidyUpper(x, group);
+
+ x10 = x[10] + x[16] * ecfp_twom128;
+ x11 = x[11] + x[17] * ecfp_twom128;
+ x12 = x[12] + x[18] * ecfp_twom128;
+ x13 = x[13] + x[19] * ecfp_twom128;
+
+ /* Tidy up, or we won't have enough bits later to add it in */
+ q = x10 + group->alpha[11];
+ q -= group->alpha[11];
+ x10 -= q;
+ x11 = x11 + q;
+
+ q = x11 + group->alpha[12];
+ q -= group->alpha[12];
+ x11 -= q;
+ x12 = x12 + q;
+
+ q = x12 + group->alpha[13];
+ q -= group->alpha[13];
+ x12 -= q;
+ x13 = x13 + q;
+
+ q = x13 + group->alpha[14];
+ q -= group->alpha[14];
+ x13 -= q;
+ x14 = x[14] + q;
+
+ r[9] = x[9] + x[15] * ecfp_twom128 - x[19] * ecfp_twom224;
+ r[8] = x[8] + x14 * ecfp_twom128 - x[18] * ecfp_twom224;
+ r[7] = x[7] + x13 * ecfp_twom128 - x[17] * ecfp_twom224;
+ r[6] = x[6] + x12 * ecfp_twom128 - x[16] * ecfp_twom224;
+ r[5] = x[5] + x11 * ecfp_twom128 - x[15] * ecfp_twom224;
+ r[4] = x[4] + x10 * ecfp_twom128 - x14 * ecfp_twom224;
+ r[3] = x[3] - x13 * ecfp_twom224;
+ r[2] = x[2] - x12 * ecfp_twom224;
+ r[1] = x[1] - x11 * ecfp_twom224;
+ r[0] = x[0] - x10 * ecfp_twom224;
+
+ /*
+ * Tidy up just r[ECFP_NUMDOUBLES-2] so that the number of reductions
+ * is accurate plus or minus one. (Rather than tidy all to make it
+ * totally accurate) */
+ q = r[ECFP_NUMDOUBLES - 2] + group->alpha[ECFP_NUMDOUBLES - 1];
+ q -= group->alpha[ECFP_NUMDOUBLES - 1];
+ r[ECFP_NUMDOUBLES - 2] -= q;
+ r[ECFP_NUMDOUBLES - 1] += q;
+
+ /* Tidy up the excess bits on r[ECFP_NUMDOUBLES-1] using reduction */
+ /* Use ecfp_beta so we get a positive res */
+ q = r[ECFP_NUMDOUBLES - 1] - ecfp_beta_224;
+ q += group->bitSize_alpha;
+ q -= group->bitSize_alpha;
+
+ r[ECFP_NUMDOUBLES - 1] -= q;
+ r[0] -= q * ecfp_twom224;
+ r[4] += q * ecfp_twom128;
+
+ ecfp_tidyShort(r, group);
+}
+
+/* Sets group to use optimized calculations in this file */
+mp_err
+ec_group_set_nistp224_fp(ECGroup *group)
+{
+
+ EC_group_fp *fpg;
+
+ /* Allocate memory for floating point group data */
+ fpg = (EC_group_fp *) malloc(sizeof(EC_group_fp));
+ if (fpg == NULL) {
+ return MP_MEM;
+ }
+
+ fpg->numDoubles = ECFP_NUMDOUBLES;
+ fpg->primeBitSize = ECFP_BSIZE;
+ fpg->orderBitSize = 224;
+ fpg->doubleBitSize = 24;
+ fpg->numInts = (ECFP_BSIZE + ECL_BITS - 1) / ECL_BITS;
+ fpg->aIsM3 = 1;
+ fpg->ecfp_singleReduce = &ecfp224_singleReduce;
+ fpg->ecfp_reduce = &ecfp224_reduce;
+ fpg->ecfp_tidy = &ecfp_tidy;
+
+ fpg->pt_add_jac_aff = &ecfp224_pt_add_jac_aff;
+ fpg->pt_add_jac = &ecfp224_pt_add_jac;
+ fpg->pt_add_jm_chud = &ecfp224_pt_add_jm_chud;
+ fpg->pt_add_chud = &ecfp224_pt_add_chud;
+ fpg->pt_dbl_jac = &ecfp224_pt_dbl_jac;
+ fpg->pt_dbl_jm = &ecfp224_pt_dbl_jm;
+ fpg->pt_dbl_aff2chud = &ecfp224_pt_dbl_aff2chud;
+ fpg->precompute_chud = &ecfp224_precompute_chud;
+ fpg->precompute_jac = &ecfp224_precompute_jac;
+
+ group->point_mul = &ec_GFp_point_mul_wNAF_fp;
+ group->points_mul = &ec_pts_mul_basic;
+ group->extra1 = fpg;
+ group->extra_free = &ec_GFp_extra_free_fp;
+
+ ec_set_fp_precision(fpg);
+ fpg->bitSize_alpha = ECFP_TWO224 * fpg->alpha[0];
+
+ return MP_OKAY;
+}
diff --git a/security/nss/lib/freebl/ecl/ecp_fpinc.c b/security/nss/lib/freebl/ecl/ecp_fpinc.c
new file mode 100644
index 000000000..e05e478ef
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_fpinc.c
@@ -0,0 +1,854 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves using floating point operations.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+/* This source file is meant to be included by other source files
+ * (ecp_fp###.c, where ### is one of 160, 192, 224) and should not
+ * constitute an independent compilation unit. It requires the following
+ * preprocessor definitions be made: ECFP_BSIZE - the number of bits in
+ * the field's prime
+ * ECFP_NUMDOUBLES - the number of doubles to store one
+ * multi-precision integer in floating point
+
+/* Adds a prefix to a given token to give a unique token name. Prefixes
+ * with "ecfp" + ECFP_BSIZE + "_". e.g. if ECFP_BSIZE = 160, then
+ * PREFIX(hello) = ecfp160_hello This optimization allows static function
+ * linking and compiler loop unrolling without code duplication. */
+#ifndef PREFIX
+#define PREFIX(b) PREFIX1(ECFP_BSIZE, b)
+#define PREFIX1(bsize, b) PREFIX2(bsize, b)
+#define PREFIX2(bsize, b) ecfp ## bsize ## _ ## b
+#endif
+
+/* Returns true iff every double in d is 0. (If d == 0 and it is tidied,
+ * this will be true.) */
+mp_err PREFIX(isZero) (const double *d) {
+ int i;
+
+ for (i = 0; i < ECFP_NUMDOUBLES; i++) {
+ if (d[i] != 0)
+ return MP_NO;
+ }
+ return MP_YES;
+}
+
+/* Sets the multi-precision floating point number at t = 0 */
+void PREFIX(zero) (double *t) {
+ int i;
+
+ for (i = 0; i < ECFP_NUMDOUBLES; i++) {
+ t[i] = 0;
+ }
+}
+
+/* Sets the multi-precision floating point number at t = 1 */
+void PREFIX(one) (double *t) {
+ int i;
+
+ t[0] = 1;
+ for (i = 1; i < ECFP_NUMDOUBLES; i++) {
+ t[i] = 0;
+ }
+}
+
+/* Checks if point P(x, y, z) is at infinity. Uses Jacobian coordinates. */
+mp_err PREFIX(pt_is_inf_jac) (const ecfp_jac_pt * p) {
+ return PREFIX(isZero) (p->z);
+}
+
+/* Sets the Jacobian point P to be at infinity. */
+void PREFIX(set_pt_inf_jac) (ecfp_jac_pt * p) {
+ PREFIX(zero) (p->z);
+}
+
+/* Checks if point P(x, y) is at infinity. Uses Affine coordinates. */
+mp_err PREFIX(pt_is_inf_aff) (const ecfp_aff_pt * p) {
+ if (PREFIX(isZero) (p->x) == MP_YES && PREFIX(isZero) (p->y) == MP_YES)
+ return MP_YES;
+ return MP_NO;
+}
+
+/* Sets the affine point P to be at infinity. */
+void PREFIX(set_pt_inf_aff) (ecfp_aff_pt * p) {
+ PREFIX(zero) (p->x);
+ PREFIX(zero) (p->y);
+}
+
+/* Checks if point P(x, y, z, a*z^4) is at infinity. Uses Modified
+ * Jacobian coordinates. */
+mp_err PREFIX(pt_is_inf_jm) (const ecfp_jm_pt * p) {
+ return PREFIX(isZero) (p->z);
+}
+
+/* Sets the Modified Jacobian point P to be at infinity. */
+void PREFIX(set_pt_inf_jm) (ecfp_jm_pt * p) {
+ PREFIX(zero) (p->z);
+}
+
+/* Checks if point P(x, y, z, z^2, z^3) is at infinity. Uses Chudnovsky
+ * Jacobian coordinates */
+mp_err PREFIX(pt_is_inf_chud) (const ecfp_chud_pt * p) {
+ return PREFIX(isZero) (p->z);
+}
+
+/* Sets the Chudnovsky Jacobian point P to be at infinity. */
+void PREFIX(set_pt_inf_chud) (ecfp_chud_pt * p) {
+ PREFIX(zero) (p->z);
+}
+
+/* Copies a multi-precision floating point number, Setting dest = src */
+void PREFIX(copy) (double *dest, const double *src) {
+ int i;
+
+ for (i = 0; i < ECFP_NUMDOUBLES; i++) {
+ dest[i] = src[i];
+ }
+}
+
+/* Sets dest = -src */
+void PREFIX(negLong) (double *dest, const double *src) {
+ int i;
+
+ for (i = 0; i < 2 * ECFP_NUMDOUBLES; i++) {
+ dest[i] = -src[i];
+ }
+}
+
+/* Sets r = -p p = (x, y, z, z2, z3) r = (x, -y, z, z2, z3) Uses
+ * Chudnovsky Jacobian coordinates. */
+/* TODO reverse order */
+void PREFIX(pt_neg_chud) (const ecfp_chud_pt * p, ecfp_chud_pt * r) {
+ int i;
+
+ PREFIX(copy) (r->x, p->x);
+ PREFIX(copy) (r->z, p->z);
+ PREFIX(copy) (r->z2, p->z2);
+ PREFIX(copy) (r->z3, p->z3);
+ for (i = 0; i < ECFP_NUMDOUBLES; i++) {
+ r->y[i] = -p->y[i];
+ }
+}
+
+/* Computes r = x + y. Does not tidy or reduce. Any combinations of r, x,
+ * y can point to the same data. Componentwise adds first ECFP_NUMDOUBLES
+ * doubles of x and y and stores the result in r. */
+void PREFIX(addShort) (double *r, const double *x, const double *y) {
+ int i;
+
+ for (i = 0; i < ECFP_NUMDOUBLES; i++) {
+ *r++ = *x++ + *y++;
+ }
+}
+
+/* Computes r = x + y. Does not tidy or reduce. Any combinations of r, x,
+ * y can point to the same data. Componentwise adds first
+ * 2*ECFP_NUMDOUBLES doubles of x and y and stores the result in r. */
+void PREFIX(addLong) (double *r, const double *x, const double *y) {
+ int i;
+
+ for (i = 0; i < 2 * ECFP_NUMDOUBLES; i++) {
+ *r++ = *x++ + *y++;
+ }
+}
+
+/* Computes r = x - y. Does not tidy or reduce. Any combinations of r, x,
+ * y can point to the same data. Componentwise subtracts first
+ * ECFP_NUMDOUBLES doubles of x and y and stores the result in r. */
+void PREFIX(subtractShort) (double *r, const double *x, const double *y) {
+ int i;
+
+ for (i = 0; i < ECFP_NUMDOUBLES; i++) {
+ *r++ = *x++ - *y++;
+ }
+}
+
+/* Computes r = x - y. Does not tidy or reduce. Any combinations of r, x,
+ * y can point to the same data. Componentwise subtracts first
+ * 2*ECFP_NUMDOUBLES doubles of x and y and stores the result in r. */
+void PREFIX(subtractLong) (double *r, const double *x, const double *y) {
+ int i;
+
+ for (i = 0; i < 2 * ECFP_NUMDOUBLES; i++) {
+ *r++ = *x++ - *y++;
+ }
+}
+
+/* Computes r = x*y. Both x and y should be tidied and reduced,
+ * r must be different (point to different memory) than x and y.
+ * Does not tidy or reduce. */
+void PREFIX(multiply)(double *r, const double *x, const double *y) {
+ int i, j;
+
+ for(j=0;j<ECFP_NUMDOUBLES-1;j++) {
+ r[j] = x[0] * y[j];
+ r[j+(ECFP_NUMDOUBLES-1)] = x[ECFP_NUMDOUBLES-1] * y[j];
+ }
+ r[ECFP_NUMDOUBLES-1] = x[0] * y[ECFP_NUMDOUBLES-1];
+ r[ECFP_NUMDOUBLES-1] += x[ECFP_NUMDOUBLES-1] * y[0];
+ r[2*ECFP_NUMDOUBLES-2] = x[ECFP_NUMDOUBLES-1] * y[ECFP_NUMDOUBLES-1];
+ r[2*ECFP_NUMDOUBLES-1] = 0;
+
+ for(i=1;i<ECFP_NUMDOUBLES-1;i++) {
+ for(j=0;j<ECFP_NUMDOUBLES;j++) {
+ r[i+j] += (x[i] * y[j]);
+ }
+ }
+}
+
+/* Computes the square of x and stores the result in r. x should be
+ * tidied & reduced, r will be neither tidied nor reduced.
+ * r should point to different memory than x */
+void PREFIX(square) (double *r, const double *x) {
+ PREFIX(multiply) (r, x, x);
+}
+
+/* Perform a point doubling in Jacobian coordinates. Input and output
+ * should be multi-precision floating point integers. */
+void PREFIX(pt_dbl_jac) (const ecfp_jac_pt * dp, ecfp_jac_pt * dr,
+ const EC_group_fp * group) {
+ double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
+ M[2 * ECFP_NUMDOUBLES], S[2 * ECFP_NUMDOUBLES];
+
+ /* Check for point at infinity */
+ if (PREFIX(pt_is_inf_jac) (dp) == MP_YES) {
+ /* Set r = pt at infinity */
+ PREFIX(set_pt_inf_jac) (dr);
+ goto CLEANUP;
+ }
+
+ /* Perform typical point doubling operations */
+
+ /* TODO? is it worthwhile to do optimizations for when pz = 1? */
+
+ if (group->aIsM3) {
+ /* When a = -3, M = 3(px - pz^2)(px + pz^2) */
+ PREFIX(square) (t1, dp->z);
+ group->ecfp_reduce(t1, t1, group); /* 2^23 since the negative
+ * rounding buys another bit */
+ PREFIX(addShort) (t0, dp->x, t1); /* 2*2^23 */
+ PREFIX(subtractShort) (t1, dp->x, t1); /* 2 * 2^23 */
+ PREFIX(multiply) (M, t0, t1); /* 40 * 2^46 */
+ PREFIX(addLong) (t0, M, M); /* 80 * 2^46 */
+ PREFIX(addLong) (M, t0, M); /* 120 * 2^46 < 2^53 */
+ group->ecfp_reduce(M, M, group);
+ } else {
+ /* Generic case */
+ /* M = 3 (px^2) + a*(pz^4) */
+ PREFIX(square) (t0, dp->x);
+ PREFIX(addLong) (M, t0, t0);
+ PREFIX(addLong) (t0, t0, M); /* t0 = 3(px^2) */
+ PREFIX(square) (M, dp->z);
+ group->ecfp_reduce(M, M, group);
+ PREFIX(square) (t1, M);
+ group->ecfp_reduce(t1, t1, group);
+ PREFIX(multiply) (M, t1, group->curvea); /* M = a(pz^4) */
+ PREFIX(addLong) (M, M, t0);
+ group->ecfp_reduce(M, M, group);
+ }
+
+ /* rz = 2 * py * pz */
+ PREFIX(multiply) (t1, dp->y, dp->z);
+ PREFIX(addLong) (t1, t1, t1);
+ group->ecfp_reduce(dr->z, t1, group);
+
+ /* t0 = 2y^2 */
+ PREFIX(square) (t0, dp->y);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(addShort) (t0, t0, t0);
+
+ /* S = 4 * px * py^2 = 2 * px * t0 */
+ PREFIX(multiply) (S, dp->x, t0);
+ PREFIX(addLong) (S, S, S);
+ group->ecfp_reduce(S, S, group);
+
+ /* rx = M^2 - 2 * S */
+ PREFIX(square) (t1, M);
+ PREFIX(subtractShort) (t1, t1, S);
+ PREFIX(subtractShort) (t1, t1, S);
+ group->ecfp_reduce(dr->x, t1, group);
+
+ /* ry = M * (S - rx) - 8 * py^4 */
+ PREFIX(square) (t1, t0); /* t1 = 4y^4 */
+ PREFIX(subtractShort) (S, S, dr->x);
+ PREFIX(multiply) (t0, M, S);
+ PREFIX(subtractLong) (t0, t0, t1);
+ PREFIX(subtractLong) (t0, t0, t1);
+ group->ecfp_reduce(dr->y, t0, group);
+
+ CLEANUP:
+ return;
+}
+
+/* Perform a point addition using coordinate system Jacobian + Affine ->
+ * Jacobian. Input and output should be multi-precision floating point
+ * integers. */
+void PREFIX(pt_add_jac_aff) (const ecfp_jac_pt * p, const ecfp_aff_pt * q,
+ ecfp_jac_pt * r, const EC_group_fp * group) {
+ /* Temporary storage */
+ double A[2 * ECFP_NUMDOUBLES], B[2 * ECFP_NUMDOUBLES],
+ C[2 * ECFP_NUMDOUBLES], C2[2 * ECFP_NUMDOUBLES],
+ D[2 * ECFP_NUMDOUBLES], C3[2 * ECFP_NUMDOUBLES];
+
+ /* Check for point at infinity for p or q */
+ if (PREFIX(pt_is_inf_aff) (q) == MP_YES) {
+ PREFIX(copy) (r->x, p->x);
+ PREFIX(copy) (r->y, p->y);
+ PREFIX(copy) (r->z, p->z);
+ goto CLEANUP;
+ } else if (PREFIX(pt_is_inf_jac) (p) == MP_YES) {
+ PREFIX(copy) (r->x, q->x);
+ PREFIX(copy) (r->y, q->y);
+ /* Since the affine point is not infinity, we can set r->z = 1 */
+ PREFIX(one) (r->z);
+ goto CLEANUP;
+ }
+
+ /* Calculates c = qx * pz^2 - px d = (qy * b - py) rx = d^2 - c^3 + 2
+ * (px * c^2) ry = d * (c-rx) - py*c^3 rz = c * pz */
+
+ /* A = pz^2, B = pz^3 */
+ PREFIX(square) (A, p->z);
+ group->ecfp_reduce(A, A, group);
+ PREFIX(multiply) (B, A, p->z);
+ group->ecfp_reduce(B, B, group);
+
+ /* C = qx * A - px */
+ PREFIX(multiply) (C, q->x, A);
+ PREFIX(subtractShort) (C, C, p->x);
+ group->ecfp_reduce(C, C, group);
+
+ /* D = qy * B - py */
+ PREFIX(multiply) (D, q->y, B);
+ PREFIX(subtractShort) (D, D, p->y);
+ group->ecfp_reduce(D, D, group);
+
+ /* C2 = C^2, C3 = C^3 */
+ PREFIX(square) (C2, C);
+ group->ecfp_reduce(C2, C2, group);
+ PREFIX(multiply) (C3, C2, C);
+ group->ecfp_reduce(C3, C3, group);
+
+ /* rz = A = pz * C */
+ PREFIX(multiply) (A, p->z, C);
+ group->ecfp_reduce(r->z, A, group);
+
+ /* C = px * C^2, untidied, unreduced */
+ PREFIX(multiply) (C, p->x, C2);
+
+ /* A = D^2, untidied, unreduced */
+ PREFIX(square) (A, D);
+
+ /* rx = B = A - C3 - C - C = D^2 - (C^3 + 2 * (px * C^2) */
+ PREFIX(subtractShort) (A, A, C3);
+ PREFIX(subtractLong) (A, A, C);
+ PREFIX(subtractLong) (A, A, C);
+ group->ecfp_reduce(r->x, A, group);
+
+ /* B = py * C3, untidied, unreduced */
+ PREFIX(multiply) (B, p->y, C3);
+
+ /* C = px * C^2 - rx */
+ PREFIX(subtractShort) (C, C, r->x);
+ group->ecfp_reduce(C, C, group);
+
+ /* ry = A = D * C - py * C^3 */
+ PREFIX(multiply) (A, D, C);
+ PREFIX(subtractLong) (A, A, B);
+ group->ecfp_reduce(r->y, A, group);
+
+ CLEANUP:
+ return;
+}
+
+/* Perform a point addition using Jacobian coordinate system. Input and
+ * output should be multi-precision floating point integers. */
+void PREFIX(pt_add_jac) (const ecfp_jac_pt * p, const ecfp_jac_pt * q,
+ ecfp_jac_pt * r, const EC_group_fp * group) {
+
+ /* Temporary Storage */
+ double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
+ U[2 * ECFP_NUMDOUBLES], R[2 * ECFP_NUMDOUBLES],
+ S[2 * ECFP_NUMDOUBLES], H[2 * ECFP_NUMDOUBLES],
+ H3[2 * ECFP_NUMDOUBLES];
+
+ /* Check for point at infinity for p, if so set r = q */
+ if (PREFIX(pt_is_inf_jac) (p) == MP_YES) {
+ PREFIX(copy) (r->x, q->x);
+ PREFIX(copy) (r->y, q->y);
+ PREFIX(copy) (r->z, q->z);
+ goto CLEANUP;
+ }
+
+ /* Check for point at infinity for p, if so set r = q */
+ if (PREFIX(pt_is_inf_jac) (q) == MP_YES) {
+ PREFIX(copy) (r->x, p->x);
+ PREFIX(copy) (r->y, p->y);
+ PREFIX(copy) (r->z, p->z);
+ goto CLEANUP;
+ }
+
+ /* U = px * qz^2 , S = py * qz^3 */
+ PREFIX(square) (t0, q->z);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(multiply) (U, p->x, t0);
+ group->ecfp_reduce(U, U, group);
+ PREFIX(multiply) (t1, t0, q->z);
+ group->ecfp_reduce(t1, t1, group);
+ PREFIX(multiply) (t0, p->y, t1);
+ group->ecfp_reduce(S, t0, group);
+
+ /* H = qx*(pz)^2 - U , R = (qy * pz^3 - S) */
+ PREFIX(square) (t0, p->z);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(multiply) (H, q->x, t0);
+ PREFIX(subtractShort) (H, H, U);
+ group->ecfp_reduce(H, H, group);
+ PREFIX(multiply) (t1, t0, p->z); /* t1 = pz^3 */
+ group->ecfp_reduce(t1, t1, group);
+ PREFIX(multiply) (t0, t1, q->y); /* t0 = qy * pz^3 */
+ PREFIX(subtractShort) (t0, t0, S);
+ group->ecfp_reduce(R, t0, group);
+
+ /* U = U*H^2, H3 = H^3 */
+ PREFIX(square) (t0, H);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(multiply) (t1, U, t0);
+ group->ecfp_reduce(U, t1, group);
+ PREFIX(multiply) (H3, t0, H);
+ group->ecfp_reduce(H3, H3, group);
+
+ /* rz = pz * qz * H */
+ PREFIX(multiply) (t0, q->z, H);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(multiply) (t1, t0, p->z);
+ group->ecfp_reduce(r->z, t1, group);
+
+ /* rx = R^2 - H^3 - 2 * U */
+ PREFIX(square) (t0, R);
+ PREFIX(subtractShort) (t0, t0, H3);
+ PREFIX(subtractShort) (t0, t0, U);
+ PREFIX(subtractShort) (t0, t0, U);
+ group->ecfp_reduce(r->x, t0, group);
+
+ /* ry = R(U - rx) - S*H3 */
+ PREFIX(subtractShort) (t1, U, r->x);
+ PREFIX(multiply) (t0, t1, R);
+ PREFIX(multiply) (t1, S, H3);
+ PREFIX(subtractLong) (t1, t0, t1);
+ group->ecfp_reduce(r->y, t1, group);
+
+ CLEANUP:
+ return;
+}
+
+/* Perform a point doubling in Modified Jacobian coordinates. Input and
+ * output should be multi-precision floating point integers. */
+void PREFIX(pt_dbl_jm) (const ecfp_jm_pt * p, ecfp_jm_pt * r,
+ const EC_group_fp * group) {
+
+ /* Temporary storage */
+ double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
+ M[2 * ECFP_NUMDOUBLES], S[2 * ECFP_NUMDOUBLES],
+ U[2 * ECFP_NUMDOUBLES], T[2 * ECFP_NUMDOUBLES];
+
+ /* Check for point at infinity */
+ if (PREFIX(pt_is_inf_jm) (p) == MP_YES) {
+ /* Set r = pt at infinity by setting rz = 0 */
+ PREFIX(set_pt_inf_jm) (r);
+ goto CLEANUP;
+ }
+
+ /* M = 3 (px^2) + a*(pz^4) */
+ PREFIX(square) (t0, p->x);
+ PREFIX(addLong) (M, t0, t0);
+ PREFIX(addLong) (t0, t0, M); /* t0 = 3(px^2) */
+ PREFIX(addShort) (t0, t0, p->az4);
+ group->ecfp_reduce(M, t0, group);
+
+ /* rz = 2 * py * pz */
+ PREFIX(multiply) (t1, p->y, p->z);
+ PREFIX(addLong) (t1, t1, t1);
+ group->ecfp_reduce(r->z, t1, group);
+
+ /* t0 = 2y^2, U = 8y^4 */
+ PREFIX(square) (t0, p->y);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(addShort) (t0, t0, t0);
+ PREFIX(square) (U, t0);
+ group->ecfp_reduce(U, U, group);
+ PREFIX(addShort) (U, U, U);
+
+ /* S = 4 * px * py^2 = 2 * px * t0 */
+ PREFIX(multiply) (S, p->x, t0);
+ group->ecfp_reduce(S, S, group);
+ PREFIX(addShort) (S, S, S);
+
+ /* rx = M^2 - 2S */
+ PREFIX(square) (T, M);
+ PREFIX(subtractShort) (T, T, S);
+ PREFIX(subtractShort) (T, T, S);
+ group->ecfp_reduce(r->x, T, group);
+
+ /* ry = M * (S - rx) - U */
+ PREFIX(subtractShort) (S, S, r->x);
+ PREFIX(multiply) (t0, M, S);
+ PREFIX(subtractShort) (t0, t0, U);
+ group->ecfp_reduce(r->y, t0, group);
+
+ /* ra*z^4 = 2*U*(apz4) */
+ PREFIX(multiply) (t1, U, p->az4);
+ PREFIX(addLong) (t1, t1, t1);
+ group->ecfp_reduce(r->az4, t1, group);
+
+ CLEANUP:
+ return;
+}
+
+/* Perform a point doubling using coordinates Affine -> Chudnovsky
+ * Jacobian. Input and output should be multi-precision floating point
+ * integers. */
+void PREFIX(pt_dbl_aff2chud) (const ecfp_aff_pt * p, ecfp_chud_pt * r,
+ const EC_group_fp * group) {
+ double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
+ M[2 * ECFP_NUMDOUBLES], twoY2[2 * ECFP_NUMDOUBLES],
+ S[2 * ECFP_NUMDOUBLES];
+
+ /* Check for point at infinity for p, if so set r = O */
+ if (PREFIX(pt_is_inf_aff) (p) == MP_YES) {
+ PREFIX(set_pt_inf_chud) (r);
+ goto CLEANUP;
+ }
+
+ /* M = 3(px)^2 + a */
+ PREFIX(square) (t0, p->x);
+ PREFIX(addLong) (t1, t0, t0);
+ PREFIX(addLong) (t1, t1, t0);
+ PREFIX(addShort) (t1, t1, group->curvea);
+ group->ecfp_reduce(M, t1, group);
+
+ /* twoY2 = 2*(py)^2, S = 4(px)(py)^2 */
+ PREFIX(square) (twoY2, p->y);
+ PREFIX(addLong) (twoY2, twoY2, twoY2);
+ group->ecfp_reduce(twoY2, twoY2, group);
+ PREFIX(multiply) (S, p->x, twoY2);
+ PREFIX(addLong) (S, S, S);
+ group->ecfp_reduce(S, S, group);
+
+ /* rx = M^2 - 2S */
+ PREFIX(square) (t0, M);
+ PREFIX(subtractShort) (t0, t0, S);
+ PREFIX(subtractShort) (t0, t0, S);
+ group->ecfp_reduce(r->x, t0, group);
+
+ /* ry = M(S-rx) - 8y^4 */
+ PREFIX(subtractShort) (t0, S, r->x);
+ PREFIX(multiply) (t1, t0, M);
+ PREFIX(square) (t0, twoY2);
+ PREFIX(subtractLong) (t1, t1, t0);
+ PREFIX(subtractLong) (t1, t1, t0);
+ group->ecfp_reduce(r->y, t1, group);
+
+ /* rz = 2py */
+ PREFIX(addShort) (r->z, p->y, p->y);
+
+ /* rz2 = rz^2 */
+ PREFIX(square) (t0, r->z);
+ group->ecfp_reduce(r->z2, t0, group);
+
+ /* rz3 = rz^3 */
+ PREFIX(multiply) (t0, r->z, r->z2);
+ group->ecfp_reduce(r->z3, t0, group);
+
+ CLEANUP:
+ return;
+}
+
+/* Perform a point addition using coordinates: Modified Jacobian +
+ * Chudnovsky Jacobian -> Modified Jacobian. Input and output should be
+ * multi-precision floating point integers. */
+void PREFIX(pt_add_jm_chud) (ecfp_jm_pt * p, ecfp_chud_pt * q,
+ ecfp_jm_pt * r, const EC_group_fp * group) {
+
+ double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
+ U[2 * ECFP_NUMDOUBLES], R[2 * ECFP_NUMDOUBLES],
+ S[2 * ECFP_NUMDOUBLES], H[2 * ECFP_NUMDOUBLES],
+ H3[2 * ECFP_NUMDOUBLES], pz2[2 * ECFP_NUMDOUBLES];
+
+ /* Check for point at infinity for p, if so set r = q need to convert
+ * from Chudnovsky form to Modified Jacobian form */
+ if (PREFIX(pt_is_inf_jm) (p) == MP_YES) {
+ PREFIX(copy) (r->x, q->x);
+ PREFIX(copy) (r->y, q->y);
+ PREFIX(copy) (r->z, q->z);
+ PREFIX(square) (t0, q->z2);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(multiply) (t1, t0, group->curvea);
+ group->ecfp_reduce(r->az4, t1, group);
+ goto CLEANUP;
+ }
+ /* Check for point at infinity for q, if so set r = p */
+ if (PREFIX(pt_is_inf_chud) (q) == MP_YES) {
+ PREFIX(copy) (r->x, p->x);
+ PREFIX(copy) (r->y, p->y);
+ PREFIX(copy) (r->z, p->z);
+ PREFIX(copy) (r->az4, p->az4);
+ goto CLEANUP;
+ }
+
+ /* U = px * qz^2 */
+ PREFIX(multiply) (U, p->x, q->z2);
+ group->ecfp_reduce(U, U, group);
+
+ /* H = qx*(pz)^2 - U */
+ PREFIX(square) (t0, p->z);
+ group->ecfp_reduce(pz2, t0, group);
+ PREFIX(multiply) (H, pz2, q->x);
+ group->ecfp_reduce(H, H, group);
+ PREFIX(subtractShort) (H, H, U);
+
+ /* U = U*H^2, H3 = H^3 */
+ PREFIX(square) (t0, H);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(multiply) (t1, U, t0);
+ group->ecfp_reduce(U, t1, group);
+ PREFIX(multiply) (H3, t0, H);
+ group->ecfp_reduce(H3, H3, group);
+
+ /* S = py * qz^3 */
+ PREFIX(multiply) (S, p->y, q->z3);
+ group->ecfp_reduce(S, S, group);
+
+ /* R = (qy * z1^3 - s) */
+ PREFIX(multiply) (t0, pz2, p->z);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(multiply) (R, t0, q->y);
+ PREFIX(subtractShort) (R, R, S);
+ group->ecfp_reduce(R, R, group);
+
+ /* rz = pz * qz * H */
+ PREFIX(multiply) (t1, q->z, H);
+ group->ecfp_reduce(t1, t1, group);
+ PREFIX(multiply) (t0, p->z, t1);
+ group->ecfp_reduce(r->z, t0, group);
+
+ /* rx = R^2 - H^3 - 2 * U */
+ PREFIX(square) (t0, R);
+ PREFIX(subtractShort) (t0, t0, H3);
+ PREFIX(subtractShort) (t0, t0, U);
+ PREFIX(subtractShort) (t0, t0, U);
+ group->ecfp_reduce(r->x, t0, group);
+
+ /* ry = R(U - rx) - S*H3 */
+ PREFIX(subtractShort) (t1, U, r->x);
+ PREFIX(multiply) (t0, t1, R);
+ PREFIX(multiply) (t1, S, H3);
+ PREFIX(subtractLong) (t1, t0, t1);
+ group->ecfp_reduce(r->y, t1, group);
+
+ if (group->aIsM3) { /* a == -3 */
+ /* a(rz^4) = -3 * ((rz^2)^2) */
+ PREFIX(square) (t0, r->z);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(square) (t1, t0);
+ PREFIX(addLong) (t0, t1, t1);
+ PREFIX(addLong) (t0, t0, t1);
+ PREFIX(negLong) (t0, t0);
+ group->ecfp_reduce(r->az4, t0, group);
+ } else { /* Generic case */
+ /* a(rz^4) = a * ((rz^2)^2) */
+ PREFIX(square) (t0, r->z);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(square) (t1, t0);
+ group->ecfp_reduce(t1, t1, group);
+ PREFIX(multiply) (t0, group->curvea, t1);
+ group->ecfp_reduce(r->az4, t0, group);
+ }
+ CLEANUP:
+ return;
+}
+
+/* Perform a point addition using Chudnovsky Jacobian coordinates. Input
+ * and output should be multi-precision floating point integers. */
+void PREFIX(pt_add_chud) (const ecfp_chud_pt * p, const ecfp_chud_pt * q,
+ ecfp_chud_pt * r, const EC_group_fp * group) {
+
+ /* Temporary Storage */
+ double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
+ U[2 * ECFP_NUMDOUBLES], R[2 * ECFP_NUMDOUBLES],
+ S[2 * ECFP_NUMDOUBLES], H[2 * ECFP_NUMDOUBLES],
+ H3[2 * ECFP_NUMDOUBLES];
+
+ /* Check for point at infinity for p, if so set r = q */
+ if (PREFIX(pt_is_inf_chud) (p) == MP_YES) {
+ PREFIX(copy) (r->x, q->x);
+ PREFIX(copy) (r->y, q->y);
+ PREFIX(copy) (r->z, q->z);
+ PREFIX(copy) (r->z2, q->z2);
+ PREFIX(copy) (r->z3, q->z3);
+ goto CLEANUP;
+ }
+
+ /* Check for point at infinity for p, if so set r = q */
+ if (PREFIX(pt_is_inf_chud) (q) == MP_YES) {
+ PREFIX(copy) (r->x, p->x);
+ PREFIX(copy) (r->y, p->y);
+ PREFIX(copy) (r->z, p->z);
+ PREFIX(copy) (r->z2, p->z2);
+ PREFIX(copy) (r->z3, p->z3);
+ goto CLEANUP;
+ }
+
+ /* U = px * qz^2 */
+ PREFIX(multiply) (U, p->x, q->z2);
+ group->ecfp_reduce(U, U, group);
+
+ /* H = qx*(pz)^2 - U */
+ PREFIX(multiply) (H, q->x, p->z2);
+ PREFIX(subtractShort) (H, H, U);
+ group->ecfp_reduce(H, H, group);
+
+ /* U = U*H^2, H3 = H^3 */
+ PREFIX(square) (t0, H);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(multiply) (t1, U, t0);
+ group->ecfp_reduce(U, t1, group);
+ PREFIX(multiply) (H3, t0, H);
+ group->ecfp_reduce(H3, H3, group);
+
+ /* S = py * qz^3 */
+ PREFIX(multiply) (S, p->y, q->z3);
+ group->ecfp_reduce(S, S, group);
+
+ /* rz = pz * qz * H */
+ PREFIX(multiply) (t0, q->z, H);
+ group->ecfp_reduce(t0, t0, group);
+ PREFIX(multiply) (t1, t0, p->z);
+ group->ecfp_reduce(r->z, t1, group);
+
+ /* R = (qy * z1^3 - s) */
+ PREFIX(multiply) (t0, q->y, p->z3);
+ PREFIX(subtractShort) (t0, t0, S);
+ group->ecfp_reduce(R, t0, group);
+
+ /* rx = R^2 - H^3 - 2 * U */
+ PREFIX(square) (t0, R);
+ PREFIX(subtractShort) (t0, t0, H3);
+ PREFIX(subtractShort) (t0, t0, U);
+ PREFIX(subtractShort) (t0, t0, U);
+ group->ecfp_reduce(r->x, t0, group);
+
+ /* ry = R(U - rx) - S*H3 */
+ PREFIX(subtractShort) (t1, U, r->x);
+ PREFIX(multiply) (t0, t1, R);
+ PREFIX(multiply) (t1, S, H3);
+ PREFIX(subtractLong) (t1, t0, t1);
+ group->ecfp_reduce(r->y, t1, group);
+
+ /* rz2 = rz^2 */
+ PREFIX(square) (t0, r->z);
+ group->ecfp_reduce(r->z2, t0, group);
+
+ /* rz3 = rz^3 */
+ PREFIX(multiply) (t0, r->z, r->z2);
+ group->ecfp_reduce(r->z3, t0, group);
+
+ CLEANUP:
+ return;
+}
+
+/* Expects out to be an array of size 16 of Chudnovsky Jacobian points.
+ * Fills in Chudnovsky Jacobian form (x, y, z, z^2, z^3), for -15P, -13P,
+ * -11P, -9P, -7P, -5P, -3P, -P, P, 3P, 5P, 7P, 9P, 11P, 13P, 15P */
+void PREFIX(precompute_chud) (ecfp_chud_pt * out, const ecfp_aff_pt * p,
+ const EC_group_fp * group) {
+
+ ecfp_chud_pt p2;
+
+ /* Set out[8] = P */
+ PREFIX(copy) (out[8].x, p->x);
+ PREFIX(copy) (out[8].y, p->y);
+ PREFIX(one) (out[8].z);
+ PREFIX(one) (out[8].z2);
+ PREFIX(one) (out[8].z3);
+
+ /* Set p2 = 2P */
+ PREFIX(pt_dbl_aff2chud) (p, &p2, group);
+
+ /* Set 3P, 5P, ..., 15P */
+ PREFIX(pt_add_chud) (&out[8], &p2, &out[9], group);
+ PREFIX(pt_add_chud) (&out[9], &p2, &out[10], group);
+ PREFIX(pt_add_chud) (&out[10], &p2, &out[11], group);
+ PREFIX(pt_add_chud) (&out[11], &p2, &out[12], group);
+ PREFIX(pt_add_chud) (&out[12], &p2, &out[13], group);
+ PREFIX(pt_add_chud) (&out[13], &p2, &out[14], group);
+ PREFIX(pt_add_chud) (&out[14], &p2, &out[15], group);
+
+ /* Set -15P, -13P, ..., -P */
+ PREFIX(pt_neg_chud) (&out[8], &out[7]);
+ PREFIX(pt_neg_chud) (&out[9], &out[6]);
+ PREFIX(pt_neg_chud) (&out[10], &out[5]);
+ PREFIX(pt_neg_chud) (&out[11], &out[4]);
+ PREFIX(pt_neg_chud) (&out[12], &out[3]);
+ PREFIX(pt_neg_chud) (&out[13], &out[2]);
+ PREFIX(pt_neg_chud) (&out[14], &out[1]);
+ PREFIX(pt_neg_chud) (&out[15], &out[0]);
+}
+
+/* Expects out to be an array of size 16 of Jacobian points. Fills in
+ * Jacobian form (x, y, z), for O, P, 2P, ... 15P */
+void PREFIX(precompute_jac) (ecfp_jac_pt * precomp, const ecfp_aff_pt * p,
+ const EC_group_fp * group) {
+ int i;
+
+ /* fill precomputation table */
+ /* set precomp[0] */
+ PREFIX(set_pt_inf_jac) (&precomp[0]);
+ /* set precomp[1] */
+ PREFIX(copy) (precomp[1].x, p->x);
+ PREFIX(copy) (precomp[1].y, p->y);
+ if (PREFIX(pt_is_inf_aff) (p) == MP_YES) {
+ PREFIX(zero) (precomp[1].z);
+ } else {
+ PREFIX(one) (precomp[1].z);
+ }
+ /* set precomp[2] */
+ group->pt_dbl_jac(&precomp[1], &precomp[2], group);
+
+ /* set rest of precomp */
+ for (i = 3; i < 16; i++) {
+ group->pt_add_jac_aff(&precomp[i - 1], p, &precomp[i], group);
+ }
+}
diff --git a/security/nss/lib/freebl/ecl/ecp_jac.c b/security/nss/lib/freebl/ecl/ecp_jac.c
new file mode 100644
index 000000000..8eea8c904
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_jac.c
@@ -0,0 +1,553 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Sheueling Chang-Shantz <sheueling.chang@sun.com>,
+ * Stephen Fung <fungstep@hotmail.com>, and
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
+ *
+ * Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>,
+ * Nils Larsch <nla@trustcenter.de>, and
+ * Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecp.h"
+#include "mplogic.h"
+#include <stdlib.h>
+#ifdef ECL_DEBUG
+#include <assert.h>
+#endif
+
+/* Converts a point P(px, py) from affine coordinates to Jacobian
+ * projective coordinates R(rx, ry, rz). Assumes input is already
+ * field-encoded using field_enc, and returns output that is still
+ * field-encoded. */
+mp_err
+ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
+ mp_int *ry, mp_int *rz, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+
+ if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
+ MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
+ } else {
+ MP_CHECKOK(mp_copy(px, rx));
+ MP_CHECKOK(mp_copy(py, ry));
+ MP_CHECKOK(mp_set_int(rz, 1));
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->field_enc(rz, rz, group->meth));
+ }
+ }
+ CLEANUP:
+ return res;
+}
+
+/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
+ * affine coordinates R(rx, ry). P and R can share x and y coordinates.
+ * Assumes input is already field-encoded using field_enc, and returns
+ * output that is still field-encoded. */
+mp_err
+ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
+ mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int z1, z2, z3;
+
+ MP_DIGITS(&z1) = 0;
+ MP_DIGITS(&z2) = 0;
+ MP_DIGITS(&z3) = 0;
+ MP_CHECKOK(mp_init(&z1));
+ MP_CHECKOK(mp_init(&z2));
+ MP_CHECKOK(mp_init(&z3));
+
+ /* if point at infinity, then set point at infinity and exit */
+ if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
+ MP_CHECKOK(ec_GFp_pt_set_inf_aff(rx, ry));
+ goto CLEANUP;
+ }
+
+ /* transform (px, py, pz) into (px / pz^2, py / pz^3) */
+ if (mp_cmp_d(pz, 1) == 0) {
+ MP_CHECKOK(mp_copy(px, rx));
+ MP_CHECKOK(mp_copy(py, ry));
+ } else {
+ MP_CHECKOK(group->meth->field_div(NULL, pz, &z1, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(&z1, &z2, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&z1, &z2, &z3, group->meth));
+ MP_CHECKOK(group->meth->field_mul(px, &z2, rx, group->meth));
+ MP_CHECKOK(group->meth->field_mul(py, &z3, ry, group->meth));
+ }
+
+ CLEANUP:
+ mp_clear(&z1);
+ mp_clear(&z2);
+ mp_clear(&z3);
+ return res;
+}
+
+/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
+ * coordinates. */
+mp_err
+ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz)
+{
+ return mp_cmp_z(pz);
+}
+
+/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
+ * coordinates. */
+mp_err
+ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
+{
+ mp_zero(pz);
+ return MP_OKAY;
+}
+
+/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
+ * (qx, qy, 1). Elliptic curve points P, Q, and R can all be identical.
+ * Uses mixed Jacobian-affine coordinates. Assumes input is already
+ * field-encoded using field_enc, and returns output that is still
+ * field-encoded. Uses equation (2) from Brown, Hankerson, Lopez, and
+ * Menezes. Software Implementation of the NIST Elliptic Curves Over Prime
+ * Fields. */
+mp_err
+ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
+ const mp_int *qx, const mp_int *qy, mp_int *rx,
+ mp_int *ry, mp_int *rz, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int A, B, C, D, C2, C3;
+
+ MP_DIGITS(&A) = 0;
+ MP_DIGITS(&B) = 0;
+ MP_DIGITS(&C) = 0;
+ MP_DIGITS(&D) = 0;
+ MP_DIGITS(&C2) = 0;
+ MP_DIGITS(&C3) = 0;
+ MP_CHECKOK(mp_init(&A));
+ MP_CHECKOK(mp_init(&B));
+ MP_CHECKOK(mp_init(&C));
+ MP_CHECKOK(mp_init(&D));
+ MP_CHECKOK(mp_init(&C2));
+ MP_CHECKOK(mp_init(&C3));
+
+ /* If either P or Q is the point at infinity, then return the other
+ * point */
+ if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
+ MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
+ goto CLEANUP;
+ }
+ if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
+ MP_CHECKOK(mp_copy(px, rx));
+ MP_CHECKOK(mp_copy(py, ry));
+ MP_CHECKOK(mp_copy(pz, rz));
+ goto CLEANUP;
+ }
+
+ /* A = qx * pz^2, B = qy * pz^3 */
+ MP_CHECKOK(group->meth->field_sqr(pz, &A, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&A, pz, &B, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&A, qx, &A, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&B, qy, &B, group->meth));
+
+ /* C = A - px, D = B - py */
+ MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth));
+ MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth));
+
+ /* C2 = C^2, C3 = C^3 */
+ MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth));
+
+ /* rz = pz * C */
+ MP_CHECKOK(group->meth->field_mul(pz, &C, rz, group->meth));
+
+ /* C = px * C^2 */
+ MP_CHECKOK(group->meth->field_mul(px, &C2, &C, group->meth));
+ /* A = D^2 */
+ MP_CHECKOK(group->meth->field_sqr(&D, &A, group->meth));
+
+ /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
+ MP_CHECKOK(group->meth->field_add(&C, &C, rx, group->meth));
+ MP_CHECKOK(group->meth->field_add(&C3, rx, rx, group->meth));
+ MP_CHECKOK(group->meth->field_sub(&A, rx, rx, group->meth));
+
+ /* C3 = py * C^3 */
+ MP_CHECKOK(group->meth->field_mul(py, &C3, &C3, group->meth));
+
+ /* ry = D * (px * C^2 - rx) - py * C^3 */
+ MP_CHECKOK(group->meth->field_sub(&C, rx, ry, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&D, ry, ry, group->meth));
+ MP_CHECKOK(group->meth->field_sub(ry, &C3, ry, group->meth));
+
+ CLEANUP:
+ mp_clear(&A);
+ mp_clear(&B);
+ mp_clear(&C);
+ mp_clear(&D);
+ mp_clear(&C2);
+ mp_clear(&C3);
+ return res;
+}
+
+/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
+ * Jacobian coordinates.
+ *
+ * Assumes input is already field-encoded using field_enc, and returns
+ * output that is still field-encoded.
+ *
+ * This routine implements Point Doubling in the Jacobian Projective
+ * space as described in the paper "Efficient elliptic curve exponentiation
+ * using mixed coordinates", by H. Cohen, A Miyaji, T. Ono.
+ */
+mp_err
+ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py, const mp_int *pz,
+ mp_int *rx, mp_int *ry, mp_int *rz, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int t0, t1, M, S;
+
+ MP_DIGITS(&t0) = 0;
+ MP_DIGITS(&t1) = 0;
+ MP_DIGITS(&M) = 0;
+ MP_DIGITS(&S) = 0;
+ MP_CHECKOK(mp_init(&t0));
+ MP_CHECKOK(mp_init(&t1));
+ MP_CHECKOK(mp_init(&M));
+ MP_CHECKOK(mp_init(&S));
+
+ if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
+ MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
+ goto CLEANUP;
+ }
+
+ if (mp_cmp_d(pz, 1) == 0) {
+ /* M = 3 * px^2 + a */
+ MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
+ MP_CHECKOK(group->meth->
+ field_add(&t0, &group->curvea, &M, group->meth));
+ } else if (mp_cmp_int(&group->curvea, -3) == 0) {
+ /* M = 3 * (px + pz^2) * (px - pz^2) */
+ MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
+ MP_CHECKOK(group->meth->field_add(px, &M, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_sub(px, &M, &t1, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&t0, &t1, &M, group->meth));
+ MP_CHECKOK(group->meth->field_add(&M, &M, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t0, &M, &M, group->meth));
+ } else {
+ /* M = 3 * (px^2) + a * (pz^4) */
+ MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(&M, &M, group->meth));
+ MP_CHECKOK(group->meth->
+ field_mul(&M, &group->curvea, &M, group->meth));
+ MP_CHECKOK(group->meth->field_add(&M, &t0, &M, group->meth));
+ }
+
+ /* rz = 2 * py * pz */
+ /* t0 = 4 * py^2 */
+ if (mp_cmp_d(pz, 1) == 0) {
+ MP_CHECKOK(group->meth->field_add(py, py, rz, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(rz, &t0, group->meth));
+ } else {
+ MP_CHECKOK(group->meth->field_add(py, py, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&t0, pz, rz, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(&t0, &t0, group->meth));
+ }
+
+ /* S = 4 * px * py^2 = px * (2 * py)^2 */
+ MP_CHECKOK(group->meth->field_mul(px, &t0, &S, group->meth));
+
+ /* rx = M^2 - 2 * S */
+ MP_CHECKOK(group->meth->field_add(&S, &S, &t1, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(&M, rx, group->meth));
+ MP_CHECKOK(group->meth->field_sub(rx, &t1, rx, group->meth));
+
+ /* ry = M * (S - rx) - 8 * py^4 */
+ MP_CHECKOK(group->meth->field_sqr(&t0, &t1, group->meth));
+ if (mp_isodd(&t1)) {
+ MP_CHECKOK(mp_add(&t1, &group->meth->irr, &t1));
+ }
+ MP_CHECKOK(mp_div_2(&t1, &t1));
+ MP_CHECKOK(group->meth->field_sub(&S, rx, &S, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&M, &S, &M, group->meth));
+ MP_CHECKOK(group->meth->field_sub(&M, &t1, ry, group->meth));
+
+ CLEANUP:
+ mp_clear(&t0);
+ mp_clear(&t1);
+ mp_clear(&M);
+ mp_clear(&S);
+ return res;
+}
+
+/* by default, this routine is unused and thus doesn't need to be compiled */
+#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
+/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
+ * a, b and p are the elliptic curve coefficients and the prime that
+ * determines the field GFp. Elliptic curve points P and R can be
+ * identical. Uses mixed Jacobian-affine coordinates. Assumes input is
+ * already field-encoded using field_enc, and returns output that is still
+ * field-encoded. Uses 4-bit window method. */
+mp_err
+ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px, const mp_int *py,
+ mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int precomp[16][2], rz;
+ int i, ni, d;
+
+ MP_DIGITS(&rz) = 0;
+ for (i = 0; i < 16; i++) {
+ MP_DIGITS(&precomp[i][0]) = 0;
+ MP_DIGITS(&precomp[i][1]) = 0;
+ }
+
+ ARGCHK(group != NULL, MP_BADARG);
+ ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
+
+ /* initialize precomputation table */
+ for (i = 0; i < 16; i++) {
+ MP_CHECKOK(mp_init(&precomp[i][0]));
+ MP_CHECKOK(mp_init(&precomp[i][1]));
+ }
+
+ /* fill precomputation table */
+ mp_zero(&precomp[0][0]);
+ mp_zero(&precomp[0][1]);
+ MP_CHECKOK(mp_copy(px, &precomp[1][0]));
+ MP_CHECKOK(mp_copy(py, &precomp[1][1]));
+ for (i = 2; i < 16; i++) {
+ MP_CHECKOK(group->
+ point_add(&precomp[1][0], &precomp[1][1],
+ &precomp[i - 1][0], &precomp[i - 1][1],
+ &precomp[i][0], &precomp[i][1], group));
+ }
+
+ d = (mpl_significant_bits(n) + 3) / 4;
+
+ /* R = inf */
+ MP_CHECKOK(mp_init(&rz));
+ MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
+
+ for (i = d - 1; i >= 0; i--) {
+ /* compute window ni */
+ ni = MP_GET_BIT(n, 4 * i + 3);
+ ni <<= 1;
+ ni |= MP_GET_BIT(n, 4 * i + 2);
+ ni <<= 1;
+ ni |= MP_GET_BIT(n, 4 * i + 1);
+ ni <<= 1;
+ ni |= MP_GET_BIT(n, 4 * i);
+ /* R = 2^4 * R */
+ MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+ MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+ MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+ MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+ /* R = R + (ni * P) */
+ MP_CHECKOK(ec_GFp_pt_add_jac_aff
+ (rx, ry, &rz, &precomp[ni][0], &precomp[ni][1], rx, ry,
+ &rz, group));
+ }
+
+ /* convert result S to affine coordinates */
+ MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
+
+ CLEANUP:
+ mp_clear(&rz);
+ for (i = 0; i < 16; i++) {
+ mp_clear(&precomp[i][0]);
+ mp_clear(&precomp[i][1]);
+ }
+ return res;
+}
+#endif
+
+/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
+ * k2 * P(x, y), where G is the generator (base point) of the group of
+ * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
+ * Uses mixed Jacobian-affine coordinates. Input and output values are
+ * assumed to be NOT field-encoded. Uses algorithm 15 (simultaneous
+ * multiple point multiplication) from Brown, Hankerson, Lopez, Menezes.
+ * Software Implementation of the NIST Elliptic Curves over Prime Fields. */
+mp_err
+ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int precomp[4][4][2];
+ mp_int rz;
+ const mp_int *a, *b;
+ int i, j;
+ int ai, bi, d;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ MP_DIGITS(&precomp[i][j][0]) = 0;
+ MP_DIGITS(&precomp[i][j][1]) = 0;
+ }
+ }
+ MP_DIGITS(&rz) = 0;
+
+ ARGCHK(group != NULL, MP_BADARG);
+ ARGCHK(!((k1 == NULL)
+ && ((k2 == NULL) || (px == NULL)
+ || (py == NULL))), MP_BADARG);
+
+ /* if some arguments are not defined used ECPoint_mul */
+ if (k1 == NULL) {
+ return ECPoint_mul(group, k2, px, py, rx, ry);
+ } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
+ return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
+ }
+
+ /* initialize precomputation table */
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ MP_CHECKOK(mp_init(&precomp[i][j][0]));
+ MP_CHECKOK(mp_init(&precomp[i][j][1]));
+ }
+ }
+
+ /* fill precomputation table */
+ /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
+ if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
+ a = k2;
+ b = k1;
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->
+ field_enc(px, &precomp[1][0][0], group->meth));
+ MP_CHECKOK(group->meth->
+ field_enc(py, &precomp[1][0][1], group->meth));
+ } else {
+ MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
+ MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
+ }
+ MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
+ MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
+ } else {
+ a = k1;
+ b = k2;
+ MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
+ MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
+ if (group->meth->field_enc) {
+ MP_CHECKOK(group->meth->
+ field_enc(px, &precomp[0][1][0], group->meth));
+ MP_CHECKOK(group->meth->
+ field_enc(py, &precomp[0][1][1], group->meth));
+ } else {
+ MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
+ MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
+ }
+ }
+ /* precompute [*][0][*] */
+ mp_zero(&precomp[0][0][0]);
+ mp_zero(&precomp[0][0][1]);
+ MP_CHECKOK(group->
+ point_dbl(&precomp[1][0][0], &precomp[1][0][1],
+ &precomp[2][0][0], &precomp[2][0][1], group));
+ MP_CHECKOK(group->
+ point_add(&precomp[1][0][0], &precomp[1][0][1],
+ &precomp[2][0][0], &precomp[2][0][1],
+ &precomp[3][0][0], &precomp[3][0][1], group));
+ /* precompute [*][1][*] */
+ for (i = 1; i < 4; i++) {
+ MP_CHECKOK(group->
+ point_add(&precomp[0][1][0], &precomp[0][1][1],
+ &precomp[i][0][0], &precomp[i][0][1],
+ &precomp[i][1][0], &precomp[i][1][1], group));
+ }
+ /* precompute [*][2][*] */
+ MP_CHECKOK(group->
+ point_dbl(&precomp[0][1][0], &precomp[0][1][1],
+ &precomp[0][2][0], &precomp[0][2][1], group));
+ for (i = 1; i < 4; i++) {
+ MP_CHECKOK(group->
+ point_add(&precomp[0][2][0], &precomp[0][2][1],
+ &precomp[i][0][0], &precomp[i][0][1],
+ &precomp[i][2][0], &precomp[i][2][1], group));
+ }
+ /* precompute [*][3][*] */
+ MP_CHECKOK(group->
+ point_add(&precomp[0][1][0], &precomp[0][1][1],
+ &precomp[0][2][0], &precomp[0][2][1],
+ &precomp[0][3][0], &precomp[0][3][1], group));
+ for (i = 1; i < 4; i++) {
+ MP_CHECKOK(group->
+ point_add(&precomp[0][3][0], &precomp[0][3][1],
+ &precomp[i][0][0], &precomp[i][0][1],
+ &precomp[i][3][0], &precomp[i][3][1], group));
+ }
+
+ d = (mpl_significant_bits(a) + 1) / 2;
+
+ /* R = inf */
+ MP_CHECKOK(mp_init(&rz));
+ MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
+
+ for (i = d - 1; i >= 0; i--) {
+ ai = MP_GET_BIT(a, 2 * i + 1);
+ ai <<= 1;
+ ai |= MP_GET_BIT(a, 2 * i);
+ bi = MP_GET_BIT(b, 2 * i + 1);
+ bi <<= 1;
+ bi |= MP_GET_BIT(b, 2 * i);
+ /* R = 2^2 * R */
+ MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+ MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
+ /* R = R + (ai * A + bi * B) */
+ MP_CHECKOK(ec_GFp_pt_add_jac_aff
+ (rx, ry, &rz, &precomp[ai][bi][0], &precomp[ai][bi][1],
+ rx, ry, &rz, group));
+ }
+
+ MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
+
+ if (group->meth->field_dec) {
+ MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
+ MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
+ }
+
+ CLEANUP:
+ mp_clear(&rz);
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ mp_clear(&precomp[i][j][0]);
+ mp_clear(&precomp[i][j][1]);
+ }
+ }
+ return res;
+}
diff --git a/security/nss/lib/freebl/ecl/ecp_jm.c b/security/nss/lib/freebl/ecl/ecp_jm.c
new file mode 100644
index 000000000..2174650d1
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_jm.c
@@ -0,0 +1,320 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library for prime
+ * field curves.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stephen Fung <fungstep@hotmail.com>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#include "ecp.h"
+#include "ecl-priv.h"
+#include "mplogic.h"
+#include <stdlib.h>
+
+/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
+ * Modified Jacobian coordinates.
+ *
+ * Assumes input is already field-encoded using field_enc, and returns
+ * output that is still field-encoded.
+ *
+ */
+mp_err
+ec_GFp_pt_dbl_jm(const mp_int *px, const mp_int *py, const mp_int *pz,
+ const mp_int *paz4, mp_int *rx, mp_int *ry, mp_int *rz,
+ mp_int *raz4, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int t0, t1, M, S;
+
+ MP_DIGITS(&t0) = 0;
+ MP_DIGITS(&t1) = 0;
+ MP_DIGITS(&M) = 0;
+ MP_DIGITS(&S) = 0;
+ MP_CHECKOK(mp_init(&t0));
+ MP_CHECKOK(mp_init(&t1));
+ MP_CHECKOK(mp_init(&M));
+ MP_CHECKOK(mp_init(&S));
+
+ /* Check for point at infinity */
+ if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
+ /* Set r = pt at infinity by setting rz = 0 */
+
+ MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
+ goto CLEANUP;
+ }
+
+ /* M = 3 (px^2) + a*(pz^4) */
+ MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t0, paz4, &M, group->meth));
+
+ /* rz = 2 * py * pz */
+ MP_CHECKOK(group->meth->field_mul(py, pz, rz, group->meth));
+ MP_CHECKOK(group->meth->field_add(rz, rz, rz, group->meth));
+
+ /* t0 = 2y^2 , t1 = 8y^4 */
+ MP_CHECKOK(group->meth->field_sqr(py, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t0, &t0, &t0, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(&t0, &t1, group->meth));
+ MP_CHECKOK(group->meth->field_add(&t1, &t1, &t1, group->meth));
+
+ /* S = 4 * px * py^2 = 2 * px * t0 */
+ MP_CHECKOK(group->meth->field_mul(px, &t0, &S, group->meth));
+ MP_CHECKOK(group->meth->field_add(&S, &S, &S, group->meth));
+
+ /* rx = M^2 - 2S */
+ MP_CHECKOK(group->meth->field_sqr(&M, rx, group->meth));
+ MP_CHECKOK(group->meth->field_sub(rx, &S, rx, group->meth));
+ MP_CHECKOK(group->meth->field_sub(rx, &S, rx, group->meth));
+
+ /* ry = M * (S - rx) - t1 */
+ MP_CHECKOK(group->meth->field_sub(&S, rx, ry, group->meth));
+ MP_CHECKOK(group->meth->field_mul(ry, &M, ry, group->meth));
+ MP_CHECKOK(group->meth->field_sub(ry, &t1, ry, group->meth));
+
+ /* ra*z^4 = 2*t1*(apz4) */
+ MP_CHECKOK(group->meth->field_mul(paz4, &t1, raz4, group->meth));
+ MP_CHECKOK(group->meth->field_add(raz4, raz4, raz4, group->meth));
+
+ CLEANUP:
+ mp_clear(&t0);
+ mp_clear(&t1);
+ mp_clear(&M);
+ mp_clear(&S);
+ return res;
+}
+
+/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
+ * (qx, qy, 1). Elliptic curve points P, Q, and R can all be identical.
+ * Uses mixed Modified_Jacobian-affine coordinates. Assumes input is
+ * already field-encoded using field_enc, and returns output that is still
+ * field-encoded. */
+mp_err
+ec_GFp_pt_add_jm_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
+ const mp_int *paz4, const mp_int *qx,
+ const mp_int *qy, mp_int *rx, mp_int *ry, mp_int *rz,
+ mp_int *raz4, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int A, B, C, D, C2, C3;
+
+ MP_DIGITS(&A) = 0;
+ MP_DIGITS(&B) = 0;
+ MP_DIGITS(&C) = 0;
+ MP_DIGITS(&D) = 0;
+ MP_DIGITS(&C2) = 0;
+ MP_DIGITS(&C3) = 0;
+ MP_CHECKOK(mp_init(&A));
+ MP_CHECKOK(mp_init(&B));
+ MP_CHECKOK(mp_init(&C));
+ MP_CHECKOK(mp_init(&D));
+ MP_CHECKOK(mp_init(&C2));
+ MP_CHECKOK(mp_init(&C3));
+
+ /* If either P or Q is the point at infinity, then return the other
+ * point */
+ if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
+ MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
+ MP_CHECKOK(group->meth->field_sqr(rz, raz4, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(raz4, raz4, group->meth));
+ MP_CHECKOK(group->meth->
+ field_mul(raz4, &group->curvea, raz4, group->meth));
+ goto CLEANUP;
+ }
+ if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
+ MP_CHECKOK(mp_copy(px, rx));
+ MP_CHECKOK(mp_copy(py, ry));
+ MP_CHECKOK(mp_copy(pz, rz));
+ MP_CHECKOK(mp_copy(paz4, raz4));
+ goto CLEANUP;
+ }
+
+ /* A = qx * pz^2, B = qy * pz^3 */
+ MP_CHECKOK(group->meth->field_sqr(pz, &A, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&A, pz, &B, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&A, qx, &A, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&B, qy, &B, group->meth));
+
+ /* C = A - px, D = B - py */
+ MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth));
+ MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth));
+
+ /* C2 = C^2, C3 = C^3 */
+ MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth));
+
+ /* rz = pz * C */
+ MP_CHECKOK(group->meth->field_mul(pz, &C, rz, group->meth));
+
+ /* C = px * C^2 */
+ MP_CHECKOK(group->meth->field_mul(px, &C2, &C, group->meth));
+ /* A = D^2 */
+ MP_CHECKOK(group->meth->field_sqr(&D, &A, group->meth));
+
+ /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
+ MP_CHECKOK(group->meth->field_add(&C, &C, rx, group->meth));
+ MP_CHECKOK(group->meth->field_add(&C3, rx, rx, group->meth));
+ MP_CHECKOK(group->meth->field_sub(&A, rx, rx, group->meth));
+
+ /* C3 = py * C^3 */
+ MP_CHECKOK(group->meth->field_mul(py, &C3, &C3, group->meth));
+
+ /* ry = D * (px * C^2 - rx) - py * C^3 */
+ MP_CHECKOK(group->meth->field_sub(&C, rx, ry, group->meth));
+ MP_CHECKOK(group->meth->field_mul(&D, ry, ry, group->meth));
+ MP_CHECKOK(group->meth->field_sub(ry, &C3, ry, group->meth));
+
+ /* raz4 = a * rz^4 */
+ MP_CHECKOK(group->meth->field_sqr(rz, raz4, group->meth));
+ MP_CHECKOK(group->meth->field_sqr(raz4, raz4, group->meth));
+ MP_CHECKOK(group->meth->
+ field_mul(raz4, &group->curvea, raz4, group->meth));
+
+ CLEANUP:
+ mp_clear(&A);
+ mp_clear(&B);
+ mp_clear(&C);
+ mp_clear(&D);
+ mp_clear(&C2);
+ mp_clear(&C3);
+ return res;
+}
+
+/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
+ * curve points P and R can be identical. Uses mixed Modified-Jacobian
+ * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
+ * additions. Assumes input is already field-encoded using field_enc, and
+ * returns output that is still field-encoded. Uses 5-bit window NAF
+ * method (algorithm 11) for scalar-point multiplication from Brown,
+ * Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
+ * Curves Over Prime Fields. */
+mp_err
+ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
+ mp_int *rx, mp_int *ry, const ECGroup *group)
+{
+ mp_err res = MP_OKAY;
+ mp_int precomp[16][2], rz, tpx, tpy;
+ mp_int raz4;
+ signed char *naf = NULL;
+ int i, orderBitSize;
+
+ MP_DIGITS(&rz) = 0;
+ MP_DIGITS(&raz4) = 0;
+ MP_DIGITS(&tpx) = 0;
+ MP_DIGITS(&tpy) = 0;
+ for (i = 0; i < 16; i++) {
+ MP_DIGITS(&precomp[i][0]) = 0;
+ MP_DIGITS(&precomp[i][1]) = 0;
+ }
+
+ ARGCHK(group != NULL, MP_BADARG);
+ ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
+
+ /* initialize precomputation table */
+ MP_CHECKOK(mp_init(&tpx));
+ MP_CHECKOK(mp_init(&tpy));;
+ MP_CHECKOK(mp_init(&rz));
+ MP_CHECKOK(mp_init(&raz4));
+
+ for (i = 0; i < 16; i++) {
+ MP_CHECKOK(mp_init(&precomp[i][0]));
+ MP_CHECKOK(mp_init(&precomp[i][1]));
+ }
+
+ /* Set out[8] = P */
+ MP_CHECKOK(mp_copy(px, &precomp[8][0]));
+ MP_CHECKOK(mp_copy(py, &precomp[8][1]));
+
+ /* Set (tpx, tpy) = 2P */
+ MP_CHECKOK(group->
+ point_dbl(&precomp[8][0], &precomp[8][1], &tpx, &tpy,
+ group));
+
+ /* Set 3P, 5P, ..., 15P */
+ for (i = 8; i < 15; i++) {
+ MP_CHECKOK(group->
+ point_add(&precomp[i][0], &precomp[i][1], &tpx, &tpy,
+ &precomp[i + 1][0], &precomp[i + 1][1],
+ group));
+ }
+
+ /* Set -15P, -13P, ..., -P */
+ for (i = 0; i < 8; i++) {
+ MP_CHECKOK(mp_copy(&precomp[15 - i][0], &precomp[i][0]));
+ MP_CHECKOK(group->meth->
+ field_neg(&precomp[15 - i][1], &precomp[i][1],
+ group->meth));
+ }
+
+ /* R = inf */
+ MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
+
+ orderBitSize = mpl_significant_bits(&group->order);
+
+ /* Allocate memory for NAF */
+ naf = (signed char *) malloc(sizeof(signed char) * orderBitSize);
+ if (naf == NULL) {
+ res = MP_MEM;
+ goto CLEANUP;
+ }
+
+ /* Compute 5NAF */
+ ec_compute_wNAF(naf, orderBitSize, n, 5);
+
+ /* wNAF method */
+ for (i = orderBitSize; i >= 0; i--) {
+ /* R = 2R */
+ ec_GFp_pt_dbl_jm(rx, ry, &rz, &raz4, rx, ry, &rz, &raz4, group);
+ if (naf[i] != 0) {
+ ec_GFp_pt_add_jm_aff(rx, ry, &rz, &raz4,
+ &precomp[(naf[i] + 15) / 2][0],
+ &precomp[(naf[i] + 15) / 2][1], rx, ry,
+ &rz, &raz4, group);
+ }
+ }
+
+ /* convert result S to affine coordinates */
+ MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
+
+ CLEANUP:
+ for (i = 0; i < 16; i++) {
+ mp_clear(&precomp[i][0]);
+ mp_clear(&precomp[i][1]);
+ }
+ mp_clear(&tpx);
+ mp_clear(&tpy);
+ mp_clear(&rz);
+ mp_clear(&raz4);
+ free(naf);
+ return res;
+}
diff --git a/security/nss/lib/freebl/ecl/ecp_mont.c b/security/nss/lib/freebl/ecl/ecp_mont.c
new file mode 100644
index 000000000..a251af1fc
--- /dev/null
+++ b/security/nss/lib/freebl/ecl/ecp_mont.c
@@ -0,0 +1,190 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 elliptic curve math library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+/* Uses Montgomery reduction for field arithmetic. See mpi/mpmontg.c for
+ * code implementation. */
+
+#include "mpi.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+#include "ecl-priv.h"
+#include "ecp.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Construct a generic GFMethod for arithmetic over prime fields with
+ * irreducible irr. */
+GFMethod *
+GFMethod_consGFp_mont(const mp_int *irr)
+{
+ mp_err res = MP_OKAY;
+ int i;
+ GFMethod *meth = NULL;
+ mp_mont_modulus *mmm;
+
+ meth = GFMethod_consGFp(irr);
+ if (meth == NULL)
+ return NULL;
+
+ mmm = (mp_mont_modulus *) malloc(sizeof(mp_mont_modulus));
+ if (mmm == NULL) {
+ res = MP_MEM;
+ goto CLEANUP;
+ }
+
+ meth->field_mul = &ec_GFp_mul_mont;
+ meth->field_sqr = &ec_GFp_sqr_mont;
+ meth->field_div = &ec_GFp_div_mont;
+ meth->field_enc = &ec_GFp_enc_mont;
+ meth->field_dec = &ec_GFp_dec_mont;
+ meth->extra1 = mmm;
+ meth->extra2 = NULL;
+ meth->extra_free = &ec_GFp_extra_free_mont;
+
+ mmm->N = meth->irr;
+ i = mpl_significant_bits(&meth->irr);
+ i += MP_DIGIT_BIT - 1;
+ mmm->b = i - i % MP_DIGIT_BIT;
+ mmm->n0prime = 0 - s_mp_invmod_radix(MP_DIGIT(&meth->irr, 0));
+
+ CLEANUP:
+ if (res != MP_OKAY) {
+ GFMethod_free(meth);
+ return NULL;
+ }
+ return meth;
+}
+
+/* Wrapper functions for generic prime field arithmetic. */
+
+/* Field multiplication using Montgomery reduction. */
+mp_err
+ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+
+#ifdef MP_MONT_USE_MP_MUL
+ /* if MP_MONT_USE_MP_MUL is defined, then the function s_mp_mul_mont
+ * is not implemented and we have to use mp_mul and s_mp_redc directly
+ */
+ MP_CHECKOK(mp_mul(a, b, r));
+ MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
+#else
+ mp_int s;
+
+ MP_DIGITS(&s) = 0;
+ /* s_mp_mul_mont doesn't allow source and destination to be the same */
+ if ((a == r) || (b == r)) {
+ MP_CHECKOK(mp_init(&s));
+ MP_CHECKOK(s_mp_mul_mont
+ (a, b, &s, (mp_mont_modulus *) meth->extra1));
+ MP_CHECKOK(mp_copy(&s, r));
+ mp_clear(&s);
+ } else {
+ return s_mp_mul_mont(a, b, r, (mp_mont_modulus *) meth->extra1);
+ }
+#endif
+ CLEANUP:
+ return res;
+}
+
+/* Field squaring using Montgomery reduction. */
+mp_err
+ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ return ec_GFp_mul_mont(a, a, r, meth);
+}
+
+/* Field division using Montgomery reduction. */
+mp_err
+ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
+ const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+
+ /* if A=aZ represents a encoded in montgomery coordinates with Z and #
+ * and \ respectively represent multiplication and division in
+ * montgomery coordinates, then A\B = (a/b)Z = (A/B)Z and Binv =
+ * (1/b)Z = (1/B)(Z^2) where B # Binv = Z */
+ MP_CHECKOK(ec_GFp_div(a, b, r, meth));
+ MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
+ if (a == NULL) {
+ MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
+ }
+ CLEANUP:
+ return res;
+}
+
+/* Encode a field element in Montgomery form. See s_mp_to_mont in
+ * mpi/mpmontg.c */
+mp_err
+ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_mont_modulus *mmm;
+ mp_err res = MP_OKAY;
+
+ mmm = (mp_mont_modulus *) meth->extra1;
+ MP_CHECKOK(mpl_lsh(a, r, mmm->b));
+ MP_CHECKOK(mp_mod(r, &mmm->N, r));
+ CLEANUP:
+ return res;
+}
+
+/* Decode a field element from Montgomery form. */
+mp_err
+ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
+{
+ mp_err res = MP_OKAY;
+
+ if (a != r) {
+ MP_CHECKOK(mp_copy(a, r));
+ }
+ MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
+ CLEANUP:
+ return res;
+}
+
+/* Free the memory allocated to the extra fields of Montgomery GFMethod
+ * object. */
+void
+ec_GFp_extra_free_mont(GFMethod *meth)
+{
+ if (meth->extra1 != NULL) {
+ free(meth->extra1);
+ meth->extra1 = NULL;
+ }
+}
diff --git a/security/nss/lib/freebl/mpi/mp_gf2m-priv.h b/security/nss/lib/freebl/mpi/mp_gf2m-priv.h
new file mode 100644
index 000000000..e2236299f
--- /dev/null
+++ b/security/nss/lib/freebl/mpi/mp_gf2m-priv.h
@@ -0,0 +1,101 @@
+/*
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 Multi-precision Binary Polynomial Arithmetic
+ * Library.
+ *
+ * The Initial Developer of the Original Code is Sun Microsystems, Inc.
+ * Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+ * Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Sheueling Chang Shantz <sheueling.chang@sun.com> and
+ * Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#ifndef _MP_GF2M_PRIV_H_
+#define _MP_GF2M_PRIV_H_
+
+#include "mpi-priv.h"
+
+extern const mp_digit mp_gf2m_sqr_tb[16];
+
+#if defined(MP_USE_UINT_DIGIT)
+#define MP_DIGIT_BITS 32
+#else
+#define MP_DIGIT_BITS 64
+#endif
+
+/* Platform-specific macros for fast binary polynomial squaring. */
+#if MP_DIGIT_BITS == 32
+#define gf2m_SQR1(w) \
+ mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 16 | \
+ mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF]
+#define gf2m_SQR0(w) \
+ mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 8 & 0xF] << 16 | \
+ mp_gf2m_sqr_tb[(w) >> 4 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) & 0xF]
+#else
+#define gf2m_SQR1(w) \
+ mp_gf2m_sqr_tb[(w) >> 60 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 56 & 0xF] << 48 | \
+ mp_gf2m_sqr_tb[(w) >> 52 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 48 & 0xF] << 32 | \
+ mp_gf2m_sqr_tb[(w) >> 44 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 40 & 0xF] << 16 | \
+ mp_gf2m_sqr_tb[(w) >> 36 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) >> 32 & 0xF]
+#define gf2m_SQR0(w) \
+ mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 48 | \
+ mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF] << 32 | \
+ mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 8 & 0xF] << 16 | \
+ mp_gf2m_sqr_tb[(w) >> 4 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) & 0xF]
+#endif
+
+/* Multiply two binary polynomials mp_digits a, b.
+ * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
+ * Output in two mp_digits rh, rl.
+ */
+void s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b);
+
+/* Compute xor-multiply of two binary polynomials (a1, a0) x (b1, b0)
+ * result is a binary polynomial in 4 mp_digits r[4].
+ * The caller MUST ensure that r has the right amount of space allocated.
+ */
+void s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1,
+ const mp_digit b0);
+
+/* Compute xor-multiply of two binary polynomials (a2, a1, a0) x (b2, b1, b0)
+ * result is a binary polynomial in 6 mp_digits r[6].
+ * The caller MUST ensure that r has the right amount of space allocated.
+ */
+void s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0,
+ const mp_digit b2, const mp_digit b1, const mp_digit b0);
+
+/* Compute xor-multiply of two binary polynomials (a3, a2, a1, a0) x (b3, b2, b1, b0)
+ * result is a binary polynomial in 8 mp_digits r[8].
+ * The caller MUST ensure that r has the right amount of space allocated.
+ */
+void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1,
+ const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1,
+ const mp_digit b0);
+
+#endif /* _MP_GF2M_PRIV_H_ */
diff --git a/security/nss/lib/freebl/mpi/target.mk b/security/nss/lib/freebl/mpi/target.mk
new file mode 100644
index 000000000..ee175d2a4
--- /dev/null
+++ b/security/nss/lib/freebl/mpi/target.mk
@@ -0,0 +1,220 @@
+## 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 MPI Arbitrary Precision Integer Arithmetic
+## library.
+##
+## The Initial Developer of the Original Code is
+## Michael J. Fromberger <sting@linguist.dartmouth.edu>
+##
+## Portions created by Michael J. Fromberger are
+## Copyright (C) 1998, 2000 Michael J. Fromberger. All Rights Reserved.
+##
+## Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+## Sun Microsystems, Inc. All Rights Reserved.
+##
+## Contributor(s):
+## Netscape Communications Corporation
+## Richard C. Swift (swift@netscape.com)
+## Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
+##
+## 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.
+##
+
+##
+## Define CFLAGS to contain any local options your compiler
+## setup requires.
+##
+## Conditional compilation options are no longer here; see
+## the file 'mpi-config.h' instead.
+##
+MPICMN = -I. -DMP_API_COMPATIBLE -DMP_IOFUNC
+CFLAGS= -O $(MPICMN)
+#CFLAGS=-ansi -fullwarn -woff 1521 -O3 $(MPICMN)
+#CFLAGS=-ansi -pedantic -Wall -O3 $(MPICMN)
+#CFLAGS=-ansi -pedantic -Wall -g -O2 -DMP_DEBUG=1 $(MPICMN)
+
+ifeq ($(TARGET),mipsIRIX)
+#IRIX
+#MPICMN += -DMP_MONT_USE_MP_MUL
+MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
+MPICMN += -DMP_USE_UINT_DIGIT
+#MPICMN += -DMP_NO_MP_WORD
+AS_OBJS = mpi_mips.o
+#ASFLAGS = -O -OPT:Olimit=4000 -dollar -fullwarn -xansi -n32 -mips3 -exceptions
+ASFLAGS = -O -OPT:Olimit=4000 -dollar -fullwarn -xansi -n32 -mips3
+#CFLAGS=-ansi -n32 -O3 -fullwarn -woff 1429 -D_SGI_SOURCE $(MPICMN)
+CFLAGS=-ansi -n32 -O2 -fullwarn -woff 1429 -D_SGI_SOURCE $(MPICMN)
+#CFLAGS=-ansi -n32 -g -fullwarn -woff 1429 -D_SGI_SOURCE $(MPICMN)
+#CFLAGS=-ansi -64 -O2 -fullwarn -woff 1429 -D_SGI_SOURCE -DMP_NO_MP_WORD \
+ $(MPICMN)
+endif
+
+ifeq ($(TARGET),alphaOSF1)
+#Alpha/OSF1
+MPICMN += -DMP_ASSEMBLY_MULTIPLY
+AS_OBJS+= mpvalpha.o
+#CFLAGS= -O -Olimit 4000 -ieee_with_inexact -std1 -DOSF1 -D_REENTRANT $(MPICMN)
+CFLAGS= -O -Olimit 4000 -ieee_with_inexact -std1 -DOSF1 -D_REENTRANT \
+ -DMP_NO_MP_WORD $(MPICMN)
+endif
+
+ifeq ($(TARGET),v9SOLARIS)
+#Solaris 64
+SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xchip=ultra -xarch=v9a -KPIC -mt
+#SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xdepend -xchip=ultra -xarch=v9a -KPIC -mt
+SOLARIS_ASM_FLAGS = -xchip=ultra -xarch=v9a -KPIC -mt
+AS_OBJS += montmulfv9.o
+AS_OBJS += mpi_sparc.o mpv_sparcv9.o
+MPICMN += -DMP_USE_UINT_DIGIT
+#MPICMN += -DMP_NO_MP_WORD
+MPICMN += -DMP_ASSEMBLY_MULTIPLY
+MPICMN += -DMP_USING_MONT_MULF
+CFLAGS= -O -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \
+ -DSOLARIS2_8 -xarch=v9 -DXP_UNIX $(MPICMN)
+#CFLAGS= -g -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \
+ -DSOLARIS2_8 -xarch=v9 -DXP_UNIX $(MPICMN)
+endif
+
+ifeq ($(TARGET),v8plusSOLARIS)
+#Solaris 32
+SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xdepend -xchip=ultra -xarch=v8plusa -KPIC -mt
+SOLARIS_ASM_FLAGS = -xchip=ultra -xarch=v8plusa -KPIC -mt
+AS_OBJS += montmulfv8.o
+AS_OBJS += mpi_sparc.o mpv_sparcv8.o
+#AS_OBJS = montmulf.o
+MPICMN += -DMP_ASSEMBLY_MULTIPLY
+MPICMN += -DMP_USING_MONT_MULF
+MPICMN += -DMP_USE_UINT_DIGIT
+MPICMN += -DMP_NO_MP_WORD
+CFLAGS=-O -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \
+ -DSOLARIS2_6 -xarch=v8plus -DXP_UNIX $(MPICMN)
+endif
+
+ifeq ($(TARGET),v8SOLARIS)
+#Solaris 32
+#SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xdepend -xchip=ultra -xarch=v8 -KPIC -mt
+#SOLARIS_ASM_FLAGS = -xchip=ultra -xarch=v8plusa -KPIC -mt
+#AS_OBJS = montmulfv8.o mpi_sparc.o mpv_sparcv8.o
+#AS_OBJS = montmulf.o
+#MPICMN += -DMP_USING_MONT_MULF
+#MPICMN += -DMP_ASSEMBLY_MULTIPLY
+MPICMN += -DMP_USE_LONG_LONG_MULTIPLY -DMP_USE_UINT_DIGIT
+MPICMN += -DMP_NO_MP_WORD
+CFLAGS=-O -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \
+ -DSOLARIS2_6 -xarch=v8 -DXP_UNIX $(MPICMN)
+endif
+
+ifeq ($(TARGET),ia64HPUX)
+#HPUX 32 on ia64 -- 64 bit digits SCREAM.
+# This one is for DD32 which is the 32-bit ABI with 64-bit registers.
+CFLAGS= +O3 -DHPUX10 -D_POSIX_C_SOURCE=199506L -Aa +Z -DHPUX -Dhppa \
+ -D_HPUX_SOURCE -Aa +e -z +p +DD32 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN)
+#CFLAGS= -O -DHPUX10 -D_POSIX_C_SOURCE=199506L -Aa +Z -DHPUX -Dhppa \
+ -D_HPUX_SOURCE -Aa +e -z +p +DD32 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN)
+#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
+ -D_HPUX_SOURCE -Aa +e -z +p +DD32 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN)
+endif
+
+ifeq ($(TARGET),ia64HPUX64)
+#HPUX 32 on ia64
+# This one is for DD64 which is the 64-bit ABI
+CFLAGS= +O3 -DHPUX10 -D_POSIX_C_SOURCE=199506L -Aa +Z -DHPUX -Dhppa \
+ -D_HPUX_SOURCE -Aa +e -z +p +DD64 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN)
+#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
+ -D_HPUX_SOURCE -Aa +e -z +p +DD64 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN)
+endif
+
+ifeq ($(TARGET),PA2.0WHPUX)
+#HPUX64 (HP PA 2.0 Wide) using MAXPY and 64-bit digits
+MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
+AS_OBJS = mpi_hp.o hpma512.o hppa20.o
+CFLAGS= -O -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
+ -D_HPUX_SOURCE -Aa +e -z +DA2.0W +DS2.0 +O3 +DChpux -DHPUX11 -DXP_UNIX \
+ $(MPICMN)
+#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
+ -D_HPUX_SOURCE -Aa +e -z +DA2.0W +DS2.0 +DChpux -DHPUX11 -DXP_UNIX \
+ $(MPICMN)
+AS = $(CC) $(CFLAGS) -c
+endif
+
+ifeq ($(TARGET),PA2.0NHPUX)
+#HPUX32 (HP PA 2.0 Narrow) hybrid model, using 32-bit digits
+# This one is for DA2.0 (N) which is the 32-bit ABI with 64-bit registers.
+MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
+AS_OBJS = mpi_hp.o hpma512.o hppa20.o
+CFLAGS= +O3 -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
+ -D_HPUX_SOURCE -Aa +e -z +DA2.0 +DS2.0 +DChpux -DHPUX11 -DXP_UNIX \
+ -Wl,+k $(MPICMN)
+#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
+ -D_HPUX_SOURCE -Aa +e -z +DA2.0 +DS2.0 +DChpux -DHPUX11 -DXP_UNIX \
+ -Wl,+k $(MPICMN)
+AS = $(CC) $(CFLAGS) -c
+endif
+
+ifeq ($(TARGET),PA1.1HPUX)
+#HPUX32 (HP PA 1.1) Pure 32 bit
+MPICMN += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
+#MPICMN += -DMP_USE_LONG_LONG_MULTIPLY
+CFLAGS= -O -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
+ -D_HPUX_SOURCE +DAportable +DS1.1 -DHPUX11 -DXP_UNIX $(MPICMN)
+##CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
+# -D_HPUX_SOURCE +DAportable +DS1.1 -DHPUX11 -DXP_UNIX $(MPICMN)
+endif
+
+ifeq ($(TARGET),32AIX)
+#
+CC = xlC_r
+MPICMN += -DMP_USE_UINT_DIGIT
+MPICMN += -DMP_NO_DIV_WORD
+#MPICMN += -DMP_NO_MUL_WORD
+MPICMN += -DMP_NO_ADD_WORD
+MPICMN += -DMP_NO_SUB_WORD
+#MPICMN += -DMP_NO_MP_WORD
+#MPICMN += -DMP_USE_LONG_LONG_MULTIPLY
+CFLAGS = -O -DAIX -DSYSV -qarch=com -DAIX4_3 -DXP_UNIX -UDEBUG -DNDEBUG $(MPICMN)
+#CFLAGS = -g -DAIX -DSYSV -qarch=com -DAIX4_3 -DXP_UNIX -UDEBUG -DNDEBUG $(MPICMN)
+#CFLAGS += -pg
+endif
+
+ifeq ($(TARGET),64AIX)
+#
+CC = xlC_r
+MPICMN += -DMP_USE_UINT_DIGIT
+CFLAGS = -O -O2 -DAIX -DSYSV -qarch=com -DAIX_64BIT -DAIX4_3 -DXP_UNIX -UDEBUG -DNDEBUG $(MPICMN)
+OBJECT_MODE=64
+export OBJECT_MODE
+endif
+
+ifeq ($(TARGET),x86LINUX)
+#Linux
+AS_OBJS = mpi_x86.o
+MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
+MPICMN += -DMP_MONT_USE_MP_MUL
+CFLAGS= -O2 -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \
+ -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \
+ -DXP_UNIX -UDEBUG -DNDEBUG -D_REENTRANT $(MPICMN)
+#CFLAGS= -g -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \
+ -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \
+ -DXP_UNIX -DDEBUG -UNDEBUG -D_REENTRANT $(MPICMN)
+#CFLAGS= -g -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \
+ -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \
+ -DXP_UNIX -UDEBUG -DNDEBUG -D_REENTRANT $(MPICMN)
+endif
diff --git a/security/nss/tests/cert/eccert.sh b/security/nss/tests/cert/eccert.sh
new file mode 100644
index 000000000..026f8827a
--- /dev/null
+++ b/security/nss/tests/cert/eccert.sh
@@ -0,0 +1,889 @@
+#! /bin/sh
+#
+# 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) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+# Sun Microsystems, Inc. All Rights Reserved.
+#
+# Contributor(s):
+# Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+#
+# 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.
+#
+
+########################################################################
+#
+# mozilla/security/nss/tests/cert/rcert.sh
+#
+# Certificate generating and handeling for NSS QA, can be included
+# multiple times from all.sh and the individual scripts
+#
+# needs to work on all Unix and Windows platforms
+#
+# included from (don't expect this to be up to date)
+# --------------------------------------------------
+# all.sh
+# ssl.sh
+# smime.sh
+# tools.sh
+#
+# special strings
+# ---------------
+# FIXME ... known problems, search for this string
+# NOTE .... unexpected behavior
+#
+# FIXME - Netscape - NSS
+########################################################################
+
+############################## cert_init ###############################
+# local shell function to initialize this script
+########################################################################
+cert_init()
+{
+ SCRIPTNAME="cert.sh"
+ if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for
+ CLEANUP="${SCRIPTNAME}" # cleaning this script will do it
+ fi
+ if [ -z "${INIT_SOURCED}" ] ; then
+ cd ../common
+ . ./init.sh
+ fi
+ SCRIPTNAME="cert.sh"
+ html_head "Certutil Tests"
+
+ ################## Generate noise for our CA cert. ######################
+ # NOTE: these keys are only suitable for testing, as this whole thing
+ # bypasses the entropy gathering. Don't use this method to generate
+ # keys and certs for product use or deployment.
+ #
+ ps -efl > ${NOISE_FILE} 2>&1
+ ps aux >> ${NOISE_FILE} 2>&1
+ noise
+
+}
+
+cert_log() ###################### write the cert_status file
+{
+ echo "$SCRIPTNAME $*"
+ echo $* >>${CERT_LOG_FILE}
+}
+
+################################ noise ##################################
+# Generate noise for our certs
+#
+# NOTE: these keys are only suitable for testing, as this whole thing bypasses
+# the entropy gathering. Don't use this method to generate keys and certs for
+# product use or deployment.
+#########################################################################
+noise()
+{
+ #netstat >> ${NOISE_FILE} 2>&1
+ date >> ${NOISE_FILE} 2>&1
+}
+
+################################ certu #################################
+# local shell function to call certutil, also: writes action and options to
+# stdout, sets variable RET and writes results to the html file results
+########################################################################
+certu()
+{
+ echo "$SCRIPTNAME: ${CU_ACTION} --------------------------"
+
+ if [ -n "${CU_SUBJECT}" ]; then
+ #the subject of the cert contains blanks, and the shell
+ #will strip the quotes off the string, if called otherwise...
+ echo "certutil -s \"${CU_SUBJECT}\" $*"
+ certutil -s "${CU_SUBJECT}" $*
+ RET=$?
+ CU_SUBJECT=""
+ else
+ echo "certutil $*"
+ certutil $*
+ RET=$?
+ fi
+ if [ "$RET" -ne 0 ]; then
+ CERTFAILED=$RET
+ html_failed "<TR><TD>${CU_ACTION} ($RET) "
+ cert_log "ERROR: ${CU_ACTION} failed $RET"
+ else
+ html_passed "<TR><TD>${CU_ACTION}"
+ fi
+
+ # echo "Contine?"
+ # cat > /dev/null
+ return $RET
+}
+
+############################# cert_init_cert ##########################
+# local shell function to initialize creation of client and server certs
+########################################################################
+cert_init_cert()
+{
+ CERTDIR="$1"
+ CERTNAME="$2"
+ CERTSERIAL="$3"
+ DOMAIN="$4"
+
+ if [ ! -d "${CERTDIR}" ]; then
+ mkdir -p "${CERTDIR}"
+ else
+ echo "$SCRIPTNAME: WARNING - ${CERTDIR} exists"
+ fi
+ cd "${CERTDIR}"
+ CERTDIR="."
+
+ PROFILEDIR=${CERTDIR}
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ PROFILEDIR="multiaccess:${DOMAIN}"
+ fi
+
+ noise
+}
+
+############################# hw_acc #################################
+# local shell function to add hw accelerator modules to the db
+########################################################################
+hw_acc()
+{
+ HW_ACC_RET=0
+ HW_ACC_ERR=""
+ if [ -n "$O_HWACC" -a "$O_HWACC" = ON -a -z "$USE_64" ] ; then
+ echo "creating $CERTNAME s cert with hwaccelerator..."
+ #case $ACCELERATOR in
+ #rainbow)
+
+
+ echo "modutil -add rainbow -libfile /usr/lib/libcryptoki22.so "
+ echo " -dbdir ${PROFILEDIR} 2>&1 "
+ echo | modutil -add rainbow -libfile /usr/lib/libcryptoki22.so \
+ -dbdir ${PROFILEDIR} 2>&1
+ if [ "$?" -ne 0 ]; then
+ echo "modutil -add rainbow failed in `pwd`"
+ HW_ACC_RET=1
+ HW_ACC_ERR="modutil -add rainbow"
+ fi
+
+ echo "modutil -add ncipher "
+ echo " -libfile /opt/nfast/toolkits/pkcs11/libcknfast.so "
+ echo " -dbdir ${PROFILEDIR} 2>&1 "
+ echo | modutil -add ncipher \
+ -libfile /opt/nfast/toolkits/pkcs11/libcknfast.so \
+ -dbdir ${PROFILEDIR} 2>&1
+ if [ "$?" -ne 0 ]; then
+ echo "modutil -add ncipher failed in `pwd`"
+ HW_ACC_RET=`expr $HW_ACC_RET + 2`
+ HW_ACC_ERR="$HW_ACC_ERR,modutil -add ncipher"
+ fi
+ if [ "$HW_ACC_RET" -ne 0 ]; then
+ html_failed "<TR><TD>Adding HW accelerators to certDB for ${CERTNAME} ($HW_ACC_RET) "
+ else
+ html_passed "<TR><TD>Adding HW accelerators to certDB for ${CERTNAME}"
+ fi
+
+ fi
+ return $HW_ACC_RET
+}
+
+############################# cert_create_cert #########################
+# local shell function to create client certs
+# initialize DB, import
+# root cert
+# add cert to DB
+########################################################################
+cert_create_cert()
+{
+ cert_init_cert "$1" "$2" "$3" "$4"
+
+ CU_ACTION="Initializing ${CERTNAME}'s Cert DB"
+ certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+ hw_acc
+ CU_ACTION="Import Root CA for $CERTNAME"
+ certu -A -n "TestCA" -t "TC,TC,TC" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${R_CADIR}/root.cert" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+ cert_add_cert "$5"
+ return $?
+}
+
+############################# cert_create_certs ########################
+# local shell function to create client certs
+# initialize DB, import
+# root certs (RSA and EC)
+# add certs (RSA and EC) to DB
+########################################################################
+cert_create_certs()
+{
+ cert_init_cert "$1" "$2" "$3" "$4"
+
+ CU_ACTION="Initializing ${CERTNAME}'s Cert DB"
+ certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+ hw_acc
+ CU_ACTION="Import Root CA for $CERTNAME"
+ certu -A -n "TestCA" -t "TC,TC,TC" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${R_CADIR}/root.cert" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+ CU_ACTION="Import EC Root CA for $CERTNAME"
+ certu -A -n "TestCA-ec" -t "TC,TC,TC" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${R_CADIR}/ecroot.cert" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+ cert_add_certs "$5"
+ return $?
+}
+
+############################# cert_add_cert ############################
+# local shell function to add client certs to an existing CERT DB
+# generate request
+# sign request
+# import Cert
+#
+########################################################################
+cert_add_cert()
+{
+
+ CU_ACTION="Generate Cert Request for $CERTNAME"
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ CU_ACTION="Sign ${CERTNAME}'s Request"
+ certu -C -c "TestCA" -m "$CERTSERIAL" -v 60 -d "${P_R_CADIR}" \
+ -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ CU_ACTION="Import $CERTNAME's Cert"
+ certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+ -i "${CERTNAME}.cert" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ cert_log "SUCCESS: $CERTNAME's Cert Created"
+ return 0
+}
+
+############################# cert_add_certs ############################
+# local shell function to add client certs to an existing CERT DB
+# generate request
+# sign request
+# import Cert
+#
+# Do this for both RSA and EC certs
+########################################################################
+cert_add_certs()
+{
+ CURVE="secp160r2"
+
+ CU_ACTION="Generate Cert Request for $CERTNAME"
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ CU_ACTION="Sign ${CERTNAME}'s Request"
+ certu -C -c "TestCA" -m "$CERTSERIAL" -v 60 -d "${P_R_CADIR}" \
+ -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ CU_ACTION="Import $CERTNAME's Cert"
+ certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+ -i "${CERTNAME}.cert" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ cert_log "SUCCESS: $CERTNAME's Cert Created"
+
+#
+# Generate and add EC cert
+#
+ CU_ACTION="Generate EC Cert Request for $CERTNAME"
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ certu -R -k ec -q "${CURVE}" -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ CU_ACTION="Sign ${CERTNAME}'s EC Request"
+ certu -C -c "TestCA-ec" -m "$CERTSERIAL" -v 60 -d "${P_R_CADIR}" \
+ -i req -o "${CERTNAME}-ec.cert" -f "${R_PWFILE}" "$1" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ CU_ACTION="Import $CERTNAME's EC Cert"
+ certu -A -n "${CERTNAME}-ec" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+ -i "${CERTNAME}-ec.cert" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ cert_log "SUCCESS: $CERTNAME's EC Cert Created"
+
+ return 0
+}
+
+################################# cert_all_CA ################################
+# local shell function to build the additional Temp. Certificate Authority (CA)
+# used for the "real life" ssl test with 2 different CA's in the
+# client and in teh server's dir
+##########################################################################
+cert_all_CA()
+{
+ CA_CURVE="secp160r1"
+
+ echo nss > ${PWFILE}
+
+ ALL_CU_SUBJECT="CN=NSS Test CA, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ cert_CA $CADIR TestCA -x "CTu,CTu,CTu" ${D_CA} "1"
+
+# Create EC version of TestCA
+ ALL_CU_SUBJECT="CN=NSS Test CA (ECC), O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ cert_ec_CA $CADIR TestCA-ec -x "CTu,CTu,CTu" ${D_CA} "1" ${CA_CURVE}
+
+ ALL_CU_SUBJECT="CN=NSS Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $SERVER_CADIR serverCA -x "Cu,Cu,Cu" ${D_SERVER_CA} "2"
+ ALL_CU_SUBJECT="CN=NSS Chain1 Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $SERVER_CADIR chain-1-serverCA "-c serverCA" "u,u,u" ${D_SERVER_CA} "3"
+ ALL_CU_SUBJECT="CN=NSS Chain2 Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $SERVER_CADIR chain-2-serverCA "-c chain-1-serverCA" "u,u,u" ${D_SERVER_CA} "4"
+
+#
+# Create EC versions of the above CA certs
+#
+ ALL_CU_SUBJECT="CN=NSS Server Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_ec_CA $SERVER_CADIR serverCA-ec -x "Cu,Cu,Cu" ${D_SERVER_CA} "2" ${CA_CURVE}
+ ALL_CU_SUBJECT="CN=NSS Chain1 Server Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_ec_CA $SERVER_CADIR chain-1-serverCA-ec "-c serverCA-ec" "u,u,u" ${D_SERVER_CA} "3" ${CA_CURVE}
+ ALL_CU_SUBJECT="CN=NSS Chain2 Server Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_ec_CA $SERVER_CADIR chain-2-serverCA-ec "-c chain-1-serverCA-ec" "u,u,u" ${D_SERVER_CA} "4" ${CA_CURVE}
+
+
+ ALL_CU_SUBJECT="CN=NSS Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $CLIENT_CADIR clientCA -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5"
+ ALL_CU_SUBJECT="CN=NSS Chain1 Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $CLIENT_CADIR chain-1-clientCA "-c clientCA" "u,u,u" ${D_CLIENT_CA} "6"
+ ALL_CU_SUBJECT="CN=NSS Chain2 Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $CLIENT_CADIR chain-2-clientCA "-c chain-1-clientCA" "u,u,u" ${D_CLIENT_CA} "7"
+
+#
+# Create EC versions of the above CA certs
+#
+ ALL_CU_SUBJECT="CN=NSS Client Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_ec_CA $CLIENT_CADIR clientCA-ec -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5" ${CA_CURVE}
+ ALL_CU_SUBJECT="CN=NSS Chain1 Client Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_ec_CA $CLIENT_CADIR chain-1-clientCA-ec "-c clientCA-ec" "u,u,u" ${D_CLIENT_CA} "6" ${CA_CURVE}
+ ALL_CU_SUBJECT="CN=NSS Chain2 Client Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_ec_CA $CLIENT_CADIR chain-2-clientCA-ec "-c chain-1-clientCA-ec" "u,u,u" ${D_CLIENT_CA} "7" ${CA_CURVE}
+
+ rm $CLIENT_CADIR/root.cert $SERVER_CADIR/root.cert
+ rm $CLIENT_CADIR/ecroot.cert $SERVER_CADIR/ecroot.cert
+ # root.cert in $CLIENT_CADIR and in $SERVER_CADIR is the one of the last
+ # in the chain
+}
+
+################################# cert_CA ################################
+# local shell function to build the Temp. Certificate Authority (CA)
+# used for testing purposes, creating a CA Certificate and a root cert
+##########################################################################
+cert_CA()
+{
+ CUR_CADIR=$1
+ NICKNAME=$2
+ SIGNER=$3
+ TRUSTARG=$4
+ DOMAIN=$5
+ CERTSERIAL=$6
+
+ echo "$SCRIPTNAME: Creating a CA Certificate $NICKNAME =========================="
+
+ if [ ! -d "${CUR_CADIR}" ]; then
+ mkdir -p "${CUR_CADIR}"
+ fi
+ cd ${CUR_CADIR}
+ pwd
+
+ LPROFILE=.
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ LPROFILE="multiaccess:${DOMAIN}"
+ fi
+
+ if [ "$SIGNER" = "-x" ] ; then # self signed -> create DB
+ CU_ACTION="Creating CA Cert DB"
+ certu -N -d ${LPROFILE} -f ${R_PWFILE} 2>&1
+ if [ "$RET" -ne 0 ]; then
+ Exit 5 "Fatal - failed to create CA $NICKNAME "
+ fi
+ echo "$SCRIPTNAME: Certificate initialized ----------"
+ fi
+
+
+ ################# Creating CA Cert ######################################
+ #
+ CU_ACTION="Creating CA Cert $NICKNAME "
+ CU_SUBJECT=$ALL_CU_SUBJECT
+ certu -S -n $NICKNAME -t $TRUSTARG -v 60 $SIGNER -d ${LPROFILE} -1 -2 -5 \
+ -f ${R_PWFILE} -z ${R_NOISE_FILE} -m $CERTSERIAL 2>&1 <<CERTSCRIPT
+5
+9
+n
+y
+-1
+n
+5
+6
+7
+9
+n
+CERTSCRIPT
+
+ if [ "$RET" -ne 0 ]; then
+ echo "return value is $RET"
+ Exit 6 "Fatal - failed to create CA cert"
+ fi
+
+ ################# Exporting Root Cert ###################################
+ #
+ CU_ACTION="Exporting Root Cert"
+ certu -L -n $NICKNAME -r -d ${LPROFILE} -o root.cert
+ if [ "$RET" -ne 0 ]; then
+ Exit 7 "Fatal - failed to export root cert"
+ fi
+ cp root.cert ${NICKNAME}.ca.cert
+}
+
+################################ cert_ec_CA ##############################
+# local shell function to build the Temp. Certificate Authority (CA)
+# used for testing purposes, creating a CA Certificate and a root cert
+# This is the ECC version of cert_CA.
+##########################################################################
+cert_ec_CA()
+{
+ CUR_CADIR=$1
+ NICKNAME=$2
+ SIGNER=$3
+ TRUSTARG=$4
+ DOMAIN=$5
+ CERTSERIAL=$6
+ CURVE=$7
+
+ echo "$SCRIPTNAME: Creating an EC CA Certificate $NICKNAME =========================="
+
+ if [ ! -d "${CUR_CADIR}" ]; then
+ mkdir -p "${CUR_CADIR}"
+ fi
+ cd ${CUR_CADIR}
+ pwd
+
+ LPROFILE=.
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ LPROFILE="multiaccess:${DOMAIN}"
+ fi
+
+ ################# Creating an EC CA Cert ################################
+ #
+ CU_ACTION="Creating EC CA Cert $NICKNAME "
+ CU_SUBJECT=$ALL_CU_SUBJECT
+ certu -S -n $NICKNAME -k ec -q $CURVE -t $TRUSTARG -v 60 $SIGNER \
+ -d ${LPROFILE} -1 -2 -5 -f ${R_PWFILE} -z ${R_NOISE_FILE} \
+ -m $CERTSERIAL 2>&1 <<CERTSCRIPT
+5
+9
+n
+y
+-1
+n
+5
+6
+7
+9
+n
+CERTSCRIPT
+
+ if [ "$RET" -ne 0 ]; then
+ echo "return value is $RET"
+ Exit 6 "Fatal - failed to create EC CA cert"
+ fi
+
+ ################# Exporting EC Root Cert ################################
+ #
+ CU_ACTION="Exporting EC Root Cert"
+ certu -L -n $NICKNAME -r -d ${LPROFILE} -o ecroot.cert
+ if [ "$RET" -ne 0 ]; then
+ Exit 7 "Fatal - failed to export ec root cert"
+ fi
+ cp ecroot.cert ${NICKNAME}.ca.cert
+}
+
+############################## cert_smime_client #############################
+# local shell function to create client Certificates for S/MIME tests
+##############################################################################
+cert_smime_client()
+{
+ CERTFAILED=0
+ echo "$SCRIPTNAME: Creating Client CA Issued Certificates =============="
+
+ cert_create_certs ${ALICEDIR} "Alice" 30 ${D_ALICE}
+ cert_create_cert ${BOBDIR} "Bob" 40 ${D_BOB}
+
+ echo "$SCRIPTNAME: Creating Dave's Certificate -------------------------"
+ cert_create_cert "${DAVEDIR}" Dave 50 ${D_DAVE}
+
+ echo "$SCRIPTNAME: Creating multiEmail's Certificate --------------------"
+ cert_create_cert "${EVEDIR}" "Eve" 60 ${D_EVE} "-7 eve@bogus.net,eve@bogus.cc,beve@bogus.com"
+
+ #echo "************* Copying CA files to ${SERVERDIR}"
+ #cp ${CADIR}/*.db .
+ #hw_acc
+
+ #########################################################################
+ #
+ #cd ${CERTDIR}
+ #CU_ACTION="Creating ${CERTNAME}'s Server Cert"
+ #CU_SUBJECT="CN=${CERTNAME}, E=${CERTNAME}@bogus.com, O=BOGUS Netscape, L=Mountain View, ST=California, C=US"
+ #certu -S -n "${CERTNAME}" -c "TestCA" -t "u,u,u" -m "$CERTSERIAL" \
+ # -d ${PROFILEDIR} -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -v 60 2>&1
+
+ #CU_ACTION="Export Dave's Cert"
+ #cd ${DAVEDIR}
+ #certu -L -n "Dave" -r -d ${P_R_DAVE} -o Dave.cert
+
+ ################# Importing Certificates for S/MIME tests ###############
+ #
+ echo "$SCRIPTNAME: Importing Certificates =============================="
+ CU_ACTION="Import Alices's cert into Bob's db"
+ certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \
+ -i ${R_ALICEDIR}/Alice.cert 2>&1
+
+ CU_ACTION="Import Bob's cert into Alice's db"
+ certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \
+ -i ${R_BOBDIR}/Bob.cert 2>&1
+
+ CU_ACTION="Import Dave's cert into Alice's DB"
+ certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \
+ -i ${R_DAVEDIR}/Dave.cert 2>&1
+
+ CU_ACTION="Import Dave's cert into Bob's DB"
+ certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \
+ -i ${R_DAVEDIR}/Dave.cert 2>&1
+
+ CU_ACTION="Import Eve's cert into Alice's DB"
+ certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \
+ -i ${R_EVEDIR}/Eve.cert 2>&1
+
+ CU_ACTION="Import Eve's cert into Bob's DB"
+ certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \
+ -i ${R_EVEDIR}/Eve.cert 2>&1
+
+ if [ "$CERTFAILED" != 0 ] ; then
+ cert_log "ERROR: SMIME failed $RET"
+ else
+ cert_log "SUCCESS: SMIME passed"
+ fi
+}
+
+############################## cert_ssl ################################
+# local shell function to create client + server certs for extended SSL test
+########################################################################
+cert_extended_ssl()
+{
+ EC_CURVE="sect163r1"
+
+ ################# Creating Certs for extended SSL test ####################
+ #
+ CERTFAILED=0
+ echo "$SCRIPTNAME: Creating Certificates, issued by the last ==============="
+ echo " of a chain of CA's which are not in the same database============"
+
+ echo "Server Cert"
+ cert_init_cert ${EXT_SERVERDIR} "${HOSTADDR}" 1 ${D_EXT_SERVER}
+
+ CU_ACTION="Initializing ${CERTNAME}'s Cert DB (ext.)"
+ certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+
+ CU_ACTION="Generate Cert Request for $CERTNAME (ext)"
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+
+ CU_ACTION="Sign ${CERTNAME}'s Request (ext)"
+ cp ${CERTDIR}/req ${SERVER_CADIR}
+ certu -C -c "chain-2-serverCA" -m 200 -v 60 -d "${P_SERVER_CADIR}" \
+ -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" 2>&1
+
+ CU_ACTION="Import $CERTNAME's Cert -t u,u,u (ext)"
+ certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+ -i "${CERTNAME}.cert" 2>&1
+
+ CU_ACTION="Import Client Root CA -t T,, for $CERTNAME (ext.)"
+ certu -A -n "clientCA" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${CLIENT_CADIR}/clientCA.ca.cert" 2>&1
+#
+# Repeat the above for EC certs
+#
+ CU_ACTION="Generate EC Cert Request for $CERTNAME (ext)"
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ certu -R -d "${PROFILEDIR}" -k ec -q "${EC_CURVE}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+
+ CU_ACTION="Sign ${CERTNAME}'s EC Request (ext)"
+ cp ${CERTDIR}/req ${SERVER_CADIR}
+ certu -C -c "chain-2-serverCA-ec" -m 200 -v 60 -d "${P_SERVER_CADIR}" \
+ -i req -o "${CERTNAME}-ec.cert" -f "${R_PWFILE}" 2>&1
+
+ CU_ACTION="Import $CERTNAME's EC Cert -t u,u,u (ext)"
+ certu -A -n "${CERTNAME}-ec" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+ -i "${CERTNAME}-ec.cert" 2>&1
+
+ CU_ACTION="Import Client EC Root CA -t T,, for $CERTNAME (ext.)"
+ certu -A -n "clientCA-ec" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${CLIENT_CADIR}/clientCA-ec.ca.cert" 2>&1
+#
+# done with EC certs
+#
+ echo "Importing all the server's own CA chain into the servers DB"
+ for CA in `find ${SERVER_CADIR} -name "?*.ca.cert"` ;
+ do
+ N=`basename $CA | sed -e "s/.ca.cert//"`
+ if [ $N = "serverCA" ] ; then
+ T="-t C,C,C"
+ else
+ T="-t u,u,u"
+ fi
+ CU_ACTION="Import $N CA $T for $CERTNAME (ext.) "
+ certu -A -n $N $T -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${CA}" 2>&1
+ done
+#============
+ echo "Client Cert"
+ cert_init_cert ${EXT_CLIENTDIR} ExtendedSSLUser 1 ${D_EXT_CLIENT}
+
+ CU_ACTION="Initializing ${CERTNAME}'s Cert DB (ext.)"
+ certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+
+ CU_ACTION="Generate Cert Request for $CERTNAME (ext)"
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+
+ CU_ACTION="Sign ${CERTNAME}'s Request (ext)"
+ cp ${CERTDIR}/req ${CLIENT_CADIR}
+ certu -C -c "chain-2-clientCA" -m 300 -v 60 -d "${P_CLIENT_CADIR}" \
+ -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" 2>&1
+
+ CU_ACTION="Import $CERTNAME's Cert -t u,u,u (ext)"
+ certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+ -i "${CERTNAME}.cert" 2>&1
+ CU_ACTION="Import Server Root CA -t C,C,C for $CERTNAME (ext.)"
+ certu -A -n "serverCA" -t "C,C,C" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${SERVER_CADIR}/serverCA.ca.cert" 2>&1
+#
+# Repeat the above for EC certs
+#
+ CU_ACTION="Generate EC Cert Request for $CERTNAME (ext)"
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ certu -R -d "${PROFILEDIR}" -k ec -q "${EC_CURVE}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+
+ CU_ACTION="Sign ${CERTNAME}'s EC Request (ext)"
+ cp ${CERTDIR}/req ${CLIENT_CADIR}
+ certu -C -c "chain-2-clientCA-ec" -m 300 -v 60 -d "${P_CLIENT_CADIR}" \
+ -i req -o "${CERTNAME}-ec.cert" -f "${R_PWFILE}" 2>&1
+
+ CU_ACTION="Import $CERTNAME's EC Cert -t u,u,u (ext)"
+ certu -A -n "${CERTNAME}-ec" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+ -i "${CERTNAME}-ec.cert" 2>&1
+ CU_ACTION="Import Server EC Root CA -t C,C,C for $CERTNAME (ext.)"
+ certu -A -n "serverCA-ec" -t "C,C,C" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${SERVER_CADIR}/serverCA-ec.ca.cert" 2>&1
+#
+# done with EC certs
+#
+ echo "Importing all the client's own CA chain into the servers DB"
+ for CA in `find ${CLIENT_CADIR} -name "?*.ca.cert"` ;
+ do
+ N=`basename $CA | sed -e "s/.ca.cert//"`
+ if [ $N = "clientCA" ] ; then
+ T="-t T,C,C"
+ else
+ T="-t u,u,u"
+ fi
+ CU_ACTION="Import $N CA $T for $CERTNAME (ext.)"
+ certu -A -n $N $T -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${CA}" 2>&1
+ done
+ if [ "$CERTFAILED" != 0 ] ; then
+ cert_log "ERROR: EXT failed $RET"
+ else
+ cert_log "SUCCESS: EXT passed"
+ fi
+}
+
+############################## cert_ssl ################################
+# local shell function to create client + server certs for SSL test
+########################################################################
+cert_ssl()
+{
+ ################# Creating Certs for SSL test ###########################
+ #
+ CERTFAILED=0
+ echo "$SCRIPTNAME: Creating Client CA Issued Certificates ==============="
+ cert_create_certs ${CLIENTDIR} "TestUser" 70 ${D_CLIENT}
+
+ echo "$SCRIPTNAME: Creating Server CA Issued Certificate for \\"
+ echo " ${HOSTADDR} ------------------------------------"
+ cert_create_certs ${SERVERDIR} "${HOSTADDR}" 100 ${D_SERVER}
+ certu -M -n "TestCA" -t "TC,TC,TC" -d ${PROFILEDIR}
+ certu -M -n "TestCA-ec" -t "TC,TC,TC" -d ${PROFILEDIR}
+# cert_init_cert ${SERVERDIR} "${HOSTADDR}" 1 ${D_SERVER}
+# echo "************* Copying CA files to ${SERVERDIR}"
+# cp ${CADIR}/*.db .
+# hw_acc
+# CU_ACTION="Creating ${CERTNAME}'s Server Cert"
+# CU_SUBJECT="CN=${CERTNAME}, O=BOGUS Netscape, L=Mountain View, ST=California, C=US"
+# certu -S -n "${CERTNAME}" -c "TestCA" -t "Pu,Pu,Pu" -d ${PROFILEDIR} \
+# -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -v 60 2>&1
+
+ if [ "$CERTFAILED" != 0 ] ; then
+ cert_log "ERROR: SSL failed $RET"
+ else
+ cert_log "SUCCESS: SSL passed"
+ fi
+}
+############################## cert_stresscerts ################################
+# local shell function to create client certs for SSL stresstest
+########################################################################
+cert_stresscerts()
+{
+
+ ############### Creating Certs for SSL stress test #######################
+ #
+ CERTDIR="$CLIENTDIR"
+ cd "${CERTDIR}"
+
+ PROFILEDIR=${CERTDIR}
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ PROFILEDIR="multiaccess:${D_CLIENT}"
+ fi
+ CERTFAILED=0
+ echo "$SCRIPTNAME: Creating Client CA Issued Certificates ==============="
+
+ CONTINUE=$GLOB_MAX_CERT
+ CERTSERIAL=10
+
+ while [ $CONTINUE -ge $GLOB_MIN_CERT ]
+ do
+ CERTNAME="TestUser$CONTINUE"
+# cert_add_cert ${CLIENTDIR} "TestUser$CONTINUE" $CERTSERIAL
+ cert_add_certs
+ CERTSERIAL=`expr $CERTSERIAL + 1 `
+ CONTINUE=`expr $CONTINUE - 1 `
+ done
+ if [ "$CERTFAILED" != 0 ] ; then
+ cert_log "ERROR: StressCert failed $RET"
+ else
+ cert_log "SUCCESS: StressCert passed"
+ fi
+}
+
+############################## cert_fips #####################################
+# local shell function to create certificates for FIPS tests
+##############################################################################
+cert_fips()
+{
+ CERTFAILED=0
+ echo "$SCRIPTNAME: Creating FIPS 140-1 DSA Certificates =============="
+ cert_init_cert "${FIPSDIR}" "FIPS PUB 140-1 Test Certificate" 1000 "${D_FIPS}"
+
+ CU_ACTION="Initializing ${CERTNAME}'s Cert DB"
+ certu -N -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" 2>&1
+
+ echo "$SCRIPTNAME: Enable FIPS mode on database -----------------------"
+ CU_ACTION="Enable FIPS mode on database for ${CERTNAME}"
+ echo "modutil -dbdir ${PROFILEDIR} -fips true "
+ modutil -dbdir ${PROFILEDIR} -fips true 2>&1 <<MODSCRIPT
+y
+MODSCRIPT
+ RET=$?
+ if [ "$RET" -ne 0 ]; then
+ html_failed "<TR><TD>${CU_ACTION} ($RET) "
+ cert_log "ERROR: ${CU_ACTION} failed $RET"
+ else
+ html_passed "<TR><TD>${CU_ACTION}"
+ fi
+
+ CU_ACTION="Generate Certificate for ${CERTNAME}"
+ CU_SUBJECT="CN=${CERTNAME}, E=fips@bogus.com, O=BOGUS NSS, OU=FIPS PUB 140-1, L=Mountain View, ST=California, C=US"
+ certu -S -n ${FIPSCERTNICK} -x -t "Cu,Cu,Cu" -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" -k dsa -m 500 -z "${R_NOISE_FILE}" 2>&1
+ if [ "$RET" -eq 0 ]; then
+ cert_log "SUCCESS: FIPS passed"
+ fi
+}
+
+############################## cert_cleanup ############################
+# local shell function to finish this script (no exit since it might be
+# sourced)
+########################################################################
+cert_cleanup()
+{
+ cert_log "$SCRIPTNAME: finished $SCRIPTNAME"
+ html "</TABLE><BR>"
+ cd ${QADIR}
+ . common/cleanup.sh
+}
+
+################## main #################################################
+
+cert_init
+cert_all_CA
+cert_extended_ssl
+cert_ssl
+cert_smime_client
+cert_fips
+if [ -n "$DO_DIST_ST" -a "$DO_DIST_ST" = "TRUE" ] ; then
+ cert_stresscerts
+ #following lines to be used when databases are to be reused
+ #cp -r /u/sonmi/tmp/stress/kentuckyderby.13/* $HOSTDIR
+ #cp -r $HOSTDIR/../${HOST}.2/* $HOSTDIR
+
+fi
+cert_cleanup
diff --git a/security/nss/tests/cert/noeccert.sh b/security/nss/tests/cert/noeccert.sh
new file mode 100755
index 000000000..6bb91b6a8
--- /dev/null
+++ b/security/nss/tests/cert/noeccert.sh
@@ -0,0 +1,654 @@
+#! /bin/sh
+#
+# 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) 1994-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.
+#
+
+########################################################################
+#
+# mozilla/security/nss/tests/cert/rcert.sh
+#
+# Certificate generating and handeling for NSS QA, can be included
+# multiple times from all.sh and the individual scripts
+#
+# needs to work on all Unix and Windows platforms
+#
+# included from (don't expect this to be up to date)
+# --------------------------------------------------
+# all.sh
+# ssl.sh
+# smime.sh
+# tools.sh
+#
+# special strings
+# ---------------
+# FIXME ... known problems, search for this string
+# NOTE .... unexpected behavior
+#
+# FIXME - Netscape - NSS
+########################################################################
+
+############################## cert_init ###############################
+# local shell function to initialize this script
+########################################################################
+cert_init()
+{
+ SCRIPTNAME="cert.sh"
+ if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for
+ CLEANUP="${SCRIPTNAME}" # cleaning this script will do it
+ fi
+ if [ -z "${INIT_SOURCED}" ] ; then
+ cd ../common
+ . ./init.sh
+ fi
+ SCRIPTNAME="cert.sh"
+ html_head "Certutil Tests"
+
+ ################## Generate noise for our CA cert. ######################
+ # NOTE: these keys are only suitable for testing, as this whole thing
+ # bypasses the entropy gathering. Don't use this method to generate
+ # keys and certs for product use or deployment.
+ #
+ ps -efl > ${NOISE_FILE} 2>&1
+ ps aux >> ${NOISE_FILE} 2>&1
+ noise
+
+}
+
+cert_log() ###################### write the cert_status file
+{
+ echo "$SCRIPTNAME $*"
+ echo $* >>${CERT_LOG_FILE}
+}
+
+################################ noise ##################################
+# Generate noise for our certs
+#
+# NOTE: these keys are only suitable for testing, as this whole thing bypasses
+# the entropy gathering. Don't use this method to generate keys and certs for
+# product use or deployment.
+#########################################################################
+noise()
+{
+ #netstat >> ${NOISE_FILE} 2>&1
+ date >> ${NOISE_FILE} 2>&1
+}
+
+################################ certu #################################
+# local shell function to call certutil, also: writes action and options to
+# stdout, sets variable RET and writes results to the html file results
+########################################################################
+certu()
+{
+ echo "$SCRIPTNAME: ${CU_ACTION} --------------------------"
+
+ if [ -n "${CU_SUBJECT}" ]; then
+ #the subject of the cert contains blanks, and the shell
+ #will strip the quotes off the string, if called otherwise...
+ echo "certutil -s \"${CU_SUBJECT}\" $*"
+ certutil -s "${CU_SUBJECT}" $*
+ RET=$?
+ CU_SUBJECT=""
+ else
+ echo "certutil $*"
+ certutil $*
+ RET=$?
+ fi
+ if [ "$RET" -ne 0 ]; then
+ CERTFAILED=$RET
+ html_failed "<TR><TD>${CU_ACTION} ($RET) "
+ cert_log "ERROR: ${CU_ACTION} failed $RET"
+ else
+ html_passed "<TR><TD>${CU_ACTION}"
+ fi
+
+ # echo "Contine?"
+ # cat > /dev/null
+ return $RET
+}
+
+############################# cert_init_cert ##########################
+# local shell function to initialize creation of client and server certs
+########################################################################
+cert_init_cert()
+{
+ CERTDIR="$1"
+ CERTNAME="$2"
+ CERTSERIAL="$3"
+ DOMAIN="$4"
+
+ if [ ! -d "${CERTDIR}" ]; then
+ mkdir -p "${CERTDIR}"
+ else
+ echo "$SCRIPTNAME: WARNING - ${CERTDIR} exists"
+ fi
+ cd "${CERTDIR}"
+ CERTDIR="."
+
+ PROFILEDIR=${CERTDIR}
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ PROFILEDIR="multiaccess:${DOMAIN}"
+ fi
+
+ noise
+}
+
+############################# hw_acc #################################
+# local shell function to add hw accelerator modules to the db
+########################################################################
+hw_acc()
+{
+ HW_ACC_RET=0
+ HW_ACC_ERR=""
+ if [ -n "$O_HWACC" -a "$O_HWACC" = ON -a -z "$USE_64" ] ; then
+ echo "creating $CERTNAME s cert with hwaccelerator..."
+ #case $ACCELERATOR in
+ #rainbow)
+
+
+ echo "modutil -add rainbow -libfile /usr/lib/libcryptoki22.so "
+ echo " -dbdir ${PROFILEDIR} 2>&1 "
+ echo | modutil -add rainbow -libfile /usr/lib/libcryptoki22.so \
+ -dbdir ${PROFILEDIR} 2>&1
+ if [ "$?" -ne 0 ]; then
+ echo "modutil -add rainbow failed in `pwd`"
+ HW_ACC_RET=1
+ HW_ACC_ERR="modutil -add rainbow"
+ fi
+
+ echo "modutil -add ncipher "
+ echo " -libfile /opt/nfast/toolkits/pkcs11/libcknfast.so "
+ echo " -dbdir ${PROFILEDIR} 2>&1 "
+ echo | modutil -add ncipher \
+ -libfile /opt/nfast/toolkits/pkcs11/libcknfast.so \
+ -dbdir ${PROFILEDIR} 2>&1
+ if [ "$?" -ne 0 ]; then
+ echo "modutil -add ncipher failed in `pwd`"
+ HW_ACC_RET=`expr $HW_ACC_RET + 2`
+ HW_ACC_ERR="$HW_ACC_ERR,modutil -add ncipher"
+ fi
+ if [ "$HW_ACC_RET" -ne 0 ]; then
+ html_failed "<TR><TD>Adding HW accelerators to certDB for ${CERTNAME} ($HW_ACC_RET) "
+ else
+ html_passed "<TR><TD>Adding HW accelerators to certDB for ${CERTNAME}"
+ fi
+
+ fi
+ return $HW_ACC_RET
+}
+
+############################# cert_create_cert #########################
+# local shell function to create client certs
+# initialize DB, import
+# root cert
+# add cert to DB
+########################################################################
+cert_create_cert()
+{
+ cert_init_cert "$1" "$2" "$3" "$4"
+
+ CU_ACTION="Initializing ${CERTNAME}'s Cert DB"
+ certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+ hw_acc
+ CU_ACTION="Import Root CA for $CERTNAME"
+ certu -A -n "TestCA" -t "TC,TC,TC" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${R_CADIR}/root.cert" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+ cert_add_cert "$5"
+ return $?
+}
+
+############################# cert_add_cert ############################
+# local shell function to add client certs to an existing CERT DB
+# generate request
+# sign request
+# import Cert
+#
+########################################################################
+cert_add_cert()
+{
+
+ CU_ACTION="Generate Cert Request for $CERTNAME"
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ CU_ACTION="Sign ${CERTNAME}'s Request"
+ certu -C -c "TestCA" -m "$CERTSERIAL" -v 60 -d "${P_R_CADIR}" \
+ -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ CU_ACTION="Import $CERTNAME's Cert"
+ certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+ -i "${CERTNAME}.cert" 2>&1
+ if [ "$RET" -ne 0 ]; then
+ return $RET
+ fi
+
+ cert_log "SUCCESS: $CERTNAME's Cert Created"
+ return 0
+}
+
+################################# cert_all_CA ################################
+# local shell function to build the additional Temp. Certificate Authority (CA)
+# used for the "real life" ssl test with 2 different CA's in the
+# client and in teh server's dir
+##########################################################################
+cert_all_CA()
+{
+ echo nss > ${PWFILE}
+
+ ALL_CU_SUBJECT="CN=NSS Test CA, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ cert_CA $CADIR TestCA -x "CTu,CTu,CTu" ${D_CA} "1"
+
+ ALL_CU_SUBJECT="CN=NSS Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $SERVER_CADIR serverCA -x "Cu,Cu,Cu" ${D_SERVER_CA} "2"
+ ALL_CU_SUBJECT="CN=NSS Chain1 Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $SERVER_CADIR chain-1-serverCA "-c serverCA" "u,u,u" ${D_SERVER_CA} "3"
+ ALL_CU_SUBJECT="CN=NSS Chain2 Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $SERVER_CADIR chain-2-serverCA "-c chain-1-serverCA" "u,u,u" ${D_SERVER_CA} "4"
+
+
+
+ ALL_CU_SUBJECT="CN=NSS Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $CLIENT_CADIR clientCA -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5"
+ ALL_CU_SUBJECT="CN=NSS Chain1 Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $CLIENT_CADIR chain-1-clientCA "-c clientCA" "u,u,u" ${D_CLIENT_CA} "6"
+ ALL_CU_SUBJECT="CN=NSS Chain2 Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
+ cert_CA $CLIENT_CADIR chain-2-clientCA "-c chain-1-clientCA" "u,u,u" ${D_CLIENT_CA} "7"
+
+ rm $CLIENT_CADIR/root.cert $SERVER_CADIR/root.cert
+ # root.cert in $CLIENT_CADIR and in $SERVER_CADIR is the one of the last
+ # in the chain
+}
+
+################################# cert_CA ################################
+# local shell function to build the Temp. Certificate Authority (CA)
+# used for testing purposes, creating a CA Certificate and a root cert
+##########################################################################
+cert_CA()
+{
+ CUR_CADIR=$1
+ NICKNAME=$2
+ SIGNER=$3
+ TRUSTARG=$4
+ DOMAIN=$5
+ CERTSERIAL=$6
+
+ echo "$SCRIPTNAME: Creating a CA Certificate $NICKNAME =========================="
+
+ if [ ! -d "${CUR_CADIR}" ]; then
+ mkdir -p "${CUR_CADIR}"
+ fi
+ cd ${CUR_CADIR}
+ pwd
+
+ LPROFILE=.
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ LPROFILE="multiaccess:${DOMAIN}"
+ fi
+
+ if [ "$SIGNER" = "-x" ] ; then # self signed -> create DB
+ CU_ACTION="Creating CA Cert DB"
+ certu -N -d ${LPROFILE} -f ${R_PWFILE} 2>&1
+ if [ "$RET" -ne 0 ]; then
+ Exit 5 "Fatal - failed to create CA $NICKNAME "
+ fi
+ echo "$SCRIPTNAME: Certificate initialized ----------"
+ fi
+
+
+ ################# Creating CA Cert ######################################
+ #
+ CU_ACTION="Creating CA Cert $NICKNAME "
+ CU_SUBJECT=$ALL_CU_SUBJECT
+ certu -S -n $NICKNAME -t $TRUSTARG -v 600 $SIGNER -d ${LPROFILE} -1 -2 -5 \
+ -f ${R_PWFILE} -z ${R_NOISE_FILE} -m $CERTSERIAL 2>&1 <<CERTSCRIPT
+5
+9
+n
+y
+-1
+n
+5
+6
+7
+9
+n
+CERTSCRIPT
+
+ if [ "$RET" -ne 0 ]; then
+ echo "return value is $RET"
+ Exit 6 "Fatal - failed to create CA cert"
+ fi
+
+ ################# Exporting Root Cert ###################################
+ #
+ CU_ACTION="Exporting Root Cert"
+ certu -L -n $NICKNAME -r -d ${LPROFILE} -o root.cert
+ if [ "$RET" -ne 0 ]; then
+ Exit 7 "Fatal - failed to export root cert"
+ fi
+ cp root.cert ${NICKNAME}.ca.cert
+}
+
+############################## cert_smime_client #############################
+# local shell function to create client Certificates for S/MIME tests
+##############################################################################
+cert_smime_client()
+{
+ CERTFAILED=0
+ echo "$SCRIPTNAME: Creating Client CA Issued Certificates =============="
+
+ cert_create_cert ${ALICEDIR} "Alice" 30 ${D_ALICE}
+ cert_create_cert ${BOBDIR} "Bob" 40 ${D_BOB}
+
+ echo "$SCRIPTNAME: Creating Dave's Certificate -------------------------"
+ cert_create_cert "${DAVEDIR}" Dave 50 ${D_DAVE}
+
+ echo "$SCRIPTNAME: Creating multiEmail's Certificate --------------------"
+ cert_create_cert "${EVEDIR}" "Eve" 60 ${D_EVE} "-7 eve@bogus.net,eve@bogus.cc,beve@bogus.com"
+
+ #echo "************* Copying CA files to ${SERVERDIR}"
+ #cp ${CADIR}/*.db .
+ #hw_acc
+
+ #########################################################################
+ #
+ #cd ${CERTDIR}
+ #CU_ACTION="Creating ${CERTNAME}'s Server Cert"
+ #CU_SUBJECT="CN=${CERTNAME}, E=${CERTNAME}@bogus.com, O=BOGUS Netscape, L=Mountain View, ST=California, C=US"
+ #certu -S -n "${CERTNAME}" -c "TestCA" -t "u,u,u" -m "$CERTSERIAL" \
+ # -d ${PROFILEDIR} -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -v 60 2>&1
+
+ #CU_ACTION="Export Dave's Cert"
+ #cd ${DAVEDIR}
+ #certu -L -n "Dave" -r -d ${P_R_DAVE} -o Dave.cert
+
+ ################# Importing Certificates for S/MIME tests ###############
+ #
+ echo "$SCRIPTNAME: Importing Certificates =============================="
+ CU_ACTION="Import Alices's cert into Bob's db"
+ certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \
+ -i ${R_ALICEDIR}/Alice.cert 2>&1
+
+ CU_ACTION="Import Bob's cert into Alice's db"
+ certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \
+ -i ${R_BOBDIR}/Bob.cert 2>&1
+
+ CU_ACTION="Import Dave's cert into Alice's DB"
+ certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \
+ -i ${R_DAVEDIR}/Dave.cert 2>&1
+
+ CU_ACTION="Import Dave's cert into Bob's DB"
+ certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \
+ -i ${R_DAVEDIR}/Dave.cert 2>&1
+
+ CU_ACTION="Import Eve's cert into Alice's DB"
+ certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \
+ -i ${R_EVEDIR}/Eve.cert 2>&1
+
+ CU_ACTION="Import Eve's cert into Bob's DB"
+ certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \
+ -i ${R_EVEDIR}/Eve.cert 2>&1
+
+ if [ "$CERTFAILED" != 0 ] ; then
+ cert_log "ERROR: SMIME failed $RET"
+ else
+ cert_log "SUCCESS: SMIME passed"
+ fi
+}
+
+############################## cert_ssl ################################
+# local shell function to create client + server certs for extended SSL test
+########################################################################
+cert_extended_ssl()
+{
+ ################# Creating Certs for extended SSL test ####################
+ #
+ CERTFAILED=0
+ echo "$SCRIPTNAME: Creating Certificates, issued by the last ==============="
+ echo " of a chain of CA's which are not in the same database============"
+
+ echo "Server Cert"
+ cert_init_cert ${EXT_SERVERDIR} "${HOSTADDR}" 1 ${D_EXT_SERVER}
+
+ CU_ACTION="Initializing ${CERTNAME}'s Cert DB (ext.)"
+ certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+
+ CU_ACTION="Generate Cert Request for $CERTNAME (ext)"
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+
+ CU_ACTION="Sign ${CERTNAME}'s Request (ext)"
+ cp ${CERTDIR}/req ${SERVER_CADIR}
+ certu -C -c "chain-2-serverCA" -m 200 -v 60 -d "${P_SERVER_CADIR}" \
+ -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" 2>&1
+
+ CU_ACTION="Import $CERTNAME's Cert -t u,u,u (ext)"
+ certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+ -i "${CERTNAME}.cert" 2>&1
+
+ CU_ACTION="Import Client Root CA -t T,, for $CERTNAME (ext.)"
+ certu -A -n "clientCA" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${CLIENT_CADIR}/clientCA.ca.cert" 2>&1
+ echo "Importing all the server's own CA chain into the servers DB"
+ for CA in `find ${SERVER_CADIR} -name "?*.ca.cert"` ;
+ do
+ N=`basename $CA | sed -e "s/.ca.cert//"`
+ if [ $N = "serverCA" ] ; then
+ T="-t C,C,C"
+ else
+ T="-t u,u,u"
+ fi
+ CU_ACTION="Import $N CA $T for $CERTNAME (ext.) "
+ certu -A -n $N $T -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${CA}" 2>&1
+ done
+#============
+ echo "Client Cert"
+ cert_init_cert ${EXT_CLIENTDIR} ExtendedSSLUser 1 ${D_EXT_CLIENT}
+
+ CU_ACTION="Initializing ${CERTNAME}'s Cert DB (ext.)"
+ certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+
+ CU_ACTION="Generate Cert Request for $CERTNAME (ext)"
+ CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+ certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+
+ CU_ACTION="Sign ${CERTNAME}'s Request (ext)"
+ cp ${CERTDIR}/req ${CLIENT_CADIR}
+ certu -C -c "chain-2-clientCA" -m 300 -v 60 -d "${P_CLIENT_CADIR}" \
+ -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" 2>&1
+
+ CU_ACTION="Import $CERTNAME's Cert -t u,u,u (ext)"
+ certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+ -i "${CERTNAME}.cert" 2>&1
+ CU_ACTION="Import Server Root CA -t C,C,C for $CERTNAME (ext.)"
+ certu -A -n "serverCA" -t "C,C,C" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${SERVER_CADIR}/serverCA.ca.cert" 2>&1
+ echo "Importing all the client's own CA chain into the servers DB"
+ for CA in `find ${CLIENT_CADIR} -name "?*.ca.cert"` ;
+ do
+ N=`basename $CA | sed -e "s/.ca.cert//"`
+ if [ $N = "clientCA" ] ; then
+ T="-t T,C,C"
+ else
+ T="-t u,u,u"
+ fi
+ CU_ACTION="Import $N CA $T for $CERTNAME (ext.)"
+ certu -A -n $N $T -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+ -i "${CA}" 2>&1
+ done
+ if [ "$CERTFAILED" != 0 ] ; then
+ cert_log "ERROR: EXT failed $RET"
+ else
+ cert_log "SUCCESS: EXT passed"
+ fi
+}
+
+############################## cert_ssl ################################
+# local shell function to create client + server certs for SSL test
+########################################################################
+cert_ssl()
+{
+ ################# Creating Certs for SSL test ###########################
+ #
+ CERTFAILED=0
+ echo "$SCRIPTNAME: Creating Client CA Issued Certificates ==============="
+ cert_create_cert ${CLIENTDIR} "TestUser" 70 ${D_CLIENT}
+
+ echo "$SCRIPTNAME: Creating Server CA Issued Certificate for \\"
+ echo " ${HOSTADDR} ------------------------------------"
+ cert_create_cert ${SERVERDIR} "${HOSTADDR}" 100 ${D_SERVER}
+ certu -M -n "TestCA" -t "TC,TC,TC" -d ${PROFILEDIR}
+# cert_init_cert ${SERVERDIR} "${HOSTADDR}" 1 ${D_SERVER}
+# echo "************* Copying CA files to ${SERVERDIR}"
+# cp ${CADIR}/*.db .
+# hw_acc
+# CU_ACTION="Creating ${CERTNAME}'s Server Cert"
+# CU_SUBJECT="CN=${CERTNAME}, O=BOGUS Netscape, L=Mountain View, ST=California, C=US"
+# certu -S -n "${CERTNAME}" -c "TestCA" -t "Pu,Pu,Pu" -d ${PROFILEDIR} \
+# -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -v 60 2>&1
+
+ if [ "$CERTFAILED" != 0 ] ; then
+ cert_log "ERROR: SSL failed $RET"
+ else
+ cert_log "SUCCESS: SSL passed"
+ fi
+}
+############################## cert_stresscerts ################################
+# local shell function to create client certs for SSL stresstest
+########################################################################
+cert_stresscerts()
+{
+
+ ############### Creating Certs for SSL stress test #######################
+ #
+ CERTDIR="$CLIENTDIR"
+ cd "${CERTDIR}"
+
+ PROFILEDIR=${CERTDIR}
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ PROFILEDIR="multiaccess:${D_CLIENT}"
+ fi
+ CERTFAILED=0
+ echo "$SCRIPTNAME: Creating Client CA Issued Certificates ==============="
+
+ CONTINUE=$GLOB_MAX_CERT
+ CERTSERIAL=10
+
+ while [ $CONTINUE -ge $GLOB_MIN_CERT ]
+ do
+ CERTNAME="TestUser$CONTINUE"
+# cert_add_cert ${CLIENTDIR} "TestUser$CONTINUE" $CERTSERIAL
+ cert_add_cert
+ CERTSERIAL=`expr $CERTSERIAL + 1 `
+ CONTINUE=`expr $CONTINUE - 1 `
+ done
+ if [ "$CERTFAILED" != 0 ] ; then
+ cert_log "ERROR: StressCert failed $RET"
+ else
+ cert_log "SUCCESS: StressCert passed"
+ fi
+}
+
+############################## cert_fips #####################################
+# local shell function to create certificates for FIPS tests
+##############################################################################
+cert_fips()
+{
+ CERTFAILED=0
+ echo "$SCRIPTNAME: Creating FIPS 140-1 DSA Certificates =============="
+ cert_init_cert "${FIPSDIR}" "FIPS PUB 140-1 Test Certificate" 1000 "${D_FIPS}"
+
+ CU_ACTION="Initializing ${CERTNAME}'s Cert DB"
+ certu -N -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" 2>&1
+
+ echo "$SCRIPTNAME: Enable FIPS mode on database -----------------------"
+ CU_ACTION="Enable FIPS mode on database for ${CERTNAME}"
+ echo "modutil -dbdir ${PROFILEDIR} -fips true "
+ modutil -dbdir ${PROFILEDIR} -fips true 2>&1 <<MODSCRIPT
+y
+MODSCRIPT
+ RET=$?
+ if [ "$RET" -ne 0 ]; then
+ html_failed "<TR><TD>${CU_ACTION} ($RET) "
+ cert_log "ERROR: ${CU_ACTION} failed $RET"
+ else
+ html_passed "<TR><TD>${CU_ACTION}"
+ fi
+
+ CU_ACTION="Generate Certificate for ${CERTNAME}"
+ CU_SUBJECT="CN=${CERTNAME}, E=fips@bogus.com, O=BOGUS NSS, OU=FIPS PUB 140-1, L=Mountain View, ST=California, C=US"
+ certu -S -n ${FIPSCERTNICK} -x -t "Cu,Cu,Cu" -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" -k dsa -v 600 -m 500 -z "${R_NOISE_FILE}" 2>&1
+ if [ "$RET" -eq 0 ]; then
+ cert_log "SUCCESS: FIPS passed"
+ fi
+}
+
+############################## cert_cleanup ############################
+# local shell function to finish this script (no exit since it might be
+# sourced)
+########################################################################
+cert_cleanup()
+{
+ cert_log "$SCRIPTNAME: finished $SCRIPTNAME"
+ html "</TABLE><BR>"
+ cd ${QADIR}
+ . common/cleanup.sh
+}
+
+################## main #################################################
+
+cert_init
+cert_all_CA
+cert_extended_ssl
+cert_ssl
+cert_smime_client
+cert_fips
+if [ -n "$DO_DIST_ST" -a "$DO_DIST_ST" = "TRUE" ] ; then
+ cert_stresscerts
+ #following lines to be used when databases are to be reused
+ #cp -r /u/sonmi/tmp/stress/kentuckyderby.13/* $HOSTDIR
+ #cp -r $HOSTDIR/../${HOST}.2/* $HOSTDIR
+
+fi
+cert_cleanup
diff --git a/security/nss/tests/fixtests.sh b/security/nss/tests/fixtests.sh
new file mode 100755
index 000000000..e5e90e192
--- /dev/null
+++ b/security/nss/tests/fixtests.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+#
+# 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 elliptic curve test suite.
+#
+# The Initial Developer of the Original Code is Sun Microsystems, Inc.
+# Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+# Sun Microsystems, Inc. All Rights Reserved.
+#
+# Contributor(s):
+# Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+#
+# 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.
+
+####################### fix_test_scripts #######################
+#
+# Depending on the argument either enable or disable EC based
+# tests in the cert and ssl directories.
+#
+################################################################
+fix_test_scripts()
+{
+ FLAG=$1
+ CERT_DIR=cert
+ CERT_SCRIPT=cert.sh
+ SSL_DIR=ssl
+ SSLAUTH=sslauth.txt
+ SSLCOV=sslcov.txt
+ SSL_SCRIPT=ssl.sh
+ SSLSTRESS=sslstress.txt
+ TOOLS_DIR=tools
+ TOOLS_SCRIPT=tools.sh
+ EC_PREFIX=ec
+ NOEC_PREFIX=noec
+
+ if [ xx$FLAG = xx"enable_ecc" ]; then
+ if [ -f $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT -a \
+ -f $SSL_DIR/$NOEC_PREFIX$SSLAUTH -a \
+ -f $SSL_DIR/$NOEC_PREFIX$SSLCOV -a \
+ -f $SSL_DIR/$NOEC_PREFIX$SSL_SCRIPT -a \
+ -f $SSL_DIR/$NOEC_PREFIX$SSLSTRESS -a \
+ -f $TOOLS_DIR/$NOEC_PREFIX$TOOLS_SCRIPT ]; then
+ echo "noecc files exist"
+ else
+ echo "noecc files are missing"
+ echo "Saving files as noec"
+ cp $CERT_DIR/$CERT_SCRIPT $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT
+ cp $SSL_DIR/$SSLAUTH $SSL_DIR/$NOEC_PREFIX$SSLAUTH
+ cp $SSL_DIR/$SSLCOV $SSL_DIR/$NOEC_PREFIX$SSLCOV
+ cp $SSL_DIR/$SSL_SCRIPT $SSL_DIR/$NOEC_PREFIX$SSL_SCRIPT
+ cp $SSL_DIR/$SSLSTRESS $SSL_DIR/$NOEC_PREFIX$SSLSTRESS
+ cp $TOOLS_DIR/$TOOLS_SCRIPT $TOOLS_DIR/$NOEC_PREFIX$TOOLS_SCRIPT
+ fi
+ echo "Overwriting with ec versions"
+ cp $CERT_DIR/$EC_PREFIX$CERT_SCRIPT $CERT_DIR/$CERT_SCRIPT
+ cp $SSL_DIR/$EC_PREFIX$SSLAUTH $SSL_DIR/$SSLAUTH
+ cp $SSL_DIR/$EC_PREFIX$SSLCOV $SSL_DIR/$SSLCOV
+ cp $SSL_DIR/$EC_PREFIX$SSL_SCRIPT $SSL_DIR/$SSL_SCRIPT
+ cp $SSL_DIR/$EC_PREFIX$SSLSTRESS $SSL_DIR/$SSLSTRESS
+ cp $TOOLS_DIR/$EC_PREFIX$TOOLS_SCRIPT $TOOLS_DIR/$TOOLS_SCRIPT
+ elif [ xx$FLAG = xx"disable_ecc" ]; then
+ if [ -f $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT -a \
+ -f $SSL_DIR/$NOEC_PREFIX$SSLAUTH -a \
+ -f $SSL_DIR/$NOEC_PREFIX$SSLCOV -a \
+ -f $SSL_DIR/$NOEC_PREFIX$SSL_SCRIPT -a \
+ -f $SSL_DIR/$NOEC_PREFIX$SSLSTRESS -a \
+ -f $TOOLS_DIR/$NOEC_PREFIX$TOOLS_SCRIPT ]; then
+ echo "noecc files exist"
+ echo "Overwriting with noec versions"
+ cp $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT $CERT_DIR/$CERT_SCRIPT
+ cp $SSL_DIR/$NOEC_PREFIX$SSLAUTH $SSL_DIR/$SSLAUTH
+ cp $SSL_DIR/$NOEC_PREFIX$SSLCOV $SSL_DIR/$SSLCOV
+ cp $SSL_DIR/$NOEC_PREFIX$SSL_SCRIPT $SSL_DIR/$SSL_SCRIPT
+ cp $SSL_DIR/$NOEC_PREFIX$SSLSTRESS $SSL_DIR/$SSLSTRESS
+ cp $TOOLS_DIR/$NOEC_PREFIX$TOOLS_SCRIPT $TOOLS_DIR/$TOOLS_SCRIPT
+ else
+ echo "Already disabled."
+ fi
+ else
+ echo "Needs either \"enable_ecc\" or \"disable_ecc\" as argument."
+ fi
+}
+
+
+fix_test_scripts $1
diff --git a/security/nss/tests/ssl/ecssl.sh b/security/nss/tests/ssl/ecssl.sh
new file mode 100644
index 000000000..512ed3fbb
--- /dev/null
+++ b/security/nss/tests/ssl/ecssl.sh
@@ -0,0 +1,349 @@
+#! /bin/sh
+#
+# 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) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+# Sun Microsystems, Inc. All Rights Reserved.
+#
+# Contributor(s):
+# Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+#
+# 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.
+#
+#
+########################################################################
+#
+# mozilla/security/nss/tests/ssl/ssl.sh
+#
+# Script to test NSS SSL
+#
+# needs to work on all Unix and Windows platforms
+#
+# special strings
+# ---------------
+# FIXME ... known problems, search for this string
+# NOTE .... unexpected behavior
+#
+########################################################################
+
+############################## ssl_init ################################
+# local shell function to initialize this script
+########################################################################
+ssl_init()
+{
+ SCRIPTNAME=ssl.sh # sourced - $0 would point to all.sh
+
+ if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for
+ CLEANUP="${SCRIPTNAME}" # cleaning this script will do it
+ fi
+
+ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
+ cd ../common
+ . ./init.sh
+ fi
+ if [ ! -r $CERT_LOG_FILE ]; then # we need certificates here
+ cd ../cert
+ . ./cert.sh
+ fi
+ SCRIPTNAME=ssl.sh
+ echo "$SCRIPTNAME: SSL tests ==============================="
+
+ grep "SUCCESS: SSL passed" $CERT_LOG_FILE >/dev/null || {
+ html_head "SSL Test failure"
+ Exit 8 "Fatal - SSL of cert.sh needs to pass first"
+ }
+
+ PORT=${PORT-8443}
+
+ # Test case files
+ SSLCOV=${QADIR}/ssl/sslcov.txt
+ SSLAUTH=${QADIR}/ssl/sslauth.txt
+ SSLSTRESS=${QADIR}/ssl/sslstress.txt
+ REQUEST_FILE=${QADIR}/ssl/sslreq.txt
+
+ #temparary files
+ SERVEROUTFILE=${TMP}/tests_server.$$
+ SERVERPID=${TMP}/tests_pid.$$
+
+ R_SERVERPID=../tests_pid.$$
+
+ TEMPFILES="$TMPFILES ${SERVEROUTFILE} ${SERVERPID}"
+
+ fileout=0 #FIXME, looks like all.sh tried to turn this on but actually didn't
+ #fileout=1
+ #verbose="-v" #FIXME - see where this is usefull
+
+ USER_NICKNAME=TestUser
+ NORM_EXT=""
+
+ cd ${CLIENTDIR}
+}
+
+########################### is_selfserv_alive ##########################
+# local shell function to exit with a fatal error if selfserver is not
+# running
+########################################################################
+is_selfserv_alive()
+{
+ if [ ! -f "${SERVERPID}" ]; then
+ echo "$SCRIPTNAME: Error - selfserv PID file ${SERVERPID} doesn't exist"
+ sleep 5
+ if [ ! -f "${SERVERPID}" ]; then
+ Exit 9 "Fatal - selfserv pid file ${SERVERPID} does not exist"
+ fi
+ fi
+ PID=`cat ${SERVERPID}`
+ #if [ "${OS_ARCH}" = "Linux" ]; then
+ kill -0 $PID >/dev/null 2>/dev/null || Exit 10 "Fatal - selfserv process not detectable"
+ #else
+ #$PS -e | grep $PID >/dev/null || \
+ #Exit 10 "Fatal - selfserv process not detectable"
+ #fi
+}
+
+########################### wait_for_selfserv ##########################
+# local shell function to wait until selfserver is running and initialized
+########################################################################
+wait_for_selfserv()
+{
+ echo "tstclnt -p ${PORT} -h ${HOST} -q "
+ echo " -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \\"
+ #echo "tstclnt -q started at `date`"
+ tstclnt -p ${PORT} -h ${HOST} -q -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}
+ if [ $? -ne 0 ]; then
+ html_failed "<TR><TD> Wait for Server "
+ echo "RETRY: tstclnt -p ${PORT} -h ${HOST} -q \\"
+ echo " -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}"
+ tstclnt -p ${PORT} -h ${HOST} -q -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}
+ elif [ sparam = "-c ABCDEFGHIJKLMNOPQRSTabcdefghijklmnvy" ] ; then # "$1" = "cov" ] ; then
+ html_passed "<TR><TD> Wait for Server"
+ fi
+ is_selfserv_alive
+}
+
+########################### kill_selfserv ##############################
+# local shell function to kill the selfserver after the tests are done
+########################################################################
+kill_selfserv()
+{
+ ${KILL} `cat ${SERVERPID}`
+ wait `cat ${SERVERPID}`
+ if [ ${fileout} -eq 1 ]; then
+ cat ${SERVEROUTFILE}
+ fi
+ # On Linux selfserv needs up to 30 seconds to fully die and free
+ # the port. Wait until the port is free. (Bug 129701)
+ if [ "${OS_ARCH}" = "Linux" ]; then
+ until selfserv -b -p ${PORT} 2>/dev/null; do
+ sleep 1
+ done
+ fi
+ rm ${SERVERPID}
+}
+
+########################### start_selfserv #############################
+# local shell function to start the selfserver with the parameters required
+# for this test and log information (parameters, start time)
+# also: wait until the server is up and running
+########################################################################
+start_selfserv()
+{
+ if [ -n "$testname" ] ; then
+ echo "$SCRIPTNAME: $testname ----"
+ fi
+ sparam=`echo $sparam | sed -e 's;_; ;g'`
+ echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \\"
+ echo " -e ${HOSTADDR}-ec \\"
+ echo " -w nss ${sparam} -i ${R_SERVERPID} $verbose &"
+ echo "selfserv started at `date`"
+ if [ ${fileout} -eq 1 ]; then
+ selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \
+ -e ${HOSTADDR}-ec \
+ -w nss ${sparam} -i ${R_SERVERPID} $verbose \
+ > ${SERVEROUTFILE} 2>&1 &
+ else
+ selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \
+ -e ${HOSTADDR}-ec \
+ -w nss ${sparam} -i ${R_SERVERPID} $verbose &
+ fi
+ wait_for_selfserv
+}
+
+############################## ssl_cov #################################
+# local shell function to perform SSL Cipher Coverage tests
+########################################################################
+ssl_cov()
+{
+ html_head "SSL Cipher Coverage $NORM_EXT"
+
+ testname=""
+ sparam="-c ABCDEFGHIJKLMNOPQRSTabcdefghijklmnvyz"
+ start_selfserv # Launch the server
+
+ p=""
+
+ while read tls param testname
+ do
+ p=`echo "$testname" | sed -e "s/ .*//"` #sonmi, only run extended test on SSL3 and TLS
+
+ if [ "$p" = "SSL2" -a "$NORM_EXT" = "Extended test" ] ; then
+ echo "$SCRIPTNAME: skipping $testname for $NORM_EXT"
+ elif [ "$tls" != "#" ] ; then
+ echo "$SCRIPTNAME: running $testname ----------------------------"
+ TLS_FLAG=-T
+ if [ $tls = "TLS" ]; then
+ TLS_FLAG=""
+ fi
+
+ is_selfserv_alive
+ echo "tstclnt -p ${PORT} -h ${HOST} -c ${param} ${TLS_FLAG} \\"
+ echo " -f -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}"
+
+ rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
+ tstclnt -p ${PORT} -h ${HOST} -c ${param} ${TLS_FLAG} -f \
+ -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \
+ >${TMP}/$HOST.tmp.$$ 2>&1
+ ret=$?
+ cat ${TMP}/$HOST.tmp.$$
+ rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
+ html_msg $ret 0 "${testname}"
+ fi
+ done < ${SSLCOV}
+
+ kill_selfserv
+ html "</TABLE><BR>"
+}
+
+############################## ssl_auth ################################
+# local shell function to perform SSL Client Authentication tests
+########################################################################
+ssl_auth()
+{
+ html_head "SSL Client Authentication $NORM_EXT"
+
+ while read value sparam cparam testname
+ do
+ if [ $value != "#" ]; then
+ cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" `
+ start_selfserv
+
+ echo "tstclnt -p ${PORT} -h ${HOST} -f -d ${P_R_CLIENTDIR} \\"
+ echo " ${cparam} < ${REQUEST_FILE}"
+ rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
+ tstclnt -p ${PORT} -h ${HOST} -f ${cparam} \
+ -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \
+ >${TMP}/$HOST.tmp.$$ 2>&1
+ ret=$?
+ cat ${TMP}/$HOST.tmp.$$
+ rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
+
+ html_msg $ret $value "${testname}" \
+ "produced a returncode of $ret, expected is $value"
+ kill_selfserv
+ fi
+ done < ${SSLAUTH}
+
+ html "</TABLE><BR>"
+}
+
+
+############################## ssl_stress ##############################
+# local shell function to perform SSL stress test
+########################################################################
+ssl_stress()
+{
+ html_head "SSL Stress Test $NORM_EXT"
+
+ while read value sparam cparam testname
+ do
+ p=`echo "$testname" | sed -e "s/Stress //" -e "s/ .*//"` #sonmi, only run extended test on SSL3 and TLS
+ if [ "$p" = "SSL2" -a "$NORM_EXT" = "Extended test" ] ; then
+ echo "$SCRIPTNAME: skipping $testname for $NORM_EXT"
+ elif [ $value != "#" ]; then
+ cparam=`echo $cparam | sed -e 's;_; ;g'`
+ start_selfserv
+ if [ `uname -n` = "sjsu" ] ; then
+ echo "debugging disapering selfserv... ps -ef | grep selfserv"
+ ps -ef | grep selfserv
+ fi
+
+ echo "strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} -w nss $cparam \\"
+ echo " $verbose ${HOSTADDR}"
+ echo "strsclnt started at `date`"
+ strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} -w nss $cparam \
+ $verbose ${HOSTADDR}
+ ret=$?
+ echo "strsclnt completed at `date`"
+ html_msg $ret $value "${testname}"
+ if [ `uname -n` = "sjsu" ] ; then
+ echo "debugging disapering selfserv... ps -ef | grep selfserv"
+ ps -ef | grep selfserv
+ fi
+ kill_selfserv
+ fi
+ done < ${SSLSTRESS}
+
+ html "</TABLE><BR>"
+}
+
+
+############################## ssl_cleanup #############################
+# local shell function to finish this script (no exit since it might be
+# sourced)
+########################################################################
+ssl_cleanup()
+{
+ rm $SERVERPID 2>/dev/null
+ cd ${QADIR}
+ . common/cleanup.sh
+}
+
+################## main #################################################
+
+#this script may be sourced from the distributed stress test - in this case do nothing...
+
+if [ -z "$DO_REM_ST" -a -z "$DO_DIST_ST" ] ; then
+ ssl_init
+ ssl_cov
+ ssl_auth
+ ssl_stress
+
+ SERVERDIR=$EXT_SERVERDIR
+ CLIENTDIR=$EXT_CLIENTDIR
+ R_SERVERDIR=$R_EXT_SERVERDIR
+ R_CLIENTDIR=$R_EXT_CLIENTDIR
+ P_R_SERVERDIR=$P_R_EXT_SERVERDIR
+ P_R_CLIENTDIR=$P_R_EXT_CLIENTDIR
+ USER_NICKNAME=ExtendedSSLUser
+ NORM_EXT="Extended test"
+ cd ${CLIENTDIR}
+ ssl_cov
+ ssl_auth
+ ssl_stress
+ ssl_cleanup
+fi
diff --git a/security/nss/tests/ssl/ecsslauth.txt b/security/nss/tests/ssl/ecsslauth.txt
new file mode 100644
index 000000000..e7204feb2
--- /dev/null
+++ b/security/nss/tests/ssl/ecsslauth.txt
@@ -0,0 +1,50 @@
+#
+# This file defines the tests for client auth.
+#
+# expected
+# return server client Test Case name
+# value params params
+# ------ ------ ------ ---------------
+ 0 -r -w_nss TLS Request don't require client auth (client does not provide auth)
+ 0 -r -w_bogus_-n_TestUser TLS Request don't require client auth (bad password)
+ 0 -r -w_nss_-n_TestUser TLS Request don't require client auth (client auth)
+ 0 -r_-r -w_nss TLS Require client auth (client does not provide auth)
+ 254 -r_-r -w_bogus_-n_TestUser TLS Require client auth (bad password)
+ 0 -r_-r -w_nss_-n_TestUser_ TLS Require client auth (client auth)
+ 0 -r -T_-w_nss SSL3 Request don't require client auth (client does not provide auth)
+ 0 -r -T_-n_TestUser_-w_bogus SSL3 Request don't require client auth (bad password)
+ 0 -r -T_-n_TestUser_-w_nss SSL3 Request don't require client auth (client auth)
+ 0 -r_-r -T_-w_nss SSL3 Require client auth (client does not provide auth)
+ 254 -r_-r -T_-n_TestUser_-w_bogus SSL3 Require client auth (bad password)
+ 0 -r_-r -T_-n_TestUser_-w_nss SSL3 Require client auth (client auth)
+ 0 -r_-r_-r -w_nss TLS Request don't require client auth on 2nd hs (client does not provide auth)
+ 0 -r_-r_-r -w_bogus_-n_TestUser TLS Request don't require client auth on 2nd hs (bad password)
+ 0 -r_-r_-r -w_nss_-n_TestUser TLS Request don't require client auth on 2nd hs (client auth)
+ 0 -r_-r_-r_-r -w_nss TLS Require client auth on 2nd hs (client does not provide auth)
+ 1 -r_-r_-r_-r -w_bogus_-n_TestUser TLS Require client auth on 2nd hs (bad password)
+ 0 -r_-r_-r_-r -w_nss_-n_TestUser_ TLS Require client auth on 2nd hs (client auth)
+ 0 -r_-r_-r -T_-w_nss SSL3 Request don't require client auth on 2nd hs (client does not provide auth)
+ 0 -r_-r_-r -T_-n_TestUser_-w_bogus SSL3 Request don't require client auth on 2nd hs (bad password)
+ 0 -r_-r_-r -T_-n_TestUser_-w_nss SSL3 Request don't require client auth on 2nd hs (client auth)
+ 0 -r_-r_-r_-r -T_-w_nss SSL3 Require client auth on 2nd hs (client does not provide auth)
+ 1 -r_-r_-r_-r -T_-n_TestUser_-w_bogus SSL3 Require client auth on 2nd hs (bad password)
+ 0 -r_-r_-r_-r -T_-n_TestUser_-w_nss SSL3 Require client auth on 2nd hs (client auth)
+#
+# Use EC cert for client authentication
+#
+ 0 -r -w_bogus_-n_TestUser-ec TLS Request don't require client auth (EC) (bad password)
+ 0 -r -w_nss_-n_TestUser-ec TLS Request don't require client auth (EC) (client auth)
+ 254 -r_-r -w_bogus_-n_TestUser-ec TLS Require client auth (EC) (bad password)
+ 0 -r_-r -w_nss_-n_TestUser-ec_ TLS Require client auth (EC) (client auth)
+ 0 -r -T_-n_TestUser-ec_-w_bogus SSL3 Request don't require client auth (EC) (bad password)
+ 0 -r -T_-n_TestUser-ec_-w_nss SSL3 Request don't require client auth (EC) (client auth)
+ 254 -r_-r -T_-n_TestUser-ec_-w_bogus SSL3 Require client auth (EC) (bad password)
+ 0 -r_-r -T_-n_TestUser-ec_-w_nss SSL3 Require client auth (EC) (client auth)
+ 0 -r_-r_-r -w_bogus_-n_TestUser-ec TLS Request don't require client auth on 2nd hs (EC) (bad password)
+ 0 -r_-r_-r -w_nss_-n_TestUser-ec TLS Request don't require client auth on 2nd hs (EC) (client auth)
+ 1 -r_-r_-r_-r -w_bogus_-n_TestUser-ec TLS Require client auth on 2nd hs (EC) (bad password)
+ 0 -r_-r_-r_-r -w_nss_-n_TestUser-ec_ TLS Require client auth on 2nd hs (EC) (client auth)
+ 0 -r_-r_-r -T_-n_TestUser-ec_-w_bogus SSL3 Request don't require client auth on 2nd hs (EC) (bad password)
+ 0 -r_-r_-r -T_-n_TestUser-ec_-w_nss SSL3 Request don't require client auth on 2nd hs (EC) (client auth)
+ 1 -r_-r_-r_-r -T_-n_TestUser-ec_-w_bogus SSL3 Require client auth on 2nd hs (EC) (bad password)
+ 0 -r_-r_-r_-r -T_-n_TestUser-ec_-w_nss SSL3 Require client auth on 2nd hs (EC) (client auth)
diff --git a/security/nss/tests/ssl/ecsslcov.txt b/security/nss/tests/ssl/ecsslcov.txt
new file mode 100644
index 000000000..f01e56899
--- /dev/null
+++ b/security/nss/tests/ssl/ecsslcov.txt
@@ -0,0 +1,83 @@
+#
+# This file enables test coverage of the various SSL ciphers
+#
+# NOTE: SSL2 ciphers are independent of whether TLS is enabled or not. We
+# mix up the enable functions so we can tests boths paths.
+#
+# Enable Cipher Test Name
+# TLS
+#
+ noTLS A SSL2 RC4 128 WITH MD5
+ TLS B SSL2 RC4 128 EXPORT40 WITH MD5
+ TLS C SSL2 RC2 128 CBC WITH MD5
+ noTLS D SSL2 RC2 128 CBC EXPORT40 WITH MD5
+ TLS E SSL2 DES 64 CBC WITH MD5
+ noTLS F SSL2 DES 192 EDE3 CBC WITH MD5
+#
+# ECC ciphers (SSL3)
+#
+ noTLS G SSL3 ECDH ECDSA WITH NULL SHA
+ noTLS H SSL3 ECDH ECDSA WITH RC4 128 SHA
+ noTLS I SSL3 ECDH ECDSA WITH DES CBC SHA
+ noTLS J SSL3 ECDH ECDSA WITH 3DES EDE CBC SHA
+ noTLS K SSL3 ECDH ECDSA WITH AES 128 CBC SHA
+ noTLS L SSL3 ECDH ECDSA WITH AES 256 CBC SHA
+ noTLS M SSL3 ECDH RSA WITH NULL SHA
+ noTLS N SSL3 ECDH RSA WITH RC4 128 SHA
+ noTLS O SSL3 ECDH RSA WITH DES CBC SHA
+ noTLS P SSL3 ECDH RSA WITH 3DES EDE CBC SHA
+ noTLS Q SSL3 ECDH RSA WITH AES 128 CBC SHA
+ noTLS R SSL3 ECDH RSA WITH AES 256 CBC SHA
+ noTLS S SSL3 ECDHE ECDSA WITH AES 128 CBC SHA
+ noTLS T SSL3 ECDHE RSA WITH AES 128 CBC SHA
+#
+# ECC ciphers (TLS)
+#
+ TLS G TLS ECDH ECDSA WITH NULL SHA
+ TLS H TLS ECDH ECDSA WITH RC4 128 SHA
+ TLS I TLS ECDH ECDSA WITH DES CBC SHA
+ TLS J TLS ECDH ECDSA WITH 3DES EDE CBC SHA
+ TLS K TLS ECDH ECDSA WITH AES 128 CBC SHA
+ TLS L TLS ECDH ECDSA WITH AES 256 CBC SHA
+ TLS M TLS ECDH RSA WITH NULL SHA
+ TLS N TLS ECDH RSA WITH RC4 128 SHA
+ TLS O TLS ECDH RSA WITH DES CBC SHA
+ TLS P TLS ECDH RSA WITH 3DES EDE CBC SHA
+ TLS Q TLS ECDH RSA WITH AES 128 CBC SHA
+ TLS R TLS ECDH RSA WITH AES 256 CBC SHA
+ TLS S TLS ECDHE ECDSA WITH AES 128 CBC SHA
+ TLS T TLS ECDHE RSA WITH AES 128 CBC SHA
+#
+#
+# noTLS a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA
+# noTLS b SSL3 FORTEZZA DMS WITH RC4 128 SHA
+ noTLS c SSL3 RSA WITH RC4 128 MD5
+ noTLS d SSL3 RSA WITH 3DES EDE CBC SHA
+ noTLS e SSL3 RSA WITH DES CBC SHA
+ noTLS f SSL3 RSA EXPORT WITH RC4 40 MD5
+ noTLS g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5
+# noTLS h SSL3 FORTEZZA DMS WITH NULL SHA
+ noTLS i SSL3 RSA WITH NULL MD5
+ noTLS j SSL3 RSA FIPS WITH 3DES EDE CBC SHA
+ noTLS k SSL3 RSA FIPS WITH DES CBC SHA
+ noTLS l SSL3 RSA EXPORT WITH DES CBC SHA (new)
+ noTLS m SSL3 RSA EXPORT WITH RC4 56 SHA (new)
+ noTLS n SSL3 RSA WITH RC4 128 SHA
+ noTLS v SSL3 RSA WITH AES 128 CBC SHA
+ noTLS y SSL3 RSA WITH AES 256 CBC SHA
+ noTLS z SSL3 RSA WITH NULL SHA
+#
+ TLS c TLS RSA WITH RC4 128 MD5
+ TLS d TLS RSA WITH 3DES EDE CBC SHA
+ TLS e TLS RSA WITH DES CBC SHA
+ TLS f TLS RSA EXPORT WITH RC4 40 MD5
+ TLS g TLS RSA EXPORT WITH RC2 CBC 40 MD5
+ TLS i TLS RSA WITH NULL MD5
+ TLS j TLS RSA FIPS WITH 3DES EDE CBC SHA
+ TLS k TLS RSA FIPS WITH DES CBC SHA
+ TLS l TLS RSA EXPORT WITH DES CBC SHA (new)
+ TLS m TLS RSA EXPORT WITH RC4 56 SHA (new)
+ TLS n TLS RSA WITH RC4 128 SHA
+ TLS v TLS RSA WITH AES 128 CBC SHA
+ TLS y TLS RSA WITH AES 256 CBC SHA
+ TLS z TLS RSA WITH NULL SHA
diff --git a/security/nss/tests/ssl/ecsslstress.txt b/security/nss/tests/ssl/ecsslstress.txt
new file mode 100644
index 000000000..f9feb5d99
--- /dev/null
+++ b/security/nss/tests/ssl/ecsslstress.txt
@@ -0,0 +1,24 @@
+#
+# This file defines the tests for client auth.
+#
+# expected
+# return server client Test Case name
+# value params params
+# ------ ------ ------ ---------------
+ 0 _ -c_1000_-C_A Stress SSL2 RC4 128 with MD5
+ 0 _ -c_1000_-C_c Stress SSL3 RC4 128 with MD5
+ 0 _ -c_1000_-C_c Stress TLS RC4 128 with MD5
+#
+# ECC ciphers
+# XXX Session reuse does not seem to work for ECDH-ECDSA, ECDHE-ECDSA ciphers
+# but works ok for ECDHE-RSA ciphers. With session reuse turned off
+# setting up 1000 connections would take too long so use only 10 connections
+#
+ 0 -c_H -c_10_-C_H_-N Stress TLS ECDH-ECDSA RC4 128 with SHA (no reuse)
+ 0 -c_S -c_10_-C_S_-N Stress TLS ECDHE-ECDSA AES 128 CBC with SHA (no reuse)
+ 0 -c_T -c_1000_-C_T Stress TLS ECDHE-RSA AES 128 CBC with SHA
+
+#
+# add client auth versions here...
+#
+# 0 -r -w_bogus_-n_"Test_User" TLS Request don't require client auth (bad password)
diff --git a/security/nss/tests/ssl/sslreq.dat b/security/nss/tests/ssl/sslreq.dat
new file mode 100644
index 000000000..2f7ad7736
--- /dev/null
+++ b/security/nss/tests/ssl/sslreq.dat
@@ -0,0 +1,2 @@
+GET / HTTP/1.0
+
diff --git a/security/nss/tests/tools/ectools.sh b/security/nss/tests/tools/ectools.sh
new file mode 100644
index 000000000..d3ce81fa4
--- /dev/null
+++ b/security/nss/tests/tools/ectools.sh
@@ -0,0 +1,210 @@
+#! /bin/sh
+#
+# 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) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
+# Sun Microsystems, Inc. All Rights Reserved.
+#
+# Contributor(s):
+# Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+#
+# 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.
+#
+#
+########################################################################
+#
+# mozilla/security/nss/tests/tools/tools.sh
+#
+# Script to test basic functionallity of NSS tools
+#
+# needs to work on all Unix and Windows platforms
+#
+# tests implemented:
+# pk12util
+# signtool
+#
+# special strings
+# ---------------
+# FIXME ... known problems, search for this string
+# NOTE .... unexpected behavior
+#
+########################################################################
+
+############################## tools_init ##############################
+# local shell function to initialize this script
+########################################################################
+tools_init()
+{
+ SCRIPTNAME=tools.sh # sourced - $0 would point to all.sh
+
+ if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for
+ CLEANUP="${SCRIPTNAME}" # cleaning this script will do it
+ fi
+
+ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
+ cd ../common
+ . ./init.sh
+ fi
+ if [ ! -r $CERT_LOG_FILE ]; then # we need certificates here
+ cd ../cert
+ . ./cert.sh
+ fi
+ SCRIPTNAME=tools.sh
+ html_head "Tools Tests"
+
+ grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || {
+ Exit 15 "Fatal - S/MIME of cert.sh needs to pass first"
+ }
+
+ TOOLSDIR=${HOSTDIR}/tools
+ COPYDIR=${TOOLSDIR}/copydir
+
+ R_TOOLSDIR=../tools
+ R_COPYDIR=../tools/copydir
+ P_R_COPYDIR=${R_COPYDIR}
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ P_R_COPYDIR="multiaccess:Tools.$version"
+ fi
+
+ mkdir -p ${TOOLSDIR}
+ mkdir -p ${COPYDIR}
+ mkdir -p ${TOOLSDIR}/html
+ cp ${QADIR}/tools/sign*.html ${TOOLSDIR}/html
+
+ cd ${TOOLSDIR}
+}
+
+############################## tools_p12 ###############################
+# local shell function to test basic functionality of pk12util
+########################################################################
+tools_p12()
+{
+ echo "$SCRIPTNAME: Exporting Alice's email cert & key------------------"
+ echo "pk12util -o Alice.p12 -n \"Alice\" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \\"
+ echo " -w ${R_PWFILE}"
+ pk12util -o Alice.p12 -n "Alice" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \
+ -w ${R_PWFILE} 2>&1
+ ret=$?
+ html_msg $ret 0 "Exporting Alice's email cert & key (pk12util -o)"
+ check_tmpfile
+
+ echo "$SCRIPTNAME: Importing Alice's email cert & key -----------------"
+ echo "pk12util -i Alice.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}"
+ pk12util -i Alice.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1
+ ret=$?
+ html_msg $ret 0 "Importing Alice's email cert & key (pk12util -i)"
+ check_tmpfile
+
+ echo "$SCRIPTNAME: Exporting Alice's email EC cert & key---------------"
+ echo "pk12util -o Alice-ec.p12 -n \"Alice-ec\" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \\"
+ echo " -w ${R_PWFILE}"
+ pk12util -o Alice-ec.p12 -n "Alice-ec" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \
+ -w ${R_PWFILE} 2>&1
+ ret=$?
+ html_msg $ret 0 "Exporting Alice's email EC cert & key (pk12util -o)"
+ check_tmpfile
+
+ echo "$SCRIPTNAME: Importing Alice's email EC cert & key --------------"
+ echo "pk12util -i Alice-ec.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}"
+ pk12util -i Alice-ec.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1
+ ret=$?
+ html_msg $ret 0 "Importing Alice's email EC cert & key (pk12util -i)"
+ check_tmpfile
+
+}
+
+############################## tools_sign ##############################
+# local shell function pk12util uses a hardcoded tmp file, if this exists
+# and is owned by another user we don't get reasonable errormessages
+########################################################################
+check_tmpfile()
+{
+ if [ $ret != "0" -a -f /tmp/Pk12uTemp ] ; then
+ echo "Error: pk12util temp file exists. Please remove this file and"
+ echo " rerun the test (/tmp/Pk12uTemp) "
+ fi
+}
+
+############################## tools_sign ##############################
+# local shell function to test basic functionality of signtool
+########################################################################
+tools_sign()
+{
+ echo "$SCRIPTNAME: Create objsign cert -------------------------------"
+ echo "signtool -G \"objectsigner\" -d ${P_R_ALICEDIR} -p \"nss\""
+ signtool -G "objsigner" -d ${P_R_ALICEDIR} -p "nss" 2>&1 <<SIGNSCRIPT
+y
+TEST
+MOZ
+NSS
+NY
+US
+liz
+liz@moz.org
+SIGNSCRIPT
+ html_msg $? 0 "Create objsign cert (signtool -G)"
+
+ echo "$SCRIPTNAME: Signing a set of files ----------------------------"
+ echo "signtool -Z nojs.jar -d ${P_R_ALICEDIR} -p \"nss\" -k objsigner \\"
+ echo " ${R_TOOLSDIR}/html"
+ signtool -Z nojs.jar -d ${P_R_ALICEDIR} -p "nss" -k objsigner \
+ ${R_TOOLSDIR}/html
+ html_msg $? 0 "Signing a set of files (signtool -Z)"
+
+ echo "$SCRIPTNAME: Listing signed files in jar ----------------------"
+ echo "signtool -v nojs.jar -d ${P_R_ALICEDIR} -p nss -k objsigner"
+ signtool -v nojs.jar -d ${P_R_ALICEDIR} -p nss -k objsigner
+ html_msg $? 0 "Listing signed files in jar (signtool -v)"
+
+ echo "$SCRIPTNAME: Show who signed jar ------------------------------"
+ echo "signtool -w nojs.jar -d ${P_R_ALICEDIR}"
+ signtool -w nojs.jar -d ${P_R_ALICEDIR}
+ html_msg $? 0 "Show who signed jar (signtool -w)"
+}
+
+############################## tools_cleanup ###########################
+# local shell function to finish this script (no exit since it might be
+# sourced)
+########################################################################
+tools_cleanup()
+{
+ html "</TABLE><BR>"
+ cd ${QADIR}
+ . common/cleanup.sh
+}
+
+################## main #################################################
+
+tools_init
+
+tools_p12
+
+tools_sign
+tools_cleanup
+
+
diff --git a/security/nss/tests/tools/noectools.sh b/security/nss/tests/tools/noectools.sh
new file mode 100644
index 000000000..b301fc72b
--- /dev/null
+++ b/security/nss/tests/tools/noectools.sh
@@ -0,0 +1,189 @@
+#! /bin/sh
+#
+# 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) 1994-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.
+#
+#
+########################################################################
+#
+# mozilla/security/nss/tests/tools/tools.sh
+#
+# Script to test basic functionallity of NSS tools
+#
+# needs to work on all Unix and Windows platforms
+#
+# tests implemented:
+# pk12util
+# signtool
+#
+# special strings
+# ---------------
+# FIXME ... known problems, search for this string
+# NOTE .... unexpected behavior
+#
+########################################################################
+
+############################## tools_init ##############################
+# local shell function to initialize this script
+########################################################################
+tools_init()
+{
+ SCRIPTNAME=tools.sh # sourced - $0 would point to all.sh
+
+ if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for
+ CLEANUP="${SCRIPTNAME}" # cleaning this script will do it
+ fi
+
+ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
+ cd ../common
+ . ./init.sh
+ fi
+ if [ ! -r $CERT_LOG_FILE ]; then # we need certificates here
+ cd ../cert
+ . ./cert.sh
+ fi
+ SCRIPTNAME=tools.sh
+ html_head "Tools Tests"
+
+ grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || {
+ Exit 15 "Fatal - S/MIME of cert.sh needs to pass first"
+ }
+
+ TOOLSDIR=${HOSTDIR}/tools
+ COPYDIR=${TOOLSDIR}/copydir
+
+ R_TOOLSDIR=../tools
+ R_COPYDIR=../tools/copydir
+ P_R_COPYDIR=${R_COPYDIR}
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ P_R_COPYDIR="multiaccess:Tools.$version"
+ fi
+
+ mkdir -p ${TOOLSDIR}
+ mkdir -p ${COPYDIR}
+ mkdir -p ${TOOLSDIR}/html
+ cp ${QADIR}/tools/sign*.html ${TOOLSDIR}/html
+
+ cd ${TOOLSDIR}
+}
+
+############################## tools_p12 ###############################
+# local shell function to test basic functionality of pk12util
+########################################################################
+tools_p12()
+{
+ echo "$SCRIPTNAME: Exporting Alice's email cert & key------------------"
+ echo "pk12util -o Alice.p12 -n \"Alice\" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \\"
+ echo " -w ${R_PWFILE}"
+ pk12util -o Alice.p12 -n "Alice" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \
+ -w ${R_PWFILE} 2>&1
+ ret=$?
+ html_msg $ret 0 "Exporting Alice's email cert & key (pk12util -o)"
+ check_tmpfile
+
+ echo "$SCRIPTNAME: Importing Alice's email cert & key -----------------"
+ echo "pk12util -i Alice.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}"
+ pk12util -i Alice.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1
+ ret=$?
+ html_msg $ret 0 "Importing Alice's email cert & key (pk12util -i)"
+ check_tmpfile
+}
+
+############################## tools_sign ##############################
+# local shell function pk12util uses a hardcoded tmp file, if this exists
+# and is owned by another user we don't get reasonable errormessages
+########################################################################
+check_tmpfile()
+{
+ if [ $ret != "0" -a -f /tmp/Pk12uTemp ] ; then
+ echo "Error: pk12util temp file exists. Please remove this file and"
+ echo " rerun the test (/tmp/Pk12uTemp) "
+ fi
+}
+
+############################## tools_sign ##############################
+# local shell function to test basic functionality of signtool
+########################################################################
+tools_sign()
+{
+ echo "$SCRIPTNAME: Create objsign cert -------------------------------"
+ echo "signtool -G \"objectsigner\" -d ${P_R_ALICEDIR} -p \"nss\""
+ signtool -G "objsigner" -d ${P_R_ALICEDIR} -p "nss" 2>&1 <<SIGNSCRIPT
+y
+TEST
+MOZ
+NSS
+NY
+US
+liz
+liz@moz.org
+SIGNSCRIPT
+ html_msg $? 0 "Create objsign cert (signtool -G)"
+
+ echo "$SCRIPTNAME: Signing a set of files ----------------------------"
+ echo "signtool -Z nojs.jar -d ${P_R_ALICEDIR} -p \"nss\" -k objsigner \\"
+ echo " ${R_TOOLSDIR}/html"
+ signtool -Z nojs.jar -d ${P_R_ALICEDIR} -p "nss" -k objsigner \
+ ${R_TOOLSDIR}/html
+ html_msg $? 0 "Signing a set of files (signtool -Z)"
+
+ echo "$SCRIPTNAME: Listing signed files in jar ----------------------"
+ echo "signtool -v nojs.jar -d ${P_R_ALICEDIR} -p nss -k objsigner"
+ signtool -v nojs.jar -d ${P_R_ALICEDIR} -p nss -k objsigner
+ html_msg $? 0 "Listing signed files in jar (signtool -v)"
+
+ echo "$SCRIPTNAME: Show who signed jar ------------------------------"
+ echo "signtool -w nojs.jar -d ${P_R_ALICEDIR}"
+ signtool -w nojs.jar -d ${P_R_ALICEDIR}
+ html_msg $? 0 "Show who signed jar (signtool -w)"
+}
+
+############################## tools_cleanup ###########################
+# local shell function to finish this script (no exit since it might be
+# sourced)
+########################################################################
+tools_cleanup()
+{
+ html "</TABLE><BR>"
+ cd ${QADIR}
+ . common/cleanup.sh
+}
+
+################## main #################################################
+
+tools_init
+
+tools_p12
+
+tools_sign
+tools_cleanup
+
+